Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/util/format/u_format.h
7099 views
1
/**************************************************************************
2
*
3
* Copyright 2009-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
#ifndef U_FORMAT_H
30
#define U_FORMAT_H
31
32
33
#include "pipe/p_format.h"
34
#include "pipe/p_defines.h"
35
#include "util/u_debug.h"
36
37
union pipe_color_union;
38
struct pipe_screen;
39
40
41
#ifdef __cplusplus
42
extern "C" {
43
#endif
44
45
46
/**
47
* Describe how to pack/unpack pixels into/from the prescribed format.
48
*
49
* XXX: This could be renamed to something like util_format_pack, or broke down
50
* in flags inside util_format_block that said exactly what we want.
51
*/
52
enum util_format_layout {
53
/**
54
* Formats with util_format_block::width == util_format_block::height == 1
55
* that can be described as an ordinary data structure.
56
*/
57
UTIL_FORMAT_LAYOUT_PLAIN,
58
59
/**
60
* Formats with sub-sampled channels.
61
*
62
* This is for formats like YVYU where there is less than one sample per
63
* pixel.
64
*/
65
UTIL_FORMAT_LAYOUT_SUBSAMPLED,
66
67
/**
68
* S3 Texture Compression formats.
69
*/
70
UTIL_FORMAT_LAYOUT_S3TC,
71
72
/**
73
* Red-Green Texture Compression formats.
74
*/
75
UTIL_FORMAT_LAYOUT_RGTC,
76
77
/**
78
* Ericsson Texture Compression
79
*/
80
UTIL_FORMAT_LAYOUT_ETC,
81
82
/**
83
* BC6/7 Texture Compression
84
*/
85
UTIL_FORMAT_LAYOUT_BPTC,
86
87
UTIL_FORMAT_LAYOUT_ASTC,
88
89
UTIL_FORMAT_LAYOUT_ATC,
90
91
/** Formats with 2 or more planes. */
92
UTIL_FORMAT_LAYOUT_PLANAR2,
93
UTIL_FORMAT_LAYOUT_PLANAR3,
94
95
UTIL_FORMAT_LAYOUT_FXT1 = 10,
96
97
/**
98
* Everything else that doesn't fit in any of the above layouts.
99
*/
100
UTIL_FORMAT_LAYOUT_OTHER,
101
};
102
103
104
struct util_format_block
105
{
106
/** Block width in pixels */
107
unsigned width;
108
109
/** Block height in pixels */
110
unsigned height;
111
112
/** Block depth in pixels */
113
unsigned depth;
114
115
/** Block size in bits */
116
unsigned bits;
117
};
118
119
120
enum util_format_type {
121
UTIL_FORMAT_TYPE_VOID = 0,
122
UTIL_FORMAT_TYPE_UNSIGNED = 1,
123
UTIL_FORMAT_TYPE_SIGNED = 2,
124
UTIL_FORMAT_TYPE_FIXED = 3,
125
UTIL_FORMAT_TYPE_FLOAT = 4
126
};
127
128
129
enum util_format_colorspace {
130
UTIL_FORMAT_COLORSPACE_RGB = 0,
131
UTIL_FORMAT_COLORSPACE_SRGB = 1,
132
UTIL_FORMAT_COLORSPACE_YUV = 2,
133
UTIL_FORMAT_COLORSPACE_ZS = 3
134
};
135
136
137
struct util_format_channel_description
138
{
139
unsigned type:5; /**< UTIL_FORMAT_TYPE_x */
140
unsigned normalized:1;
141
unsigned pure_integer:1;
142
unsigned size:9; /**< bits per channel */
143
unsigned shift:16; /** number of bits from lsb */
144
};
145
146
147
struct util_format_description
148
{
149
enum pipe_format format;
150
151
const char *name;
152
153
/**
154
* Short name, striped of the prefix, lower case.
155
*/
156
const char *short_name;
157
158
/**
159
* Pixel block dimensions.
160
*/
161
struct util_format_block block;
162
163
enum util_format_layout layout;
164
165
/**
166
* The number of channels.
167
*/
168
unsigned nr_channels:3;
169
170
/**
171
* Whether all channels have the same number of (whole) bytes and type.
172
*/
173
unsigned is_array:1;
174
175
/**
176
* Whether the pixel format can be described as a bitfield structure.
177
*
178
* In particular:
179
* - pixel depth must be 8, 16, or 32 bits;
180
* - all channels must be unsigned, signed, or void
181
*/
182
unsigned is_bitmask:1;
183
184
/**
185
* Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
186
*/
187
unsigned is_mixed:1;
188
189
/**
190
* Whether the format contains UNORM channels
191
*/
192
unsigned is_unorm:1;
193
194
/**
195
* Whether the format contains SNORM channels
196
*/
197
unsigned is_snorm:1;
198
199
/**
200
* Input channel description, in the order XYZW.
201
*
202
* Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
203
*
204
* If each channel is accessed as an individual N-byte value, X is always
205
* at the lowest address in memory, Y is always next, and so on. For all
206
* currently-defined formats, the N-byte value has native endianness.
207
*
208
* If instead a group of channels is accessed as a single N-byte value,
209
* the order of the channels within that value depends on endianness.
210
* For big-endian targets, X is the most significant subvalue,
211
* otherwise it is the least significant one.
212
*
213
* For example, if X is 8 bits and Y is 24 bits, the memory order is:
214
*
215
* 0 1 2 3
216
* little-endian: X Yl Ym Yu (l = lower, m = middle, u = upper)
217
* big-endian: X Yu Ym Yl
218
*
219
* If X is 5 bits, Y is 5 bits, Z is 5 bits and W is 1 bit, the layout is:
220
*
221
* 0 1
222
* msb lsb msb lsb
223
* little-endian: YYYXXXXX WZZZZZYY
224
* big-endian: XXXXXYYY YYZZZZZW
225
*/
226
struct util_format_channel_description channel[4];
227
228
/**
229
* Output channel swizzle.
230
*
231
* The order is either:
232
* - RGBA
233
* - YUV(A)
234
* - ZS
235
* depending on the colorspace.
236
*/
237
unsigned char swizzle[4];
238
239
/**
240
* Colorspace transformation.
241
*/
242
enum util_format_colorspace colorspace;
243
};
244
245
struct util_format_pack_description {
246
/**
247
* Pack pixel blocks from R8G8B8A8_UNORM.
248
* Note: strides are in bytes.
249
*
250
* Only defined for non-depth-stencil formats.
251
*/
252
void
253
(*pack_rgba_8unorm)(uint8_t *restrict dst, unsigned dst_stride,
254
const uint8_t *restrict src, unsigned src_stride,
255
unsigned width, unsigned height);
256
257
/**
258
* Pack pixel blocks from R32G32B32A32_FLOAT.
259
* Note: strides are in bytes.
260
*
261
* Only defined for non-depth-stencil formats.
262
*/
263
void
264
(*pack_rgba_float)(uint8_t *restrict dst, unsigned dst_stride,
265
const float *restrict src, unsigned src_stride,
266
unsigned width, unsigned height);
267
268
/**
269
* Pack pixels from Z32_FLOAT.
270
* Note: strides are in bytes.
271
*
272
* Only defined for depth formats.
273
*/
274
void
275
(*pack_z_32unorm)(uint8_t *restrict dst, unsigned dst_stride,
276
const uint32_t *restrict src, unsigned src_stride,
277
unsigned width, unsigned height);
278
279
/**
280
* Pack pixels from Z32_FLOAT.
281
* Note: strides are in bytes.
282
*
283
* Only defined for depth formats.
284
*/
285
void
286
(*pack_z_float)(uint8_t *restrict dst, unsigned dst_stride,
287
const float *restrict src, unsigned src_stride,
288
unsigned width, unsigned height);
289
290
/**
291
* Pack pixels from S8_UINT.
292
* Note: strides are in bytes.
293
*
294
* Only defined for stencil formats.
295
*/
296
void
297
(*pack_s_8uint)(uint8_t *restrict dst, unsigned dst_stride,
298
const uint8_t *restrict src, unsigned src_stride,
299
unsigned width, unsigned height);
300
301
void
302
(*pack_rgba_uint)(uint8_t *restrict dst, unsigned dst_stride,
303
const uint32_t *restrict src, unsigned src_stride,
304
unsigned width, unsigned height);
305
306
void
307
(*pack_rgba_sint)(uint8_t *restrict dst, unsigned dst_stride,
308
const int32_t *restrict src, unsigned src_stride,
309
unsigned width, unsigned height);
310
};
311
312
313
struct util_format_unpack_description {
314
/**
315
* Unpack pixel blocks to R8G8B8A8_UNORM.
316
* Note: strides are in bytes.
317
*
318
* Only defined for non-block non-depth-stencil formats.
319
*/
320
void
321
(*unpack_rgba_8unorm)(uint8_t *restrict dst, const uint8_t *restrict src,
322
unsigned width);
323
324
/**
325
* Unpack pixel blocks to R8G8B8A8_UNORM.
326
* Note: strides are in bytes.
327
*
328
* Only defined for block non-depth-stencil formats.
329
*/
330
void
331
(*unpack_rgba_8unorm_rect)(uint8_t *restrict dst, unsigned dst_stride,
332
const uint8_t *restrict src, unsigned src_stride,
333
unsigned width, unsigned height);
334
335
/**
336
* Fetch a single pixel (i, j) from a block.
337
*
338
* XXX: Only defined for a very few select formats.
339
*/
340
void
341
(*fetch_rgba_8unorm)(uint8_t *restrict dst,
342
const uint8_t *restrict src,
343
unsigned i, unsigned j);
344
345
/**
346
* Unpack pixel blocks to R32G32B32A32_UINT/_INT_FLOAT based on whether the
347
* type is pure uint, int, or other.
348
*
349
* Note: strides are in bytes.
350
*
351
* Only defined for non-block non-depth-stencil formats.
352
*/
353
void
354
(*unpack_rgba)(void *restrict dst, const uint8_t *restrict src,
355
unsigned width);
356
357
/**
358
* Unpack pixel blocks to R32G32B32A32_UINT/_INT_FLOAT based on whether the
359
* type is pure uint, int, or other.
360
*
361
* Note: strides are in bytes.
362
*
363
* Only defined for block non-depth-stencil formats.
364
*/
365
void
366
(*unpack_rgba_rect)(void *restrict dst, unsigned dst_stride,
367
const uint8_t *restrict src, unsigned src_stride,
368
unsigned width, unsigned height);
369
370
/**
371
* Unpack pixels to Z32_UNORM.
372
* Note: strides are in bytes.
373
*
374
* Only defined for depth formats.
375
*/
376
void
377
(*unpack_z_32unorm)(uint32_t *restrict dst, unsigned dst_stride,
378
const uint8_t *restrict src, unsigned src_stride,
379
unsigned width, unsigned height);
380
381
/**
382
* Unpack pixels to Z32_FLOAT.
383
* Note: strides are in bytes.
384
*
385
* Only defined for depth formats.
386
*/
387
void
388
(*unpack_z_float)(float *restrict dst, unsigned dst_stride,
389
const uint8_t *restrict src, unsigned src_stride,
390
unsigned width, unsigned height);
391
392
/**
393
* Unpack pixels to S8_UINT.
394
* Note: strides are in bytes.
395
*
396
* Only defined for stencil formats.
397
*/
398
void
399
(*unpack_s_8uint)(uint8_t *restrict dst, unsigned dst_stride,
400
const uint8_t *restrict src, unsigned src_stride,
401
unsigned width, unsigned height);
402
};
403
404
typedef void (*util_format_fetch_rgba_func_ptr)(void *restrict dst, const uint8_t *restrict src,
405
unsigned i, unsigned j);
406
407
/* Silence warnings triggered by sharing function/struct names */
408
#ifdef __GNUC__
409
#pragma GCC diagnostic push
410
#pragma GCC diagnostic ignored "-Wshadow"
411
#endif
412
const struct util_format_description *
413
util_format_description(enum pipe_format format) ATTRIBUTE_CONST;
414
415
const struct util_format_pack_description *
416
util_format_pack_description(enum pipe_format format) ATTRIBUTE_CONST;
417
418
/* Lookup with CPU detection for choosing optimized paths. */
419
const struct util_format_unpack_description *
420
util_format_unpack_description(enum pipe_format format) ATTRIBUTE_CONST;
421
422
/* Codegenned table of CPU-agnostic unpack code. */
423
const struct util_format_unpack_description *
424
util_format_unpack_description_generic(enum pipe_format format) ATTRIBUTE_CONST;
425
426
const struct util_format_unpack_description *
427
util_format_unpack_description_neon(enum pipe_format format) ATTRIBUTE_CONST;
428
429
#ifdef __GNUC__
430
#pragma GCC diagnostic pop
431
#endif
432
433
/**
434
* Returns a function to fetch a single pixel (i, j) from a block.
435
*
436
* Only defined for non-depth-stencil and non-integer formats.
437
*/
438
util_format_fetch_rgba_func_ptr
439
util_format_fetch_rgba_func(enum pipe_format format) ATTRIBUTE_CONST;
440
441
/*
442
* Format query functions.
443
*/
444
445
static inline const char *
446
util_format_name(enum pipe_format format)
447
{
448
const struct util_format_description *desc = util_format_description(format);
449
450
assert(desc);
451
if (!desc) {
452
return "PIPE_FORMAT_???";
453
}
454
455
return desc->name;
456
}
457
458
static inline const char *
459
util_format_short_name(enum pipe_format format)
460
{
461
const struct util_format_description *desc = util_format_description(format);
462
463
assert(desc);
464
if (!desc) {
465
return "???";
466
}
467
468
return desc->short_name;
469
}
470
471
/**
472
* Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
473
*/
474
static inline boolean
475
util_format_is_plain(enum pipe_format format)
476
{
477
const struct util_format_description *desc = util_format_description(format);
478
479
if (!format) {
480
return FALSE;
481
}
482
483
return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
484
}
485
486
static inline boolean
487
util_format_is_compressed(enum pipe_format format)
488
{
489
const struct util_format_description *desc = util_format_description(format);
490
491
assert(desc);
492
if (!desc) {
493
return FALSE;
494
}
495
496
switch (desc->layout) {
497
case UTIL_FORMAT_LAYOUT_S3TC:
498
case UTIL_FORMAT_LAYOUT_RGTC:
499
case UTIL_FORMAT_LAYOUT_ETC:
500
case UTIL_FORMAT_LAYOUT_BPTC:
501
case UTIL_FORMAT_LAYOUT_ASTC:
502
case UTIL_FORMAT_LAYOUT_ATC:
503
case UTIL_FORMAT_LAYOUT_FXT1:
504
/* XXX add other formats in the future */
505
return TRUE;
506
default:
507
return FALSE;
508
}
509
}
510
511
static inline boolean
512
util_format_is_s3tc(enum pipe_format format)
513
{
514
const struct util_format_description *desc = util_format_description(format);
515
516
assert(desc);
517
if (!desc) {
518
return FALSE;
519
}
520
521
return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
522
}
523
524
static inline boolean
525
util_format_is_etc(enum pipe_format format)
526
{
527
const struct util_format_description *desc = util_format_description(format);
528
529
assert(desc);
530
if (!desc) {
531
return FALSE;
532
}
533
534
return desc->layout == UTIL_FORMAT_LAYOUT_ETC ? TRUE : FALSE;
535
}
536
537
static inline boolean
538
util_format_is_srgb(enum pipe_format format)
539
{
540
const struct util_format_description *desc = util_format_description(format);
541
return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
542
}
543
544
static inline boolean
545
util_format_has_depth(const struct util_format_description *desc)
546
{
547
return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
548
desc->swizzle[0] != PIPE_SWIZZLE_NONE;
549
}
550
551
static inline boolean
552
util_format_has_stencil(const struct util_format_description *desc)
553
{
554
return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
555
desc->swizzle[1] != PIPE_SWIZZLE_NONE;
556
}
557
558
static inline boolean
559
util_format_is_depth_or_stencil(enum pipe_format format)
560
{
561
const struct util_format_description *desc = util_format_description(format);
562
563
assert(desc);
564
if (!desc) {
565
return FALSE;
566
}
567
568
return util_format_has_depth(desc) ||
569
util_format_has_stencil(desc);
570
}
571
572
static inline boolean
573
util_format_is_depth_and_stencil(enum pipe_format format)
574
{
575
const struct util_format_description *desc = util_format_description(format);
576
577
assert(desc);
578
if (!desc) {
579
return FALSE;
580
}
581
582
return util_format_has_depth(desc) &&
583
util_format_has_stencil(desc);
584
}
585
586
/**
587
* For depth-stencil formats, return the equivalent depth-only format.
588
*/
589
static inline enum pipe_format
590
util_format_get_depth_only(enum pipe_format format)
591
{
592
switch (format) {
593
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
594
return PIPE_FORMAT_Z24X8_UNORM;
595
596
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
597
return PIPE_FORMAT_X8Z24_UNORM;
598
599
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
600
return PIPE_FORMAT_Z32_FLOAT;
601
602
default:
603
return format;
604
}
605
}
606
607
static inline boolean
608
util_format_is_yuv(enum pipe_format format)
609
{
610
const struct util_format_description *desc = util_format_description(format);
611
612
assert(desc);
613
if (!desc) {
614
return FALSE;
615
}
616
617
return desc->colorspace == UTIL_FORMAT_COLORSPACE_YUV;
618
}
619
620
/**
621
* Calculates the depth format type based upon the incoming format description.
622
*/
623
static inline unsigned
624
util_get_depth_format_type(const struct util_format_description *desc)
625
{
626
unsigned depth_channel = desc->swizzle[0];
627
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
628
depth_channel != PIPE_SWIZZLE_NONE) {
629
return desc->channel[depth_channel].type;
630
} else {
631
return UTIL_FORMAT_TYPE_VOID;
632
}
633
}
634
635
636
/**
637
* Calculates the MRD for the depth format. MRD is used in depth bias
638
* for UNORM and unbound depth buffers. When the depth buffer is floating
639
* point, the depth bias calculation does not use the MRD. However, the
640
* default MRD will be 1.0 / ((1 << 24) - 1).
641
*/
642
double
643
util_get_depth_format_mrd(const struct util_format_description *desc);
644
645
646
/**
647
* Return whether this is an RGBA, Z, S, or combined ZS format.
648
* Useful for initializing pipe_blit_info::mask.
649
*/
650
static inline unsigned
651
util_format_get_mask(enum pipe_format format)
652
{
653
const struct util_format_description *desc =
654
util_format_description(format);
655
656
if (!desc)
657
return 0;
658
659
if (util_format_has_depth(desc)) {
660
if (util_format_has_stencil(desc)) {
661
return PIPE_MASK_ZS;
662
} else {
663
return PIPE_MASK_Z;
664
}
665
} else {
666
if (util_format_has_stencil(desc)) {
667
return PIPE_MASK_S;
668
} else {
669
return PIPE_MASK_RGBA;
670
}
671
}
672
}
673
674
/**
675
* Give the RGBA colormask of the channels that can be represented in this
676
* format.
677
*
678
* That is, the channels whose values are preserved.
679
*/
680
static inline unsigned
681
util_format_colormask(const struct util_format_description *desc)
682
{
683
unsigned colormask;
684
unsigned chan;
685
686
switch (desc->colorspace) {
687
case UTIL_FORMAT_COLORSPACE_RGB:
688
case UTIL_FORMAT_COLORSPACE_SRGB:
689
case UTIL_FORMAT_COLORSPACE_YUV:
690
colormask = 0;
691
for (chan = 0; chan < 4; ++chan) {
692
if (desc->swizzle[chan] < 4) {
693
colormask |= (1 << chan);
694
}
695
}
696
return colormask;
697
case UTIL_FORMAT_COLORSPACE_ZS:
698
return 0;
699
default:
700
assert(0);
701
return 0;
702
}
703
}
704
705
706
/**
707
* Checks if color mask covers every channel for the specified format
708
*
709
* @param desc a format description to check colormask with
710
* @param colormask a bit mask for channels, matches format of PIPE_MASK_RGBA
711
*/
712
static inline boolean
713
util_format_colormask_full(const struct util_format_description *desc, unsigned colormask)
714
{
715
return (~colormask & util_format_colormask(desc)) == 0;
716
}
717
718
719
boolean
720
util_format_is_float(enum pipe_format format) ATTRIBUTE_CONST;
721
722
723
boolean
724
util_format_has_alpha(enum pipe_format format) ATTRIBUTE_CONST;
725
726
boolean
727
util_format_has_alpha1(enum pipe_format format) ATTRIBUTE_CONST;
728
729
boolean
730
util_format_is_luminance(enum pipe_format format) ATTRIBUTE_CONST;
731
732
boolean
733
util_format_is_alpha(enum pipe_format format) ATTRIBUTE_CONST;
734
735
boolean
736
util_format_is_luminance_alpha(enum pipe_format format) ATTRIBUTE_CONST;
737
738
739
boolean
740
util_format_is_intensity(enum pipe_format format) ATTRIBUTE_CONST;
741
742
boolean
743
util_format_is_subsampled_422(enum pipe_format format) ATTRIBUTE_CONST;
744
745
boolean
746
util_format_is_pure_integer(enum pipe_format format) ATTRIBUTE_CONST;
747
748
boolean
749
util_format_is_pure_sint(enum pipe_format format) ATTRIBUTE_CONST;
750
751
boolean
752
util_format_is_pure_uint(enum pipe_format format) ATTRIBUTE_CONST;
753
754
boolean
755
util_format_is_snorm(enum pipe_format format) ATTRIBUTE_CONST;
756
757
boolean
758
util_format_is_unorm(enum pipe_format format) ATTRIBUTE_CONST;
759
760
boolean
761
util_format_is_snorm8(enum pipe_format format) ATTRIBUTE_CONST;
762
763
boolean
764
util_format_is_scaled(enum pipe_format format) ATTRIBUTE_CONST;
765
/**
766
* Check if the src format can be blitted to the destination format with
767
* a simple memcpy. For example, blitting from RGBA to RGBx is OK, but not
768
* the reverse.
769
*/
770
boolean
771
util_is_format_compatible(const struct util_format_description *src_desc,
772
const struct util_format_description *dst_desc) ATTRIBUTE_CONST;
773
774
/**
775
* Whether this format is a rgab8 variant.
776
*
777
* That is, any format that matches the
778
*
779
* PIPE_FORMAT_?8?8?8?8_UNORM
780
*/
781
static inline boolean
782
util_format_is_rgba8_variant(const struct util_format_description *desc)
783
{
784
unsigned chan;
785
786
if(desc->block.width != 1 ||
787
desc->block.height != 1 ||
788
desc->block.bits != 32)
789
return FALSE;
790
791
for(chan = 0; chan < 4; ++chan) {
792
if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
793
desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
794
return FALSE;
795
if(desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED &&
796
!desc->channel[chan].normalized)
797
return FALSE;
798
if(desc->channel[chan].size != 8)
799
return FALSE;
800
}
801
802
return TRUE;
803
}
804
805
806
static inline bool
807
util_format_is_rgbx_or_bgrx(enum pipe_format format)
808
{
809
const struct util_format_description *desc = util_format_description(format);
810
return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
811
desc->nr_channels == 4 &&
812
(desc->swizzle[0] == PIPE_SWIZZLE_X || desc->swizzle[0] == PIPE_SWIZZLE_Z) &&
813
desc->swizzle[1] == PIPE_SWIZZLE_Y &&
814
(desc->swizzle[2] == PIPE_SWIZZLE_Z || desc->swizzle[2] == PIPE_SWIZZLE_X) &&
815
desc->swizzle[3] == PIPE_SWIZZLE_1;
816
}
817
818
/**
819
* Return total bits needed for the pixel format per block.
820
*/
821
static inline uint
822
util_format_get_blocksizebits(enum pipe_format format)
823
{
824
const struct util_format_description *desc = util_format_description(format);
825
826
assert(desc);
827
if (!desc) {
828
return 0;
829
}
830
831
return desc->block.bits;
832
}
833
834
/**
835
* Return bytes per block (not pixel) for the given format.
836
*/
837
static inline uint
838
util_format_get_blocksize(enum pipe_format format)
839
{
840
uint bits = util_format_get_blocksizebits(format);
841
uint bytes = bits / 8;
842
843
assert(bits % 8 == 0);
844
assert(bytes > 0);
845
if (bytes == 0) {
846
bytes = 1;
847
}
848
849
return bytes;
850
}
851
852
static inline uint
853
util_format_get_blockwidth(enum pipe_format format)
854
{
855
const struct util_format_description *desc = util_format_description(format);
856
857
assert(desc);
858
if (!desc) {
859
return 1;
860
}
861
862
return desc->block.width;
863
}
864
865
static inline uint
866
util_format_get_blockheight(enum pipe_format format)
867
{
868
const struct util_format_description *desc = util_format_description(format);
869
870
assert(desc);
871
if (!desc) {
872
return 1;
873
}
874
875
return desc->block.height;
876
}
877
878
static inline uint
879
util_format_get_blockdepth(enum pipe_format format)
880
{
881
const struct util_format_description *desc = util_format_description(format);
882
883
assert(desc);
884
if (!desc) {
885
return 1;
886
}
887
888
return desc->block.depth;
889
}
890
891
static inline unsigned
892
util_format_get_nblocksx(enum pipe_format format,
893
unsigned x)
894
{
895
unsigned blockwidth = util_format_get_blockwidth(format);
896
return (x + blockwidth - 1) / blockwidth;
897
}
898
899
static inline unsigned
900
util_format_get_nblocksy(enum pipe_format format,
901
unsigned y)
902
{
903
unsigned blockheight = util_format_get_blockheight(format);
904
return (y + blockheight - 1) / blockheight;
905
}
906
907
static inline unsigned
908
util_format_get_nblocksz(enum pipe_format format,
909
unsigned z)
910
{
911
unsigned blockdepth = util_format_get_blockdepth(format);
912
return (z + blockdepth - 1) / blockdepth;
913
}
914
915
static inline unsigned
916
util_format_get_nblocks(enum pipe_format format,
917
unsigned width,
918
unsigned height)
919
{
920
assert(util_format_get_blockdepth(format) == 1);
921
return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
922
}
923
924
static inline size_t
925
util_format_get_stride(enum pipe_format format,
926
unsigned width)
927
{
928
return (size_t)util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
929
}
930
931
static inline size_t
932
util_format_get_2d_size(enum pipe_format format,
933
size_t stride,
934
unsigned height)
935
{
936
return util_format_get_nblocksy(format, height) * stride;
937
}
938
939
static inline uint
940
util_format_get_component_bits(enum pipe_format format,
941
enum util_format_colorspace colorspace,
942
uint component)
943
{
944
const struct util_format_description *desc = util_format_description(format);
945
enum util_format_colorspace desc_colorspace;
946
947
assert(format);
948
if (!format) {
949
return 0;
950
}
951
952
assert(component < 4);
953
954
/* Treat RGB and SRGB as equivalent. */
955
if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
956
colorspace = UTIL_FORMAT_COLORSPACE_RGB;
957
}
958
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
959
desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
960
} else {
961
desc_colorspace = desc->colorspace;
962
}
963
964
if (desc_colorspace != colorspace) {
965
return 0;
966
}
967
968
switch (desc->swizzle[component]) {
969
case PIPE_SWIZZLE_X:
970
return desc->channel[0].size;
971
case PIPE_SWIZZLE_Y:
972
return desc->channel[1].size;
973
case PIPE_SWIZZLE_Z:
974
return desc->channel[2].size;
975
case PIPE_SWIZZLE_W:
976
return desc->channel[3].size;
977
default:
978
return 0;
979
}
980
}
981
982
/**
983
* Given a linear RGB colorspace format, return the corresponding SRGB
984
* format, or PIPE_FORMAT_NONE if none.
985
*/
986
static inline enum pipe_format
987
util_format_srgb(enum pipe_format format)
988
{
989
if (util_format_is_srgb(format))
990
return format;
991
992
switch (format) {
993
case PIPE_FORMAT_L8_UNORM:
994
return PIPE_FORMAT_L8_SRGB;
995
case PIPE_FORMAT_R8_UNORM:
996
return PIPE_FORMAT_R8_SRGB;
997
case PIPE_FORMAT_L8A8_UNORM:
998
return PIPE_FORMAT_L8A8_SRGB;
999
case PIPE_FORMAT_R8G8_UNORM:
1000
return PIPE_FORMAT_R8G8_SRGB;
1001
case PIPE_FORMAT_R8G8B8_UNORM:
1002
return PIPE_FORMAT_R8G8B8_SRGB;
1003
case PIPE_FORMAT_B8G8R8_UNORM:
1004
return PIPE_FORMAT_B8G8R8_SRGB;
1005
case PIPE_FORMAT_A8B8G8R8_UNORM:
1006
return PIPE_FORMAT_A8B8G8R8_SRGB;
1007
case PIPE_FORMAT_X8B8G8R8_UNORM:
1008
return PIPE_FORMAT_X8B8G8R8_SRGB;
1009
case PIPE_FORMAT_B8G8R8A8_UNORM:
1010
return PIPE_FORMAT_B8G8R8A8_SRGB;
1011
case PIPE_FORMAT_B8G8R8X8_UNORM:
1012
return PIPE_FORMAT_B8G8R8X8_SRGB;
1013
case PIPE_FORMAT_A8R8G8B8_UNORM:
1014
return PIPE_FORMAT_A8R8G8B8_SRGB;
1015
case PIPE_FORMAT_X8R8G8B8_UNORM:
1016
return PIPE_FORMAT_X8R8G8B8_SRGB;
1017
case PIPE_FORMAT_R8G8B8A8_UNORM:
1018
return PIPE_FORMAT_R8G8B8A8_SRGB;
1019
case PIPE_FORMAT_R8G8B8X8_UNORM:
1020
return PIPE_FORMAT_R8G8B8X8_SRGB;
1021
case PIPE_FORMAT_DXT1_RGB:
1022
return PIPE_FORMAT_DXT1_SRGB;
1023
case PIPE_FORMAT_DXT1_RGBA:
1024
return PIPE_FORMAT_DXT1_SRGBA;
1025
case PIPE_FORMAT_DXT3_RGBA:
1026
return PIPE_FORMAT_DXT3_SRGBA;
1027
case PIPE_FORMAT_DXT5_RGBA:
1028
return PIPE_FORMAT_DXT5_SRGBA;
1029
case PIPE_FORMAT_R5G6B5_UNORM:
1030
return PIPE_FORMAT_R5G6B5_SRGB;
1031
case PIPE_FORMAT_B5G6R5_UNORM:
1032
return PIPE_FORMAT_B5G6R5_SRGB;
1033
case PIPE_FORMAT_BPTC_RGBA_UNORM:
1034
return PIPE_FORMAT_BPTC_SRGBA;
1035
case PIPE_FORMAT_ETC2_RGB8:
1036
return PIPE_FORMAT_ETC2_SRGB8;
1037
case PIPE_FORMAT_ETC2_RGB8A1:
1038
return PIPE_FORMAT_ETC2_SRGB8A1;
1039
case PIPE_FORMAT_ETC2_RGBA8:
1040
return PIPE_FORMAT_ETC2_SRGBA8;
1041
case PIPE_FORMAT_ASTC_4x4:
1042
return PIPE_FORMAT_ASTC_4x4_SRGB;
1043
case PIPE_FORMAT_ASTC_5x4:
1044
return PIPE_FORMAT_ASTC_5x4_SRGB;
1045
case PIPE_FORMAT_ASTC_5x5:
1046
return PIPE_FORMAT_ASTC_5x5_SRGB;
1047
case PIPE_FORMAT_ASTC_6x5:
1048
return PIPE_FORMAT_ASTC_6x5_SRGB;
1049
case PIPE_FORMAT_ASTC_6x6:
1050
return PIPE_FORMAT_ASTC_6x6_SRGB;
1051
case PIPE_FORMAT_ASTC_8x5:
1052
return PIPE_FORMAT_ASTC_8x5_SRGB;
1053
case PIPE_FORMAT_ASTC_8x6:
1054
return PIPE_FORMAT_ASTC_8x6_SRGB;
1055
case PIPE_FORMAT_ASTC_8x8:
1056
return PIPE_FORMAT_ASTC_8x8_SRGB;
1057
case PIPE_FORMAT_ASTC_10x5:
1058
return PIPE_FORMAT_ASTC_10x5_SRGB;
1059
case PIPE_FORMAT_ASTC_10x6:
1060
return PIPE_FORMAT_ASTC_10x6_SRGB;
1061
case PIPE_FORMAT_ASTC_10x8:
1062
return PIPE_FORMAT_ASTC_10x8_SRGB;
1063
case PIPE_FORMAT_ASTC_10x10:
1064
return PIPE_FORMAT_ASTC_10x10_SRGB;
1065
case PIPE_FORMAT_ASTC_12x10:
1066
return PIPE_FORMAT_ASTC_12x10_SRGB;
1067
case PIPE_FORMAT_ASTC_12x12:
1068
return PIPE_FORMAT_ASTC_12x12_SRGB;
1069
case PIPE_FORMAT_ASTC_3x3x3:
1070
return PIPE_FORMAT_ASTC_3x3x3_SRGB;
1071
case PIPE_FORMAT_ASTC_4x3x3:
1072
return PIPE_FORMAT_ASTC_4x3x3_SRGB;
1073
case PIPE_FORMAT_ASTC_4x4x3:
1074
return PIPE_FORMAT_ASTC_4x4x3_SRGB;
1075
case PIPE_FORMAT_ASTC_4x4x4:
1076
return PIPE_FORMAT_ASTC_4x4x4_SRGB;
1077
case PIPE_FORMAT_ASTC_5x4x4:
1078
return PIPE_FORMAT_ASTC_5x4x4_SRGB;
1079
case PIPE_FORMAT_ASTC_5x5x4:
1080
return PIPE_FORMAT_ASTC_5x5x4_SRGB;
1081
case PIPE_FORMAT_ASTC_5x5x5:
1082
return PIPE_FORMAT_ASTC_5x5x5_SRGB;
1083
case PIPE_FORMAT_ASTC_6x5x5:
1084
return PIPE_FORMAT_ASTC_6x5x5_SRGB;
1085
case PIPE_FORMAT_ASTC_6x6x5:
1086
return PIPE_FORMAT_ASTC_6x6x5_SRGB;
1087
case PIPE_FORMAT_ASTC_6x6x6:
1088
return PIPE_FORMAT_ASTC_6x6x6_SRGB;
1089
1090
default:
1091
return PIPE_FORMAT_NONE;
1092
}
1093
}
1094
1095
/**
1096
* Given an sRGB format, return the corresponding linear colorspace format.
1097
* For non sRGB formats, return the format unchanged.
1098
*/
1099
static inline enum pipe_format
1100
util_format_linear(enum pipe_format format)
1101
{
1102
switch (format) {
1103
case PIPE_FORMAT_L8_SRGB:
1104
return PIPE_FORMAT_L8_UNORM;
1105
case PIPE_FORMAT_R8_SRGB:
1106
return PIPE_FORMAT_R8_UNORM;
1107
case PIPE_FORMAT_L8A8_SRGB:
1108
return PIPE_FORMAT_L8A8_UNORM;
1109
case PIPE_FORMAT_R8G8_SRGB:
1110
return PIPE_FORMAT_R8G8_UNORM;
1111
case PIPE_FORMAT_R8G8B8_SRGB:
1112
return PIPE_FORMAT_R8G8B8_UNORM;
1113
case PIPE_FORMAT_B8G8R8_SRGB:
1114
return PIPE_FORMAT_B8G8R8_UNORM;
1115
case PIPE_FORMAT_A8B8G8R8_SRGB:
1116
return PIPE_FORMAT_A8B8G8R8_UNORM;
1117
case PIPE_FORMAT_X8B8G8R8_SRGB:
1118
return PIPE_FORMAT_X8B8G8R8_UNORM;
1119
case PIPE_FORMAT_B8G8R8A8_SRGB:
1120
return PIPE_FORMAT_B8G8R8A8_UNORM;
1121
case PIPE_FORMAT_B8G8R8X8_SRGB:
1122
return PIPE_FORMAT_B8G8R8X8_UNORM;
1123
case PIPE_FORMAT_A8R8G8B8_SRGB:
1124
return PIPE_FORMAT_A8R8G8B8_UNORM;
1125
case PIPE_FORMAT_X8R8G8B8_SRGB:
1126
return PIPE_FORMAT_X8R8G8B8_UNORM;
1127
case PIPE_FORMAT_R8G8B8A8_SRGB:
1128
return PIPE_FORMAT_R8G8B8A8_UNORM;
1129
case PIPE_FORMAT_R8G8B8X8_SRGB:
1130
return PIPE_FORMAT_R8G8B8X8_UNORM;
1131
case PIPE_FORMAT_DXT1_SRGB:
1132
return PIPE_FORMAT_DXT1_RGB;
1133
case PIPE_FORMAT_DXT1_SRGBA:
1134
return PIPE_FORMAT_DXT1_RGBA;
1135
case PIPE_FORMAT_DXT3_SRGBA:
1136
return PIPE_FORMAT_DXT3_RGBA;
1137
case PIPE_FORMAT_DXT5_SRGBA:
1138
return PIPE_FORMAT_DXT5_RGBA;
1139
case PIPE_FORMAT_R5G6B5_SRGB:
1140
return PIPE_FORMAT_R5G6B5_UNORM;
1141
case PIPE_FORMAT_B5G6R5_SRGB:
1142
return PIPE_FORMAT_B5G6R5_UNORM;
1143
case PIPE_FORMAT_BPTC_SRGBA:
1144
return PIPE_FORMAT_BPTC_RGBA_UNORM;
1145
case PIPE_FORMAT_ETC2_SRGB8:
1146
return PIPE_FORMAT_ETC2_RGB8;
1147
case PIPE_FORMAT_ETC2_SRGB8A1:
1148
return PIPE_FORMAT_ETC2_RGB8A1;
1149
case PIPE_FORMAT_ETC2_SRGBA8:
1150
return PIPE_FORMAT_ETC2_RGBA8;
1151
case PIPE_FORMAT_ASTC_4x4_SRGB:
1152
return PIPE_FORMAT_ASTC_4x4;
1153
case PIPE_FORMAT_ASTC_5x4_SRGB:
1154
return PIPE_FORMAT_ASTC_5x4;
1155
case PIPE_FORMAT_ASTC_5x5_SRGB:
1156
return PIPE_FORMAT_ASTC_5x5;
1157
case PIPE_FORMAT_ASTC_6x5_SRGB:
1158
return PIPE_FORMAT_ASTC_6x5;
1159
case PIPE_FORMAT_ASTC_6x6_SRGB:
1160
return PIPE_FORMAT_ASTC_6x6;
1161
case PIPE_FORMAT_ASTC_8x5_SRGB:
1162
return PIPE_FORMAT_ASTC_8x5;
1163
case PIPE_FORMAT_ASTC_8x6_SRGB:
1164
return PIPE_FORMAT_ASTC_8x6;
1165
case PIPE_FORMAT_ASTC_8x8_SRGB:
1166
return PIPE_FORMAT_ASTC_8x8;
1167
case PIPE_FORMAT_ASTC_10x5_SRGB:
1168
return PIPE_FORMAT_ASTC_10x5;
1169
case PIPE_FORMAT_ASTC_10x6_SRGB:
1170
return PIPE_FORMAT_ASTC_10x6;
1171
case PIPE_FORMAT_ASTC_10x8_SRGB:
1172
return PIPE_FORMAT_ASTC_10x8;
1173
case PIPE_FORMAT_ASTC_10x10_SRGB:
1174
return PIPE_FORMAT_ASTC_10x10;
1175
case PIPE_FORMAT_ASTC_12x10_SRGB:
1176
return PIPE_FORMAT_ASTC_12x10;
1177
case PIPE_FORMAT_ASTC_12x12_SRGB:
1178
return PIPE_FORMAT_ASTC_12x12;
1179
case PIPE_FORMAT_ASTC_3x3x3_SRGB:
1180
return PIPE_FORMAT_ASTC_3x3x3;
1181
case PIPE_FORMAT_ASTC_4x3x3_SRGB:
1182
return PIPE_FORMAT_ASTC_4x3x3;
1183
case PIPE_FORMAT_ASTC_4x4x3_SRGB:
1184
return PIPE_FORMAT_ASTC_4x4x3;
1185
case PIPE_FORMAT_ASTC_4x4x4_SRGB:
1186
return PIPE_FORMAT_ASTC_4x4x4;
1187
case PIPE_FORMAT_ASTC_5x4x4_SRGB:
1188
return PIPE_FORMAT_ASTC_5x4x4;
1189
case PIPE_FORMAT_ASTC_5x5x4_SRGB:
1190
return PIPE_FORMAT_ASTC_5x5x4;
1191
case PIPE_FORMAT_ASTC_5x5x5_SRGB:
1192
return PIPE_FORMAT_ASTC_5x5x5;
1193
case PIPE_FORMAT_ASTC_6x5x5_SRGB:
1194
return PIPE_FORMAT_ASTC_6x5x5;
1195
case PIPE_FORMAT_ASTC_6x6x5_SRGB:
1196
return PIPE_FORMAT_ASTC_6x6x5;
1197
case PIPE_FORMAT_ASTC_6x6x6_SRGB:
1198
return PIPE_FORMAT_ASTC_6x6x6;
1199
default:
1200
assert(!util_format_is_srgb(format));
1201
return format;
1202
}
1203
}
1204
1205
/**
1206
* Given a depth-stencil format, return the corresponding stencil-only format.
1207
* For stencil-only formats, return the format unchanged.
1208
*/
1209
static inline enum pipe_format
1210
util_format_stencil_only(enum pipe_format format)
1211
{
1212
switch (format) {
1213
/* mask out the depth component */
1214
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
1215
return PIPE_FORMAT_X24S8_UINT;
1216
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
1217
return PIPE_FORMAT_S8X24_UINT;
1218
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
1219
return PIPE_FORMAT_X32_S8X24_UINT;
1220
1221
/* stencil only formats */
1222
case PIPE_FORMAT_X24S8_UINT:
1223
case PIPE_FORMAT_S8X24_UINT:
1224
case PIPE_FORMAT_X32_S8X24_UINT:
1225
case PIPE_FORMAT_S8_UINT:
1226
return format;
1227
1228
default:
1229
assert(0);
1230
return PIPE_FORMAT_NONE;
1231
}
1232
}
1233
1234
/**
1235
* Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*.
1236
* This is identity for non-intensity formats.
1237
*/
1238
static inline enum pipe_format
1239
util_format_intensity_to_red(enum pipe_format format)
1240
{
1241
switch (format) {
1242
case PIPE_FORMAT_I8_UNORM:
1243
return PIPE_FORMAT_R8_UNORM;
1244
case PIPE_FORMAT_I8_SNORM:
1245
return PIPE_FORMAT_R8_SNORM;
1246
case PIPE_FORMAT_I16_UNORM:
1247
return PIPE_FORMAT_R16_UNORM;
1248
case PIPE_FORMAT_I16_SNORM:
1249
return PIPE_FORMAT_R16_SNORM;
1250
case PIPE_FORMAT_I16_FLOAT:
1251
return PIPE_FORMAT_R16_FLOAT;
1252
case PIPE_FORMAT_I32_FLOAT:
1253
return PIPE_FORMAT_R32_FLOAT;
1254
case PIPE_FORMAT_I8_UINT:
1255
return PIPE_FORMAT_R8_UINT;
1256
case PIPE_FORMAT_I8_SINT:
1257
return PIPE_FORMAT_R8_SINT;
1258
case PIPE_FORMAT_I16_UINT:
1259
return PIPE_FORMAT_R16_UINT;
1260
case PIPE_FORMAT_I16_SINT:
1261
return PIPE_FORMAT_R16_SINT;
1262
case PIPE_FORMAT_I32_UINT:
1263
return PIPE_FORMAT_R32_UINT;
1264
case PIPE_FORMAT_I32_SINT:
1265
return PIPE_FORMAT_R32_SINT;
1266
default:
1267
assert(!util_format_is_intensity(format));
1268
return format;
1269
}
1270
}
1271
1272
/**
1273
* Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*.
1274
* This is identity for non-luminance formats.
1275
*/
1276
static inline enum pipe_format
1277
util_format_luminance_to_red(enum pipe_format format)
1278
{
1279
switch (format) {
1280
case PIPE_FORMAT_L8_UNORM:
1281
return PIPE_FORMAT_R8_UNORM;
1282
case PIPE_FORMAT_L8_SNORM:
1283
return PIPE_FORMAT_R8_SNORM;
1284
case PIPE_FORMAT_L16_UNORM:
1285
return PIPE_FORMAT_R16_UNORM;
1286
case PIPE_FORMAT_L16_SNORM:
1287
return PIPE_FORMAT_R16_SNORM;
1288
case PIPE_FORMAT_L16_FLOAT:
1289
return PIPE_FORMAT_R16_FLOAT;
1290
case PIPE_FORMAT_L32_FLOAT:
1291
return PIPE_FORMAT_R32_FLOAT;
1292
case PIPE_FORMAT_L8_UINT:
1293
return PIPE_FORMAT_R8_UINT;
1294
case PIPE_FORMAT_L8_SINT:
1295
return PIPE_FORMAT_R8_SINT;
1296
case PIPE_FORMAT_L16_UINT:
1297
return PIPE_FORMAT_R16_UINT;
1298
case PIPE_FORMAT_L16_SINT:
1299
return PIPE_FORMAT_R16_SINT;
1300
case PIPE_FORMAT_L32_UINT:
1301
return PIPE_FORMAT_R32_UINT;
1302
case PIPE_FORMAT_L32_SINT:
1303
return PIPE_FORMAT_R32_SINT;
1304
1305
case PIPE_FORMAT_LATC1_UNORM:
1306
return PIPE_FORMAT_RGTC1_UNORM;
1307
case PIPE_FORMAT_LATC1_SNORM:
1308
return PIPE_FORMAT_RGTC1_SNORM;
1309
1310
case PIPE_FORMAT_L4A4_UNORM:
1311
return PIPE_FORMAT_R4A4_UNORM;
1312
1313
case PIPE_FORMAT_L8A8_UNORM:
1314
return PIPE_FORMAT_R8A8_UNORM;
1315
case PIPE_FORMAT_L8A8_SNORM:
1316
return PIPE_FORMAT_R8A8_SNORM;
1317
case PIPE_FORMAT_L16A16_UNORM:
1318
return PIPE_FORMAT_R16A16_UNORM;
1319
case PIPE_FORMAT_L16A16_SNORM:
1320
return PIPE_FORMAT_R16A16_SNORM;
1321
case PIPE_FORMAT_L16A16_FLOAT:
1322
return PIPE_FORMAT_R16A16_FLOAT;
1323
case PIPE_FORMAT_L32A32_FLOAT:
1324
return PIPE_FORMAT_R32A32_FLOAT;
1325
case PIPE_FORMAT_L8A8_UINT:
1326
return PIPE_FORMAT_R8A8_UINT;
1327
case PIPE_FORMAT_L8A8_SINT:
1328
return PIPE_FORMAT_R8A8_SINT;
1329
case PIPE_FORMAT_L16A16_UINT:
1330
return PIPE_FORMAT_R16A16_UINT;
1331
case PIPE_FORMAT_L16A16_SINT:
1332
return PIPE_FORMAT_R16A16_SINT;
1333
case PIPE_FORMAT_L32A32_UINT:
1334
return PIPE_FORMAT_R32A32_UINT;
1335
case PIPE_FORMAT_L32A32_SINT:
1336
return PIPE_FORMAT_R32A32_SINT;
1337
1338
/* We don't have compressed red-alpha variants for these. */
1339
case PIPE_FORMAT_LATC2_UNORM:
1340
case PIPE_FORMAT_LATC2_SNORM:
1341
return PIPE_FORMAT_NONE;
1342
1343
default:
1344
assert(!util_format_is_luminance(format) &&
1345
!util_format_is_luminance_alpha(format));
1346
return format;
1347
}
1348
}
1349
1350
static inline unsigned
1351
util_format_get_num_planes(enum pipe_format format)
1352
{
1353
switch (util_format_description(format)->layout) {
1354
case UTIL_FORMAT_LAYOUT_PLANAR3:
1355
return 3;
1356
case UTIL_FORMAT_LAYOUT_PLANAR2:
1357
return 2;
1358
default:
1359
return 1;
1360
}
1361
}
1362
1363
static inline enum pipe_format
1364
util_format_get_plane_format(enum pipe_format format, unsigned plane)
1365
{
1366
switch (format) {
1367
case PIPE_FORMAT_YV12:
1368
case PIPE_FORMAT_YV16:
1369
case PIPE_FORMAT_IYUV:
1370
case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
1371
case PIPE_FORMAT_Y8_U8_V8_444_UNORM:
1372
return PIPE_FORMAT_R8_UNORM;
1373
case PIPE_FORMAT_NV12:
1374
case PIPE_FORMAT_Y8_U8V8_422_UNORM:
1375
return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_RG88_UNORM;
1376
case PIPE_FORMAT_NV21:
1377
return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_GR88_UNORM;
1378
case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1379
case PIPE_FORMAT_Y16_U16_V16_422_UNORM:
1380
case PIPE_FORMAT_Y16_U16_V16_444_UNORM:
1381
return PIPE_FORMAT_R16_UNORM;
1382
case PIPE_FORMAT_P010:
1383
case PIPE_FORMAT_P012:
1384
case PIPE_FORMAT_P016:
1385
case PIPE_FORMAT_Y16_U16V16_422_UNORM:
1386
return !plane ? PIPE_FORMAT_R16_UNORM : PIPE_FORMAT_R16G16_UNORM;
1387
default:
1388
return format;
1389
}
1390
}
1391
1392
static inline unsigned
1393
util_format_get_plane_width(enum pipe_format format, unsigned plane,
1394
unsigned width)
1395
{
1396
switch (format) {
1397
case PIPE_FORMAT_YV12:
1398
case PIPE_FORMAT_YV16:
1399
case PIPE_FORMAT_IYUV:
1400
case PIPE_FORMAT_NV12:
1401
case PIPE_FORMAT_NV21:
1402
case PIPE_FORMAT_P010:
1403
case PIPE_FORMAT_P012:
1404
case PIPE_FORMAT_P016:
1405
case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
1406
case PIPE_FORMAT_Y8_U8V8_422_UNORM:
1407
case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1408
case PIPE_FORMAT_Y16_U16_V16_422_UNORM:
1409
case PIPE_FORMAT_Y16_U16V16_422_UNORM:
1410
return !plane ? width : (width + 1) / 2;
1411
default:
1412
return width;
1413
}
1414
}
1415
1416
static inline unsigned
1417
util_format_get_plane_height(enum pipe_format format, unsigned plane,
1418
unsigned height)
1419
{
1420
switch (format) {
1421
case PIPE_FORMAT_YV12:
1422
case PIPE_FORMAT_IYUV:
1423
case PIPE_FORMAT_NV12:
1424
case PIPE_FORMAT_NV21:
1425
case PIPE_FORMAT_P010:
1426
case PIPE_FORMAT_P012:
1427
case PIPE_FORMAT_P016:
1428
case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1429
return !plane ? height : (height + 1) / 2;
1430
case PIPE_FORMAT_YV16:
1431
default:
1432
return height;
1433
}
1434
}
1435
1436
/**
1437
* Return the number of components stored.
1438
* Formats with block size != 1x1 will always have 1 component (the block).
1439
*/
1440
static inline unsigned
1441
util_format_get_nr_components(enum pipe_format format)
1442
{
1443
const struct util_format_description *desc = util_format_description(format);
1444
return desc->nr_channels;
1445
}
1446
1447
/**
1448
* Return the index of the first non-void channel
1449
* -1 if no non-void channels
1450
*/
1451
static inline int
1452
util_format_get_first_non_void_channel(enum pipe_format format)
1453
{
1454
const struct util_format_description *desc = util_format_description(format);
1455
int i;
1456
1457
for (i = 0; i < 4; i++)
1458
if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
1459
break;
1460
1461
if (i == 4)
1462
return -1;
1463
1464
return i;
1465
}
1466
1467
/**
1468
* Whether this format is any 8-bit UNORM variant. Looser than
1469
* util_is_rgba8_variant (also includes alpha textures, for instance).
1470
*/
1471
1472
static inline bool
1473
util_format_is_unorm8(const struct util_format_description *desc)
1474
{
1475
int c = util_format_get_first_non_void_channel(desc->format);
1476
1477
if (c == -1)
1478
return false;
1479
1480
return desc->is_unorm && desc->is_array && desc->channel[c].size == 8;
1481
}
1482
1483
static inline void
1484
util_format_unpack_z_float(enum pipe_format format, float *dst,
1485
const void *src, unsigned w)
1486
{
1487
const struct util_format_unpack_description *desc =
1488
util_format_unpack_description(format);
1489
1490
desc->unpack_z_float(dst, 0, (const uint8_t *)src, 0, w, 1);
1491
}
1492
1493
static inline void
1494
util_format_unpack_z_32unorm(enum pipe_format format, uint32_t *dst,
1495
const void *src, unsigned w)
1496
{
1497
const struct util_format_unpack_description *desc =
1498
util_format_unpack_description(format);
1499
1500
desc->unpack_z_32unorm(dst, 0, (const uint8_t *)src, 0, w, 1);
1501
}
1502
1503
static inline void
1504
util_format_unpack_s_8uint(enum pipe_format format, uint8_t *dst,
1505
const void *src, unsigned w)
1506
{
1507
const struct util_format_unpack_description *desc =
1508
util_format_unpack_description(format);
1509
1510
desc->unpack_s_8uint(dst, 0, (const uint8_t *)src, 0, w, 1);
1511
}
1512
1513
/**
1514
* Unpacks a row of color data to 32-bit RGBA, either integers for pure
1515
* integer formats (sign-extended for signed data), or 32-bit floats.
1516
*/
1517
static inline void
1518
util_format_unpack_rgba(enum pipe_format format, void *dst,
1519
const void *src, unsigned w)
1520
{
1521
const struct util_format_unpack_description *desc =
1522
util_format_unpack_description(format);
1523
1524
desc->unpack_rgba(dst, (const uint8_t *)src, w);
1525
}
1526
1527
static inline void
1528
util_format_pack_z_float(enum pipe_format format, void *dst,
1529
const float *src, unsigned w)
1530
{
1531
const struct util_format_pack_description *desc =
1532
util_format_pack_description(format);
1533
1534
desc->pack_z_float((uint8_t *)dst, 0, src, 0, w, 1);
1535
}
1536
1537
static inline void
1538
util_format_pack_z_32unorm(enum pipe_format format, void *dst,
1539
const uint32_t *src, unsigned w)
1540
{
1541
const struct util_format_pack_description *desc =
1542
util_format_pack_description(format);
1543
1544
desc->pack_z_32unorm((uint8_t *)dst, 0, src, 0, w, 1);
1545
}
1546
1547
static inline void
1548
util_format_pack_s_8uint(enum pipe_format format, void *dst,
1549
const uint8_t *src, unsigned w)
1550
{
1551
const struct util_format_pack_description *desc =
1552
util_format_pack_description(format);
1553
1554
desc->pack_s_8uint((uint8_t *)dst, 0, src, 0, w, 1);
1555
}
1556
1557
/**
1558
* Packs a row of color data from 32-bit RGBA, either integers for pure
1559
* integer formats, or 32-bit floats. Values are clamped to the packed
1560
* representation's range.
1561
*/
1562
static inline void
1563
util_format_pack_rgba(enum pipe_format format, void *dst,
1564
const void *src, unsigned w)
1565
{
1566
const struct util_format_pack_description *desc =
1567
util_format_pack_description(format);
1568
1569
if (util_format_is_pure_uint(format))
1570
desc->pack_rgba_uint((uint8_t *)dst, 0, (const uint32_t *)src, 0, w, 1);
1571
else if (util_format_is_pure_sint(format))
1572
desc->pack_rgba_sint((uint8_t *)dst, 0, (const int32_t *)src, 0, w, 1);
1573
else
1574
desc->pack_rgba_float((uint8_t *)dst, 0, (const float *)src, 0, w, 1);
1575
}
1576
1577
/*
1578
* Format access functions for subrectangles
1579
*/
1580
1581
void
1582
util_format_read_4(enum pipe_format format,
1583
void *dst, unsigned dst_stride,
1584
const void *src, unsigned src_stride,
1585
unsigned x, unsigned y, unsigned w, unsigned h);
1586
1587
void
1588
util_format_write_4(enum pipe_format format,
1589
const void *src, unsigned src_stride,
1590
void *dst, unsigned dst_stride,
1591
unsigned x, unsigned y, unsigned w, unsigned h);
1592
1593
void
1594
util_format_read_4ub(enum pipe_format format,
1595
uint8_t *dst, unsigned dst_stride,
1596
const void *src, unsigned src_stride,
1597
unsigned x, unsigned y, unsigned w, unsigned h);
1598
1599
void
1600
util_format_write_4ub(enum pipe_format format,
1601
const uint8_t *src, unsigned src_stride,
1602
void *dst, unsigned dst_stride,
1603
unsigned x, unsigned y, unsigned w, unsigned h);
1604
1605
void
1606
util_format_unpack_rgba_rect(enum pipe_format format,
1607
void *dst, unsigned dst_stride,
1608
const void *src, unsigned src_stride,
1609
unsigned w, unsigned h);
1610
1611
void
1612
util_format_unpack_rgba_8unorm_rect(enum pipe_format format,
1613
void *dst, unsigned dst_stride,
1614
const void *src, unsigned src_stride,
1615
unsigned w, unsigned h);
1616
1617
/*
1618
* Generic format conversion;
1619
*/
1620
1621
boolean
1622
util_format_fits_8unorm(const struct util_format_description *format_desc) ATTRIBUTE_CONST;
1623
1624
boolean
1625
util_format_translate(enum pipe_format dst_format,
1626
void *dst, unsigned dst_stride,
1627
unsigned dst_x, unsigned dst_y,
1628
enum pipe_format src_format,
1629
const void *src, unsigned src_stride,
1630
unsigned src_x, unsigned src_y,
1631
unsigned width, unsigned height);
1632
1633
boolean
1634
util_format_translate_3d(enum pipe_format dst_format,
1635
void *dst, unsigned dst_stride,
1636
unsigned dst_slice_stride,
1637
unsigned dst_x, unsigned dst_y,
1638
unsigned dst_z,
1639
enum pipe_format src_format,
1640
const void *src, unsigned src_stride,
1641
unsigned src_slice_stride,
1642
unsigned src_x, unsigned src_y,
1643
unsigned src_z, unsigned width,
1644
unsigned height, unsigned depth);
1645
1646
/*
1647
* Swizzle operations.
1648
*/
1649
1650
/* Compose two sets of swizzles.
1651
* If V is a 4D vector and the function parameters represent functions that
1652
* swizzle vector components, this holds:
1653
* swz2(swz1(V)) = dst(V)
1654
*/
1655
void util_format_compose_swizzles(const unsigned char swz1[4],
1656
const unsigned char swz2[4],
1657
unsigned char dst[4]);
1658
1659
/* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x)
1660
* to \param src and store the result in \param dst.
1661
* \param is_integer determines the value written for PIPE_SWIZZLE_1.
1662
*/
1663
void util_format_apply_color_swizzle(union pipe_color_union *dst,
1664
const union pipe_color_union *src,
1665
const unsigned char swz[4],
1666
const boolean is_integer);
1667
1668
void pipe_swizzle_4f(float *dst, const float *src,
1669
const unsigned char swz[4]);
1670
1671
void util_format_unswizzle_4f(float *dst, const float *src,
1672
const unsigned char swz[4]);
1673
1674
enum pipe_format
1675
util_format_snorm8_to_sint8(enum pipe_format format) ATTRIBUTE_CONST;
1676
1677
1678
extern void
1679
util_copy_rect(ubyte * dst, enum pipe_format format,
1680
unsigned dst_stride, unsigned dst_x, unsigned dst_y,
1681
unsigned width, unsigned height, const ubyte * src,
1682
int src_stride, unsigned src_x, unsigned src_y);
1683
1684
/**
1685
* If the format is RGB, return BGR. If the format is BGR, return RGB.
1686
* This may fail by returning PIPE_FORMAT_NONE.
1687
*/
1688
enum pipe_format
1689
util_format_rgb_to_bgr(enum pipe_format format);
1690
1691
#ifdef __cplusplus
1692
} // extern "C" {
1693
#endif
1694
1695
#endif /* ! U_FORMAT_H */
1696
1697