Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 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
 
39
 
40
#ifdef __cplusplus
41
extern "C" {
42
#endif
43
 
44
 
45
/**
46
 * Describe how to pack/unpack pixels into/from the prescribed format.
47
 *
48
 * XXX: This could be renamed to something like util_format_pack, or broke down
49
 * in flags inside util_format_block that said exactly what we want.
50
 */
51
enum util_format_layout {
52
   /**
53
    * Formats with util_format_block::width == util_format_block::height == 1
54
    * that can be described as an ordinary data structure.
55
    */
56
   UTIL_FORMAT_LAYOUT_PLAIN = 0,
57
 
58
   /**
59
    * Formats with sub-sampled channels.
60
    *
61
    * This is for formats like YVYU where there is less than one sample per
62
    * pixel.
63
    */
64
   UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
65
 
66
   /**
67
    * S3 Texture Compression formats.
68
    */
69
   UTIL_FORMAT_LAYOUT_S3TC = 4,
70
 
71
   /**
72
    * Red-Green Texture Compression formats.
73
    */
74
   UTIL_FORMAT_LAYOUT_RGTC = 5,
75
 
76
   /**
77
    * Ericsson Texture Compression
78
    */
79
   UTIL_FORMAT_LAYOUT_ETC = 6,
80
 
81
   /**
82
    * BC6/7 Texture Compression
83
    */
84
   UTIL_FORMAT_LAYOUT_BPTC = 7,
85
 
86
   /**
87
    * Everything else that doesn't fit in any of the above layouts.
88
    */
89
   UTIL_FORMAT_LAYOUT_OTHER = 8
90
};
91
 
92
 
93
struct util_format_block
94
{
95
   /** Block width in pixels */
96
   unsigned width;
97
 
98
   /** Block height in pixels */
99
   unsigned height;
100
 
101
   /** Block size in bits */
102
   unsigned bits;
103
};
104
 
105
 
106
enum util_format_type {
107
   UTIL_FORMAT_TYPE_VOID = 0,
108
   UTIL_FORMAT_TYPE_UNSIGNED = 1,
109
   UTIL_FORMAT_TYPE_SIGNED = 2,
110
   UTIL_FORMAT_TYPE_FIXED = 3,
111
   UTIL_FORMAT_TYPE_FLOAT = 4
112
};
113
 
114
 
115
enum util_format_swizzle {
116
   UTIL_FORMAT_SWIZZLE_X = 0,
117
   UTIL_FORMAT_SWIZZLE_Y = 1,
118
   UTIL_FORMAT_SWIZZLE_Z = 2,
119
   UTIL_FORMAT_SWIZZLE_W = 3,
120
   UTIL_FORMAT_SWIZZLE_0 = 4,
121
   UTIL_FORMAT_SWIZZLE_1 = 5,
122
   UTIL_FORMAT_SWIZZLE_NONE = 6,
123
   UTIL_FORMAT_SWIZZLE_MAX = 7  /**< Number of enums counter (must be last) */
124
};
125
 
126
 
127
enum util_format_colorspace {
128
   UTIL_FORMAT_COLORSPACE_RGB = 0,
129
   UTIL_FORMAT_COLORSPACE_SRGB = 1,
130
   UTIL_FORMAT_COLORSPACE_YUV = 2,
131
   UTIL_FORMAT_COLORSPACE_ZS = 3
132
};
133
 
134
 
135
struct util_format_channel_description
136
{
137
   unsigned type:5;        /**< UTIL_FORMAT_TYPE_x */
138
   unsigned normalized:1;
139
   unsigned pure_integer:1;
140
   unsigned size:9;        /**< bits per channel */
141
   unsigned shift:16;      /** number of bits from lsb */
142
};
143
 
144
 
145
struct util_format_description
146
{
147
   enum pipe_format format;
148
 
149
   const char *name;
150
 
151
   /**
152
    * Short name, striped of the prefix, lower case.
153
    */
154
   const char *short_name;
155
 
156
   /**
157
    * Pixel block dimensions.
158
    */
159
   struct util_format_block block;
160
 
161
   enum util_format_layout layout;
162
 
163
   /**
164
    * The number of channels.
165
    */
166
   unsigned nr_channels:3;
167
 
168
   /**
169
    * Whether all channels have the same number of (whole) bytes and type.
170
    */
171
   unsigned is_array:1;
172
 
173
   /**
174
    * Whether the pixel format can be described as a bitfield structure.
175
    *
176
    * In particular:
177
    * - pixel depth must be 8, 16, or 32 bits;
178
    * - all channels must be unsigned, signed, or void
179
    */
180
   unsigned is_bitmask:1;
181
 
182
   /**
183
    * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
184
    */
185
   unsigned is_mixed:1;
186
 
187
   /**
188
    * Input channel description, in the order XYZW.
189
    *
190
    * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
191
    *
192
    * If each channel is accessed as an individual N-byte value, X is always
193
    * at the lowest address in memory, Y is always next, and so on.  For all
194
    * currently-defined formats, the N-byte value has native endianness.
195
    *
196
    * If instead a group of channels is accessed as a single N-byte value,
197
    * the order of the channels within that value depends on endianness.
198
    * For big-endian targets, X is the most significant subvalue,
199
    * otherwise it is the least significant one.
200
    *
201
    * For example, if X is 8 bits and Y is 24 bits, the memory order is:
202
    *
203
    *                 0  1  2  3
204
    *  little-endian: X  Yl Ym Yu    (l = lower, m = middle, u = upper)
205
    *  big-endian:    X  Yu Ym Yl
206
    *
207
    * If X is 5 bits, Y is 5 bits, Z is 5 bits and W is 1 bit, the layout is:
208
    *
209
    *                        0        1
210
    *                 msb  lsb msb  lsb
211
    *  little-endian: YYYXXXXX WZZZZZYY
212
    *  big-endian:    XXXXXYYY YYZZZZZW
213
    */
214
   struct util_format_channel_description channel[4];
215
 
216
   /**
217
    * Output channel swizzle.
218
    *
219
    * The order is either:
220
    * - RGBA
221
    * - YUV(A)
222
    * - ZS
223
    * depending on the colorspace.
224
    */
225
   unsigned char swizzle[4];
226
 
227
   /**
228
    * Colorspace transformation.
229
    */
230
   enum util_format_colorspace colorspace;
231
 
232
   /**
233
    * Unpack pixel blocks to R8G8B8A8_UNORM.
234
    * Note: strides are in bytes.
235
    *
236
    * Only defined for non-depth-stencil formats.
237
    */
238
   void
239
   (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
240
                         const uint8_t *src, unsigned src_stride,
241
                         unsigned width, unsigned height);
242
 
243
   /**
244
    * Pack pixel blocks from R8G8B8A8_UNORM.
245
    * Note: strides are in bytes.
246
    *
247
    * Only defined for non-depth-stencil formats.
248
    */
249
   void
250
   (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
251
                       const uint8_t *src, unsigned src_stride,
252
                       unsigned width, unsigned height);
253
 
254
   /**
255
    * Fetch a single pixel (i, j) from a block.
256
    *
257
    * XXX: Only defined for a very few select formats.
258
    */
259
   void
260
   (*fetch_rgba_8unorm)(uint8_t *dst,
261
                        const uint8_t *src,
262
                        unsigned i, unsigned j);
263
 
264
   /**
265
    * Unpack pixel blocks to R32G32B32A32_FLOAT.
266
    * Note: strides are in bytes.
267
    *
268
    * Only defined for non-depth-stencil formats.
269
    */
270
   void
271
   (*unpack_rgba_float)(float *dst, unsigned dst_stride,
272
                        const uint8_t *src, unsigned src_stride,
273
                        unsigned width, unsigned height);
274
 
275
   /**
276
    * Pack pixel blocks from R32G32B32A32_FLOAT.
277
    * Note: strides are in bytes.
278
    *
279
    * Only defined for non-depth-stencil formats.
280
    */
281
   void
282
   (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride,
283
                      const float *src, unsigned src_stride,
284
                      unsigned width, unsigned height);
285
 
286
   /**
287
    * Fetch a single pixel (i, j) from a block.
288
    *
289
    * Only defined for non-depth-stencil and non-integer formats.
290
    */
291
   void
292
   (*fetch_rgba_float)(float *dst,
293
                       const uint8_t *src,
294
                       unsigned i, unsigned j);
295
 
296
   /**
297
    * Unpack pixels to Z32_UNORM.
298
    * Note: strides are in bytes.
299
    *
300
    * Only defined for depth formats.
301
    */
302
   void
303
   (*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride,
304
                       const uint8_t *src, unsigned src_stride,
305
                       unsigned width, unsigned height);
306
 
307
   /**
308
    * Pack pixels from Z32_FLOAT.
309
    * Note: strides are in bytes.
310
    *
311
    * Only defined for depth formats.
312
    */
313
   void
314
   (*pack_z_32unorm)(uint8_t *dst, unsigned dst_stride,
315
                     const uint32_t *src, unsigned src_stride,
316
                     unsigned width, unsigned height);
317
 
318
   /**
319
    * Unpack pixels to Z32_FLOAT.
320
    * Note: strides are in bytes.
321
    *
322
    * Only defined for depth formats.
323
    */
324
   void
325
   (*unpack_z_float)(float *dst, unsigned dst_stride,
326
                     const uint8_t *src, unsigned src_stride,
327
                     unsigned width, unsigned height);
328
 
329
   /**
330
    * Pack pixels from Z32_FLOAT.
331
    * Note: strides are in bytes.
332
    *
333
    * Only defined for depth formats.
334
    */
335
   void
336
   (*pack_z_float)(uint8_t *dst, unsigned dst_stride,
337
                   const float *src, unsigned src_stride,
338
                   unsigned width, unsigned height);
339
 
340
   /**
341
    * Unpack pixels to S8_UINT.
342
    * Note: strides are in bytes.
343
    *
344
    * Only defined for stencil formats.
345
    */
346
   void
347
   (*unpack_s_8uint)(uint8_t *dst, unsigned dst_stride,
348
                     const uint8_t *src, unsigned src_stride,
349
                     unsigned width, unsigned height);
350
 
351
   /**
352
    * Pack pixels from S8_UINT.
353
    * Note: strides are in bytes.
354
    *
355
    * Only defined for stencil formats.
356
    */
357
   void
358
   (*pack_s_8uint)(uint8_t *dst, unsigned dst_stride,
359
                   const uint8_t *src, unsigned src_stride,
360
                   unsigned width, unsigned height);
361
 
362
  /**
363
    * Unpack pixel blocks to R32G32B32A32_UINT.
364
    * Note: strides are in bytes.
365
    *
366
    * Only defined for INT formats.
367
    */
368
   void
369
   (*unpack_rgba_uint)(uint32_t *dst, unsigned dst_stride,
370
                       const uint8_t *src, unsigned src_stride,
371
                       unsigned width, unsigned height);
372
 
373
   void
374
   (*pack_rgba_uint)(uint8_t *dst, unsigned dst_stride,
375
                     const uint32_t *src, unsigned src_stride,
376
                     unsigned width, unsigned height);
377
 
378
  /**
379
    * Unpack pixel blocks to R32G32B32A32_SINT.
380
    * Note: strides are in bytes.
381
    *
382
    * Only defined for INT formats.
383
    */
384
   void
385
   (*unpack_rgba_sint)(int32_t *dst, unsigned dst_stride,
386
                       const uint8_t *src, unsigned src_stride,
387
                       unsigned width, unsigned height);
388
 
389
   void
390
   (*pack_rgba_sint)(uint8_t *dst, unsigned dst_stride,
391
                     const int32_t *src, unsigned src_stride,
392
                     unsigned width, unsigned height);
393
 
394
   /**
395
    * Fetch a single pixel (i, j) from a block.
396
    *
397
    * Only defined for unsigned (pure) integer formats.
398
    */
399
   void
400
   (*fetch_rgba_uint)(uint32_t *dst,
401
                      const uint8_t *src,
402
                      unsigned i, unsigned j);
403
 
404
   /**
405
    * Fetch a single pixel (i, j) from a block.
406
    *
407
    * Only defined for signed (pure) integer formats.
408
    */
409
   void
410
   (*fetch_rgba_sint)(int32_t *dst,
411
                      const uint8_t *src,
412
                      unsigned i, unsigned j);
413
};
414
 
415
 
416
extern const struct util_format_description
417
util_format_description_table[];
418
 
419
 
420
const struct util_format_description *
421
util_format_description(enum pipe_format format);
422
 
423
 
424
/*
425
 * Format query functions.
426
 */
427
 
428
static INLINE const char *
429
util_format_name(enum pipe_format format)
430
{
431
   const struct util_format_description *desc = util_format_description(format);
432
 
433
   assert(desc);
434
   if (!desc) {
435
      return "PIPE_FORMAT_???";
436
   }
437
 
438
   return desc->name;
439
}
440
 
441
static INLINE const char *
442
util_format_short_name(enum pipe_format format)
443
{
444
   const struct util_format_description *desc = util_format_description(format);
445
 
446
   assert(desc);
447
   if (!desc) {
448
      return "???";
449
   }
450
 
451
   return desc->short_name;
452
}
453
 
454
/**
455
 * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
456
 */
457
static INLINE boolean
458
util_format_is_plain(enum pipe_format format)
459
{
460
   const struct util_format_description *desc = util_format_description(format);
461
 
462
   if (!format) {
463
      return FALSE;
464
   }
465
 
466
   return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
467
}
468
 
469
static INLINE boolean
470
util_format_is_compressed(enum pipe_format format)
471
{
472
   const struct util_format_description *desc = util_format_description(format);
473
 
474
   assert(desc);
475
   if (!desc) {
476
      return FALSE;
477
   }
478
 
479
   switch (desc->layout) {
480
   case UTIL_FORMAT_LAYOUT_S3TC:
481
   case UTIL_FORMAT_LAYOUT_RGTC:
482
   case UTIL_FORMAT_LAYOUT_ETC:
483
   case UTIL_FORMAT_LAYOUT_BPTC:
484
      /* XXX add other formats in the future */
485
      return TRUE;
486
   default:
487
      return FALSE;
488
   }
489
}
490
 
491
static INLINE boolean
492
util_format_is_s3tc(enum pipe_format format)
493
{
494
   const struct util_format_description *desc = util_format_description(format);
495
 
496
   assert(desc);
497
   if (!desc) {
498
      return FALSE;
499
   }
500
 
501
   return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
502
}
503
 
504
static INLINE boolean
505
util_format_is_srgb(enum pipe_format format)
506
{
507
   const struct util_format_description *desc = util_format_description(format);
508
   return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
509
}
510
 
511
static INLINE boolean
512
util_format_has_depth(const struct util_format_description *desc)
513
{
514
   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
515
          desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE;
516
}
517
 
518
static INLINE boolean
519
util_format_has_stencil(const struct util_format_description *desc)
520
{
521
   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
522
          desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE;
523
}
524
 
525
static INLINE boolean
526
util_format_is_depth_or_stencil(enum pipe_format format)
527
{
528
   const struct util_format_description *desc = util_format_description(format);
529
 
530
   assert(desc);
531
   if (!desc) {
532
      return FALSE;
533
   }
534
 
535
   return util_format_has_depth(desc) ||
536
          util_format_has_stencil(desc);
537
}
538
 
539
static INLINE boolean
540
util_format_is_depth_and_stencil(enum pipe_format format)
541
{
542
   const struct util_format_description *desc = util_format_description(format);
543
 
544
   assert(desc);
545
   if (!desc) {
546
      return FALSE;
547
   }
548
 
549
   return util_format_has_depth(desc) &&
550
          util_format_has_stencil(desc);
551
}
552
 
553
 
554
/**
555
 * Calculates the depth format type based upon the incoming format description.
556
 */
557
static INLINE unsigned
558
util_get_depth_format_type(const struct util_format_description *desc)
559
{
560
   unsigned depth_channel = desc->swizzle[0];
561
   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
562
       depth_channel != UTIL_FORMAT_SWIZZLE_NONE) {
563
      return desc->channel[depth_channel].type;
564
   } else {
565
      return UTIL_FORMAT_TYPE_VOID;
566
   }
567
}
568
 
569
 
570
/**
571
 * Calculates the MRD for the depth format. MRD is used in depth bias
572
 * for UNORM and unbound depth buffers. When the depth buffer is floating
573
 * point, the depth bias calculation does not use the MRD. However, the
574
 * default MRD will be 1.0 / ((1 << 24) - 1).
575
 */
576
double
577
util_get_depth_format_mrd(const struct util_format_description *desc);
578
 
579
 
580
/**
581
 * Return whether this is an RGBA, Z, S, or combined ZS format.
582
 * Useful for initializing pipe_blit_info::mask.
583
 */
584
static INLINE unsigned
585
util_format_get_mask(enum pipe_format format)
586
{
587
   const struct util_format_description *desc =
588
      util_format_description(format);
589
 
590
   if (!desc)
591
      return 0;
592
 
593
   if (util_format_has_depth(desc)) {
594
      if (util_format_has_stencil(desc)) {
595
         return PIPE_MASK_ZS;
596
      } else {
597
         return PIPE_MASK_Z;
598
      }
599
   } else {
600
      if (util_format_has_stencil(desc)) {
601
         return PIPE_MASK_S;
602
      } else {
603
         return PIPE_MASK_RGBA;
604
      }
605
   }
606
}
607
 
608
/**
609
 * Give the RGBA colormask of the channels that can be represented in this
610
 * format.
611
 *
612
 * That is, the channels whose values are preserved.
613
 */
614
static INLINE unsigned
615
util_format_colormask(const struct util_format_description *desc)
616
{
617
   unsigned colormask;
618
   unsigned chan;
619
 
620
   switch (desc->colorspace) {
621
   case UTIL_FORMAT_COLORSPACE_RGB:
622
   case UTIL_FORMAT_COLORSPACE_SRGB:
623
   case UTIL_FORMAT_COLORSPACE_YUV:
624
      colormask = 0;
625
      for (chan = 0; chan < 4; ++chan) {
626
         if (desc->swizzle[chan] < 4) {
627
            colormask |= (1 << chan);
628
         }
629
      }
630
      return colormask;
631
   case UTIL_FORMAT_COLORSPACE_ZS:
632
      return 0;
633
   default:
634
      assert(0);
635
      return 0;
636
   }
637
}
638
 
639
 
640
/**
641
 * Checks if color mask covers every channel for the specified format
642
 *
643
 * @param desc       a format description to check colormask with
644
 * @param colormask  a bit mask for channels, matches format of PIPE_MASK_RGBA
645
 */
646
static INLINE boolean
647
util_format_colormask_full(const struct util_format_description *desc, unsigned colormask)
648
{
649
   return (~colormask & util_format_colormask(desc)) == 0;
650
}
651
 
652
 
653
boolean
654
util_format_is_float(enum pipe_format format);
655
 
656
 
657
boolean
658
util_format_has_alpha(enum pipe_format format);
659
 
660
 
661
boolean
662
util_format_is_luminance(enum pipe_format format);
663
 
664
boolean
665
util_format_is_alpha(enum pipe_format format);
666
 
667
boolean
668
util_format_is_luminance_alpha(enum pipe_format format);
669
 
670
 
671
boolean
672
util_format_is_intensity(enum pipe_format format);
673
 
674
boolean
675
util_format_is_subsampled_422(enum pipe_format format);
676
 
677
boolean
678
util_format_is_pure_integer(enum pipe_format format);
679
 
680
boolean
681
util_format_is_pure_sint(enum pipe_format format);
682
 
683
boolean
684
util_format_is_pure_uint(enum pipe_format format);
685
 
686
boolean
687
util_format_is_snorm(enum pipe_format format);
688
 
689
/**
690
 * Check if the src format can be blitted to the destination format with
691
 * a simple memcpy.  For example, blitting from RGBA to RGBx is OK, but not
692
 * the reverse.
693
 */
694
boolean
695
util_is_format_compatible(const struct util_format_description *src_desc,
696
                          const struct util_format_description *dst_desc);
697
 
698
/**
699
 * Whether the format is supported by Gallium for the given bindings.
700
 * This covers S3TC textures and floating-point render targets.
701
 */
702
boolean
703
util_format_is_supported(enum pipe_format format, unsigned bind);
704
 
705
/**
706
 * Whether this format is a rgab8 variant.
707
 *
708
 * That is, any format that matches the
709
 *
710
 *   PIPE_FORMAT_?8?8?8?8_UNORM
711
 */
712
static INLINE boolean
713
util_format_is_rgba8_variant(const struct util_format_description *desc)
714
{
715
   unsigned chan;
716
 
717
   if(desc->block.width != 1 ||
718
      desc->block.height != 1 ||
719
      desc->block.bits != 32)
720
      return FALSE;
721
 
722
   for(chan = 0; chan < 4; ++chan) {
723
      if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
724
         desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
725
         return FALSE;
726
      if(desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED &&
727
         !desc->channel[chan].normalized)
728
         return FALSE;
729
      if(desc->channel[chan].size != 8)
730
         return FALSE;
731
   }
732
 
733
   return TRUE;
734
}
735
 
736
 
737
/**
738
 * Return total bits needed for the pixel format per block.
739
 */
740
static INLINE uint
741
util_format_get_blocksizebits(enum pipe_format format)
742
{
743
   const struct util_format_description *desc = util_format_description(format);
744
 
745
   assert(desc);
746
   if (!desc) {
747
      return 0;
748
   }
749
 
750
   return desc->block.bits;
751
}
752
 
753
/**
754
 * Return bytes per block (not pixel) for the given format.
755
 */
756
static INLINE uint
757
util_format_get_blocksize(enum pipe_format format)
758
{
759
   uint bits = util_format_get_blocksizebits(format);
760
   uint bytes = bits / 8;
761
 
762
   assert(bits % 8 == 0);
763
   assert(bytes > 0);
764
   if (bytes == 0) {
765
      bytes = 1;
766
   }
767
 
768
   return bytes;
769
}
770
 
771
static INLINE uint
772
util_format_get_blockwidth(enum pipe_format format)
773
{
774
   const struct util_format_description *desc = util_format_description(format);
775
 
776
   assert(desc);
777
   if (!desc) {
778
      return 1;
779
   }
780
 
781
   return desc->block.width;
782
}
783
 
784
static INLINE uint
785
util_format_get_blockheight(enum pipe_format format)
786
{
787
   const struct util_format_description *desc = util_format_description(format);
788
 
789
   assert(desc);
790
   if (!desc) {
791
      return 1;
792
   }
793
 
794
   return desc->block.height;
795
}
796
 
797
static INLINE unsigned
798
util_format_get_nblocksx(enum pipe_format format,
799
                         unsigned x)
800
{
801
   unsigned blockwidth = util_format_get_blockwidth(format);
802
   return (x + blockwidth - 1) / blockwidth;
803
}
804
 
805
static INLINE unsigned
806
util_format_get_nblocksy(enum pipe_format format,
807
                         unsigned y)
808
{
809
   unsigned blockheight = util_format_get_blockheight(format);
810
   return (y + blockheight - 1) / blockheight;
811
}
812
 
813
static INLINE unsigned
814
util_format_get_nblocks(enum pipe_format format,
815
                        unsigned width,
816
                        unsigned height)
817
{
818
   return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
819
}
820
 
821
static INLINE size_t
822
util_format_get_stride(enum pipe_format format,
823
                       unsigned width)
824
{
825
   return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
826
}
827
 
828
static INLINE size_t
829
util_format_get_2d_size(enum pipe_format format,
830
                        size_t stride,
831
                        unsigned height)
832
{
833
   return util_format_get_nblocksy(format, height) * stride;
834
}
835
 
836
static INLINE uint
837
util_format_get_component_bits(enum pipe_format format,
838
                               enum util_format_colorspace colorspace,
839
                               uint component)
840
{
841
   const struct util_format_description *desc = util_format_description(format);
842
   enum util_format_colorspace desc_colorspace;
843
 
844
   assert(format);
845
   if (!format) {
846
      return 0;
847
   }
848
 
849
   assert(component < 4);
850
 
851
   /* Treat RGB and SRGB as equivalent. */
852
   if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
853
      colorspace = UTIL_FORMAT_COLORSPACE_RGB;
854
   }
855
   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
856
      desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
857
   } else {
858
      desc_colorspace = desc->colorspace;
859
   }
860
 
861
   if (desc_colorspace != colorspace) {
862
      return 0;
863
   }
864
 
865
   switch (desc->swizzle[component]) {
866
   case UTIL_FORMAT_SWIZZLE_X:
867
      return desc->channel[0].size;
868
   case UTIL_FORMAT_SWIZZLE_Y:
869
      return desc->channel[1].size;
870
   case UTIL_FORMAT_SWIZZLE_Z:
871
      return desc->channel[2].size;
872
   case UTIL_FORMAT_SWIZZLE_W:
873
      return desc->channel[3].size;
874
   default:
875
      return 0;
876
   }
877
}
878
 
879
/**
880
 * Given a linear RGB colorspace format, return the corresponding SRGB
881
 * format, or PIPE_FORMAT_NONE if none.
882
 */
883
static INLINE enum pipe_format
884
util_format_srgb(enum pipe_format format)
885
{
886
   if (util_format_is_srgb(format))
887
      return format;
888
 
889
   switch (format) {
890
   case PIPE_FORMAT_L8_UNORM:
891
      return PIPE_FORMAT_L8_SRGB;
892
   case PIPE_FORMAT_L8A8_UNORM:
893
      return PIPE_FORMAT_L8A8_SRGB;
894
   case PIPE_FORMAT_R8G8B8_UNORM:
895
      return PIPE_FORMAT_R8G8B8_SRGB;
896
   case PIPE_FORMAT_A8B8G8R8_UNORM:
897
      return PIPE_FORMAT_A8B8G8R8_SRGB;
898
   case PIPE_FORMAT_X8B8G8R8_UNORM:
899
      return PIPE_FORMAT_X8B8G8R8_SRGB;
900
   case PIPE_FORMAT_B8G8R8A8_UNORM:
901
      return PIPE_FORMAT_B8G8R8A8_SRGB;
902
   case PIPE_FORMAT_B8G8R8X8_UNORM:
903
      return PIPE_FORMAT_B8G8R8X8_SRGB;
904
   case PIPE_FORMAT_A8R8G8B8_UNORM:
905
      return PIPE_FORMAT_A8R8G8B8_SRGB;
906
   case PIPE_FORMAT_X8R8G8B8_UNORM:
907
      return PIPE_FORMAT_X8R8G8B8_SRGB;
908
   case PIPE_FORMAT_R8G8B8A8_UNORM:
909
      return PIPE_FORMAT_R8G8B8A8_SRGB;
910
   case PIPE_FORMAT_R8G8B8X8_UNORM:
911
      return PIPE_FORMAT_R8G8B8X8_SRGB;
912
   case PIPE_FORMAT_DXT1_RGB:
913
      return PIPE_FORMAT_DXT1_SRGB;
914
   case PIPE_FORMAT_DXT1_RGBA:
915
      return PIPE_FORMAT_DXT1_SRGBA;
916
   case PIPE_FORMAT_DXT3_RGBA:
917
      return PIPE_FORMAT_DXT3_SRGBA;
918
   case PIPE_FORMAT_DXT5_RGBA:
919
      return PIPE_FORMAT_DXT5_SRGBA;
920
   case PIPE_FORMAT_B5G6R5_UNORM:
921
      return PIPE_FORMAT_B5G6R5_SRGB;
922
   case PIPE_FORMAT_BPTC_RGBA_UNORM:
923
      return PIPE_FORMAT_BPTC_SRGBA;
924
   default:
925
      return PIPE_FORMAT_NONE;
926
   }
927
}
928
 
929
/**
930
 * Given an sRGB format, return the corresponding linear colorspace format.
931
 * For non sRGB formats, return the format unchanged.
932
 */
933
static INLINE enum pipe_format
934
util_format_linear(enum pipe_format format)
935
{
936
   switch (format) {
937
   case PIPE_FORMAT_L8_SRGB:
938
      return PIPE_FORMAT_L8_UNORM;
939
   case PIPE_FORMAT_L8A8_SRGB:
940
      return PIPE_FORMAT_L8A8_UNORM;
941
   case PIPE_FORMAT_R8G8B8_SRGB:
942
      return PIPE_FORMAT_R8G8B8_UNORM;
943
   case PIPE_FORMAT_A8B8G8R8_SRGB:
944
      return PIPE_FORMAT_A8B8G8R8_UNORM;
945
   case PIPE_FORMAT_X8B8G8R8_SRGB:
946
      return PIPE_FORMAT_X8B8G8R8_UNORM;
947
   case PIPE_FORMAT_B8G8R8A8_SRGB:
948
      return PIPE_FORMAT_B8G8R8A8_UNORM;
949
   case PIPE_FORMAT_B8G8R8X8_SRGB:
950
      return PIPE_FORMAT_B8G8R8X8_UNORM;
951
   case PIPE_FORMAT_A8R8G8B8_SRGB:
952
      return PIPE_FORMAT_A8R8G8B8_UNORM;
953
   case PIPE_FORMAT_X8R8G8B8_SRGB:
954
      return PIPE_FORMAT_X8R8G8B8_UNORM;
955
   case PIPE_FORMAT_R8G8B8A8_SRGB:
956
      return PIPE_FORMAT_R8G8B8A8_UNORM;
957
   case PIPE_FORMAT_R8G8B8X8_SRGB:
958
      return PIPE_FORMAT_R8G8B8X8_UNORM;
959
   case PIPE_FORMAT_DXT1_SRGB:
960
      return PIPE_FORMAT_DXT1_RGB;
961
   case PIPE_FORMAT_DXT1_SRGBA:
962
      return PIPE_FORMAT_DXT1_RGBA;
963
   case PIPE_FORMAT_DXT3_SRGBA:
964
      return PIPE_FORMAT_DXT3_RGBA;
965
   case PIPE_FORMAT_DXT5_SRGBA:
966
      return PIPE_FORMAT_DXT5_RGBA;
967
   case PIPE_FORMAT_B5G6R5_SRGB:
968
      return PIPE_FORMAT_B5G6R5_UNORM;
969
   case PIPE_FORMAT_BPTC_SRGBA:
970
      return PIPE_FORMAT_BPTC_RGBA_UNORM;
971
   default:
972
      return format;
973
   }
974
}
975
 
976
/**
977
 * Given a depth-stencil format, return the corresponding stencil-only format.
978
 * For stencil-only formats, return the format unchanged.
979
 */
980
static INLINE enum pipe_format
981
util_format_stencil_only(enum pipe_format format)
982
{
983
   switch (format) {
984
   /* mask out the depth component */
985
   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
986
      return PIPE_FORMAT_X24S8_UINT;
987
   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
988
      return PIPE_FORMAT_S8X24_UINT;
989
   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
990
      return PIPE_FORMAT_X32_S8X24_UINT;
991
 
992
   /* stencil only formats */
993
   case PIPE_FORMAT_X24S8_UINT:
994
   case PIPE_FORMAT_S8X24_UINT:
995
   case PIPE_FORMAT_X32_S8X24_UINT:
996
   case PIPE_FORMAT_S8_UINT:
997
      return format;
998
 
999
   default:
1000
      assert(0);
1001
      return PIPE_FORMAT_NONE;
1002
   }
1003
}
1004
 
1005
/**
1006
 * Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*.
1007
 * This is identity for non-intensity formats.
1008
 */
1009
static INLINE enum pipe_format
1010
util_format_intensity_to_red(enum pipe_format format)
1011
{
1012
   switch (format) {
1013
   case PIPE_FORMAT_I8_UNORM:
1014
      return PIPE_FORMAT_R8_UNORM;
1015
   case PIPE_FORMAT_I8_SNORM:
1016
      return PIPE_FORMAT_R8_SNORM;
1017
   case PIPE_FORMAT_I16_UNORM:
1018
      return PIPE_FORMAT_R16_UNORM;
1019
   case PIPE_FORMAT_I16_SNORM:
1020
      return PIPE_FORMAT_R16_SNORM;
1021
   case PIPE_FORMAT_I16_FLOAT:
1022
      return PIPE_FORMAT_R16_FLOAT;
1023
   case PIPE_FORMAT_I32_FLOAT:
1024
      return PIPE_FORMAT_R32_FLOAT;
1025
   case PIPE_FORMAT_I8_UINT:
1026
      return PIPE_FORMAT_R8_UINT;
1027
   case PIPE_FORMAT_I8_SINT:
1028
      return PIPE_FORMAT_R8_SINT;
1029
   case PIPE_FORMAT_I16_UINT:
1030
      return PIPE_FORMAT_R16_UINT;
1031
   case PIPE_FORMAT_I16_SINT:
1032
      return PIPE_FORMAT_R16_SINT;
1033
   case PIPE_FORMAT_I32_UINT:
1034
      return PIPE_FORMAT_R32_UINT;
1035
   case PIPE_FORMAT_I32_SINT:
1036
      return PIPE_FORMAT_R32_SINT;
1037
   default:
1038
      assert(!util_format_is_intensity(format));
1039
      return format;
1040
   }
1041
}
1042
 
1043
/**
1044
 * Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*.
1045
 * This is identity for non-luminance formats.
1046
 */
1047
static INLINE enum pipe_format
1048
util_format_luminance_to_red(enum pipe_format format)
1049
{
1050
   switch (format) {
1051
   case PIPE_FORMAT_L8_UNORM:
1052
      return PIPE_FORMAT_R8_UNORM;
1053
   case PIPE_FORMAT_L8_SNORM:
1054
      return PIPE_FORMAT_R8_SNORM;
1055
   case PIPE_FORMAT_L16_UNORM:
1056
      return PIPE_FORMAT_R16_UNORM;
1057
   case PIPE_FORMAT_L16_SNORM:
1058
      return PIPE_FORMAT_R16_SNORM;
1059
   case PIPE_FORMAT_L16_FLOAT:
1060
      return PIPE_FORMAT_R16_FLOAT;
1061
   case PIPE_FORMAT_L32_FLOAT:
1062
      return PIPE_FORMAT_R32_FLOAT;
1063
   case PIPE_FORMAT_L8_UINT:
1064
      return PIPE_FORMAT_R8_UINT;
1065
   case PIPE_FORMAT_L8_SINT:
1066
      return PIPE_FORMAT_R8_SINT;
1067
   case PIPE_FORMAT_L16_UINT:
1068
      return PIPE_FORMAT_R16_UINT;
1069
   case PIPE_FORMAT_L16_SINT:
1070
      return PIPE_FORMAT_R16_SINT;
1071
   case PIPE_FORMAT_L32_UINT:
1072
      return PIPE_FORMAT_R32_UINT;
1073
   case PIPE_FORMAT_L32_SINT:
1074
      return PIPE_FORMAT_R32_SINT;
1075
 
1076
   case PIPE_FORMAT_LATC1_UNORM:
1077
      return PIPE_FORMAT_RGTC1_UNORM;
1078
   case PIPE_FORMAT_LATC1_SNORM:
1079
      return PIPE_FORMAT_RGTC1_SNORM;
1080
 
1081
   case PIPE_FORMAT_L4A4_UNORM:
1082
      return PIPE_FORMAT_R4A4_UNORM;
1083
 
1084
   case PIPE_FORMAT_L8A8_UNORM:
1085
      return PIPE_FORMAT_R8A8_UNORM;
1086
   case PIPE_FORMAT_L8A8_SNORM:
1087
      return PIPE_FORMAT_R8A8_SNORM;
1088
   case PIPE_FORMAT_L16A16_UNORM:
1089
      return PIPE_FORMAT_R16A16_UNORM;
1090
   case PIPE_FORMAT_L16A16_SNORM:
1091
      return PIPE_FORMAT_R16A16_SNORM;
1092
   case PIPE_FORMAT_L16A16_FLOAT:
1093
      return PIPE_FORMAT_R16A16_FLOAT;
1094
   case PIPE_FORMAT_L32A32_FLOAT:
1095
      return PIPE_FORMAT_R32A32_FLOAT;
1096
   case PIPE_FORMAT_L8A8_UINT:
1097
      return PIPE_FORMAT_R8A8_UINT;
1098
   case PIPE_FORMAT_L8A8_SINT:
1099
      return PIPE_FORMAT_R8A8_SINT;
1100
   case PIPE_FORMAT_L16A16_UINT:
1101
      return PIPE_FORMAT_R16A16_UINT;
1102
   case PIPE_FORMAT_L16A16_SINT:
1103
      return PIPE_FORMAT_R16A16_SINT;
1104
   case PIPE_FORMAT_L32A32_UINT:
1105
      return PIPE_FORMAT_R32A32_UINT;
1106
   case PIPE_FORMAT_L32A32_SINT:
1107
      return PIPE_FORMAT_R32A32_SINT;
1108
 
1109
   /* We don't have compressed red-alpha variants for these. */
1110
   case PIPE_FORMAT_LATC2_UNORM:
1111
   case PIPE_FORMAT_LATC2_SNORM:
1112
      return PIPE_FORMAT_NONE;
1113
 
1114
   default:
1115
      assert(!util_format_is_luminance(format) &&
1116
	     !util_format_is_luminance_alpha(format));
1117
      return format;
1118
   }
1119
}
1120
 
1121
/**
1122
 * Return the number of components stored.
1123
 * Formats with block size != 1x1 will always have 1 component (the block).
1124
 */
1125
static INLINE unsigned
1126
util_format_get_nr_components(enum pipe_format format)
1127
{
1128
   const struct util_format_description *desc = util_format_description(format);
1129
   return desc->nr_channels;
1130
}
1131
 
1132
/**
1133
 * Return the index of the first non-void channel
1134
 * -1 if no non-void channels
1135
 */
1136
static INLINE int
1137
util_format_get_first_non_void_channel(enum pipe_format format)
1138
{
1139
   const struct util_format_description *desc = util_format_description(format);
1140
   int i;
1141
 
1142
   for (i = 0; i < 4; i++)
1143
      if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
1144
         break;
1145
 
1146
   if (i == 4)
1147
       return -1;
1148
 
1149
   return i;
1150
}
1151
 
1152
/*
1153
 * Format access functions.
1154
 */
1155
 
1156
void
1157
util_format_read_4f(enum pipe_format format,
1158
                    float *dst, unsigned dst_stride,
1159
                    const void *src, unsigned src_stride,
1160
                    unsigned x, unsigned y, unsigned w, unsigned h);
1161
 
1162
void
1163
util_format_write_4f(enum pipe_format format,
1164
                     const float *src, unsigned src_stride,
1165
                     void *dst, unsigned dst_stride,
1166
                     unsigned x, unsigned y, unsigned w, unsigned h);
1167
 
1168
void
1169
util_format_read_4ub(enum pipe_format format,
1170
                     uint8_t *dst, unsigned dst_stride,
1171
                     const void *src, unsigned src_stride,
1172
                     unsigned x, unsigned y, unsigned w, unsigned h);
1173
 
1174
void
1175
util_format_write_4ub(enum pipe_format format,
1176
                      const uint8_t *src, unsigned src_stride,
1177
                      void *dst, unsigned dst_stride,
1178
                      unsigned x, unsigned y, unsigned w, unsigned h);
1179
 
1180
void
1181
util_format_read_4ui(enum pipe_format format,
1182
                     unsigned *dst, unsigned dst_stride,
1183
                     const void *src, unsigned src_stride,
1184
                     unsigned x, unsigned y, unsigned w, unsigned h);
1185
 
1186
void
1187
util_format_write_4ui(enum pipe_format format,
1188
                      const unsigned int *src, unsigned src_stride,
1189
                      void *dst, unsigned dst_stride,
1190
                      unsigned x, unsigned y, unsigned w, unsigned h);
1191
 
1192
void
1193
util_format_read_4i(enum pipe_format format,
1194
                    int *dst, unsigned dst_stride,
1195
                    const void *src, unsigned src_stride,
1196
                    unsigned x, unsigned y, unsigned w, unsigned h);
1197
 
1198
void
1199
util_format_write_4i(enum pipe_format format,
1200
                     const int *src, unsigned src_stride,
1201
                     void *dst, unsigned dst_stride,
1202
                     unsigned x, unsigned y, unsigned w, unsigned h);
1203
 
1204
/*
1205
 * Generic format conversion;
1206
 */
1207
 
1208
boolean
1209
util_format_fits_8unorm(const struct util_format_description *format_desc);
1210
 
1211
boolean
1212
util_format_translate(enum pipe_format dst_format,
1213
                      void *dst, unsigned dst_stride,
1214
                      unsigned dst_x, unsigned dst_y,
1215
                      enum pipe_format src_format,
1216
                      const void *src, unsigned src_stride,
1217
                      unsigned src_x, unsigned src_y,
1218
                      unsigned width, unsigned height);
1219
 
1220
/*
1221
 * Swizzle operations.
1222
 */
1223
 
1224
/* Compose two sets of swizzles.
1225
 * If V is a 4D vector and the function parameters represent functions that
1226
 * swizzle vector components, this holds:
1227
 *     swz2(swz1(V)) = dst(V)
1228
 */
1229
void util_format_compose_swizzles(const unsigned char swz1[4],
1230
                                  const unsigned char swz2[4],
1231
                                  unsigned char dst[4]);
1232
 
1233
/* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x)
1234
 * to \param src and store the result in \param dst.
1235
 * \param is_integer determines the value written for PIPE_SWIZZLE_ONE.
1236
 */
1237
void util_format_apply_color_swizzle(union pipe_color_union *dst,
1238
                                     const union pipe_color_union *src,
1239
                                     const unsigned char swz[4],
1240
                                     const boolean is_integer);
1241
 
1242
void util_format_swizzle_4f(float *dst, const float *src,
1243
                            const unsigned char swz[4]);
1244
 
1245
void util_format_unswizzle_4f(float *dst, const float *src,
1246
                              const unsigned char swz[4]);
1247
 
1248
#ifdef __cplusplus
1249
} // extern "C" {
1250
#endif
1251
 
1252
#endif /* ! U_FORMAT_H */