Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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