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
24 * DEALINGS IN THE SOFTWARE.
31 #include <util/macros.h>
33 #include <vulkan/vulkan.h>
38 * Formats with vk_format_block::width == vk_format_block::height == 1
39 * that can be described as an ordinary data structure.
41 VK_FORMAT_LAYOUT_PLAIN
= 0,
44 * Formats with sub-sampled channels.
46 * This is for formats like YVYU where there is less than one sample per
49 VK_FORMAT_LAYOUT_SUBSAMPLED
= 3,
52 * S3 Texture Compression formats.
54 VK_FORMAT_LAYOUT_S3TC
= 4,
57 * Red-Green Texture Compression formats.
59 VK_FORMAT_LAYOUT_RGTC
= 5,
62 * Ericsson Texture Compression
64 VK_FORMAT_LAYOUT_ETC
= 6,
67 * BC6/7 Texture Compression
69 VK_FORMAT_LAYOUT_BPTC
= 7,
74 VK_FORMAT_LAYOUT_ASTC
= 8,
77 * Everything else that doesn't fit in any of the above layouts.
79 VK_FORMAT_LAYOUT_OTHER
= 9
82 struct vk_format_block
84 /** Block width in pixels */
87 /** Block height in pixels */
90 /** Block size in bits */
96 VK_FORMAT_TYPE_VOID
= 0,
97 VK_FORMAT_TYPE_UNSIGNED
= 1,
98 VK_FORMAT_TYPE_SIGNED
= 2,
99 VK_FORMAT_TYPE_FIXED
= 3,
100 VK_FORMAT_TYPE_FLOAT
= 4
103 enum vk_format_colorspace
105 VK_FORMAT_COLORSPACE_RGB
= 0,
106 VK_FORMAT_COLORSPACE_SRGB
= 1,
107 VK_FORMAT_COLORSPACE_YUV
= 2,
108 VK_FORMAT_COLORSPACE_ZS
= 3
111 struct vk_format_channel_description
114 unsigned normalized
: 1;
115 unsigned pure_integer
: 1;
121 struct vk_format_description
125 const char *short_name
;
127 struct vk_format_block block
;
128 enum vk_format_layout layout
;
130 unsigned nr_channels
: 3;
131 unsigned is_array
: 1;
132 unsigned is_bitmask
: 1;
133 unsigned is_mixed
: 1;
135 struct vk_format_channel_description channel
[4];
137 unsigned char swizzle
[4];
139 enum vk_format_colorspace colorspace
;
142 extern const struct vk_format_description vk_format_description_table
[];
144 const struct vk_format_description
*
145 vk_format_description(VkFormat format
);
148 * Return total bits needed for the pixel format per block.
150 static inline unsigned
151 vk_format_get_blocksizebits(VkFormat format
)
153 const struct vk_format_description
*desc
= vk_format_description(format
);
160 return desc
->block
.bits
;
164 * Return bytes per block (not pixel) for the given format.
166 static inline unsigned
167 vk_format_get_blocksize(VkFormat format
)
169 unsigned bits
= vk_format_get_blocksizebits(format
);
170 unsigned bytes
= bits
/ 8;
172 assert(bits
% 8 == 0);
181 static inline unsigned
182 vk_format_get_blockwidth(VkFormat format
)
184 const struct vk_format_description
*desc
= vk_format_description(format
);
191 return desc
->block
.width
;
194 static inline unsigned
195 vk_format_get_blockheight(VkFormat format
)
197 const struct vk_format_description
*desc
= vk_format_description(format
);
204 return desc
->block
.height
;
207 static inline unsigned
208 vk_format_get_block_count_width(VkFormat format
, unsigned width
)
210 unsigned blockwidth
= vk_format_get_blockwidth(format
);
211 return (width
+ blockwidth
- 1) / blockwidth
;
214 static inline unsigned
215 vk_format_get_block_count_height(VkFormat format
, unsigned height
)
217 unsigned blockheight
= vk_format_get_blockheight(format
);
218 return (height
+ blockheight
- 1) / blockheight
;
221 static inline unsigned
222 vk_format_get_block_count(VkFormat format
, unsigned width
, unsigned height
)
224 return vk_format_get_block_count_width(format
, width
) *
225 vk_format_get_block_count_height(format
, height
);
229 * Return the index of the first non-void channel
230 * -1 if no non-void channels
233 vk_format_get_first_non_void_channel(VkFormat format
)
235 const struct vk_format_description
*desc
= vk_format_description(format
);
238 for (i
= 0; i
< 4; i
++)
239 if (desc
->channel
[i
].type
!= VK_FORMAT_TYPE_VOID
)
257 VK_SWIZZLE_MAX
, /**< Number of enums counter (must be last) */
260 static inline VkImageAspectFlags
261 vk_format_aspects(VkFormat format
)
264 case VK_FORMAT_UNDEFINED
:
267 case VK_FORMAT_S8_UINT
:
268 return VK_IMAGE_ASPECT_STENCIL_BIT
;
270 case VK_FORMAT_D16_UNORM_S8_UINT
:
271 case VK_FORMAT_D24_UNORM_S8_UINT
:
272 case VK_FORMAT_D32_SFLOAT_S8_UINT
:
273 return VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT
;
275 case VK_FORMAT_D16_UNORM
:
276 case VK_FORMAT_X8_D24_UNORM_PACK32
:
277 case VK_FORMAT_D32_SFLOAT
:
278 return VK_IMAGE_ASPECT_DEPTH_BIT
;
281 return VK_IMAGE_ASPECT_COLOR_BIT
;
285 static inline enum vk_swizzle
286 tu_swizzle_conv(VkComponentSwizzle component
,
287 const unsigned char chan
[4],
288 VkComponentSwizzle vk_swiz
)
292 if (vk_swiz
== VK_COMPONENT_SWIZZLE_IDENTITY
)
295 case VK_COMPONENT_SWIZZLE_ZERO
:
297 case VK_COMPONENT_SWIZZLE_ONE
:
299 case VK_COMPONENT_SWIZZLE_R
:
300 for (x
= 0; x
< 4; x
++)
304 case VK_COMPONENT_SWIZZLE_G
:
305 for (x
= 0; x
< 4; x
++)
309 case VK_COMPONENT_SWIZZLE_B
:
310 for (x
= 0; x
< 4; x
++)
314 case VK_COMPONENT_SWIZZLE_A
:
315 for (x
= 0; x
< 4; x
++)
320 unreachable("Illegal swizzle");
325 vk_format_compose_swizzles(const VkComponentMapping
*mapping
,
326 const unsigned char swz
[4],
327 enum vk_swizzle dst
[4])
329 dst
[0] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_R
, swz
, mapping
->r
);
330 dst
[1] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_G
, swz
, mapping
->g
);
331 dst
[2] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_B
, swz
, mapping
->b
);
332 dst
[3] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_A
, swz
, mapping
->a
);
336 vk_format_is_compressed(VkFormat format
)
338 const struct vk_format_description
*desc
= vk_format_description(format
);
345 switch (desc
->layout
) {
346 case VK_FORMAT_LAYOUT_S3TC
:
347 case VK_FORMAT_LAYOUT_RGTC
:
348 case VK_FORMAT_LAYOUT_ETC
:
349 case VK_FORMAT_LAYOUT_BPTC
:
350 case VK_FORMAT_LAYOUT_ASTC
:
351 /* XXX add other formats in the future */
359 vk_format_has_depth(const struct vk_format_description
*desc
)
361 return desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
&&
362 desc
->swizzle
[0] != VK_SWIZZLE_NONE
;
366 vk_format_has_stencil(const struct vk_format_description
*desc
)
368 return desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
&&
369 desc
->swizzle
[1] != VK_SWIZZLE_NONE
;
373 vk_format_is_depth_or_stencil(VkFormat format
)
375 const struct vk_format_description
*desc
= vk_format_description(format
);
382 return vk_format_has_depth(desc
) || vk_format_has_stencil(desc
);
386 vk_format_is_depth(VkFormat format
)
388 const struct vk_format_description
*desc
= vk_format_description(format
);
395 return vk_format_has_depth(desc
);
399 vk_format_is_stencil(VkFormat format
)
401 const struct vk_format_description
*desc
= vk_format_description(format
);
408 return vk_format_has_stencil(desc
);
412 vk_format_is_color(VkFormat format
)
414 return !vk_format_is_depth_or_stencil(format
);
418 vk_format_has_alpha(VkFormat format
)
420 const struct vk_format_description
*desc
= vk_format_description(format
);
422 return (desc
->colorspace
== VK_FORMAT_COLORSPACE_RGB
||
423 desc
->colorspace
== VK_FORMAT_COLORSPACE_SRGB
) &&
424 desc
->swizzle
[3] != VK_SWIZZLE_1
;
427 static inline VkFormat
428 vk_format_depth_only(VkFormat format
)
431 case VK_FORMAT_D16_UNORM_S8_UINT
:
432 return VK_FORMAT_D16_UNORM
;
433 case VK_FORMAT_D24_UNORM_S8_UINT
:
434 return VK_FORMAT_X8_D24_UNORM_PACK32
;
435 case VK_FORMAT_D32_SFLOAT_S8_UINT
:
436 return VK_FORMAT_D32_SFLOAT
;
443 vk_format_is_int(VkFormat format
)
445 const struct vk_format_description
*desc
= vk_format_description(format
);
446 int channel
= vk_format_get_first_non_void_channel(format
);
448 return channel
>= 0 && desc
->channel
[channel
].pure_integer
;
452 vk_format_is_srgb(VkFormat format
)
454 const struct vk_format_description
*desc
= vk_format_description(format
);
455 return desc
->colorspace
== VK_FORMAT_COLORSPACE_SRGB
;
458 static inline VkFormat
459 vk_format_no_srgb(VkFormat format
)
462 case VK_FORMAT_R8_SRGB
:
463 return VK_FORMAT_R8_UNORM
;
464 case VK_FORMAT_R8G8_SRGB
:
465 return VK_FORMAT_R8G8_UNORM
;
466 case VK_FORMAT_R8G8B8_SRGB
:
467 return VK_FORMAT_R8G8B8_UNORM
;
468 case VK_FORMAT_B8G8R8_SRGB
:
469 return VK_FORMAT_B8G8R8_UNORM
;
470 case VK_FORMAT_R8G8B8A8_SRGB
:
471 return VK_FORMAT_R8G8B8A8_UNORM
;
472 case VK_FORMAT_B8G8R8A8_SRGB
:
473 return VK_FORMAT_B8G8R8A8_UNORM
;
474 case VK_FORMAT_A8B8G8R8_SRGB_PACK32
:
475 return VK_FORMAT_A8B8G8R8_UNORM_PACK32
;
476 case VK_FORMAT_BC1_RGB_SRGB_BLOCK
:
477 return VK_FORMAT_BC1_RGB_UNORM_BLOCK
;
478 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK
:
479 return VK_FORMAT_BC1_RGBA_UNORM_BLOCK
;
480 case VK_FORMAT_BC2_SRGB_BLOCK
:
481 return VK_FORMAT_BC2_UNORM_BLOCK
;
482 case VK_FORMAT_BC3_SRGB_BLOCK
:
483 return VK_FORMAT_BC3_UNORM_BLOCK
;
484 case VK_FORMAT_BC7_SRGB_BLOCK
:
485 return VK_FORMAT_BC7_UNORM_BLOCK
;
486 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK
:
487 return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK
;
488 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK
:
489 return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK
;
490 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK
:
491 return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK
;
493 assert(!vk_format_is_srgb(format
));
498 static inline VkFormat
499 vk_format_stencil_only(VkFormat format
)
501 return VK_FORMAT_S8_UINT
;
504 static inline unsigned
505 vk_format_get_component_bits(VkFormat format
,
506 enum vk_format_colorspace colorspace
,
509 const struct vk_format_description
*desc
= vk_format_description(format
);
510 enum vk_format_colorspace desc_colorspace
;
517 assert(component
< 4);
519 /* Treat RGB and SRGB as equivalent. */
520 if (colorspace
== VK_FORMAT_COLORSPACE_SRGB
) {
521 colorspace
= VK_FORMAT_COLORSPACE_RGB
;
523 if (desc
->colorspace
== VK_FORMAT_COLORSPACE_SRGB
) {
524 desc_colorspace
= VK_FORMAT_COLORSPACE_RGB
;
526 desc_colorspace
= desc
->colorspace
;
529 if (desc_colorspace
!= colorspace
) {
533 switch (desc
->swizzle
[component
]) {
535 return desc
->channel
[0].size
;
537 return desc
->channel
[1].size
;
539 return desc
->channel
[2].size
;
541 return desc
->channel
[3].size
;
547 static inline VkFormat
548 vk_to_non_srgb_format(VkFormat format
)
551 case VK_FORMAT_R8_SRGB
:
552 return VK_FORMAT_R8_UNORM
;
553 case VK_FORMAT_R8G8_SRGB
:
554 return VK_FORMAT_R8G8_UNORM
;
555 case VK_FORMAT_R8G8B8_SRGB
:
556 return VK_FORMAT_R8G8B8_UNORM
;
557 case VK_FORMAT_B8G8R8_SRGB
:
558 return VK_FORMAT_B8G8R8_UNORM
;
559 case VK_FORMAT_R8G8B8A8_SRGB
:
560 return VK_FORMAT_R8G8B8A8_UNORM
;
561 case VK_FORMAT_B8G8R8A8_SRGB
:
562 return VK_FORMAT_B8G8R8A8_UNORM
;
563 case VK_FORMAT_A8B8G8R8_SRGB_PACK32
:
564 return VK_FORMAT_A8B8G8R8_UNORM_PACK32
;
570 static inline unsigned
571 vk_format_get_nr_components(VkFormat format
)
573 const struct vk_format_description
*desc
= vk_format_description(format
);
574 return desc
->nr_channels
;
577 #endif /* VK_FORMAT_H */