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
30 #include <vulkan/vulkan.h>
31 #include <util/macros.h>
33 enum vk_format_layout
{
35 * Formats with vk_format_block::width == vk_format_block::height == 1
36 * that can be described as an ordinary data structure.
38 VK_FORMAT_LAYOUT_PLAIN
= 0,
41 * Formats with sub-sampled channels.
43 * This is for formats like YVYU where there is less than one sample per
46 VK_FORMAT_LAYOUT_SUBSAMPLED
= 3,
49 * S3 Texture Compression formats.
51 VK_FORMAT_LAYOUT_S3TC
= 4,
54 * Red-Green Texture Compression formats.
56 VK_FORMAT_LAYOUT_RGTC
= 5,
59 * Ericsson Texture Compression
61 VK_FORMAT_LAYOUT_ETC
= 6,
64 * BC6/7 Texture Compression
66 VK_FORMAT_LAYOUT_BPTC
= 7,
71 VK_FORMAT_LAYOUT_ASTC
= 8,
74 * Everything else that doesn't fit in any of the above layouts.
76 VK_FORMAT_LAYOUT_OTHER
= 9
79 struct vk_format_block
81 /** Block width in pixels */
84 /** Block height in pixels */
87 /** Block size in bits */
92 VK_FORMAT_TYPE_VOID
= 0,
93 VK_FORMAT_TYPE_UNSIGNED
= 1,
94 VK_FORMAT_TYPE_SIGNED
= 2,
95 VK_FORMAT_TYPE_FIXED
= 3,
96 VK_FORMAT_TYPE_FLOAT
= 4
100 enum vk_format_colorspace
{
101 VK_FORMAT_COLORSPACE_RGB
= 0,
102 VK_FORMAT_COLORSPACE_SRGB
= 1,
103 VK_FORMAT_COLORSPACE_YUV
= 2,
104 VK_FORMAT_COLORSPACE_ZS
= 3
107 struct vk_format_channel_description
{
109 unsigned normalized
:1;
110 unsigned pure_integer
:1;
116 struct vk_format_description
120 const char *short_name
;
122 struct vk_format_block block
;
123 enum vk_format_layout layout
;
125 unsigned nr_channels
:3;
127 unsigned is_bitmask
:1;
130 struct vk_format_channel_description channel
[4];
132 unsigned char swizzle
[4];
134 enum vk_format_colorspace colorspace
;
137 extern const struct vk_format_description vk_format_description_table
[];
139 const struct vk_format_description
*vk_format_description(VkFormat format
);
142 * Return total bits needed for the pixel format per block.
144 static inline unsigned
145 vk_format_get_blocksizebits(VkFormat format
)
147 const struct vk_format_description
*desc
= vk_format_description(format
);
154 return desc
->block
.bits
;
158 * Return bytes per block (not pixel) for the given format.
160 static inline unsigned
161 vk_format_get_blocksize(VkFormat format
)
163 unsigned bits
= vk_format_get_blocksizebits(format
);
164 unsigned bytes
= bits
/ 8;
166 assert(bits
% 8 == 0);
175 static inline unsigned
176 vk_format_get_blockwidth(VkFormat format
)
178 const struct vk_format_description
*desc
= vk_format_description(format
);
185 return desc
->block
.width
;
188 static inline unsigned
189 vk_format_get_blockheight(VkFormat format
)
191 const struct vk_format_description
*desc
= vk_format_description(format
);
198 return desc
->block
.height
;
202 * Return the index of the first non-void channel
203 * -1 if no non-void channels
206 vk_format_get_first_non_void_channel(VkFormat format
)
208 const struct vk_format_description
*desc
= vk_format_description(format
);
211 for (i
= 0; i
< 4; i
++)
212 if (desc
->channel
[i
].type
!= VK_FORMAT_TYPE_VOID
)
229 VK_SWIZZLE_MAX
, /**< Number of enums counter (must be last) */
232 static inline VkImageAspectFlags
233 vk_format_aspects(VkFormat format
)
236 case VK_FORMAT_UNDEFINED
:
239 case VK_FORMAT_S8_UINT
:
240 return VK_IMAGE_ASPECT_STENCIL_BIT
;
242 case VK_FORMAT_D16_UNORM_S8_UINT
:
243 case VK_FORMAT_D24_UNORM_S8_UINT
:
244 case VK_FORMAT_D32_SFLOAT_S8_UINT
:
245 return VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT
;
247 case VK_FORMAT_D16_UNORM
:
248 case VK_FORMAT_X8_D24_UNORM_PACK32
:
249 case VK_FORMAT_D32_SFLOAT
:
250 return VK_IMAGE_ASPECT_DEPTH_BIT
;
253 return VK_IMAGE_ASPECT_COLOR_BIT
;
257 static inline enum vk_swizzle
258 radv_swizzle_conv(VkComponentSwizzle component
, const unsigned char chan
[4], VkComponentSwizzle vk_swiz
)
262 if (vk_swiz
== VK_COMPONENT_SWIZZLE_IDENTITY
)
265 case VK_COMPONENT_SWIZZLE_ZERO
:
267 case VK_COMPONENT_SWIZZLE_ONE
:
269 case VK_COMPONENT_SWIZZLE_R
:
270 for (x
= 0; x
< 4; x
++)
274 case VK_COMPONENT_SWIZZLE_G
:
275 for (x
= 0; x
< 4; x
++)
279 case VK_COMPONENT_SWIZZLE_B
:
280 for (x
= 0; x
< 4; x
++)
284 case VK_COMPONENT_SWIZZLE_A
:
285 for (x
= 0; x
< 4; x
++)
290 unreachable("Illegal swizzle");
294 static inline void vk_format_compose_swizzles(const VkComponentMapping
*mapping
,
295 const unsigned char swz
[4],
296 enum vk_swizzle dst
[4])
298 dst
[0] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_R
, swz
, mapping
->r
);
299 dst
[1] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_G
, swz
, mapping
->g
);
300 dst
[2] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_B
, swz
, mapping
->b
);
301 dst
[3] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_A
, swz
, mapping
->a
);
305 vk_format_is_compressed(VkFormat format
)
307 const struct vk_format_description
*desc
= vk_format_description(format
);
314 switch (desc
->layout
) {
315 case VK_FORMAT_LAYOUT_S3TC
:
316 case VK_FORMAT_LAYOUT_RGTC
:
317 case VK_FORMAT_LAYOUT_ETC
:
318 case VK_FORMAT_LAYOUT_BPTC
:
319 case VK_FORMAT_LAYOUT_ASTC
:
320 /* XXX add other formats in the future */
328 vk_format_has_depth(const struct vk_format_description
*desc
)
330 return desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
&&
331 desc
->swizzle
[0] != VK_SWIZZLE_NONE
;
335 vk_format_has_stencil(const struct vk_format_description
*desc
)
337 return desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
&&
338 desc
->swizzle
[1] != VK_SWIZZLE_NONE
;
342 vk_format_is_depth_or_stencil(VkFormat format
)
344 const struct vk_format_description
*desc
= vk_format_description(format
);
351 return vk_format_has_depth(desc
) ||
352 vk_format_has_stencil(desc
);
356 vk_format_is_depth(VkFormat format
)
358 const struct vk_format_description
*desc
= vk_format_description(format
);
365 return vk_format_has_depth(desc
);
369 vk_format_is_color(VkFormat format
)
371 return !vk_format_is_depth_or_stencil(format
);
374 static inline VkFormat
375 vk_format_depth_only(VkFormat format
)
378 case VK_FORMAT_D16_UNORM_S8_UINT
:
379 return VK_FORMAT_D16_UNORM
;
380 case VK_FORMAT_D24_UNORM_S8_UINT
:
381 return VK_FORMAT_X8_D24_UNORM_PACK32
;
382 case VK_FORMAT_D32_SFLOAT_S8_UINT
:
383 return VK_FORMAT_D32_SFLOAT
;
390 vk_format_is_int(VkFormat format
)
392 const struct vk_format_description
*desc
= vk_format_description(format
);
393 int channel
= vk_format_get_first_non_void_channel(format
);
395 return channel
>= 0 && desc
->channel
[channel
].pure_integer
;
398 static inline VkFormat
399 vk_format_stencil_only(VkFormat format
)
401 return VK_FORMAT_S8_UINT
;
404 static inline unsigned
405 vk_format_get_component_bits(VkFormat format
,
406 enum vk_format_colorspace colorspace
,
409 const struct vk_format_description
*desc
= vk_format_description(format
);
410 enum vk_format_colorspace desc_colorspace
;
417 assert(component
< 4);
419 /* Treat RGB and SRGB as equivalent. */
420 if (colorspace
== VK_FORMAT_COLORSPACE_SRGB
) {
421 colorspace
= VK_FORMAT_COLORSPACE_RGB
;
423 if (desc
->colorspace
== VK_FORMAT_COLORSPACE_SRGB
) {
424 desc_colorspace
= VK_FORMAT_COLORSPACE_RGB
;
426 desc_colorspace
= desc
->colorspace
;
429 if (desc_colorspace
!= colorspace
) {
433 switch (desc
->swizzle
[component
]) {
435 return desc
->channel
[0].size
;
437 return desc
->channel
[1].size
;
439 return desc
->channel
[2].size
;
441 return desc
->channel
[3].size
;