turnip: Fix indentation in function signatures
[mesa.git] / src / freedreno / vulkan / vk_format.h
1 /*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
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:
13 *
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
16 * Software.
17 *
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
24 * IN THE SOFTWARE.
25 */
26
27 #ifndef VK_FORMAT_H
28 #define VK_FORMAT_H
29
30 #include <assert.h>
31 #include <util/macros.h>
32 #include <vulkan/vulkan.h>
33
34 enum vk_format_layout
35 {
36 /**
37 * Formats with vk_format_block::width == vk_format_block::height == 1
38 * that can be described as an ordinary data structure.
39 */
40 VK_FORMAT_LAYOUT_PLAIN = 0,
41
42 /**
43 * Formats with sub-sampled channels.
44 *
45 * This is for formats like YVYU where there is less than one sample per
46 * pixel.
47 */
48 VK_FORMAT_LAYOUT_SUBSAMPLED = 3,
49
50 /**
51 * S3 Texture Compression formats.
52 */
53 VK_FORMAT_LAYOUT_S3TC = 4,
54
55 /**
56 * Red-Green Texture Compression formats.
57 */
58 VK_FORMAT_LAYOUT_RGTC = 5,
59
60 /**
61 * Ericsson Texture Compression
62 */
63 VK_FORMAT_LAYOUT_ETC = 6,
64
65 /**
66 * BC6/7 Texture Compression
67 */
68 VK_FORMAT_LAYOUT_BPTC = 7,
69
70 /**
71 * ASTC
72 */
73 VK_FORMAT_LAYOUT_ASTC = 8,
74
75 /**
76 * Everything else that doesn't fit in any of the above layouts.
77 */
78 VK_FORMAT_LAYOUT_OTHER = 9
79 };
80
81 struct vk_format_block
82 {
83 /** Block width in pixels */
84 unsigned width;
85
86 /** Block height in pixels */
87 unsigned height;
88
89 /** Block size in bits */
90 unsigned bits;
91 };
92
93 enum vk_format_type
94 {
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
100 };
101
102 enum vk_format_colorspace
103 {
104 VK_FORMAT_COLORSPACE_RGB = 0,
105 VK_FORMAT_COLORSPACE_SRGB = 1,
106 VK_FORMAT_COLORSPACE_YUV = 2,
107 VK_FORMAT_COLORSPACE_ZS = 3
108 };
109
110 struct vk_format_channel_description
111 {
112 unsigned type : 5;
113 unsigned normalized : 1;
114 unsigned pure_integer : 1;
115 unsigned scaled : 1;
116 unsigned size : 8;
117 unsigned shift : 16;
118 };
119
120 struct vk_format_description
121 {
122 VkFormat format;
123 const char *name;
124 const char *short_name;
125
126 struct vk_format_block block;
127 enum vk_format_layout layout;
128
129 unsigned nr_channels : 3;
130 unsigned is_array : 1;
131 unsigned is_bitmask : 1;
132 unsigned is_mixed : 1;
133
134 struct vk_format_channel_description channel[4];
135
136 unsigned char swizzle[4];
137
138 enum vk_format_colorspace colorspace;
139 };
140
141 extern const struct vk_format_description vk_format_description_table[];
142
143 const struct vk_format_description *
144 vk_format_description(VkFormat format);
145
146 /**
147 * Return total bits needed for the pixel format per block.
148 */
149 static inline unsigned
150 vk_format_get_blocksizebits(VkFormat format)
151 {
152 const struct vk_format_description *desc = vk_format_description(format);
153
154 assert(desc);
155 if (!desc) {
156 return 0;
157 }
158
159 return desc->block.bits;
160 }
161
162 /**
163 * Return bytes per block (not pixel) for the given format.
164 */
165 static inline unsigned
166 vk_format_get_blocksize(VkFormat format)
167 {
168 unsigned bits = vk_format_get_blocksizebits(format);
169 unsigned bytes = bits / 8;
170
171 assert(bits % 8 == 0);
172 assert(bytes > 0);
173 if (bytes == 0) {
174 bytes = 1;
175 }
176
177 return bytes;
178 }
179
180 static inline unsigned
181 vk_format_get_blockwidth(VkFormat format)
182 {
183 const struct vk_format_description *desc = vk_format_description(format);
184
185 assert(desc);
186 if (!desc) {
187 return 1;
188 }
189
190 return desc->block.width;
191 }
192
193 static inline unsigned
194 vk_format_get_blockheight(VkFormat format)
195 {
196 const struct vk_format_description *desc = vk_format_description(format);
197
198 assert(desc);
199 if (!desc) {
200 return 1;
201 }
202
203 return desc->block.height;
204 }
205
206 /**
207 * Return the index of the first non-void channel
208 * -1 if no non-void channels
209 */
210 static inline int
211 vk_format_get_first_non_void_channel(VkFormat format)
212 {
213 const struct vk_format_description *desc = vk_format_description(format);
214 int i;
215
216 for (i = 0; i < 4; i++)
217 if (desc->channel[i].type != VK_FORMAT_TYPE_VOID)
218 break;
219
220 if (i == 4)
221 return -1;
222
223 return i;
224 }
225
226 enum vk_swizzle
227 {
228 VK_SWIZZLE_X,
229 VK_SWIZZLE_Y,
230 VK_SWIZZLE_Z,
231 VK_SWIZZLE_W,
232 VK_SWIZZLE_0,
233 VK_SWIZZLE_1,
234 VK_SWIZZLE_NONE,
235 VK_SWIZZLE_MAX, /**< Number of enums counter (must be last) */
236 };
237
238 static inline VkImageAspectFlags
239 vk_format_aspects(VkFormat format)
240 {
241 switch (format) {
242 case VK_FORMAT_UNDEFINED:
243 return 0;
244
245 case VK_FORMAT_S8_UINT:
246 return VK_IMAGE_ASPECT_STENCIL_BIT;
247
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;
252
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;
257
258 default:
259 return VK_IMAGE_ASPECT_COLOR_BIT;
260 }
261 }
262
263 static inline enum vk_swizzle
264 tu_swizzle_conv(VkComponentSwizzle component,
265 const unsigned char chan[4],
266 VkComponentSwizzle vk_swiz)
267 {
268 int x;
269
270 if (vk_swiz == VK_COMPONENT_SWIZZLE_IDENTITY)
271 vk_swiz = component;
272 switch (vk_swiz) {
273 case VK_COMPONENT_SWIZZLE_ZERO:
274 return VK_SWIZZLE_0;
275 case VK_COMPONENT_SWIZZLE_ONE:
276 return VK_SWIZZLE_1;
277 case VK_COMPONENT_SWIZZLE_R:
278 for (x = 0; x < 4; x++)
279 if (chan[x] == 0)
280 return x;
281 return VK_SWIZZLE_0;
282 case VK_COMPONENT_SWIZZLE_G:
283 for (x = 0; x < 4; x++)
284 if (chan[x] == 1)
285 return x;
286 return VK_SWIZZLE_0;
287 case VK_COMPONENT_SWIZZLE_B:
288 for (x = 0; x < 4; x++)
289 if (chan[x] == 2)
290 return x;
291 return VK_SWIZZLE_0;
292 case VK_COMPONENT_SWIZZLE_A:
293 for (x = 0; x < 4; x++)
294 if (chan[x] == 3)
295 return x;
296 return VK_SWIZZLE_1;
297 default:
298 unreachable("Illegal swizzle");
299 }
300 }
301
302 static inline void
303 vk_format_compose_swizzles(const VkComponentMapping *mapping,
304 const unsigned char swz[4],
305 enum vk_swizzle dst[4])
306 {
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);
311 }
312
313 static inline bool
314 vk_format_is_compressed(VkFormat format)
315 {
316 const struct vk_format_description *desc = vk_format_description(format);
317
318 assert(desc);
319 if (!desc) {
320 return false;
321 }
322
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 */
330 return true;
331 default:
332 return false;
333 }
334 }
335
336 static inline bool
337 vk_format_has_depth(const struct vk_format_description *desc)
338 {
339 return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
340 desc->swizzle[0] != VK_SWIZZLE_NONE;
341 }
342
343 static inline bool
344 vk_format_has_stencil(const struct vk_format_description *desc)
345 {
346 return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
347 desc->swizzle[1] != VK_SWIZZLE_NONE;
348 }
349
350 static inline bool
351 vk_format_is_depth_or_stencil(VkFormat format)
352 {
353 const struct vk_format_description *desc = vk_format_description(format);
354
355 assert(desc);
356 if (!desc) {
357 return false;
358 }
359
360 return vk_format_has_depth(desc) || vk_format_has_stencil(desc);
361 }
362
363 static inline bool
364 vk_format_is_depth(VkFormat format)
365 {
366 const struct vk_format_description *desc = vk_format_description(format);
367
368 assert(desc);
369 if (!desc) {
370 return false;
371 }
372
373 return vk_format_has_depth(desc);
374 }
375
376 static inline bool
377 vk_format_is_stencil(VkFormat format)
378 {
379 const struct vk_format_description *desc = vk_format_description(format);
380
381 assert(desc);
382 if (!desc) {
383 return false;
384 }
385
386 return vk_format_has_stencil(desc);
387 }
388
389 static inline bool
390 vk_format_is_color(VkFormat format)
391 {
392 return !vk_format_is_depth_or_stencil(format);
393 }
394
395 static inline VkFormat
396 vk_format_depth_only(VkFormat format)
397 {
398 switch (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;
405 default:
406 return format;
407 }
408 }
409
410 static inline bool
411 vk_format_is_int(VkFormat format)
412 {
413 const struct vk_format_description *desc = vk_format_description(format);
414 int channel = vk_format_get_first_non_void_channel(format);
415
416 return channel >= 0 && desc->channel[channel].pure_integer;
417 }
418
419 static inline bool
420 vk_format_is_srgb(VkFormat format)
421 {
422 const struct vk_format_description *desc = vk_format_description(format);
423 return desc->colorspace == VK_FORMAT_COLORSPACE_SRGB;
424 }
425
426 static inline VkFormat
427 vk_format_no_srgb(VkFormat format)
428 {
429 switch (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;
460 default:
461 assert(!vk_format_is_srgb(format));
462 return format;
463 }
464 }
465
466 static inline VkFormat
467 vk_format_stencil_only(VkFormat format)
468 {
469 return VK_FORMAT_S8_UINT;
470 }
471
472 static inline unsigned
473 vk_format_get_component_bits(VkFormat format,
474 enum vk_format_colorspace colorspace,
475 unsigned component)
476 {
477 const struct vk_format_description *desc = vk_format_description(format);
478 enum vk_format_colorspace desc_colorspace;
479
480 assert(format);
481 if (!format) {
482 return 0;
483 }
484
485 assert(component < 4);
486
487 /* Treat RGB and SRGB as equivalent. */
488 if (colorspace == VK_FORMAT_COLORSPACE_SRGB) {
489 colorspace = VK_FORMAT_COLORSPACE_RGB;
490 }
491 if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
492 desc_colorspace = VK_FORMAT_COLORSPACE_RGB;
493 } else {
494 desc_colorspace = desc->colorspace;
495 }
496
497 if (desc_colorspace != colorspace) {
498 return 0;
499 }
500
501 switch (desc->swizzle[component]) {
502 case VK_SWIZZLE_X:
503 return desc->channel[0].size;
504 case VK_SWIZZLE_Y:
505 return desc->channel[1].size;
506 case VK_SWIZZLE_Z:
507 return desc->channel[2].size;
508 case VK_SWIZZLE_W:
509 return desc->channel[3].size;
510 default:
511 return 0;
512 }
513 }
514
515 static inline VkFormat
516 vk_to_non_srgb_format(VkFormat format)
517 {
518 switch (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;
533 default:
534 return format;
535 }
536 }
537
538 static inline unsigned
539 vk_format_get_nr_components(VkFormat format)
540 {
541 const struct vk_format_description *desc = vk_format_description(format);
542 return desc->nr_channels;
543 }
544
545 #endif /* VK_FORMAT_H */