u_format.h revision ba6f1f2c29c148e33acc9d2b411c19c7c9a9d04f
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 "util/u_debug.h"
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40
41/**
42 * Describe how to pack/unpack pixels into/from the prescribed format.
43 *
44 * XXX: This could be renamed to something like util_format_pack, or broke down
45 * in flags inside util_format_block that said exactly what we want.
46 */
47enum util_format_layout {
48   /**
49    * Formats with util_format_block::width == util_format_block::height == 1
50    * that can be described as an ordinary data structure.
51    */
52   UTIL_FORMAT_LAYOUT_PLAIN = 0,
53
54   /**
55    * Formats with sub-sampled channels.
56    *
57    * This is for formats like YV12 where there is less than one sample per
58    * pixel.
59    */
60   UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
61
62   /**
63    * S3 Texture Compression formats.
64    */
65   UTIL_FORMAT_LAYOUT_S3TC = 4,
66
67   /**
68    * Red-Green Texture Compression formats.
69    */
70   UTIL_FORMAT_LAYOUT_RGTC = 5,
71
72   /**
73    * Everything else that doesn't fit in any of the above layouts.
74    */
75   UTIL_FORMAT_LAYOUT_OTHER = 6
76};
77
78
79struct util_format_block
80{
81   /** Block width in pixels */
82   unsigned width;
83
84   /** Block height in pixels */
85   unsigned height;
86
87   /** Block size in bits */
88   unsigned bits;
89};
90
91
92enum util_format_type {
93   UTIL_FORMAT_TYPE_VOID = 0,
94   UTIL_FORMAT_TYPE_UNSIGNED = 1,
95   UTIL_FORMAT_TYPE_SIGNED = 2,
96   UTIL_FORMAT_TYPE_FIXED = 3,
97   UTIL_FORMAT_TYPE_FLOAT = 4
98};
99
100
101enum util_format_swizzle {
102   UTIL_FORMAT_SWIZZLE_X = 0,
103   UTIL_FORMAT_SWIZZLE_Y = 1,
104   UTIL_FORMAT_SWIZZLE_Z = 2,
105   UTIL_FORMAT_SWIZZLE_W = 3,
106   UTIL_FORMAT_SWIZZLE_0 = 4,
107   UTIL_FORMAT_SWIZZLE_1 = 5,
108   UTIL_FORMAT_SWIZZLE_NONE = 6,
109   UTIL_FORMAT_SWIZZLE_MAX = 7  /**< Number of enums counter (must be last) */
110};
111
112
113enum util_format_colorspace {
114   UTIL_FORMAT_COLORSPACE_RGB = 0,
115   UTIL_FORMAT_COLORSPACE_SRGB = 1,
116   UTIL_FORMAT_COLORSPACE_YUV = 2,
117   UTIL_FORMAT_COLORSPACE_ZS = 3
118};
119
120
121struct util_format_channel_description
122{
123   unsigned type:6;        /**< UTIL_FORMAT_TYPE_x */
124   unsigned normalized:1;
125   unsigned size:9;        /**< bits per channel */
126};
127
128
129struct util_format_description
130{
131   enum pipe_format format;
132
133   const char *name;
134
135   /**
136    * Short name, striped of the prefix, lower case.
137    */
138   const char *short_name;
139
140   /**
141    * Pixel block dimensions.
142    */
143   struct util_format_block block;
144
145   enum util_format_layout layout;
146
147   /**
148    * The number of channels.
149    */
150   unsigned nr_channels:3;
151
152   /**
153    * Whether all channels have the same number of (whole) bytes.
154    */
155   unsigned is_array:1;
156
157   /**
158    * Whether the pixel format can be described as a bitfield structure.
159    *
160    * In particular:
161    * - pixel depth must be 8, 16, or 32 bits;
162    * - all channels must be unsigned, signed, or void
163    */
164   unsigned is_bitmask:1;
165
166   /**
167    * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
168    */
169   unsigned is_mixed:1;
170
171   /**
172    * Input channel description.
173    *
174    * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
175    */
176   struct util_format_channel_description channel[4];
177
178   /**
179    * Output channel swizzle.
180    *
181    * The order is either:
182    * - RGBA
183    * - YUV(A)
184    * - ZS
185    * depending on the colorspace.
186    */
187   unsigned char swizzle[4];
188
189   /**
190    * Colorspace transformation.
191    */
192   enum util_format_colorspace colorspace;
193
194   /**
195    * Unpack pixel blocks to R8G8B8A8_UNORM.
196    * Note: strides are in bytes.
197    *
198    * Only defined for non-depth-stencil formats.
199    */
200   void
201   (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
202                         const uint8_t *src, unsigned src_stride,
203                         unsigned width, unsigned height);
204
205   /**
206    * Pack pixel blocks from R8G8B8A8_UNORM.
207    * Note: strides are in bytes.
208    *
209    * Only defined for non-depth-stencil formats.
210    */
211   void
212   (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
213                       const uint8_t *src, unsigned src_stride,
214                       unsigned width, unsigned height);
215
216   /**
217    * Fetch a single pixel (i, j) from a block.
218    *
219    * XXX: Only defined for a very few select formats.
220    */
221   void
222   (*fetch_rgba_8unorm)(uint8_t *dst,
223                        const uint8_t *src,
224                        unsigned i, unsigned j);
225
226   /**
227    * Unpack pixel blocks to R32G32B32A32_FLOAT.
228    * Note: strides are in bytes.
229    *
230    * Only defined for non-depth-stencil formats.
231    */
232   void
233   (*unpack_rgba_float)(float *dst, unsigned dst_stride,
234                        const uint8_t *src, unsigned src_stride,
235                        unsigned width, unsigned height);
236
237   /**
238    * Pack pixel blocks from R32G32B32A32_FLOAT.
239    * Note: strides are in bytes.
240    *
241    * Only defined for non-depth-stencil formats.
242    */
243   void
244   (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride,
245                      const float *src, unsigned src_stride,
246                      unsigned width, unsigned height);
247
248   /**
249    * Fetch a single pixel (i, j) from a block.
250    *
251    * Only defined for non-depth-stencil formats.
252    */
253   void
254   (*fetch_rgba_float)(float *dst,
255                       const uint8_t *src,
256                       unsigned i, unsigned j);
257
258   /**
259    * Unpack pixels to Z32_UNORM.
260    * Note: strides are in bytes.
261    *
262    * Only defined for depth formats.
263    */
264   void
265   (*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride,
266                       const uint8_t *src, unsigned src_stride,
267                       unsigned width, unsigned height);
268
269   /**
270    * Pack pixels from Z32_FLOAT.
271    * Note: strides are in bytes.
272    *
273    * Only defined for depth formats.
274    */
275   void
276   (*pack_z_32unorm)(uint8_t *dst, unsigned dst_stride,
277                     const uint32_t *src, unsigned src_stride,
278                     unsigned width, unsigned height);
279
280   /**
281    * Unpack pixels to Z32_FLOAT.
282    * Note: strides are in bytes.
283    *
284    * Only defined for depth formats.
285    */
286   void
287   (*unpack_z_float)(float *dst, unsigned dst_stride,
288                     const uint8_t *src, unsigned src_stride,
289                     unsigned width, unsigned height);
290
291   /**
292    * Pack pixels from Z32_FLOAT.
293    * Note: strides are in bytes.
294    *
295    * Only defined for depth formats.
296    */
297   void
298   (*pack_z_float)(uint8_t *dst, unsigned dst_stride,
299                   const float *src, unsigned src_stride,
300                   unsigned width, unsigned height);
301
302   /**
303    * Unpack pixels to S8_USCALED.
304    * Note: strides are in bytes.
305    *
306    * Only defined for stencil formats.
307    */
308   void
309   (*unpack_s_8uscaled)(uint8_t *dst, unsigned dst_stride,
310                        const uint8_t *src, unsigned src_stride,
311                        unsigned width, unsigned height);
312
313   /**
314    * Pack pixels from S8_USCALED.
315    * Note: strides are in bytes.
316    *
317    * Only defined for stencil formats.
318    */
319   void
320   (*pack_s_8uscaled)(uint8_t *dst, unsigned dst_stride,
321                      const uint8_t *src, unsigned src_stride,
322                      unsigned width, unsigned height);
323
324};
325
326
327extern const struct util_format_description
328util_format_description_table[];
329
330
331const struct util_format_description *
332util_format_description(enum pipe_format format);
333
334
335/*
336 * Format query functions.
337 */
338
339static INLINE const char *
340util_format_name(enum pipe_format format)
341{
342   const struct util_format_description *desc = util_format_description(format);
343
344   assert(desc);
345   if (!desc) {
346      return "PIPE_FORMAT_???";
347   }
348
349   return desc->name;
350}
351
352static INLINE const char *
353util_format_short_name(enum pipe_format format)
354{
355   const struct util_format_description *desc = util_format_description(format);
356
357   assert(desc);
358   if (!desc) {
359      return "???";
360   }
361
362   return desc->short_name;
363}
364
365/**
366 * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
367 */
368static INLINE boolean
369util_format_is_plain(enum pipe_format format)
370{
371   const struct util_format_description *desc = util_format_description(format);
372
373   if (!format) {
374      return FALSE;
375   }
376
377   return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
378}
379
380static INLINE boolean
381util_format_is_compressed(enum pipe_format format)
382{
383   const struct util_format_description *desc = util_format_description(format);
384
385   assert(desc);
386   if (!desc) {
387      return FALSE;
388   }
389
390   switch (desc->layout) {
391   case UTIL_FORMAT_LAYOUT_S3TC:
392   case UTIL_FORMAT_LAYOUT_RGTC:
393      /* XXX add other formats in the future */
394      return TRUE;
395   default:
396      return FALSE;
397   }
398}
399
400static INLINE boolean
401util_format_is_s3tc(enum pipe_format format)
402{
403   const struct util_format_description *desc = util_format_description(format);
404
405   assert(desc);
406   if (!desc) {
407      return FALSE;
408   }
409
410   return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
411}
412
413static INLINE boolean
414util_format_is_depth_or_stencil(enum pipe_format format)
415{
416   const struct util_format_description *desc = util_format_description(format);
417
418   assert(desc);
419   if (!desc) {
420      return FALSE;
421   }
422
423   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? TRUE : FALSE;
424}
425
426static INLINE boolean
427util_format_is_depth_and_stencil(enum pipe_format format)
428{
429   const struct util_format_description *desc = util_format_description(format);
430
431   assert(desc);
432   if (!desc) {
433      return FALSE;
434   }
435
436   if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) {
437      return FALSE;
438   }
439
440   return (desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE &&
441           desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE;
442}
443
444
445/**
446 * Give the RGBA colormask of the channels that can be represented in this
447 * format.
448 *
449 * That is, the channels whose values are preserved.
450 */
451static INLINE unsigned
452util_format_colormask(const struct util_format_description *desc)
453{
454   unsigned colormask;
455   unsigned chan;
456
457   switch (desc->colorspace) {
458   case UTIL_FORMAT_COLORSPACE_RGB:
459   case UTIL_FORMAT_COLORSPACE_SRGB:
460   case UTIL_FORMAT_COLORSPACE_YUV:
461      colormask = 0;
462      for (chan = 0; chan < 4; ++chan) {
463         if (desc->swizzle[chan] < 4) {
464            colormask |= (1 << chan);
465         }
466      }
467      return colormask;
468   case UTIL_FORMAT_COLORSPACE_ZS:
469      return 0;
470   default:
471      assert(0);
472      return 0;
473   }
474}
475
476
477boolean
478util_format_is_float(enum pipe_format format);
479
480
481boolean
482util_format_is_rgb_no_alpha(enum pipe_format format);
483
484
485boolean
486util_format_is_luminance(enum pipe_format format);
487
488
489boolean
490util_format_is_luminance_alpha(enum pipe_format format);
491
492
493boolean
494util_format_is_intensity(enum pipe_format format);
495
496
497/**
498 * Whether the src format can be blitted to destation format with a simple
499 * memcpy.
500 */
501boolean
502util_is_format_compatible(const struct util_format_description *src_desc,
503                          const struct util_format_description *dst_desc);
504
505/**
506 * Whether the format is supported by Gallium for the given bindings.
507 * This covers S3TC textures and floating-point render targets.
508 */
509boolean
510util_format_is_supported(enum pipe_format format, unsigned bind);
511
512/**
513 * Whether this format is a rgab8 variant.
514 *
515 * That is, any format that matches the
516 *
517 *   PIPE_FORMAT_?8?8?8?8_UNORM
518 */
519static INLINE boolean
520util_format_is_rgba8_variant(const struct util_format_description *desc)
521{
522   unsigned chan;
523
524   if(desc->block.width != 1 ||
525      desc->block.height != 1 ||
526      desc->block.bits != 32)
527      return FALSE;
528
529   for(chan = 0; chan < 4; ++chan) {
530      if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
531         desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
532         return FALSE;
533      if(desc->channel[chan].size != 8)
534         return FALSE;
535   }
536
537   return TRUE;
538}
539
540
541/**
542 * Return total bits needed for the pixel format per block.
543 */
544static INLINE uint
545util_format_get_blocksizebits(enum pipe_format format)
546{
547   const struct util_format_description *desc = util_format_description(format);
548
549   assert(desc);
550   if (!desc) {
551      return 0;
552   }
553
554   return desc->block.bits;
555}
556
557/**
558 * Return bytes per block (not pixel) for the given format.
559 */
560static INLINE uint
561util_format_get_blocksize(enum pipe_format format)
562{
563   uint bits = util_format_get_blocksizebits(format);
564
565   assert(bits % 8 == 0);
566
567   return bits / 8;
568}
569
570static INLINE uint
571util_format_get_blockwidth(enum pipe_format format)
572{
573   const struct util_format_description *desc = util_format_description(format);
574
575   assert(desc);
576   if (!desc) {
577      return 1;
578   }
579
580   return desc->block.width;
581}
582
583static INLINE uint
584util_format_get_blockheight(enum pipe_format format)
585{
586   const struct util_format_description *desc = util_format_description(format);
587
588   assert(desc);
589   if (!desc) {
590      return 1;
591   }
592
593   return desc->block.height;
594}
595
596static INLINE unsigned
597util_format_get_nblocksx(enum pipe_format format,
598                         unsigned x)
599{
600   unsigned blockwidth = util_format_get_blockwidth(format);
601   return (x + blockwidth - 1) / blockwidth;
602}
603
604static INLINE unsigned
605util_format_get_nblocksy(enum pipe_format format,
606                         unsigned y)
607{
608   unsigned blockheight = util_format_get_blockheight(format);
609   return (y + blockheight - 1) / blockheight;
610}
611
612static INLINE unsigned
613util_format_get_nblocks(enum pipe_format format,
614                        unsigned width,
615                        unsigned height)
616{
617   return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
618}
619
620static INLINE size_t
621util_format_get_stride(enum pipe_format format,
622                       unsigned width)
623{
624   return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
625}
626
627static INLINE size_t
628util_format_get_2d_size(enum pipe_format format,
629                        size_t stride,
630                        unsigned height)
631{
632   return util_format_get_nblocksy(format, height) * stride;
633}
634
635static INLINE uint
636util_format_get_component_bits(enum pipe_format format,
637                               enum util_format_colorspace colorspace,
638                               uint component)
639{
640   const struct util_format_description *desc = util_format_description(format);
641   enum util_format_colorspace desc_colorspace;
642
643   assert(format);
644   if (!format) {
645      return 0;
646   }
647
648   assert(component < 4);
649
650   /* Treat RGB and SRGB as equivalent. */
651   if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
652      colorspace = UTIL_FORMAT_COLORSPACE_RGB;
653   }
654   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
655      desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
656   } else {
657      desc_colorspace = desc->colorspace;
658   }
659
660   if (desc_colorspace != colorspace) {
661      return 0;
662   }
663
664   switch (desc->swizzle[component]) {
665   case UTIL_FORMAT_SWIZZLE_X:
666      return desc->channel[0].size;
667   case UTIL_FORMAT_SWIZZLE_Y:
668      return desc->channel[1].size;
669   case UTIL_FORMAT_SWIZZLE_Z:
670      return desc->channel[2].size;
671   case UTIL_FORMAT_SWIZZLE_W:
672      return desc->channel[3].size;
673   default:
674      return 0;
675   }
676}
677
678static INLINE boolean
679util_format_has_alpha(enum pipe_format format)
680{
681   const struct util_format_description *desc = util_format_description(format);
682
683   assert(format);
684   if (!format) {
685      return FALSE;
686   }
687
688   switch (desc->colorspace) {
689   case UTIL_FORMAT_COLORSPACE_RGB:
690   case UTIL_FORMAT_COLORSPACE_SRGB:
691      return desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1;
692   case UTIL_FORMAT_COLORSPACE_YUV:
693      return FALSE;
694   case UTIL_FORMAT_COLORSPACE_ZS:
695      return FALSE;
696   default:
697      assert(0);
698      return FALSE;
699   }
700}
701
702/**
703 * Given a linear RGB colorspace format, return the corresponding SRGB
704 * format, or PIPE_FORMAT_NONE if none.
705 */
706static INLINE enum pipe_format
707util_format_srgb(enum pipe_format format)
708{
709   switch (format) {
710   case PIPE_FORMAT_L8_UNORM:
711      return PIPE_FORMAT_L8_SRGB;
712   case PIPE_FORMAT_L8A8_UNORM:
713      return PIPE_FORMAT_L8A8_SRGB;
714   case PIPE_FORMAT_R8G8B8_UNORM:
715      return PIPE_FORMAT_R8G8B8_SRGB;
716   case PIPE_FORMAT_A8B8G8R8_UNORM:
717      return PIPE_FORMAT_A8B8G8R8_SRGB;
718   case PIPE_FORMAT_X8B8G8R8_UNORM:
719      return PIPE_FORMAT_X8B8G8R8_SRGB;
720   case PIPE_FORMAT_B8G8R8A8_UNORM:
721      return PIPE_FORMAT_B8G8R8A8_SRGB;
722   case PIPE_FORMAT_B8G8R8X8_UNORM:
723      return PIPE_FORMAT_B8G8R8X8_SRGB;
724   case PIPE_FORMAT_A8R8G8B8_UNORM:
725      return PIPE_FORMAT_A8R8G8B8_SRGB;
726   case PIPE_FORMAT_X8R8G8B8_UNORM:
727      return PIPE_FORMAT_X8R8G8B8_SRGB;
728   case PIPE_FORMAT_DXT1_RGB:
729      return PIPE_FORMAT_DXT1_SRGB;
730   case PIPE_FORMAT_DXT1_RGBA:
731      return PIPE_FORMAT_DXT1_SRGBA;
732   case PIPE_FORMAT_DXT3_RGBA:
733      return PIPE_FORMAT_DXT3_SRGBA;
734   case PIPE_FORMAT_DXT5_RGBA:
735      return PIPE_FORMAT_DXT5_SRGBA;
736   default:
737      return PIPE_FORMAT_NONE;
738   }
739}
740
741/**
742 * Given an sRGB format, return the corresponding linear colorspace format.
743 * For non sRGB formats, return the format unchanged.
744 */
745static INLINE enum pipe_format
746util_format_linear(enum pipe_format format)
747{
748   switch (format) {
749   case PIPE_FORMAT_L8_SRGB:
750      return PIPE_FORMAT_L8_UNORM;
751   case PIPE_FORMAT_L8A8_SRGB:
752      return PIPE_FORMAT_L8A8_UNORM;
753   case PIPE_FORMAT_R8G8B8_SRGB:
754      return PIPE_FORMAT_R8G8B8_UNORM;
755   case PIPE_FORMAT_A8B8G8R8_SRGB:
756      return PIPE_FORMAT_A8B8G8R8_UNORM;
757   case PIPE_FORMAT_X8B8G8R8_SRGB:
758      return PIPE_FORMAT_X8B8G8R8_UNORM;
759   case PIPE_FORMAT_B8G8R8A8_SRGB:
760      return PIPE_FORMAT_B8G8R8A8_UNORM;
761   case PIPE_FORMAT_B8G8R8X8_SRGB:
762      return PIPE_FORMAT_B8G8R8X8_UNORM;
763   case PIPE_FORMAT_A8R8G8B8_SRGB:
764      return PIPE_FORMAT_A8R8G8B8_UNORM;
765   case PIPE_FORMAT_X8R8G8B8_SRGB:
766      return PIPE_FORMAT_X8R8G8B8_UNORM;
767   case PIPE_FORMAT_DXT1_SRGB:
768      return PIPE_FORMAT_DXT1_RGB;
769   case PIPE_FORMAT_DXT1_SRGBA:
770      return PIPE_FORMAT_DXT1_RGBA;
771   case PIPE_FORMAT_DXT3_SRGBA:
772      return PIPE_FORMAT_DXT3_RGBA;
773   case PIPE_FORMAT_DXT5_SRGBA:
774      return PIPE_FORMAT_DXT5_RGBA;
775   default:
776      return format;
777   }
778}
779
780/**
781 * Return the number of components stored.
782 * Formats with block size != 1x1 will always have 1 component (the block).
783 */
784static INLINE unsigned
785util_format_get_nr_components(enum pipe_format format)
786{
787   const struct util_format_description *desc = util_format_description(format);
788   return desc->nr_channels;
789}
790
791/*
792 * Format access functions.
793 */
794
795void
796util_format_read_4f(enum pipe_format format,
797                    float *dst, unsigned dst_stride,
798                    const void *src, unsigned src_stride,
799                    unsigned x, unsigned y, unsigned w, unsigned h);
800
801void
802util_format_write_4f(enum pipe_format format,
803                     const float *src, unsigned src_stride,
804                     void *dst, unsigned dst_stride,
805                     unsigned x, unsigned y, unsigned w, unsigned h);
806
807void
808util_format_read_4ub(enum pipe_format format,
809                     uint8_t *dst, unsigned dst_stride,
810                     const void *src, unsigned src_stride,
811                     unsigned x, unsigned y, unsigned w, unsigned h);
812
813void
814util_format_write_4ub(enum pipe_format format,
815                      const uint8_t *src, unsigned src_stride,
816                      void *dst, unsigned dst_stride,
817                      unsigned x, unsigned y, unsigned w, unsigned h);
818
819/*
820 * Generic format conversion;
821 */
822
823boolean
824util_format_fits_8unorm(const struct util_format_description *format_desc);
825
826void
827util_format_translate(enum pipe_format dst_format,
828                      void *dst, unsigned dst_stride,
829                      unsigned dst_x, unsigned dst_y,
830                      enum pipe_format src_format,
831                      const void *src, unsigned src_stride,
832                      unsigned src_x, unsigned src_y,
833                      unsigned width, unsigned height);
834
835/*
836 * Swizzle operations.
837 */
838
839/* Compose two sets of swizzles.
840 * If V is a 4D vector and the function parameters represent functions that
841 * swizzle vector components, this holds:
842 *     swz2(swz1(V)) = dst(V)
843 */
844void util_format_compose_swizzles(const unsigned char swz1[4],
845                                  const unsigned char swz2[4],
846                                  unsigned char dst[4]);
847
848void util_format_swizzle_4f(float *dst, const float *src,
849                            const unsigned char swz[4]);
850
851void util_format_unswizzle_4f(float *dst, const float *src,
852                              const unsigned char swz[4]);
853
854#ifdef __cplusplus
855} // extern "C" {
856#endif
857
858#endif /* ! U_FORMAT_H */
859