xref: /aosp_15_r20/external/mesa3d/src/util/format/u_format.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2010 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 /**
29  * @file
30  * Pixel format accessor functions.
31  *
32  * @author Jose Fonseca <[email protected]>
33  */
34 
35 #include "c11/threads.h"
36 #include "util/detect_arch.h"
37 #include "util/format/u_format.h"
38 #include "util/format/u_format_s3tc.h"
39 #include "util/u_math.h"
40 
41 /**
42  * Copy 2D rect from one place to another.
43  * Position and sizes are in pixels.
44  * src_stride may be negative to do vertical flip of pixels from source.
45  */
46 void
util_copy_rect(void * dst_in,enum pipe_format format,unsigned dst_stride,unsigned dst_x,unsigned dst_y,unsigned width,unsigned height,const void * src_in,int src_stride,unsigned src_x,unsigned src_y)47 util_copy_rect(void * dst_in,
48                enum pipe_format format,
49                unsigned dst_stride,
50                unsigned dst_x,
51                unsigned dst_y,
52                unsigned width,
53                unsigned height,
54                const void * src_in,
55                int src_stride,
56                unsigned src_x,
57                unsigned src_y)
58 {
59    uint8_t *dst = dst_in;
60    const uint8_t *src = src_in;
61    unsigned i;
62    int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
63    int blocksize = util_format_get_blocksize(format);
64    int blockwidth = util_format_get_blockwidth(format);
65    int blockheight = util_format_get_blockheight(format);
66 
67    assert(blocksize > 0);
68    assert(blockwidth > 0);
69    assert(blockheight > 0);
70 
71    dst_x /= blockwidth;
72    dst_y /= blockheight;
73    width = (width + blockwidth - 1)/blockwidth;
74    height = (height + blockheight - 1)/blockheight;
75    src_x /= blockwidth;
76    src_y /= blockheight;
77 
78    dst += dst_x * blocksize;
79    src += src_x * blocksize;
80    dst += dst_y * dst_stride;
81    src += src_y * src_stride_pos;
82    width *= blocksize;
83 
84    if (width == dst_stride && width == (unsigned)src_stride) {
85       uint64_t size = (uint64_t)height * width;
86 
87       assert(size <= SIZE_MAX);
88       memcpy(dst, src, size);
89    } else {
90       for (i = 0; i < height; i++) {
91          memcpy(dst, src, width);
92          dst += dst_stride;
93          src += src_stride;
94       }
95    }
96 }
97 
98 
99 bool
util_format_is_float(enum pipe_format format)100 util_format_is_float(enum pipe_format format)
101 {
102    const struct util_format_description *desc = util_format_description(format);
103    int i;
104 
105    i = util_format_get_first_non_void_channel(format);
106    if (i < 0) {
107       return false;
108    }
109 
110    return desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT ? true : false;
111 }
112 
113 
114 /** Test if the format contains RGB, but not alpha */
115 bool
util_format_has_alpha(enum pipe_format format)116 util_format_has_alpha(enum pipe_format format)
117 {
118    const struct util_format_description *desc =
119       util_format_description(format);
120 
121    return (desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
122            desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
123           desc->swizzle[3] != PIPE_SWIZZLE_1;
124 }
125 
126 /** Test if format has alpha as 1 (like RGBX) */
127 bool
util_format_has_alpha1(enum pipe_format format)128 util_format_has_alpha1(enum pipe_format format)
129 {
130    const struct util_format_description *desc =
131       util_format_description(format);
132 
133    return (desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
134            desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
135            desc->nr_channels == 4 &&
136            desc->swizzle[3] == PIPE_SWIZZLE_1;
137 }
138 
139 bool
util_format_is_luminance(enum pipe_format format)140 util_format_is_luminance(enum pipe_format format)
141 {
142    const struct util_format_description *desc =
143       util_format_description(format);
144 
145    if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
146         desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
147        desc->swizzle[0] == PIPE_SWIZZLE_X &&
148        desc->swizzle[1] == PIPE_SWIZZLE_X &&
149        desc->swizzle[2] == PIPE_SWIZZLE_X &&
150        desc->swizzle[3] == PIPE_SWIZZLE_1) {
151       return true;
152    }
153    return false;
154 }
155 
156 bool
util_format_is_alpha(enum pipe_format format)157 util_format_is_alpha(enum pipe_format format)
158 {
159    const struct util_format_description *desc =
160       util_format_description(format);
161 
162    if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
163         desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
164        desc->swizzle[0] == PIPE_SWIZZLE_0 &&
165        desc->swizzle[1] == PIPE_SWIZZLE_0 &&
166        desc->swizzle[2] == PIPE_SWIZZLE_0 &&
167        desc->swizzle[3] == PIPE_SWIZZLE_X) {
168       return true;
169    }
170    return false;
171 }
172 
173 bool
util_format_is_pure_integer(enum pipe_format format)174 util_format_is_pure_integer(enum pipe_format format)
175 {
176    const struct util_format_description *desc = util_format_description(format);
177    int i;
178 
179    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
180       if (util_format_has_depth(desc))
181          return false;
182 
183       assert(util_format_has_stencil(desc));
184       return true;
185    }
186 
187    /* Find the first non-void channel. */
188    i = util_format_get_first_non_void_channel(format);
189    if (i == -1)
190       return false;
191 
192    return desc->channel[i].pure_integer ? true : false;
193 }
194 
195 bool
util_format_is_pure_sint(enum pipe_format format)196 util_format_is_pure_sint(enum pipe_format format)
197 {
198    const struct util_format_description *desc = util_format_description(format);
199    int i;
200 
201    i = util_format_get_first_non_void_channel(format);
202    if (i == -1)
203       return false;
204 
205    return (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED && desc->channel[i].pure_integer) ? true : false;
206 }
207 
208 bool
util_format_is_pure_uint(enum pipe_format format)209 util_format_is_pure_uint(enum pipe_format format)
210 {
211    const struct util_format_description *desc = util_format_description(format);
212    int i;
213 
214    i = util_format_get_first_non_void_channel(format);
215    if (i == -1)
216       return false;
217 
218    return (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED && desc->channel[i].pure_integer) ? true : false;
219 }
220 
221 /**
222  * Returns true if the format contains normalized signed channels.
223  */
224 bool
util_format_is_snorm(enum pipe_format format)225 util_format_is_snorm(enum pipe_format format)
226 {
227    const struct util_format_description *desc = util_format_description(format);
228 
229    return desc->is_snorm;
230 }
231 
232 /**
233  * Returns true if the format contains normalized unsigned channels.
234  */
235 bool
util_format_is_unorm(enum pipe_format format)236 util_format_is_unorm(enum pipe_format format)
237 {
238    const struct util_format_description *desc = util_format_description(format);
239 
240    return desc->is_unorm;
241 }
242 
243 /**
244  * Returns true if the format contains scaled integer format channels.
245  */
246 bool
util_format_is_scaled(enum pipe_format format)247 util_format_is_scaled(enum pipe_format format)
248 {
249    const struct util_format_description *desc = util_format_description(format);
250    int i;
251 
252    /* format none is described as scaled but not for this check */
253    if (format == PIPE_FORMAT_NONE)
254       return false;
255 
256    /* Find the first non-void channel. */
257    i = util_format_get_first_non_void_channel(format);
258    if (i == -1)
259       return false;
260 
261    return !desc->channel[i].pure_integer && !desc->channel[i].normalized &&
262       (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED ||
263        desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED);
264 }
265 
266 bool
util_format_is_snorm8(enum pipe_format format)267 util_format_is_snorm8(enum pipe_format format)
268 {
269    const struct util_format_description *desc = util_format_description(format);
270    int i;
271 
272    if (desc->is_mixed)
273       return false;
274 
275    i = util_format_get_first_non_void_channel(format);
276    if (i == -1)
277       return false;
278 
279    return desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED &&
280           !desc->channel[i].pure_integer &&
281           desc->channel[i].normalized &&
282           desc->channel[i].size == 8;
283 }
284 
285 bool
util_format_is_luminance_alpha(enum pipe_format format)286 util_format_is_luminance_alpha(enum pipe_format format)
287 {
288    const struct util_format_description *desc =
289       util_format_description(format);
290 
291    if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
292         desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
293        desc->swizzle[0] == PIPE_SWIZZLE_X &&
294        desc->swizzle[1] == PIPE_SWIZZLE_X &&
295        desc->swizzle[2] == PIPE_SWIZZLE_X &&
296        desc->swizzle[3] == PIPE_SWIZZLE_Y) {
297       return true;
298    }
299    return false;
300 }
301 
302 bool
util_format_is_red_alpha(enum pipe_format format)303 util_format_is_red_alpha(enum pipe_format format)
304 {
305    const struct util_format_description *desc =
306       util_format_description(format);
307 
308    if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
309         desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
310        desc->swizzle[0] == PIPE_SWIZZLE_X &&
311        desc->swizzle[1] == PIPE_SWIZZLE_0 &&
312        desc->swizzle[2] == PIPE_SWIZZLE_0 &&
313        desc->swizzle[3] == PIPE_SWIZZLE_Y) {
314       return true;
315    }
316    return false;
317 }
318 
319 bool
util_format_is_red_green(enum pipe_format format)320 util_format_is_red_green(enum pipe_format format)
321 {
322    const struct util_format_description *desc =
323       util_format_description(format);
324 
325    if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
326         desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
327        desc->swizzle[0] == PIPE_SWIZZLE_X &&
328        desc->swizzle[1] == PIPE_SWIZZLE_Y &&
329        desc->swizzle[2] == PIPE_SWIZZLE_0 &&
330        desc->swizzle[3] == PIPE_SWIZZLE_1) {
331       return true;
332    }
333    return false;
334 }
335 
336 bool
util_format_is_intensity(enum pipe_format format)337 util_format_is_intensity(enum pipe_format format)
338 {
339    const struct util_format_description *desc =
340       util_format_description(format);
341 
342    if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
343         desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
344        desc->swizzle[0] == PIPE_SWIZZLE_X &&
345        desc->swizzle[1] == PIPE_SWIZZLE_X &&
346        desc->swizzle[2] == PIPE_SWIZZLE_X &&
347        desc->swizzle[3] == PIPE_SWIZZLE_X) {
348       return true;
349    }
350    return false;
351 }
352 
353 bool
util_format_is_subsampled_422(enum pipe_format format)354 util_format_is_subsampled_422(enum pipe_format format)
355 {
356    const struct util_format_description *desc =
357       util_format_description(format);
358 
359    return desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED &&
360       desc->block.width == 2 &&
361       desc->block.height == 1 &&
362       desc->block.bits == 32;
363 }
364 
365 /**
366  * Calculates the MRD for the depth format. MRD is used in depth bias
367  * for UNORM and unbound depth buffers. When the depth buffer is floating
368  * point, the depth bias calculation does not use the MRD. However, the
369  * default MRD will be 1.0 / ((1 << 24) - 1).
370  */
371 double
util_get_depth_format_mrd(const struct util_format_description * desc)372 util_get_depth_format_mrd(const struct util_format_description *desc)
373 {
374    /*
375     * Depth buffer formats without a depth component OR scenarios
376     * without a bound depth buffer default to D24.
377     */
378    double mrd = 1.0 / ((1 << 24) - 1);
379    unsigned depth_channel;
380 
381    /*
382     * Some depth formats do not store the depth component in the first
383     * channel, detect the format and adjust the depth channel. Get the
384     * swizzled depth component channel.
385     */
386    depth_channel = desc->swizzle[0];
387 
388    if (desc->channel[depth_channel].type == UTIL_FORMAT_TYPE_UNSIGNED &&
389        desc->channel[depth_channel].normalized) {
390       int depth_bits;
391 
392       depth_bits = desc->channel[depth_channel].size;
393       mrd = 1.0 / ((1ULL << depth_bits) - 1);
394    }
395 
396    return mrd;
397 }
398 
399 void
util_format_unpack_rgba_rect(enum pipe_format format,void * dst,unsigned dst_stride,const void * src,unsigned src_stride,unsigned w,unsigned h)400 util_format_unpack_rgba_rect(enum pipe_format format,
401                    void *dst, unsigned dst_stride,
402                    const void *src, unsigned src_stride,
403                    unsigned w, unsigned h)
404 {
405    const struct util_format_unpack_description *unpack =
406       util_format_unpack_description(format);
407 
408    /* Optimized function for block-compressed formats */
409    if (unpack->unpack_rgba_rect) {
410       unpack->unpack_rgba_rect(dst, dst_stride, src, src_stride, w, h);
411    } else {
412      for (unsigned y = 0; y < h; y++) {
413         unpack->unpack_rgba(dst, src, w);
414         src = (const char *)src + src_stride;
415         dst = (char *)dst + dst_stride;
416      }
417   }
418 }
419 
420 void
util_format_unpack_rgba_8unorm_rect(enum pipe_format format,void * dst,unsigned dst_stride,const void * src,unsigned src_stride,unsigned w,unsigned h)421 util_format_unpack_rgba_8unorm_rect(enum pipe_format format,
422                    void *dst, unsigned dst_stride,
423                    const void *src, unsigned src_stride,
424                    unsigned w, unsigned h)
425 {
426    const struct util_format_unpack_description *unpack =
427       util_format_unpack_description(format);
428 
429    /* Optimized function for block-compressed formats */
430    if (unpack->unpack_rgba_8unorm_rect) {
431       unpack->unpack_rgba_8unorm_rect(dst, dst_stride, src, src_stride, w, h);
432    } else {
433      for (unsigned y = 0; y < h; y++) {
434         unpack->unpack_rgba_8unorm(dst, src, w);
435         src = (const char *)src + src_stride;
436         dst = (char *)dst + dst_stride;
437      }
438   }
439 }
440 
441 void
util_format_read_4(enum pipe_format format,void * dst,unsigned dst_stride,const void * src,unsigned src_stride,unsigned x,unsigned y,unsigned w,unsigned h)442 util_format_read_4(enum pipe_format format,
443                    void *dst, unsigned dst_stride,
444                    const void *src, unsigned src_stride,
445                    unsigned x, unsigned y, unsigned w, unsigned h)
446 {
447    const struct util_format_description *format_desc;
448    const uint8_t *src_row;
449 
450    format_desc = util_format_description(format);
451 
452    assert(x % format_desc->block.width == 0);
453    assert(y % format_desc->block.height == 0);
454 
455    src_row = (const uint8_t *)src + (uint64_t)y*src_stride + x*(format_desc->block.bits/8);
456 
457    util_format_unpack_rgba_rect(format, dst, dst_stride, src_row, src_stride, w, h);
458 }
459 
460 
461 void
util_format_write_4(enum pipe_format format,const void * src,unsigned src_stride,void * dst,unsigned dst_stride,unsigned x,unsigned y,unsigned w,unsigned h)462 util_format_write_4(enum pipe_format format,
463                      const void *src, unsigned src_stride,
464                      void *dst, unsigned dst_stride,
465                      unsigned x, unsigned y, unsigned w, unsigned h)
466 {
467    const struct util_format_description *format_desc;
468    const struct util_format_pack_description *pack =
469       util_format_pack_description(format);
470    uint8_t *dst_row;
471 
472    format_desc = util_format_description(format);
473 
474    assert(x % format_desc->block.width == 0);
475    assert(y % format_desc->block.height == 0);
476 
477    dst_row = (uint8_t *)dst + (uint64_t)y*dst_stride + x*(format_desc->block.bits/8);
478 
479    if (util_format_is_pure_uint(format))
480       pack->pack_rgba_uint(dst_row, dst_stride, src, src_stride, w, h);
481    else if (util_format_is_pure_sint(format))
482       pack->pack_rgba_sint(dst_row, dst_stride, src, src_stride, w, h);
483    else
484       pack->pack_rgba_float(dst_row, dst_stride, src, src_stride, w, h);
485 }
486 
487 
488 void
util_format_read_4ub(enum pipe_format format,uint8_t * dst,unsigned dst_stride,const void * src,unsigned src_stride,unsigned x,unsigned y,unsigned w,unsigned h)489 util_format_read_4ub(enum pipe_format format, uint8_t *dst, unsigned dst_stride, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h)
490 {
491    const struct util_format_description *format_desc;
492    const uint8_t *src_row;
493 
494    format_desc = util_format_description(format);
495 
496    assert(x % format_desc->block.width == 0);
497    assert(y % format_desc->block.height == 0);
498 
499    src_row = (const uint8_t *)src + (uint64_t)y*src_stride + x*(format_desc->block.bits/8);
500 
501    util_format_unpack_rgba_8unorm_rect(format, dst, dst_stride, src_row, src_stride, w, h);
502 }
503 
504 
505 void
util_format_write_4ub(enum pipe_format format,const uint8_t * src,unsigned src_stride,void * dst,unsigned dst_stride,unsigned x,unsigned y,unsigned w,unsigned h)506 util_format_write_4ub(enum pipe_format format, const uint8_t *src, unsigned src_stride, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h)
507 {
508    const struct util_format_description *format_desc;
509    const struct util_format_pack_description *pack =
510       util_format_pack_description(format);
511    uint8_t *dst_row;
512    const uint8_t *src_row;
513 
514    format_desc = util_format_description(format);
515 
516    assert(x % format_desc->block.width == 0);
517    assert(y % format_desc->block.height == 0);
518 
519    dst_row = (uint8_t *)dst + (uint64_t)y*dst_stride + x*(format_desc->block.bits/8);
520    src_row = src;
521 
522    pack->pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, w, h);
523 }
524 
525 /**
526  * Check if we can safely memcopy from the source format to the dest format.
527  * This basically covers the cases of a "used" channel copied to a typeless
528  * channel, plus some 1-channel cases.
529  * Examples of compatible copy formats include:
530  *    b8g8r8a8_unorm -> b8g8r8x8_unorm
531  *    a8r8g8b8_unorm -> x8r8g8b8_unorm
532  *    b5g5r5a1_unorm -> b5g5r5x1_unorm
533  *    b4g4r4a4_unorm -> b4g4r4x4_unorm
534  *    l8_unorm -> r8_unorm
535  *    i8_unorm -> l8_unorm
536  *    i8_unorm -> a8_unorm
537  *    i8_unorm -> r8_unorm
538  *    l16_unorm -> r16_unorm
539  *    z24_unorm_s8_uint -> z24x8_unorm
540  *    s8_uint_z24_unorm -> x8z24_unorm
541  *    r8g8b8a8_unorm -> r8g8b8x8_unorm
542  *    a8b8g8r8_srgb -> x8b8g8r8_srgb
543  *    b8g8r8a8_srgb -> b8g8r8x8_srgb
544  *    a8r8g8b8_srgb -> x8r8g8b8_srgb
545  *    a8b8g8r8_unorm -> x8b8g8r8_unorm
546  *    r10g10b10a2_uscaled -> r10g10b10x2_uscaled
547  *    r10sg10sb10sa2u_norm -> r10g10b10x2_snorm
548  */
549 bool
util_is_format_compatible(const struct util_format_description * src_desc,const struct util_format_description * dst_desc)550 util_is_format_compatible(const struct util_format_description *src_desc,
551                           const struct util_format_description *dst_desc)
552 {
553    unsigned chan;
554 
555    if (src_desc->format == dst_desc->format) {
556       return true;
557    }
558 
559    if (src_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
560        dst_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
561       return false;
562    }
563 
564    if (src_desc->block.bits != dst_desc->block.bits ||
565        src_desc->nr_channels != dst_desc->nr_channels ||
566        src_desc->colorspace != dst_desc->colorspace) {
567       return false;
568    }
569 
570    for (chan = 0; chan < 4; ++chan) {
571       if (src_desc->channel[chan].size !=
572           dst_desc->channel[chan].size) {
573          return false;
574       }
575    }
576 
577    for (chan = 0; chan < 4; ++chan) {
578       enum pipe_swizzle swizzle = dst_desc->swizzle[chan];
579 
580       if (swizzle < 4) {
581          if (src_desc->swizzle[chan] != swizzle) {
582             return false;
583          }
584          if ((src_desc->channel[swizzle].type !=
585               dst_desc->channel[swizzle].type) ||
586              (src_desc->channel[swizzle].normalized !=
587               dst_desc->channel[swizzle].normalized)) {
588             return false;
589          }
590       }
591    }
592 
593    return true;
594 }
595 
596 
597 bool
util_format_fits_8unorm(const struct util_format_description * format_desc)598 util_format_fits_8unorm(const struct util_format_description *format_desc)
599 {
600    unsigned chan;
601 
602    /*
603     * After linearized sRGB values require more than 8bits.
604     */
605 
606    if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
607       return false;
608    }
609 
610    switch (format_desc->layout) {
611 
612    case UTIL_FORMAT_LAYOUT_S3TC:
613       /*
614        * These are straight forward.
615        */
616       return true;
617    case UTIL_FORMAT_LAYOUT_RGTC:
618       if (format_desc->format == PIPE_FORMAT_RGTC1_SNORM ||
619           format_desc->format == PIPE_FORMAT_RGTC2_SNORM ||
620           format_desc->format == PIPE_FORMAT_LATC1_SNORM ||
621           format_desc->format == PIPE_FORMAT_LATC2_SNORM)
622          return false;
623       return true;
624    case UTIL_FORMAT_LAYOUT_BPTC:
625       if (format_desc->format == PIPE_FORMAT_BPTC_RGBA_UNORM)
626          return true;
627       return false;
628 
629    case UTIL_FORMAT_LAYOUT_ETC:
630       if (format_desc->format == PIPE_FORMAT_ETC1_RGB8)
631          return true;
632       return false;
633 
634    case UTIL_FORMAT_LAYOUT_PLAIN:
635       /*
636        * For these we can find a generic rule.
637        */
638 
639       for (chan = 0; chan < format_desc->nr_channels; ++chan) {
640          switch (format_desc->channel[chan].type) {
641          case UTIL_FORMAT_TYPE_VOID:
642             break;
643          case UTIL_FORMAT_TYPE_UNSIGNED:
644             if (!format_desc->channel[chan].normalized ||
645                 format_desc->channel[chan].size > 8) {
646                return false;
647             }
648             break;
649          default:
650             return false;
651          }
652       }
653       return true;
654 
655    default:
656       /*
657        * Handle all others on a case by case basis.
658        */
659 
660       switch (format_desc->format) {
661       case PIPE_FORMAT_R1_UNORM:
662       case PIPE_FORMAT_UYVY:
663       case PIPE_FORMAT_VYUY:
664       case PIPE_FORMAT_YUYV:
665       case PIPE_FORMAT_YVYU:
666       case PIPE_FORMAT_R8G8_B8G8_UNORM:
667       case PIPE_FORMAT_G8R8_G8B8_UNORM:
668          return true;
669 
670       default:
671          return false;
672       }
673    }
674 }
675 
676 
677 bool
util_format_translate(enum pipe_format dst_format,void * dst,unsigned dst_stride,unsigned dst_x,unsigned dst_y,enum pipe_format src_format,const void * src,unsigned src_stride,unsigned src_x,unsigned src_y,unsigned width,unsigned height)678 util_format_translate(enum pipe_format dst_format,
679                       void *dst, unsigned dst_stride,
680                       unsigned dst_x, unsigned dst_y,
681                       enum pipe_format src_format,
682                       const void *src, unsigned src_stride,
683                       unsigned src_x, unsigned src_y,
684                       unsigned width, unsigned height)
685 {
686    const struct util_format_description *dst_format_desc;
687    const struct util_format_description *src_format_desc;
688    const struct util_format_pack_description *pack =
689       util_format_pack_description(dst_format);
690    const struct util_format_unpack_description *unpack =
691       util_format_unpack_description(src_format);
692    uint8_t *dst_row;
693    const uint8_t *src_row;
694    unsigned x_step, y_step;
695    unsigned dst_step;
696    unsigned src_step;
697 
698    dst_format_desc = util_format_description(dst_format);
699    src_format_desc = util_format_description(src_format);
700 
701    if (util_is_format_compatible(src_format_desc, dst_format_desc)) {
702       /*
703        * Trivial case.
704        */
705 
706       util_copy_rect(dst, dst_format, dst_stride,  dst_x, dst_y,
707                      width, height, src, (int)src_stride,
708                      src_x, src_y);
709       return true;
710    }
711 
712    assert(dst_x % dst_format_desc->block.width == 0);
713    assert(dst_y % dst_format_desc->block.height == 0);
714    assert(src_x % src_format_desc->block.width == 0);
715    assert(src_y % src_format_desc->block.height == 0);
716 
717    dst_row = (uint8_t *)dst + (uint64_t)dst_y*dst_stride + dst_x*(dst_format_desc->block.bits/8);
718    src_row = (const uint8_t *)src + (uint64_t)src_y*src_stride + src_x*(src_format_desc->block.bits/8);
719 
720    /*
721     * This works because all pixel formats have pixel blocks with power of two
722     * sizes.
723     */
724 
725    y_step = MAX2(dst_format_desc->block.height, src_format_desc->block.height);
726    x_step = MAX2(dst_format_desc->block.width, src_format_desc->block.width);
727    assert(y_step % dst_format_desc->block.height == 0);
728    assert(y_step % src_format_desc->block.height == 0);
729 
730    dst_step = y_step / dst_format_desc->block.height * dst_stride;
731    src_step = y_step / src_format_desc->block.height * src_stride;
732 
733    /*
734     * TODO: double formats will loose precision
735     * TODO: Add a special case for formats that are mere swizzles of each other
736     */
737 
738    if (src_format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ||
739        dst_format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
740       float *tmp_z = NULL;
741       uint8_t *tmp_s = NULL;
742 
743       assert(x_step == 1);
744       assert(y_step == 1);
745 
746       if (unpack->unpack_z_float && pack->pack_z_float) {
747          tmp_z = malloc(width * sizeof *tmp_z);
748       }
749 
750       if (unpack->unpack_s_8uint && pack->pack_s_8uint) {
751          tmp_s = malloc(width * sizeof *tmp_s);
752       }
753 
754       while (height--) {
755          if (tmp_z) {
756             util_format_unpack_z_float(src_format, tmp_z, src_row, width);
757             util_format_pack_z_float(dst_format, dst_row, tmp_z, width);
758          }
759 
760          if (tmp_s) {
761             util_format_unpack_s_8uint(src_format, tmp_s, src_row, width);
762             util_format_pack_s_8uint(dst_format, dst_row, tmp_s, width);
763          }
764 
765          dst_row += dst_step;
766          src_row += src_step;
767       }
768 
769       free(tmp_s);
770 
771       free(tmp_z);
772 
773       return true;
774    }
775 
776    if (util_format_fits_8unorm(src_format_desc) ||
777        util_format_fits_8unorm(dst_format_desc)) {
778       unsigned tmp_stride;
779       uint8_t *tmp_row;
780 
781       if ((!unpack->unpack_rgba_8unorm && !unpack->unpack_rgba_8unorm_rect) ||
782           !pack->pack_rgba_8unorm) {
783          return false;
784       }
785 
786       tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row;
787       tmp_row = malloc((uint64_t)y_step * tmp_stride);
788       if (!tmp_row)
789          return false;
790 
791       while (height >= y_step) {
792          util_format_unpack_rgba_8unorm_rect(src_format, tmp_row, tmp_stride, src_row, src_stride, width, y_step);
793          pack->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step);
794 
795          dst_row += dst_step;
796          src_row += src_step;
797          height -= y_step;
798       }
799 
800       if (height) {
801          util_format_unpack_rgba_8unorm_rect(src_format, tmp_row, tmp_stride, src_row, src_stride, width, height);
802          pack->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, height);
803       }
804 
805       free(tmp_row);
806    }
807    else if (util_format_is_pure_sint(src_format) ||
808             util_format_is_pure_sint(dst_format)) {
809       unsigned tmp_stride;
810       int *tmp_row;
811 
812       if (util_format_is_pure_sint(src_format) !=
813           util_format_is_pure_sint(dst_format)) {
814          return false;
815       }
816 
817       tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row;
818       tmp_row = malloc((uint64_t)y_step * tmp_stride);
819       if (!tmp_row)
820          return false;
821 
822       while (height >= y_step) {
823          util_format_unpack_rgba_rect(src_format, tmp_row, tmp_stride, src_row, src_stride, width, y_step);
824          pack->pack_rgba_sint(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step);
825 
826          dst_row += dst_step;
827          src_row += src_step;
828          height -= y_step;
829       }
830 
831       if (height) {
832          util_format_unpack_rgba_rect(src_format, tmp_row, tmp_stride, src_row, src_stride, width, height);
833          pack->pack_rgba_sint(dst_row, dst_stride, tmp_row, tmp_stride, width, height);
834       }
835 
836       free(tmp_row);
837    }
838    else if (util_format_is_pure_uint(src_format) ||
839             util_format_is_pure_uint(dst_format)) {
840       unsigned tmp_stride;
841       unsigned int *tmp_row;
842 
843       if ((!unpack->unpack_rgba && !unpack->unpack_rgba_rect) ||
844           !pack->pack_rgba_uint) {
845          return false;
846       }
847 
848       tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row;
849       tmp_row = malloc((uint64_t)y_step * tmp_stride);
850       if (!tmp_row)
851          return false;
852 
853       while (height >= y_step) {
854          util_format_unpack_rgba_rect(src_format, tmp_row, tmp_stride, src_row, src_stride, width, y_step);
855          pack->pack_rgba_uint(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step);
856 
857          dst_row += dst_step;
858          src_row += src_step;
859          height -= y_step;
860       }
861 
862       if (height) {
863          util_format_unpack_rgba_rect(src_format, tmp_row, tmp_stride, src_row, src_stride, width, height);
864          pack->pack_rgba_uint(dst_row, dst_stride, tmp_row, tmp_stride, width, height);
865       }
866 
867       free(tmp_row);
868    }
869    else {
870       unsigned tmp_stride;
871       float *tmp_row;
872 
873       if ((!unpack->unpack_rgba && !unpack->unpack_rgba_rect) ||
874           !pack->pack_rgba_float) {
875          return false;
876       }
877 
878       tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row;
879       tmp_row = malloc((uint64_t)y_step * tmp_stride);
880       if (!tmp_row)
881          return false;
882 
883       while (height >= y_step) {
884          util_format_unpack_rgba_rect(src_format, tmp_row, tmp_stride, src_row, src_stride, width, y_step);
885          pack->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step);
886 
887          dst_row += dst_step;
888          src_row += src_step;
889          height -= y_step;
890       }
891 
892       if (height) {
893          util_format_unpack_rgba_rect(src_format, tmp_row, tmp_stride, src_row, src_stride, width, height);
894          pack->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, height);
895       }
896 
897       free(tmp_row);
898    }
899    return true;
900 }
901 
902 bool
util_format_translate_3d(enum pipe_format dst_format,void * dst,unsigned dst_stride,uint64_t dst_slice_stride,unsigned dst_x,unsigned dst_y,unsigned dst_z,enum pipe_format src_format,const void * src,unsigned src_stride,uint64_t src_slice_stride,unsigned src_x,unsigned src_y,unsigned src_z,unsigned width,unsigned height,unsigned depth)903 util_format_translate_3d(enum pipe_format dst_format,
904                          void *dst, unsigned dst_stride,
905                          uint64_t dst_slice_stride,
906                          unsigned dst_x, unsigned dst_y,
907                          unsigned dst_z,
908                          enum pipe_format src_format,
909                          const void *src, unsigned src_stride,
910                          uint64_t src_slice_stride,
911                          unsigned src_x, unsigned src_y,
912                          unsigned src_z, unsigned width,
913                          unsigned height, unsigned depth)
914 {
915    uint8_t *dst_layer;
916    const uint8_t *src_layer;
917    unsigned z;
918    dst_layer = dst;
919    src_layer = src;
920    dst_layer += dst_z * dst_slice_stride;
921    src_layer += src_z * src_slice_stride;
922    for (z = 0; z < depth; ++z) {
923       if (!util_format_translate(dst_format, dst_layer, dst_stride,
924                                  dst_x, dst_y,
925                                  src_format, src_layer, src_stride,
926                                  src_x, src_y,
927                                  width, height))
928           return false;
929 
930       dst_layer += dst_slice_stride;
931       src_layer += src_slice_stride;
932    }
933    return true;
934 }
935 
util_format_compose_swizzles(const unsigned char swz1[4],const unsigned char swz2[4],unsigned char dst[4])936 void util_format_compose_swizzles(const unsigned char swz1[4],
937                                   const unsigned char swz2[4],
938                                   unsigned char dst[4])
939 {
940    unsigned i;
941 
942    for (i = 0; i < 4; i++) {
943       dst[i] = swz2[i] <= PIPE_SWIZZLE_W ?
944                swz1[swz2[i]] : swz2[i];
945    }
946 }
947 
util_format_apply_color_swizzle(union pipe_color_union * dst,const union pipe_color_union * src,const unsigned char swz[4],const bool is_integer)948 void util_format_apply_color_swizzle(union pipe_color_union *dst,
949                                      const union pipe_color_union *src,
950                                      const unsigned char swz[4],
951                                      const bool is_integer)
952 {
953    unsigned c;
954 
955    if (is_integer) {
956       for (c = 0; c < 4; ++c) {
957          switch (swz[c]) {
958          case PIPE_SWIZZLE_X:   dst->ui[c] = src->ui[0]; break;
959          case PIPE_SWIZZLE_Y: dst->ui[c] = src->ui[1]; break;
960          case PIPE_SWIZZLE_Z:  dst->ui[c] = src->ui[2]; break;
961          case PIPE_SWIZZLE_W: dst->ui[c] = src->ui[3]; break;
962          default:
963             dst->ui[c] = (swz[c] == PIPE_SWIZZLE_1) ? 1 : 0;
964             break;
965          }
966       }
967    } else {
968       for (c = 0; c < 4; ++c) {
969          switch (swz[c]) {
970          case PIPE_SWIZZLE_X:   dst->f[c] = src->f[0]; break;
971          case PIPE_SWIZZLE_Y: dst->f[c] = src->f[1]; break;
972          case PIPE_SWIZZLE_Z:  dst->f[c] = src->f[2]; break;
973          case PIPE_SWIZZLE_W: dst->f[c] = src->f[3]; break;
974          default:
975             dst->f[c] = (swz[c] == PIPE_SWIZZLE_1) ? 1.0f : 0.0f;
976             break;
977          }
978       }
979    }
980 }
981 
pipe_swizzle_4f(float * dst,const float * src,const unsigned char swz[4])982 void pipe_swizzle_4f(float *dst, const float *src,
983                             const unsigned char swz[4])
984 {
985    unsigned i;
986 
987    for (i = 0; i < 4; i++) {
988       if (swz[i] <= PIPE_SWIZZLE_W)
989          dst[i] = src[swz[i]];
990       else if (swz[i] == PIPE_SWIZZLE_0)
991          dst[i] = 0;
992       else if (swz[i] == PIPE_SWIZZLE_1)
993          dst[i] = 1;
994    }
995 }
996 
util_format_unswizzle_4f(float * dst,const float * src,const unsigned char swz[4])997 void util_format_unswizzle_4f(float *dst, const float *src,
998                               const unsigned char swz[4])
999 {
1000    unsigned i;
1001 
1002    for (i = 0; i < 4; i++) {
1003       switch (swz[i]) {
1004       case PIPE_SWIZZLE_X:
1005          dst[0] = src[i];
1006          break;
1007       case PIPE_SWIZZLE_Y:
1008          dst[1] = src[i];
1009          break;
1010       case PIPE_SWIZZLE_Z:
1011          dst[2] = src[i];
1012          break;
1013       case PIPE_SWIZZLE_W:
1014          dst[3] = src[i];
1015          break;
1016       }
1017    }
1018 }
1019 
1020 enum pipe_format
util_format_snorm_to_sint(enum pipe_format format)1021 util_format_snorm_to_sint(enum pipe_format format)
1022 {
1023    switch (format) {
1024    case PIPE_FORMAT_R32_SNORM:
1025       return PIPE_FORMAT_R32_SINT;
1026    case PIPE_FORMAT_R32G32_SNORM:
1027       return PIPE_FORMAT_R32G32_SINT;
1028    case PIPE_FORMAT_R32G32B32_SNORM:
1029       return PIPE_FORMAT_R32G32B32_SINT;
1030    case PIPE_FORMAT_R32G32B32A32_SNORM:
1031       return PIPE_FORMAT_R32G32B32A32_SINT;
1032 
1033    case PIPE_FORMAT_R16_SNORM:
1034       return PIPE_FORMAT_R16_SINT;
1035    case PIPE_FORMAT_R16G16_SNORM:
1036       return PIPE_FORMAT_R16G16_SINT;
1037    case PIPE_FORMAT_R16G16B16_SNORM:
1038       return PIPE_FORMAT_R16G16B16_SINT;
1039    case PIPE_FORMAT_R16G16B16A16_SNORM:
1040       return PIPE_FORMAT_R16G16B16A16_SINT;
1041 
1042    case PIPE_FORMAT_R8_SNORM:
1043       return PIPE_FORMAT_R8_SINT;
1044    case PIPE_FORMAT_R8G8_SNORM:
1045       return PIPE_FORMAT_R8G8_SINT;
1046    case PIPE_FORMAT_R8G8B8_SNORM:
1047       return PIPE_FORMAT_R8G8B8_SINT;
1048    case PIPE_FORMAT_B8G8R8_SNORM:
1049       return PIPE_FORMAT_B8G8R8_SINT;
1050    case PIPE_FORMAT_R8G8B8A8_SNORM:
1051       return PIPE_FORMAT_R8G8B8A8_SINT;
1052    case PIPE_FORMAT_B8G8R8A8_SNORM:
1053       return PIPE_FORMAT_B8G8R8A8_SINT;
1054 
1055    case PIPE_FORMAT_R10G10B10A2_SNORM:
1056       return PIPE_FORMAT_R10G10B10A2_SINT;
1057    case PIPE_FORMAT_B10G10R10A2_SNORM:
1058       return PIPE_FORMAT_B10G10R10A2_SINT;
1059 
1060    case PIPE_FORMAT_R10G10B10X2_SNORM:
1061       return PIPE_FORMAT_R10G10B10X2_SINT;
1062 
1063    case PIPE_FORMAT_A8_SNORM:
1064       return PIPE_FORMAT_A8_SINT;
1065    case PIPE_FORMAT_L8_SNORM:
1066       return PIPE_FORMAT_L8_SINT;
1067    case PIPE_FORMAT_L8A8_SNORM:
1068       return PIPE_FORMAT_L8A8_SINT;
1069    case PIPE_FORMAT_I8_SNORM:
1070       return PIPE_FORMAT_I8_SINT;
1071 
1072    case PIPE_FORMAT_A16_SNORM:
1073       return PIPE_FORMAT_A16_SINT;
1074    case PIPE_FORMAT_L16_SNORM:
1075       return PIPE_FORMAT_L16_SINT;
1076    case PIPE_FORMAT_L16A16_SNORM:
1077       return PIPE_FORMAT_L16A16_SINT;
1078    case PIPE_FORMAT_I16_SNORM:
1079       return PIPE_FORMAT_I16_SINT;
1080 
1081    case PIPE_FORMAT_R8G8B8X8_SNORM:
1082       return PIPE_FORMAT_R8G8B8X8_SINT;
1083    case PIPE_FORMAT_R16G16B16X16_SNORM:
1084       return PIPE_FORMAT_R16G16B16X16_SINT;
1085 
1086    case PIPE_FORMAT_R8A8_SNORM:
1087       return PIPE_FORMAT_R8A8_SINT;
1088    case PIPE_FORMAT_R16A16_SNORM:
1089       return PIPE_FORMAT_R16A16_SINT;
1090 
1091    case PIPE_FORMAT_G8R8_SNORM:
1092       return PIPE_FORMAT_G8R8_SINT;
1093    case PIPE_FORMAT_G16R16_SNORM:
1094       return PIPE_FORMAT_G16R16_SINT;
1095 
1096    case PIPE_FORMAT_A8B8G8R8_SNORM:
1097       return PIPE_FORMAT_A8B8G8R8_SINT;
1098    case PIPE_FORMAT_X8B8G8R8_SNORM:
1099       return PIPE_FORMAT_X8B8G8R8_SINT;
1100 
1101    case PIPE_FORMAT_B8G8R8X8_SNORM:
1102       return PIPE_FORMAT_B8G8R8X8_SINT;
1103    case PIPE_FORMAT_A8R8G8B8_SNORM:
1104       return PIPE_FORMAT_A8R8G8B8_SINT;
1105    case PIPE_FORMAT_X8R8G8B8_SNORM:
1106       return PIPE_FORMAT_X8R8G8B8_SINT;
1107    case PIPE_FORMAT_B10G10R10X2_SNORM:
1108       return PIPE_FORMAT_B10G10R10X2_SINT;
1109 
1110    default:
1111       return format;
1112    }
1113 }
1114 
1115 /**
1116  * If the format is RGB, return BGR. If the format is BGR, return RGB.
1117  * This may fail by returning PIPE_FORMAT_NONE.
1118  */
1119 enum pipe_format
util_format_rgb_to_bgr(enum pipe_format format)1120 util_format_rgb_to_bgr(enum pipe_format format)
1121 {
1122 #define REMAP_RGB_ONE(r, rs, g, gs, b, bs, type) \
1123    case PIPE_FORMAT_##r##rs##g##gs##b##bs##_##type: \
1124       return PIPE_FORMAT_##b##bs##g##gs##r##rs##_##type;
1125 
1126 #define REMAP_RGB(rs, gs, bs, type) \
1127    REMAP_RGB_ONE(R, rs, G, gs, B, bs, type) \
1128    REMAP_RGB_ONE(B, bs, G, gs, R, rs, type) \
1129 
1130 #define REMAP_RGBA_ONE(r, rs, g, gs, b, bs, a, as, type) \
1131    case PIPE_FORMAT_##r##rs##g##gs##b##bs##a##as##_##type: \
1132       return PIPE_FORMAT_##b##bs##g##gs##r##rs##a##as##_##type;
1133 
1134 #define REMAP_ARGB_ONE(a, as, r, rs, g, gs, b, bs, type) \
1135    case PIPE_FORMAT_##a##as##r##rs##g##gs##b##bs##_##type: \
1136       return PIPE_FORMAT_##a##as##b##bs##g##gs##r##rs##_##type;
1137 
1138 #define REMAP_RGB_AX(A, rs, gs, bs, as, type) \
1139    REMAP_RGBA_ONE(R, rs, G, gs, B, bs, A, as, type) \
1140    REMAP_RGBA_ONE(B, bs, G, gs, R, rs, A, as, type) \
1141 
1142 #define REMAP_AX_RGB(A, rs, gs, bs, as, type) \
1143    REMAP_ARGB_ONE(A, as, R, rs, G, gs, B, bs, type) \
1144    REMAP_ARGB_ONE(A, as, B, bs, G, gs, R, rs, type) \
1145 
1146 #define REMAP_RGBA(rs, gs, bs, as, type) REMAP_RGB_AX(A, rs, gs, bs, as, type)
1147 #define REMAP_RGBX(rs, gs, bs, as, type) REMAP_RGB_AX(X, rs, gs, bs, as, type)
1148 #define REMAP_ARGB(rs, gs, bs, as, type) REMAP_AX_RGB(A, rs, gs, bs, as, type)
1149 #define REMAP_XRGB(rs, gs, bs, as, type) REMAP_AX_RGB(X, rs, gs, bs, as, type)
1150 
1151 #define REMAP_RGBA_ALL(rs, gs, bs, as, type) \
1152    REMAP_RGBA(rs, gs, bs, as, type) \
1153    REMAP_RGBX(rs, gs, bs, as, type) \
1154    REMAP_ARGB(rs, gs, bs, as, type) \
1155    REMAP_XRGB(rs, gs, bs, as, type)
1156 
1157    switch (format) {
1158    REMAP_RGB(3, 3, 2, UNORM);
1159    REMAP_RGB(3, 3, 2, UINT);
1160    REMAP_RGB(5, 6, 5, SRGB);
1161    REMAP_RGB(5, 6, 5, UNORM);
1162    REMAP_RGB(5, 6, 5, UINT);
1163    REMAP_RGB(8, 8, 8, SRGB);
1164    REMAP_RGB(8, 8, 8, UNORM);
1165    REMAP_RGB(8, 8, 8, SNORM);
1166    REMAP_RGB(8, 8, 8, UINT);
1167    REMAP_RGB(8, 8, 8, SINT);
1168    REMAP_RGB(8, 8, 8, USCALED);
1169    REMAP_RGB(8, 8, 8, SSCALED);
1170 
1171    /* Complete format sets. */
1172    REMAP_RGBA_ALL(5, 5, 5, 1, UNORM);
1173    REMAP_RGBA_ALL(8, 8, 8, 8, SRGB);
1174    REMAP_RGBA_ALL(8, 8, 8, 8, UNORM);
1175    REMAP_RGBA_ALL(8, 8, 8, 8, SNORM);
1176    REMAP_RGBA_ALL(8, 8, 8, 8, SINT);
1177 
1178    /* Format sets missing XRGB/XBGR. */
1179    REMAP_RGBA(4, 4, 4, 4, UNORM);
1180    REMAP_RGBX(4, 4, 4, 4, UNORM);
1181    REMAP_ARGB(4, 4, 4, 4, UNORM);
1182 
1183    REMAP_RGBA(8, 8, 8, 8, UINT);
1184    REMAP_RGBX(8, 8, 8, 8, UINT);
1185    REMAP_ARGB(8, 8, 8, 8, UINT);
1186 
1187    REMAP_RGBA(10, 10, 10, 2, UNORM);
1188    REMAP_RGBX(10, 10, 10, 2, UNORM);
1189    REMAP_ARGB(10, 10, 10, 2, UNORM);
1190 
1191    /* Format sets missing a half of combinations. */
1192    REMAP_RGBA(4, 4, 4, 4, UINT);
1193    REMAP_ARGB(4, 4, 4, 4, UINT);
1194 
1195    REMAP_RGBA(5, 5, 5, 1, UINT);
1196    REMAP_ARGB(5, 5, 5, 1, UINT);
1197 
1198    REMAP_RGBA(10, 10, 10, 2, SNORM);
1199    REMAP_RGBX(10, 10, 10, 2, SNORM);
1200 
1201    REMAP_RGBA(10, 10, 10, 2, UINT);
1202    REMAP_ARGB(10, 10, 10, 2, UINT);
1203 
1204    REMAP_RGBA(10, 10, 10, 2, SINT);
1205    REMAP_RGBX(10, 10, 10, 2, SINT);
1206 
1207    /* Format sets having only RGBA/BGRA. */
1208    REMAP_RGBA(8, 8, 8, 8, USCALED);
1209    REMAP_RGBA(8, 8, 8, 8, SSCALED);
1210    REMAP_RGBA(10, 10, 10, 2, USCALED);
1211    REMAP_RGBA(10, 10, 10, 2, SSCALED);
1212 
1213    default:
1214       return PIPE_FORMAT_NONE;
1215    }
1216 }
1217 
1218 static const struct util_format_unpack_description *util_format_unpack_table[PIPE_FORMAT_COUNT];
1219 
1220 static void
util_format_unpack_table_init(void)1221 util_format_unpack_table_init(void)
1222 {
1223    for (enum pipe_format format = PIPE_FORMAT_NONE; format < PIPE_FORMAT_COUNT; format++) {
1224 #if (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM) && !defined(NO_FORMAT_ASM) && !defined(__SOFTFP__)
1225       const struct util_format_unpack_description *unpack = util_format_unpack_description_neon(format);
1226       if (unpack) {
1227          util_format_unpack_table[format] = unpack;
1228          continue;
1229       }
1230 #endif
1231 
1232       util_format_unpack_table[format] = util_format_unpack_description_generic(format);
1233    }
1234 }
1235 
1236 const struct util_format_unpack_description *
util_format_unpack_description(enum pipe_format format)1237 util_format_unpack_description(enum pipe_format format)
1238 {
1239    static once_flag flag = ONCE_FLAG_INIT;
1240    call_once(&flag, util_format_unpack_table_init);
1241 
1242    return util_format_unpack_table[format];
1243 }
1244 
1245 enum pipe_format
util_format_snorm_to_unorm(enum pipe_format format)1246 util_format_snorm_to_unorm(enum pipe_format format)
1247 {
1248 #define CASE(x) case PIPE_FORMAT_##x##_SNORM: return PIPE_FORMAT_##x##_UNORM
1249 
1250    switch (format) {
1251    CASE(R8G8B8A8);
1252    CASE(R8G8B8X8);
1253    CASE(B8G8R8A8);
1254    CASE(B8G8R8X8);
1255    CASE(A8R8G8B8);
1256    CASE(X8R8G8B8);
1257    CASE(A8B8G8R8);
1258    CASE(X8B8G8R8);
1259 
1260    CASE(R10G10B10A2);
1261    CASE(R10G10B10X2);
1262    CASE(B10G10R10A2);
1263    CASE(B10G10R10X2);
1264 
1265    CASE(R8);
1266    CASE(R8G8);
1267    CASE(G8R8);
1268    CASE(R8G8B8);
1269    CASE(B8G8R8);
1270 
1271    CASE(R16);
1272    CASE(R16G16);
1273    CASE(G16R16);
1274    CASE(R16G16B16);
1275 
1276    CASE(R16G16B16A16);
1277    CASE(R16G16B16X16);
1278 
1279    CASE(R32);
1280    CASE(R32G32);
1281    CASE(R32G32B32);
1282    CASE(R32G32B32A32);
1283 
1284    CASE(RGTC1);
1285    CASE(RGTC2);
1286    CASE(ETC2_R11);
1287    CASE(ETC2_RG11);
1288 
1289    CASE(A8);
1290    CASE(A16);
1291    CASE(L8);
1292    CASE(L16);
1293    CASE(I8);
1294    CASE(I16);
1295 
1296    CASE(L8A8);
1297    CASE(L16A16);
1298    CASE(R8A8);
1299    CASE(R16A16);
1300 
1301    CASE(LATC1);
1302    CASE(LATC2);
1303 
1304    default:
1305       return format;
1306    }
1307 
1308 #undef CASE
1309 }
1310 
1311 enum pipe_format
util_format_rgbx_to_rgba(enum pipe_format format)1312 util_format_rgbx_to_rgba(enum pipe_format format)
1313 {
1314    switch (format) {
1315    case PIPE_FORMAT_B8G8R8X8_UNORM:
1316       return PIPE_FORMAT_B8G8R8A8_UNORM;
1317    case PIPE_FORMAT_X8B8G8R8_UNORM:
1318       return PIPE_FORMAT_A8B8G8R8_UNORM;
1319    case PIPE_FORMAT_X8R8G8B8_UNORM:
1320       return PIPE_FORMAT_A8R8G8B8_UNORM;
1321    case PIPE_FORMAT_X8B8G8R8_SRGB:
1322       return PIPE_FORMAT_A8B8G8R8_SRGB;
1323    case PIPE_FORMAT_B8G8R8X8_SRGB:
1324       return PIPE_FORMAT_B8G8R8A8_SRGB;
1325    case PIPE_FORMAT_X8R8G8B8_SRGB:
1326       return PIPE_FORMAT_A8R8G8B8_SRGB;
1327    case PIPE_FORMAT_B5G5R5X1_UNORM:
1328       return PIPE_FORMAT_B5G5R5A1_UNORM;
1329    case PIPE_FORMAT_R10G10B10X2_USCALED:
1330       return PIPE_FORMAT_R10G10B10A2_USCALED;
1331    case PIPE_FORMAT_R10G10B10X2_SNORM:
1332       return PIPE_FORMAT_R10G10B10A2_SNORM;
1333    case PIPE_FORMAT_R8G8B8X8_UNORM:
1334       return PIPE_FORMAT_R8G8B8A8_UNORM;
1335    case PIPE_FORMAT_B4G4R4X4_UNORM:
1336       return PIPE_FORMAT_B4G4R4A4_UNORM;
1337    case PIPE_FORMAT_R8G8B8X8_SNORM:
1338       return PIPE_FORMAT_R8G8B8A8_SNORM;
1339    case PIPE_FORMAT_R8G8B8X8_SRGB:
1340       return PIPE_FORMAT_R8G8B8A8_SRGB;
1341    case PIPE_FORMAT_R8G8B8X8_UINT:
1342       return PIPE_FORMAT_R8G8B8A8_UINT;
1343    case PIPE_FORMAT_R8G8B8X8_SINT:
1344       return PIPE_FORMAT_R8G8B8A8_SINT;
1345    case PIPE_FORMAT_B10G10R10X2_UNORM:
1346       return PIPE_FORMAT_B10G10R10A2_UNORM;
1347    case PIPE_FORMAT_R16G16B16X16_UNORM:
1348       return PIPE_FORMAT_R16G16B16A16_UNORM;
1349    case PIPE_FORMAT_R16G16B16X16_SNORM:
1350       return PIPE_FORMAT_R16G16B16A16_SNORM;
1351    case PIPE_FORMAT_R16G16B16X16_FLOAT:
1352       return PIPE_FORMAT_R16G16B16A16_FLOAT;
1353    case PIPE_FORMAT_R16G16B16X16_UINT:
1354       return PIPE_FORMAT_R16G16B16A16_UINT;
1355    case PIPE_FORMAT_R16G16B16X16_SINT:
1356       return PIPE_FORMAT_R16G16B16A16_SINT;
1357    case PIPE_FORMAT_R32G32B32X32_FLOAT:
1358       return PIPE_FORMAT_R32G32B32A32_FLOAT;
1359    case PIPE_FORMAT_R32G32B32X32_UINT:
1360       return PIPE_FORMAT_R32G32B32A32_UINT;
1361    case PIPE_FORMAT_R32G32B32X32_SINT:
1362       return PIPE_FORMAT_R32G32B32A32_SINT;
1363    case PIPE_FORMAT_X8B8G8R8_SNORM:
1364       return PIPE_FORMAT_A8B8G8R8_SNORM;
1365    case PIPE_FORMAT_R10G10B10X2_UNORM:
1366       return PIPE_FORMAT_R10G10B10A2_UNORM;
1367    case PIPE_FORMAT_X1B5G5R5_UNORM:
1368       return PIPE_FORMAT_A1B5G5R5_UNORM;
1369    case PIPE_FORMAT_X8B8G8R8_SINT:
1370       return PIPE_FORMAT_A8B8G8R8_SINT;
1371    case PIPE_FORMAT_B8G8R8X8_SNORM:
1372       return PIPE_FORMAT_B8G8R8A8_SNORM;
1373    case PIPE_FORMAT_B8G8R8X8_UINT:
1374       return PIPE_FORMAT_B8G8R8A8_UINT;
1375    case PIPE_FORMAT_B8G8R8X8_SINT:
1376       return PIPE_FORMAT_B8G8R8A8_SINT;
1377    case PIPE_FORMAT_X8R8G8B8_SNORM:
1378       return PIPE_FORMAT_A8R8G8B8_SNORM;
1379    case PIPE_FORMAT_X8R8G8B8_SINT:
1380       return PIPE_FORMAT_A8R8G8B8_SINT;
1381    case PIPE_FORMAT_R5G5B5X1_UNORM:
1382       return PIPE_FORMAT_R5G5B5A1_UNORM;
1383    case PIPE_FORMAT_X1R5G5B5_UNORM:
1384       return PIPE_FORMAT_A1R5G5B5_UNORM;
1385    case PIPE_FORMAT_R4G4B4X4_UNORM:
1386       return PIPE_FORMAT_R4G4B4A4_UNORM;
1387    case PIPE_FORMAT_B10G10R10X2_SNORM:
1388       return PIPE_FORMAT_B10G10R10A2_SNORM;
1389    case PIPE_FORMAT_R10G10B10X2_SINT:
1390       return PIPE_FORMAT_R10G10B10A2_SINT;
1391    case PIPE_FORMAT_B10G10R10X2_SINT:
1392       return PIPE_FORMAT_B10G10R10A2_SINT;
1393    default: {
1394       ASSERTED const struct util_format_description *desc = util_format_description(format);
1395 
1396       /* Assert that the format doesn't contain X instead of A. */
1397       assert(desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS ||
1398              (desc->channel[0].type != UTIL_FORMAT_TYPE_VOID &&
1399               desc->channel[desc->nr_channels - 1].type != UTIL_FORMAT_TYPE_VOID));
1400       return format;
1401    }
1402    }
1403 }
1404 
1405 enum pipe_format
util_format_get_array(const enum util_format_type type,const unsigned bits,const unsigned nr_components,const bool normalized,const bool pure_integer)1406 util_format_get_array(const enum util_format_type type, const unsigned bits,
1407                       const unsigned nr_components, const bool normalized,
1408                       const bool pure_integer)
1409 {
1410 #define CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS, NR_VAR) \
1411    case BITS: \
1412       switch (NR_VAR) { \
1413       case 1: \
1414          return PIPE_FORMAT_R##BITS##_##TYPE; \
1415       case 2: \
1416          return PIPE_FORMAT_R##BITS##G##BITS##_##TYPE; \
1417       case 3: \
1418          return PIPE_FORMAT_R##BITS##G##BITS##B##BITS##_##TYPE; \
1419       case 4: \
1420          return PIPE_FORMAT_R##BITS##G##BITS##B##BITS##A##BITS##_##TYPE; \
1421       default: \
1422          return PIPE_FORMAT_NONE; \
1423       }
1424 
1425 #define SWITCH_BY_BITS_CASEX3(TYPE, BITS_VAR, BITS1, BITS2, BITS3, NR_VAR) \
1426    switch (BITS_VAR) { \
1427    CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS1, NR_VAR) \
1428    CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS2, NR_VAR) \
1429    CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS3, NR_VAR) \
1430    default: \
1431       return PIPE_FORMAT_NONE; \
1432    }
1433 
1434 #define SWITCH_BY_BITS_CASEX4(TYPE, BITS_VAR, BITS1, BITS2, BITS3, BITS4, NR_VAR) \
1435    switch (BITS_VAR) { \
1436    CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS1, NR_VAR) \
1437    CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS2, NR_VAR) \
1438    CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS3, NR_VAR) \
1439    CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4(TYPE, BITS4, NR_VAR) \
1440    default: \
1441       return PIPE_FORMAT_NONE; \
1442    }
1443 
1444    switch (type) {
1445    case UTIL_FORMAT_TYPE_UNSIGNED:
1446       if (normalized)
1447          SWITCH_BY_BITS_CASEX3(UNORM, bits, 8, 16, 32, nr_components)
1448       else if (!pure_integer)
1449          SWITCH_BY_BITS_CASEX3(USCALED, bits, 8, 16, 32, nr_components)
1450       else
1451          SWITCH_BY_BITS_CASEX4(UINT, bits, 8, 16, 32, 64, nr_components)
1452    case UTIL_FORMAT_TYPE_SIGNED:
1453       if (normalized)
1454          SWITCH_BY_BITS_CASEX3(SNORM, bits, 8, 16, 32, nr_components)
1455       else if (!pure_integer)
1456          SWITCH_BY_BITS_CASEX3(SSCALED, bits, 8, 16, 32, nr_components)
1457       else
1458          SWITCH_BY_BITS_CASEX4(SINT, bits, 8, 16, 32, 64, nr_components)
1459    case UTIL_FORMAT_TYPE_FLOAT:
1460       SWITCH_BY_BITS_CASEX3(FLOAT, bits, 16, 32, 64, nr_components)
1461    default:
1462       return PIPE_FORMAT_NONE;
1463    }
1464 
1465 #undef CASE_BY_BIT_SWITCH_BY_NR_COMPONENTS_1TO4
1466 #undef SWITCH_BY_BITS_CASEX3
1467 #undef SWITCH_BY_BITS_CASEX4
1468 
1469    return PIPE_FORMAT_NONE;
1470 }
1471 
1472 unsigned
util_format_get_last_component(enum pipe_format format)1473 util_format_get_last_component(enum pipe_format format)
1474 {
1475    const struct util_format_description *desc = util_format_description(format);
1476    unsigned num = 0;
1477 
1478    for (unsigned i = 1; i < 4; i++) {
1479       if (desc->swizzle[i] <= PIPE_SWIZZLE_W)
1480          num = i;
1481    }
1482    return num;
1483 }
1484 
1485 int
util_format_get_largest_non_void_channel(enum pipe_format format)1486 util_format_get_largest_non_void_channel(enum pipe_format format)
1487 {
1488    const struct util_format_description *desc = util_format_description(format);
1489    int chan = -1, max_size = 0;
1490 
1491    for (int i = 0; i < 4; i++) {
1492       if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID &&
1493           desc->channel[i].size > max_size) {
1494          chan = i;
1495          max_size = desc->channel[i].size;
1496       }
1497    }
1498 
1499    return chan;
1500 }
1501 
1502 unsigned
util_format_get_max_channel_size(enum pipe_format format)1503 util_format_get_max_channel_size(enum pipe_format format)
1504 {
1505    const struct util_format_description *desc = util_format_description(format);
1506    int max_src_chan = util_format_get_largest_non_void_channel(format);
1507    assert(max_src_chan >= 0 || util_format_is_compressed(format));
1508 
1509    switch (format) {
1510    case PIPE_FORMAT_BPTC_RGB_FLOAT:
1511    case PIPE_FORMAT_BPTC_RGB_UFLOAT:
1512       return 16;
1513    case PIPE_FORMAT_ETC2_R11_UNORM:
1514    case PIPE_FORMAT_ETC2_R11_SNORM:
1515    case PIPE_FORMAT_ETC2_RG11_UNORM:
1516    case PIPE_FORMAT_ETC2_RG11_SNORM:
1517       return 11;
1518    default:
1519       return util_format_is_compressed(format) ?
1520                8 : desc->channel[max_src_chan].size;
1521    }
1522 }
1523 
1524 static uint32_t blocksizes_64kb[5][6][3] = {
1525 /*   3D              2D 1 sample      2D 2 samples     2D 4 samples      2D 8 samples   2D 16 samples) */
1526    { { 64, 32, 32 }, { 256, 256, 1 }, { 128, 256, 1 }, { 128, 128, 1 }, { 64, 128, 1 }, { 64, 64, 1 } }, /* 8 bits */
1527    { { 32, 32, 32 }, { 256, 128, 1 }, { 128, 128, 1 }, { 128, 64,  1 }, { 64, 64,  1 }, { 64, 32, 1 } }, /* 16 bits */
1528    { { 32, 32, 16 }, { 128, 128, 1 }, { 64,  128, 1 }, { 64,  64,  1 }, { 32, 64,  1 }, { 32, 32, 1 } }, /* 32 bits */
1529    { { 32, 16, 16 }, { 128, 64,  1 }, { 64,  64,  1 }, { 64,  32,  1 }, { 32, 32,  1 }, { 32, 16, 1 } }, /* 64 bits */
1530    { { 16, 16, 16 }, { 64,  64,  1 }, { 32,  64,  1 }, { 32,  32,  1 }, { 16, 32,  1 }, { 16, 16, 1 } }, /* 128 bits */
1531 };
1532 
1533 uint32_t
util_format_get_tilesize(enum pipe_format format,uint32_t dimensions,uint32_t samples,uint32_t axis)1534 util_format_get_tilesize(enum pipe_format format, uint32_t dimensions, uint32_t samples, uint32_t axis)
1535 {
1536    if (dimensions == 1)
1537       return axis == 0 ? 64 * 1024 : 1;
1538 
1539    uint32_t kind = 0;
1540    if (dimensions == 2)
1541       kind = util_logbase2(samples) + 1;
1542 
1543    uint32_t block_size_log2 = util_logbase2_ceil(util_format_get_blocksize(format));
1544    return blocksizes_64kb[block_size_log2][kind][axis];
1545 }
1546