tests/util: Remove unused variable warning in fill_tiles_rgb16fp()
[platform/upstream/libdrm.git] / tests / util / pattern.c
1 /*
2  * Copyright 2008 Tungsten Graphics
3  *   Jakob Bornecrantz <jakob@tungstengraphics.com>
4  * Copyright 2008 Intel Corporation
5  *   Jesse Barnes <jesse.barnes@intel.com>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23  * IN THE SOFTWARE.
24  */
25
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <drm_fourcc.h>
32
33 #if HAVE_CAIRO
34 #include <cairo.h>
35 #include <math.h>
36 #endif
37
38 #include "common.h"
39 #include "format.h"
40 #include "pattern.h"
41
42 struct color_rgb24 {
43         unsigned int value:24;
44 } __attribute__((__packed__));
45
46 struct color_yuv {
47         unsigned char y;
48         unsigned char u;
49         unsigned char v;
50 };
51
52 #define MAKE_YUV_601_Y(r, g, b) \
53         ((( 66 * (r) + 129 * (g) +  25 * (b) + 128) >> 8) + 16)
54 #define MAKE_YUV_601_U(r, g, b) \
55         (((-38 * (r) -  74 * (g) + 112 * (b) + 128) >> 8) + 128)
56 #define MAKE_YUV_601_V(r, g, b) \
57         (((112 * (r) -  94 * (g) -  18 * (b) + 128) >> 8) + 128)
58
59 #define MAKE_YUV_601(r, g, b) \
60         { .y = MAKE_YUV_601_Y(r, g, b), \
61           .u = MAKE_YUV_601_U(r, g, b), \
62           .v = MAKE_YUV_601_V(r, g, b) }
63
64 /* This function takes 8-bit color values */
65 static inline uint32_t shiftcolor8(const struct util_color_component *comp,
66                                   uint32_t value)
67 {
68         value &= 0xff;
69         /* Fill the low bits with the high bits. */
70         value = (value << 8) | value;
71         /* Shift down to remove unwanted low bits */
72         value = value >> (16 - comp->length);
73         /* Shift back up to where the value should be */
74         return value << comp->offset;
75 }
76
77 /* This function takes 10-bit color values */
78 static inline uint32_t shiftcolor10(const struct util_color_component *comp,
79                                     uint32_t value)
80 {
81         value &= 0x3ff;
82         /* Fill the low bits with the high bits. */
83         value = (value << 6) | (value >> 4);
84         /* Shift down to remove unwanted low bits */
85         value = value >> (16 - comp->length);
86         /* Shift back up to where the value should be */
87         return value << comp->offset;
88 }
89
90 /* This function takes 16-bit color values */
91 static inline uint64_t shiftcolor16(const struct util_color_component *comp,
92                                     uint64_t value)
93 {
94         value &= 0xffff;
95         /* Shift down to remove unwanted low bits */
96         value = value >> (16 - comp->length);
97         /* Shift back up to where the value should be */
98         return value << comp->offset;
99 }
100
101 #define MAKE_RGBA10(rgb, r, g, b, a) \
102         (shiftcolor10(&(rgb)->red, (r)) | \
103          shiftcolor10(&(rgb)->green, (g)) | \
104          shiftcolor10(&(rgb)->blue, (b)) | \
105          shiftcolor10(&(rgb)->alpha, (a)))
106
107 #define MAKE_RGBA(rgb, r, g, b, a) \
108         (shiftcolor8(&(rgb)->red, (r)) | \
109          shiftcolor8(&(rgb)->green, (g)) | \
110          shiftcolor8(&(rgb)->blue, (b)) | \
111          shiftcolor8(&(rgb)->alpha, (a)))
112
113 #define MAKE_RGB24(rgb, r, g, b) \
114         { .value = MAKE_RGBA(rgb, r, g, b, 0) }
115
116
117 /**
118   * Takes a uint16_t, divides by 65536, converts the infinite-precision
119   * result to fp16 with round-to-zero.
120   *
121   * Copied from mesa:src/util/half_float.c
122   */
123 static uint16_t uint16_div_64k_to_half(uint16_t v)
124 {
125         /* Zero or subnormal. Set the mantissa to (v << 8) and return. */
126         if (v < 4)
127                 return v << 8;
128
129         /* Count the leading 0s in the uint16_t */
130         int n = __builtin_clz(v) - 16;
131
132         /* Shift the mantissa up so bit 16 is the hidden 1 bit,
133          * mask it off, then shift back down to 10 bits
134          */
135         int m = ( ((uint32_t)v << (n + 1)) & 0xffff ) >> 6;
136
137         /*  (0{n} 1 X{15-n}) * 2^-16
138          * = 1.X * 2^(15-n-16)
139          * = 1.X * 2^(14-n - 15)
140          * which is the FP16 form with e = 14 - n
141          */
142         int e = 14 - n;
143
144         return (e << 10) | m;
145 }
146
147 #define MAKE_RGBA8FP16(rgb, r, g, b, a) \
148         (shiftcolor16(&(rgb)->red, uint16_div_64k_to_half((r) << 8)) | \
149          shiftcolor16(&(rgb)->green, uint16_div_64k_to_half((g) << 8)) | \
150          shiftcolor16(&(rgb)->blue, uint16_div_64k_to_half((b) << 8)) | \
151          shiftcolor16(&(rgb)->alpha, uint16_div_64k_to_half((a) << 8)))
152
153 #define MAKE_RGBA10FP16(rgb, r, g, b, a) \
154         (shiftcolor16(&(rgb)->red, uint16_div_64k_to_half((r) << 6)) | \
155          shiftcolor16(&(rgb)->green, uint16_div_64k_to_half((g) << 6)) | \
156          shiftcolor16(&(rgb)->blue, uint16_div_64k_to_half((b) << 6)) | \
157          shiftcolor16(&(rgb)->alpha, uint16_div_64k_to_half((a) << 6)))
158
159 static void fill_smpte_yuv_planar(const struct util_yuv_info *yuv,
160                                   unsigned char *y_mem, unsigned char *u_mem,
161                                   unsigned char *v_mem, unsigned int width,
162                                   unsigned int height, unsigned int stride)
163 {
164         const struct color_yuv colors_top[] = {
165                 MAKE_YUV_601(191, 192, 192),    /* grey */
166                 MAKE_YUV_601(192, 192, 0),      /* yellow */
167                 MAKE_YUV_601(0, 192, 192),      /* cyan */
168                 MAKE_YUV_601(0, 192, 0),        /* green */
169                 MAKE_YUV_601(192, 0, 192),      /* magenta */
170                 MAKE_YUV_601(192, 0, 0),        /* red */
171                 MAKE_YUV_601(0, 0, 192),        /* blue */
172         };
173         const struct color_yuv colors_middle[] = {
174                 MAKE_YUV_601(0, 0, 192),        /* blue */
175                 MAKE_YUV_601(19, 19, 19),       /* black */
176                 MAKE_YUV_601(192, 0, 192),      /* magenta */
177                 MAKE_YUV_601(19, 19, 19),       /* black */
178                 MAKE_YUV_601(0, 192, 192),      /* cyan */
179                 MAKE_YUV_601(19, 19, 19),       /* black */
180                 MAKE_YUV_601(192, 192, 192),    /* grey */
181         };
182         const struct color_yuv colors_bottom[] = {
183                 MAKE_YUV_601(0, 33, 76),        /* in-phase */
184                 MAKE_YUV_601(255, 255, 255),    /* super white */
185                 MAKE_YUV_601(50, 0, 106),       /* quadrature */
186                 MAKE_YUV_601(19, 19, 19),       /* black */
187                 MAKE_YUV_601(9, 9, 9),          /* 3.5% */
188                 MAKE_YUV_601(19, 19, 19),       /* 7.5% */
189                 MAKE_YUV_601(29, 29, 29),       /* 11.5% */
190                 MAKE_YUV_601(19, 19, 19),       /* black */
191         };
192         unsigned int cs = yuv->chroma_stride;
193         unsigned int xsub = yuv->xsub;
194         unsigned int ysub = yuv->ysub;
195         unsigned int x;
196         unsigned int y;
197
198         /* Luma */
199         for (y = 0; y < height * 6 / 9; ++y) {
200                 for (x = 0; x < width; ++x)
201                         y_mem[x] = colors_top[x * 7 / width].y;
202                 y_mem += stride;
203         }
204
205         for (; y < height * 7 / 9; ++y) {
206                 for (x = 0; x < width; ++x)
207                         y_mem[x] = colors_middle[x * 7 / width].y;
208                 y_mem += stride;
209         }
210
211         for (; y < height; ++y) {
212                 for (x = 0; x < width * 5 / 7; ++x)
213                         y_mem[x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
214                 for (; x < width * 6 / 7; ++x)
215                         y_mem[x] = colors_bottom[(x - width * 5 / 7) * 3
216                                                  / (width / 7) + 4].y;
217                 for (; x < width; ++x)
218                         y_mem[x] = colors_bottom[7].y;
219                 y_mem += stride;
220         }
221
222         /* Chroma */
223         for (y = 0; y < height / ysub * 6 / 9; ++y) {
224                 for (x = 0; x < width; x += xsub) {
225                         u_mem[x*cs/xsub] = colors_top[x * 7 / width].u;
226                         v_mem[x*cs/xsub] = colors_top[x * 7 / width].v;
227                 }
228                 u_mem += stride * cs / xsub;
229                 v_mem += stride * cs / xsub;
230         }
231
232         for (; y < height / ysub * 7 / 9; ++y) {
233                 for (x = 0; x < width; x += xsub) {
234                         u_mem[x*cs/xsub] = colors_middle[x * 7 / width].u;
235                         v_mem[x*cs/xsub] = colors_middle[x * 7 / width].v;
236                 }
237                 u_mem += stride * cs / xsub;
238                 v_mem += stride * cs / xsub;
239         }
240
241         for (; y < height / ysub; ++y) {
242                 for (x = 0; x < width * 5 / 7; x += xsub) {
243                         u_mem[x*cs/xsub] =
244                                 colors_bottom[x * 4 / (width * 5 / 7)].u;
245                         v_mem[x*cs/xsub] =
246                                 colors_bottom[x * 4 / (width * 5 / 7)].v;
247                 }
248                 for (; x < width * 6 / 7; x += xsub) {
249                         u_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
250                                                          3 / (width / 7) + 4].u;
251                         v_mem[x*cs/xsub] = colors_bottom[(x - width * 5 / 7) *
252                                                          3 / (width / 7) + 4].v;
253                 }
254                 for (; x < width; x += xsub) {
255                         u_mem[x*cs/xsub] = colors_bottom[7].u;
256                         v_mem[x*cs/xsub] = colors_bottom[7].v;
257                 }
258                 u_mem += stride * cs / xsub;
259                 v_mem += stride * cs / xsub;
260         }
261 }
262
263 static void fill_smpte_yuv_packed(const struct util_yuv_info *yuv, void *mem,
264                                   unsigned int width, unsigned int height,
265                                   unsigned int stride)
266 {
267         const struct color_yuv colors_top[] = {
268                 MAKE_YUV_601(191, 192, 192),    /* grey */
269                 MAKE_YUV_601(192, 192, 0),      /* yellow */
270                 MAKE_YUV_601(0, 192, 192),      /* cyan */
271                 MAKE_YUV_601(0, 192, 0),        /* green */
272                 MAKE_YUV_601(192, 0, 192),      /* magenta */
273                 MAKE_YUV_601(192, 0, 0),        /* red */
274                 MAKE_YUV_601(0, 0, 192),        /* blue */
275         };
276         const struct color_yuv colors_middle[] = {
277                 MAKE_YUV_601(0, 0, 192),        /* blue */
278                 MAKE_YUV_601(19, 19, 19),       /* black */
279                 MAKE_YUV_601(192, 0, 192),      /* magenta */
280                 MAKE_YUV_601(19, 19, 19),       /* black */
281                 MAKE_YUV_601(0, 192, 192),      /* cyan */
282                 MAKE_YUV_601(19, 19, 19),       /* black */
283                 MAKE_YUV_601(192, 192, 192),    /* grey */
284         };
285         const struct color_yuv colors_bottom[] = {
286                 MAKE_YUV_601(0, 33, 76),        /* in-phase */
287                 MAKE_YUV_601(255, 255, 255),    /* super white */
288                 MAKE_YUV_601(50, 0, 106),       /* quadrature */
289                 MAKE_YUV_601(19, 19, 19),       /* black */
290                 MAKE_YUV_601(9, 9, 9),          /* 3.5% */
291                 MAKE_YUV_601(19, 19, 19),       /* 7.5% */
292                 MAKE_YUV_601(29, 29, 29),       /* 11.5% */
293                 MAKE_YUV_601(19, 19, 19),       /* black */
294         };
295         unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
296         unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
297         unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
298         unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
299         unsigned int x;
300         unsigned int y;
301
302         /* Luma */
303         for (y = 0; y < height * 6 / 9; ++y) {
304                 for (x = 0; x < width; ++x)
305                         y_mem[2*x] = colors_top[x * 7 / width].y;
306                 y_mem += stride;
307         }
308
309         for (; y < height * 7 / 9; ++y) {
310                 for (x = 0; x < width; ++x)
311                         y_mem[2*x] = colors_middle[x * 7 / width].y;
312                 y_mem += stride;
313         }
314
315         for (; y < height; ++y) {
316                 for (x = 0; x < width * 5 / 7; ++x)
317                         y_mem[2*x] = colors_bottom[x * 4 / (width * 5 / 7)].y;
318                 for (; x < width * 6 / 7; ++x)
319                         y_mem[2*x] = colors_bottom[(x - width * 5 / 7) * 3
320                                                    / (width / 7) + 4].y;
321                 for (; x < width; ++x)
322                         y_mem[2*x] = colors_bottom[7].y;
323                 y_mem += stride;
324         }
325
326         /* Chroma */
327         for (y = 0; y < height * 6 / 9; ++y) {
328                 for (x = 0; x < width; x += 2) {
329                         c_mem[2*x+u] = colors_top[x * 7 / width].u;
330                         c_mem[2*x+v] = colors_top[x * 7 / width].v;
331                 }
332                 c_mem += stride;
333         }
334
335         for (; y < height * 7 / 9; ++y) {
336                 for (x = 0; x < width; x += 2) {
337                         c_mem[2*x+u] = colors_middle[x * 7 / width].u;
338                         c_mem[2*x+v] = colors_middle[x * 7 / width].v;
339                 }
340                 c_mem += stride;
341         }
342
343         for (; y < height; ++y) {
344                 for (x = 0; x < width * 5 / 7; x += 2) {
345                         c_mem[2*x+u] = colors_bottom[x * 4 / (width * 5 / 7)].u;
346                         c_mem[2*x+v] = colors_bottom[x * 4 / (width * 5 / 7)].v;
347                 }
348                 for (; x < width * 6 / 7; x += 2) {
349                         c_mem[2*x+u] = colors_bottom[(x - width * 5 / 7) *
350                                                      3 / (width / 7) + 4].u;
351                         c_mem[2*x+v] = colors_bottom[(x - width * 5 / 7) *
352                                                      3 / (width / 7) + 4].v;
353                 }
354                 for (; x < width; x += 2) {
355                         c_mem[2*x+u] = colors_bottom[7].u;
356                         c_mem[2*x+v] = colors_bottom[7].v;
357                 }
358                 c_mem += stride;
359         }
360 }
361
362 static void fill_smpte_rgb16(const struct util_rgb_info *rgb, void *mem,
363                              unsigned int width, unsigned int height,
364                              unsigned int stride)
365 {
366         const uint16_t colors_top[] = {
367                 MAKE_RGBA(rgb, 192, 192, 192, 255),     /* grey */
368                 MAKE_RGBA(rgb, 192, 192, 0, 255),       /* yellow */
369                 MAKE_RGBA(rgb, 0, 192, 192, 255),       /* cyan */
370                 MAKE_RGBA(rgb, 0, 192, 0, 255),         /* green */
371                 MAKE_RGBA(rgb, 192, 0, 192, 255),       /* magenta */
372                 MAKE_RGBA(rgb, 192, 0, 0, 255),         /* red */
373                 MAKE_RGBA(rgb, 0, 0, 192, 255),         /* blue */
374         };
375         const uint16_t colors_middle[] = {
376                 MAKE_RGBA(rgb, 0, 0, 192, 127),         /* blue */
377                 MAKE_RGBA(rgb, 19, 19, 19, 127),        /* black */
378                 MAKE_RGBA(rgb, 192, 0, 192, 127),       /* magenta */
379                 MAKE_RGBA(rgb, 19, 19, 19, 127),        /* black */
380                 MAKE_RGBA(rgb, 0, 192, 192, 127),       /* cyan */
381                 MAKE_RGBA(rgb, 19, 19, 19, 127),        /* black */
382                 MAKE_RGBA(rgb, 192, 192, 192, 127),     /* grey */
383         };
384         const uint16_t colors_bottom[] = {
385                 MAKE_RGBA(rgb, 0, 33, 76, 255),         /* in-phase */
386                 MAKE_RGBA(rgb, 255, 255, 255, 255),     /* super white */
387                 MAKE_RGBA(rgb, 50, 0, 106, 255),        /* quadrature */
388                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
389                 MAKE_RGBA(rgb, 9, 9, 9, 255),           /* 3.5% */
390                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* 7.5% */
391                 MAKE_RGBA(rgb, 29, 29, 29, 255),        /* 11.5% */
392                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
393         };
394         unsigned int x;
395         unsigned int y;
396
397         for (y = 0; y < height * 6 / 9; ++y) {
398                 for (x = 0; x < width; ++x)
399                         ((uint16_t *)mem)[x] = colors_top[x * 7 / width];
400                 mem += stride;
401         }
402
403         for (; y < height * 7 / 9; ++y) {
404                 for (x = 0; x < width; ++x)
405                         ((uint16_t *)mem)[x] = colors_middle[x * 7 / width];
406                 mem += stride;
407         }
408
409         for (; y < height; ++y) {
410                 for (x = 0; x < width * 5 / 7; ++x)
411                         ((uint16_t *)mem)[x] =
412                                 colors_bottom[x * 4 / (width * 5 / 7)];
413                 for (; x < width * 6 / 7; ++x)
414                         ((uint16_t *)mem)[x] =
415                                 colors_bottom[(x - width * 5 / 7) * 3
416                                               / (width / 7) + 4];
417                 for (; x < width; ++x)
418                         ((uint16_t *)mem)[x] = colors_bottom[7];
419                 mem += stride;
420         }
421 }
422
423 static void fill_smpte_rgb24(const struct util_rgb_info *rgb, void *mem,
424                              unsigned int width, unsigned int height,
425                              unsigned int stride)
426 {
427         const struct color_rgb24 colors_top[] = {
428                 MAKE_RGB24(rgb, 192, 192, 192), /* grey */
429                 MAKE_RGB24(rgb, 192, 192, 0),   /* yellow */
430                 MAKE_RGB24(rgb, 0, 192, 192),   /* cyan */
431                 MAKE_RGB24(rgb, 0, 192, 0),     /* green */
432                 MAKE_RGB24(rgb, 192, 0, 192),   /* magenta */
433                 MAKE_RGB24(rgb, 192, 0, 0),     /* red */
434                 MAKE_RGB24(rgb, 0, 0, 192),     /* blue */
435         };
436         const struct color_rgb24 colors_middle[] = {
437                 MAKE_RGB24(rgb, 0, 0, 192),     /* blue */
438                 MAKE_RGB24(rgb, 19, 19, 19),    /* black */
439                 MAKE_RGB24(rgb, 192, 0, 192),   /* magenta */
440                 MAKE_RGB24(rgb, 19, 19, 19),    /* black */
441                 MAKE_RGB24(rgb, 0, 192, 192),   /* cyan */
442                 MAKE_RGB24(rgb, 19, 19, 19),    /* black */
443                 MAKE_RGB24(rgb, 192, 192, 192), /* grey */
444         };
445         const struct color_rgb24 colors_bottom[] = {
446                 MAKE_RGB24(rgb, 0, 33, 76),     /* in-phase */
447                 MAKE_RGB24(rgb, 255, 255, 255), /* super white */
448                 MAKE_RGB24(rgb, 50, 0, 106),    /* quadrature */
449                 MAKE_RGB24(rgb, 19, 19, 19),    /* black */
450                 MAKE_RGB24(rgb, 9, 9, 9),       /* 3.5% */
451                 MAKE_RGB24(rgb, 19, 19, 19),    /* 7.5% */
452                 MAKE_RGB24(rgb, 29, 29, 29),    /* 11.5% */
453                 MAKE_RGB24(rgb, 19, 19, 19),    /* black */
454         };
455         unsigned int x;
456         unsigned int y;
457
458         for (y = 0; y < height * 6 / 9; ++y) {
459                 for (x = 0; x < width; ++x)
460                         ((struct color_rgb24 *)mem)[x] =
461                                 colors_top[x * 7 / width];
462                 mem += stride;
463         }
464
465         for (; y < height * 7 / 9; ++y) {
466                 for (x = 0; x < width; ++x)
467                         ((struct color_rgb24 *)mem)[x] =
468                                 colors_middle[x * 7 / width];
469                 mem += stride;
470         }
471
472         for (; y < height; ++y) {
473                 for (x = 0; x < width * 5 / 7; ++x)
474                         ((struct color_rgb24 *)mem)[x] =
475                                 colors_bottom[x * 4 / (width * 5 / 7)];
476                 for (; x < width * 6 / 7; ++x)
477                         ((struct color_rgb24 *)mem)[x] =
478                                 colors_bottom[(x - width * 5 / 7) * 3
479                                               / (width / 7) + 4];
480                 for (; x < width; ++x)
481                         ((struct color_rgb24 *)mem)[x] = colors_bottom[7];
482                 mem += stride;
483         }
484 }
485
486 static void fill_smpte_rgb32(const struct util_rgb_info *rgb, void *mem,
487                              unsigned int width, unsigned int height,
488                              unsigned int stride)
489 {
490         const uint32_t colors_top[] = {
491                 MAKE_RGBA(rgb, 192, 192, 192, 255),     /* grey */
492                 MAKE_RGBA(rgb, 192, 192, 0, 255),       /* yellow */
493                 MAKE_RGBA(rgb, 0, 192, 192, 255),       /* cyan */
494                 MAKE_RGBA(rgb, 0, 192, 0, 255),         /* green */
495                 MAKE_RGBA(rgb, 192, 0, 192, 255),       /* magenta */
496                 MAKE_RGBA(rgb, 192, 0, 0, 255),         /* red */
497                 MAKE_RGBA(rgb, 0, 0, 192, 255),         /* blue */
498         };
499         const uint32_t colors_middle[] = {
500                 MAKE_RGBA(rgb, 0, 0, 192, 127),         /* blue */
501                 MAKE_RGBA(rgb, 19, 19, 19, 127),        /* black */
502                 MAKE_RGBA(rgb, 192, 0, 192, 127),       /* magenta */
503                 MAKE_RGBA(rgb, 19, 19, 19, 127),        /* black */
504                 MAKE_RGBA(rgb, 0, 192, 192, 127),       /* cyan */
505                 MAKE_RGBA(rgb, 19, 19, 19, 127),        /* black */
506                 MAKE_RGBA(rgb, 192, 192, 192, 127),     /* grey */
507         };
508         const uint32_t colors_bottom[] = {
509                 MAKE_RGBA(rgb, 0, 33, 76, 255),         /* in-phase */
510                 MAKE_RGBA(rgb, 255, 255, 255, 255),     /* super white */
511                 MAKE_RGBA(rgb, 50, 0, 106, 255),        /* quadrature */
512                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
513                 MAKE_RGBA(rgb, 9, 9, 9, 255),           /* 3.5% */
514                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* 7.5% */
515                 MAKE_RGBA(rgb, 29, 29, 29, 255),        /* 11.5% */
516                 MAKE_RGBA(rgb, 19, 19, 19, 255),        /* black */
517         };
518         unsigned int x;
519         unsigned int y;
520
521         for (y = 0; y < height * 6 / 9; ++y) {
522                 for (x = 0; x < width; ++x)
523                         ((uint32_t *)mem)[x] = colors_top[x * 7 / width];
524                 mem += stride;
525         }
526
527         for (; y < height * 7 / 9; ++y) {
528                 for (x = 0; x < width; ++x)
529                         ((uint32_t *)mem)[x] = colors_middle[x * 7 / width];
530                 mem += stride;
531         }
532
533         for (; y < height; ++y) {
534                 for (x = 0; x < width * 5 / 7; ++x)
535                         ((uint32_t *)mem)[x] =
536                                 colors_bottom[x * 4 / (width * 5 / 7)];
537                 for (; x < width * 6 / 7; ++x)
538                         ((uint32_t *)mem)[x] =
539                                 colors_bottom[(x - width * 5 / 7) * 3
540                                               / (width / 7) + 4];
541                 for (; x < width; ++x)
542                         ((uint32_t *)mem)[x] = colors_bottom[7];
543                 mem += stride;
544         }
545 }
546
547 static void fill_smpte_rgb16fp(const struct util_rgb_info *rgb, void *mem,
548                                unsigned int width, unsigned int height,
549                                unsigned int stride)
550 {
551         const uint64_t colors_top[] = {
552                 MAKE_RGBA8FP16(rgb, 192, 192, 192, 255),/* grey */
553                 MAKE_RGBA8FP16(rgb, 192, 192, 0, 255),  /* yellow */
554                 MAKE_RGBA8FP16(rgb, 0, 192, 192, 255),  /* cyan */
555                 MAKE_RGBA8FP16(rgb, 0, 192, 0, 255),    /* green */
556                 MAKE_RGBA8FP16(rgb, 192, 0, 192, 255),  /* magenta */
557                 MAKE_RGBA8FP16(rgb, 192, 0, 0, 255),    /* red */
558                 MAKE_RGBA8FP16(rgb, 0, 0, 192, 255),    /* blue */
559         };
560         const uint64_t colors_middle[] = {
561                 MAKE_RGBA8FP16(rgb, 0, 0, 192, 127),    /* blue */
562                 MAKE_RGBA8FP16(rgb, 19, 19, 19, 127),   /* black */
563                 MAKE_RGBA8FP16(rgb, 192, 0, 192, 127),  /* magenta */
564                 MAKE_RGBA8FP16(rgb, 19, 19, 19, 127),   /* black */
565                 MAKE_RGBA8FP16(rgb, 0, 192, 192, 127),  /* cyan */
566                 MAKE_RGBA8FP16(rgb, 19, 19, 19, 127),   /* black */
567                 MAKE_RGBA8FP16(rgb, 192, 192, 192, 127),/* grey */
568         };
569         const uint64_t colors_bottom[] = {
570                 MAKE_RGBA8FP16(rgb, 0, 33, 76, 255),    /* in-phase */
571                 MAKE_RGBA8FP16(rgb, 255, 255, 255, 255),/* super white */
572                 MAKE_RGBA8FP16(rgb, 50, 0, 106, 255),   /* quadrature */
573                 MAKE_RGBA8FP16(rgb, 19, 19, 19, 255),   /* black */
574                 MAKE_RGBA8FP16(rgb, 9, 9, 9, 255),      /* 3.5% */
575                 MAKE_RGBA8FP16(rgb, 19, 19, 19, 255),   /* 7.5% */
576                 MAKE_RGBA8FP16(rgb, 29, 29, 29, 255),   /* 11.5% */
577                 MAKE_RGBA8FP16(rgb, 19, 19, 19, 255),   /* black */
578         };
579         unsigned int x;
580         unsigned int y;
581
582         for (y = 0; y < height * 6 / 9; ++y) {
583                 for (x = 0; x < width; ++x)
584                         ((uint64_t *)mem)[x] = colors_top[x * 7 / width];
585                 mem += stride;
586         }
587
588         for (; y < height * 7 / 9; ++y) {
589                 for (x = 0; x < width; ++x)
590                         ((uint64_t *)mem)[x] = colors_middle[x * 7 / width];
591                 mem += stride;
592         }
593
594         for (; y < height; ++y) {
595                 for (x = 0; x < width * 5 / 7; ++x)
596                         ((uint64_t *)mem)[x] =
597                                 colors_bottom[x * 4 / (width * 5 / 7)];
598                 for (; x < width * 6 / 7; ++x)
599                         ((uint64_t *)mem)[x] =
600                                 colors_bottom[(x - width * 5 / 7) * 3
601                                               / (width / 7) + 4];
602                 for (; x < width; ++x)
603                         ((uint64_t *)mem)[x] = colors_bottom[7];
604                 mem += stride;
605         }
606 }
607
608 static void fill_smpte_c8(void *mem, unsigned int width, unsigned int height,
609                           unsigned int stride)
610 {
611         unsigned int x;
612         unsigned int y;
613
614         for (y = 0; y < height * 6 / 9; ++y) {
615                 for (x = 0; x < width; ++x)
616                         ((uint8_t *)mem)[x] = x * 7 / width;
617                 mem += stride;
618         }
619
620         for (; y < height * 7 / 9; ++y) {
621                 for (x = 0; x < width; ++x)
622                         ((uint8_t *)mem)[x] = 7 + (x * 7 / width);
623                 mem += stride;
624         }
625
626         for (; y < height; ++y) {
627                 for (x = 0; x < width * 5 / 7; ++x)
628                         ((uint8_t *)mem)[x] =
629                                 14 + (x * 4 / (width * 5 / 7));
630                 for (; x < width * 6 / 7; ++x)
631                         ((uint8_t *)mem)[x] =
632                                 14 + ((x - width * 5 / 7) * 3
633                                               / (width / 7) + 4);
634                 for (; x < width; ++x)
635                         ((uint8_t *)mem)[x] = 14 + 7;
636                 mem += stride;
637         }
638 }
639
640 void util_smpte_c8_gamma(unsigned size, struct drm_color_lut *lut)
641 {
642         if (size < 7 + 7 + 8) {
643                 printf("Error: gamma too small: %d < %d\n", size, 7 + 7 + 8);
644                 return;
645         }
646         memset(lut, 0, size * sizeof(struct drm_color_lut));
647
648 #define FILL_COLOR(idx, r, g, b) \
649         lut[idx].red = (r) << 8; \
650         lut[idx].green = (g) << 8; \
651         lut[idx].blue = (b) << 8
652
653         FILL_COLOR( 0, 192, 192, 192);  /* grey */
654         FILL_COLOR( 1, 192, 192, 0  );  /* yellow */
655         FILL_COLOR( 2, 0,   192, 192);  /* cyan */
656         FILL_COLOR( 3, 0,   192, 0  );  /* green */
657         FILL_COLOR( 4, 192, 0,   192);  /* magenta */
658         FILL_COLOR( 5, 192, 0,   0  );  /* red */
659         FILL_COLOR( 6, 0,   0,   192);  /* blue */
660
661         FILL_COLOR( 7, 0,   0,   192);  /* blue */
662         FILL_COLOR( 8, 19,  19,  19 );  /* black */
663         FILL_COLOR( 9, 192, 0,   192);  /* magenta */
664         FILL_COLOR(10, 19,  19,  19 );  /* black */
665         FILL_COLOR(11, 0,   192, 192);  /* cyan */
666         FILL_COLOR(12, 19,  19,  19 );  /* black */
667         FILL_COLOR(13, 192, 192, 192);  /* grey */
668
669         FILL_COLOR(14, 0,   33,  76);   /* in-phase */
670         FILL_COLOR(15, 255, 255, 255);  /* super white */
671         FILL_COLOR(16, 50,  0,   106);  /* quadrature */
672         FILL_COLOR(17, 19,  19,  19);   /* black */
673         FILL_COLOR(18, 9,   9,   9);    /* 3.5% */
674         FILL_COLOR(19, 19,  19,  19);   /* 7.5% */
675         FILL_COLOR(20, 29,  29,  29);   /* 11.5% */
676         FILL_COLOR(21, 19,  19,  19);   /* black */
677
678 #undef FILL_COLOR
679 }
680
681 static void fill_smpte(const struct util_format_info *info, void *planes[3],
682                        unsigned int width, unsigned int height,
683                        unsigned int stride)
684 {
685         unsigned char *u, *v;
686
687         switch (info->format) {
688         case DRM_FORMAT_C8:
689                 return fill_smpte_c8(planes[0], width, height, stride);
690         case DRM_FORMAT_UYVY:
691         case DRM_FORMAT_VYUY:
692         case DRM_FORMAT_YUYV:
693         case DRM_FORMAT_YVYU:
694                 return fill_smpte_yuv_packed(&info->yuv, planes[0], width,
695                                              height, stride);
696
697         case DRM_FORMAT_NV12:
698         case DRM_FORMAT_NV21:
699         case DRM_FORMAT_NV16:
700         case DRM_FORMAT_NV61:
701                 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
702                 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
703                 return fill_smpte_yuv_planar(&info->yuv, planes[0], u, v,
704                                              width, height, stride);
705
706         case DRM_FORMAT_YUV420:
707                 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[1],
708                                              planes[2], width, height, stride);
709
710         case DRM_FORMAT_YVU420:
711                 return fill_smpte_yuv_planar(&info->yuv, planes[0], planes[2],
712                                              planes[1], width, height, stride);
713
714         case DRM_FORMAT_ARGB4444:
715         case DRM_FORMAT_XRGB4444:
716         case DRM_FORMAT_ABGR4444:
717         case DRM_FORMAT_XBGR4444:
718         case DRM_FORMAT_RGBA4444:
719         case DRM_FORMAT_RGBX4444:
720         case DRM_FORMAT_BGRA4444:
721         case DRM_FORMAT_BGRX4444:
722         case DRM_FORMAT_RGB565:
723         case DRM_FORMAT_BGR565:
724         case DRM_FORMAT_ARGB1555:
725         case DRM_FORMAT_XRGB1555:
726         case DRM_FORMAT_ABGR1555:
727         case DRM_FORMAT_XBGR1555:
728         case DRM_FORMAT_RGBA5551:
729         case DRM_FORMAT_RGBX5551:
730         case DRM_FORMAT_BGRA5551:
731         case DRM_FORMAT_BGRX5551:
732                 return fill_smpte_rgb16(&info->rgb, planes[0],
733                                         width, height, stride);
734
735         case DRM_FORMAT_BGR888:
736         case DRM_FORMAT_RGB888:
737                 return fill_smpte_rgb24(&info->rgb, planes[0],
738                                         width, height, stride);
739         case DRM_FORMAT_ARGB8888:
740         case DRM_FORMAT_XRGB8888:
741         case DRM_FORMAT_ABGR8888:
742         case DRM_FORMAT_XBGR8888:
743         case DRM_FORMAT_RGBA8888:
744         case DRM_FORMAT_RGBX8888:
745         case DRM_FORMAT_BGRA8888:
746         case DRM_FORMAT_BGRX8888:
747         case DRM_FORMAT_ARGB2101010:
748         case DRM_FORMAT_XRGB2101010:
749         case DRM_FORMAT_ABGR2101010:
750         case DRM_FORMAT_XBGR2101010:
751         case DRM_FORMAT_RGBA1010102:
752         case DRM_FORMAT_RGBX1010102:
753         case DRM_FORMAT_BGRA1010102:
754         case DRM_FORMAT_BGRX1010102:
755                 return fill_smpte_rgb32(&info->rgb, planes[0],
756                                         width, height, stride);
757
758         case DRM_FORMAT_XRGB16161616F:
759         case DRM_FORMAT_XBGR16161616F:
760         case DRM_FORMAT_ARGB16161616F:
761         case DRM_FORMAT_ABGR16161616F:
762                 return fill_smpte_rgb16fp(&info->rgb, planes[0],
763                                           width, height, stride);
764         }
765 }
766
767 /* swap these for big endian.. */
768 #define RED   2
769 #define GREEN 1
770 #define BLUE  0
771
772 static void make_pwetty(void *data, unsigned int width, unsigned int height,
773                         unsigned int stride, uint32_t format)
774 {
775 #if HAVE_CAIRO
776         cairo_surface_t *surface;
777         cairo_t *cr;
778         cairo_format_t cairo_format;
779
780         /* we can ignore the order of R,G,B channels */
781         switch (format) {
782         case DRM_FORMAT_XRGB8888:
783         case DRM_FORMAT_ARGB8888:
784         case DRM_FORMAT_XBGR8888:
785         case DRM_FORMAT_ABGR8888:
786                 cairo_format = CAIRO_FORMAT_ARGB32;
787                 break;
788         case DRM_FORMAT_RGB565:
789         case DRM_FORMAT_BGR565:
790                 cairo_format = CAIRO_FORMAT_RGB16_565;
791                 break;
792 #if CAIRO_VERSION_MAJOR > 1 || (CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR >= 12)
793         case DRM_FORMAT_ARGB2101010:
794         case DRM_FORMAT_XRGB2101010:
795         case DRM_FORMAT_ABGR2101010:
796         case DRM_FORMAT_XBGR2101010:
797                 cairo_format = CAIRO_FORMAT_RGB30;
798                 break;
799 #endif
800         default:
801                 return;
802         }
803
804         surface = cairo_image_surface_create_for_data(data,
805                                                       cairo_format,
806                                                       width, height,
807                                                       stride);
808         cr = cairo_create(surface);
809         cairo_surface_destroy(surface);
810
811         cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
812         for (unsigned x = 0; x < width; x += 250)
813                 for (unsigned y = 0; y < height; y += 250) {
814                         char buf[64];
815
816                         cairo_move_to(cr, x, y - 20);
817                         cairo_line_to(cr, x, y + 20);
818                         cairo_move_to(cr, x - 20, y);
819                         cairo_line_to(cr, x + 20, y);
820                         cairo_new_sub_path(cr);
821                         cairo_arc(cr, x, y, 10, 0, M_PI * 2);
822                         cairo_set_line_width(cr, 4);
823                         cairo_set_source_rgb(cr, 0, 0, 0);
824                         cairo_stroke_preserve(cr);
825                         cairo_set_source_rgb(cr, 1, 1, 1);
826                         cairo_set_line_width(cr, 2);
827                         cairo_stroke(cr);
828
829                         snprintf(buf, sizeof buf, "%d, %d", x, y);
830                         cairo_move_to(cr, x + 20, y + 20);
831                         cairo_text_path(cr, buf);
832                         cairo_set_source_rgb(cr, 0, 0, 0);
833                         cairo_stroke_preserve(cr);
834                         cairo_set_source_rgb(cr, 1, 1, 1);
835                         cairo_fill(cr);
836                 }
837
838         cairo_destroy(cr);
839 #endif
840 }
841
842 static void fill_tiles_yuv_planar(const struct util_format_info *info,
843                                   unsigned char *y_mem, unsigned char *u_mem,
844                                   unsigned char *v_mem, unsigned int width,
845                                   unsigned int height, unsigned int stride)
846 {
847         const struct util_yuv_info *yuv = &info->yuv;
848         unsigned int cs = yuv->chroma_stride;
849         unsigned int xsub = yuv->xsub;
850         unsigned int ysub = yuv->ysub;
851         unsigned int x;
852         unsigned int y;
853
854         for (y = 0; y < height; ++y) {
855                 for (x = 0; x < width; ++x) {
856                         div_t d = div(x+y, width);
857                         uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
858                                        + 0x000a1120 * (d.rem >> 6);
859                         struct color_yuv color =
860                                 MAKE_YUV_601((rgb32 >> 16) & 0xff,
861                                              (rgb32 >> 8) & 0xff, rgb32 & 0xff);
862
863                         y_mem[x] = color.y;
864                         u_mem[x/xsub*cs] = color.u;
865                         v_mem[x/xsub*cs] = color.v;
866                 }
867
868                 y_mem += stride;
869                 if ((y + 1) % ysub == 0) {
870                         u_mem += stride * cs / xsub;
871                         v_mem += stride * cs / xsub;
872                 }
873         }
874 }
875
876 static void fill_tiles_yuv_packed(const struct util_format_info *info,
877                                   void *mem, unsigned int width,
878                                   unsigned int height, unsigned int stride)
879 {
880         const struct util_yuv_info *yuv = &info->yuv;
881         unsigned char *y_mem = (yuv->order & YUV_YC) ? mem : mem + 1;
882         unsigned char *c_mem = (yuv->order & YUV_CY) ? mem : mem + 1;
883         unsigned int u = (yuv->order & YUV_YCrCb) ? 2 : 0;
884         unsigned int v = (yuv->order & YUV_YCbCr) ? 2 : 0;
885         unsigned int x;
886         unsigned int y;
887
888         for (y = 0; y < height; ++y) {
889                 for (x = 0; x < width; x += 2) {
890                         div_t d = div(x+y, width);
891                         uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
892                                        + 0x000a1120 * (d.rem >> 6);
893                         struct color_yuv color =
894                                 MAKE_YUV_601((rgb32 >> 16) & 0xff,
895                                              (rgb32 >> 8) & 0xff, rgb32 & 0xff);
896
897                         y_mem[2*x] = color.y;
898                         c_mem[2*x+u] = color.u;
899                         y_mem[2*x+2] = color.y;
900                         c_mem[2*x+v] = color.v;
901                 }
902
903                 y_mem += stride;
904                 c_mem += stride;
905         }
906 }
907
908 static void fill_tiles_rgb16(const struct util_format_info *info, void *mem,
909                              unsigned int width, unsigned int height,
910                              unsigned int stride)
911 {
912         const struct util_rgb_info *rgb = &info->rgb;
913         void *mem_base = mem;
914         unsigned int x, y;
915
916         for (y = 0; y < height; ++y) {
917                 for (x = 0; x < width; ++x) {
918                         div_t d = div(x+y, width);
919                         uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
920                                        + 0x000a1120 * (d.rem >> 6);
921                         uint16_t color =
922                                 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
923                                           (rgb32 >> 8) & 0xff, rgb32 & 0xff,
924                                           255);
925
926                         ((uint16_t *)mem)[x] = color;
927                 }
928                 mem += stride;
929         }
930
931         make_pwetty(mem_base, width, height, stride, info->format);
932 }
933
934 static void fill_tiles_rgb24(const struct util_format_info *info, void *mem,
935                              unsigned int width, unsigned int height,
936                              unsigned int stride)
937 {
938         const struct util_rgb_info *rgb = &info->rgb;
939         unsigned int x, y;
940
941         for (y = 0; y < height; ++y) {
942                 for (x = 0; x < width; ++x) {
943                         div_t d = div(x+y, width);
944                         uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
945                                        + 0x000a1120 * (d.rem >> 6);
946                         struct color_rgb24 color =
947                                 MAKE_RGB24(rgb, (rgb32 >> 16) & 0xff,
948                                            (rgb32 >> 8) & 0xff, rgb32 & 0xff);
949
950                         ((struct color_rgb24 *)mem)[x] = color;
951                 }
952                 mem += stride;
953         }
954 }
955
956 static void fill_tiles_rgb32(const struct util_format_info *info, void *mem,
957                              unsigned int width, unsigned int height,
958                              unsigned int stride)
959 {
960         const struct util_rgb_info *rgb = &info->rgb;
961         void *mem_base = mem;
962         unsigned int x, y;
963
964         for (y = 0; y < height; ++y) {
965                 for (x = 0; x < width; ++x) {
966                         div_t d = div(x+y, width);
967                         uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
968                                        + 0x000a1120 * (d.rem >> 6);
969                         uint32_t alpha = ((y < height/2) && (x < width/2)) ? 127 : 255;
970                         uint32_t color =
971                                 MAKE_RGBA(rgb, (rgb32 >> 16) & 0xff,
972                                           (rgb32 >> 8) & 0xff, rgb32 & 0xff,
973                                           alpha);
974
975                         ((uint32_t *)mem)[x] = color;
976                 }
977                 mem += stride;
978         }
979
980         make_pwetty(mem_base, width, height, stride, info->format);
981 }
982
983 static void fill_tiles_rgb16fp(const struct util_format_info *info, void *mem,
984                                unsigned int width, unsigned int height,
985                                unsigned int stride)
986 {
987         const struct util_rgb_info *rgb = &info->rgb;
988         unsigned int x, y;
989
990         /* TODO: Give this actual fp16 precision */
991         for (y = 0; y < height; ++y) {
992                 for (x = 0; x < width; ++x) {
993                         div_t d = div(x+y, width);
994                         uint32_t rgb32 = 0x00130502 * (d.quot >> 6)
995                                        + 0x000a1120 * (d.rem >> 6);
996                         uint32_t alpha = ((y < height/2) && (x < width/2)) ? 127 : 255;
997                         uint64_t color =
998                                 MAKE_RGBA8FP16(rgb, (rgb32 >> 16) & 0xff,
999                                                (rgb32 >> 8) & 0xff, rgb32 & 0xff,
1000                                                alpha);
1001
1002                         ((uint64_t *)mem)[x] = color;
1003                 }
1004                 mem += stride;
1005         }
1006 }
1007
1008 static void fill_tiles(const struct util_format_info *info, void *planes[3],
1009                        unsigned int width, unsigned int height,
1010                        unsigned int stride)
1011 {
1012         unsigned char *u, *v;
1013
1014         switch (info->format) {
1015         case DRM_FORMAT_UYVY:
1016         case DRM_FORMAT_VYUY:
1017         case DRM_FORMAT_YUYV:
1018         case DRM_FORMAT_YVYU:
1019                 return fill_tiles_yuv_packed(info, planes[0],
1020                                              width, height, stride);
1021
1022         case DRM_FORMAT_NV12:
1023         case DRM_FORMAT_NV21:
1024         case DRM_FORMAT_NV16:
1025         case DRM_FORMAT_NV61:
1026                 u = info->yuv.order & YUV_YCbCr ? planes[1] : planes[1] + 1;
1027                 v = info->yuv.order & YUV_YCrCb ? planes[1] : planes[1] + 1;
1028                 return fill_tiles_yuv_planar(info, planes[0], u, v,
1029                                              width, height, stride);
1030
1031         case DRM_FORMAT_YUV420:
1032                 return fill_tiles_yuv_planar(info, planes[0], planes[1],
1033                                              planes[2], width, height, stride);
1034
1035         case DRM_FORMAT_YVU420:
1036                 return fill_tiles_yuv_planar(info, planes[0], planes[2],
1037                                              planes[1], width, height, stride);
1038
1039         case DRM_FORMAT_ARGB4444:
1040         case DRM_FORMAT_XRGB4444:
1041         case DRM_FORMAT_ABGR4444:
1042         case DRM_FORMAT_XBGR4444:
1043         case DRM_FORMAT_RGBA4444:
1044         case DRM_FORMAT_RGBX4444:
1045         case DRM_FORMAT_BGRA4444:
1046         case DRM_FORMAT_BGRX4444:
1047         case DRM_FORMAT_RGB565:
1048         case DRM_FORMAT_BGR565:
1049         case DRM_FORMAT_ARGB1555:
1050         case DRM_FORMAT_XRGB1555:
1051         case DRM_FORMAT_ABGR1555:
1052         case DRM_FORMAT_XBGR1555:
1053         case DRM_FORMAT_RGBA5551:
1054         case DRM_FORMAT_RGBX5551:
1055         case DRM_FORMAT_BGRA5551:
1056         case DRM_FORMAT_BGRX5551:
1057                 return fill_tiles_rgb16(info, planes[0],
1058                                         width, height, stride);
1059
1060         case DRM_FORMAT_BGR888:
1061         case DRM_FORMAT_RGB888:
1062                 return fill_tiles_rgb24(info, planes[0],
1063                                         width, height, stride);
1064         case DRM_FORMAT_ARGB8888:
1065         case DRM_FORMAT_XRGB8888:
1066         case DRM_FORMAT_ABGR8888:
1067         case DRM_FORMAT_XBGR8888:
1068         case DRM_FORMAT_RGBA8888:
1069         case DRM_FORMAT_RGBX8888:
1070         case DRM_FORMAT_BGRA8888:
1071         case DRM_FORMAT_BGRX8888:
1072         case DRM_FORMAT_ARGB2101010:
1073         case DRM_FORMAT_XRGB2101010:
1074         case DRM_FORMAT_ABGR2101010:
1075         case DRM_FORMAT_XBGR2101010:
1076         case DRM_FORMAT_RGBA1010102:
1077         case DRM_FORMAT_RGBX1010102:
1078         case DRM_FORMAT_BGRA1010102:
1079         case DRM_FORMAT_BGRX1010102:
1080                 return fill_tiles_rgb32(info, planes[0],
1081                                         width, height, stride);
1082
1083         case DRM_FORMAT_XRGB16161616F:
1084         case DRM_FORMAT_XBGR16161616F:
1085         case DRM_FORMAT_ARGB16161616F:
1086         case DRM_FORMAT_ABGR16161616F:
1087                 return fill_tiles_rgb16fp(info, planes[0],
1088                                           width, height, stride);
1089         }
1090 }
1091
1092 static void fill_plain(const struct util_format_info *info, void *planes[3],
1093                        unsigned int height,
1094                        unsigned int stride)
1095 {
1096         switch (info->format) {
1097         case DRM_FORMAT_XRGB16161616F:
1098         case DRM_FORMAT_XBGR16161616F:
1099         case DRM_FORMAT_ARGB16161616F:
1100         case DRM_FORMAT_ABGR16161616F:
1101                 /* 0x3838 = 0.5273 */
1102                 memset(planes[0], 0x38, stride * height);
1103                 break;
1104         default:
1105                 memset(planes[0], 0x77, stride * height);
1106                 break;
1107         }
1108 }
1109
1110 static void fill_gradient_rgb32(const struct util_rgb_info *rgb,
1111                                 void *mem,
1112                                 unsigned int width, unsigned int height,
1113                                 unsigned int stride)
1114 {
1115         int i, j;
1116
1117         for (i = 0; i < height / 2; i++) {
1118                 uint32_t *row = mem;
1119
1120                 for (j = 0; j < width / 2; j++) {
1121                         uint32_t value = MAKE_RGBA10(rgb, j & 0x3ff, j & 0x3ff, j & 0x3ff, 0);
1122                         row[2*j] = row[2*j+1] = value;
1123                 }
1124                 mem += stride;
1125         }
1126
1127         for (; i < height; i++) {
1128                 uint32_t *row = mem;
1129
1130                 for (j = 0; j < width / 2; j++) {
1131                         uint32_t value = MAKE_RGBA10(rgb, j & 0x3fc, j & 0x3fc, j & 0x3fc, 0);
1132                         row[2*j] = row[2*j+1] = value;
1133                 }
1134                 mem += stride;
1135         }
1136 }
1137
1138 static void fill_gradient_rgb16fp(const struct util_rgb_info *rgb,
1139                                   void *mem,
1140                                   unsigned int width, unsigned int height,
1141                                   unsigned int stride)
1142 {
1143         int i, j;
1144
1145         for (i = 0; i < height / 2; i++) {
1146                 uint64_t *row = mem;
1147
1148                 for (j = 0; j < width / 2; j++) {
1149                         uint64_t value = MAKE_RGBA10FP16(rgb, j & 0x3ff, j & 0x3ff, j & 0x3ff, 0);
1150                         row[2*j] = row[2*j+1] = value;
1151                 }
1152                 mem += stride;
1153         }
1154
1155         for (; i < height; i++) {
1156                 uint64_t *row = mem;
1157
1158                 for (j = 0; j < width / 2; j++) {
1159                         uint64_t value = MAKE_RGBA10FP16(rgb, j & 0x3fc, j & 0x3fc, j & 0x3fc, 0);
1160                         row[2*j] = row[2*j+1] = value;
1161                 }
1162                 mem += stride;
1163         }
1164 }
1165
1166 /* The gradient pattern creates two horizontal gray gradients, split
1167  * into two halves. The top half has 10bpc precision, the bottom half
1168  * has 8bpc precision. When using with a 10bpc fb format, there are 3
1169  * possible outcomes:
1170  *
1171  *  - Pixel data is encoded as 8bpc to the display, no dithering. This
1172  *    would lead to the top and bottom halves looking identical.
1173  *
1174  *  - Pixel data is encoded as 8bpc to the display, with dithering. This
1175  *    would lead to there being a visible difference between the two halves,
1176  *    but the top half would look a little speck-y due to the dithering.
1177  *
1178  *  - Pixel data is encoded at 10bpc+ to the display (which implies
1179  *    the display is able to show this level of depth). This should
1180  *    lead to the top half being a very clean gradient, and visibly different
1181  *    from the bottom half.
1182  *
1183  * Once we support additional fb formats, this approach could be extended
1184  * to distinguish even higher bpc precisions.
1185  *
1186  * Note that due to practical size considerations, for the screens
1187  * where this matters, the pattern actually emits stripes 2-pixels
1188  * wide for each gradient color. Otherwise the difference may be a bit
1189  * hard to notice.
1190  */
1191 static void fill_gradient(const struct util_format_info *info, void *planes[3],
1192                           unsigned int width, unsigned int height,
1193                           unsigned int stride)
1194 {
1195         switch (info->format) {
1196         case DRM_FORMAT_ARGB8888:
1197         case DRM_FORMAT_XRGB8888:
1198         case DRM_FORMAT_ABGR8888:
1199         case DRM_FORMAT_XBGR8888:
1200         case DRM_FORMAT_RGBA8888:
1201         case DRM_FORMAT_RGBX8888:
1202         case DRM_FORMAT_BGRA8888:
1203         case DRM_FORMAT_BGRX8888:
1204         case DRM_FORMAT_ARGB2101010:
1205         case DRM_FORMAT_XRGB2101010:
1206         case DRM_FORMAT_ABGR2101010:
1207         case DRM_FORMAT_XBGR2101010:
1208         case DRM_FORMAT_RGBA1010102:
1209         case DRM_FORMAT_RGBX1010102:
1210         case DRM_FORMAT_BGRA1010102:
1211         case DRM_FORMAT_BGRX1010102:
1212                 return fill_gradient_rgb32(&info->rgb, planes[0],
1213                                            width, height, stride);
1214
1215         case DRM_FORMAT_XRGB16161616F:
1216         case DRM_FORMAT_XBGR16161616F:
1217         case DRM_FORMAT_ARGB16161616F:
1218         case DRM_FORMAT_ABGR16161616F:
1219                 return fill_gradient_rgb16fp(&info->rgb, planes[0],
1220                                              width, height, stride);
1221         }
1222 }
1223
1224 /*
1225  * util_fill_pattern - Fill a buffer with a test pattern
1226  * @format: Pixel format
1227  * @pattern: Test pattern
1228  * @planes: Array of buffers
1229  * @width: Width in pixels
1230  * @height: Height in pixels
1231  * @stride: Line stride (pitch) in bytes
1232  *
1233  * Fill the buffers with the test pattern specified by the pattern parameter.
1234  * Supported formats vary depending on the selected pattern.
1235  */
1236 void util_fill_pattern(uint32_t format, enum util_fill_pattern pattern,
1237                        void *planes[3], unsigned int width,
1238                        unsigned int height, unsigned int stride)
1239 {
1240         const struct util_format_info *info;
1241
1242         info = util_format_info_find(format);
1243         if (info == NULL)
1244                 return;
1245
1246         switch (pattern) {
1247         case UTIL_PATTERN_TILES:
1248                 return fill_tiles(info, planes, width, height, stride);
1249
1250         case UTIL_PATTERN_SMPTE:
1251                 return fill_smpte(info, planes, width, height, stride);
1252
1253         case UTIL_PATTERN_PLAIN:
1254                 return fill_plain(info, planes, height, stride);
1255
1256         case UTIL_PATTERN_GRADIENT:
1257                 return fill_gradient(info, planes, width, height, stride);
1258
1259         default:
1260                 printf("Error: unsupported test pattern %u.\n", pattern);
1261                 break;
1262         }
1263 }
1264
1265 static const char *pattern_names[] = {
1266         [UTIL_PATTERN_TILES] = "tiles",
1267         [UTIL_PATTERN_SMPTE] = "smpte",
1268         [UTIL_PATTERN_PLAIN] = "plain",
1269         [UTIL_PATTERN_GRADIENT] = "gradient",
1270 };
1271
1272 enum util_fill_pattern util_pattern_enum(const char *name)
1273 {
1274         unsigned int i;
1275
1276         for (i = 0; i < ARRAY_SIZE(pattern_names); i++)
1277                 if (!strcmp(pattern_names[i], name))
1278                         return (enum util_fill_pattern)i;
1279
1280         printf("Error: unsupported test pattern %s.\n", name);
1281         return UTIL_PATTERN_SMPTE;
1282 }