freedreno/ir3: track # of driver params
[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
24 * DEALINGS 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
33 #include <vulkan/vulkan.h>
34
35 enum vk_format_layout
36 {
37 /**
38 * Formats with vk_format_block::width == vk_format_block::height == 1
39 * that can be described as an ordinary data structure.
40 */
41 VK_FORMAT_LAYOUT_PLAIN = 0,
42
43 /**
44 * Formats with sub-sampled channels.
45 *
46 * This is for formats like YVYU where there is less than one sample per
47 * pixel.
48 */
49 VK_FORMAT_LAYOUT_SUBSAMPLED = 3,
50
51 /**
52 * S3 Texture Compression formats.
53 */
54 VK_FORMAT_LAYOUT_S3TC = 4,
55
56 /**
57 * Red-Green Texture Compression formats.
58 */
59 VK_FORMAT_LAYOUT_RGTC = 5,
60
61 /**
62 * Ericsson Texture Compression
63 */
64 VK_FORMAT_LAYOUT_ETC = 6,
65
66 /**
67 * BC6/7 Texture Compression
68 */
69 VK_FORMAT_LAYOUT_BPTC = 7,
70
71 /**
72 * ASTC
73 */
74 VK_FORMAT_LAYOUT_ASTC = 8,
75
76 /**
77 * Everything else that doesn't fit in any of the above layouts.
78 */
79 VK_FORMAT_LAYOUT_OTHER = 9
80 };
81
82 struct vk_format_block
83 {
84 /** Block width in pixels */
85 unsigned width;
86
87 /** Block height in pixels */
88 unsigned height;
89
90 /** Block size in bits */
91 unsigned bits;
92 };
93
94 enum vk_format_type
95 {
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
101 };
102
103 enum vk_format_colorspace
104 {
105 VK_FORMAT_COLORSPACE_RGB = 0,
106 VK_FORMAT_COLORSPACE_SRGB = 1,
107 VK_FORMAT_COLORSPACE_YUV = 2,
108 VK_FORMAT_COLORSPACE_ZS = 3
109 };
110
111 struct vk_format_channel_description
112 {
113 unsigned type : 5;
114 unsigned normalized : 1;
115 unsigned pure_integer : 1;
116 unsigned scaled : 1;
117 unsigned size : 8;
118 unsigned shift : 16;
119 };
120
121 struct vk_format_description
122 {
123 VkFormat format;
124 const char *name;
125 const char *short_name;
126
127 struct vk_format_block block;
128 enum vk_format_layout layout;
129
130 unsigned nr_channels : 3;
131 unsigned is_array : 1;
132 unsigned is_bitmask : 1;
133 unsigned is_mixed : 1;
134
135 struct vk_format_channel_description channel[4];
136
137 unsigned char swizzle[4];
138
139 enum vk_format_colorspace colorspace;
140 };
141
142 extern const struct vk_format_description vk_format_description_table[];
143
144 const struct vk_format_description *
145 vk_format_description(VkFormat format);
146
147 /**
148 * Return total bits needed for the pixel format per block.
149 */
150 static inline unsigned
151 vk_format_get_blocksizebits(VkFormat format)
152 {
153 const struct vk_format_description *desc = vk_format_description(format);
154
155 assert(desc);
156 if (!desc) {
157 return 0;
158 }
159
160 return desc->block.bits;
161 }
162
163 /**
164 * Return bytes per block (not pixel) for the given format.
165 */
166 static inline unsigned
167 vk_format_get_blocksize(VkFormat format)
168 {
169 unsigned bits = vk_format_get_blocksizebits(format);
170 unsigned bytes = bits / 8;
171
172 assert(bits % 8 == 0);
173 assert(bytes > 0);
174 if (bytes == 0) {
175 bytes = 1;
176 }
177
178 return bytes;
179 }
180
181 static inline unsigned
182 vk_format_get_blockwidth(VkFormat format)
183 {
184 const struct vk_format_description *desc = vk_format_description(format);
185
186 assert(desc);
187 if (!desc) {
188 return 1;
189 }
190
191 return desc->block.width;
192 }
193
194 static inline unsigned
195 vk_format_get_blockheight(VkFormat format)
196 {
197 const struct vk_format_description *desc = vk_format_description(format);
198
199 assert(desc);
200 if (!desc) {
201 return 1;
202 }
203
204 return desc->block.height;
205 }
206
207 static inline unsigned
208 vk_format_get_block_count_width(VkFormat format, unsigned width)
209 {
210 unsigned blockwidth = vk_format_get_blockwidth(format);
211 return (width + blockwidth - 1) / blockwidth;
212 }
213
214 static inline unsigned
215 vk_format_get_block_count_height(VkFormat format, unsigned height)
216 {
217 unsigned blockheight = vk_format_get_blockheight(format);
218 return (height + blockheight - 1) / blockheight;
219 }
220
221 static inline unsigned
222 vk_format_get_block_count(VkFormat format, unsigned width, unsigned height)
223 {
224 return vk_format_get_block_count_width(format, width) *
225 vk_format_get_block_count_height(format, height);
226 }
227
228 /**
229 * Return the index of the first non-void channel
230 * -1 if no non-void channels
231 */
232 static inline int
233 vk_format_get_first_non_void_channel(VkFormat format)
234 {
235 const struct vk_format_description *desc = vk_format_description(format);
236 int i;
237
238 for (i = 0; i < 4; i++)
239 if (desc->channel[i].type != VK_FORMAT_TYPE_VOID)
240 break;
241
242 if (i == 4)
243 return -1;
244
245 return i;
246 }
247
248 enum vk_swizzle
249 {
250 VK_SWIZZLE_X,
251 VK_SWIZZLE_Y,
252 VK_SWIZZLE_Z,
253 VK_SWIZZLE_W,
254 VK_SWIZZLE_0,
255 VK_SWIZZLE_1,
256 VK_SWIZZLE_NONE,
257 VK_SWIZZLE_MAX, /**< Number of enums counter (must be last) */
258 };
259
260 static inline VkImageAspectFlags
261 vk_format_aspects(VkFormat format)
262 {
263 switch (format) {
264 case VK_FORMAT_UNDEFINED:
265 return 0;
266
267 case VK_FORMAT_S8_UINT:
268 return VK_IMAGE_ASPECT_STENCIL_BIT;
269
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;
274
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;
279
280 default:
281 return VK_IMAGE_ASPECT_COLOR_BIT;
282 }
283 }
284
285 static inline enum vk_swizzle
286 tu_swizzle_conv(VkComponentSwizzle component,
287 const unsigned char chan[4],
288 VkComponentSwizzle vk_swiz)
289 {
290 int x;
291
292 if (vk_swiz == VK_COMPONENT_SWIZZLE_IDENTITY)
293 vk_swiz = component;
294 switch (vk_swiz) {
295 case VK_COMPONENT_SWIZZLE_ZERO:
296 return VK_SWIZZLE_0;
297 case VK_COMPONENT_SWIZZLE_ONE:
298 return VK_SWIZZLE_1;
299 case VK_COMPONENT_SWIZZLE_R:
300 for (x = 0; x < 4; x++)
301 if (chan[x] == 0)
302 return x;
303 return VK_SWIZZLE_0;
304 case VK_COMPONENT_SWIZZLE_G:
305 for (x = 0; x < 4; x++)
306 if (chan[x] == 1)
307 return x;
308 return VK_SWIZZLE_0;
309 case VK_COMPONENT_SWIZZLE_B:
310 for (x = 0; x < 4; x++)
311 if (chan[x] == 2)
312 return x;
313 return VK_SWIZZLE_0;
314 case VK_COMPONENT_SWIZZLE_A:
315 for (x = 0; x < 4; x++)
316 if (chan[x] == 3)
317 return x;
318 return VK_SWIZZLE_1;
319 default:
320 unreachable("Illegal swizzle");
321 }
322 }
323
324 static inline void
325 vk_format_compose_swizzles(const VkComponentMapping *mapping,
326 const unsigned char swz[4],
327 enum vk_swizzle dst[4])
328 {
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);
333 }
334
335 static inline bool
336 vk_format_is_compressed(VkFormat format)
337 {
338 const struct vk_format_description *desc = vk_format_description(format);
339
340 assert(desc);
341 if (!desc) {
342 return false;
343 }
344
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 */
352 return true;
353 default:
354 return false;
355 }
356 }
357
358 static inline bool
359 vk_format_has_depth(const struct vk_format_description *desc)
360 {
361 return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
362 desc->swizzle[0] != VK_SWIZZLE_NONE;
363 }
364
365 static inline bool
366 vk_format_has_stencil(const struct vk_format_description *desc)
367 {
368 return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
369 desc->swizzle[1] != VK_SWIZZLE_NONE;
370 }
371
372 static inline bool
373 vk_format_is_depth_or_stencil(VkFormat format)
374 {
375 const struct vk_format_description *desc = vk_format_description(format);
376
377 assert(desc);
378 if (!desc) {
379 return false;
380 }
381
382 return vk_format_has_depth(desc) || vk_format_has_stencil(desc);
383 }
384
385 static inline bool
386 vk_format_is_depth(VkFormat format)
387 {
388 const struct vk_format_description *desc = vk_format_description(format);
389
390 assert(desc);
391 if (!desc) {
392 return false;
393 }
394
395 return vk_format_has_depth(desc);
396 }
397
398 static inline bool
399 vk_format_is_stencil(VkFormat format)
400 {
401 const struct vk_format_description *desc = vk_format_description(format);
402
403 assert(desc);
404 if (!desc) {
405 return false;
406 }
407
408 return vk_format_has_stencil(desc);
409 }
410
411 static inline bool
412 vk_format_is_color(VkFormat format)
413 {
414 return !vk_format_is_depth_or_stencil(format);
415 }
416
417 static inline bool
418 vk_format_has_alpha(VkFormat format)
419 {
420 const struct vk_format_description *desc = vk_format_description(format);
421
422 return (desc->colorspace == VK_FORMAT_COLORSPACE_RGB ||
423 desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) &&
424 desc->swizzle[3] != VK_SWIZZLE_1;
425 }
426
427 static inline VkFormat
428 vk_format_depth_only(VkFormat format)
429 {
430 switch (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;
437 default:
438 return format;
439 }
440 }
441
442 static inline bool
443 vk_format_is_int(VkFormat format)
444 {
445 const struct vk_format_description *desc = vk_format_description(format);
446 int channel = vk_format_get_first_non_void_channel(format);
447
448 return channel >= 0 && desc->channel[channel].pure_integer;
449 }
450
451 static inline bool
452 vk_format_is_srgb(VkFormat format)
453 {
454 const struct vk_format_description *desc = vk_format_description(format);
455 return desc->colorspace == VK_FORMAT_COLORSPACE_SRGB;
456 }
457
458 static inline VkFormat
459 vk_format_no_srgb(VkFormat format)
460 {
461 switch (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;
492 default:
493 assert(!vk_format_is_srgb(format));
494 return format;
495 }
496 }
497
498 static inline VkFormat
499 vk_format_stencil_only(VkFormat format)
500 {
501 return VK_FORMAT_S8_UINT;
502 }
503
504 static inline unsigned
505 vk_format_get_component_bits(VkFormat format,
506 enum vk_format_colorspace colorspace,
507 unsigned component)
508 {
509 const struct vk_format_description *desc = vk_format_description(format);
510 enum vk_format_colorspace desc_colorspace;
511
512 assert(format);
513 if (!format) {
514 return 0;
515 }
516
517 assert(component < 4);
518
519 /* Treat RGB and SRGB as equivalent. */
520 if (colorspace == VK_FORMAT_COLORSPACE_SRGB) {
521 colorspace = VK_FORMAT_COLORSPACE_RGB;
522 }
523 if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
524 desc_colorspace = VK_FORMAT_COLORSPACE_RGB;
525 } else {
526 desc_colorspace = desc->colorspace;
527 }
528
529 if (desc_colorspace != colorspace) {
530 return 0;
531 }
532
533 switch (desc->swizzle[component]) {
534 case VK_SWIZZLE_X:
535 return desc->channel[0].size;
536 case VK_SWIZZLE_Y:
537 return desc->channel[1].size;
538 case VK_SWIZZLE_Z:
539 return desc->channel[2].size;
540 case VK_SWIZZLE_W:
541 return desc->channel[3].size;
542 default:
543 return 0;
544 }
545 }
546
547 static inline VkFormat
548 vk_to_non_srgb_format(VkFormat format)
549 {
550 switch (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;
565 default:
566 return format;
567 }
568 }
569
570 static inline unsigned
571 vk_format_get_nr_components(VkFormat format)
572 {
573 const struct vk_format_description *desc = vk_format_description(format);
574 return desc->nr_channels;
575 }
576
577 #endif /* VK_FORMAT_H */