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 <vulkan/vulkan.h>
32 #include <util/macros.h>
34 enum vk_format_layout
{
36 * Formats with vk_format_block::width == vk_format_block::height == 1
37 * that can be described as an ordinary data structure.
39 VK_FORMAT_LAYOUT_PLAIN
= 0,
42 * Formats with sub-sampled channels.
44 * This is for formats like YVYU where there is less than one sample per
47 VK_FORMAT_LAYOUT_SUBSAMPLED
= 3,
50 * S3 Texture Compression formats.
52 VK_FORMAT_LAYOUT_S3TC
= 4,
55 * Red-Green Texture Compression formats.
57 VK_FORMAT_LAYOUT_RGTC
= 5,
60 * Ericsson Texture Compression
62 VK_FORMAT_LAYOUT_ETC
= 6,
65 * BC6/7 Texture Compression
67 VK_FORMAT_LAYOUT_BPTC
= 7,
72 VK_FORMAT_LAYOUT_ASTC
= 8,
75 * Everything else that doesn't fit in any of the above layouts.
77 VK_FORMAT_LAYOUT_OTHER
= 9,
80 * Formats that contain multiple planes.
82 VK_FORMAT_LAYOUT_MULTIPLANE
= 10,
85 struct vk_format_block
87 /** Block width in pixels */
90 /** Block height in pixels */
93 /** Block size in bits */
98 VK_FORMAT_TYPE_VOID
= 0,
99 VK_FORMAT_TYPE_UNSIGNED
= 1,
100 VK_FORMAT_TYPE_SIGNED
= 2,
101 VK_FORMAT_TYPE_FIXED
= 3,
102 VK_FORMAT_TYPE_FLOAT
= 4
106 enum vk_format_colorspace
{
107 VK_FORMAT_COLORSPACE_RGB
= 0,
108 VK_FORMAT_COLORSPACE_SRGB
= 1,
109 VK_FORMAT_COLORSPACE_YUV
= 2,
110 VK_FORMAT_COLORSPACE_ZS
= 3
113 struct vk_format_channel_description
{
115 unsigned normalized
:1;
116 unsigned pure_integer
:1;
122 struct vk_format_description
126 const char *short_name
;
128 struct vk_format_block block
;
129 enum vk_format_layout layout
;
131 unsigned nr_channels
:3;
133 unsigned is_bitmask
:1;
136 struct vk_format_channel_description channel
[4];
138 unsigned char swizzle
[4];
140 enum vk_format_colorspace colorspace
;
142 unsigned plane_count
:2;
143 unsigned width_divisor
:2;
144 unsigned height_divisor
:2;
145 VkFormat plane_formats
[3];
148 extern const struct vk_format_description vk_format_description_table
[];
150 const struct vk_format_description
*vk_format_description(VkFormat format
);
153 * Return total bits needed for the pixel format per block.
155 static inline unsigned
156 vk_format_get_blocksizebits(VkFormat format
)
158 const struct vk_format_description
*desc
= vk_format_description(format
);
165 return desc
->block
.bits
;
169 * Return bytes per block (not pixel) for the given format.
171 static inline unsigned
172 vk_format_get_blocksize(VkFormat format
)
174 unsigned bits
= vk_format_get_blocksizebits(format
);
175 unsigned bytes
= bits
/ 8;
177 assert(bits
% 8 == 0);
186 static inline unsigned
187 vk_format_get_blockwidth(VkFormat format
)
189 const struct vk_format_description
*desc
= vk_format_description(format
);
196 return desc
->block
.width
;
199 static inline unsigned
200 vk_format_get_blockheight(VkFormat format
)
202 const struct vk_format_description
*desc
= vk_format_description(format
);
209 return desc
->block
.height
;
213 * Return the index of the first non-void channel
214 * -1 if no non-void channels
217 vk_format_get_first_non_void_channel(VkFormat format
)
219 const struct vk_format_description
*desc
= vk_format_description(format
);
222 for (i
= 0; i
< 4; i
++)
223 if (desc
->channel
[i
].type
!= VK_FORMAT_TYPE_VOID
)
240 VK_SWIZZLE_MAX
, /**< Number of enums counter (must be last) */
243 static inline VkImageAspectFlags
244 vk_format_aspects(VkFormat format
)
247 case VK_FORMAT_UNDEFINED
:
250 case VK_FORMAT_S8_UINT
:
251 return VK_IMAGE_ASPECT_STENCIL_BIT
;
253 case VK_FORMAT_D16_UNORM_S8_UINT
:
254 case VK_FORMAT_D24_UNORM_S8_UINT
:
255 case VK_FORMAT_D32_SFLOAT_S8_UINT
:
256 return VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT
;
258 case VK_FORMAT_D16_UNORM
:
259 case VK_FORMAT_X8_D24_UNORM_PACK32
:
260 case VK_FORMAT_D32_SFLOAT
:
261 return VK_IMAGE_ASPECT_DEPTH_BIT
;
264 return VK_IMAGE_ASPECT_COLOR_BIT
;
268 static inline enum vk_swizzle
269 radv_swizzle_conv(VkComponentSwizzle component
, const unsigned char chan
[4], VkComponentSwizzle vk_swiz
)
273 if (vk_swiz
== VK_COMPONENT_SWIZZLE_IDENTITY
)
276 case VK_COMPONENT_SWIZZLE_ZERO
:
278 case VK_COMPONENT_SWIZZLE_ONE
:
280 case VK_COMPONENT_SWIZZLE_R
:
281 for (x
= 0; x
< 4; x
++)
285 case VK_COMPONENT_SWIZZLE_G
:
286 for (x
= 0; x
< 4; x
++)
290 case VK_COMPONENT_SWIZZLE_B
:
291 for (x
= 0; x
< 4; x
++)
295 case VK_COMPONENT_SWIZZLE_A
:
296 for (x
= 0; x
< 4; x
++)
301 unreachable("Illegal swizzle");
305 static inline void vk_format_compose_swizzles(const VkComponentMapping
*mapping
,
306 const unsigned char swz
[4],
307 enum vk_swizzle dst
[4])
309 dst
[0] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_R
, swz
, mapping
->r
);
310 dst
[1] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_G
, swz
, mapping
->g
);
311 dst
[2] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_B
, swz
, mapping
->b
);
312 dst
[3] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_A
, swz
, mapping
->a
);
316 vk_format_is_compressed(VkFormat format
)
318 const struct vk_format_description
*desc
= vk_format_description(format
);
325 switch (desc
->layout
) {
326 case VK_FORMAT_LAYOUT_S3TC
:
327 case VK_FORMAT_LAYOUT_RGTC
:
328 case VK_FORMAT_LAYOUT_ETC
:
329 case VK_FORMAT_LAYOUT_BPTC
:
330 case VK_FORMAT_LAYOUT_ASTC
:
331 /* XXX add other formats in the future */
339 vk_format_is_subsampled(VkFormat format
)
341 const struct vk_format_description
*desc
= vk_format_description(format
);
348 return desc
->layout
== VK_FORMAT_LAYOUT_SUBSAMPLED
;
352 vk_format_has_depth(const struct vk_format_description
*desc
)
354 return desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
&&
355 desc
->swizzle
[0] != VK_SWIZZLE_NONE
;
359 vk_format_has_stencil(const struct vk_format_description
*desc
)
361 return desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
&&
362 desc
->swizzle
[1] != VK_SWIZZLE_NONE
;
366 vk_format_is_depth_or_stencil(VkFormat format
)
368 const struct vk_format_description
*desc
= vk_format_description(format
);
375 return vk_format_has_depth(desc
) ||
376 vk_format_has_stencil(desc
);
380 vk_format_is_depth(VkFormat format
)
382 const struct vk_format_description
*desc
= vk_format_description(format
);
389 return vk_format_has_depth(desc
);
393 vk_format_is_stencil(VkFormat format
)
395 const struct vk_format_description
*desc
= vk_format_description(format
);
402 return vk_format_has_stencil(desc
);
406 vk_format_is_color(VkFormat format
)
408 return !vk_format_is_depth_or_stencil(format
);
411 static inline VkFormat
412 vk_format_depth_only(VkFormat format
)
415 case VK_FORMAT_D16_UNORM_S8_UINT
:
416 return VK_FORMAT_D16_UNORM
;
417 case VK_FORMAT_D24_UNORM_S8_UINT
:
418 return VK_FORMAT_X8_D24_UNORM_PACK32
;
419 case VK_FORMAT_D32_SFLOAT_S8_UINT
:
420 return VK_FORMAT_D32_SFLOAT
;
427 vk_format_is_int(VkFormat format
)
429 const struct vk_format_description
*desc
= vk_format_description(format
);
430 int channel
= vk_format_get_first_non_void_channel(format
);
432 return channel
>= 0 && desc
->channel
[channel
].pure_integer
;
436 vk_format_is_srgb(VkFormat format
)
438 const struct vk_format_description
*desc
= vk_format_description(format
);
439 return desc
->colorspace
== VK_FORMAT_COLORSPACE_SRGB
;
442 static inline VkFormat
443 vk_format_no_srgb(VkFormat format
)
446 case VK_FORMAT_R8_SRGB
:
447 return VK_FORMAT_R8_UNORM
;
448 case VK_FORMAT_R8G8_SRGB
:
449 return VK_FORMAT_R8G8_UNORM
;
450 case VK_FORMAT_R8G8B8_SRGB
:
451 return VK_FORMAT_R8G8B8_UNORM
;
452 case VK_FORMAT_B8G8R8_SRGB
:
453 return VK_FORMAT_B8G8R8_UNORM
;
454 case VK_FORMAT_R8G8B8A8_SRGB
:
455 return VK_FORMAT_R8G8B8A8_UNORM
;
456 case VK_FORMAT_B8G8R8A8_SRGB
:
457 return VK_FORMAT_B8G8R8A8_UNORM
;
458 case VK_FORMAT_A8B8G8R8_SRGB_PACK32
:
459 return VK_FORMAT_A8B8G8R8_UNORM_PACK32
;
460 case VK_FORMAT_BC1_RGB_SRGB_BLOCK
:
461 return VK_FORMAT_BC1_RGB_UNORM_BLOCK
;
462 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK
:
463 return VK_FORMAT_BC1_RGBA_UNORM_BLOCK
;
464 case VK_FORMAT_BC2_SRGB_BLOCK
:
465 return VK_FORMAT_BC2_UNORM_BLOCK
;
466 case VK_FORMAT_BC3_SRGB_BLOCK
:
467 return VK_FORMAT_BC3_UNORM_BLOCK
;
468 case VK_FORMAT_BC7_SRGB_BLOCK
:
469 return VK_FORMAT_BC7_UNORM_BLOCK
;
470 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK
:
471 return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK
;
472 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK
:
473 return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK
;
474 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK
:
475 return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK
;
477 assert(!vk_format_is_srgb(format
));
482 static inline VkFormat
483 vk_format_stencil_only(VkFormat format
)
485 return VK_FORMAT_S8_UINT
;
488 static inline unsigned
489 vk_format_get_component_bits(VkFormat format
,
490 enum vk_format_colorspace colorspace
,
493 const struct vk_format_description
*desc
= vk_format_description(format
);
494 enum vk_format_colorspace desc_colorspace
;
501 assert(component
< 4);
503 /* Treat RGB and SRGB as equivalent. */
504 if (colorspace
== VK_FORMAT_COLORSPACE_SRGB
) {
505 colorspace
= VK_FORMAT_COLORSPACE_RGB
;
507 if (desc
->colorspace
== VK_FORMAT_COLORSPACE_SRGB
) {
508 desc_colorspace
= VK_FORMAT_COLORSPACE_RGB
;
510 desc_colorspace
= desc
->colorspace
;
513 if (desc_colorspace
!= colorspace
) {
517 switch (desc
->swizzle
[component
]) {
519 return desc
->channel
[0].size
;
521 return desc
->channel
[1].size
;
523 return desc
->channel
[2].size
;
525 return desc
->channel
[3].size
;
531 static inline VkFormat
532 vk_to_non_srgb_format(VkFormat format
)
535 case VK_FORMAT_R8_SRGB
:
536 return VK_FORMAT_R8_UNORM
;
537 case VK_FORMAT_R8G8_SRGB
:
538 return VK_FORMAT_R8G8_UNORM
;
539 case VK_FORMAT_R8G8B8_SRGB
:
540 return VK_FORMAT_R8G8B8_UNORM
;
541 case VK_FORMAT_B8G8R8_SRGB
:
542 return VK_FORMAT_B8G8R8_UNORM
;
543 case VK_FORMAT_R8G8B8A8_SRGB
:
544 return VK_FORMAT_R8G8B8A8_UNORM
;
545 case VK_FORMAT_B8G8R8A8_SRGB
:
546 return VK_FORMAT_B8G8R8A8_UNORM
;
547 case VK_FORMAT_A8B8G8R8_SRGB_PACK32
:
548 return VK_FORMAT_A8B8G8R8_UNORM_PACK32
;
554 static inline unsigned
555 vk_format_get_nr_components(VkFormat format
)
557 const struct vk_format_description
*desc
= vk_format_description(format
);
558 return desc
->nr_channels
;
561 static inline unsigned
562 vk_format_get_plane_count(VkFormat format
)
564 const struct vk_format_description
*desc
= vk_format_description(format
);
566 return desc
->plane_count
;
569 static inline VkFormat
570 vk_format_get_plane_format(VkFormat format
, unsigned plane_id
)
572 const struct vk_format_description
*desc
= vk_format_description(format
);
574 if (desc
->layout
!= VK_FORMAT_LAYOUT_MULTIPLANE
) {
575 assert(plane_id
== 0);
579 assert(plane_id
< desc
->plane_count
);
581 return desc
->plane_formats
[plane_id
];
585 #endif /* VK_FORMAT_H */