2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
5 * Based on u_format.h which is:
6 * Copyright 2009-2010 Vmware, Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
31 #include <util/macros.h>
32 #include <vulkan/vulkan.h>
37 * Formats with vk_format_block::width == vk_format_block::height == 1
38 * that can be described as an ordinary data structure.
40 VK_FORMAT_LAYOUT_PLAIN
= 0,
43 * Formats with sub-sampled channels.
45 * This is for formats like YVYU where there is less than one sample per
48 VK_FORMAT_LAYOUT_SUBSAMPLED
= 3,
51 * S3 Texture Compression formats.
53 VK_FORMAT_LAYOUT_S3TC
= 4,
56 * Red-Green Texture Compression formats.
58 VK_FORMAT_LAYOUT_RGTC
= 5,
61 * Ericsson Texture Compression
63 VK_FORMAT_LAYOUT_ETC
= 6,
66 * BC6/7 Texture Compression
68 VK_FORMAT_LAYOUT_BPTC
= 7,
73 VK_FORMAT_LAYOUT_ASTC
= 8,
76 * Everything else that doesn't fit in any of the above layouts.
78 VK_FORMAT_LAYOUT_OTHER
= 9
81 struct vk_format_block
83 /** Block width in pixels */
86 /** Block height in pixels */
89 /** Block size in bits */
95 VK_FORMAT_TYPE_VOID
= 0,
96 VK_FORMAT_TYPE_UNSIGNED
= 1,
97 VK_FORMAT_TYPE_SIGNED
= 2,
98 VK_FORMAT_TYPE_FIXED
= 3,
99 VK_FORMAT_TYPE_FLOAT
= 4
102 enum vk_format_colorspace
104 VK_FORMAT_COLORSPACE_RGB
= 0,
105 VK_FORMAT_COLORSPACE_SRGB
= 1,
106 VK_FORMAT_COLORSPACE_YUV
= 2,
107 VK_FORMAT_COLORSPACE_ZS
= 3
110 struct vk_format_channel_description
113 unsigned normalized
: 1;
114 unsigned pure_integer
: 1;
120 struct vk_format_description
124 const char *short_name
;
126 struct vk_format_block block
;
127 enum vk_format_layout layout
;
129 unsigned nr_channels
: 3;
130 unsigned is_array
: 1;
131 unsigned is_bitmask
: 1;
132 unsigned is_mixed
: 1;
134 struct vk_format_channel_description channel
[4];
136 unsigned char swizzle
[4];
138 enum vk_format_colorspace colorspace
;
141 extern const struct vk_format_description vk_format_description_table
[];
143 const struct vk_format_description
*
144 vk_format_description(VkFormat format
);
147 * Return total bits needed for the pixel format per block.
149 static inline unsigned
150 vk_format_get_blocksizebits(VkFormat format
)
152 const struct vk_format_description
*desc
= vk_format_description(format
);
159 return desc
->block
.bits
;
163 * Return bytes per block (not pixel) for the given format.
165 static inline unsigned
166 vk_format_get_blocksize(VkFormat format
)
168 unsigned bits
= vk_format_get_blocksizebits(format
);
169 unsigned bytes
= bits
/ 8;
171 assert(bits
% 8 == 0);
180 static inline unsigned
181 vk_format_get_blockwidth(VkFormat format
)
183 const struct vk_format_description
*desc
= vk_format_description(format
);
190 return desc
->block
.width
;
193 static inline unsigned
194 vk_format_get_blockheight(VkFormat format
)
196 const struct vk_format_description
*desc
= vk_format_description(format
);
203 return desc
->block
.height
;
207 * Return the index of the first non-void channel
208 * -1 if no non-void channels
211 vk_format_get_first_non_void_channel(VkFormat format
)
213 const struct vk_format_description
*desc
= vk_format_description(format
);
216 for (i
= 0; i
< 4; i
++)
217 if (desc
->channel
[i
].type
!= VK_FORMAT_TYPE_VOID
)
235 VK_SWIZZLE_MAX
, /**< Number of enums counter (must be last) */
238 static inline VkImageAspectFlags
239 vk_format_aspects(VkFormat format
)
242 case VK_FORMAT_UNDEFINED
:
245 case VK_FORMAT_S8_UINT
:
246 return VK_IMAGE_ASPECT_STENCIL_BIT
;
248 case VK_FORMAT_D16_UNORM_S8_UINT
:
249 case VK_FORMAT_D24_UNORM_S8_UINT
:
250 case VK_FORMAT_D32_SFLOAT_S8_UINT
:
251 return VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT
;
253 case VK_FORMAT_D16_UNORM
:
254 case VK_FORMAT_X8_D24_UNORM_PACK32
:
255 case VK_FORMAT_D32_SFLOAT
:
256 return VK_IMAGE_ASPECT_DEPTH_BIT
;
259 return VK_IMAGE_ASPECT_COLOR_BIT
;
263 static inline enum vk_swizzle
264 tu_swizzle_conv(VkComponentSwizzle component
,
265 const unsigned char chan
[4],
266 VkComponentSwizzle vk_swiz
)
270 if (vk_swiz
== VK_COMPONENT_SWIZZLE_IDENTITY
)
273 case VK_COMPONENT_SWIZZLE_ZERO
:
275 case VK_COMPONENT_SWIZZLE_ONE
:
277 case VK_COMPONENT_SWIZZLE_R
:
278 for (x
= 0; x
< 4; x
++)
282 case VK_COMPONENT_SWIZZLE_G
:
283 for (x
= 0; x
< 4; x
++)
287 case VK_COMPONENT_SWIZZLE_B
:
288 for (x
= 0; x
< 4; x
++)
292 case VK_COMPONENT_SWIZZLE_A
:
293 for (x
= 0; x
< 4; x
++)
298 unreachable("Illegal swizzle");
303 vk_format_compose_swizzles(const VkComponentMapping
*mapping
,
304 const unsigned char swz
[4],
305 enum vk_swizzle dst
[4])
307 dst
[0] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_R
, swz
, mapping
->r
);
308 dst
[1] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_G
, swz
, mapping
->g
);
309 dst
[2] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_B
, swz
, mapping
->b
);
310 dst
[3] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_A
, swz
, mapping
->a
);
314 vk_format_is_compressed(VkFormat format
)
316 const struct vk_format_description
*desc
= vk_format_description(format
);
323 switch (desc
->layout
) {
324 case VK_FORMAT_LAYOUT_S3TC
:
325 case VK_FORMAT_LAYOUT_RGTC
:
326 case VK_FORMAT_LAYOUT_ETC
:
327 case VK_FORMAT_LAYOUT_BPTC
:
328 case VK_FORMAT_LAYOUT_ASTC
:
329 /* XXX add other formats in the future */
337 vk_format_has_depth(const struct vk_format_description
*desc
)
339 return desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
&&
340 desc
->swizzle
[0] != VK_SWIZZLE_NONE
;
344 vk_format_has_stencil(const struct vk_format_description
*desc
)
346 return desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
&&
347 desc
->swizzle
[1] != VK_SWIZZLE_NONE
;
351 vk_format_is_depth_or_stencil(VkFormat format
)
353 const struct vk_format_description
*desc
= vk_format_description(format
);
360 return vk_format_has_depth(desc
) || vk_format_has_stencil(desc
);
364 vk_format_is_depth(VkFormat format
)
366 const struct vk_format_description
*desc
= vk_format_description(format
);
373 return vk_format_has_depth(desc
);
377 vk_format_is_stencil(VkFormat format
)
379 const struct vk_format_description
*desc
= vk_format_description(format
);
386 return vk_format_has_stencil(desc
);
390 vk_format_is_color(VkFormat format
)
392 return !vk_format_is_depth_or_stencil(format
);
395 static inline VkFormat
396 vk_format_depth_only(VkFormat format
)
399 case VK_FORMAT_D16_UNORM_S8_UINT
:
400 return VK_FORMAT_D16_UNORM
;
401 case VK_FORMAT_D24_UNORM_S8_UINT
:
402 return VK_FORMAT_X8_D24_UNORM_PACK32
;
403 case VK_FORMAT_D32_SFLOAT_S8_UINT
:
404 return VK_FORMAT_D32_SFLOAT
;
411 vk_format_is_int(VkFormat format
)
413 const struct vk_format_description
*desc
= vk_format_description(format
);
414 int channel
= vk_format_get_first_non_void_channel(format
);
416 return channel
>= 0 && desc
->channel
[channel
].pure_integer
;
420 vk_format_is_srgb(VkFormat format
)
422 const struct vk_format_description
*desc
= vk_format_description(format
);
423 return desc
->colorspace
== VK_FORMAT_COLORSPACE_SRGB
;
426 static inline VkFormat
427 vk_format_no_srgb(VkFormat format
)
430 case VK_FORMAT_R8_SRGB
:
431 return VK_FORMAT_R8_UNORM
;
432 case VK_FORMAT_R8G8_SRGB
:
433 return VK_FORMAT_R8G8_UNORM
;
434 case VK_FORMAT_R8G8B8_SRGB
:
435 return VK_FORMAT_R8G8B8_UNORM
;
436 case VK_FORMAT_B8G8R8_SRGB
:
437 return VK_FORMAT_B8G8R8_UNORM
;
438 case VK_FORMAT_R8G8B8A8_SRGB
:
439 return VK_FORMAT_R8G8B8A8_UNORM
;
440 case VK_FORMAT_B8G8R8A8_SRGB
:
441 return VK_FORMAT_B8G8R8A8_UNORM
;
442 case VK_FORMAT_A8B8G8R8_SRGB_PACK32
:
443 return VK_FORMAT_A8B8G8R8_UNORM_PACK32
;
444 case VK_FORMAT_BC1_RGB_SRGB_BLOCK
:
445 return VK_FORMAT_BC1_RGB_UNORM_BLOCK
;
446 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK
:
447 return VK_FORMAT_BC1_RGBA_UNORM_BLOCK
;
448 case VK_FORMAT_BC2_SRGB_BLOCK
:
449 return VK_FORMAT_BC2_UNORM_BLOCK
;
450 case VK_FORMAT_BC3_SRGB_BLOCK
:
451 return VK_FORMAT_BC3_UNORM_BLOCK
;
452 case VK_FORMAT_BC7_SRGB_BLOCK
:
453 return VK_FORMAT_BC7_UNORM_BLOCK
;
454 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK
:
455 return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK
;
456 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK
:
457 return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK
;
458 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK
:
459 return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK
;
461 assert(!vk_format_is_srgb(format
));
466 static inline VkFormat
467 vk_format_stencil_only(VkFormat format
)
469 return VK_FORMAT_S8_UINT
;
472 static inline unsigned
473 vk_format_get_component_bits(VkFormat format
,
474 enum vk_format_colorspace colorspace
,
477 const struct vk_format_description
*desc
= vk_format_description(format
);
478 enum vk_format_colorspace desc_colorspace
;
485 assert(component
< 4);
487 /* Treat RGB and SRGB as equivalent. */
488 if (colorspace
== VK_FORMAT_COLORSPACE_SRGB
) {
489 colorspace
= VK_FORMAT_COLORSPACE_RGB
;
491 if (desc
->colorspace
== VK_FORMAT_COLORSPACE_SRGB
) {
492 desc_colorspace
= VK_FORMAT_COLORSPACE_RGB
;
494 desc_colorspace
= desc
->colorspace
;
497 if (desc_colorspace
!= colorspace
) {
501 switch (desc
->swizzle
[component
]) {
503 return desc
->channel
[0].size
;
505 return desc
->channel
[1].size
;
507 return desc
->channel
[2].size
;
509 return desc
->channel
[3].size
;
515 static inline VkFormat
516 vk_to_non_srgb_format(VkFormat format
)
519 case VK_FORMAT_R8_SRGB
:
520 return VK_FORMAT_R8_UNORM
;
521 case VK_FORMAT_R8G8_SRGB
:
522 return VK_FORMAT_R8G8_UNORM
;
523 case VK_FORMAT_R8G8B8_SRGB
:
524 return VK_FORMAT_R8G8B8_UNORM
;
525 case VK_FORMAT_B8G8R8_SRGB
:
526 return VK_FORMAT_B8G8R8_UNORM
;
527 case VK_FORMAT_R8G8B8A8_SRGB
:
528 return VK_FORMAT_R8G8B8A8_UNORM
;
529 case VK_FORMAT_B8G8R8A8_SRGB
:
530 return VK_FORMAT_B8G8R8A8_UNORM
;
531 case VK_FORMAT_A8B8G8R8_SRGB_PACK32
:
532 return VK_FORMAT_A8B8G8R8_UNORM_PACK32
;
538 static inline unsigned
539 vk_format_get_nr_components(VkFormat format
)
541 const struct vk_format_description
*desc
= vk_format_description(format
);
542 return desc
->nr_channels
;
545 #endif /* VK_FORMAT_H */