• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <vulkan/vulkan.h>
32 #include <util/macros.h>
33 
34 enum vk_format_layout {
35 	/**
36 	 * Formats with vk_format_block::width == vk_format_block::height == 1
37 	 * that can be described as an ordinary data structure.
38 	 */
39 	VK_FORMAT_LAYOUT_PLAIN = 0,
40 
41 	/**
42 	 * Formats with sub-sampled channels.
43 	 *
44 	 * This is for formats like YVYU where there is less than one sample per
45 	 * pixel.
46 	 */
47 	VK_FORMAT_LAYOUT_SUBSAMPLED = 3,
48 
49 	/**
50 	 * S3 Texture Compression formats.
51 	 */
52 	VK_FORMAT_LAYOUT_S3TC = 4,
53 
54 	/**
55 	 * Red-Green Texture Compression formats.
56 	 */
57 	VK_FORMAT_LAYOUT_RGTC = 5,
58 
59 	/**
60 	 * Ericsson Texture Compression
61 	 */
62 	VK_FORMAT_LAYOUT_ETC = 6,
63 
64 	/**
65 	 * BC6/7 Texture Compression
66 	 */
67 	VK_FORMAT_LAYOUT_BPTC = 7,
68 
69 	/**
70 	 * ASTC
71 	 */
72 	VK_FORMAT_LAYOUT_ASTC = 8,
73 
74 	/**
75 	 * Everything else that doesn't fit in any of the above layouts.
76 	 */
77 	VK_FORMAT_LAYOUT_OTHER = 9
78 };
79 
80 struct vk_format_block
81 {
82 	/** Block width in pixels */
83 	unsigned width;
84 
85 	/** Block height in pixels */
86 	unsigned height;
87 
88 	/** Block size in bits */
89 	unsigned bits;
90 };
91 
92 enum vk_format_type {
93 	VK_FORMAT_TYPE_VOID = 0,
94 	VK_FORMAT_TYPE_UNSIGNED = 1,
95 	VK_FORMAT_TYPE_SIGNED = 2,
96 	VK_FORMAT_TYPE_FIXED = 3,
97 	VK_FORMAT_TYPE_FLOAT = 4
98 };
99 
100 
101 enum vk_format_colorspace {
102 	VK_FORMAT_COLORSPACE_RGB = 0,
103 	VK_FORMAT_COLORSPACE_SRGB = 1,
104 	VK_FORMAT_COLORSPACE_YUV = 2,
105 	VK_FORMAT_COLORSPACE_ZS = 3
106 };
107 
108 struct vk_format_channel_description {
109 	unsigned type:5;
110 	unsigned normalized:1;
111 	unsigned pure_integer:1;
112 	unsigned scaled:1;
113 	unsigned size:8;
114 	unsigned shift:16;
115 };
116 
117 struct vk_format_description
118 {
119 	VkFormat format;
120 	const char *name;
121 	const char *short_name;
122 
123 	struct vk_format_block block;
124 	enum vk_format_layout layout;
125 
126 	unsigned nr_channels:3;
127 	unsigned is_array:1;
128 	unsigned is_bitmask:1;
129 	unsigned is_mixed:1;
130 
131 	struct vk_format_channel_description channel[4];
132 
133 	unsigned char swizzle[4];
134 
135 	enum vk_format_colorspace colorspace;
136 };
137 
138 extern const struct vk_format_description vk_format_description_table[];
139 
140 const struct vk_format_description *vk_format_description(VkFormat format);
141 
142 /**
143  * Return total bits needed for the pixel format per block.
144  */
145 static inline unsigned
vk_format_get_blocksizebits(VkFormat format)146 vk_format_get_blocksizebits(VkFormat format)
147 {
148 	const struct vk_format_description *desc = vk_format_description(format);
149 
150 	assert(desc);
151 	if (!desc) {
152 		return 0;
153 	}
154 
155 	return desc->block.bits;
156 }
157 
158 /**
159  * Return bytes per block (not pixel) for the given format.
160  */
161 static inline unsigned
vk_format_get_blocksize(VkFormat format)162 vk_format_get_blocksize(VkFormat format)
163 {
164 	unsigned bits = vk_format_get_blocksizebits(format);
165 	unsigned bytes = bits / 8;
166 
167 	assert(bits % 8 == 0);
168 	assert(bytes > 0);
169 	if (bytes == 0) {
170 		bytes = 1;
171 	}
172 
173 	return bytes;
174 }
175 
176 static inline unsigned
vk_format_get_blockwidth(VkFormat format)177 vk_format_get_blockwidth(VkFormat format)
178 {
179 	const struct vk_format_description *desc = vk_format_description(format);
180 
181 	assert(desc);
182 	if (!desc) {
183 		return 1;
184 	}
185 
186 	return desc->block.width;
187 }
188 
189 static inline unsigned
vk_format_get_blockheight(VkFormat format)190 vk_format_get_blockheight(VkFormat format)
191 {
192 	const struct vk_format_description *desc = vk_format_description(format);
193 
194 	assert(desc);
195 	if (!desc) {
196 		return 1;
197 	}
198 
199 	return desc->block.height;
200 }
201 
202 /**
203  * Return the index of the first non-void channel
204  * -1 if no non-void channels
205  */
206 static inline int
vk_format_get_first_non_void_channel(VkFormat format)207 vk_format_get_first_non_void_channel(VkFormat format)
208 {
209 	const struct vk_format_description *desc = vk_format_description(format);
210 	int i;
211 
212 	for (i = 0; i < 4; i++)
213 		if (desc->channel[i].type != VK_FORMAT_TYPE_VOID)
214 			break;
215 
216 	if (i == 4)
217 		return -1;
218 
219 	return i;
220 }
221 
222 enum vk_swizzle {
223 	VK_SWIZZLE_X,
224 	VK_SWIZZLE_Y,
225 	VK_SWIZZLE_Z,
226 	VK_SWIZZLE_W,
227 	VK_SWIZZLE_0,
228 	VK_SWIZZLE_1,
229 	VK_SWIZZLE_NONE,
230 	VK_SWIZZLE_MAX, /**< Number of enums counter (must be last) */
231 };
232 
233 static inline VkImageAspectFlags
vk_format_aspects(VkFormat format)234 vk_format_aspects(VkFormat format)
235 {
236 	switch (format) {
237 	case VK_FORMAT_UNDEFINED:
238 		return 0;
239 
240 	case VK_FORMAT_S8_UINT:
241 		return VK_IMAGE_ASPECT_STENCIL_BIT;
242 
243 	case VK_FORMAT_D16_UNORM_S8_UINT:
244 	case VK_FORMAT_D24_UNORM_S8_UINT:
245 	case VK_FORMAT_D32_SFLOAT_S8_UINT:
246 		return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
247 
248 	case VK_FORMAT_D16_UNORM:
249 	case VK_FORMAT_X8_D24_UNORM_PACK32:
250 	case VK_FORMAT_D32_SFLOAT:
251 		return VK_IMAGE_ASPECT_DEPTH_BIT;
252 
253 	default:
254 		return VK_IMAGE_ASPECT_COLOR_BIT;
255 	}
256 }
257 
258 static inline enum vk_swizzle
radv_swizzle_conv(VkComponentSwizzle component,const unsigned char chan[4],VkComponentSwizzle vk_swiz)259 radv_swizzle_conv(VkComponentSwizzle component, const unsigned char chan[4], VkComponentSwizzle vk_swiz)
260 {
261 	int x;
262 
263 	if (vk_swiz == VK_COMPONENT_SWIZZLE_IDENTITY)
264 		vk_swiz = component;
265 	switch (vk_swiz) {
266 	case VK_COMPONENT_SWIZZLE_ZERO:
267 		return VK_SWIZZLE_0;
268 	case VK_COMPONENT_SWIZZLE_ONE:
269 		return VK_SWIZZLE_1;
270 	case VK_COMPONENT_SWIZZLE_R:
271 		for (x = 0; x < 4; x++)
272 			if (chan[x] == 0)
273 				return x;
274 		return VK_SWIZZLE_0;
275 	case VK_COMPONENT_SWIZZLE_G:
276 		for (x = 0; x < 4; x++)
277 			if (chan[x] == 1)
278 				return x;
279 		return VK_SWIZZLE_0;
280 	case VK_COMPONENT_SWIZZLE_B:
281 		for (x = 0; x < 4; x++)
282 			if (chan[x] == 2)
283 				return x;
284 		return VK_SWIZZLE_0;
285 	case VK_COMPONENT_SWIZZLE_A:
286 		for (x = 0; x < 4; x++)
287 			if (chan[x] == 3)
288 				return x;
289 		return VK_SWIZZLE_1;
290 	default:
291 		unreachable("Illegal swizzle");
292 	}
293 }
294 
vk_format_compose_swizzles(const VkComponentMapping * mapping,const unsigned char swz[4],enum vk_swizzle dst[4])295 static inline void vk_format_compose_swizzles(const VkComponentMapping *mapping,
296 					      const unsigned char swz[4],
297 					      enum vk_swizzle dst[4])
298 {
299 	dst[0] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_R, swz, mapping->r);
300 	dst[1] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_G, swz, mapping->g);
301 	dst[2] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_B, swz, mapping->b);
302 	dst[3] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_A, swz, mapping->a);
303 }
304 
305 static inline bool
vk_format_is_compressed(VkFormat format)306 vk_format_is_compressed(VkFormat format)
307 {
308 	const struct vk_format_description *desc = vk_format_description(format);
309 
310 	assert(desc);
311 	if (!desc) {
312 		return false;
313 	}
314 
315 	switch (desc->layout) {
316 	case VK_FORMAT_LAYOUT_S3TC:
317 	case VK_FORMAT_LAYOUT_RGTC:
318 	case VK_FORMAT_LAYOUT_ETC:
319 	case VK_FORMAT_LAYOUT_BPTC:
320 	case VK_FORMAT_LAYOUT_ASTC:
321 		/* XXX add other formats in the future */
322 		return true;
323 	default:
324 		return false;
325 	}
326 }
327 
328 static inline bool
vk_format_has_depth(const struct vk_format_description * desc)329 vk_format_has_depth(const struct vk_format_description *desc)
330 {
331 	return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
332 		desc->swizzle[0] != VK_SWIZZLE_NONE;
333 }
334 
335 static inline bool
vk_format_has_stencil(const struct vk_format_description * desc)336 vk_format_has_stencil(const struct vk_format_description *desc)
337 {
338 	return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
339 		desc->swizzle[1] != VK_SWIZZLE_NONE;
340 }
341 
342 static inline bool
vk_format_is_depth_or_stencil(VkFormat format)343 vk_format_is_depth_or_stencil(VkFormat format)
344 {
345 	const struct vk_format_description *desc = vk_format_description(format);
346 
347 	assert(desc);
348 	if (!desc) {
349 		return false;
350 	}
351 
352 	return vk_format_has_depth(desc) ||
353 		vk_format_has_stencil(desc);
354 }
355 
356 static inline bool
vk_format_is_depth(VkFormat format)357 vk_format_is_depth(VkFormat format)
358 {
359 	const struct vk_format_description *desc = vk_format_description(format);
360 
361 	assert(desc);
362 	if (!desc) {
363 		return false;
364 	}
365 
366 	return vk_format_has_depth(desc);
367 }
368 
369 static inline bool
vk_format_is_stencil(VkFormat format)370 vk_format_is_stencil(VkFormat format)
371 {
372 	const struct vk_format_description *desc = vk_format_description(format);
373 
374 	assert(desc);
375 	if (!desc) {
376 		return false;
377 	}
378 
379 	return vk_format_has_stencil(desc);
380 }
381 
382 static inline bool
vk_format_is_color(VkFormat format)383 vk_format_is_color(VkFormat format)
384 {
385 	return !vk_format_is_depth_or_stencil(format);
386 }
387 
388 static inline VkFormat
vk_format_depth_only(VkFormat format)389 vk_format_depth_only(VkFormat format)
390 {
391 	switch (format) {
392 	case VK_FORMAT_D16_UNORM_S8_UINT:
393 		return VK_FORMAT_D16_UNORM;
394 	case VK_FORMAT_D24_UNORM_S8_UINT:
395 		return VK_FORMAT_X8_D24_UNORM_PACK32;
396 	case VK_FORMAT_D32_SFLOAT_S8_UINT:
397 		return VK_FORMAT_D32_SFLOAT;
398 	default:
399 		return format;
400 	}
401 }
402 
403 static inline bool
vk_format_is_int(VkFormat format)404 vk_format_is_int(VkFormat format)
405 {
406 	const struct vk_format_description *desc = vk_format_description(format);
407 	int channel =  vk_format_get_first_non_void_channel(format);
408 
409 	return channel >= 0 && desc->channel[channel].pure_integer;
410 }
411 
412 static inline bool
vk_format_is_srgb(VkFormat format)413 vk_format_is_srgb(VkFormat format)
414 {
415 	const struct vk_format_description *desc = vk_format_description(format);
416 	return desc->colorspace == VK_FORMAT_COLORSPACE_SRGB;
417 }
418 
419 static inline VkFormat
vk_format_stencil_only(VkFormat format)420 vk_format_stencil_only(VkFormat format)
421 {
422 	return VK_FORMAT_S8_UINT;
423 }
424 
425 static inline unsigned
vk_format_get_component_bits(VkFormat format,enum vk_format_colorspace colorspace,unsigned component)426 vk_format_get_component_bits(VkFormat format,
427 			     enum vk_format_colorspace colorspace,
428 			     unsigned component)
429 {
430 	const struct vk_format_description *desc = vk_format_description(format);
431 	enum vk_format_colorspace desc_colorspace;
432 
433 	assert(format);
434 	if (!format) {
435 		return 0;
436 	}
437 
438 	assert(component < 4);
439 
440 	/* Treat RGB and SRGB as equivalent. */
441 	if (colorspace == VK_FORMAT_COLORSPACE_SRGB) {
442 		colorspace = VK_FORMAT_COLORSPACE_RGB;
443 	}
444 	if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
445 		desc_colorspace = VK_FORMAT_COLORSPACE_RGB;
446 	} else {
447 		desc_colorspace = desc->colorspace;
448 	}
449 
450 	if (desc_colorspace != colorspace) {
451 		return 0;
452 	}
453 
454 	switch (desc->swizzle[component]) {
455 	case VK_SWIZZLE_X:
456 		return desc->channel[0].size;
457 	case VK_SWIZZLE_Y:
458 		return desc->channel[1].size;
459 	case VK_SWIZZLE_Z:
460 		return desc->channel[2].size;
461 	case VK_SWIZZLE_W:
462 		return desc->channel[3].size;
463 	default:
464 		return 0;
465 	}
466 }
467 
468 static inline VkFormat
vk_to_non_srgb_format(VkFormat format)469 vk_to_non_srgb_format(VkFormat format)
470 {
471 	switch(format) {
472 	case VK_FORMAT_R8_SRGB :
473 		return VK_FORMAT_R8_UNORM;
474 	case VK_FORMAT_R8G8_SRGB:
475 		return VK_FORMAT_R8G8_UNORM;
476 	case VK_FORMAT_R8G8B8_SRGB:
477 		return VK_FORMAT_R8G8B8_UNORM;
478 	case VK_FORMAT_B8G8R8_SRGB:
479 		return VK_FORMAT_B8G8R8_UNORM;
480 	case VK_FORMAT_R8G8B8A8_SRGB :
481 		return VK_FORMAT_R8G8B8A8_UNORM;
482 	case VK_FORMAT_B8G8R8A8_SRGB:
483 		return VK_FORMAT_B8G8R8A8_UNORM;
484 	case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
485 		return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
486 	default:
487 		return format;
488 	}
489 }
490 
491 #endif /* VK_FORMAT_H */
492