1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2016 Red Hat.
3b8e80941Smrg * Copyright © 2016 Bas Nieuwenhuizen
4b8e80941Smrg *
5b8e80941Smrg * Based on u_format.h which is:
6b8e80941Smrg * Copyright 2009-2010 Vmware, Inc.
7b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
8b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
9b8e80941Smrg * to deal in the Software without restriction, including without limitation
10b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
12b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
13b8e80941Smrg *
14b8e80941Smrg * The above copyright notice and this permission notice (including the next
15b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
16b8e80941Smrg * Software.
17b8e80941Smrg *
18b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24b8e80941Smrg * DEALINGS IN THE SOFTWARE.
25b8e80941Smrg */
26b8e80941Smrg
27b8e80941Smrg#ifndef VK_FORMAT_H
28b8e80941Smrg#define VK_FORMAT_H
29b8e80941Smrg
30b8e80941Smrg#include <assert.h>
31b8e80941Smrg#include <util/macros.h>
32b8e80941Smrg
33b8e80941Smrg#include <vulkan/vulkan.h>
34b8e80941Smrg
35b8e80941Smrgenum vk_format_layout
36b8e80941Smrg{
37b8e80941Smrg   /**
38b8e80941Smrg    * Formats with vk_format_block::width == vk_format_block::height == 1
39b8e80941Smrg    * that can be described as an ordinary data structure.
40b8e80941Smrg    */
41b8e80941Smrg   VK_FORMAT_LAYOUT_PLAIN = 0,
42b8e80941Smrg
43b8e80941Smrg   /**
44b8e80941Smrg    * Formats with sub-sampled channels.
45b8e80941Smrg    *
46b8e80941Smrg    * This is for formats like YVYU where there is less than one sample per
47b8e80941Smrg    * pixel.
48b8e80941Smrg    */
49b8e80941Smrg   VK_FORMAT_LAYOUT_SUBSAMPLED = 3,
50b8e80941Smrg
51b8e80941Smrg   /**
52b8e80941Smrg    * S3 Texture Compression formats.
53b8e80941Smrg    */
54b8e80941Smrg   VK_FORMAT_LAYOUT_S3TC = 4,
55b8e80941Smrg
56b8e80941Smrg   /**
57b8e80941Smrg    * Red-Green Texture Compression formats.
58b8e80941Smrg    */
59b8e80941Smrg   VK_FORMAT_LAYOUT_RGTC = 5,
60b8e80941Smrg
61b8e80941Smrg   /**
62b8e80941Smrg    * Ericsson Texture Compression
63b8e80941Smrg    */
64b8e80941Smrg   VK_FORMAT_LAYOUT_ETC = 6,
65b8e80941Smrg
66b8e80941Smrg   /**
67b8e80941Smrg    * BC6/7 Texture Compression
68b8e80941Smrg    */
69b8e80941Smrg   VK_FORMAT_LAYOUT_BPTC = 7,
70b8e80941Smrg
71b8e80941Smrg   /**
72b8e80941Smrg    * ASTC
73b8e80941Smrg    */
74b8e80941Smrg   VK_FORMAT_LAYOUT_ASTC = 8,
75b8e80941Smrg
76b8e80941Smrg   /**
77b8e80941Smrg    * Everything else that doesn't fit in any of the above layouts.
78b8e80941Smrg    */
79b8e80941Smrg   VK_FORMAT_LAYOUT_OTHER = 9
80b8e80941Smrg};
81b8e80941Smrg
82b8e80941Smrgstruct vk_format_block
83b8e80941Smrg{
84b8e80941Smrg   /** Block width in pixels */
85b8e80941Smrg   unsigned width;
86b8e80941Smrg
87b8e80941Smrg   /** Block height in pixels */
88b8e80941Smrg   unsigned height;
89b8e80941Smrg
90b8e80941Smrg   /** Block size in bits */
91b8e80941Smrg   unsigned bits;
92b8e80941Smrg};
93b8e80941Smrg
94b8e80941Smrgenum vk_format_type
95b8e80941Smrg{
96b8e80941Smrg   VK_FORMAT_TYPE_VOID = 0,
97b8e80941Smrg   VK_FORMAT_TYPE_UNSIGNED = 1,
98b8e80941Smrg   VK_FORMAT_TYPE_SIGNED = 2,
99b8e80941Smrg   VK_FORMAT_TYPE_FIXED = 3,
100b8e80941Smrg   VK_FORMAT_TYPE_FLOAT = 4
101b8e80941Smrg};
102b8e80941Smrg
103b8e80941Smrgenum vk_format_colorspace
104b8e80941Smrg{
105b8e80941Smrg   VK_FORMAT_COLORSPACE_RGB = 0,
106b8e80941Smrg   VK_FORMAT_COLORSPACE_SRGB = 1,
107b8e80941Smrg   VK_FORMAT_COLORSPACE_YUV = 2,
108b8e80941Smrg   VK_FORMAT_COLORSPACE_ZS = 3
109b8e80941Smrg};
110b8e80941Smrg
111b8e80941Smrgstruct vk_format_channel_description
112b8e80941Smrg{
113b8e80941Smrg   unsigned type : 5;
114b8e80941Smrg   unsigned normalized : 1;
115b8e80941Smrg   unsigned pure_integer : 1;
116b8e80941Smrg   unsigned scaled : 1;
117b8e80941Smrg   unsigned size : 8;
118b8e80941Smrg   unsigned shift : 16;
119b8e80941Smrg};
120b8e80941Smrg
121b8e80941Smrgstruct vk_format_description
122b8e80941Smrg{
123b8e80941Smrg   VkFormat format;
124b8e80941Smrg   const char *name;
125b8e80941Smrg   const char *short_name;
126b8e80941Smrg
127b8e80941Smrg   struct vk_format_block block;
128b8e80941Smrg   enum vk_format_layout layout;
129b8e80941Smrg
130b8e80941Smrg   unsigned nr_channels : 3;
131b8e80941Smrg   unsigned is_array : 1;
132b8e80941Smrg   unsigned is_bitmask : 1;
133b8e80941Smrg   unsigned is_mixed : 1;
134b8e80941Smrg
135b8e80941Smrg   struct vk_format_channel_description channel[4];
136b8e80941Smrg
137b8e80941Smrg   unsigned char swizzle[4];
138b8e80941Smrg
139b8e80941Smrg   enum vk_format_colorspace colorspace;
140b8e80941Smrg};
141b8e80941Smrg
142b8e80941Smrgextern const struct vk_format_description vk_format_description_table[];
143b8e80941Smrg
144b8e80941Smrgconst struct vk_format_description *
145b8e80941Smrgvk_format_description(VkFormat format);
146b8e80941Smrg
147b8e80941Smrg/**
148b8e80941Smrg * Return total bits needed for the pixel format per block.
149b8e80941Smrg */
150b8e80941Smrgstatic inline unsigned
151b8e80941Smrgvk_format_get_blocksizebits(VkFormat format)
152b8e80941Smrg{
153b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
154b8e80941Smrg
155b8e80941Smrg   assert(desc);
156b8e80941Smrg   if (!desc) {
157b8e80941Smrg      return 0;
158b8e80941Smrg   }
159b8e80941Smrg
160b8e80941Smrg   return desc->block.bits;
161b8e80941Smrg}
162b8e80941Smrg
163b8e80941Smrg/**
164b8e80941Smrg * Return bytes per block (not pixel) for the given format.
165b8e80941Smrg */
166b8e80941Smrgstatic inline unsigned
167b8e80941Smrgvk_format_get_blocksize(VkFormat format)
168b8e80941Smrg{
169b8e80941Smrg   unsigned bits = vk_format_get_blocksizebits(format);
170b8e80941Smrg   unsigned bytes = bits / 8;
171b8e80941Smrg
172b8e80941Smrg   assert(bits % 8 == 0);
173b8e80941Smrg   assert(bytes > 0);
174b8e80941Smrg   if (bytes == 0) {
175b8e80941Smrg      bytes = 1;
176b8e80941Smrg   }
177b8e80941Smrg
178b8e80941Smrg   return bytes;
179b8e80941Smrg}
180b8e80941Smrg
181b8e80941Smrgstatic inline unsigned
182b8e80941Smrgvk_format_get_blockwidth(VkFormat format)
183b8e80941Smrg{
184b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
185b8e80941Smrg
186b8e80941Smrg   assert(desc);
187b8e80941Smrg   if (!desc) {
188b8e80941Smrg      return 1;
189b8e80941Smrg   }
190b8e80941Smrg
191b8e80941Smrg   return desc->block.width;
192b8e80941Smrg}
193b8e80941Smrg
194b8e80941Smrgstatic inline unsigned
195b8e80941Smrgvk_format_get_blockheight(VkFormat format)
196b8e80941Smrg{
197b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
198b8e80941Smrg
199b8e80941Smrg   assert(desc);
200b8e80941Smrg   if (!desc) {
201b8e80941Smrg      return 1;
202b8e80941Smrg   }
203b8e80941Smrg
204b8e80941Smrg   return desc->block.height;
205b8e80941Smrg}
206b8e80941Smrg
207b8e80941Smrgstatic inline unsigned
208b8e80941Smrgvk_format_get_block_count_width(VkFormat format, unsigned width)
209b8e80941Smrg{
210b8e80941Smrg   unsigned blockwidth = vk_format_get_blockwidth(format);
211b8e80941Smrg   return (width + blockwidth - 1) / blockwidth;
212b8e80941Smrg}
213b8e80941Smrg
214b8e80941Smrgstatic inline unsigned
215b8e80941Smrgvk_format_get_block_count_height(VkFormat format, unsigned height)
216b8e80941Smrg{
217b8e80941Smrg   unsigned blockheight = vk_format_get_blockheight(format);
218b8e80941Smrg   return (height + blockheight - 1) / blockheight;
219b8e80941Smrg}
220b8e80941Smrg
221b8e80941Smrgstatic inline unsigned
222b8e80941Smrgvk_format_get_block_count(VkFormat format, unsigned width, unsigned height)
223b8e80941Smrg{
224b8e80941Smrg   return vk_format_get_block_count_width(format, width) *
225b8e80941Smrg          vk_format_get_block_count_height(format, height);
226b8e80941Smrg}
227b8e80941Smrg
228b8e80941Smrg/**
229b8e80941Smrg * Return the index of the first non-void channel
230b8e80941Smrg * -1 if no non-void channels
231b8e80941Smrg */
232b8e80941Smrgstatic inline int
233b8e80941Smrgvk_format_get_first_non_void_channel(VkFormat format)
234b8e80941Smrg{
235b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
236b8e80941Smrg   int i;
237b8e80941Smrg
238b8e80941Smrg   for (i = 0; i < 4; i++)
239b8e80941Smrg      if (desc->channel[i].type != VK_FORMAT_TYPE_VOID)
240b8e80941Smrg         break;
241b8e80941Smrg
242b8e80941Smrg   if (i == 4)
243b8e80941Smrg      return -1;
244b8e80941Smrg
245b8e80941Smrg   return i;
246b8e80941Smrg}
247b8e80941Smrg
248b8e80941Smrgenum vk_swizzle
249b8e80941Smrg{
250b8e80941Smrg   VK_SWIZZLE_X,
251b8e80941Smrg   VK_SWIZZLE_Y,
252b8e80941Smrg   VK_SWIZZLE_Z,
253b8e80941Smrg   VK_SWIZZLE_W,
254b8e80941Smrg   VK_SWIZZLE_0,
255b8e80941Smrg   VK_SWIZZLE_1,
256b8e80941Smrg   VK_SWIZZLE_NONE,
257b8e80941Smrg   VK_SWIZZLE_MAX, /**< Number of enums counter (must be last) */
258b8e80941Smrg};
259b8e80941Smrg
260b8e80941Smrgstatic inline VkImageAspectFlags
261b8e80941Smrgvk_format_aspects(VkFormat format)
262b8e80941Smrg{
263b8e80941Smrg   switch (format) {
264b8e80941Smrg   case VK_FORMAT_UNDEFINED:
265b8e80941Smrg      return 0;
266b8e80941Smrg
267b8e80941Smrg   case VK_FORMAT_S8_UINT:
268b8e80941Smrg      return VK_IMAGE_ASPECT_STENCIL_BIT;
269b8e80941Smrg
270b8e80941Smrg   case VK_FORMAT_D16_UNORM_S8_UINT:
271b8e80941Smrg   case VK_FORMAT_D24_UNORM_S8_UINT:
272b8e80941Smrg   case VK_FORMAT_D32_SFLOAT_S8_UINT:
273b8e80941Smrg      return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
274b8e80941Smrg
275b8e80941Smrg   case VK_FORMAT_D16_UNORM:
276b8e80941Smrg   case VK_FORMAT_X8_D24_UNORM_PACK32:
277b8e80941Smrg   case VK_FORMAT_D32_SFLOAT:
278b8e80941Smrg      return VK_IMAGE_ASPECT_DEPTH_BIT;
279b8e80941Smrg
280b8e80941Smrg   default:
281b8e80941Smrg      return VK_IMAGE_ASPECT_COLOR_BIT;
282b8e80941Smrg   }
283b8e80941Smrg}
284b8e80941Smrg
285b8e80941Smrgstatic inline enum vk_swizzle
286b8e80941Smrgtu_swizzle_conv(VkComponentSwizzle component,
287b8e80941Smrg                const unsigned char chan[4],
288b8e80941Smrg                VkComponentSwizzle vk_swiz)
289b8e80941Smrg{
290b8e80941Smrg   int x;
291b8e80941Smrg
292b8e80941Smrg   if (vk_swiz == VK_COMPONENT_SWIZZLE_IDENTITY)
293b8e80941Smrg      vk_swiz = component;
294b8e80941Smrg   switch (vk_swiz) {
295b8e80941Smrg   case VK_COMPONENT_SWIZZLE_ZERO:
296b8e80941Smrg      return VK_SWIZZLE_0;
297b8e80941Smrg   case VK_COMPONENT_SWIZZLE_ONE:
298b8e80941Smrg      return VK_SWIZZLE_1;
299b8e80941Smrg   case VK_COMPONENT_SWIZZLE_R:
300b8e80941Smrg      for (x = 0; x < 4; x++)
301b8e80941Smrg         if (chan[x] == 0)
302b8e80941Smrg            return x;
303b8e80941Smrg      return VK_SWIZZLE_0;
304b8e80941Smrg   case VK_COMPONENT_SWIZZLE_G:
305b8e80941Smrg      for (x = 0; x < 4; x++)
306b8e80941Smrg         if (chan[x] == 1)
307b8e80941Smrg            return x;
308b8e80941Smrg      return VK_SWIZZLE_0;
309b8e80941Smrg   case VK_COMPONENT_SWIZZLE_B:
310b8e80941Smrg      for (x = 0; x < 4; x++)
311b8e80941Smrg         if (chan[x] == 2)
312b8e80941Smrg            return x;
313b8e80941Smrg      return VK_SWIZZLE_0;
314b8e80941Smrg   case VK_COMPONENT_SWIZZLE_A:
315b8e80941Smrg      for (x = 0; x < 4; x++)
316b8e80941Smrg         if (chan[x] == 3)
317b8e80941Smrg            return x;
318b8e80941Smrg      return VK_SWIZZLE_1;
319b8e80941Smrg   default:
320b8e80941Smrg      unreachable("Illegal swizzle");
321b8e80941Smrg   }
322b8e80941Smrg}
323b8e80941Smrg
324b8e80941Smrgstatic inline void
325b8e80941Smrgvk_format_compose_swizzles(const VkComponentMapping *mapping,
326b8e80941Smrg                           const unsigned char swz[4],
327b8e80941Smrg                           enum vk_swizzle dst[4])
328b8e80941Smrg{
329b8e80941Smrg   dst[0] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_R, swz, mapping->r);
330b8e80941Smrg   dst[1] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_G, swz, mapping->g);
331b8e80941Smrg   dst[2] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_B, swz, mapping->b);
332b8e80941Smrg   dst[3] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_A, swz, mapping->a);
333b8e80941Smrg}
334b8e80941Smrg
335b8e80941Smrgstatic inline bool
336b8e80941Smrgvk_format_is_compressed(VkFormat format)
337b8e80941Smrg{
338b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
339b8e80941Smrg
340b8e80941Smrg   assert(desc);
341b8e80941Smrg   if (!desc) {
342b8e80941Smrg      return false;
343b8e80941Smrg   }
344b8e80941Smrg
345b8e80941Smrg   switch (desc->layout) {
346b8e80941Smrg   case VK_FORMAT_LAYOUT_S3TC:
347b8e80941Smrg   case VK_FORMAT_LAYOUT_RGTC:
348b8e80941Smrg   case VK_FORMAT_LAYOUT_ETC:
349b8e80941Smrg   case VK_FORMAT_LAYOUT_BPTC:
350b8e80941Smrg   case VK_FORMAT_LAYOUT_ASTC:
351b8e80941Smrg      /* XXX add other formats in the future */
352b8e80941Smrg      return true;
353b8e80941Smrg   default:
354b8e80941Smrg      return false;
355b8e80941Smrg   }
356b8e80941Smrg}
357b8e80941Smrg
358b8e80941Smrgstatic inline bool
359b8e80941Smrgvk_format_has_depth(const struct vk_format_description *desc)
360b8e80941Smrg{
361b8e80941Smrg   return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
362b8e80941Smrg          desc->swizzle[0] != VK_SWIZZLE_NONE;
363b8e80941Smrg}
364b8e80941Smrg
365b8e80941Smrgstatic inline bool
366b8e80941Smrgvk_format_has_stencil(const struct vk_format_description *desc)
367b8e80941Smrg{
368b8e80941Smrg   return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
369b8e80941Smrg          desc->swizzle[1] != VK_SWIZZLE_NONE;
370b8e80941Smrg}
371b8e80941Smrg
372b8e80941Smrgstatic inline bool
373b8e80941Smrgvk_format_is_depth_or_stencil(VkFormat format)
374b8e80941Smrg{
375b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
376b8e80941Smrg
377b8e80941Smrg   assert(desc);
378b8e80941Smrg   if (!desc) {
379b8e80941Smrg      return false;
380b8e80941Smrg   }
381b8e80941Smrg
382b8e80941Smrg   return vk_format_has_depth(desc) || vk_format_has_stencil(desc);
383b8e80941Smrg}
384b8e80941Smrg
385b8e80941Smrgstatic inline bool
386b8e80941Smrgvk_format_is_depth(VkFormat format)
387b8e80941Smrg{
388b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
389b8e80941Smrg
390b8e80941Smrg   assert(desc);
391b8e80941Smrg   if (!desc) {
392b8e80941Smrg      return false;
393b8e80941Smrg   }
394b8e80941Smrg
395b8e80941Smrg   return vk_format_has_depth(desc);
396b8e80941Smrg}
397b8e80941Smrg
398b8e80941Smrgstatic inline bool
399b8e80941Smrgvk_format_is_stencil(VkFormat format)
400b8e80941Smrg{
401b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
402b8e80941Smrg
403b8e80941Smrg   assert(desc);
404b8e80941Smrg   if (!desc) {
405b8e80941Smrg      return false;
406b8e80941Smrg   }
407b8e80941Smrg
408b8e80941Smrg   return vk_format_has_stencil(desc);
409b8e80941Smrg}
410b8e80941Smrg
411b8e80941Smrgstatic inline bool
412b8e80941Smrgvk_format_is_color(VkFormat format)
413b8e80941Smrg{
414b8e80941Smrg   return !vk_format_is_depth_or_stencil(format);
415b8e80941Smrg}
416b8e80941Smrg
417b8e80941Smrgstatic inline bool
418b8e80941Smrgvk_format_has_alpha(VkFormat format)
419b8e80941Smrg{
420b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
421b8e80941Smrg
422b8e80941Smrg   return (desc->colorspace == VK_FORMAT_COLORSPACE_RGB ||
423b8e80941Smrg           desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) &&
424b8e80941Smrg          desc->swizzle[3] != VK_SWIZZLE_1;
425b8e80941Smrg}
426b8e80941Smrg
427b8e80941Smrgstatic inline VkFormat
428b8e80941Smrgvk_format_depth_only(VkFormat format)
429b8e80941Smrg{
430b8e80941Smrg   switch (format) {
431b8e80941Smrg   case VK_FORMAT_D16_UNORM_S8_UINT:
432b8e80941Smrg      return VK_FORMAT_D16_UNORM;
433b8e80941Smrg   case VK_FORMAT_D24_UNORM_S8_UINT:
434b8e80941Smrg      return VK_FORMAT_X8_D24_UNORM_PACK32;
435b8e80941Smrg   case VK_FORMAT_D32_SFLOAT_S8_UINT:
436b8e80941Smrg      return VK_FORMAT_D32_SFLOAT;
437b8e80941Smrg   default:
438b8e80941Smrg      return format;
439b8e80941Smrg   }
440b8e80941Smrg}
441b8e80941Smrg
442b8e80941Smrgstatic inline bool
443b8e80941Smrgvk_format_is_int(VkFormat format)
444b8e80941Smrg{
445b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
446b8e80941Smrg   int channel = vk_format_get_first_non_void_channel(format);
447b8e80941Smrg
448b8e80941Smrg   return channel >= 0 && desc->channel[channel].pure_integer;
449b8e80941Smrg}
450b8e80941Smrg
451b8e80941Smrgstatic inline bool
452b8e80941Smrgvk_format_is_srgb(VkFormat format)
453b8e80941Smrg{
454b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
455b8e80941Smrg   return desc->colorspace == VK_FORMAT_COLORSPACE_SRGB;
456b8e80941Smrg}
457b8e80941Smrg
458b8e80941Smrgstatic inline VkFormat
459b8e80941Smrgvk_format_no_srgb(VkFormat format)
460b8e80941Smrg{
461b8e80941Smrg   switch (format) {
462b8e80941Smrg   case VK_FORMAT_R8_SRGB:
463b8e80941Smrg      return VK_FORMAT_R8_UNORM;
464b8e80941Smrg   case VK_FORMAT_R8G8_SRGB:
465b8e80941Smrg      return VK_FORMAT_R8G8_UNORM;
466b8e80941Smrg   case VK_FORMAT_R8G8B8_SRGB:
467b8e80941Smrg      return VK_FORMAT_R8G8B8_UNORM;
468b8e80941Smrg   case VK_FORMAT_B8G8R8_SRGB:
469b8e80941Smrg      return VK_FORMAT_B8G8R8_UNORM;
470b8e80941Smrg   case VK_FORMAT_R8G8B8A8_SRGB:
471b8e80941Smrg      return VK_FORMAT_R8G8B8A8_UNORM;
472b8e80941Smrg   case VK_FORMAT_B8G8R8A8_SRGB:
473b8e80941Smrg      return VK_FORMAT_B8G8R8A8_UNORM;
474b8e80941Smrg   case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
475b8e80941Smrg      return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
476b8e80941Smrg   case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
477b8e80941Smrg      return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
478b8e80941Smrg   case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
479b8e80941Smrg      return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
480b8e80941Smrg   case VK_FORMAT_BC2_SRGB_BLOCK:
481b8e80941Smrg      return VK_FORMAT_BC2_UNORM_BLOCK;
482b8e80941Smrg   case VK_FORMAT_BC3_SRGB_BLOCK:
483b8e80941Smrg      return VK_FORMAT_BC3_UNORM_BLOCK;
484b8e80941Smrg   case VK_FORMAT_BC7_SRGB_BLOCK:
485b8e80941Smrg      return VK_FORMAT_BC7_UNORM_BLOCK;
486b8e80941Smrg   case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
487b8e80941Smrg      return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
488b8e80941Smrg   case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
489b8e80941Smrg      return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
490b8e80941Smrg   case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
491b8e80941Smrg      return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
492b8e80941Smrg   default:
493b8e80941Smrg      assert(!vk_format_is_srgb(format));
494b8e80941Smrg      return format;
495b8e80941Smrg   }
496b8e80941Smrg}
497b8e80941Smrg
498b8e80941Smrgstatic inline VkFormat
499b8e80941Smrgvk_format_stencil_only(VkFormat format)
500b8e80941Smrg{
501b8e80941Smrg   return VK_FORMAT_S8_UINT;
502b8e80941Smrg}
503b8e80941Smrg
504b8e80941Smrgstatic inline unsigned
505b8e80941Smrgvk_format_get_component_bits(VkFormat format,
506b8e80941Smrg                             enum vk_format_colorspace colorspace,
507b8e80941Smrg                             unsigned component)
508b8e80941Smrg{
509b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
510b8e80941Smrg   enum vk_format_colorspace desc_colorspace;
511b8e80941Smrg
512b8e80941Smrg   assert(format);
513b8e80941Smrg   if (!format) {
514b8e80941Smrg      return 0;
515b8e80941Smrg   }
516b8e80941Smrg
517b8e80941Smrg   assert(component < 4);
518b8e80941Smrg
519b8e80941Smrg   /* Treat RGB and SRGB as equivalent. */
520b8e80941Smrg   if (colorspace == VK_FORMAT_COLORSPACE_SRGB) {
521b8e80941Smrg      colorspace = VK_FORMAT_COLORSPACE_RGB;
522b8e80941Smrg   }
523b8e80941Smrg   if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
524b8e80941Smrg      desc_colorspace = VK_FORMAT_COLORSPACE_RGB;
525b8e80941Smrg   } else {
526b8e80941Smrg      desc_colorspace = desc->colorspace;
527b8e80941Smrg   }
528b8e80941Smrg
529b8e80941Smrg   if (desc_colorspace != colorspace) {
530b8e80941Smrg      return 0;
531b8e80941Smrg   }
532b8e80941Smrg
533b8e80941Smrg   switch (desc->swizzle[component]) {
534b8e80941Smrg   case VK_SWIZZLE_X:
535b8e80941Smrg      return desc->channel[0].size;
536b8e80941Smrg   case VK_SWIZZLE_Y:
537b8e80941Smrg      return desc->channel[1].size;
538b8e80941Smrg   case VK_SWIZZLE_Z:
539b8e80941Smrg      return desc->channel[2].size;
540b8e80941Smrg   case VK_SWIZZLE_W:
541b8e80941Smrg      return desc->channel[3].size;
542b8e80941Smrg   default:
543b8e80941Smrg      return 0;
544b8e80941Smrg   }
545b8e80941Smrg}
546b8e80941Smrg
547b8e80941Smrgstatic inline VkFormat
548b8e80941Smrgvk_to_non_srgb_format(VkFormat format)
549b8e80941Smrg{
550b8e80941Smrg   switch (format) {
551b8e80941Smrg   case VK_FORMAT_R8_SRGB:
552b8e80941Smrg      return VK_FORMAT_R8_UNORM;
553b8e80941Smrg   case VK_FORMAT_R8G8_SRGB:
554b8e80941Smrg      return VK_FORMAT_R8G8_UNORM;
555b8e80941Smrg   case VK_FORMAT_R8G8B8_SRGB:
556b8e80941Smrg      return VK_FORMAT_R8G8B8_UNORM;
557b8e80941Smrg   case VK_FORMAT_B8G8R8_SRGB:
558b8e80941Smrg      return VK_FORMAT_B8G8R8_UNORM;
559b8e80941Smrg   case VK_FORMAT_R8G8B8A8_SRGB:
560b8e80941Smrg      return VK_FORMAT_R8G8B8A8_UNORM;
561b8e80941Smrg   case VK_FORMAT_B8G8R8A8_SRGB:
562b8e80941Smrg      return VK_FORMAT_B8G8R8A8_UNORM;
563b8e80941Smrg   case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
564b8e80941Smrg      return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
565b8e80941Smrg   default:
566b8e80941Smrg      return format;
567b8e80941Smrg   }
568b8e80941Smrg}
569b8e80941Smrg
570b8e80941Smrgstatic inline unsigned
571b8e80941Smrgvk_format_get_nr_components(VkFormat format)
572b8e80941Smrg{
573b8e80941Smrg   const struct vk_format_description *desc = vk_format_description(format);
574b8e80941Smrg   return desc->nr_channels;
575b8e80941Smrg}
576b8e80941Smrg
577b8e80941Smrg#endif /* VK_FORMAT_H */
578