1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Imagination Technologies Ltd.
7  * Copyright (c) 2015 Google Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Utilities for images.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vkImageUtil.hpp"
27 #include "vkRefUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vkTypeUtil.hpp"
30 #include "vkCmdUtil.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "deMath.h"
33 
34 namespace vk
35 {
36 
isFloatFormat(VkFormat format)37 bool isFloatFormat (VkFormat format)
38 {
39 	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
40 }
41 
isUnormFormat(VkFormat format)42 bool isUnormFormat (VkFormat format)
43 {
44 	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
45 }
46 
isSnormFormat(VkFormat format)47 bool isSnormFormat (VkFormat format)
48 {
49 	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
50 }
51 
isIntFormat(VkFormat format)52 bool isIntFormat (VkFormat format)
53 {
54 	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
55 }
56 
isUintFormat(VkFormat format)57 bool isUintFormat (VkFormat format)
58 {
59 	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
60 }
61 
isDepthStencilFormat(VkFormat format)62 bool isDepthStencilFormat (VkFormat format)
63 {
64 	if (isCompressedFormat(format))
65 		return false;
66 
67 	if (isYCbCrFormat(format))
68 		return false;
69 
70 	const tcu::TextureFormat tcuFormat = mapVkFormat(format);
71 	return tcuFormat.order == tcu::TextureFormat::D || tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS;
72 }
73 
isSrgbFormat(VkFormat format)74 bool isSrgbFormat (VkFormat format)
75 {
76 	switch (mapVkFormat(format).order)
77 	{
78 		case tcu::TextureFormat::sR:
79 		case tcu::TextureFormat::sRG:
80 		case tcu::TextureFormat::sRGB:
81 		case tcu::TextureFormat::sRGBA:
82 		case tcu::TextureFormat::sBGR:
83 		case tcu::TextureFormat::sBGRA:
84 			return true;
85 
86 		default:
87 			return false;
88 	}
89 }
90 
isUfloatFormat(VkFormat format)91 bool isUfloatFormat (VkFormat format)
92 {
93 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
94 
95 	switch (format)
96 	{
97 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
98 		case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
99 		case VK_FORMAT_BC6H_UFLOAT_BLOCK:
100 			return true;
101 
102 		default:
103 			return false;
104 	}
105 }
106 
isSfloatFormat(VkFormat format)107 bool isSfloatFormat (VkFormat format)
108 {
109 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
110 
111 	switch (format)
112 	{
113 		case VK_FORMAT_R16_SFLOAT:
114 		case VK_FORMAT_R16G16_SFLOAT:
115 		case VK_FORMAT_R16G16B16_SFLOAT:
116 		case VK_FORMAT_R16G16B16A16_SFLOAT:
117 		case VK_FORMAT_R32_SFLOAT:
118 		case VK_FORMAT_R32G32_SFLOAT:
119 		case VK_FORMAT_R32G32B32_SFLOAT:
120 		case VK_FORMAT_R32G32B32A32_SFLOAT:
121 		case VK_FORMAT_R64_SFLOAT:
122 		case VK_FORMAT_R64G64_SFLOAT:
123 		case VK_FORMAT_R64G64B64_SFLOAT:
124 		case VK_FORMAT_R64G64B64A64_SFLOAT:
125 		case VK_FORMAT_D32_SFLOAT:
126 		case VK_FORMAT_BC6H_SFLOAT_BLOCK:
127 			return true;
128 
129 		default:
130 			return false;
131 	}
132 }
133 
isCompressedFormat(VkFormat format)134 bool isCompressedFormat (VkFormat format)
135 {
136 	// update this mapping if VkFormat changes
137 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
138 
139 	switch (format)
140 	{
141 		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
142 		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
143 		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
144 		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
145 		case VK_FORMAT_BC2_UNORM_BLOCK:
146 		case VK_FORMAT_BC2_SRGB_BLOCK:
147 		case VK_FORMAT_BC3_UNORM_BLOCK:
148 		case VK_FORMAT_BC3_SRGB_BLOCK:
149 		case VK_FORMAT_BC4_UNORM_BLOCK:
150 		case VK_FORMAT_BC4_SNORM_BLOCK:
151 		case VK_FORMAT_BC5_UNORM_BLOCK:
152 		case VK_FORMAT_BC5_SNORM_BLOCK:
153 		case VK_FORMAT_BC6H_UFLOAT_BLOCK:
154 		case VK_FORMAT_BC6H_SFLOAT_BLOCK:
155 		case VK_FORMAT_BC7_UNORM_BLOCK:
156 		case VK_FORMAT_BC7_SRGB_BLOCK:
157 		case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
158 		case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
159 		case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
160 		case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
161 		case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
162 		case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
163 		case VK_FORMAT_EAC_R11_UNORM_BLOCK:
164 		case VK_FORMAT_EAC_R11_SNORM_BLOCK:
165 		case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
166 		case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
167 		case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
168 		case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
169 		case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
170 		case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
171 		case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
172 		case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
173 		case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
174 		case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
175 		case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
176 		case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
177 		case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
178 		case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
179 		case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
180 		case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
181 		case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
182 		case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
183 		case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
184 		case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
185 		case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
186 		case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
187 		case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
188 		case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
189 		case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
190 		case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
191 		case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
192 		case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
193 		case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
194 		case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
195 			return true;
196 
197 		default:
198 			return false;
199 	}
200 }
201 
isYCbCrFormat(VkFormat format)202 bool isYCbCrFormat (VkFormat format)
203 {
204 	switch (format)
205 	{
206 		case VK_FORMAT_G8B8G8R8_422_UNORM:
207 		case VK_FORMAT_B8G8R8G8_422_UNORM:
208 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
209 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
210 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
211 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
212 		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
213 		case VK_FORMAT_R10X6_UNORM_PACK16:
214 		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
215 		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
216 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
217 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
218 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
219 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
220 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
221 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
222 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
223 		case VK_FORMAT_R12X4_UNORM_PACK16:
224 		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
225 		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
226 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
227 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
228 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
229 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
230 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
231 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
232 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
233 		case VK_FORMAT_G16B16G16R16_422_UNORM:
234 		case VK_FORMAT_B16G16R16G16_422_UNORM:
235 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
236 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
237 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
238 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
239 		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
240 		case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
241 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
242 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
243 		case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
244 			return true;
245 
246 		default:
247 			return false;
248 	}
249 }
250 
isYCbCrExtensionFormat(VkFormat format)251 bool isYCbCrExtensionFormat (VkFormat format)
252 {
253 	switch (format)
254 	{
255 	case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
256 	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
257 	case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
258 	case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
259 		return true;
260 
261 	default:
262 		return false;
263 	}
264 }
265 
isYCbCr420Format(VkFormat format)266 bool isYCbCr420Format (VkFormat format)
267 {
268 	switch (format)
269 	{
270 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
271 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
272 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
273 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
274 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
275 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
276 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
277 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
278 			return true;
279 
280 		default:
281 			return false;
282 	}
283 }
284 
isYCbCr422Format(VkFormat format)285 bool isYCbCr422Format (VkFormat format)
286 {
287 	switch (format)
288 	{
289 		case VK_FORMAT_G8B8G8R8_422_UNORM:
290 		case VK_FORMAT_B8G8R8G8_422_UNORM:
291 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
292 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
293 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
294 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
295 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
296 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
297 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
298 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
299 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
300 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
301 		case VK_FORMAT_G16B16G16R16_422_UNORM:
302 		case VK_FORMAT_B16G16R16G16_422_UNORM:
303 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
304 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
305 			return true;
306 
307 		default:
308 			return false;
309 	}
310 }
311 
getYCbCrPlanarFormatDescription(VkFormat format)312 const PlanarFormatDescription& getYCbCrPlanarFormatDescription (VkFormat format)
313 {
314 	using tcu::TextureFormat;
315 
316 	const deUint32	chanR			= PlanarFormatDescription::CHANNEL_R;
317 	const deUint32	chanG			= PlanarFormatDescription::CHANNEL_G;
318 	const deUint32	chanB			= PlanarFormatDescription::CHANNEL_B;
319 	const deUint32	chanA			= PlanarFormatDescription::CHANNEL_A;
320 
321 	const deUint8	unorm			= (deUint8)tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
322 
323 	if (format >= VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT && format <= VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT)
324 	{
325 		static const PlanarFormatDescription s_formatInfo[] =
326 		{
327 			// VK_FORMAT_G8_B8R8_2PLANE_444_UNORM
328 			{
329 				2, // planes
330 				chanR|chanG|chanB,
331 				1,1,
332 				{
333 				//		Size	WDiv	HDiv	planeCompatibleFormat
334 					{	1,		1,		1,		VK_FORMAT_R8_UNORM },
335 					{	2,		1,		1,		VK_FORMAT_R8G8_UNORM },
336 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
337 				},
338 				{
339 				//		Plane	Type	Offs	Size	Stride
340 					{	1,		unorm,	8,		8,		2 },	// R
341 					{	0,		unorm,	0,		8,		1 },	// G
342 					{	1,		unorm,	0,		8,		2 },	// B
343 					{ 0, 0, 0, 0, 0 }
344 				}
345 			},
346 			// VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT
347 			{
348 				2, // planes
349 				chanR|chanG|chanB,
350 				1,1,
351 				{
352 				//		Size	WDiv	HDiv	planeCompatibleFormat
353 					{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
354 					{	4,		1,		1,		VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
355 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
356 				},
357 				{
358 				//		Plane	Type	Offs	Size	Stride
359 					{	1,		unorm,	22,		10,		4 },	// R
360 					{	0,		unorm,	6,		10,		2 },	// G
361 					{	1,		unorm,	6,		10,		4 },	// B
362 					{ 0, 0, 0, 0, 0 }
363 				}
364 			},
365 			// VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT
366 			{
367 				2, // planes
368 				chanR|chanG|chanB,
369 				1,1,
370 				{
371 				//		Size	WDiv	HDiv	planeCompatibleFormat
372 					{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
373 					{	4,		1,		1,		VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
374 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
375 				},
376 				{
377 				//		Plane	Type	Offs	Size	Stride
378 					{	1,		unorm,	20,		12,		4 },	// R
379 					{	0,		unorm,	4,		12,		2 },	// G
380 					{	1,		unorm,	4,		12,		4 },	// B
381 					{ 0, 0, 0, 0, 0 }
382 				}
383 			},
384 			// VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT
385 			{
386 				2, // planes
387 				chanR|chanG|chanB,
388 				1,1,
389 				{
390 				//		Size	WDiv	HDiv	planeCompatibleFormat
391 					{	2,		1,		1,		VK_FORMAT_R16_UNORM },
392 					{	4,		1,		1,		VK_FORMAT_R16G16_UNORM },
393 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
394 				},
395 				{
396 				//		Plane	Type	Offs	Size	Stride
397 					{	1,		unorm,	16,		16,		4 },	// R
398 					{	0,		unorm,	0,		16,		2 },	// G
399 					{	1,		unorm,	0,		16,		4 },	// B
400 					{ 0, 0, 0, 0, 0 }
401 				}
402 			},
403 		};
404 
405 		const size_t	offset	= (size_t)VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT;
406 
407 		DE_ASSERT(de::inBounds<size_t>((size_t)format, offset, offset+(size_t)DE_LENGTH_OF_ARRAY(s_formatInfo)));
408 
409 		return s_formatInfo[(size_t)format-offset];
410 	}
411 
412 	static const PlanarFormatDescription s_formatInfo[] =
413 	{
414 		// VK_FORMAT_G8B8G8R8_422_UNORM
415 		{
416 			1, // planes
417 			chanR|chanG|chanB,
418 			2,1,
419 			{
420 			//		Size	WDiv	HDiv	planeCompatibleFormat
421 				{	4,		1,		1,		VK_FORMAT_G8B8G8R8_422_UNORM	},
422 				{	0,		0,		0,		VK_FORMAT_UNDEFINED	},
423 				{	0,		0,		0,		VK_FORMAT_UNDEFINED	},
424 			},
425 			{
426 			//		Plane	Type	Offs	Size	Stride
427 				{	0,		unorm,	24,		8,		4 },	// R
428 				{	0,		unorm,	0,		8,		2 },	// G
429 				{	0,		unorm,	8,		8,		4 },	// B
430 				{ 0, 0, 0, 0, 0 }
431 			}
432 		},
433 		// VK_FORMAT_B8G8R8G8_422_UNORM
434 		{
435 			1, // planes
436 			chanR|chanG|chanB,
437 			2,1,
438 			{
439 			//		Size	WDiv	HDiv	planeCompatibleFormat
440 				{	4,		1,		1,		VK_FORMAT_B8G8R8G8_422_UNORM },
441 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
442 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
443 			},
444 			{
445 			//		Plane	Type	Offs	Size	Stride
446 				{	0,		unorm,	16,		8,		4 },	// R
447 				{	0,		unorm,	8,		8,		2 },	// G
448 				{	0,		unorm,	0,		8,		4 },	// B
449 				{ 0, 0, 0, 0, 0 }
450 			}
451 		},
452 		// VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM
453 		{
454 			3, // planes
455 			chanR|chanG|chanB,
456 			1,1,
457 			{
458 			//		Size	WDiv	HDiv	planeCompatibleFormat
459 				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
460 				{	1,		2,		2,		VK_FORMAT_R8_UNORM },
461 				{	1,		2,		2,		VK_FORMAT_R8_UNORM },
462 			},
463 			{
464 			//		Plane	Type	Offs	Size	Stride
465 				{	2,		unorm,	0,		8,		1 },	// R
466 				{	0,		unorm,	0,		8,		1 },	// G
467 				{	1,		unorm,	0,		8,		1 },	// B
468 				{ 0, 0, 0, 0, 0 }
469 			}
470 		},
471 		// VK_FORMAT_G8_B8R8_2PLANE_420_UNORM
472 		{
473 			2, // planes
474 			chanR|chanG|chanB,
475 			1,1,
476 			{
477 			//		Size	WDiv	HDiv	planeCompatibleFormat
478 				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
479 				{	2,		2,		2,		VK_FORMAT_R8G8_UNORM },
480 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
481 			},
482 			{
483 			//		Plane	Type	Offs	Size	Stride
484 				{	1,		unorm,	8,		8,		2 },	// R
485 				{	0,		unorm,	0,		8,		1 },	// G
486 				{	1,		unorm,	0,		8,		2 },	// B
487 				{ 0, 0, 0, 0, 0 }
488 			}
489 		},
490 		// VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM
491 		{
492 			3, // planes
493 			chanR|chanG|chanB,
494 			1,1,
495 			{
496 			//		Size	WDiv	HDiv	planeCompatibleFormat
497 				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
498 				{	1,		2,		1,		VK_FORMAT_R8_UNORM },
499 				{	1,		2,		1,		VK_FORMAT_R8_UNORM },
500 			},
501 			{
502 			//		Plane	Type	Offs	Size	Stride
503 				{	2,		unorm,	0,		8,		1 },	// R
504 				{	0,		unorm,	0,		8,		1 },	// G
505 				{	1,		unorm,	0,		8,		1 },	// B
506 				{ 0, 0, 0, 0, 0 }
507 			}
508 		},
509 		// VK_FORMAT_G8_B8R8_2PLANE_422_UNORM
510 		{
511 			2, // planes
512 			chanR|chanG|chanB,
513 			1,1,
514 			{
515 			//		Size	WDiv	HDiv	planeCompatibleFormat
516 				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
517 				{	2,		2,		1,		VK_FORMAT_R8G8_UNORM },
518 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
519 			},
520 			{
521 			//		Plane	Type	Offs	Size	Stride
522 				{	1,		unorm,	8,		8,		2 },	// R
523 				{	0,		unorm,	0,		8,		1 },	// G
524 				{	1,		unorm,	0,		8,		2 },	// B
525 				{ 0, 0, 0, 0, 0 }
526 			}
527 		},
528 		// VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM
529 		{
530 			3, // planes
531 			chanR|chanG|chanB,
532 			1,1,
533 			{
534 			//		Size	WDiv	HDiv	planeCompatibleFormat
535 				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
536 				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
537 				{	1,		1,		1,		VK_FORMAT_R8_UNORM },
538 			},
539 			{
540 			//		Plane	Type	Offs	Size	Stride
541 				{	2,		unorm,	0,		8,		1 },	// R
542 				{	0,		unorm,	0,		8,		1 },	// G
543 				{	1,		unorm,	0,		8,		1 },	// B
544 				{ 0, 0, 0, 0, 0 }
545 			}
546 		},
547 		// VK_FORMAT_R10X6_UNORM_PACK16
548 		{
549 			1, // planes
550 			chanR,
551 			1,1,
552 			{
553 			//		Size	WDiv	HDiv	planeCompatibleFormat
554 				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
555 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
556 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
557 			},
558 			{
559 			//		Plane	Type	Offs	Size	Stride
560 				{	0,		unorm,	6,		10,		2 },	// R
561 				{ 0, 0, 0, 0, 0 },
562 				{ 0, 0, 0, 0, 0 },
563 				{ 0, 0, 0, 0, 0 },
564 			}
565 		},
566 		// VK_FORMAT_R10X6G10X6_UNORM_2PACK16
567 		{
568 			1, // planes
569 			chanR|chanG,
570 			1,1,
571 			{
572 			//		Size	WDiv	HDiv	planeCompatibleFormat
573 				{	4,		1,		1,		VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
574 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
575 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
576 			},
577 			{
578 			//		Plane	Type	Offs	Size	Stride
579 				{	0,		unorm,	6,		10,		4 },	// R
580 				{	0,		unorm,	22,		10,		4 },	// G
581 				{ 0, 0, 0, 0, 0 },
582 				{ 0, 0, 0, 0, 0 },
583 			}
584 		},
585 		// VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16
586 		{
587 			1, // planes
588 			chanR|chanG|chanB|chanA,
589 			1,1,
590 			{
591 			//		Size	WDiv	HDiv	planeCompatibleFormat
592 				{	8,		1,		1,		VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 },
593 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
594 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
595 			},
596 			{
597 			//		Plane	Type	Offs	Size	Stride
598 				{	0,		unorm,	6,		10,		8 },	// R
599 				{	0,		unorm,	22,		10,		8 },	// G
600 				{	0,		unorm,	38,		10,		8 },	// B
601 				{	0,		unorm,	54,		10,		8 },	// A
602 			}
603 		},
604 		// VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16
605 		{
606 			1, // planes
607 			chanR|chanG|chanB,
608 			2,1,
609 			{
610 			//		Size	WDiv	HDiv	planeCompatibleFormat
611 				{	8,		1,		1,		VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 },
612 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
613 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
614 			},
615 			{
616 			//		Plane	Type	Offs	Size	Stride
617 				{	0,		unorm,	54,		10,		8 },	// R
618 				{	0,		unorm,	6,		10,		4 },	// G
619 				{	0,		unorm,	22,		10,		8 },	// B
620 				{ 0, 0, 0, 0, 0 }
621 			}
622 		},
623 		// VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16
624 		{
625 			1, // planes
626 			chanR|chanG|chanB,
627 			2,1,
628 			{
629 			//		Size	WDiv	HDiv	planeCompatibleFormat
630 				{	8,		1,		1,		VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 },
631 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
632 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
633 			},
634 			{
635 			//		Plane	Type	Offs	Size	Stride
636 				{	0,		unorm,	38,		10,		8 },	// R
637 				{	0,		unorm,	22,		10,		4 },	// G
638 				{	0,		unorm,	6,		10,		8 },	// B
639 				{ 0, 0, 0, 0, 0 }
640 			}
641 		},
642 		// VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16
643 		{
644 			3, // planes
645 			chanR|chanG|chanB,
646 			1,1,
647 			{
648 			//		Size	WDiv	HDiv	planeCompatibleFormat
649 				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
650 				{	2,		2,		2,		VK_FORMAT_R10X6_UNORM_PACK16 },
651 				{	2,		2,		2,		VK_FORMAT_R10X6_UNORM_PACK16 },
652 			},
653 			{
654 			//		Plane	Type	Offs	Size	Stride
655 				{	2,		unorm,	6,		10,		2 },	// R
656 				{	0,		unorm,	6,		10,		2 },	// G
657 				{	1,		unorm,	6,		10,		2 },	// B
658 				{ 0, 0, 0, 0, 0 }
659 			}
660 		},
661 		// VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16
662 		{
663 			2, // planes
664 			chanR|chanG|chanB,
665 			1,1,
666 			{
667 			//		Size	WDiv	HDiv	planeCompatibleFormat
668 				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
669 				{	4,		2,		2,		VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
670 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
671 			},
672 			{
673 			//		Plane	Type	Offs	Size	Stride
674 				{	1,		unorm,	22,		10,		4 },	// R
675 				{	0,		unorm,	6,		10,		2 },	// G
676 				{	1,		unorm,	6,		10,		4 },	// B
677 				{ 0, 0, 0, 0, 0 }
678 			}
679 		},
680 		// VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16
681 		{
682 			3, // planes
683 			chanR|chanG|chanB,
684 			1,1,
685 			{
686 			//		Size	WDiv	HDiv	planeCompatibleFormat
687 				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
688 				{	2,		2,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
689 				{	2,		2,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
690 			},
691 			{
692 			//		Plane	Type	Offs	Size	Stride
693 				{	2,		unorm,	6,		10,		2 },	// R
694 				{	0,		unorm,	6,		10,		2 },	// G
695 				{	1,		unorm,	6,		10,		2 },	// B
696 				{ 0, 0, 0, 0, 0 }
697 			}
698 		},
699 		// VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16
700 		{
701 			2, // planes
702 			chanR|chanG|chanB,
703 			1,1,
704 			{
705 			//		Size	WDiv	HDiv	planeCompatibleFormat
706 				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
707 				{	4,		2,		1,		VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
708 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
709 			},
710 			{
711 			//		Plane	Type	Offs	Size	Stride
712 				{	1,		unorm,	22,		10,		4 },	// R
713 				{	0,		unorm,	6,		10,		2 },	// G
714 				{	1,		unorm,	6,		10,		4 },	// B
715 				{ 0, 0, 0, 0, 0 }
716 			}
717 		},
718 		// VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16
719 		{
720 			3, // planes
721 			chanR|chanG|chanB,
722 			1,1,
723 			{
724 			//		Size	WDiv	HDiv	planeCompatibleFormat
725 				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
726 				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
727 				{	2,		1,		1,		VK_FORMAT_R10X6_UNORM_PACK16 },
728 			},
729 			{
730 			//		Plane	Type	Offs	Size	Stride
731 				{	2,		unorm,	6,		10,		2 },	// R
732 				{	0,		unorm,	6,		10,		2 },	// G
733 				{	1,		unorm,	6,		10,		2 },	// B
734 				{ 0, 0, 0, 0, 0 }
735 			}
736 		},
737 		// VK_FORMAT_R12X4_UNORM_PACK16
738 		{
739 			1, // planes
740 			chanR,
741 			1,1,
742 			{
743 			//		Size	WDiv	HDiv	planeCompatibleFormat
744 				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
745 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
746 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
747 			},
748 			{
749 			//		Plane	Type	Offs	Size	Stride
750 				{	0,		unorm,	4,		12,		2 },	// R
751 				{ 0, 0, 0, 0, 0 },
752 				{ 0, 0, 0, 0, 0 },
753 				{ 0, 0, 0, 0, 0 },
754 			}
755 		},
756 		// VK_FORMAT_R12X4G12X4_UNORM_2PACK16
757 		{
758 			1, // planes
759 			chanR|chanG,
760 			1,1,
761 			{
762 			//		Size	WDiv	HDiv	planeCompatibleFormat
763 				{	4,		1,		1,		VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
764 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
765 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
766 			},
767 			{
768 			//		Plane	Type	Offs	Size	Stride
769 				{	0,		unorm,	4,		12,		4 },	// R
770 				{	0,		unorm,	20,		12,		4 },	// G
771 				{ 0, 0, 0, 0, 0 },
772 				{ 0, 0, 0, 0, 0 },
773 			}
774 		},
775 		// VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16
776 		{
777 			1, // planes
778 			chanR|chanG|chanB|chanA,
779 			1,1,
780 			{
781 			//		Size	WDiv	HDiv	planeCompatibleFormat
782 				{	8,		1,		1,		VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 },
783 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
784 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
785 			},
786 			{
787 			//		Plane	Type	Offs	Size	Stride
788 				{	0,		unorm,	4,		12,		8 },	// R
789 				{	0,		unorm,	20,		12,		8 },	// G
790 				{	0,		unorm,	36,		12,		8 },	// B
791 				{	0,		unorm,	52,		12,		8 },	// A
792 			}
793 		},
794 		// VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16
795 		{
796 			1, // planes
797 			chanR|chanG|chanB,
798 			2,1,
799 			{
800 			//		Size	WDiv	HDiv	planeCompatibleFormat
801 				{	8,		1,		1,		VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 },
802 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
803 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
804 			},
805 			{
806 			//		Plane	Type	Offs	Size	Stride
807 				{	0,		unorm,	52,		12,		8 },	// R
808 				{	0,		unorm,	4,		12,		4 },	// G
809 				{	0,		unorm,	20,		12,		8 },	// B
810 				{ 0, 0, 0, 0, 0 }
811 			}
812 		},
813 		// VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16
814 		{
815 			1, // planes
816 			chanR|chanG|chanB,
817 			2,1,
818 			{
819 			//		Size	WDiv	HDiv	planeCompatibleFormat
820 				{	8,		1,		1,		VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 },
821 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
822 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
823 			},
824 			{
825 			//		Plane	Type	Offs	Size	Stride
826 				{	0,		unorm,	36,		12,		8 },	// R
827 				{	0,		unorm,	20,		12,		4 },	// G
828 				{	0,		unorm,	4,		12,		8 },	// B
829 				{ 0, 0, 0, 0, 0 }
830 			}
831 		},
832 		// VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16
833 		{
834 			3, // planes
835 			chanR|chanG|chanB,
836 			1,1,
837 			{
838 			//		Size	WDiv	HDiv	planeCompatibleFormat
839 				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
840 				{	2,		2,		2,		VK_FORMAT_R12X4_UNORM_PACK16 },
841 				{	2,		2,		2,		VK_FORMAT_R12X4_UNORM_PACK16 },
842 			},
843 			{
844 			//		Plane	Type	Offs	Size	Stride
845 				{	2,		unorm,	4,		12,		2 },	// R
846 				{	0,		unorm,	4,		12,		2 },	// G
847 				{	1,		unorm,	4,		12,		2 },	// B
848 				{ 0, 0, 0, 0, 0 }
849 			}
850 		},
851 		// VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16
852 		{
853 			2, // planes
854 			chanR|chanG|chanB,
855 			1,1,
856 			{
857 			//		Size	WDiv	HDiv	planeCompatibleFormat
858 				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
859 				{	4,		2,		2,		VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
860 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
861 			},
862 			{
863 			//		Plane	Type	Offs	Size	Stride
864 				{	1,		unorm,	20,		12,		4 },	// R
865 				{	0,		unorm,	4,		12,		2 },	// G
866 				{	1,		unorm,	4,		12,		4 },	// B
867 				{ 0, 0, 0, 0, 0 }
868 			}
869 		},
870 		// VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16
871 		{
872 			3, // planes
873 			chanR|chanG|chanB,
874 			1,1,
875 			{
876 			//		Size	WDiv	HDiv	planeCompatibleFormat
877 				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
878 				{	2,		2,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
879 				{	2,		2,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
880 			},
881 			{
882 			//		Plane	Type	Offs	Size	Stride
883 				{	2,		unorm,	4,		12,		2 },	// R
884 				{	0,		unorm,	4,		12,		2 },	// G
885 				{	1,		unorm,	4,		12,		2 },	// B
886 				{ 0, 0, 0, 0, 0 }
887 			}
888 		},
889 		// VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16
890 		{
891 			2, // planes
892 			chanR|chanG|chanB,
893 			1,1,
894 			{
895 			//		Size	WDiv	HDiv	planeCompatibleFormat
896 				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
897 				{	4,		2,		1,		VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
898 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
899 			},
900 			{
901 			//		Plane	Type	Offs	Size	Stride
902 				{	1,		unorm,	20,		12,		4 },	// R
903 				{	0,		unorm,	4,		12,		2 },	// G
904 				{	1,		unorm,	4,		12,		4 },	// B
905 				{ 0, 0, 0, 0, 0 }
906 			}
907 		},
908 		// VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16
909 		{
910 			3, // planes
911 			chanR|chanG|chanB,
912 			1,1,
913 			{
914 			//		Size	WDiv	HDiv	planeCompatibleFormat
915 				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
916 				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
917 				{	2,		1,		1,		VK_FORMAT_R12X4_UNORM_PACK16 },
918 			},
919 			{
920 			//		Plane	Type	Offs	Size	Stride
921 				{	2,		unorm,	4,		12,		2 },	// R
922 				{	0,		unorm,	4,		12,		2 },	// G
923 				{	1,		unorm,	4,		12,		2 },	// B
924 				{ 0, 0, 0, 0, 0 }
925 			}
926 		},
927 		// VK_FORMAT_G16B16G16R16_422_UNORM
928 		{
929 			1, // planes
930 			chanR|chanG|chanB,
931 			2,1,
932 			{
933 			//		Size	WDiv	HDiv	planeCompatibleFormat
934 				{	8,		1,		1,		VK_FORMAT_G16B16G16R16_422_UNORM },
935 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
936 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
937 			},
938 			{
939 			//		Plane	Type	Offs	Size	Stride
940 				{	0,		unorm,	48,		16,		8 },	// R
941 				{	0,		unorm,	0,		16,		4 },	// G
942 				{	0,		unorm,	16,		16,		8 },	// B
943 				{ 0, 0, 0, 0, 0 }
944 			}
945 		},
946 		// VK_FORMAT_B16G16R16G16_422_UNORM
947 		{
948 			1, // planes
949 			chanR|chanG|chanB,
950 			2,1,
951 			{
952 			//		Size	WDiv	HDiv	planeCompatibleFormat
953 				{	8,		1,		1,		VK_FORMAT_B16G16R16G16_422_UNORM },
954 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
955 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
956 			},
957 			{
958 			//		Plane	Type	Offs	Size	Stride
959 				{	0,		unorm,	32,		16,		8 },	// R
960 				{	0,		unorm,	16,		16,		4 },	// G
961 				{	0,		unorm,	0,		16,		8 },	// B
962 				{ 0, 0, 0, 0, 0 }
963 			}
964 		},
965 		// VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM
966 		{
967 			3, // planes
968 			chanR|chanG|chanB,
969 			1,1,
970 			{
971 			//		Size	WDiv	HDiv	planeCompatibleFormat
972 				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
973 				{	2,		2,		2,		VK_FORMAT_R16_UNORM },
974 				{	2,		2,		2,		VK_FORMAT_R16_UNORM },
975 			},
976 			{
977 			//		Plane	Type	Offs	Size	Stride
978 				{	2,		unorm,	0,		16,		2 },	// R
979 				{	0,		unorm,	0,		16,		2 },	// G
980 				{	1,		unorm,	0,		16,		2 },	// B
981 				{ 0, 0, 0, 0, 0 }
982 			}
983 		},
984 		// VK_FORMAT_G16_B16R16_2PLANE_420_UNORM
985 		{
986 			2, // planes
987 			chanR|chanG|chanB,
988 			1,1,
989 			{
990 			//		Size	WDiv	HDiv	planeCompatibleFormat
991 				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
992 				{	4,		2,		2,		VK_FORMAT_R16G16_UNORM },
993 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
994 			},
995 			{
996 			//		Plane	Type	Offs	Size	Stride
997 				{	1,		unorm,	16,		16,		4 },	// R
998 				{	0,		unorm,	0,		16,		2 },	// G
999 				{	1,		unorm,	0,		16,		4 },	// B
1000 				{ 0, 0, 0, 0, 0 }
1001 			}
1002 		},
1003 		// VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM
1004 		{
1005 			3, // planes
1006 			chanR|chanG|chanB,
1007 			1,1,
1008 			{
1009 			//		Size	WDiv	HDiv	planeCompatibleFormat
1010 				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
1011 				{	2,		2,		1,		VK_FORMAT_R16_UNORM },
1012 				{	2,		2,		1,		VK_FORMAT_R16_UNORM },
1013 			},
1014 			{
1015 			//		Plane	Type	Offs	Size	Stride
1016 				{	2,		unorm,	0,		16,		2 },	// R
1017 				{	0,		unorm,	0,		16,		2 },	// G
1018 				{	1,		unorm,	0,		16,		2 },	// B
1019 				{ 0, 0, 0, 0, 0 }
1020 			}
1021 		},
1022 		// VK_FORMAT_G16_B16R16_2PLANE_422_UNORM
1023 		{
1024 			2, // planes
1025 			chanR|chanG|chanB,
1026 			1,1,
1027 			{
1028 			//		Size	WDiv	HDiv	planeCompatibleFormat
1029 				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
1030 				{	4,		2,		1,		VK_FORMAT_R16G16_UNORM },
1031 				{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1032 			},
1033 			{
1034 			//		Plane	Type	Offs	Size	Stride
1035 				{	1,		unorm,	16,		16,		4 },	// R
1036 				{	0,		unorm,	0,		16,		2 },	// G
1037 				{	1,		unorm,	0,		16,		4 },	// B
1038 				{ 0, 0, 0, 0, 0 }
1039 			}
1040 		},
1041 		// VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM
1042 		{
1043 			3, // planes
1044 			chanR|chanG|chanB,
1045 			1,1,
1046 			{
1047 			//		Size	WDiv	HDiv	planeCompatibleFormat
1048 				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
1049 				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
1050 				{	2,		1,		1,		VK_FORMAT_R16_UNORM },
1051 			},
1052 			{
1053 			//		Plane	Type	Offs	Size	Stride
1054 				{	2,		unorm,	0,		16,		2 },	// R
1055 				{	0,		unorm,	0,		16,		2 },	// G
1056 				{	1,		unorm,	0,		16,		2 },	// B
1057 				{ 0, 0, 0, 0, 0 }
1058 			}
1059 		},
1060 	};
1061 
1062 	const size_t	offset	= (size_t)VK_FORMAT_G8B8G8R8_422_UNORM;
1063 
1064 	DE_ASSERT(de::inBounds<size_t>((size_t)format, offset, offset+(size_t)DE_LENGTH_OF_ARRAY(s_formatInfo)));
1065 
1066 	return s_formatInfo[(size_t)format-offset];
1067 }
1068 
getCorePlanarFormatDescription(VkFormat format)1069 PlanarFormatDescription getCorePlanarFormatDescription (VkFormat format)
1070 {
1071 	const deUint8			snorm	= (deUint8)tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
1072 	const deUint8			unorm	= (deUint8)tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
1073 	const deUint8			sint	= (deUint8)tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
1074 	const deUint8			uint	= (deUint8)tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
1075 	const deUint8			sfloat	= (deUint8)tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
1076 
1077 	const deUint8			chanR	= (deUint8)PlanarFormatDescription::CHANNEL_R;
1078 	const deUint8			chanG	= (deUint8)PlanarFormatDescription::CHANNEL_G;
1079 	const deUint8			chanB	= (deUint8)PlanarFormatDescription::CHANNEL_B;
1080 	const deUint8			chanA	= (deUint8)PlanarFormatDescription::CHANNEL_A;
1081 
1082 	DE_ASSERT(de::inBounds<deUint32>(format, VK_FORMAT_UNDEFINED+1, VK_CORE_FORMAT_LAST));
1083 
1084 #if (DE_ENDIANNESS != DE_LITTLE_ENDIAN)
1085 #	error "Big-endian is not supported"
1086 #endif
1087 
1088 	switch (format)
1089 	{
1090 		case VK_FORMAT_R8_UNORM:
1091 		{
1092 			const PlanarFormatDescription	desc	=
1093 			{
1094 				1, // planes
1095 				chanR,
1096 				1,1,
1097 				{
1098 				//		Size	WDiv	HDiv	planeCompatibleFormat
1099 					{	1,		1,		1,		VK_FORMAT_R8_UNORM },
1100 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1101 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1102 				},
1103 				{
1104 				//		Plane	Type	Offs	Size	Stride
1105 					{	0,		unorm,	0,		8,		1 },	// R
1106 					{	0,		0,		0,		0,		0 },	// G
1107 					{	0,		0,		0,		0,		0 },	// B
1108 					{	0,		0,		0,		0,		0 }		// A
1109 				}
1110 			};
1111 			return desc;
1112 		}
1113 
1114 		case VK_FORMAT_R8_SNORM:
1115 		{
1116 			const PlanarFormatDescription	desc	=
1117 			{
1118 				1, // planes
1119 				chanR,
1120 				1,1,
1121 				{
1122 				//		Size	WDiv	HDiv	planeCompatibleFormat
1123 					{	1,		1,		1,		VK_FORMAT_R8_SNORM },
1124 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1125 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1126 				},
1127 				{
1128 				//		Plane	Type	Offs	Size	Stride
1129 					{	0,		snorm,	0,		8,		1 },	// R
1130 					{	0,		0,		0,		0,		0 },	// G
1131 					{	0,		0,		0,		0,		0 },	// B
1132 					{	0,		0,		0,		0,		0 }		// A
1133 				}
1134 			};
1135 			return desc;
1136 		}
1137 
1138 
1139 		case VK_FORMAT_R8G8_UNORM:
1140 		{
1141 			const PlanarFormatDescription	desc	=
1142 			{
1143 				1, // planes
1144 				chanR|chanG,
1145 				1,1,
1146 				{
1147 				//		Size	WDiv	HDiv	planeCompatibleFormat
1148 					{	2,		1,		1,		VK_FORMAT_R8G8_UNORM },
1149 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1150 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1151 				},
1152 				{
1153 				//		Plane	Type	Offs	Size	Stride
1154 					{	0,		unorm,	0,		8,		2 },	// R
1155 					{	0,		unorm,	8,		8,		2 },	// G
1156 					{	0,		0,		0,		0,		0 },	// B
1157 					{	0,		0,		0,		0,		0 }		// A
1158 				}
1159 			};
1160 			return desc;
1161 		}
1162 
1163 		case VK_FORMAT_R8G8_SNORM:
1164 		{
1165 			const PlanarFormatDescription	desc	=
1166 			{
1167 				1, // planes
1168 				chanR | chanG,
1169 				1,1,
1170 				{
1171 				//		Size	WDiv	HDiv	planeCompatibleFormat
1172 					{	2,		1,		1,		VK_FORMAT_R8G8_SNORM },
1173 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1174 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1175 				},
1176 				{
1177 				//		Plane	Type	Offs	Size	Stride
1178 					{	0,		snorm,	0,		8,		2 },	// R
1179 					{	0,		snorm,	8,		8,		2 },	// G
1180 					{	0,		0,		0,		0,		0 },	// B
1181 					{	0,		0,		0,		0,		0 }		// A
1182 				}
1183 			};
1184 			return desc;
1185 		}
1186 
1187 		case VK_FORMAT_R16_UNORM:
1188 		{
1189 			const PlanarFormatDescription	desc	=
1190 			{
1191 				1, // planes
1192 				chanR,
1193 				1,1,
1194 				{
1195 				//		Size	WDiv	HDiv	planeCompatibleFormat
1196 					{	2,		1,		1,		VK_FORMAT_R16_UNORM },
1197 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1198 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1199 				},
1200 				{
1201 				//		Plane	Type	Offs	Size	Stride
1202 					{	0,		unorm,	0,		16,		2 },	// R
1203 					{	0,		0,		0,		0,		0 },	// G
1204 					{	0,		0,		0,		0,		0 },	// B
1205 					{	0,		0,		0,		0,		0 }		// A
1206 				}
1207 			};
1208 			return desc;
1209 		}
1210 
1211 		case VK_FORMAT_R16_SNORM:
1212 		{
1213 			const PlanarFormatDescription	desc	=
1214 			{
1215 				1, // planes
1216 				chanR,
1217 				1,1,
1218 				{
1219 				//		Size	WDiv	HDiv	planeCompatibleFormat
1220 					{	2,		1,		1,		VK_FORMAT_R16_SNORM },
1221 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1222 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1223 				},
1224 				{
1225 				//		Plane	Type	Offs	Size	Stride
1226 					{	0,		snorm,	0,		16,		2 },	// R
1227 					{	0,		0,		0,		0,		0 },	// G
1228 					{	0,		0,		0,		0,		0 },	// B
1229 					{	0,		0,		0,		0,		0 }		// A
1230 				}
1231 			};
1232 			return desc;
1233 		}
1234 
1235 		case VK_FORMAT_R16G16_UNORM:
1236 		{
1237 			const PlanarFormatDescription	desc	=
1238 			{
1239 				1, // planes
1240 				chanR|chanG,
1241 				1,1,
1242 				{
1243 				//		Size	WDiv	HDiv	planeCompatibleFormat
1244 					{	4,		1,		1,		VK_FORMAT_R16G16_UNORM },
1245 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1246 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1247 				},
1248 				{
1249 				//		Plane	Type	Offs	Size	Stride
1250 					{	0,		unorm,	0,		16,		4 },	// R
1251 					{	0,		unorm,	16,		16,		4 },	// G
1252 					{	0,		0,		0,		0,		0 },	// B
1253 					{	0,		0,		0,		0,		0 }		// A
1254 				}
1255 			};
1256 			return desc;
1257 		}
1258 
1259 		case VK_FORMAT_R16G16_SNORM:
1260 		{
1261 			const PlanarFormatDescription	desc	=
1262 			{
1263 				1, // planes
1264 				chanR | chanG,
1265 				1,1,
1266 				{
1267 				//		Size	WDiv	HDiv	planeCompatibleFormat
1268 					{	4,		1,		1,		VK_FORMAT_R16G16_SNORM },
1269 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1270 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1271 				},
1272 				{
1273 				//		Plane	Type	Offs	Size	Stride
1274 					{	0,		snorm,	0,		16,		4 },	// R
1275 					{	0,		snorm,	16,		16,		4 },	// G
1276 					{	0,		0,		0,		0,		0 },	// B
1277 					{	0,		0,		0,		0,		0 }		// A
1278 				}
1279 			};
1280 			return desc;
1281 		}
1282 
1283 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
1284 		{
1285 			const PlanarFormatDescription	desc	=
1286 			{
1287 				1, // planes
1288 				chanR|chanG|chanB,
1289 				1,1,
1290 				{
1291 				//		Size	WDiv	HDiv	planeCompatibleFormat
1292 					{	4,		1,		1,		VK_FORMAT_B10G11R11_UFLOAT_PACK32 },
1293 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1294 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1295 				},
1296 				{
1297 				//		Plane	Type	Offs	Size	Stride
1298 					{	0,		unorm,	0,		11,		4 },	// R
1299 					{	0,		unorm,	11,		11,		4 },	// G
1300 					{	0,		unorm,	22,		10,		4 },	// B
1301 					{	0,		0,		0,		0,		0 }		// A
1302 				}
1303 			};
1304 			return desc;
1305 		}
1306 
1307 		case VK_FORMAT_R4G4_UNORM_PACK8:
1308 		{
1309 			const PlanarFormatDescription	desc	=
1310 			{
1311 				1, // planes
1312 				chanR|chanG,
1313 				1,1,
1314 				{
1315 				//		Size	WDiv	HDiv	planeCompatibleFormat
1316 					{	1,		1,		1,		VK_FORMAT_R4G4_UNORM_PACK8 },
1317 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1318 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1319 				},
1320 				{
1321 				//		Plane	Type	Offs	Size	Stride
1322 					{	0,		unorm,	4,		4,		1 },	// R
1323 					{	0,		unorm,	0,		4,		1 },	// G
1324 					{	0,		0,		0,		0,		0 },	// B
1325 					{	0,		0,		0,		0,		0 }		// A
1326 				}
1327 			};
1328 			return desc;
1329 		}
1330 
1331 		case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
1332 		{
1333 			const PlanarFormatDescription	desc	=
1334 			{
1335 				1, // planes
1336 				chanR|chanG|chanB|chanA,
1337 				1,1,
1338 				{
1339 				//		Size	WDiv	HDiv	planeCompatibleFormat
1340 					{	2,		1,		1,		VK_FORMAT_R4G4B4A4_UNORM_PACK16 },
1341 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1342 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1343 				},
1344 				{
1345 				//		Plane	Type	Offs	Size	Stride
1346 					{	0,		unorm,	12,		4,		2 },	// R
1347 					{	0,		unorm,	8,		4,		2 },	// G
1348 					{	0,		unorm,	4,		4,		2 },	// B
1349 					{	0,		unorm,	0,		4,		2 }		// A
1350 				}
1351 			};
1352 			return desc;
1353 		}
1354 
1355 		case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
1356 		{
1357 			const PlanarFormatDescription	desc	=
1358 			{
1359 				1, // planes
1360 				chanR|chanG|chanB|chanA,
1361 				1,1,
1362 				{
1363 				//		Size	WDiv	HDiv	planeCompatibleFormat
1364 					{	2,		1,		1,		VK_FORMAT_B4G4R4A4_UNORM_PACK16 },
1365 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1366 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1367 				},
1368 				{
1369 				//		Plane	Type	Offs	Size	Stride
1370 					{	0,		unorm,	4,		4,		2 },	// R
1371 					{	0,		unorm,	8,		4,		2 },	// G
1372 					{	0,		unorm,	12,		4,		2 },	// B
1373 					{	0,		unorm,	0,		4,		2 }		// A
1374 				}
1375 			};
1376 			return desc;
1377 		}
1378 
1379 		case VK_FORMAT_R5G6B5_UNORM_PACK16:
1380 		{
1381 			const PlanarFormatDescription	desc	=
1382 			{
1383 				1, // planes
1384 				chanR|chanG|chanB,
1385 				1,1,
1386 				{
1387 				//		Size	WDiv	HDiv	planeCompatibleFormat
1388 					{	2,		1,		1,		VK_FORMAT_R5G6B5_UNORM_PACK16 },
1389 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1390 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1391 				},
1392 				{
1393 				//		Plane	Type	Offs	Size	Stride
1394 					{	0,		unorm,	11,		5,		2 },	// R
1395 					{	0,		unorm,	5,		6,		2 },	// G
1396 					{	0,		unorm,	0,		5,		2 },	// B
1397 					{	0,		0,		0,		0,		0 }		// A
1398 				}
1399 			};
1400 			return desc;
1401 		}
1402 
1403 		case VK_FORMAT_B5G6R5_UNORM_PACK16:
1404 		{
1405 			const PlanarFormatDescription	desc	=
1406 			{
1407 				1, // planes
1408 				chanR|chanG|chanB,
1409 				1,1,
1410 				{
1411 				//		Size	WDiv	HDiv	planeCompatibleFormat
1412 					{	2,		1,		1,		VK_FORMAT_B5G6R5_UNORM_PACK16 },
1413 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1414 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1415 				},
1416 				{
1417 				//		Plane	Type	Offs	Size	Stride
1418 					{	0,		unorm,	0,		5,		2 },	// R
1419 					{	0,		unorm,	5,		6,		2 },	// G
1420 					{	0,		unorm,	11,		5,		2 },	// B
1421 					{	0,		0,		0,		0,		0 }		// A
1422 				}
1423 			};
1424 			return desc;
1425 		}
1426 
1427 		case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
1428 		{
1429 			const PlanarFormatDescription	desc	=
1430 			{
1431 				1, // planes
1432 				chanR|chanG|chanB|chanA,
1433 				1,1,
1434 				{
1435 				//		Size	WDiv	HDiv	planeCompatibleFormat
1436 					{	2,		1,		1,		VK_FORMAT_R5G5B5A1_UNORM_PACK16 },
1437 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1438 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1439 				},
1440 				{
1441 				//		Plane	Type	Offs	Size	Stride
1442 					{	0,		unorm,	11,		5,		2 },	// R
1443 					{	0,		unorm,	6,		5,		2 },	// G
1444 					{	0,		unorm,	1,		5,		2 },	// B
1445 					{	0,		unorm,	0,		1,		2 }		// A
1446 				}
1447 			};
1448 			return desc;
1449 		}
1450 
1451 		case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
1452 		{
1453 			const PlanarFormatDescription	desc	=
1454 			{
1455 				1, // planes
1456 				chanR|chanG|chanB|chanA,
1457 				1,1,
1458 				{
1459 				//		Size	WDiv	HDiv	planeCompatibleFormat
1460 					{	2,		1,		1,		VK_FORMAT_B5G5R5A1_UNORM_PACK16 },
1461 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1462 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1463 				},
1464 				{
1465 				//		Plane	Type	Offs	Size	Stride
1466 					{	0,		unorm,	1,		5,		2 },	// R
1467 					{	0,		unorm,	6,		5,		2 },	// G
1468 					{	0,		unorm,	11,		5,		2 },	// B
1469 					{	0,		unorm,	0,		1,		2 }		// A
1470 				}
1471 			};
1472 			return desc;
1473 		}
1474 
1475 		case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
1476 		{
1477 			const PlanarFormatDescription	desc	=
1478 			{
1479 				1, // planes
1480 				chanR|chanG|chanB|chanA,
1481 				1,1,
1482 				{
1483 				//		Size	WDiv	HDiv	planeCompatibleFormat
1484 					{	2,		1,		1,		VK_FORMAT_A1R5G5B5_UNORM_PACK16 },
1485 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1486 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1487 				},
1488 				{
1489 				//		Plane	Type	Offs	Size	Stride
1490 					{	0,		unorm,	10,		5,		2 },	// R
1491 					{	0,		unorm,	5,		5,		2 },	// G
1492 					{	0,		unorm,	0,		5,		2 },	// B
1493 					{	0,		unorm,	15,		1,		2 }		// A
1494 				}
1495 			};
1496 			return desc;
1497 		}
1498 
1499 		case VK_FORMAT_R8G8B8_UNORM:
1500 		{
1501 			const PlanarFormatDescription	desc	=
1502 			{
1503 				1, // planes
1504 				chanR|chanG|chanB,
1505 				1,1,
1506 				{
1507 				//		Size	WDiv	HDiv	planeCompatibleFormat
1508 					{	3,		1,		1,		VK_FORMAT_R8G8B8_UNORM },
1509 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1510 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1511 				},
1512 				{
1513 				//		Plane	Type	Offs	Size	Stride
1514 					{	0,		unorm,	0,		8,		3 },	// R
1515 					{	0,		unorm,	8,		8,		3 },	// G
1516 					{	0,		unorm,	16,		8,		3 },	// B
1517 					{	0,		0,		0,		0,		0 }		// A
1518 				}
1519 			};
1520 			return desc;
1521 		}
1522 
1523 		case VK_FORMAT_B8G8R8_UNORM:
1524 		{
1525 			const PlanarFormatDescription	desc	=
1526 			{
1527 				1, // planes
1528 				chanR|chanG|chanB,
1529 				1,1,
1530 				{
1531 				//		Size	WDiv	HDiv	planeCompatibleFormat
1532 					{	3,		1,		1,		VK_FORMAT_B8G8R8_UNORM },
1533 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1534 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1535 				},
1536 				{
1537 				//		Plane	Type	Offs	Size	Stride
1538 					{	0,		unorm,	16,		8,		3 },	// R
1539 					{	0,		unorm,	8,		8,		3 },	// G
1540 					{	0,		unorm,	0,		8,		3 },	// B
1541 					{	0,		0,		0,		0,		0 }		// A
1542 				}
1543 			};
1544 			return desc;
1545 		}
1546 
1547 		case VK_FORMAT_R8G8B8A8_UNORM:
1548 		case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
1549 		{
1550 			const PlanarFormatDescription	desc	=
1551 			{
1552 				1, // planes
1553 				chanR|chanG|chanB|chanA,
1554 				1,1,
1555 				{
1556 				//		Size	WDiv	HDiv	planeCompatibleFormat
1557 					{	4,		1,		1,		VK_FORMAT_R8G8B8A8_UNORM },
1558 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1559 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1560 				},
1561 				{
1562 				//		Plane	Type	Offs	Size	Stride
1563 					{	0,		unorm,	0,		8,		4 },	// R
1564 					{	0,		unorm,	8,		8,		4 },	// G
1565 					{	0,		unorm,	16,		8,		4 },	// B
1566 					{	0,		unorm,	24,		8,		4 }		// A
1567 				}
1568 			};
1569 			return desc;
1570 		}
1571 
1572 		case VK_FORMAT_B8G8R8A8_UNORM:
1573 		{
1574 			const PlanarFormatDescription	desc	=
1575 			{
1576 				1, // planes
1577 				chanR|chanG|chanB|chanA,
1578 				1,1,
1579 				{
1580 				//		Size	WDiv	HDiv	planeCompatibleFormat
1581 					{	4,		1,		1,		VK_FORMAT_B8G8R8A8_UNORM },
1582 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1583 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1584 				},
1585 				{
1586 				//		Plane	Type	Offs	Size	Stride
1587 					{	0,		unorm,	16,		8,		4 },	// R
1588 					{	0,		unorm,	8,		8,		4 },	// G
1589 					{	0,		unorm,	0,		8,		4 },	// B
1590 					{	0,		unorm,	24,		8,		4 }		// A
1591 				}
1592 			};
1593 			return desc;
1594 		}
1595 
1596 		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
1597 		{
1598 			const PlanarFormatDescription	desc	=
1599 			{
1600 				1, // planes
1601 				chanR|chanG|chanB|chanA,
1602 				1,1,
1603 				{
1604 				//		Size	WDiv	HDiv	planeCompatibleFormat
1605 					{	4,		1,		1,		VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
1606 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1607 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1608 				},
1609 				{
1610 				//		Plane	Type	Offs	Size	Stride
1611 					{	0,		unorm,	20,		10,		4 },	// R
1612 					{	0,		unorm,	10,		10,		4 },	// G
1613 					{	0,		unorm,	0,		10,		4 },	// B
1614 					{	0,		unorm,	30,		2,		4 }		// A
1615 				}
1616 			};
1617 			return desc;
1618 		}
1619 
1620 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1621 		{
1622 			const PlanarFormatDescription	desc	=
1623 			{
1624 				1, // planes
1625 				chanR|chanG|chanB|chanA,
1626 				1,1,
1627 				{
1628 				//		Size	WDiv	HDiv	planeCompatibleFormat
1629 					{	4,		1,		1,		VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
1630 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1631 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1632 				},
1633 				{
1634 				//		Plane	Type	Offs	Size	Stride
1635 					{	0,		unorm,	0,		10,		4 },	// R
1636 					{	0,		unorm,	10,		10,		4 },	// G
1637 					{	0,		unorm,	20,		10,		4 },	// B
1638 					{	0,		unorm,	30,		2,		4 }		// A
1639 				}
1640 			};
1641 			return desc;
1642 		}
1643 
1644 		case VK_FORMAT_R16G16B16_UNORM:
1645 		{
1646 			const PlanarFormatDescription	desc	=
1647 			{
1648 				1, // planes
1649 				chanR|chanG|chanB,
1650 				1,1,
1651 				{
1652 				//		Size	WDiv	HDiv	planeCompatibleFormat
1653 					{	6,		1,		1,		VK_FORMAT_R16G16B16_UNORM },
1654 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1655 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1656 				},
1657 				{
1658 				//		Plane	Type	Offs	Size	Stride
1659 					{	0,		unorm,	0,		16,		6 },	// R
1660 					{	0,		unorm,	16,		16,		6 },	// G
1661 					{	0,		unorm,	32,		16,		6 },	// B
1662 					{	0,		0,		0,		0,		0 }		// A
1663 				}
1664 			};
1665 			return desc;
1666 		}
1667 
1668 		case VK_FORMAT_R16G16B16A16_UNORM:
1669 		{
1670 			const PlanarFormatDescription	desc	=
1671 			{
1672 				1, // planes
1673 				chanR|chanG|chanB|chanA,
1674 				1,1,
1675 				{
1676 				//		Size	WDiv	HDiv	planeCompatibleFormat
1677 					{	8,		1,		1,		VK_FORMAT_R16G16B16A16_UNORM },
1678 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1679 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1680 				},
1681 				{
1682 				//		Plane	Type	Offs	Size	Stride
1683 					{	0,		unorm,	0,		16,		8 },	// R
1684 					{	0,		unorm,	16,		16,		8 },	// G
1685 					{	0,		unorm,	32,		16,		8 },	// B
1686 					{	0,		unorm,	48,		16,		8 }		// A
1687 				}
1688 			};
1689 			return desc;
1690 		}
1691 
1692 		case VK_FORMAT_R8_SINT:
1693 		{
1694 			const PlanarFormatDescription	desc	=
1695 			{
1696 				1, // planes
1697 				chanR,
1698 				1,1,
1699 				{
1700 				//		Size	WDiv	HDiv	planeCompatibleFormat
1701 					{	1,		1,		1,		VK_FORMAT_R8_SINT },
1702 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1703 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1704 				},
1705 				{
1706 				//		Plane	Type	Offs	Size	Stride
1707 					{	0,		sint,	0,		8,		1 },	// R
1708 					{	0,		0,		0,		0,		0 },	// G
1709 					{	0,		0,		0,		0,		0 },	// B
1710 					{	0,		0,		0,		0,		0 }		// A
1711 				}
1712 			};
1713 			return desc;
1714 		}
1715 
1716 		case VK_FORMAT_R16_SINT:
1717 		{
1718 			const PlanarFormatDescription	desc	=
1719 			{
1720 				1, // planes
1721 				chanR,
1722 				1,1,
1723 				{
1724 				//		Size	WDiv	HDiv	planeCompatibleFormat
1725 					{	2,		1,		1,		VK_FORMAT_R16_SINT },
1726 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1727 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1728 				},
1729 				{
1730 				//		Plane	Type	Offs	Size	Stride
1731 					{	0,		sint,	0,		16,		2 },	// R
1732 					{	0,		0,		0,		0,		0 },	// G
1733 					{	0,		0,		0,		0,		0 },	// B
1734 					{	0,		0,		0,		0,		0 }		// A
1735 				}
1736 			};
1737 			return desc;
1738 		}
1739 
1740 		case VK_FORMAT_R32_SINT:
1741 		{
1742 			const PlanarFormatDescription	desc	=
1743 			{
1744 				1, // planes
1745 				chanR,
1746 				1,1,
1747 				{
1748 				//		Size	WDiv	HDiv	planeCompatibleFormat
1749 					{	4,		1,		1,		VK_FORMAT_R32_SINT },
1750 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1751 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1752 				},
1753 				{
1754 				//		Plane	Type	Offs	Size	Stride
1755 					{	0,		sint,	0,		32,		4 },	// R
1756 					{	0,		0,		0,		0,		0 },	// G
1757 					{	0,		0,		0,		0,		0 },	// B
1758 					{	0,		0,		0,		0,		0 }		// A
1759 				}
1760 			};
1761 			return desc;
1762 		}
1763 
1764 
1765 		case VK_FORMAT_R64_SINT:
1766 		{
1767 			const PlanarFormatDescription	desc =
1768 			{
1769 				1, // planes
1770 				chanR,
1771 				1,1,
1772 				{
1773 				//		Size	WDiv	HDiv	planeCompatibleFormat
1774 					{	8,		1,		1,		VK_FORMAT_R64_SINT },
1775 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1776 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1777 				},
1778 				{
1779 					//		Plane	Type	Offs	Size	Stride
1780 						{	0,		sint,	0,		64,		8 },	// R
1781 						{	0,		0,		0,		0,		0 },	// G
1782 						{	0,		0,		0,		0,		0 },	// B
1783 						{	0,		0,		0,		0,		0 }		// A
1784 					}
1785 			};
1786 			return desc;
1787 		}
1788 
1789 		case VK_FORMAT_R8G8_SINT:
1790 		{
1791 			const PlanarFormatDescription	desc	=
1792 			{
1793 				1, // planes
1794 				chanR | chanG,
1795 				1,1,
1796 				{
1797 				//		Size	WDiv	HDiv	planeCompatibleFormat
1798 					{	2,		1,		1,		VK_FORMAT_R8G8_SINT },
1799 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1800 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1801 				},
1802 				{
1803 				//		Plane	Type	Offs	Size	Stride
1804 					{	0,		sint,	0,		8,		2 },	// R
1805 					{	0,		sint,	8,		8,		2 },	// G
1806 					{	0,		0,		0,		0,		0 },	// B
1807 					{	0,		0,		0,		0,		0 }		// A
1808 				}
1809 			};
1810 			return desc;
1811 		}
1812 
1813 		case VK_FORMAT_R16G16_SINT:
1814 		{
1815 			const PlanarFormatDescription	desc	=
1816 			{
1817 				1, // planes
1818 				chanR | chanG,
1819 				1,1,
1820 				{
1821 				//		Size	WDiv	HDiv	planeCompatibleFormat
1822 					{	4,		1,		1,		VK_FORMAT_R16G16_SINT },
1823 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1824 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1825 				},
1826 				{
1827 				//		Plane	Type	Offs	Size	Stride
1828 					{	0,		sint,	0,		16,		4 },	// R
1829 					{	0,		sint,	16,		16,		4 },	// G
1830 					{	0,		0,		0,		0,		0 },	// B
1831 					{	0,		0,		0,		0,		0 }		// A
1832 				}
1833 			};
1834 			return desc;
1835 		}
1836 
1837 		case VK_FORMAT_R32G32_SINT:
1838 		{
1839 			const PlanarFormatDescription	desc	=
1840 			{
1841 				1, // planes
1842 				chanR | chanG,
1843 				1,1,
1844 				{
1845 				//		Size	WDiv	HDiv	planeCompatibleFormat
1846 					{	8,		1,		1,		VK_FORMAT_R32G32_SINT },
1847 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1848 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1849 				},
1850 				{
1851 				//		Plane	Type	Offs	Size	Stride
1852 					{	0,		sint,	0,		32,		8 },	// R
1853 					{	0,		sint,	32,		32,		8 },	// G
1854 					{	0,		0,		0,		0,		0 },	// B
1855 					{	0,		0,		0,		0,		0 }		// A
1856 				}
1857 			};
1858 			return desc;
1859 		}
1860 
1861 		case VK_FORMAT_R8G8B8A8_SINT:
1862 		{
1863 			const PlanarFormatDescription	desc	=
1864 			{
1865 				1, // planes
1866 				chanR | chanG | chanB | chanA,
1867 				1,1,
1868 				{
1869 				//		Size	WDiv	HDiv	planeCompatibleFormat
1870 					{	4,		1,		1,		VK_FORMAT_R8G8B8A8_SINT },
1871 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1872 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1873 				},
1874 				{
1875 				//		Plane	Type	Offs	Size	Stride
1876 					{	0,		sint,	0,		8,		4 },	// R
1877 					{	0,		sint,	8,		8,		4 },	// G
1878 					{	0,		sint,	16,		8,		4 },	// B
1879 					{	0,		sint,	24,		8,		4 }		// A
1880 				}
1881 			};
1882 			return desc;
1883 		}
1884 
1885 		case VK_FORMAT_R16G16B16A16_SINT:
1886 		{
1887 			const PlanarFormatDescription	desc	=
1888 			{
1889 				1, // planes
1890 				chanR | chanG | chanB | chanA,
1891 				1,1,
1892 				{
1893 				//		Size	WDiv	HDiv	planeCompatibleFormat
1894 					{	8,		1,		1,		VK_FORMAT_R16G16B16A16_SINT },
1895 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1896 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1897 				},
1898 				{
1899 				//		Plane	Type	Offs	Size	Stride
1900 					{	0,		sint,	0,		16,		8 },	// R
1901 					{	0,		sint,	16,		16,		8 },	// G
1902 					{	0,		sint,	32,		16,		8 },	// B
1903 					{	0,		sint,	48,		16,		8 }		// A
1904 				}
1905 			};
1906 			return desc;
1907 		}
1908 
1909 		case VK_FORMAT_R32G32B32A32_SINT:
1910 		{
1911 			const PlanarFormatDescription	desc	=
1912 			{
1913 				1, // planes
1914 				chanR | chanG | chanB | chanA,
1915 				1,1,
1916 				{
1917 				//		Size	WDiv	HDiv	planeCompatibleFormat
1918 					{	16,		1,		1,		VK_FORMAT_R32G32B32A32_SINT },
1919 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1920 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1921 				},
1922 				{
1923 				//		Plane	Type	Offs	Size	Stride
1924 					{	0,		sint,	0,		32,		16 },	// R
1925 					{	0,		sint,	32,		32,		16 },	// G
1926 					{	0,		sint,	64,		32,		16 },	// B
1927 					{	0,		sint,	96,		32,		16 }	// A
1928 				}
1929 			};
1930 			return desc;
1931 		}
1932 
1933 		case VK_FORMAT_R8_UINT:
1934 		{
1935 			const PlanarFormatDescription	desc	=
1936 			{
1937 				1, // planes
1938 				chanR,
1939 				1,1,
1940 				{
1941 				//		Size	WDiv	HDiv	planeCompatibleFormat
1942 					{	1,		1,		1,		VK_FORMAT_R8_UINT },
1943 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1944 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1945 				},
1946 				{
1947 				//		Plane	Type	Offs	Size	Stride
1948 					{	0,		uint,	0,		8,		1 },	// R
1949 					{	0,		0,		0,		0,		0 },	// G
1950 					{	0,		0,		0,		0,		0 },	// B
1951 					{	0,		0,		0,		0,		0 }		// A
1952 				}
1953 			};
1954 			return desc;
1955 		}
1956 
1957 		case VK_FORMAT_R16_UINT:
1958 		{
1959 			const PlanarFormatDescription	desc	=
1960 			{
1961 				1, // planes
1962 				chanR,
1963 				1,1,
1964 				{
1965 				//		Size	WDiv	HDiv	planeCompatibleFormat
1966 					{	2,		1,		1,		VK_FORMAT_R16_UINT },
1967 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1968 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1969 				},
1970 				{
1971 				//		Plane	Type	Offs	Size	Stride
1972 					{	0,		uint,	0,		16,		2 },	// R
1973 					{	0,		0,		0,		0,		0 },	// G
1974 					{	0,		0,		0,		0,		0 },	// B
1975 					{	0,		0,		0,		0,		0 }		// A
1976 				}
1977 			};
1978 			return desc;
1979 		}
1980 
1981 		case VK_FORMAT_R32_UINT:
1982 		{
1983 			const PlanarFormatDescription	desc	=
1984 			{
1985 				1, // planes
1986 				chanR,
1987 				1,1,
1988 				{
1989 				//		Size	WDiv	HDiv	planeCompatibleFormat
1990 					{	4,		1,		1,		VK_FORMAT_R32_UINT },
1991 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1992 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
1993 				},
1994 				{
1995 				//		Plane	Type	Offs	Size	Stride
1996 					{	0,		uint,	0,		32,		4 },	// R
1997 					{	0,		0,		0,		0,		0 },	// G
1998 					{	0,		0,		0,		0,		0 },	// B
1999 					{	0,		0,		0,		0,		0 }		// A
2000 				}
2001 			};
2002 			return desc;
2003 		}
2004 
2005 		case VK_FORMAT_R64_UINT:
2006 		{
2007 			const PlanarFormatDescription	desc =
2008 			{
2009 				1, // planes
2010 				chanR,
2011 				1,1,
2012 				{
2013 				//		Size	WDiv	HDiv	planeCompatibleFormat
2014 					{	8,		1,		1,		VK_FORMAT_R64_UINT },
2015 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2016 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2017 				},
2018 				{
2019 					//		Plane	Type	Offs	Size	Stride
2020 						{	0,		uint,	0,		64,		8 },	// R
2021 						{	0,		0,		0,		0,		0 },	// G
2022 						{	0,		0,		0,		0,		0 },	// B
2023 						{	0,		0,		0,		0,		0 }		// A
2024 					}
2025 			};
2026 			return desc;
2027 		}
2028 
2029 		case VK_FORMAT_R8G8_UINT:
2030 		{
2031 			const PlanarFormatDescription	desc	=
2032 			{
2033 				1, // planes
2034 				chanR | chanG,
2035 				1,1,
2036 				{
2037 				//		Size	WDiv	HDiv	planeCompatibleFormat
2038 					{	2,		1,		1,		VK_FORMAT_R8G8_UINT },
2039 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2040 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2041 				},
2042 				{
2043 				//		Plane	Type	Offs	Size	Stride
2044 					{	0,		uint,	0,		8,		2 },	// R
2045 					{	0,		uint,	8,		8,		2 },	// G
2046 					{	0,		0,		0,		0,		0 },	// B
2047 					{	0,		0,		0,		0,		0 }		// A
2048 				}
2049 			};
2050 			return desc;
2051 		}
2052 
2053 		case VK_FORMAT_R16G16_UINT:
2054 		{
2055 			const PlanarFormatDescription	desc	=
2056 			{
2057 				1, // planes
2058 				chanR | chanG,
2059 				1,1,
2060 				{
2061 				//		Size	WDiv	HDiv	planeCompatibleFormat
2062 					{	4,		1,		1,		VK_FORMAT_R16G16_UINT },
2063 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2064 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2065 				},
2066 				{
2067 				//		Plane	Type	Offs	Size	Stride
2068 					{	0,		uint,	0,		16,		4 },	// R
2069 					{	0,		uint,	16,		16,		4 },	// G
2070 					{	0,		0,		0,		0,		0 },	// B
2071 					{	0,		0,		0,		0,		0 }		// A
2072 				}
2073 			};
2074 			return desc;
2075 		}
2076 
2077 		case VK_FORMAT_R32G32_UINT:
2078 		{
2079 			const PlanarFormatDescription	desc	=
2080 			{
2081 				1, // planes
2082 				chanR | chanG,
2083 				1,1,
2084 				{
2085 				//		Size	WDiv	HDiv	planeCompatibleFormat
2086 					{	8,		1,		1,		VK_FORMAT_R32G32_UINT },
2087 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2088 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2089 				},
2090 				{
2091 				//		Plane	Type	Offs	Size	Stride
2092 					{	0,		uint,	0,		32,		8 },	// R
2093 					{	0,		uint,	32,		32,		8 },	// G
2094 					{	0,		0,		0,		0,		0 },	// B
2095 					{	0,		0,		0,		0,		0 }		// A
2096 				}
2097 			};
2098 			return desc;
2099 		}
2100 
2101 		case VK_FORMAT_R8G8B8A8_UINT:
2102 		{
2103 			const PlanarFormatDescription	desc	=
2104 			{
2105 				1, // planes
2106 				chanR | chanG | chanB | chanA,
2107 				1,1,
2108 				{
2109 				//		Size	WDiv	HDiv	planeCompatibleFormat
2110 					{	4,		1,		1,		VK_FORMAT_R8G8B8A8_UINT },
2111 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2112 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2113 				},
2114 				{
2115 				//		Plane	Type	Offs	Size	Stride
2116 					{	0,		uint,	0,		8,		4 },	// R
2117 					{	0,		uint,	8,		8,		4 },	// G
2118 					{	0,		uint,	16,		8,		4 },	// B
2119 					{	0,		uint,	24,		8,		4 }		// A
2120 				}
2121 			};
2122 			return desc;
2123 		}
2124 
2125 		case VK_FORMAT_R16G16B16A16_UINT:
2126 		{
2127 			const PlanarFormatDescription	desc	=
2128 			{
2129 				1, // planes
2130 				chanR | chanG | chanB | chanA,
2131 				1,1,
2132 				{
2133 				//		Size	WDiv	HDiv	planeCompatibleFormat
2134 					{	8,		1,		1,		VK_FORMAT_R16G16B16A16_UINT },
2135 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2136 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2137 				},
2138 				{
2139 				//		Plane	Type	Offs	Size	Stride
2140 					{	0,		uint,	0,		16,		8 },	// R
2141 					{	0,		uint,	16,		16,		8 },	// G
2142 					{	0,		uint,	32,		16,		8 },	// B
2143 					{	0,		uint,	48,		16,		8 }		// A
2144 				}
2145 			};
2146 			return desc;
2147 		}
2148 
2149 		case VK_FORMAT_R32G32B32A32_UINT:
2150 		{
2151 			const PlanarFormatDescription	desc	=
2152 			{
2153 				1, // planes
2154 				chanR | chanG | chanB | chanA,
2155 				1,1,
2156 				{
2157 				//		Size	WDiv	HDiv	planeCompatibleFormat
2158 					{	16,		1,		1,		VK_FORMAT_R32G32B32A32_UINT },
2159 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2160 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2161 				},
2162 				{
2163 				//		Plane	Type	Offs	Size	Stride
2164 					{	0,		uint,	0,		32,		16 },	// R
2165 					{	0,		uint,	32,		32,		16 },	// G
2166 					{	0,		uint,	64,		32,		16 },	// B
2167 					{	0,		uint,	96,		32,		16 }	// A
2168 				}
2169 			};
2170 			return desc;
2171 		}
2172 
2173 		case VK_FORMAT_R8G8B8A8_SNORM:
2174 		{
2175 			const PlanarFormatDescription	desc	=
2176 			{
2177 				1, // planes
2178 				chanR | chanG | chanB | chanA,
2179 				1,1,
2180 				{
2181 				//		Size	WDiv	HDiv	planeCompatibleFormat
2182 					{	4,		1,		1,		VK_FORMAT_R8G8B8A8_SNORM },
2183 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2184 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2185 				},
2186 				{
2187 				//		Plane	Type	Offs	Size	Stride
2188 					{	0,		snorm,	0,		8,		4 },	// R
2189 					{	0,		snorm,	8,		8,		4 },	// G
2190 					{	0,		snorm,	16,		8,		4 },	// B
2191 					{	0,		snorm,	24,		8,		4 }		// A
2192 				}
2193 			};
2194 			return desc;
2195 		}
2196 
2197 		case VK_FORMAT_R16G16B16A16_SNORM:
2198 		{
2199 			const PlanarFormatDescription	desc	=
2200 			{
2201 				1, // planes
2202 				chanR | chanG | chanB | chanA,
2203 				1,1,
2204 				{
2205 				//		Size	WDiv	HDiv	planeCompatibleFormat
2206 					{	8,		1,		1,		VK_FORMAT_R16G16B16A16_SNORM },
2207 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2208 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2209 				},
2210 				{
2211 				//		Plane	Type	Offs	Size	Stride
2212 					{	0,		snorm,	0,		16,		8 },	// R
2213 					{	0,		snorm,	16,		16,		8 },	// G
2214 					{	0,		snorm,	32,		16,		8 },	// B
2215 					{	0,		snorm,	48,		16,		8 }		// A
2216 				}
2217 			};
2218 			return desc;
2219 		}
2220 		case VK_FORMAT_R32_SFLOAT:
2221 		case VK_FORMAT_D32_SFLOAT:
2222 		{
2223 			const PlanarFormatDescription	desc	=
2224 			{
2225 				1, // planes
2226 				chanR,
2227 				1,1,
2228 				{
2229 				//		Size	WDiv	HDiv	planeCompatibleFormat
2230 					{	4,		1,		1,		VK_FORMAT_R32_SFLOAT },
2231 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2232 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2233 				},
2234 				{
2235 				//		Plane	Type	Offs	Size	Stride
2236 					{	0,		sfloat,	0,		32,		4 },	// R
2237 					{	0,		0,		0,		0,		0 },	// G
2238 					{	0,		0,		0,		0,		0 },	// B
2239 					{	0,		0,		0,		0,		0 }		// A
2240 				}
2241 			};
2242 			return desc;
2243 		}
2244 
2245 		case VK_FORMAT_D16_UNORM:
2246 		{
2247 			const PlanarFormatDescription	desc	=
2248 			{
2249 				1, // planes
2250 				chanR,
2251 				1,1,
2252 				{
2253 				//		Size	WDiv	HDiv	planeCompatibleFormat
2254 					{	2,		1,		1,		VK_FORMAT_D16_UNORM },
2255 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2256 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2257 				},
2258 				{
2259 				//		Plane	Type	Offs	Size	Stride
2260 					{	0,		unorm,	0,		16,		2 },	// R
2261 					{	0,		0,		0,		0,		0 },	// G
2262 					{	0,		0,		0,		0,		0 },	// B
2263 					{	0,		0,		0,		0,		0 }		// A
2264 				}
2265 			};
2266 			return desc;
2267 		}
2268 
2269 		case VK_FORMAT_S8_UINT:
2270 		{
2271 			const PlanarFormatDescription	desc	=
2272 			{
2273 				1, // planes
2274 				chanR,
2275 				1,1,
2276 				{
2277 				//		Size	WDiv	HDiv	planeCompatibleFormat
2278 					{	1,		1,		1,		VK_FORMAT_S8_UINT },
2279 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2280 					{	0,		0,		0,		VK_FORMAT_UNDEFINED},
2281 				},
2282 				{
2283 				//		Plane	Type	Offs	Size	Stride
2284 					{	0,		uint,	0,		8,		1 },	// R
2285 					{	0,		0,		0,		0,		0 },	// G
2286 					{	0,		0,		0,		0,		0 },	// B
2287 					{	0,		0,		0,		0,		0 }		// A
2288 				}
2289 			};
2290 			return desc;
2291 		}
2292 
2293 		case VK_FORMAT_R32G32B32A32_SFLOAT:
2294 		{
2295 			const PlanarFormatDescription	desc	=
2296 			{
2297 				1, // planes
2298 				chanR|chanG|chanB|chanA,
2299 				1,1,
2300 				{
2301 				//		Size	WDiv	HDiv	planeCompatibleFormat
2302 					{	16,		1,		1,		VK_FORMAT_R32G32B32A32_SFLOAT },
2303 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2304 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2305 				},
2306 				{
2307 				//		Plane	Type	Offs	Size	Stride
2308 					{	0,		sfloat,	0,		32,		16 },	// R
2309 					{	0,		sfloat,	32,		32,		16 },	// G
2310 					{	0,		sfloat,	64,		32,		16 },	// B
2311 					{	0,		sfloat,	96,		32,		16 },	// A
2312 				}
2313 			};
2314 			return desc;
2315 		}
2316 
2317 		case VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT:
2318 		{
2319 			const PlanarFormatDescription	desc	=
2320 			{
2321 				1, // planes
2322 				chanR|chanG|chanB|chanA,
2323 				1,1,
2324 				{
2325 				//		Size	WDiv	HDiv	planeCompatibleFormat
2326 					{	2,		1,		1,		VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT },
2327 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2328 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2329 				},
2330 				{
2331 				//		Plane	Type	Offs	Size	Stride
2332 					{	0,		unorm,	8,		4,		2 },	// R
2333 					{	0,		unorm,	4,		4,		2 },	// G
2334 					{	0,		unorm,	0,		4,		2 },	// B
2335 					{	0,		unorm,	12,		4,		2 }		// A
2336 				}
2337 			};
2338 			return desc;
2339 		}
2340 
2341 		case VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT:
2342 		{
2343 			const PlanarFormatDescription	desc	=
2344 			{
2345 				1, // planes
2346 				chanR|chanG|chanB|chanA,
2347 				1,1,
2348 				{
2349 				//		Size	WDiv	HDiv	planeCompatibleFormat
2350 					{	2,		1,		1,		VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT },
2351 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2352 					{	0,		0,		0,		VK_FORMAT_UNDEFINED },
2353 				},
2354 				{
2355 				//		Plane	Type	Offs	Size	Stride
2356 					{	0,		unorm,	0,		4,		2 },	// R
2357 					{	0,		unorm,	4,		4,		2 },	// G
2358 					{	0,		unorm,	8,		4,		2 },	// B
2359 					{	0,		unorm,	12,		4,		2 }		// A
2360 				}
2361 			};
2362 			return desc;
2363 		}
2364 
2365 
2366 		default:
2367 			TCU_THROW(InternalError, "Not implemented");
2368 	}
2369 }
2370 
getPlanarFormatDescription(VkFormat format)2371 PlanarFormatDescription getPlanarFormatDescription (VkFormat format)
2372 {
2373 	if (isYCbCrFormat(format))
2374 		return getYCbCrPlanarFormatDescription(format);
2375 	else
2376 		return getCorePlanarFormatDescription(format);
2377 }
2378 
getPlaneCount(VkFormat format)2379 int getPlaneCount (VkFormat format)
2380 {
2381 	switch (format)
2382 	{
2383 		case VK_FORMAT_G8B8G8R8_422_UNORM:
2384 		case VK_FORMAT_B8G8R8G8_422_UNORM:
2385 		case VK_FORMAT_R10X6_UNORM_PACK16:
2386 		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
2387 		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
2388 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
2389 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
2390 		case VK_FORMAT_R12X4_UNORM_PACK16:
2391 		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
2392 		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
2393 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
2394 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
2395 		case VK_FORMAT_G16B16G16R16_422_UNORM:
2396 		case VK_FORMAT_B16G16R16G16_422_UNORM:
2397 			return 1;
2398 
2399 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
2400 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
2401 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
2402 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
2403 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
2404 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
2405 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
2406 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
2407 		case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
2408 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
2409 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
2410 		case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
2411 			return 2;
2412 
2413 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
2414 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
2415 		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
2416 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
2417 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
2418 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
2419 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
2420 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
2421 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
2422 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
2423 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
2424 		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
2425 			return 3;
2426 
2427 		default:
2428 			DE_FATAL("Not YCbCr format");
2429 			return 0;
2430 	}
2431 }
2432 
getMipmapCount(VkFormat format,const vk::PlanarFormatDescription & formatDescription,const VkImageFormatProperties & imageFormatProperties,const VkExtent3D & extent)2433 deUint32 getMipmapCount(VkFormat format, const vk::PlanarFormatDescription& formatDescription, const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent)
2434 {
2435 	if (isYCbCrFormat(format))
2436 		return 1;
2437 	tcu::UVec3 imageAlignment	= getImageSizeAlignment(formatDescription);
2438 	deUint32 mipmapEdge			= std::max(std::max(extent.width, extent.height), extent.depth);
2439 	if (imageAlignment.x() > 1)
2440 		mipmapEdge = std::min(mipmapEdge, extent.width / imageAlignment.x());
2441 	if (imageAlignment.y() > 1)
2442 		mipmapEdge = std::min(mipmapEdge, extent.height / imageAlignment.y());
2443 	if (imageAlignment.z() > 1)
2444 		mipmapEdge = std::min(mipmapEdge, extent.depth / imageAlignment.z());
2445 	return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(mipmapEdge))) + 1u, imageFormatProperties.maxMipLevels);
2446 }
2447 
getPlaneSizeInBytes(const PlanarFormatDescription & formatInfo,const VkExtent3D & baseExtents,const deUint32 planeNdx,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)2448 deUint32 getPlaneSizeInBytes (const PlanarFormatDescription&	formatInfo,
2449 							  const VkExtent3D&					baseExtents,
2450 							  const deUint32					planeNdx,
2451 							  const deUint32					mipmapLevel,
2452 							  const deUint32					mipmapMemoryAlignment)
2453 {
2454 	VkExtent3D imageExtent	= getPlaneExtent(formatInfo, baseExtents, planeNdx, mipmapLevel);
2455 	imageExtent.width		/= formatInfo.blockWidth;
2456 	imageExtent.height		/= formatInfo.blockHeight;
2457 	return deAlign32( formatInfo.planes[planeNdx].elementSizeBytes * imageExtent.width * imageExtent.height * imageExtent.depth, mipmapMemoryAlignment);
2458 }
2459 
getPlaneSizeInBytes(const PlanarFormatDescription & formatInfo,const tcu::UVec2 & baseExtents,const deUint32 planeNdx,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)2460 deUint32 getPlaneSizeInBytes (const PlanarFormatDescription&	formatInfo,
2461 							  const tcu::UVec2&					baseExtents,
2462 							  const deUint32					planeNdx,
2463 							  const deUint32					mipmapLevel,
2464 							  const deUint32					mipmapMemoryAlignment)
2465 {
2466 	tcu::UVec2 mipExtents = getPlaneExtent(formatInfo, baseExtents, planeNdx, mipmapLevel) / tcu::UVec2(formatInfo.blockWidth, formatInfo.blockHeight);
2467 	return deAlign32( formatInfo.planes[planeNdx].elementSizeBytes * mipExtents.x() * mipExtents.y(), mipmapMemoryAlignment);
2468 }
2469 
getPlaneExtent(const PlanarFormatDescription & formatInfo,const VkExtent3D & baseExtents,const deUint32 planeNdx,const deUint32 mipmapLevel)2470 VkExtent3D getPlaneExtent(const PlanarFormatDescription&	formatInfo,
2471 						  const VkExtent3D&					baseExtents,
2472 						  const deUint32					planeNdx,
2473 						  const deUint32					mipmapLevel)
2474 {
2475 	deUint32	widthDivisor	= formatInfo.planes[planeNdx].widthDivisor;
2476 	deUint32	heightDivisor	= formatInfo.planes[planeNdx].heightDivisor;
2477 	deUint32	depthDivisor	= 1u;
2478 	VkExtent3D	mip0Extents		{ baseExtents.width / widthDivisor, baseExtents.height / heightDivisor, baseExtents.depth / depthDivisor };
2479 
2480 	return mipLevelExtents(mip0Extents, mipmapLevel);
2481 }
2482 
getPlaneExtent(const PlanarFormatDescription & formatInfo,const tcu::UVec2 & baseExtents,const deUint32 planeNdx,const deUint32 mipmapLevel)2483 tcu::UVec2 getPlaneExtent(const PlanarFormatDescription&	formatInfo,
2484 						  const tcu::UVec2&					baseExtents,
2485 						  const deUint32					planeNdx,
2486 						  const deUint32					mipmapLevel)
2487 {
2488 	deUint32 widthDivisor			= formatInfo.planes[planeNdx].widthDivisor;
2489 	deUint32 heightDivisor			= formatInfo.planes[planeNdx].heightDivisor;
2490 	tcu::UVec2 mip0Extents			{ baseExtents.x() / widthDivisor, baseExtents.y() / heightDivisor };
2491 
2492 	return tcu::UVec2
2493 	{
2494 		std::max(mip0Extents.x() >> mipmapLevel, 1u),
2495 		std::max(mip0Extents.y() >> mipmapLevel, 1u)
2496 	};
2497 }
2498 
getImageSizeAlignment(VkFormat format)2499 tcu::UVec3 getImageSizeAlignment(VkFormat format)
2500 {
2501 	return getImageSizeAlignment(getPlanarFormatDescription(format));
2502 }
2503 
getImageSizeAlignment(const PlanarFormatDescription & formatInfo)2504 tcu::UVec3 getImageSizeAlignment(const PlanarFormatDescription&	formatInfo)
2505 {
2506 	tcu::UVec3 imgAlignment{ formatInfo.blockWidth, formatInfo.blockHeight, 1 };
2507 	for (deUint32 planeNdx = 0; planeNdx < formatInfo.numPlanes; ++planeNdx)
2508 	{
2509 		imgAlignment.x() = std::max(imgAlignment.x(), static_cast<deUint32>(formatInfo.planes[planeNdx].widthDivisor));
2510 		imgAlignment.y() = std::max(imgAlignment.y(), static_cast<deUint32>(formatInfo.planes[planeNdx].heightDivisor));
2511 	}
2512 	return imgAlignment;
2513 }
2514 
getBlockExtent(VkFormat format)2515 tcu::UVec2 getBlockExtent(VkFormat format)
2516 {
2517 	return getBlockExtent(getPlanarFormatDescription(format));
2518 }
2519 
getBlockExtent(const PlanarFormatDescription & formatInfo)2520 tcu::UVec2 getBlockExtent(const PlanarFormatDescription& formatInfo)
2521 {
2522 	return tcu::UVec2{ formatInfo.blockWidth, formatInfo.blockHeight };
2523 }
2524 
getPlaneCompatibleFormat(VkFormat format,deUint32 planeNdx)2525 VkFormat getPlaneCompatibleFormat(VkFormat format, deUint32 planeNdx)
2526 {
2527 	return getPlaneCompatibleFormat(getPlanarFormatDescription(format), planeNdx);
2528 }
2529 
getPlaneCompatibleFormat(const PlanarFormatDescription & formatInfo,deUint32 planeNdx)2530 VkFormat getPlaneCompatibleFormat(const PlanarFormatDescription& formatInfo, deUint32 planeNdx)
2531 {
2532 	DE_ASSERT(planeNdx < formatInfo.numPlanes);
2533 	return formatInfo.planes[planeNdx].planeCompatibleFormat;
2534 }
2535 
getPlaneAspect(deUint32 planeNdx)2536 VkImageAspectFlagBits getPlaneAspect (deUint32 planeNdx)
2537 {
2538 	DE_ASSERT(de::inBounds(planeNdx, 0u, 3u));
2539 	return (VkImageAspectFlagBits)(VK_IMAGE_ASPECT_PLANE_0_BIT << planeNdx);
2540 }
2541 
getAspectPlaneNdx(VkImageAspectFlagBits flags)2542 deUint32 getAspectPlaneNdx (VkImageAspectFlagBits flags)
2543 {
2544 	switch (flags)
2545 	{
2546 		case VK_IMAGE_ASPECT_PLANE_0_BIT:	return 0;
2547 		case VK_IMAGE_ASPECT_PLANE_1_BIT:	return 1;
2548 		case VK_IMAGE_ASPECT_PLANE_2_BIT:	return 2;
2549 		default:
2550 			DE_FATAL("Invalid plane aspect");
2551 			return 0;
2552 	}
2553 }
2554 
isChromaSubsampled(VkFormat format)2555 bool isChromaSubsampled (VkFormat format)
2556 {
2557 	switch (format)
2558 	{
2559 		case VK_FORMAT_G8B8G8R8_422_UNORM:
2560 		case VK_FORMAT_B8G8R8G8_422_UNORM:
2561 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
2562 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
2563 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
2564 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
2565 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
2566 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
2567 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
2568 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
2569 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
2570 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
2571 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
2572 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
2573 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
2574 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
2575 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
2576 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
2577 		case VK_FORMAT_G16B16G16R16_422_UNORM:
2578 		case VK_FORMAT_B16G16R16G16_422_UNORM:
2579 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
2580 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
2581 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
2582 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
2583 			return true;
2584 
2585 		default:
2586 			return false;
2587 	}
2588 }
2589 
isSupportedByFramework(VkFormat format)2590 bool isSupportedByFramework (VkFormat format)
2591 {
2592 	if (format == VK_FORMAT_UNDEFINED || format > VK_CORE_FORMAT_LAST)
2593 		return false;
2594 
2595 	switch (format)
2596 	{
2597 		case VK_FORMAT_R64_UINT:
2598 		case VK_FORMAT_R64_SINT:
2599 		case VK_FORMAT_R64_SFLOAT:
2600 		case VK_FORMAT_R64G64_UINT:
2601 		case VK_FORMAT_R64G64_SINT:
2602 		case VK_FORMAT_R64G64_SFLOAT:
2603 		case VK_FORMAT_R64G64B64_UINT:
2604 		case VK_FORMAT_R64G64B64_SINT:
2605 		case VK_FORMAT_R64G64B64_SFLOAT:
2606 		case VK_FORMAT_R64G64B64A64_UINT:
2607 		case VK_FORMAT_R64G64B64A64_SINT:
2608 		case VK_FORMAT_R64G64B64A64_SFLOAT:
2609 			// \todo [2016-12-01 pyry] Support 64-bit channel types
2610 			return false;
2611 
2612 		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
2613 		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
2614 		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
2615 		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
2616 		case VK_FORMAT_BC2_UNORM_BLOCK:
2617 		case VK_FORMAT_BC2_SRGB_BLOCK:
2618 		case VK_FORMAT_BC3_UNORM_BLOCK:
2619 		case VK_FORMAT_BC3_SRGB_BLOCK:
2620 		case VK_FORMAT_BC4_UNORM_BLOCK:
2621 		case VK_FORMAT_BC4_SNORM_BLOCK:
2622 		case VK_FORMAT_BC5_UNORM_BLOCK:
2623 		case VK_FORMAT_BC5_SNORM_BLOCK:
2624 		case VK_FORMAT_BC6H_UFLOAT_BLOCK:
2625 		case VK_FORMAT_BC6H_SFLOAT_BLOCK:
2626 		case VK_FORMAT_BC7_UNORM_BLOCK:
2627 		case VK_FORMAT_BC7_SRGB_BLOCK:
2628 			return false;
2629 
2630 		default:
2631 			return true;
2632 	}
2633 }
2634 
checkImageSupport(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const VkImageCreateInfo & imageCreateInfo)2635 void checkImageSupport (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, const VkImageCreateInfo& imageCreateInfo)
2636 {
2637 	VkImageFormatProperties imageFormatProperties;
2638 
2639 	if (vki.getPhysicalDeviceImageFormatProperties(physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType,
2640 												   imageCreateInfo.tiling, imageCreateInfo.usage, imageCreateInfo.flags,
2641 												   &imageFormatProperties))
2642 	{
2643 		TCU_THROW(NotSupportedError, "Image format not supported.");
2644 	}
2645 	if (((VkSampleCountFlagBits)imageFormatProperties.sampleCounts & imageCreateInfo.samples) == 0)
2646 	{
2647 		TCU_THROW(NotSupportedError, "Sample count not supported.");
2648 	}
2649 	if (imageFormatProperties.maxArrayLayers < imageCreateInfo.arrayLayers)
2650 	{
2651 		TCU_THROW(NotSupportedError, "Layer count not supported.");
2652 	}
2653 }
2654 
mapTextureFormat(const tcu::TextureFormat & format)2655 VkFormat mapTextureFormat (const tcu::TextureFormat& format)
2656 {
2657 	DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST < (1<<16));
2658 	DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELTYPE_LAST < (1<<16));
2659 
2660 #define PACK_FMT(ORDER, TYPE) ((int(ORDER) << 16) | int(TYPE))
2661 #define FMT_CASE(ORDER, TYPE) PACK_FMT(tcu::TextureFormat::ORDER, tcu::TextureFormat::TYPE)
2662 
2663 	// update this mapping if VkFormat changes
2664 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
2665 
2666 	switch (PACK_FMT(format.order, format.type))
2667 	{
2668 		case FMT_CASE(RG, UNORM_BYTE_44):					return VK_FORMAT_R4G4_UNORM_PACK8;
2669 		case FMT_CASE(RGB, UNORM_SHORT_565):				return VK_FORMAT_R5G6B5_UNORM_PACK16;
2670 		case FMT_CASE(RGBA, UNORM_SHORT_4444):				return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
2671 		case FMT_CASE(RGBA, UNORM_SHORT_5551):				return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
2672 
2673 		case FMT_CASE(BGR, UNORM_SHORT_565):				return VK_FORMAT_B5G6R5_UNORM_PACK16;
2674 		case FMT_CASE(BGRA, UNORM_SHORT_4444):				return VK_FORMAT_B4G4R4A4_UNORM_PACK16;
2675 		case FMT_CASE(BGRA, UNORM_SHORT_5551):				return VK_FORMAT_B5G5R5A1_UNORM_PACK16;
2676 
2677 		case FMT_CASE(ARGB, UNORM_SHORT_1555):				return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
2678 
2679 		case FMT_CASE(R, UNORM_INT8):						return VK_FORMAT_R8_UNORM;
2680 		case FMT_CASE(R, SNORM_INT8):						return VK_FORMAT_R8_SNORM;
2681 		case FMT_CASE(R, UNSIGNED_INT8):					return VK_FORMAT_R8_UINT;
2682 		case FMT_CASE(R, SIGNED_INT8):						return VK_FORMAT_R8_SINT;
2683 		case FMT_CASE(sR, UNORM_INT8):						return VK_FORMAT_R8_SRGB;
2684 
2685 		case FMT_CASE(RG, UNORM_INT8):						return VK_FORMAT_R8G8_UNORM;
2686 		case FMT_CASE(RG, SNORM_INT8):						return VK_FORMAT_R8G8_SNORM;
2687 		case FMT_CASE(RG, UNSIGNED_INT8):					return VK_FORMAT_R8G8_UINT;
2688 		case FMT_CASE(RG, SIGNED_INT8):						return VK_FORMAT_R8G8_SINT;
2689 		case FMT_CASE(sRG, UNORM_INT8):						return VK_FORMAT_R8G8_SRGB;
2690 
2691 		case FMT_CASE(RGB, UNORM_INT8):						return VK_FORMAT_R8G8B8_UNORM;
2692 		case FMT_CASE(RGB, SNORM_INT8):						return VK_FORMAT_R8G8B8_SNORM;
2693 		case FMT_CASE(RGB, UNSIGNED_INT8):					return VK_FORMAT_R8G8B8_UINT;
2694 		case FMT_CASE(RGB, SIGNED_INT8):					return VK_FORMAT_R8G8B8_SINT;
2695 		case FMT_CASE(sRGB, UNORM_INT8):					return VK_FORMAT_R8G8B8_SRGB;
2696 
2697 		case FMT_CASE(RGBA, UNORM_INT8):					return VK_FORMAT_R8G8B8A8_UNORM;
2698 		case FMT_CASE(RGBA, SNORM_INT8):					return VK_FORMAT_R8G8B8A8_SNORM;
2699 		case FMT_CASE(RGBA, UNSIGNED_INT8):					return VK_FORMAT_R8G8B8A8_UINT;
2700 		case FMT_CASE(RGBA, SIGNED_INT8):					return VK_FORMAT_R8G8B8A8_SINT;
2701 		case FMT_CASE(sRGBA, UNORM_INT8):					return VK_FORMAT_R8G8B8A8_SRGB;
2702 
2703 		case FMT_CASE(RGBA, UNORM_INT_1010102_REV):			return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
2704 		case FMT_CASE(RGBA, SNORM_INT_1010102_REV):			return VK_FORMAT_A2B10G10R10_SNORM_PACK32;
2705 		case FMT_CASE(RGBA, UNSIGNED_INT_1010102_REV):		return VK_FORMAT_A2B10G10R10_UINT_PACK32;
2706 		case FMT_CASE(RGBA, SIGNED_INT_1010102_REV):		return VK_FORMAT_A2B10G10R10_SINT_PACK32;
2707 
2708 		case FMT_CASE(R, UNORM_INT16):						return VK_FORMAT_R16_UNORM;
2709 		case FMT_CASE(R, SNORM_INT16):						return VK_FORMAT_R16_SNORM;
2710 		case FMT_CASE(R, UNSIGNED_INT16):					return VK_FORMAT_R16_UINT;
2711 		case FMT_CASE(R, SIGNED_INT16):						return VK_FORMAT_R16_SINT;
2712 		case FMT_CASE(R, HALF_FLOAT):						return VK_FORMAT_R16_SFLOAT;
2713 
2714 		case FMT_CASE(RG, UNORM_INT16):						return VK_FORMAT_R16G16_UNORM;
2715 		case FMT_CASE(RG, SNORM_INT16):						return VK_FORMAT_R16G16_SNORM;
2716 		case FMT_CASE(RG, UNSIGNED_INT16):					return VK_FORMAT_R16G16_UINT;
2717 		case FMT_CASE(RG, SIGNED_INT16):					return VK_FORMAT_R16G16_SINT;
2718 		case FMT_CASE(RG, HALF_FLOAT):						return VK_FORMAT_R16G16_SFLOAT;
2719 
2720 		case FMT_CASE(RGB, UNORM_INT16):					return VK_FORMAT_R16G16B16_UNORM;
2721 		case FMT_CASE(RGB, SNORM_INT16):					return VK_FORMAT_R16G16B16_SNORM;
2722 		case FMT_CASE(RGB, UNSIGNED_INT16):					return VK_FORMAT_R16G16B16_UINT;
2723 		case FMT_CASE(RGB, SIGNED_INT16):					return VK_FORMAT_R16G16B16_SINT;
2724 		case FMT_CASE(RGB, HALF_FLOAT):						return VK_FORMAT_R16G16B16_SFLOAT;
2725 
2726 		case FMT_CASE(RGBA, UNORM_INT16):					return VK_FORMAT_R16G16B16A16_UNORM;
2727 		case FMT_CASE(RGBA, SNORM_INT16):					return VK_FORMAT_R16G16B16A16_SNORM;
2728 		case FMT_CASE(RGBA, UNSIGNED_INT16):				return VK_FORMAT_R16G16B16A16_UINT;
2729 		case FMT_CASE(RGBA, SIGNED_INT16):					return VK_FORMAT_R16G16B16A16_SINT;
2730 		case FMT_CASE(RGBA, HALF_FLOAT):					return VK_FORMAT_R16G16B16A16_SFLOAT;
2731 
2732 		case FMT_CASE(R, UNSIGNED_INT32):					return VK_FORMAT_R32_UINT;
2733 		case FMT_CASE(R, SIGNED_INT32):						return VK_FORMAT_R32_SINT;
2734 		case FMT_CASE(R, UNSIGNED_INT64):					return VK_FORMAT_R64_UINT;
2735 		case FMT_CASE(R, SIGNED_INT64):						return VK_FORMAT_R64_SINT;
2736 		case FMT_CASE(R, FLOAT):							return VK_FORMAT_R32_SFLOAT;
2737 
2738 		case FMT_CASE(RG, UNSIGNED_INT32):					return VK_FORMAT_R32G32_UINT;
2739 		case FMT_CASE(RG, SIGNED_INT32):					return VK_FORMAT_R32G32_SINT;
2740 		case FMT_CASE(RG, FLOAT):							return VK_FORMAT_R32G32_SFLOAT;
2741 
2742 		case FMT_CASE(RGB, UNSIGNED_INT32):					return VK_FORMAT_R32G32B32_UINT;
2743 		case FMT_CASE(RGB, SIGNED_INT32):					return VK_FORMAT_R32G32B32_SINT;
2744 		case FMT_CASE(RGB, FLOAT):							return VK_FORMAT_R32G32B32_SFLOAT;
2745 
2746 		case FMT_CASE(RGBA, UNSIGNED_INT32):				return VK_FORMAT_R32G32B32A32_UINT;
2747 		case FMT_CASE(RGBA, SIGNED_INT32):					return VK_FORMAT_R32G32B32A32_SINT;
2748 		case FMT_CASE(RGBA, FLOAT):							return VK_FORMAT_R32G32B32A32_SFLOAT;
2749 
2750 		case FMT_CASE(R, FLOAT64):							return VK_FORMAT_R64_SFLOAT;
2751 		case FMT_CASE(RG, FLOAT64):							return VK_FORMAT_R64G64_SFLOAT;
2752 		case FMT_CASE(RGB, FLOAT64):						return VK_FORMAT_R64G64B64_SFLOAT;
2753 		case FMT_CASE(RGBA, FLOAT64):						return VK_FORMAT_R64G64B64A64_SFLOAT;
2754 
2755 		case FMT_CASE(RGB, UNSIGNED_INT_11F_11F_10F_REV):	return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
2756 		case FMT_CASE(RGB, UNSIGNED_INT_999_E5_REV):		return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;
2757 
2758 		case FMT_CASE(BGR, UNORM_INT8):						return VK_FORMAT_B8G8R8_UNORM;
2759 		case FMT_CASE(BGR, SNORM_INT8):						return VK_FORMAT_B8G8R8_SNORM;
2760 		case FMT_CASE(BGR, UNSIGNED_INT8):					return VK_FORMAT_B8G8R8_UINT;
2761 		case FMT_CASE(BGR, SIGNED_INT8):					return VK_FORMAT_B8G8R8_SINT;
2762 		case FMT_CASE(sBGR, UNORM_INT8):					return VK_FORMAT_B8G8R8_SRGB;
2763 
2764 		case FMT_CASE(BGRA, UNORM_INT8):					return VK_FORMAT_B8G8R8A8_UNORM;
2765 		case FMT_CASE(BGRA, SNORM_INT8):					return VK_FORMAT_B8G8R8A8_SNORM;
2766 		case FMT_CASE(BGRA, UNSIGNED_INT8):					return VK_FORMAT_B8G8R8A8_UINT;
2767 		case FMT_CASE(BGRA, SIGNED_INT8):					return VK_FORMAT_B8G8R8A8_SINT;
2768 		case FMT_CASE(sBGRA, UNORM_INT8):					return VK_FORMAT_B8G8R8A8_SRGB;
2769 
2770 		case FMT_CASE(BGRA, UNORM_INT_1010102_REV):			return VK_FORMAT_A2R10G10B10_UNORM_PACK32;
2771 		case FMT_CASE(BGRA, SNORM_INT_1010102_REV):			return VK_FORMAT_A2R10G10B10_SNORM_PACK32;
2772 		case FMT_CASE(BGRA, UNSIGNED_INT_1010102_REV):		return VK_FORMAT_A2R10G10B10_UINT_PACK32;
2773 		case FMT_CASE(BGRA, SIGNED_INT_1010102_REV):		return VK_FORMAT_A2R10G10B10_SINT_PACK32;
2774 
2775 		case FMT_CASE(D, UNORM_INT16):						return VK_FORMAT_D16_UNORM;
2776 		case FMT_CASE(D, UNSIGNED_INT_24_8_REV):			return VK_FORMAT_X8_D24_UNORM_PACK32;
2777 		case FMT_CASE(D, FLOAT):							return VK_FORMAT_D32_SFLOAT;
2778 
2779 		case FMT_CASE(S, UNSIGNED_INT8):					return VK_FORMAT_S8_UINT;
2780 
2781 		case FMT_CASE(DS, UNSIGNED_INT_16_8_8):				return VK_FORMAT_D16_UNORM_S8_UINT;
2782 		case FMT_CASE(DS, UNSIGNED_INT_24_8_REV):			return VK_FORMAT_D24_UNORM_S8_UINT;
2783 		case FMT_CASE(DS, FLOAT_UNSIGNED_INT_24_8_REV):		return VK_FORMAT_D32_SFLOAT_S8_UINT;
2784 
2785 		case FMT_CASE(R,	UNORM_SHORT_10):				return VK_FORMAT_R10X6_UNORM_PACK16;
2786 		case FMT_CASE(RG,	UNORM_SHORT_10):				return VK_FORMAT_R10X6G10X6_UNORM_2PACK16;
2787 		case FMT_CASE(RGBA,	UNORM_SHORT_10):				return VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16;
2788 
2789 		case FMT_CASE(R,	UNORM_SHORT_12):				return VK_FORMAT_R12X4_UNORM_PACK16;
2790 		case FMT_CASE(RG,	UNORM_SHORT_12):				return VK_FORMAT_R12X4G12X4_UNORM_2PACK16;
2791 		case FMT_CASE(RGBA,	UNORM_SHORT_12):				return VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16;
2792 
2793 		case FMT_CASE(R,	USCALED_INT8):					return VK_FORMAT_R8_USCALED;
2794 		case FMT_CASE(RG,	USCALED_INT8):					return VK_FORMAT_R8G8_USCALED;
2795 		case FMT_CASE(RGB,	USCALED_INT8):					return VK_FORMAT_R8G8B8_USCALED;
2796 		case FMT_CASE(RGBA,	USCALED_INT8):					return VK_FORMAT_R8G8B8A8_USCALED;
2797 
2798 		case FMT_CASE(R,	USCALED_INT16):					return VK_FORMAT_R16_USCALED;
2799 		case FMT_CASE(RG,	USCALED_INT16):					return VK_FORMAT_R16G16_USCALED;
2800 		case FMT_CASE(RGB,	USCALED_INT16):					return VK_FORMAT_R16G16B16_USCALED;
2801 		case FMT_CASE(RGBA,	USCALED_INT16):					return VK_FORMAT_R16G16B16A16_USCALED;
2802 
2803 		case FMT_CASE(R,	SSCALED_INT8):					return VK_FORMAT_R8_SSCALED;
2804 		case FMT_CASE(RG,	SSCALED_INT8):					return VK_FORMAT_R8G8_SSCALED;
2805 		case FMT_CASE(RGB,	SSCALED_INT8):					return VK_FORMAT_R8G8B8_SSCALED;
2806 		case FMT_CASE(RGBA,	SSCALED_INT8):					return VK_FORMAT_R8G8B8A8_SSCALED;
2807 
2808 		case FMT_CASE(R,	SSCALED_INT16):					return VK_FORMAT_R16_SSCALED;
2809 		case FMT_CASE(RG,	SSCALED_INT16):					return VK_FORMAT_R16G16_SSCALED;
2810 		case FMT_CASE(RGB,	SSCALED_INT16):					return VK_FORMAT_R16G16B16_SSCALED;
2811 		case FMT_CASE(RGBA,	SSCALED_INT16):					return VK_FORMAT_R16G16B16A16_SSCALED;
2812 
2813 		case FMT_CASE(RGBA, USCALED_INT_1010102_REV):		return VK_FORMAT_A2B10G10R10_USCALED_PACK32;
2814 		case FMT_CASE(RGBA, SSCALED_INT_1010102_REV):		return VK_FORMAT_A2B10G10R10_SSCALED_PACK32;
2815 
2816 		case FMT_CASE(ARGB, UNORM_SHORT_4444):				return VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT;
2817 		case FMT_CASE(ABGR, UNORM_SHORT_4444):				return VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT;
2818 
2819 		default:
2820 			TCU_THROW(InternalError, "Unknown texture format");
2821 	}
2822 
2823 #undef PACK_FMT
2824 #undef FMT_CASE
2825 }
2826 
mapCompressedTextureFormat(const tcu::CompressedTexFormat format)2827 VkFormat mapCompressedTextureFormat (const tcu::CompressedTexFormat format)
2828 {
2829 	// update this mapping if CompressedTexFormat changes
2830 	DE_STATIC_ASSERT(tcu::COMPRESSEDTEXFORMAT_LAST == 55);
2831 
2832 	switch (format)
2833 	{
2834 		case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:						return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
2835 		case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:						return VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
2836 		case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:	return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
2837 		case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:	return VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
2838 		case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:					return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
2839 		case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:			return VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
2840 
2841 		case tcu::COMPRESSEDTEXFORMAT_EAC_R11:							return VK_FORMAT_EAC_R11_UNORM_BLOCK;
2842 		case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:					return VK_FORMAT_EAC_R11_SNORM_BLOCK;
2843 		case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:							return VK_FORMAT_EAC_R11G11_UNORM_BLOCK;
2844 		case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:					return VK_FORMAT_EAC_R11G11_SNORM_BLOCK;
2845 
2846 		case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:					return VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
2847 		case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_4x4_SRGB_BLOCK;
2848 		case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:					return VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
2849 		case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_5x4_SRGB_BLOCK;
2850 		case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:					return VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
2851 		case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_5x5_SRGB_BLOCK;
2852 		case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:					return VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
2853 		case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_6x5_SRGB_BLOCK;
2854 		case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:					return VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
2855 		case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
2856 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:					return VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
2857 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_8x5_SRGB_BLOCK;
2858 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:					return VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
2859 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_8x6_SRGB_BLOCK;
2860 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:					return VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
2861 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_8x8_SRGB_BLOCK;
2862 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:					return VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
2863 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_10x5_SRGB_BLOCK;
2864 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:					return VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
2865 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_10x6_SRGB_BLOCK;
2866 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:					return VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
2867 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_10x8_SRGB_BLOCK;
2868 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:					return VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
2869 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
2870 		case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:					return VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
2871 		case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
2872 		case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:					return VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
2873 		case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
2874 
2875 		case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:				return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
2876 		case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:				return VK_FORMAT_BC1_RGB_SRGB_BLOCK;
2877 		case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:				return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
2878 		case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:				return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
2879 		case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:					return VK_FORMAT_BC2_UNORM_BLOCK;
2880 		case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:					return VK_FORMAT_BC2_SRGB_BLOCK;
2881 		case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:					return VK_FORMAT_BC3_UNORM_BLOCK;
2882 		case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:					return VK_FORMAT_BC3_SRGB_BLOCK;
2883 		case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:					return VK_FORMAT_BC4_UNORM_BLOCK;
2884 		case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:					return VK_FORMAT_BC4_SNORM_BLOCK;
2885 		case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:					return VK_FORMAT_BC5_UNORM_BLOCK;
2886 		case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:					return VK_FORMAT_BC5_SNORM_BLOCK;
2887 		case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:				return VK_FORMAT_BC6H_UFLOAT_BLOCK;
2888 		case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:				return VK_FORMAT_BC6H_SFLOAT_BLOCK;
2889 		case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:					return VK_FORMAT_BC7_UNORM_BLOCK;
2890 		case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:					return VK_FORMAT_BC7_SRGB_BLOCK;
2891 
2892 		default:
2893 			TCU_THROW(InternalError, "Unknown texture format");
2894 			return VK_FORMAT_UNDEFINED;
2895 	}
2896 }
2897 
mapVkFormat(VkFormat format)2898 tcu::TextureFormat mapVkFormat (VkFormat format)
2899 {
2900 	using tcu::TextureFormat;
2901 
2902 	// update this mapping if VkFormat changes
2903 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
2904 
2905 	switch (format)
2906 	{
2907 		case VK_FORMAT_R4G4_UNORM_PACK8:		return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_BYTE_44);
2908 		case VK_FORMAT_R5G6B5_UNORM_PACK16:		return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_SHORT_565);
2909 		case VK_FORMAT_R4G4B4A4_UNORM_PACK16:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_4444);
2910 		case VK_FORMAT_R5G5B5A1_UNORM_PACK16:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_5551);
2911 
2912 		case VK_FORMAT_B5G6R5_UNORM_PACK16:		return TextureFormat(TextureFormat::BGR,	TextureFormat::UNORM_SHORT_565);
2913 		case VK_FORMAT_B4G4R4A4_UNORM_PACK16:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_SHORT_4444);
2914 		case VK_FORMAT_B5G5R5A1_UNORM_PACK16:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_SHORT_5551);
2915 
2916 		case VK_FORMAT_A1R5G5B5_UNORM_PACK16:	return TextureFormat(TextureFormat::ARGB,	TextureFormat::UNORM_SHORT_1555);
2917 
2918 		case VK_FORMAT_R8_UNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::UNORM_INT8);
2919 		case VK_FORMAT_R8_SNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::SNORM_INT8);
2920 		case VK_FORMAT_R8_USCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::USCALED_INT8);
2921 		case VK_FORMAT_R8_SSCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::SSCALED_INT8);
2922 		case VK_FORMAT_R8_UINT:					return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT8);
2923 		case VK_FORMAT_R8_SINT:					return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT8);
2924 		case VK_FORMAT_R8_SRGB:					return TextureFormat(TextureFormat::sR,		TextureFormat::UNORM_INT8);
2925 
2926 		case VK_FORMAT_R8G8_UNORM:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_INT8);
2927 		case VK_FORMAT_R8G8_SNORM:				return TextureFormat(TextureFormat::RG,		TextureFormat::SNORM_INT8);
2928 		case VK_FORMAT_R8G8_USCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::USCALED_INT8);
2929 		case VK_FORMAT_R8G8_SSCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::SSCALED_INT8);
2930 		case VK_FORMAT_R8G8_UINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT8);
2931 		case VK_FORMAT_R8G8_SINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT8);
2932 		case VK_FORMAT_R8G8_SRGB:				return TextureFormat(TextureFormat::sRG,	TextureFormat::UNORM_INT8);
2933 
2934 		case VK_FORMAT_R8G8B8_UNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT8);
2935 		case VK_FORMAT_R8G8B8_SNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SNORM_INT8);
2936 		case VK_FORMAT_R8G8B8_USCALED:			return TextureFormat(TextureFormat::RGB,	TextureFormat::USCALED_INT8);
2937 		case VK_FORMAT_R8G8B8_SSCALED:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SSCALED_INT8);
2938 		case VK_FORMAT_R8G8B8_UINT:				return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT8);
2939 		case VK_FORMAT_R8G8B8_SINT:				return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT8);
2940 		case VK_FORMAT_R8G8B8_SRGB:				return TextureFormat(TextureFormat::sRGB,	TextureFormat::UNORM_INT8);
2941 
2942 		case VK_FORMAT_R8G8B8A8_UNORM:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
2943 		case VK_FORMAT_R8G8B8A8_SNORM:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT8);
2944 		case VK_FORMAT_R8G8B8A8_USCALED:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::USCALED_INT8);
2945 		case VK_FORMAT_R8G8B8A8_SSCALED:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SSCALED_INT8);
2946 		case VK_FORMAT_R8G8B8A8_UINT:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT8);
2947 		case VK_FORMAT_R8G8B8A8_SINT:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT8);
2948 		case VK_FORMAT_R8G8B8A8_SRGB:			return TextureFormat(TextureFormat::sRGBA,	TextureFormat::UNORM_INT8);
2949 
2950 		case VK_FORMAT_R16_UNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::UNORM_INT16);
2951 		case VK_FORMAT_R16_SNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::SNORM_INT16);
2952 		case VK_FORMAT_R16_USCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::USCALED_INT16);
2953 		case VK_FORMAT_R16_SSCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::SSCALED_INT16);
2954 		case VK_FORMAT_R16_UINT:				return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT16);
2955 		case VK_FORMAT_R16_SINT:				return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT16);
2956 		case VK_FORMAT_R16_SFLOAT:				return TextureFormat(TextureFormat::R,		TextureFormat::HALF_FLOAT);
2957 
2958 		case VK_FORMAT_R16G16_UNORM:			return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_INT16);
2959 		case VK_FORMAT_R16G16_SNORM:			return TextureFormat(TextureFormat::RG,		TextureFormat::SNORM_INT16);
2960 		case VK_FORMAT_R16G16_USCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::USCALED_INT16);
2961 		case VK_FORMAT_R16G16_SSCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::SSCALED_INT16);
2962 		case VK_FORMAT_R16G16_UINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT16);
2963 		case VK_FORMAT_R16G16_SINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT16);
2964 		case VK_FORMAT_R16G16_SFLOAT:			return TextureFormat(TextureFormat::RG,		TextureFormat::HALF_FLOAT);
2965 
2966 		case VK_FORMAT_R16G16B16_UNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT16);
2967 		case VK_FORMAT_R16G16B16_SNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SNORM_INT16);
2968 		case VK_FORMAT_R16G16B16_USCALED:		return TextureFormat(TextureFormat::RGB,	TextureFormat::USCALED_INT16);
2969 		case VK_FORMAT_R16G16B16_SSCALED:		return TextureFormat(TextureFormat::RGB,	TextureFormat::SSCALED_INT16);
2970 		case VK_FORMAT_R16G16B16_UINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT16);
2971 		case VK_FORMAT_R16G16B16_SINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT16);
2972 		case VK_FORMAT_R16G16B16_SFLOAT:		return TextureFormat(TextureFormat::RGB,	TextureFormat::HALF_FLOAT);
2973 
2974 		case VK_FORMAT_R16G16B16A16_UNORM:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT16);
2975 		case VK_FORMAT_R16G16B16A16_SNORM:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT16);
2976 		case VK_FORMAT_R16G16B16A16_USCALED:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::USCALED_INT16);
2977 		case VK_FORMAT_R16G16B16A16_SSCALED:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SSCALED_INT16);
2978 		case VK_FORMAT_R16G16B16A16_UINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT16);
2979 		case VK_FORMAT_R16G16B16A16_SINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT16);
2980 		case VK_FORMAT_R16G16B16A16_SFLOAT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::HALF_FLOAT);
2981 
2982 		case VK_FORMAT_R32_UINT:				return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT32);
2983 		case VK_FORMAT_R32_SINT:				return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT32);
2984 		case VK_FORMAT_R32_SFLOAT:				return TextureFormat(TextureFormat::R,		TextureFormat::FLOAT);
2985 
2986 		case VK_FORMAT_R32G32_UINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT32);
2987 		case VK_FORMAT_R32G32_SINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT32);
2988 		case VK_FORMAT_R32G32_SFLOAT:			return TextureFormat(TextureFormat::RG,		TextureFormat::FLOAT);
2989 
2990 		case VK_FORMAT_R32G32B32_UINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT32);
2991 		case VK_FORMAT_R32G32B32_SINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT32);
2992 		case VK_FORMAT_R32G32B32_SFLOAT:		return TextureFormat(TextureFormat::RGB,	TextureFormat::FLOAT);
2993 
2994 		case VK_FORMAT_R32G32B32A32_UINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT32);
2995 		case VK_FORMAT_R32G32B32A32_SINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT32);
2996 		case VK_FORMAT_R32G32B32A32_SFLOAT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::FLOAT);
2997 
2998 		case VK_FORMAT_R64_UINT:				return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT64);
2999 		case VK_FORMAT_R64G64_UINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT64);
3000 		case VK_FORMAT_R64G64B64_UINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT64);
3001 		case VK_FORMAT_R64G64B64A64_UINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT64);
3002 		case VK_FORMAT_R64_SINT:				return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT64);
3003 		case VK_FORMAT_R64G64_SINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT64);
3004 		case VK_FORMAT_R64G64B64_SINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT64);
3005 		case VK_FORMAT_R64G64B64A64_SINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT64);
3006 		case VK_FORMAT_R64_SFLOAT:				return TextureFormat(TextureFormat::R,		TextureFormat::FLOAT64);
3007 		case VK_FORMAT_R64G64_SFLOAT:			return TextureFormat(TextureFormat::RG,		TextureFormat::FLOAT64);
3008 		case VK_FORMAT_R64G64B64_SFLOAT:		return TextureFormat(TextureFormat::RGB,	TextureFormat::FLOAT64);
3009 		case VK_FORMAT_R64G64B64A64_SFLOAT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::FLOAT64);
3010 
3011 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:	return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT_11F_11F_10F_REV);
3012 		case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:	return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT_999_E5_REV);
3013 
3014 		case VK_FORMAT_B8G8R8_UNORM:			return TextureFormat(TextureFormat::BGR,	TextureFormat::UNORM_INT8);
3015 		case VK_FORMAT_B8G8R8_SNORM:			return TextureFormat(TextureFormat::BGR,	TextureFormat::SNORM_INT8);
3016 		case VK_FORMAT_B8G8R8_USCALED:			return TextureFormat(TextureFormat::BGR,	TextureFormat::USCALED_INT8);
3017 		case VK_FORMAT_B8G8R8_SSCALED:			return TextureFormat(TextureFormat::BGR,	TextureFormat::SSCALED_INT8);
3018 		case VK_FORMAT_B8G8R8_UINT:				return TextureFormat(TextureFormat::BGR,	TextureFormat::UNSIGNED_INT8);
3019 		case VK_FORMAT_B8G8R8_SINT:				return TextureFormat(TextureFormat::BGR,	TextureFormat::SIGNED_INT8);
3020 		case VK_FORMAT_B8G8R8_SRGB:				return TextureFormat(TextureFormat::sBGR,	TextureFormat::UNORM_INT8);
3021 
3022 		case VK_FORMAT_B8G8R8A8_UNORM:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_INT8);
3023 		case VK_FORMAT_B8G8R8A8_SNORM:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::SNORM_INT8);
3024 		case VK_FORMAT_B8G8R8A8_USCALED:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::USCALED_INT8);
3025 		case VK_FORMAT_B8G8R8A8_SSCALED:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::SSCALED_INT8);
3026 		case VK_FORMAT_B8G8R8A8_UINT:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNSIGNED_INT8);
3027 		case VK_FORMAT_B8G8R8A8_SINT:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::SIGNED_INT8);
3028 		case VK_FORMAT_B8G8R8A8_SRGB:			return TextureFormat(TextureFormat::sBGRA,	TextureFormat::UNORM_INT8);
3029 
3030 		case VK_FORMAT_D16_UNORM:				return TextureFormat(TextureFormat::D,		TextureFormat::UNORM_INT16);
3031 		case VK_FORMAT_X8_D24_UNORM_PACK32:		return TextureFormat(TextureFormat::D,		TextureFormat::UNSIGNED_INT_24_8_REV);
3032 		case VK_FORMAT_D32_SFLOAT:				return TextureFormat(TextureFormat::D,		TextureFormat::FLOAT);
3033 
3034 		case VK_FORMAT_S8_UINT:					return TextureFormat(TextureFormat::S,		TextureFormat::UNSIGNED_INT8);
3035 
3036 		// \note There is no standard interleaved memory layout for DS formats; buffer-image copies
3037 		//		 will always operate on either D or S aspect only. See Khronos bug 12998
3038 		case VK_FORMAT_D16_UNORM_S8_UINT:		return TextureFormat(TextureFormat::DS,		TextureFormat::UNSIGNED_INT_16_8_8);
3039 		case VK_FORMAT_D24_UNORM_S8_UINT:		return TextureFormat(TextureFormat::DS,		TextureFormat::UNSIGNED_INT_24_8_REV);
3040 		case VK_FORMAT_D32_SFLOAT_S8_UINT:		return TextureFormat(TextureFormat::DS,		TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV);
3041 
3042 #if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
3043 		case VK_FORMAT_A8B8G8R8_UNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
3044 		case VK_FORMAT_A8B8G8R8_SNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT8);
3045 		case VK_FORMAT_A8B8G8R8_USCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::USCALED_INT8);
3046 		case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SSCALED_INT8);
3047 		case VK_FORMAT_A8B8G8R8_UINT_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT8);
3048 		case VK_FORMAT_A8B8G8R8_SINT_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT8);
3049 		case VK_FORMAT_A8B8G8R8_SRGB_PACK32:	return TextureFormat(TextureFormat::sRGBA,	TextureFormat::UNORM_INT8);
3050 #else
3051 #	error "Big-endian not supported"
3052 #endif
3053 
3054 		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_INT_1010102_REV);
3055 		case VK_FORMAT_A2R10G10B10_SNORM_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::SNORM_INT_1010102_REV);
3056 		case VK_FORMAT_A2R10G10B10_USCALED_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::USCALED_INT_1010102_REV);
3057 		case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::SSCALED_INT_1010102_REV);
3058 		case VK_FORMAT_A2R10G10B10_UINT_PACK32:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNSIGNED_INT_1010102_REV);
3059 		case VK_FORMAT_A2R10G10B10_SINT_PACK32:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::SIGNED_INT_1010102_REV);
3060 
3061 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT_1010102_REV);
3062 		case VK_FORMAT_A2B10G10R10_SNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT_1010102_REV);
3063 		case VK_FORMAT_A2B10G10R10_USCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::USCALED_INT_1010102_REV);
3064 		case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SSCALED_INT_1010102_REV);
3065 		case VK_FORMAT_A2B10G10R10_UINT_PACK32:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT_1010102_REV);
3066 		case VK_FORMAT_A2B10G10R10_SINT_PACK32:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT_1010102_REV);
3067 
3068 		// YCbCr formats that can be mapped
3069 		case VK_FORMAT_R10X6_UNORM_PACK16:					return TextureFormat(TextureFormat::R,		TextureFormat::UNORM_SHORT_10);
3070 		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:			return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_SHORT_10);
3071 		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_10);
3072 
3073 		case VK_FORMAT_R12X4_UNORM_PACK16:					return TextureFormat(TextureFormat::R,		TextureFormat::UNORM_SHORT_12);
3074 		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:			return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_SHORT_12);
3075 		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_12);
3076 
3077 		case VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT:				return TextureFormat(TextureFormat::ARGB,	TextureFormat::UNORM_SHORT_4444);
3078 		case VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT:				return TextureFormat(TextureFormat::ABGR,	TextureFormat::UNORM_SHORT_4444);
3079 
3080 		default:
3081 			TCU_THROW(InternalError, "Unknown image format");
3082 	}
3083 }
3084 
mapVkCompressedFormat(VkFormat format)3085 tcu::CompressedTexFormat mapVkCompressedFormat (VkFormat format)
3086 {
3087 	// update this mapping if VkFormat changes
3088 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
3089 
3090 	switch (format)
3091 	{
3092 		case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8;
3093 		case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8;
3094 		case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1;
3095 		case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1;
3096 		case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8;
3097 		case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8;
3098 
3099 		case VK_FORMAT_EAC_R11_UNORM_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_EAC_R11;
3100 		case VK_FORMAT_EAC_R11_SNORM_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11;
3101 		case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_EAC_RG11;
3102 		case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11;
3103 
3104 		case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA;
3105 		case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8;
3106 		case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA;
3107 		case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8;
3108 		case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA;
3109 		case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8;
3110 		case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA;
3111 		case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8;
3112 		case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA;
3113 		case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8;
3114 		case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA;
3115 		case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8;
3116 		case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA;
3117 		case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8;
3118 		case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA;
3119 		case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8;
3120 		case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA;
3121 		case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8;
3122 		case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA;
3123 		case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8;
3124 		case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA;
3125 		case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8;
3126 		case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA;
3127 		case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8;
3128 		case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA;
3129 		case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8;
3130 		case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA;
3131 		case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8;
3132 
3133 		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK;
3134 		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK;
3135 		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK;
3136 		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK;
3137 		case VK_FORMAT_BC2_UNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK;
3138 		case VK_FORMAT_BC2_SRGB_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK;
3139 		case VK_FORMAT_BC3_UNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK;
3140 		case VK_FORMAT_BC3_SRGB_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK;
3141 		case VK_FORMAT_BC4_UNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK;
3142 		case VK_FORMAT_BC4_SNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK;
3143 		case VK_FORMAT_BC5_UNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK;
3144 		case VK_FORMAT_BC5_SNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK;
3145 		case VK_FORMAT_BC6H_UFLOAT_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK;
3146 		case VK_FORMAT_BC6H_SFLOAT_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK;
3147 		case VK_FORMAT_BC7_UNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK;
3148 		case VK_FORMAT_BC7_SRGB_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK;
3149 
3150 		default:
3151 			TCU_THROW(InternalError, "Unknown image format");
3152 			return tcu::COMPRESSEDTEXFORMAT_LAST;
3153 	}
3154 }
3155 
isScaledFormat(VkFormat format)3156 static bool isScaledFormat (VkFormat format)
3157 {
3158 	// update this mapping if VkFormat changes
3159 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
3160 
3161 	switch (format)
3162 	{
3163 		case VK_FORMAT_R8_USCALED:
3164 		case VK_FORMAT_R8_SSCALED:
3165 		case VK_FORMAT_R8G8_USCALED:
3166 		case VK_FORMAT_R8G8_SSCALED:
3167 		case VK_FORMAT_R8G8B8_USCALED:
3168 		case VK_FORMAT_R8G8B8_SSCALED:
3169 		case VK_FORMAT_R8G8B8A8_USCALED:
3170 		case VK_FORMAT_R8G8B8A8_SSCALED:
3171 		case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
3172 		case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
3173 		case VK_FORMAT_R16_USCALED:
3174 		case VK_FORMAT_R16_SSCALED:
3175 		case VK_FORMAT_R16G16_USCALED:
3176 		case VK_FORMAT_R16G16_SSCALED:
3177 		case VK_FORMAT_R16G16B16_USCALED:
3178 		case VK_FORMAT_R16G16B16_SSCALED:
3179 		case VK_FORMAT_R16G16B16A16_USCALED:
3180 		case VK_FORMAT_R16G16B16A16_SSCALED:
3181 		case VK_FORMAT_B8G8R8_USCALED:
3182 		case VK_FORMAT_B8G8R8_SSCALED:
3183 		case VK_FORMAT_B8G8R8A8_USCALED:
3184 		case VK_FORMAT_B8G8R8A8_SSCALED:
3185 		case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
3186 		case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
3187 			return true;
3188 
3189 		default:
3190 			return false;
3191 	}
3192 }
3193 
fullTextureFormatRoundTripSupported(VkFormat format)3194 static bool fullTextureFormatRoundTripSupported (VkFormat format)
3195 {
3196 	if (isScaledFormat(format))
3197 	{
3198 		// *SCALED formats get mapped to correspoding (u)int formats since
3199 		// accessing them through (float) getPixel/setPixel has same behavior
3200 		// as in shader access in Vulkan.
3201 		// Unfortunately full round-trip between tcu::TextureFormat and VkFormat
3202 		// for most SCALED formats is not supported though.
3203 
3204 		const tcu::TextureFormat	tcuFormat	= mapVkFormat(format);
3205 
3206 		switch (tcuFormat.type)
3207 		{
3208 			case tcu::TextureFormat::UNSIGNED_INT8:
3209 			case tcu::TextureFormat::UNSIGNED_INT16:
3210 			case tcu::TextureFormat::UNSIGNED_INT32:
3211 			case tcu::TextureFormat::SIGNED_INT8:
3212 			case tcu::TextureFormat::SIGNED_INT16:
3213 			case tcu::TextureFormat::SIGNED_INT32:
3214 			case tcu::TextureFormat::UNSIGNED_INT_1010102_REV:
3215 			case tcu::TextureFormat::SIGNED_INT_1010102_REV:
3216 				return false;
3217 
3218 			default:
3219 				return true;
3220 		}
3221 	}
3222 	else
3223 	{
3224 		switch (format)
3225 		{
3226 			case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
3227 			case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
3228 			case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
3229 			case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
3230 			case VK_FORMAT_A8B8G8R8_UINT_PACK32:
3231 			case VK_FORMAT_A8B8G8R8_SINT_PACK32:
3232 			case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
3233 				return false; // These map to regular byte array formats
3234 
3235 			default:
3236 				break;
3237 		}
3238 
3239 		return (format != VK_FORMAT_UNDEFINED);
3240 	}
3241 }
3242 
getChannelAccessFormat(tcu::TextureChannelClass type,deUint32 offsetBits,deUint32 sizeBits)3243 tcu::TextureFormat getChannelAccessFormat (tcu::TextureChannelClass	type,
3244 										   deUint32					offsetBits,
3245 										   deUint32					sizeBits)
3246 {
3247 	using tcu::TextureFormat;
3248 
3249 	if (offsetBits == 0)
3250 	{
3251 		static const TextureFormat::ChannelType	s_size8[tcu::TEXTURECHANNELCLASS_LAST] =
3252 		{
3253 			TextureFormat::SNORM_INT8,			// snorm
3254 			TextureFormat::UNORM_INT8,			// unorm
3255 			TextureFormat::SIGNED_INT8,			// sint
3256 			TextureFormat::UNSIGNED_INT8,		// uint
3257 			TextureFormat::CHANNELTYPE_LAST,	// float
3258 		};
3259 		static const TextureFormat::ChannelType	s_size16[tcu::TEXTURECHANNELCLASS_LAST] =
3260 		{
3261 			TextureFormat::SNORM_INT16,			// snorm
3262 			TextureFormat::UNORM_INT16,			// unorm
3263 			TextureFormat::SIGNED_INT16,		// sint
3264 			TextureFormat::UNSIGNED_INT16,		// uint
3265 			TextureFormat::HALF_FLOAT,			// float
3266 		};
3267 		static const TextureFormat::ChannelType	s_size32[tcu::TEXTURECHANNELCLASS_LAST] =
3268 		{
3269 			TextureFormat::SNORM_INT32,			// snorm
3270 			TextureFormat::UNORM_INT32,			// unorm
3271 			TextureFormat::SIGNED_INT32,		// sint
3272 			TextureFormat::UNSIGNED_INT32,		// uint
3273 			TextureFormat::FLOAT,				// float
3274 		};
3275 
3276 		static const TextureFormat::ChannelType	s_size64[tcu::TEXTURECHANNELCLASS_LAST] =
3277 		{
3278 			TextureFormat::CHANNELTYPE_LAST,	// snorm
3279 			TextureFormat::CHANNELTYPE_LAST,	// unorm
3280 			TextureFormat::SIGNED_INT64,		// sint
3281 			TextureFormat::UNSIGNED_INT64,		// uint
3282 			TextureFormat::FLOAT64,				// float
3283 		};
3284 
3285 		TextureFormat::ChannelType	chnType		= TextureFormat::CHANNELTYPE_LAST;
3286 
3287 		if (sizeBits == 8)
3288 			chnType = s_size8[type];
3289 		else if (sizeBits == 16)
3290 			chnType = s_size16[type];
3291 		else if (sizeBits == 32)
3292 			chnType = s_size32[type];
3293 		else if (sizeBits == 64)
3294 			chnType = s_size64[type];
3295 
3296 		if (chnType != TextureFormat::CHANNELTYPE_LAST)
3297 			return TextureFormat(TextureFormat::R, chnType);
3298 	}
3299 	else
3300 	{
3301 		if (type		== tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT	&&
3302 			offsetBits	== 6												&&
3303 			sizeBits	== 10)
3304 			return TextureFormat(TextureFormat::R, TextureFormat::UNORM_SHORT_10);
3305 		else if (type		== tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT	&&
3306 				 offsetBits	== 4												&&
3307 				 sizeBits	== 12)
3308 			return TextureFormat(TextureFormat::R, TextureFormat::UNORM_SHORT_12);
3309 	}
3310 
3311 	TCU_THROW(InternalError, "Channel access format is not supported");
3312 }
3313 
getChannelAccess(const PlanarFormatDescription & formatInfo,const tcu::UVec2 & size,const deUint32 * planeRowPitches,void * const * planePtrs,deUint32 channelNdx)3314 tcu::PixelBufferAccess getChannelAccess (const PlanarFormatDescription&	formatInfo,
3315 										 const tcu::UVec2&				size,
3316 										 const deUint32*				planeRowPitches,
3317 										 void* const*					planePtrs,
3318 										 deUint32						channelNdx)
3319 {
3320 	DE_ASSERT(formatInfo.hasChannelNdx(channelNdx));
3321 
3322 	const deUint32	planeNdx			= formatInfo.channels[channelNdx].planeNdx;
3323 	const deUint32	planeOffsetBytes	= formatInfo.channels[channelNdx].offsetBits / 8;
3324 	const deUint32	valueOffsetBits		= formatInfo.channels[channelNdx].offsetBits % 8;
3325 	const deUint32	pixelStrideBytes	= formatInfo.channels[channelNdx].strideBytes;
3326 
3327 	DE_ASSERT(size.x() % (formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor) == 0);
3328 	DE_ASSERT(size.y() % (formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor) == 0);
3329 
3330 	const deUint32	accessHeight		= size.y() / ( formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor );
3331 	const deUint32	elementSizeBytes	= formatInfo.planes[planeNdx].elementSizeBytes;
3332 	const deUint32	rowPitch			= planeRowPitches[planeNdx];
3333 
3334 	DE_ASSERT(elementSizeBytes % pixelStrideBytes == 0);
3335 
3336 	tcu::IVec3		texDivider(
3337 		std::max(formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor * pixelStrideBytes / elementSizeBytes, 1u),
3338 		std::max(formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor * pixelStrideBytes / elementSizeBytes, 1u),
3339 		1);
3340 
3341 	return tcu::PixelBufferAccess(getChannelAccessFormat((tcu::TextureChannelClass)formatInfo.channels[channelNdx].type,
3342 														 valueOffsetBits,
3343 														 formatInfo.channels[channelNdx].sizeBits),
3344 														 tcu::IVec3((int)size.x(), (int)size.y(), 1),
3345 														 tcu::IVec3((int)pixelStrideBytes, (int)rowPitch, (int)(accessHeight*rowPitch)),
3346 														 texDivider,
3347 														 (deUint8*)planePtrs[planeNdx] + planeOffsetBytes);
3348 }
3349 
getChannelAccess(const PlanarFormatDescription & formatInfo,const tcu::UVec2 & size,const deUint32 * planeRowPitches,const void * const * planePtrs,deUint32 channelNdx)3350 tcu::ConstPixelBufferAccess getChannelAccess (const PlanarFormatDescription&	formatInfo,
3351 											  const tcu::UVec2&					size,
3352 											  const deUint32*					planeRowPitches,
3353 											  const void* const*				planePtrs,
3354 											  deUint32							channelNdx)
3355 {
3356 	return getChannelAccess(formatInfo, size, planeRowPitches, const_cast<void* const*>(planePtrs), channelNdx);
3357 }
3358 
getChannelAccess(const PlanarFormatDescription & formatInfo,const tcu::UVec3 & size,const deUint32 * planeRowPitches,void * const * planePtrs,deUint32 channelNdx)3359 tcu::PixelBufferAccess getChannelAccess (const PlanarFormatDescription&	formatInfo,
3360 										 const tcu::UVec3&				size,
3361 										 const deUint32*				planeRowPitches,
3362 										 void* const*					planePtrs,
3363 										 deUint32						channelNdx)
3364 {
3365 	DE_ASSERT(formatInfo.hasChannelNdx(channelNdx));
3366 
3367 	const deUint32	planeNdx			= formatInfo.channels[channelNdx].planeNdx;
3368 	const deUint32	planeOffsetBytes	= formatInfo.channels[channelNdx].offsetBits / 8;
3369 	const deUint32	valueOffsetBits		= formatInfo.channels[channelNdx].offsetBits % 8;
3370 	const deUint32	pixelStrideBytes	= formatInfo.channels[channelNdx].strideBytes;
3371 
3372 	DE_ASSERT(size.x() % (formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor) == 0);
3373 	DE_ASSERT(size.y() % (formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor) == 0);
3374 
3375 	const deUint32	accessHeight		= size.y() / ( formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor );
3376 	const deUint32	elementSizeBytes	= formatInfo.planes[planeNdx].elementSizeBytes;
3377 	const deUint32	rowPitch			= planeRowPitches[planeNdx];
3378 
3379 	DE_ASSERT(elementSizeBytes % pixelStrideBytes == 0);
3380 
3381 	tcu::IVec3		texDivider(
3382 		std::max(formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor * pixelStrideBytes / elementSizeBytes, 1u),
3383 		std::max(formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor * pixelStrideBytes / elementSizeBytes, 1u),
3384 		1);
3385 
3386 	return tcu::PixelBufferAccess(getChannelAccessFormat((tcu::TextureChannelClass)formatInfo.channels[channelNdx].type,
3387 														 valueOffsetBits,
3388 														 formatInfo.channels[channelNdx].sizeBits),
3389 														 tcu::IVec3((int)size.x(), (int)size.y(), (int)size.z()),
3390 														 tcu::IVec3((int)pixelStrideBytes, (int)rowPitch, (int)(accessHeight*rowPitch)),
3391 														 texDivider,
3392 														 (deUint8*)planePtrs[planeNdx] + planeOffsetBytes);
3393 }
3394 
getChannelAccess(const PlanarFormatDescription & formatInfo,const tcu::UVec3 & size,const deUint32 * planeRowPitches,const void * const * planePtrs,deUint32 channelNdx)3395 tcu::ConstPixelBufferAccess getChannelAccess (const PlanarFormatDescription&	formatInfo,
3396 											  const tcu::UVec3&					size,
3397 											  const deUint32*					planeRowPitches,
3398 											  const void* const*				planePtrs,
3399 											  deUint32							channelNdx)
3400 {
3401 	return getChannelAccess(formatInfo, size, planeRowPitches, const_cast<void* const*>(planePtrs), channelNdx);
3402 }
3403 
imageUtilSelfTest(void)3404 void imageUtilSelfTest (void)
3405 {
3406 	for (int formatNdx = 0; formatNdx < VK_CORE_FORMAT_LAST; formatNdx++)
3407 	{
3408 		const VkFormat	format	= (VkFormat)formatNdx;
3409 
3410 		if (format == VK_FORMAT_R64_UINT			||
3411 			format == VK_FORMAT_R64_SINT			||
3412 			format == VK_FORMAT_R64G64_UINT			||
3413 			format == VK_FORMAT_R64G64_SINT			||
3414 			format == VK_FORMAT_R64G64B64_UINT		||
3415 			format == VK_FORMAT_R64G64B64_SINT		||
3416 			format == VK_FORMAT_R64G64B64A64_UINT	||
3417 			format == VK_FORMAT_R64G64B64A64_SINT)
3418 			continue; // \todo [2015-12-05 pyry] Add framework support for (u)int64 channel type
3419 
3420 		if (format != VK_FORMAT_UNDEFINED && !isCompressedFormat(format))
3421 		{
3422 			const tcu::TextureFormat	tcuFormat		= mapVkFormat(format);
3423 			const VkFormat				remappedFormat	= mapTextureFormat(tcuFormat);
3424 
3425 			DE_TEST_ASSERT(isValid(tcuFormat));
3426 
3427 			if (fullTextureFormatRoundTripSupported(format))
3428 				DE_TEST_ASSERT(format == remappedFormat);
3429 		}
3430 	}
3431 
3432 	for (int formatNdx = VK_FORMAT_G8B8G8R8_422_UNORM; formatNdx <= VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM; formatNdx++)
3433 	{
3434 		const VkFormat					format	= (VkFormat)formatNdx;
3435 		const PlanarFormatDescription&	info	= getPlanarFormatDescription(format);
3436 
3437 		DE_TEST_ASSERT(isYCbCrFormat(format));
3438 		DE_TEST_ASSERT(de::inRange<deUint8>(info.numPlanes, 1u, 3u));
3439 		DE_TEST_ASSERT(info.numPlanes == getPlaneCount(format));
3440 	}
3441 
3442 	for (int formatNdx = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT; formatNdx <= VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT; formatNdx++)
3443 	{
3444 		const VkFormat					format	= (VkFormat)formatNdx;
3445 		const PlanarFormatDescription&	info	= getPlanarFormatDescription(format);
3446 
3447 		DE_TEST_ASSERT(isYCbCrFormat(format));
3448 		DE_TEST_ASSERT(de::inRange<deUint8>(info.numPlanes, 1u, 3u));
3449 		DE_TEST_ASSERT(info.numPlanes == getPlaneCount(format));
3450 	}
3451 }
3452 
3453 struct CompressedFormatParameters
3454 {
3455 	VkFormat	format;
3456 	deUint32	blockBytes;
3457 	deUint32	blockWidth;
3458 	deUint32	blockHeight;
3459 };
3460 
3461 CompressedFormatParameters	compressedFormatParameters[VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_BC1_RGB_UNORM_BLOCK + 1] =
3462 {
3463 	{ VK_FORMAT_BC1_RGB_UNORM_BLOCK,		8,	4,	4 },
3464 	{ VK_FORMAT_BC1_RGB_SRGB_BLOCK,			8,	4,	4 },
3465 	{ VK_FORMAT_BC1_RGBA_UNORM_BLOCK,		8,	4,	4 },
3466 	{ VK_FORMAT_BC1_RGBA_SRGB_BLOCK,		8,	4,	4 },
3467 	{ VK_FORMAT_BC2_UNORM_BLOCK,			16,	4,	4 },
3468 	{ VK_FORMAT_BC2_SRGB_BLOCK,				16,	4,	4 },
3469 	{ VK_FORMAT_BC3_UNORM_BLOCK,			16,	4,	4 },
3470 	{ VK_FORMAT_BC3_SRGB_BLOCK,				16,	4,	4 },
3471 	{ VK_FORMAT_BC4_UNORM_BLOCK,			8,	4,	4 },
3472 	{ VK_FORMAT_BC4_SNORM_BLOCK,			8,	4,	4 },
3473 	{ VK_FORMAT_BC5_UNORM_BLOCK,			16,	4,	4 },
3474 	{ VK_FORMAT_BC5_SNORM_BLOCK,			16,	4,	4 },
3475 	{ VK_FORMAT_BC6H_UFLOAT_BLOCK,			16,	4,	4 },
3476 	{ VK_FORMAT_BC6H_SFLOAT_BLOCK,			16,	4,	4 },
3477 	{ VK_FORMAT_BC7_UNORM_BLOCK,			16,	4,	4 },
3478 	{ VK_FORMAT_BC7_SRGB_BLOCK,				16,	4,	4 },
3479 	{ VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,	8,	4,	4 },
3480 	{ VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,		8,	4,	4 },
3481 	{ VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,	8,	4,	4 },
3482 	{ VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,	8,	4,	4 },
3483 	{ VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,	16,	4,	4 },
3484 	{ VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,	16,	4,	4 },
3485 	{ VK_FORMAT_EAC_R11_UNORM_BLOCK,		8,	4,	4 },
3486 	{ VK_FORMAT_EAC_R11_SNORM_BLOCK,		8,	4,	4 },
3487 	{ VK_FORMAT_EAC_R11G11_UNORM_BLOCK,		16,	4,	4 },
3488 	{ VK_FORMAT_EAC_R11G11_SNORM_BLOCK,		16,	4,	4 },
3489 	{ VK_FORMAT_ASTC_4x4_UNORM_BLOCK,		16,	4,	4 },
3490 	{ VK_FORMAT_ASTC_4x4_SRGB_BLOCK,		16,	4,	4 },
3491 	{ VK_FORMAT_ASTC_5x4_UNORM_BLOCK,		16,	5,	4 },
3492 	{ VK_FORMAT_ASTC_5x4_SRGB_BLOCK,		16,	5,	4 },
3493 	{ VK_FORMAT_ASTC_5x5_UNORM_BLOCK,		16,	5,	5 },
3494 	{ VK_FORMAT_ASTC_5x5_SRGB_BLOCK,		16,	5,	5 },
3495 	{ VK_FORMAT_ASTC_6x5_UNORM_BLOCK,		16,	6,	5 },
3496 	{ VK_FORMAT_ASTC_6x5_SRGB_BLOCK,		16,	6,	5 },
3497 	{ VK_FORMAT_ASTC_6x6_UNORM_BLOCK,		16,	6,	6 },
3498 	{ VK_FORMAT_ASTC_6x6_SRGB_BLOCK,		16,	6,	6 },
3499 	{ VK_FORMAT_ASTC_8x5_UNORM_BLOCK,		16,	8,	5 },
3500 	{ VK_FORMAT_ASTC_8x5_SRGB_BLOCK,		16,	8,	5 },
3501 	{ VK_FORMAT_ASTC_8x6_UNORM_BLOCK,		16,	8,	6 },
3502 	{ VK_FORMAT_ASTC_8x6_SRGB_BLOCK,		16,	8,	6 },
3503 	{ VK_FORMAT_ASTC_8x8_UNORM_BLOCK,		16,	8,	8 },
3504 	{ VK_FORMAT_ASTC_8x8_SRGB_BLOCK,		16,	8,	8 },
3505 	{ VK_FORMAT_ASTC_10x5_UNORM_BLOCK,		16,	10,	5 },
3506 	{ VK_FORMAT_ASTC_10x5_SRGB_BLOCK,		16,	10,	5 },
3507 	{ VK_FORMAT_ASTC_10x6_UNORM_BLOCK,		16,	10,	6 },
3508 	{ VK_FORMAT_ASTC_10x6_SRGB_BLOCK,		16,	10,	6 },
3509 	{ VK_FORMAT_ASTC_10x8_UNORM_BLOCK,		16,	10,	8 },
3510 	{ VK_FORMAT_ASTC_10x8_SRGB_BLOCK,		16,	10,	8 },
3511 	{ VK_FORMAT_ASTC_10x10_UNORM_BLOCK,		16,	10,	10 },
3512 	{ VK_FORMAT_ASTC_10x10_SRGB_BLOCK,		16,	10,	10 },
3513 	{ VK_FORMAT_ASTC_12x10_UNORM_BLOCK,		16,	12,	10 },
3514 	{ VK_FORMAT_ASTC_12x10_SRGB_BLOCK,		16,	12,	10 },
3515 	{ VK_FORMAT_ASTC_12x12_UNORM_BLOCK,		16,	12,	12 },
3516 	{ VK_FORMAT_ASTC_12x12_SRGB_BLOCK,		16,	12,	12 }
3517 };
3518 
getFormatComponentWidth(const VkFormat format,const deUint32 componentNdx)3519 deUint32 getFormatComponentWidth (const VkFormat format, const deUint32 componentNdx)
3520 {
3521 	const tcu::TextureFormat	tcuFormat		(mapVkFormat(format));
3522 	const deUint32				componentCount	(tcu::getNumUsedChannels(tcuFormat.order));
3523 
3524 	if (componentNdx >= componentCount)
3525 		DE_FATAL("Component index out of range");
3526 	else
3527 	{
3528 		switch (tcuFormat.type)
3529 		{
3530 			case tcu::TextureFormat::UNORM_INT8:
3531 			case tcu::TextureFormat::SNORM_INT8:
3532 			case tcu::TextureFormat::UNSIGNED_INT8:
3533 			case tcu::TextureFormat::SIGNED_INT8:
3534 				return 8;
3535 
3536 			case tcu::TextureFormat::UNORM_SHORT_12:
3537 				return 12;
3538 
3539 			case tcu::TextureFormat::UNORM_INT16:
3540 			case tcu::TextureFormat::SNORM_INT16:
3541 			case tcu::TextureFormat::UNSIGNED_INT16:
3542 			case tcu::TextureFormat::SIGNED_INT16:
3543 				return 16;
3544 
3545 			case tcu::TextureFormat::UNORM_INT24:
3546 			case tcu::TextureFormat::UNSIGNED_INT24:
3547 				return 24;
3548 
3549 			case tcu::TextureFormat::UNORM_INT32:
3550 			case tcu::TextureFormat::SNORM_INT32:
3551 			case tcu::TextureFormat::UNSIGNED_INT32:
3552 			case tcu::TextureFormat::SIGNED_INT32:
3553 			case tcu::TextureFormat::FLOAT:
3554 				return 32;
3555 
3556 			case tcu::TextureFormat::FLOAT64:
3557 			case tcu::TextureFormat::UNSIGNED_INT64:
3558 			case tcu::TextureFormat::SIGNED_INT64:
3559 				return 64;
3560 
3561 			// Packed formats
3562 			case tcu::TextureFormat::UNORM_SHORT_4444:
3563 			case tcu::TextureFormat::UNSIGNED_SHORT_4444:
3564 				return 4;
3565 
3566 			case tcu::TextureFormat::UNORM_SHORT_565:
3567 			case tcu::TextureFormat::UNSIGNED_SHORT_565:
3568 				return (componentNdx == 1 ? 6 : 5);
3569 
3570 			case tcu::TextureFormat::UNSIGNED_INT_24_8:
3571 			case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
3572 			case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
3573 				return (componentNdx == 0 ? 24 : 8);
3574 
3575 			case tcu::TextureFormat::UNORM_SHORT_1555:
3576 				return (componentNdx == 0 ? 1 : 5);
3577 
3578 			case tcu::TextureFormat::UNORM_INT_1010102_REV:
3579 			case tcu::TextureFormat::SNORM_INT_1010102_REV:
3580 			case tcu::TextureFormat::UNSIGNED_INT_1010102_REV:
3581 			case tcu::TextureFormat::SIGNED_INT_1010102_REV:
3582 				return (componentNdx == 3 ? 2 : 10);
3583 
3584 			default:
3585 				DE_FATAL("Format unimplemented");
3586 		}
3587 	}
3588 
3589 	return 0;
3590 }
3591 
getRepresentableDiffUnorm(const VkFormat format,const deUint32 componentNdx)3592 float getRepresentableDiffUnorm (const VkFormat format, const deUint32 componentNdx)
3593 {
3594 	const deUint32 size (getFormatComponentWidth(format, componentNdx));
3595 
3596 	return 1.0f / float((1 << (size)) - 1);
3597 }
3598 
getRepresentableDiffSnorm(const VkFormat format,const deUint32 componentNdx)3599 float getRepresentableDiffSnorm (const VkFormat format, const deUint32 componentNdx)
3600 {
3601 	const deUint32 size (getFormatComponentWidth(format, componentNdx));
3602 
3603 	return 1.0f / float((1 << (size - 1)) - 1);
3604 }
3605 
getBlockSizeInBytes(const VkFormat compressedFormat)3606 deUint32 getBlockSizeInBytes (const VkFormat compressedFormat)
3607 {
3608 	deUint32 formatNdx = static_cast<deUint32>(compressedFormat - VK_FORMAT_BC1_RGB_UNORM_BLOCK);
3609 
3610 	DE_ASSERT(deInRange32(formatNdx, 0, DE_LENGTH_OF_ARRAY(compressedFormatParameters)));
3611 	DE_ASSERT(compressedFormatParameters[formatNdx].format == compressedFormat);
3612 
3613 	return compressedFormatParameters[formatNdx].blockBytes;
3614 }
3615 
getBlockWidth(const VkFormat compressedFormat)3616 deUint32 getBlockWidth (const VkFormat compressedFormat)
3617 {
3618 	deUint32 formatNdx = static_cast<deUint32>(compressedFormat - VK_FORMAT_BC1_RGB_UNORM_BLOCK);
3619 
3620 	DE_ASSERT(deInRange32(formatNdx, 0, DE_LENGTH_OF_ARRAY(compressedFormatParameters)));
3621 	DE_ASSERT(compressedFormatParameters[formatNdx].format == compressedFormat);
3622 
3623 	return compressedFormatParameters[formatNdx].blockWidth;
3624 }
3625 
getBlockHeight(const VkFormat compressedFormat)3626 deUint32 getBlockHeight (const VkFormat compressedFormat)
3627 {
3628 	deUint32 formatNdx = static_cast<deUint32>(compressedFormat - VK_FORMAT_BC1_RGB_UNORM_BLOCK);
3629 
3630 	DE_ASSERT(deInRange32(formatNdx, 0, DE_LENGTH_OF_ARRAY(compressedFormatParameters)));
3631 	DE_ASSERT(compressedFormatParameters[formatNdx].format == compressedFormat);
3632 
3633 	return compressedFormatParameters[formatNdx].blockHeight;
3634 }
3635 
mapFilterMode(tcu::Sampler::FilterMode filterMode)3636 VkFilter mapFilterMode (tcu::Sampler::FilterMode filterMode)
3637 {
3638 	DE_STATIC_ASSERT(tcu::Sampler::FILTERMODE_LAST == 9);
3639 
3640 	switch (filterMode)
3641 	{
3642 		case tcu::Sampler::NEAREST:					return VK_FILTER_NEAREST;
3643 		case tcu::Sampler::LINEAR:					return VK_FILTER_LINEAR;
3644 		case tcu::Sampler::CUBIC:					return VK_FILTER_CUBIC_EXT;
3645 		case tcu::Sampler::NEAREST_MIPMAP_NEAREST:	return VK_FILTER_NEAREST;
3646 		case tcu::Sampler::NEAREST_MIPMAP_LINEAR:	return VK_FILTER_NEAREST;
3647 		case tcu::Sampler::LINEAR_MIPMAP_NEAREST:	return VK_FILTER_LINEAR;
3648 		case tcu::Sampler::LINEAR_MIPMAP_LINEAR:	return VK_FILTER_LINEAR;
3649 		case tcu::Sampler::CUBIC_MIPMAP_NEAREST:	return VK_FILTER_CUBIC_EXT;
3650 		case tcu::Sampler::CUBIC_MIPMAP_LINEAR:		return VK_FILTER_CUBIC_EXT;
3651 		default:
3652 			DE_FATAL("Illegal filter mode");
3653 			return (VkFilter)0;
3654 	}
3655 }
3656 
mapMipmapMode(tcu::Sampler::FilterMode filterMode)3657 VkSamplerMipmapMode mapMipmapMode (tcu::Sampler::FilterMode filterMode)
3658 {
3659 	DE_STATIC_ASSERT(tcu::Sampler::FILTERMODE_LAST == 9);
3660 
3661 	// \note VkSamplerCreateInfo doesn't have a flag for disabling mipmapping. Instead
3662 	//		 minLod = 0 and maxLod = 0.25 should be used to match OpenGL NEAREST and LINEAR
3663 	//		 filtering mode behavior.
3664 
3665 	switch (filterMode)
3666 	{
3667 		case tcu::Sampler::NEAREST:					return VK_SAMPLER_MIPMAP_MODE_NEAREST;
3668 		case tcu::Sampler::LINEAR:					return VK_SAMPLER_MIPMAP_MODE_NEAREST;
3669 		case tcu::Sampler::CUBIC:					return VK_SAMPLER_MIPMAP_MODE_NEAREST;
3670 		case tcu::Sampler::NEAREST_MIPMAP_NEAREST:	return VK_SAMPLER_MIPMAP_MODE_NEAREST;
3671 		case tcu::Sampler::NEAREST_MIPMAP_LINEAR:	return VK_SAMPLER_MIPMAP_MODE_LINEAR;
3672 		case tcu::Sampler::LINEAR_MIPMAP_NEAREST:	return VK_SAMPLER_MIPMAP_MODE_NEAREST;
3673 		case tcu::Sampler::LINEAR_MIPMAP_LINEAR:	return VK_SAMPLER_MIPMAP_MODE_LINEAR;
3674 		case tcu::Sampler::CUBIC_MIPMAP_NEAREST:	return VK_SAMPLER_MIPMAP_MODE_NEAREST;
3675 		case tcu::Sampler::CUBIC_MIPMAP_LINEAR:		return VK_SAMPLER_MIPMAP_MODE_LINEAR;
3676 		default:
3677 			DE_FATAL("Illegal filter mode");
3678 			return (VkSamplerMipmapMode)0;
3679 	}
3680 }
3681 
mapWrapMode(tcu::Sampler::WrapMode wrapMode)3682 VkSamplerAddressMode mapWrapMode (tcu::Sampler::WrapMode wrapMode)
3683 {
3684 	switch (wrapMode)
3685 	{
3686 		case tcu::Sampler::CLAMP_TO_EDGE:		return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
3687 		case tcu::Sampler::CLAMP_TO_BORDER:		return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
3688 		case tcu::Sampler::REPEAT_GL:			return VK_SAMPLER_ADDRESS_MODE_REPEAT;
3689 		case tcu::Sampler::MIRRORED_REPEAT_GL:	return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
3690 		case tcu::Sampler::MIRRORED_ONCE:		return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
3691 		default:
3692 			DE_FATAL("Wrap mode can't be mapped to Vulkan");
3693 			return (vk::VkSamplerAddressMode)0;
3694 	}
3695 }
3696 
mapCompareMode(tcu::Sampler::CompareMode mode)3697 vk::VkCompareOp mapCompareMode (tcu::Sampler::CompareMode mode)
3698 {
3699 	switch (mode)
3700 	{
3701 		case tcu::Sampler::COMPAREMODE_NONE:				return vk::VK_COMPARE_OP_NEVER;
3702 		case tcu::Sampler::COMPAREMODE_LESS:				return vk::VK_COMPARE_OP_LESS;
3703 		case tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL:		return vk::VK_COMPARE_OP_LESS_OR_EQUAL;
3704 		case tcu::Sampler::COMPAREMODE_GREATER:				return vk::VK_COMPARE_OP_GREATER;
3705 		case tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL:	return vk::VK_COMPARE_OP_GREATER_OR_EQUAL;
3706 		case tcu::Sampler::COMPAREMODE_EQUAL:				return vk::VK_COMPARE_OP_EQUAL;
3707 		case tcu::Sampler::COMPAREMODE_NOT_EQUAL:			return vk::VK_COMPARE_OP_NOT_EQUAL;
3708 		case tcu::Sampler::COMPAREMODE_ALWAYS:				return vk::VK_COMPARE_OP_ALWAYS;
3709 		case tcu::Sampler::COMPAREMODE_NEVER:				return vk::VK_COMPARE_OP_NEVER;
3710 		default:
3711 			DE_FATAL("Illegal compare mode");
3712 			return (vk::VkCompareOp)0;
3713 	}
3714 }
3715 
mapBorderColor(tcu::TextureChannelClass channelClass,const rr::GenericVec4 & color)3716 static VkBorderColor mapBorderColor (tcu::TextureChannelClass channelClass, const rr::GenericVec4& color)
3717 {
3718 	if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
3719 	{
3720 		const tcu::UVec4	uColor	= color.get<deUint32>();
3721 
3722 		if (uColor		== tcu::UVec4(0, 0, 0, 0)) return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
3723 		else if (uColor	== tcu::UVec4(0, 0, 0, 1)) return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
3724 		else if (uColor == tcu::UVec4(1, 1, 1, 1)) return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
3725 		else									   return VK_BORDER_COLOR_INT_CUSTOM_EXT;
3726 	}
3727 	else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
3728 	{
3729 		const tcu::IVec4	sColor	= color.get<deInt32>();
3730 
3731 		if (sColor		== tcu::IVec4(0, 0, 0, 0)) return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
3732 		else if (sColor	== tcu::IVec4(0, 0, 0, 1)) return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
3733 		else if (sColor == tcu::IVec4(1, 1, 1, 1)) return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
3734 		else									   return	VK_BORDER_COLOR_INT_CUSTOM_EXT;
3735 	}
3736 	else
3737 	{
3738 		const tcu::Vec4		fColor	= color.get<float>();
3739 
3740 		if (fColor		== tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)) return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
3741 		else if (fColor == tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)) return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
3742 		else if (fColor == tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)) return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
3743 		else												  return VK_BORDER_COLOR_FLOAT_CUSTOM_EXT;
3744 	}
3745 
3746 	DE_FATAL("Unsupported border color");
3747 	return VK_BORDER_COLOR_MAX_ENUM;
3748 }
3749 
mapSampler(const tcu::Sampler & sampler,const tcu::TextureFormat & format,float minLod,float maxLod,bool unnormal)3750 VkSamplerCreateInfo mapSampler (const tcu::Sampler& sampler, const tcu::TextureFormat& format, float minLod, float maxLod, bool unnormal)
3751 {
3752 	const bool			compareEnabled	= (sampler.compare != tcu::Sampler::COMPAREMODE_NONE);
3753 	const VkCompareOp	compareOp		= (compareEnabled) ? (mapCompareMode(sampler.compare)) : (VK_COMPARE_OP_ALWAYS);
3754 	const VkBorderColor	borderColor		= mapBorderColor(getTextureChannelClass(format.type), sampler.borderColor);
3755 	const bool			isMipmapEnabled = (sampler.minFilter != tcu::Sampler::NEAREST && sampler.minFilter != tcu::Sampler::LINEAR && sampler.minFilter != tcu::Sampler::CUBIC);
3756 
3757 	const VkSamplerCreateInfo	createInfo		=
3758 	{
3759 		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
3760 		DE_NULL,
3761 		(VkSamplerCreateFlags)0,
3762 		mapFilterMode(sampler.magFilter),							// magFilter
3763 		mapFilterMode(sampler.minFilter),							// minFilter
3764 		mapMipmapMode(sampler.minFilter),							// mipMode
3765 		mapWrapMode(sampler.wrapS),									// addressU
3766 		mapWrapMode(sampler.wrapT),									// addressV
3767 		mapWrapMode(sampler.wrapR),									// addressW
3768 		0.0f,														// mipLodBias
3769 		VK_FALSE,													// anisotropyEnable
3770 		1.0f,														// maxAnisotropy
3771 		(VkBool32)(compareEnabled ? VK_TRUE : VK_FALSE),			// compareEnable
3772 		compareOp,													// compareOp
3773 		(isMipmapEnabled ? minLod : 0.0f),							// minLod
3774 		(isMipmapEnabled ? maxLod : (unnormal ? 0.0f : 0.25f)),		// maxLod
3775 		borderColor,												// borderColor
3776 		(VkBool32)(sampler.normalizedCoords ? VK_FALSE : VK_TRUE),	// unnormalizedCoords
3777 	};
3778 
3779 	return createInfo;
3780 }
3781 
mapVkColor(const VkClearColorValue & color)3782 rr::GenericVec4 mapVkColor (const VkClearColorValue& color)
3783 {
3784 	rr::GenericVec4 value;
3785 
3786 	static_assert(sizeof(rr::GenericVec4) == sizeof(VkClearColorValue), "GenericVec4 and VkClearColorValue size mismatch");
3787 	deMemcpy(&value, &color, sizeof(rr::GenericVec4));
3788 	return value;
3789 }
3790 
mapVkColor(const rr::GenericVec4 & color)3791 VkClearColorValue mapVkColor(const rr::GenericVec4& color)
3792 {
3793 	VkClearColorValue value;
3794 
3795 	static_assert(sizeof(rr::GenericVec4) == sizeof(VkClearColorValue), "GenericVec4 and VkClearColorValue size mismatch");
3796 	deMemcpy(&value, &color, sizeof(VkClearColorValue));
3797 	return value;
3798 }
3799 
mapVkSampler(const VkSamplerCreateInfo & samplerCreateInfo)3800 tcu::Sampler mapVkSampler (const VkSamplerCreateInfo& samplerCreateInfo)
3801 {
3802 	// \note minLod & maxLod are not supported by tcu::Sampler. LOD must be clamped
3803 	//       before passing it to tcu::Texture*::sample*()
3804 
3805 	tcu::Sampler::ReductionMode reductionMode = tcu::Sampler::WEIGHTED_AVERAGE;
3806 	rr::GenericVec4 borderColorValue;
3807 
3808 	void const *pNext = samplerCreateInfo.pNext;
3809 	while (pNext != DE_NULL)
3810 	{
3811 		const VkStructureType nextType = *reinterpret_cast<const VkStructureType*>(pNext);
3812 		switch (nextType)
3813 		{
3814 			case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO:
3815 			{
3816 				const VkSamplerReductionModeCreateInfo reductionModeCreateInfo = *reinterpret_cast<const VkSamplerReductionModeCreateInfo*>(pNext);
3817 				reductionMode = mapVkSamplerReductionMode(reductionModeCreateInfo.reductionMode);
3818 				pNext = reinterpret_cast<const VkSamplerReductionModeCreateInfo*>(pNext)->pNext;
3819 				break;
3820 			}
3821 			case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
3822 				pNext = reinterpret_cast<const VkSamplerYcbcrConversionInfo*>(pNext)->pNext;
3823 				break;
3824 			case VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT:
3825 			{
3826 				const VkSamplerCustomBorderColorCreateInfoEXT customBorderColorCreateInfo = *reinterpret_cast<const VkSamplerCustomBorderColorCreateInfoEXT*>(pNext);
3827 				borderColorValue = mapVkColor(customBorderColorCreateInfo.customBorderColor);
3828 				pNext = reinterpret_cast<const VkSamplerCustomBorderColorCreateInfoEXT*>(pNext)->pNext;
3829 				break;
3830 			}
3831 			default:
3832 				TCU_FAIL("Unrecognized sType in chained sampler create info");
3833 		}
3834 	}
3835 
3836 
3837 
3838 	tcu::Sampler sampler(mapVkSamplerAddressMode(samplerCreateInfo.addressModeU),
3839 						 mapVkSamplerAddressMode(samplerCreateInfo.addressModeV),
3840 						 mapVkSamplerAddressMode(samplerCreateInfo.addressModeW),
3841 						 mapVkMinTexFilter(samplerCreateInfo.minFilter, samplerCreateInfo.mipmapMode),
3842 						 mapVkMagTexFilter(samplerCreateInfo.magFilter),
3843 						 0.0f,
3844 						 !samplerCreateInfo.unnormalizedCoordinates,
3845 						 samplerCreateInfo.compareEnable ? mapVkSamplerCompareOp(samplerCreateInfo.compareOp)
3846 														 : tcu::Sampler::COMPAREMODE_NONE,
3847 						 0,
3848 						 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
3849 						 true,
3850 						 tcu::Sampler::MODE_DEPTH,
3851 						 reductionMode);
3852 
3853 	if (samplerCreateInfo.anisotropyEnable)
3854 		TCU_THROW(InternalError, "Anisotropic filtering is not supported by tcu::Sampler");
3855 
3856 	switch (samplerCreateInfo.borderColor)
3857 	{
3858 		case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
3859 			sampler.borderColor = tcu::UVec4(0,0,0,1);
3860 			break;
3861 		case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
3862 			sampler.borderColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
3863 			break;
3864 		case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
3865 			sampler.borderColor = tcu::UVec4(1, 1, 1, 1);
3866 			break;
3867 		case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
3868 			sampler.borderColor = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
3869 			break;
3870 		case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
3871 			sampler.borderColor = tcu::UVec4(0,0,0,0);
3872 			break;
3873 		case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
3874 			sampler.borderColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
3875 			break;
3876 		case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT:
3877 		case VK_BORDER_COLOR_INT_CUSTOM_EXT:
3878 			sampler.borderColor = borderColorValue;
3879 			break;
3880 
3881 		default:
3882 			DE_ASSERT(false);
3883 			break;
3884 	}
3885 
3886 	return sampler;
3887 }
3888 
mapVkSamplerCompareOp(VkCompareOp compareOp)3889 tcu::Sampler::CompareMode mapVkSamplerCompareOp (VkCompareOp compareOp)
3890 {
3891 	switch (compareOp)
3892 	{
3893 		case VK_COMPARE_OP_NEVER:				return tcu::Sampler::COMPAREMODE_NEVER;
3894 		case VK_COMPARE_OP_LESS:				return tcu::Sampler::COMPAREMODE_LESS;
3895 		case VK_COMPARE_OP_EQUAL:				return tcu::Sampler::COMPAREMODE_EQUAL;
3896 		case VK_COMPARE_OP_LESS_OR_EQUAL:		return tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL;
3897 		case VK_COMPARE_OP_GREATER:				return tcu::Sampler::COMPAREMODE_GREATER;
3898 		case VK_COMPARE_OP_NOT_EQUAL:			return tcu::Sampler::COMPAREMODE_NOT_EQUAL;
3899 		case VK_COMPARE_OP_GREATER_OR_EQUAL:	return tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL;
3900 		case VK_COMPARE_OP_ALWAYS:				return tcu::Sampler::COMPAREMODE_ALWAYS;
3901 		default:
3902 			break;
3903 	}
3904 
3905 	DE_ASSERT(false);
3906 	return tcu::Sampler::COMPAREMODE_LAST;
3907 }
3908 
mapVkSamplerAddressMode(VkSamplerAddressMode addressMode)3909 tcu::Sampler::WrapMode mapVkSamplerAddressMode (VkSamplerAddressMode addressMode)
3910 {
3911 	switch (addressMode)
3912 	{
3913 		case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:			return tcu::Sampler::CLAMP_TO_EDGE;
3914 		case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:		return tcu::Sampler::CLAMP_TO_BORDER;
3915 		case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:		return tcu::Sampler::MIRRORED_REPEAT_GL;
3916 		case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:	return tcu::Sampler::MIRRORED_ONCE;
3917 		case VK_SAMPLER_ADDRESS_MODE_REPEAT:				return tcu::Sampler::REPEAT_GL;
3918 		default:
3919 			break;
3920 	}
3921 
3922 	DE_ASSERT(false);
3923 	return tcu::Sampler::WRAPMODE_LAST;
3924 }
3925 
mapVkSamplerReductionMode(VkSamplerReductionMode reductionMode)3926 tcu::Sampler::ReductionMode mapVkSamplerReductionMode (VkSamplerReductionMode reductionMode)
3927 {
3928 	switch (reductionMode)
3929 	{
3930 		case VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE:	return tcu::Sampler::WEIGHTED_AVERAGE;
3931 		case VK_SAMPLER_REDUCTION_MODE_MIN:					return tcu::Sampler::MIN;
3932 		case VK_SAMPLER_REDUCTION_MODE_MAX:					return tcu::Sampler::MAX;
3933 		default:
3934 			break;
3935 	}
3936 
3937 	DE_ASSERT(false);
3938 	return tcu::Sampler::REDUCTIONMODE_LAST;
3939 }
3940 
mapVkMinTexFilter(VkFilter filter,VkSamplerMipmapMode mipMode)3941 tcu::Sampler::FilterMode mapVkMinTexFilter (VkFilter filter, VkSamplerMipmapMode mipMode)
3942 {
3943 	switch (filter)
3944 	{
3945 		case VK_FILTER_LINEAR:
3946 			switch (mipMode)
3947 			{
3948 				case VK_SAMPLER_MIPMAP_MODE_LINEAR:		return tcu::Sampler::LINEAR_MIPMAP_LINEAR;
3949 				case VK_SAMPLER_MIPMAP_MODE_NEAREST:	return tcu::Sampler::LINEAR_MIPMAP_NEAREST;
3950 				default:
3951 					break;
3952 			}
3953 			break;
3954 
3955 		case VK_FILTER_NEAREST:
3956 			switch (mipMode)
3957 			{
3958 				case VK_SAMPLER_MIPMAP_MODE_LINEAR:		return tcu::Sampler::NEAREST_MIPMAP_LINEAR;
3959 				case VK_SAMPLER_MIPMAP_MODE_NEAREST:	return tcu::Sampler::NEAREST_MIPMAP_NEAREST;
3960 				default:
3961 					break;
3962 			}
3963 			break;
3964 		case VK_FILTER_CUBIC_EXT:
3965 			switch (mipMode)
3966 			{
3967 			case VK_SAMPLER_MIPMAP_MODE_LINEAR:		return tcu::Sampler::CUBIC_MIPMAP_LINEAR;
3968 			case VK_SAMPLER_MIPMAP_MODE_NEAREST:	return tcu::Sampler::CUBIC_MIPMAP_NEAREST;
3969 			default:
3970 				break;
3971 			}
3972 			break;
3973 
3974 		default:
3975 			break;
3976 	}
3977 
3978 	DE_ASSERT(false);
3979 	return tcu::Sampler::FILTERMODE_LAST;
3980 }
3981 
mapVkMagTexFilter(VkFilter filter)3982 tcu::Sampler::FilterMode mapVkMagTexFilter (VkFilter filter)
3983 {
3984 	switch (filter)
3985 	{
3986 		case VK_FILTER_LINEAR:		return tcu::Sampler::LINEAR;
3987 		case VK_FILTER_NEAREST:		return tcu::Sampler::NEAREST;
3988 		case VK_FILTER_CUBIC_EXT:	return tcu::Sampler::CUBIC;
3989 		default:
3990 			break;
3991 	}
3992 
3993 	DE_ASSERT(false);
3994 	return tcu::Sampler::FILTERMODE_LAST;
3995 }
3996 
3997 //! Get a format that matches the layout in buffer memory used for a
3998 //! buffer<->image copy on a depth/stencil format.
getDepthCopyFormat(VkFormat combinedFormat)3999 tcu::TextureFormat getDepthCopyFormat (VkFormat combinedFormat)
4000 {
4001 	switch (combinedFormat)
4002 	{
4003 		case VK_FORMAT_D16_UNORM:
4004 		case VK_FORMAT_X8_D24_UNORM_PACK32:
4005 		case VK_FORMAT_D32_SFLOAT:
4006 			return mapVkFormat(combinedFormat);
4007 
4008 		case VK_FORMAT_D16_UNORM_S8_UINT:
4009 			return mapVkFormat(VK_FORMAT_D16_UNORM);
4010 		case VK_FORMAT_D24_UNORM_S8_UINT:
4011 			return mapVkFormat(VK_FORMAT_X8_D24_UNORM_PACK32);
4012 		case VK_FORMAT_D32_SFLOAT_S8_UINT:
4013 			return mapVkFormat(VK_FORMAT_D32_SFLOAT);
4014 
4015 		case VK_FORMAT_S8_UINT:
4016 		default:
4017 			DE_FATAL("Unexpected depth/stencil format");
4018 			return tcu::TextureFormat();
4019 	}
4020 }
4021 
4022 //! Get a format that matches the layout in buffer memory used for a
4023 //! buffer<->image copy on a depth/stencil format.
getStencilCopyFormat(VkFormat combinedFormat)4024 tcu::TextureFormat getStencilCopyFormat (VkFormat combinedFormat)
4025 {
4026 	switch (combinedFormat)
4027 	{
4028 		case VK_FORMAT_D16_UNORM_S8_UINT:
4029 		case VK_FORMAT_D24_UNORM_S8_UINT:
4030 		case VK_FORMAT_D32_SFLOAT_S8_UINT:
4031 		case VK_FORMAT_S8_UINT:
4032 			return mapVkFormat(VK_FORMAT_S8_UINT);
4033 
4034 		case VK_FORMAT_D16_UNORM:
4035 		case VK_FORMAT_X8_D24_UNORM_PACK32:
4036 		case VK_FORMAT_D32_SFLOAT:
4037 		default:
4038 			DE_FATAL("Unexpected depth/stencil format");
4039 			return tcu::TextureFormat();
4040 	}
4041 }
4042 
getImageAspectFlags(const tcu::TextureFormat textureFormat)4043 VkImageAspectFlags getImageAspectFlags (const tcu::TextureFormat textureFormat)
4044 {
4045 	VkImageAspectFlags imageAspectFlags = 0;
4046 
4047 	if (tcu::hasDepthComponent(textureFormat.order))
4048 		imageAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
4049 
4050 	if (tcu::hasStencilComponent(textureFormat.order))
4051 		imageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
4052 
4053 	if (imageAspectFlags == 0)
4054 		imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
4055 
4056 	return imageAspectFlags;
4057 }
4058 
mipLevelExtents(const VkExtent3D & baseExtents,const deUint32 mipLevel)4059 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel)
4060 {
4061 	VkExtent3D result;
4062 
4063 	result.width	= std::max(baseExtents.width >> mipLevel, 1u);
4064 	result.height	= std::max(baseExtents.height >> mipLevel, 1u);
4065 	result.depth	= std::max(baseExtents.depth >> mipLevel, 1u);
4066 
4067 	return result;
4068 }
4069 
alignedDivide(const VkExtent3D & extent,const VkExtent3D & divisor)4070 tcu::UVec3 alignedDivide (const VkExtent3D& extent, const VkExtent3D& divisor)
4071 {
4072 	tcu::UVec3 result;
4073 
4074 	result.x() = extent.width  / divisor.width  + ((extent.width  % divisor.width != 0)  ? 1u : 0u);
4075 	result.y() = extent.height / divisor.height + ((extent.height % divisor.height != 0) ? 1u : 0u);
4076 	result.z() = extent.depth  / divisor.depth  + ((extent.depth  % divisor.depth != 0)  ? 1u : 0u);
4077 
4078 	return result;
4079 }
4080 
copyBufferToImage(const DeviceInterface & vk,const VkCommandBuffer & cmdBuffer,const VkBuffer & buffer,VkDeviceSize bufferSize,const std::vector<VkBufferImageCopy> & copyRegions,VkImageAspectFlags imageAspectFlags,deUint32 mipLevels,deUint32 arrayLayers,VkImage destImage,VkImageLayout destImageLayout,VkPipelineStageFlags destImageDstStageFlags)4081 void copyBufferToImage (const DeviceInterface&					vk,
4082 						const VkCommandBuffer&					cmdBuffer,
4083 						const VkBuffer&							buffer,
4084 						VkDeviceSize							bufferSize,
4085 						const std::vector<VkBufferImageCopy>&	copyRegions,
4086 						VkImageAspectFlags						imageAspectFlags,
4087 						deUint32								mipLevels,
4088 						deUint32								arrayLayers,
4089 						VkImage									destImage,
4090 						VkImageLayout							destImageLayout,
4091 						VkPipelineStageFlags					destImageDstStageFlags)
4092 {
4093 	// Barriers for copying buffer to image
4094 	const VkBufferMemoryBarrier preBufferBarrier =
4095 	{
4096 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
4097 		DE_NULL,									// const void*		pNext;
4098 		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
4099 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
4100 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
4101 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
4102 		buffer,										// VkBuffer			buffer;
4103 		0u,											// VkDeviceSize		offset;
4104 		bufferSize									// VkDeviceSize		size;
4105 	};
4106 
4107 	const VkImageMemoryBarrier preImageBarrier =
4108 	{
4109 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
4110 		DE_NULL,										// const void*				pNext;
4111 		0u,												// VkAccessFlags			srcAccessMask;
4112 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
4113 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
4114 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
4115 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
4116 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
4117 		destImage,										// VkImage					image;
4118 		{												// VkImageSubresourceRange	subresourceRange;
4119 			imageAspectFlags,							// VkImageAspectFlags		aspect;
4120 			0u,											// deUint32					baseMipLevel;
4121 			mipLevels,									// deUint32					mipLevels;
4122 			0u,											// deUint32					baseArraySlice;
4123 			arrayLayers									// deUint32					arraySize;
4124 		}
4125 	};
4126 
4127 	const VkImageMemoryBarrier postImageBarrier =
4128 	{
4129 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
4130 		DE_NULL,										// const void*				pNext;
4131 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
4132 		VK_ACCESS_SHADER_READ_BIT,						// VkAccessFlags			dstAccessMask;
4133 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
4134 		destImageLayout,								// VkImageLayout			newLayout;
4135 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
4136 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
4137 		destImage,										// VkImage					image;
4138 		{												// VkImageSubresourceRange	subresourceRange;
4139 			imageAspectFlags,							// VkImageAspectFlags		aspect;
4140 			0u,											// deUint32					baseMipLevel;
4141 			mipLevels,									// deUint32					mipLevels;
4142 			0u,											// deUint32					baseArraySlice;
4143 			arrayLayers									// deUint32					arraySize;
4144 		}
4145 	};
4146 
4147 	// Copy buffer to image
4148 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
4149 	vk.cmdCopyBufferToImage(cmdBuffer, buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
4150 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, destImageDstStageFlags, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
4151 }
4152 
copyBufferToImage(const DeviceInterface & vk,VkDevice device,VkQueue queue,deUint32 queueFamilyIndex,const VkBuffer & buffer,VkDeviceSize bufferSize,const std::vector<VkBufferImageCopy> & copyRegions,const VkSemaphore * waitSemaphore,VkImageAspectFlags imageAspectFlags,deUint32 mipLevels,deUint32 arrayLayers,VkImage destImage,VkImageLayout destImageLayout,VkPipelineStageFlags destImageDstStageFlags)4153 void copyBufferToImage (const DeviceInterface&					vk,
4154 						VkDevice								device,
4155 						VkQueue									queue,
4156 						deUint32								queueFamilyIndex,
4157 						const VkBuffer&							buffer,
4158 						VkDeviceSize							bufferSize,
4159 						const std::vector<VkBufferImageCopy>&	copyRegions,
4160 						const VkSemaphore*						waitSemaphore,
4161 						VkImageAspectFlags						imageAspectFlags,
4162 						deUint32								mipLevels,
4163 						deUint32								arrayLayers,
4164 						VkImage									destImage,
4165 						VkImageLayout							destImageLayout,
4166 						VkPipelineStageFlags					destImageDstStageFlags)
4167 {
4168 	Move<VkCommandPool>		cmdPool		= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
4169 	Move<VkCommandBuffer>	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4170 	Move<VkFence>			fence		= createFence(vk, device);
4171 
4172 	const VkCommandBufferBeginInfo cmdBufferBeginInfo =
4173 	{
4174 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
4175 		DE_NULL,										// const void*						pNext;
4176 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags		flags;
4177 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
4178 	};
4179 
4180 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
4181 	copyBufferToImage(vk, *cmdBuffer, buffer, bufferSize, copyRegions, imageAspectFlags, mipLevels, arrayLayers, destImage, destImageLayout, destImageDstStageFlags);
4182 	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
4183 
4184 	const VkPipelineStageFlags pipelineStageFlags = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
4185 
4186 	const VkSubmitInfo submitInfo =
4187 	{
4188 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
4189 		DE_NULL,						// const void*					pNext;
4190 		waitSemaphore ? 1u : 0u,		// deUint32						waitSemaphoreCount;
4191 		waitSemaphore,					// const VkSemaphore*			pWaitSemaphores;
4192 		&pipelineStageFlags,			// const VkPipelineStageFlags*	pWaitDstStageMask;
4193 		1u,								// deUint32						commandBufferCount;
4194 		&cmdBuffer.get(),				// const VkCommandBuffer*		pCommandBuffers;
4195 		0u,								// deUint32						signalSemaphoreCount;
4196 		DE_NULL							// const VkSemaphore*			pSignalSemaphores;
4197 	};
4198 
4199 	try
4200 	{
4201 		VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
4202 		VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
4203 	}
4204 	catch (...)
4205 	{
4206 		VK_CHECK(vk.deviceWaitIdle(device));
4207 		throw;
4208 	}
4209 }
4210 
copyImageToBuffer(const DeviceInterface & vk,VkCommandBuffer cmdBuffer,VkImage image,VkBuffer buffer,tcu::IVec2 size,VkAccessFlags srcAccessMask,VkImageLayout oldLayout,deUint32 numLayers,VkImageAspectFlags barrierAspect,VkImageAspectFlags copyAspect)4211 void copyImageToBuffer (const DeviceInterface&	vk,
4212 						VkCommandBuffer			cmdBuffer,
4213 						VkImage					image,
4214 						VkBuffer				buffer,
4215 						tcu::IVec2				size,
4216 						VkAccessFlags			srcAccessMask,
4217 						VkImageLayout			oldLayout,
4218 						deUint32				numLayers,
4219 						VkImageAspectFlags		barrierAspect,
4220 						VkImageAspectFlags		copyAspect)
4221 {
4222 	const VkImageMemoryBarrier	imageBarrier	=
4223 	{
4224 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,							// VkStructureType			sType;
4225 		DE_NULL,														// const void*				pNext;
4226 		srcAccessMask,													// VkAccessFlags			srcAccessMask;
4227 		VK_ACCESS_TRANSFER_READ_BIT,									// VkAccessFlags			dstAccessMask;
4228 		oldLayout,														// VkImageLayout			oldLayout;
4229 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,							// VkImageLayout			newLayout;
4230 		VK_QUEUE_FAMILY_IGNORED,										// deUint32					srcQueueFamilyIndex;
4231 		VK_QUEUE_FAMILY_IGNORED,										// deUint32					destQueueFamilyIndex;
4232 		image,															// VkImage					image;
4233 		makeImageSubresourceRange(barrierAspect, 0u, 1u, 0, numLayers)	// VkImageSubresourceRange	subresourceRange;
4234 	};
4235 
4236 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
4237 						  0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
4238 
4239 	const VkImageSubresourceLayers	subresource	=
4240 	{
4241 		copyAspect,									// VkImageAspectFlags	aspectMask;
4242 		0u,											// deUint32				mipLevel;
4243 		0u,											// deUint32				baseArrayLayer;
4244 		numLayers									// deUint32				layerCount;
4245 	};
4246 
4247 	const VkBufferImageCopy			region		=
4248 	{
4249 		0ull,										// VkDeviceSize					bufferOffset;
4250 		0u,											// deUint32						bufferRowLength;
4251 		0u,											// deUint32						bufferImageHeight;
4252 		subresource,								// VkImageSubresourceLayers		imageSubresource;
4253 		makeOffset3D(0, 0, 0),						// VkOffset3D					imageOffset;
4254 		makeExtent3D(size.x(), size.y(), 1u)		// VkExtent3D					imageExtent;
4255 	};
4256 
4257 	vk.cmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, &region);
4258 
4259 	const VkBufferMemoryBarrier	bufferBarrier =
4260 	{
4261 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
4262 		DE_NULL,									// const void*		pNext;
4263 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
4264 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
4265 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
4266 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
4267 		buffer,										// VkBuffer			buffer;
4268 		0ull,										// VkDeviceSize		offset;
4269 		VK_WHOLE_SIZE								// VkDeviceSize		size;
4270 	};
4271 
4272 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
4273 						  0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
4274 }
4275 
clearColorImage(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,deUint32 queueFamilyIndex,VkImage image,tcu::Vec4 clearColor,VkImageLayout oldLayout,VkImageLayout newLayout,VkPipelineStageFlags dstStageFlags)4276 void clearColorImage (const DeviceInterface&	vk,
4277 					  const VkDevice			device,
4278 					  const VkQueue				queue,
4279 					  deUint32					queueFamilyIndex,
4280 					  VkImage					image,
4281 					  tcu::Vec4					clearColor,
4282 					  VkImageLayout				oldLayout,
4283 					  VkImageLayout				newLayout,
4284 					  VkPipelineStageFlags		dstStageFlags)
4285 {
4286 	Move<VkCommandPool>				cmdPool				= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
4287 	Move<VkCommandBuffer>			cmdBuffer			= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4288 
4289 	const VkClearColorValue			clearColorValue		= makeClearValueColor(clearColor).color;
4290 
4291 	const VkImageSubresourceRange	subresourceRange	=
4292 	{
4293 		VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
4294 		0u,							// deUint32				baseMipLevel
4295 		1u,							// deUint32				levelCount
4296 		0u,							// deUint32				baseArrayLayer
4297 		1u,							// deUint32				layerCount
4298 	};
4299 
4300 	const VkImageMemoryBarrier		preImageBarrier		=
4301 	{
4302 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4303 		DE_NULL,									// const void*				pNext;
4304 		0u,											// VkAccessFlags			srcAccessMask;
4305 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
4306 		oldLayout,									// VkImageLayout			oldLayout;
4307 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
4308 		queueFamilyIndex,							// deUint32					srcQueueFamilyIndex;
4309 		queueFamilyIndex,							// deUint32					dstQueueFamilyIndex;
4310 		image,										// VkImage					image;
4311 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
4312 	};
4313 
4314 	const VkImageMemoryBarrier		postImageBarrier	=
4315 	{
4316 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4317 		DE_NULL,									// const void*				pNext;
4318 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4319 		VK_ACCESS_SHADER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
4320 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
4321 		newLayout,									// VkImageLayout			newLayout;
4322 		queueFamilyIndex,							// deUint32					srcQueueFamilyIndex;
4323 		queueFamilyIndex,							// deUint32					dstQueueFamilyIndex;
4324 		image,										// VkImage					image;
4325 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
4326 	};
4327 
4328 	beginCommandBuffer(vk, *cmdBuffer);
4329 	vk.cmdPipelineBarrier(*cmdBuffer,
4330 						  VK_PIPELINE_STAGE_HOST_BIT,
4331 						  VK_PIPELINE_STAGE_TRANSFER_BIT,
4332 						  (VkDependencyFlags)0,
4333 						  0, (const VkMemoryBarrier*)DE_NULL,
4334 						  0, (const VkBufferMemoryBarrier*)DE_NULL,
4335 						  1, &preImageBarrier);
4336 	vk.cmdClearColorImage(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColorValue, 1, &subresourceRange);
4337 	vk.cmdPipelineBarrier(*cmdBuffer,
4338 						  VK_PIPELINE_STAGE_TRANSFER_BIT,
4339 						  dstStageFlags,
4340 						  (VkDependencyFlags)0,
4341 						  0, (const VkMemoryBarrier*)DE_NULL,
4342 						  0, (const VkBufferMemoryBarrier*)DE_NULL,
4343 						  1, &postImageBarrier);
4344 	endCommandBuffer(vk, *cmdBuffer);
4345 
4346 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
4347 }
4348 
generateChessboardCopyRegions(deUint32 tileSize,deUint32 imageWidth,deUint32 imageHeight,deUint32 tileIdx,VkImageAspectFlags aspectMask)4349 std::vector<VkBufferImageCopy> generateChessboardCopyRegions (deUint32				tileSize,
4350 															  deUint32				imageWidth,
4351 															  deUint32				imageHeight,
4352 															  deUint32				tileIdx,
4353 															  VkImageAspectFlags	aspectMask)
4354 {
4355 	std::vector<VkBufferImageCopy>	copyRegions;
4356 
4357 	for (deUint32 x = 0; x < (deUint32)deFloatCeil((float)imageWidth / (float)tileSize); x++)
4358 		for (deUint32 y = 0; y < (deUint32)deFloatCeil((float)imageHeight / (float)tileSize); y++)
4359 		{
4360 			if ((x + tileIdx) % 2 == y % 2) continue;
4361 
4362 			const deUint32					tileWidth			= de::min(tileSize, imageWidth - tileSize * x);
4363 			const deUint32					tileHeight			= de::min(tileSize, imageHeight - tileSize * y);
4364 
4365 			const VkOffset3D				offset				=
4366 			{
4367 				(deInt32)x * (deInt32)tileWidth,	// deInt32	x
4368 				(deInt32)y * (deInt32)tileHeight,	// deInt32	y
4369 				0									// deInt32	z
4370 			};
4371 
4372 			const VkExtent3D				extent				=
4373 			{
4374 				tileWidth,	// deUint32	width
4375 				tileHeight,	// deUint32	height
4376 				1u			// deUint32	depth
4377 			};
4378 
4379 			const VkImageSubresourceLayers	subresourceLayers	=
4380 			{
4381 				aspectMask,	// VkImageAspectFlags	aspectMask
4382 				0u,			// deUint32				mipLevel
4383 				0u,			// deUint32				baseArrayLayer
4384 				1u,			// deUint32				layerCount
4385 			};
4386 
4387 			const VkBufferImageCopy			copy				=
4388 			{
4389 				(VkDeviceSize)0,	// VkDeviceSize				bufferOffset
4390 				0u,					// deUint32					bufferRowLength
4391 				0u,					// deUint32					bufferImageHeight
4392 				subresourceLayers,	// VkImageSubresourceLayers	imageSubresource
4393 				offset,				// VkOffset3D				imageOffset
4394 				extent				// VkExtent3D				imageExtent
4395 			};
4396 
4397 			copyRegions.push_back(copy);
4398 		}
4399 
4400 	return copyRegions;
4401 }
4402 
initColorImageChessboardPattern(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,deUint32 queueFamilyIndex,Allocator & allocator,VkImage image,VkFormat format,tcu::Vec4 colorValue0,tcu::Vec4 colorValue1,deUint32 imageWidth,deUint32 imageHeight,deUint32 tileSize,VkImageLayout oldLayout,VkImageLayout newLayout,VkPipelineStageFlags dstStageFlags)4403 void initColorImageChessboardPattern (const DeviceInterface&	vk,
4404 									  const VkDevice			device,
4405 									  const VkQueue				queue,
4406 									  deUint32					queueFamilyIndex,
4407 									  Allocator&				allocator,
4408 									  VkImage					image,
4409 									  VkFormat					format,
4410 									  tcu::Vec4					colorValue0,
4411 									  tcu::Vec4					colorValue1,
4412 									  deUint32					imageWidth,
4413 									  deUint32					imageHeight,
4414 									  deUint32					tileSize,
4415 									  VkImageLayout				oldLayout,
4416 									  VkImageLayout				newLayout,
4417 									  VkPipelineStageFlags		dstStageFlags)
4418 {
4419 	Move<VkCommandPool>				cmdPool				= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
4420 	Move<VkCommandBuffer>			cmdBuffer			= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4421 	const tcu::TextureFormat		tcuFormat			= mapVkFormat(format);
4422 	const tcu::Vec4					colorValues[]		= { colorValue0, colorValue1 };
4423 	const deUint32					bufferSize			= tileSize * tileSize * tcuFormat.getPixelSize();
4424 
4425 	const VkImageSubresourceRange	subresourceRange	=
4426 	{
4427 		VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
4428 		0u,							// deUint32				baseMipLevel
4429 		1u,							// deUint32				levelCount
4430 		0u,							// deUint32				baseArrayLayer
4431 		1u							// deUint32				layerCount
4432 	};
4433 
4434 	const VkImageMemoryBarrier		preImageBarrier		=
4435 	{
4436 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4437 		DE_NULL,									// const void*				pNext;
4438 		0u,											// VkAccessFlags			srcAccessMask;
4439 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
4440 		oldLayout,									// VkImageLayout			oldLayout;
4441 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
4442 		queueFamilyIndex,							// deUint32					srcQueueFamilyIndex;
4443 		queueFamilyIndex,							// deUint32					dstQueueFamilyIndex;
4444 		image,										// VkImage					image;
4445 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
4446 	};
4447 
4448 	const VkImageMemoryBarrier		postImageBarrier	=
4449 	{
4450 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4451 		DE_NULL,									// const void*				pNext;
4452 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4453 		VK_ACCESS_SHADER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
4454 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
4455 		newLayout,									// VkImageLayout			newLayout;
4456 		queueFamilyIndex,							// deUint32					srcQueueFamilyIndex;
4457 		queueFamilyIndex,							// deUint32					dstQueueFamilyIndex;
4458 		image,										// VkImage					image;
4459 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
4460 	};
4461 
4462 	// Create staging buffers for both color values
4463 	Move<VkBuffer>					buffers[2];
4464 	de::MovePtr<Allocation>			bufferAllocs[2];
4465 
4466 	const VkBufferCreateInfo		bufferParams		=
4467 	{
4468 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
4469 		DE_NULL,								// const void*			pNext
4470 		0u,										// VkBufferCreateFlags	flags
4471 		(VkDeviceSize)bufferSize,				// VkDeviceSize			size
4472 		VK_BUFFER_USAGE_TRANSFER_SRC_BIT,		// VkBufferUsageFlags	usage
4473 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
4474 		0u,										// deUint32				queueFamilyIndexCount
4475 		DE_NULL									// const deUint32*		pQueueFamilyIndices
4476 	};
4477 
4478 	for (deUint32 bufferIdx = 0; bufferIdx < 2; bufferIdx++)
4479 	{
4480 		buffers[bufferIdx]		= createBuffer(vk, device, &bufferParams);
4481 		bufferAllocs[bufferIdx]	= allocator.allocate(getBufferMemoryRequirements(vk, device, *buffers[bufferIdx]), MemoryRequirement::HostVisible);
4482 		VK_CHECK(vk.bindBufferMemory(device, *buffers[bufferIdx], bufferAllocs[bufferIdx]->getMemory(), bufferAllocs[bufferIdx]->getOffset()));
4483 
4484 		deUint32*				dstPtr	= (deUint32*)bufferAllocs[bufferIdx]->getHostPtr();
4485 		tcu::PixelBufferAccess	access	(tcuFormat, tileSize, tileSize, 1, dstPtr);
4486 
4487 		for (deUint32 x = 0; x < tileSize; x++)
4488 			for (deUint32 y = 0; y < tileSize; y++)
4489 				access.setPixel(colorValues[bufferIdx], x, y, 0);
4490 
4491 		flushAlloc(vk, device, *bufferAllocs[bufferIdx]);
4492 	}
4493 
4494 	beginCommandBuffer(vk, *cmdBuffer);
4495 	vk.cmdPipelineBarrier(*cmdBuffer,
4496 						  VK_PIPELINE_STAGE_HOST_BIT,
4497 						  VK_PIPELINE_STAGE_TRANSFER_BIT,
4498 						  (VkDependencyFlags)0,
4499 						  0, (const VkMemoryBarrier*)DE_NULL,
4500 						  0, (const VkBufferMemoryBarrier*)DE_NULL,
4501 						  1, &preImageBarrier);
4502 
4503 	for (deUint32 bufferIdx = 0; bufferIdx < 2; bufferIdx++)
4504 	{
4505 		std::vector<VkBufferImageCopy> copyRegions = generateChessboardCopyRegions(tileSize, imageWidth, imageHeight, bufferIdx, VK_IMAGE_ASPECT_COLOR_BIT);
4506 
4507 		vk.cmdCopyBufferToImage(*cmdBuffer, *buffers[bufferIdx], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
4508 	}
4509 
4510 	vk.cmdPipelineBarrier(*cmdBuffer,
4511 						  VK_PIPELINE_STAGE_TRANSFER_BIT,
4512 						  dstStageFlags,
4513 						  (VkDependencyFlags)0,
4514 						  0, (const VkMemoryBarrier*)DE_NULL,
4515 						  0, (const VkBufferMemoryBarrier*)DE_NULL,
4516 						  1, &postImageBarrier);
4517 
4518 	endCommandBuffer(vk, *cmdBuffer);
4519 
4520 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
4521 }
4522 
copyDepthStencilImageToBuffers(const DeviceInterface & vk,VkCommandBuffer cmdBuffer,VkImage image,VkBuffer depthBuffer,VkBuffer stencilBuffer,tcu::IVec2 size,VkAccessFlags srcAccessMask,VkImageLayout oldLayout,deUint32 numLayers)4523 void copyDepthStencilImageToBuffers (const DeviceInterface&	vk,
4524 									 VkCommandBuffer		cmdBuffer,
4525 									 VkImage				image,
4526 									 VkBuffer				depthBuffer,
4527 									 VkBuffer				stencilBuffer,
4528 									 tcu::IVec2				size,
4529 									 VkAccessFlags			srcAccessMask,
4530 									 VkImageLayout			oldLayout,
4531 									 deUint32				numLayers)
4532 {
4533 	const VkImageAspectFlags		aspect				= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
4534 	const VkImageMemoryBarrier		imageBarrier		=
4535 	{
4536 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// VkStructureType			sType;
4537 		DE_NULL,												// const void*				pNext;
4538 		srcAccessMask,											// VkAccessFlags			srcAccessMask;
4539 		VK_ACCESS_TRANSFER_READ_BIT,							// VkAccessFlags			dstAccessMask;
4540 		oldLayout,												// VkImageLayout			oldLayout;
4541 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,					// VkImageLayout			newLayout;
4542 		VK_QUEUE_FAMILY_IGNORED,								// deUint32					srcQueueFamilyIndex;
4543 		VK_QUEUE_FAMILY_IGNORED,								// deUint32					destQueueFamilyIndex;
4544 		image,													// VkImage					image;
4545 		makeImageSubresourceRange(aspect, 0u, 1u, 0, numLayers)	// VkImageSubresourceRange	subresourceRange;
4546 	};
4547 
4548 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
4549 						  0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
4550 
4551 	const VkImageSubresourceLayers	subresourceDepth	=
4552 	{
4553 		VK_IMAGE_ASPECT_DEPTH_BIT,					// VkImageAspectFlags	aspectMask;
4554 		0u,											// deUint32				mipLevel;
4555 		0u,											// deUint32				baseArrayLayer;
4556 		numLayers									// deUint32				layerCount;
4557 	};
4558 
4559 	const VkBufferImageCopy			regionDepth			=
4560 	{
4561 		0ull,										// VkDeviceSize					bufferOffset;
4562 		0u,											// deUint32						bufferRowLength;
4563 		0u,											// deUint32						bufferImageHeight;
4564 		subresourceDepth,							// VkImageSubresourceLayers		imageSubresource;
4565 		makeOffset3D(0, 0, 0),						// VkOffset3D					imageOffset;
4566 		makeExtent3D(size.x(), size.y(), 1u)		// VkExtent3D					imageExtent;
4567 	};
4568 
4569 	const VkImageSubresourceLayers	subresourceStencil	=
4570 	{
4571 		VK_IMAGE_ASPECT_STENCIL_BIT,				// VkImageAspectFlags	aspectMask;
4572 		0u,											// deUint32				mipLevel;
4573 		0u,											// deUint32				baseArrayLayer;
4574 		numLayers									// deUint32				layerCount;
4575 	};
4576 
4577 	const VkBufferImageCopy			regionStencil		=
4578 	{
4579 		0ull,										// VkDeviceSize					bufferOffset;
4580 		0u,											// deUint32						bufferRowLength;
4581 		0u,											// deUint32						bufferImageHeight;
4582 		subresourceStencil,							// VkImageSubresourceLayers		imageSubresource;
4583 		makeOffset3D(0, 0, 0),						// VkOffset3D					imageOffset;
4584 		makeExtent3D(size.x(), size.y(), 1u)		// VkExtent3D					imageExtent;
4585 	};
4586 
4587 	vk.cmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, depthBuffer, 1u, &regionDepth);
4588 	vk.cmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stencilBuffer, 1u, &regionStencil);
4589 
4590 	const VkBufferMemoryBarrier	bufferBarriers[]		=
4591 	{
4592 		{
4593 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
4594 			DE_NULL,									// const void*		pNext;
4595 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
4596 			VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
4597 			VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
4598 			VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
4599 			depthBuffer,								// VkBuffer			buffer;
4600 			0ull,										// VkDeviceSize		offset;
4601 			VK_WHOLE_SIZE								// VkDeviceSize		size;
4602 		},
4603 		{
4604 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
4605 			DE_NULL,									// const void*		pNext;
4606 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
4607 			VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
4608 			VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
4609 			VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
4610 			stencilBuffer,								// VkBuffer			buffer;
4611 			0ull,										// VkDeviceSize		offset;
4612 			VK_WHOLE_SIZE								// VkDeviceSize		size;
4613 		}
4614 	};
4615 
4616 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
4617 						  0u, DE_NULL, 2u, bufferBarriers, 0u, DE_NULL);
4618 }
4619 
clearDepthStencilImage(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,deUint32 queueFamilyIndex,VkImage image,float depthValue,deUint32 stencilValue,VkImageLayout oldLayout,VkImageLayout newLayout,VkPipelineStageFlags dstStageFlags)4620 void clearDepthStencilImage (const DeviceInterface&	vk,
4621 							 const VkDevice			device,
4622 							 const VkQueue			queue,
4623 							 deUint32				queueFamilyIndex,
4624 							 VkImage				image,
4625 							 float					depthValue,
4626 							 deUint32				stencilValue,
4627 							 VkImageLayout			oldLayout,
4628 							 VkImageLayout			newLayout,
4629 							 VkPipelineStageFlags	dstStageFlags)
4630 {
4631 	Move<VkCommandPool>				cmdPool				= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
4632 	Move<VkCommandBuffer>			cmdBuffer			= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4633 
4634 	const VkClearDepthStencilValue	clearValue			= makeClearValueDepthStencil(depthValue, stencilValue).depthStencil;
4635 
4636 	const VkImageSubresourceRange	subresourceRange	=
4637 	{
4638 		VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask
4639 		0u,															// deUint32				baseMipLevel
4640 		1u,															// deUint32				levelCount
4641 		0u,															// deUint32				baseArrayLayer
4642 		1u															// deUint32				layerCount
4643 	};
4644 
4645 	const VkImageMemoryBarrier		preImageBarrier		=
4646 	{
4647 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4648 		DE_NULL,									// const void*				pNext;
4649 		0u,											// VkAccessFlags			srcAccessMask;
4650 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
4651 		oldLayout,									// VkImageLayout			oldLayout;
4652 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
4653 		queueFamilyIndex,							// deUint32					srcQueueFamilyIndex;
4654 		queueFamilyIndex,							// deUint32					dstQueueFamilyIndex;
4655 		image,										// VkImage					image;
4656 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
4657 	};
4658 
4659 	const VkImageMemoryBarrier		postImageBarrier	=
4660 	{
4661 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4662 		DE_NULL,									// const void*				pNext;
4663 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4664 		VK_ACCESS_SHADER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
4665 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
4666 		newLayout,									// VkImageLayout			newLayout;
4667 		queueFamilyIndex,							// deUint32					srcQueueFamilyIndex;
4668 		queueFamilyIndex,							// deUint32					dstQueueFamilyIndex;
4669 		image,										// VkImage					image;
4670 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
4671 	};
4672 
4673 	beginCommandBuffer(vk, *cmdBuffer);
4674 	vk.cmdPipelineBarrier(*cmdBuffer,
4675 						  VK_PIPELINE_STAGE_HOST_BIT,
4676 						  VK_PIPELINE_STAGE_TRANSFER_BIT,
4677 						  (VkDependencyFlags)0,
4678 						  0, (const VkMemoryBarrier*)DE_NULL,
4679 						  0, (const VkBufferMemoryBarrier*)DE_NULL,
4680 						  1, &preImageBarrier);
4681 	vk.cmdClearDepthStencilImage(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1, &subresourceRange);
4682 	vk.cmdPipelineBarrier(*cmdBuffer,
4683 						  VK_PIPELINE_STAGE_TRANSFER_BIT,
4684 						  dstStageFlags,
4685 						  (VkDependencyFlags)0,
4686 						  0, (const VkMemoryBarrier*)DE_NULL,
4687 						  0, (const VkBufferMemoryBarrier*)DE_NULL,
4688 						  1, &postImageBarrier);
4689 	endCommandBuffer(vk, *cmdBuffer);
4690 
4691 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
4692 }
4693 
initDepthStencilImageChessboardPattern(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,deUint32 queueFamilyIndex,Allocator & allocator,VkImage image,VkFormat format,float depthValue0,float depthValue1,deUint32 stencilValue0,deUint32 stencilValue1,deUint32 imageWidth,deUint32 imageHeight,deUint32 tileSize,VkImageLayout oldLayout,VkImageLayout newLayout,VkPipelineStageFlags dstStageFlags)4694 void initDepthStencilImageChessboardPattern (const DeviceInterface&	vk,
4695 											 const VkDevice			device,
4696 											 const VkQueue			queue,
4697 											 deUint32				queueFamilyIndex,
4698 											 Allocator&				allocator,
4699 											 VkImage				image,
4700 											 VkFormat				format,
4701 											 float					depthValue0,
4702 											 float					depthValue1,
4703 											 deUint32				stencilValue0,
4704 											 deUint32				stencilValue1,
4705 											 deUint32				imageWidth,
4706 											 deUint32				imageHeight,
4707 											 deUint32				tileSize,
4708 											 VkImageLayout			oldLayout,
4709 											 VkImageLayout			newLayout,
4710 											 VkPipelineStageFlags	dstStageFlags)
4711 {
4712 	Move<VkCommandPool>				cmdPool				= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
4713 	Move<VkCommandBuffer>			cmdBuffer			= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4714 
4715 	const deUint32					depthBufferSize		= tileSize * tileSize * 4;
4716 	const deUint32					stencilBufferSize	= tileSize * tileSize;
4717 	const float						depthValues[]		= { depthValue0, depthValue1 };
4718 	const deUint32					stencilValues[]		= { stencilValue0, stencilValue1 };
4719 	const tcu::TextureFormat		tcuFormat			= mapVkFormat(format);
4720 
4721 	const VkImageSubresourceRange	subresourceRange	=
4722 	{
4723 		VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask
4724 		0u,															// deUint32				baseMipLevel
4725 		1u,															// deUint32				levelCount
4726 		0u,															// deUint32				baseArrayLayer
4727 		1u															// deUint32				layerCount
4728 	};
4729 
4730 	const VkImageMemoryBarrier		preImageBarrier		=
4731 	{
4732 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4733 		DE_NULL,									// const void*				pNext;
4734 		0u,											// VkAccessFlags			srcAccessMask;
4735 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
4736 		oldLayout,									// VkImageLayout			oldLayout;
4737 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
4738 		queueFamilyIndex,							// deUint32					srcQueueFamilyIndex;
4739 		queueFamilyIndex,							// deUint32					dstQueueFamilyIndex;
4740 		image,										// VkImage					image;
4741 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
4742 	};
4743 
4744 	const VkImageMemoryBarrier		postImageBarrier	=
4745 	{
4746 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4747 		DE_NULL,									// const void*				pNext;
4748 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4749 		VK_ACCESS_SHADER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
4750 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
4751 		newLayout,									// VkImageLayout			newLayout;
4752 		queueFamilyIndex,							// deUint32					srcQueueFamilyIndex;
4753 		queueFamilyIndex,							// deUint32					dstQueueFamilyIndex;
4754 		image,										// VkImage					image;
4755 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
4756 	};
4757 
4758 	// Create staging buffers for depth and stencil values
4759 	Move<VkBuffer>					depthBuffers[2];
4760 	de::MovePtr<Allocation>			depthBufferAllocs[2];
4761 	Move<VkBuffer>					stencilBuffers[2];
4762 	de::MovePtr<Allocation>			stencilBufferAllocs[2];
4763 
4764 	const VkBufferCreateInfo		depthBufferParams	=
4765 	{
4766 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
4767 		DE_NULL,								// const void*			pNext
4768 		0u,										// VkBufferCreateFlags	flags
4769 		(VkDeviceSize)depthBufferSize,			// VkDeviceSize			size
4770 		VK_BUFFER_USAGE_TRANSFER_SRC_BIT,		// VkBufferUsageFlags	usage
4771 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
4772 		0u,										// deUint32				queueFamilyIndexCount
4773 		DE_NULL									// const deUint32*		pQueueFamilyIndices
4774 	};
4775 
4776 	const VkBufferCreateInfo		stencilBufferParams	=
4777 	{
4778 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
4779 		DE_NULL,								// const void*			pNext
4780 		0u,										// VkBufferCreateFlags	flags
4781 		(VkDeviceSize)stencilBufferSize,		// VkDeviceSize			size
4782 		VK_BUFFER_USAGE_TRANSFER_SRC_BIT,		// VkBufferUsageFlags	usage
4783 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
4784 		0u,										// deUint32				queueFamilyIndexCount
4785 		DE_NULL									// const deUint32*		pQueueFamilyIndices
4786 	};
4787 
4788 	for (deUint32 bufferIdx = 0; bufferIdx < 2; bufferIdx++)
4789 	{
4790 		depthBuffers[bufferIdx]			= createBuffer(vk, device, &depthBufferParams);
4791 		depthBufferAllocs[bufferIdx]	= allocator.allocate(getBufferMemoryRequirements(vk, device, *depthBuffers[bufferIdx]), MemoryRequirement::HostVisible);
4792 		VK_CHECK(vk.bindBufferMemory(device, *depthBuffers[bufferIdx], depthBufferAllocs[bufferIdx]->getMemory(), depthBufferAllocs[bufferIdx]->getOffset()));
4793 		stencilBuffers[bufferIdx]		= createBuffer(vk, device, &stencilBufferParams);
4794 		stencilBufferAllocs[bufferIdx]	= allocator.allocate(getBufferMemoryRequirements(vk, device, *stencilBuffers[bufferIdx]), MemoryRequirement::HostVisible);
4795 		VK_CHECK(vk.bindBufferMemory(device, *stencilBuffers[bufferIdx], stencilBufferAllocs[bufferIdx]->getMemory(), stencilBufferAllocs[bufferIdx]->getOffset()));
4796 
4797 		deUint32*	depthPtr	= (deUint32*)depthBufferAllocs[bufferIdx]->getHostPtr();
4798 		deUint32*	stencilPtr	= (deUint32*)stencilBufferAllocs[bufferIdx]->getHostPtr();
4799 
4800 		if (format == VK_FORMAT_D24_UNORM_S8_UINT)
4801 		{
4802 			tcu::PixelBufferAccess access(tcuFormat, tileSize, tileSize, 1, depthPtr);
4803 
4804 			for (deUint32 x = 0; x < tileSize; x++)
4805 				for (deUint32 y = 0; y < tileSize; y++)
4806 					access.setPixDepth(depthValues[bufferIdx], x, y, 0);
4807 		}
4808 		else
4809 		{
4810 			DE_ASSERT(format == VK_FORMAT_D32_SFLOAT_S8_UINT);
4811 
4812 			for (deUint32 i = 0; i < tileSize * tileSize; i++)
4813 				((float*)depthPtr)[i] = depthValues[bufferIdx];
4814 		}
4815 
4816 		deMemset(stencilPtr, stencilValues[bufferIdx], stencilBufferSize);
4817 		flushAlloc(vk, device, *depthBufferAllocs[bufferIdx]);
4818 		flushAlloc(vk, device, *stencilBufferAllocs[bufferIdx]);
4819 	}
4820 
4821 	beginCommandBuffer(vk, *cmdBuffer);
4822 	vk.cmdPipelineBarrier(*cmdBuffer,
4823 						  VK_PIPELINE_STAGE_HOST_BIT,
4824 						  VK_PIPELINE_STAGE_TRANSFER_BIT,
4825 						  (VkDependencyFlags)0,
4826 						  0, (const VkMemoryBarrier*)DE_NULL,
4827 						  0, (const VkBufferMemoryBarrier*)DE_NULL,
4828 						  1, &preImageBarrier);
4829 
4830 	for (deUint32 bufferIdx = 0; bufferIdx < 2; bufferIdx++)
4831 	{
4832 		std::vector<VkBufferImageCopy>	copyRegionsDepth	= generateChessboardCopyRegions(tileSize, imageWidth, imageHeight, bufferIdx, VK_IMAGE_ASPECT_DEPTH_BIT);
4833 		std::vector<VkBufferImageCopy>	copyRegionsStencil	= generateChessboardCopyRegions(tileSize, imageWidth, imageHeight, bufferIdx, VK_IMAGE_ASPECT_STENCIL_BIT);
4834 
4835 		vk.cmdCopyBufferToImage(*cmdBuffer, *depthBuffers[bufferIdx], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegionsDepth.size(), copyRegionsDepth.data());
4836 		vk.cmdCopyBufferToImage(*cmdBuffer, *stencilBuffers[bufferIdx], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegionsStencil.size(), copyRegionsStencil.data());
4837 	}
4838 
4839 	vk.cmdPipelineBarrier(*cmdBuffer,
4840 						  VK_PIPELINE_STAGE_TRANSFER_BIT,
4841 						  dstStageFlags,
4842 						  (VkDependencyFlags)0,
4843 						  0, (const VkMemoryBarrier*)DE_NULL,
4844 						  0, (const VkBufferMemoryBarrier*)DE_NULL,
4845 						  1, &postImageBarrier);
4846 
4847 	endCommandBuffer(vk, *cmdBuffer);
4848 
4849 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
4850 }
4851 
allocateAndBindSparseImage(const DeviceInterface & vk,VkDevice device,const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,const VkImageCreateInfo & imageCreateInfo,const VkSemaphore & signalSemaphore,VkQueue queue,Allocator & allocator,std::vector<de::SharedPtr<Allocation>> & allocations,tcu::TextureFormat format,VkImage destImage)4852 void allocateAndBindSparseImage (const DeviceInterface&						vk,
4853 								 VkDevice									device,
4854 								 const VkPhysicalDevice						physicalDevice,
4855 								 const InstanceInterface&					instance,
4856 								 const VkImageCreateInfo&					imageCreateInfo,
4857 								 const VkSemaphore&							signalSemaphore,
4858 								 VkQueue									queue,
4859 								 Allocator&									allocator,
4860 								 std::vector<de::SharedPtr<Allocation> >&	allocations,
4861 								 tcu::TextureFormat							format,
4862 								 VkImage									destImage)
4863 {
4864 	const VkImageAspectFlags				imageAspectFlags		= getImageAspectFlags(format);
4865 	const VkPhysicalDeviceProperties		deviceProperties		= getPhysicalDeviceProperties(instance, physicalDevice);
4866 	const VkPhysicalDeviceMemoryProperties	deviceMemoryProperties	= getPhysicalDeviceMemoryProperties(instance, physicalDevice);
4867 	deUint32								sparseMemoryReqCount	= 0;
4868 
4869 	// Check if the image format supports sparse operations
4870 	if (!checkSparseImageFormatSupport(physicalDevice, instance, imageCreateInfo))
4871 		TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");
4872 
4873 	vk.getImageSparseMemoryRequirements(device, destImage, &sparseMemoryReqCount, DE_NULL);
4874 
4875 	DE_ASSERT(sparseMemoryReqCount != 0);
4876 
4877 	std::vector<VkSparseImageMemoryRequirements> sparseImageMemoryRequirements;
4878 	sparseImageMemoryRequirements.resize(sparseMemoryReqCount);
4879 
4880 	vk.getImageSparseMemoryRequirements(device, destImage, &sparseMemoryReqCount, &sparseImageMemoryRequirements[0]);
4881 
4882 	const deUint32 noMatchFound = ~((deUint32)0);
4883 
4884 	deUint32 aspectIndex = noMatchFound;
4885 	for (deUint32 memoryReqNdx = 0; memoryReqNdx < sparseMemoryReqCount; ++memoryReqNdx)
4886 	{
4887 		if (sparseImageMemoryRequirements[memoryReqNdx].formatProperties.aspectMask == imageAspectFlags)
4888 		{
4889 			aspectIndex = memoryReqNdx;
4890 			break;
4891 		}
4892 	}
4893 
4894 	deUint32 metadataAspectIndex = noMatchFound;
4895 	for (deUint32 memoryReqNdx = 0; memoryReqNdx < sparseMemoryReqCount; ++memoryReqNdx)
4896 	{
4897 		if (sparseImageMemoryRequirements[memoryReqNdx].formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)
4898 		{
4899 			metadataAspectIndex = memoryReqNdx;
4900 			break;
4901 		}
4902 	}
4903 
4904 	if (aspectIndex == noMatchFound)
4905 		TCU_THROW(NotSupportedError, "Required image aspect not supported.");
4906 
4907 	const VkMemoryRequirements	memoryRequirements	= getImageMemoryRequirements(vk, device, destImage);
4908 
4909 	deUint32 memoryType = noMatchFound;
4910 	for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
4911 	{
4912 		if ((memoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
4913 			MemoryRequirement::Any.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
4914 		{
4915 			memoryType = memoryTypeNdx;
4916 			break;
4917 		}
4918 	}
4919 
4920 	if (memoryType == noMatchFound)
4921 		TCU_THROW(NotSupportedError, "No matching memory type found.");
4922 
4923 	if (memoryRequirements.size > deviceProperties.limits.sparseAddressSpaceSize)
4924 		TCU_THROW(NotSupportedError, "Required memory size for sparse resource exceeds device limits.");
4925 
4926 	const VkSparseImageMemoryRequirements		aspectRequirements	= sparseImageMemoryRequirements[aspectIndex];
4927 	VkExtent3D									blockSize			= aspectRequirements.formatProperties.imageGranularity;
4928 
4929 	std::vector<VkSparseImageMemoryBind>		imageResidencyMemoryBinds;
4930 	std::vector<VkSparseMemoryBind>				imageMipTailMemoryBinds;
4931 
4932 	for (deUint32 layerNdx = 0; layerNdx < imageCreateInfo.arrayLayers; ++layerNdx)
4933 	{
4934 		for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
4935 		{
4936 			const VkExtent3D	mipExtent		= mipLevelExtents(imageCreateInfo.extent, mipLevelNdx);
4937 			const tcu::UVec3	numSparseBinds	= alignedDivide(mipExtent, blockSize);
4938 			const tcu::UVec3	lastBlockExtent	= tcu::UVec3(mipExtent.width  % blockSize.width  ? mipExtent.width  % blockSize.width  : blockSize.width,
4939 															 mipExtent.height % blockSize.height ? mipExtent.height % blockSize.height : blockSize.height,
4940 															 mipExtent.depth  % blockSize.depth  ? mipExtent.depth  % blockSize.depth  : blockSize.depth );
4941 
4942 			for (deUint32 z = 0; z < numSparseBinds.z(); ++z)
4943 			for (deUint32 y = 0; y < numSparseBinds.y(); ++y)
4944 			for (deUint32 x = 0; x < numSparseBinds.x(); ++x)
4945 			{
4946 				const VkMemoryRequirements allocRequirements =
4947 				{
4948 					// 28.7.5 alignment shows the block size in bytes
4949 					memoryRequirements.alignment,		// VkDeviceSize	size;
4950 					memoryRequirements.alignment,		// VkDeviceSize	alignment;
4951 					memoryRequirements.memoryTypeBits,	// uint32_t		memoryTypeBits;
4952 				};
4953 
4954 				de::SharedPtr<Allocation> allocation(allocator.allocate(allocRequirements, MemoryRequirement::Any).release());
4955 				allocations.push_back(allocation);
4956 
4957 				VkOffset3D offset;
4958 				offset.x = x*blockSize.width;
4959 				offset.y = y*blockSize.height;
4960 				offset.z = z*blockSize.depth;
4961 
4962 				VkExtent3D extent;
4963 				extent.width	= (x == numSparseBinds.x() - 1) ? lastBlockExtent.x() : blockSize.width;
4964 				extent.height	= (y == numSparseBinds.y() - 1) ? lastBlockExtent.y() : blockSize.height;
4965 				extent.depth	= (z == numSparseBinds.z() - 1) ? lastBlockExtent.z() : blockSize.depth;
4966 
4967 				const VkSparseImageMemoryBind imageMemoryBind =
4968 				{
4969 					{
4970 						imageAspectFlags,	// VkImageAspectFlags	aspectMask;
4971 						mipLevelNdx,		// uint32_t				mipLevel;
4972 						layerNdx,			// uint32_t				arrayLayer;
4973 					},							// VkImageSubresource		subresource;
4974 					offset,						// VkOffset3D				offset;
4975 					extent,						// VkExtent3D				extent;
4976 					allocation->getMemory(),	// VkDeviceMemory			memory;
4977 					allocation->getOffset(),	// VkDeviceSize				memoryOffset;
4978 					0u,							// VkSparseMemoryBindFlags	flags;
4979 				};
4980 
4981 				imageResidencyMemoryBinds.push_back(imageMemoryBind);
4982 			}
4983 		}
4984 
4985 		// Handle MIP tail. There are two cases to consider here:
4986 		//
4987 		// 1) VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is requested by the driver: each layer needs a separate tail.
4988 		// 2) otherwise:                                                            only one tail is needed.
4989 		if (aspectRequirements.imageMipTailSize > 0)
4990 		{
4991 			if (layerNdx == 0 || (aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) == 0)
4992 			{
4993 				const VkMemoryRequirements allocRequirements =
4994 				{
4995 					aspectRequirements.imageMipTailSize,	// VkDeviceSize	size;
4996 					memoryRequirements.alignment,			// VkDeviceSize	alignment;
4997 					memoryRequirements.memoryTypeBits,		// uint32_t		memoryTypeBits;
4998 				};
4999 
5000 				const de::SharedPtr<Allocation> allocation(allocator.allocate(allocRequirements, MemoryRequirement::Any).release());
5001 
5002 				const VkSparseMemoryBind imageMipTailMemoryBind =
5003 				{
5004 					aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride,	// VkDeviceSize					resourceOffset;
5005 					aspectRequirements.imageMipTailSize,														// VkDeviceSize					size;
5006 					allocation->getMemory(),																	// VkDeviceMemory				memory;
5007 					allocation->getOffset(),																	// VkDeviceSize					memoryOffset;
5008 					0u,																							// VkSparseMemoryBindFlags		flags;
5009 				};
5010 
5011 				allocations.push_back(allocation);
5012 
5013 				imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
5014 			}
5015 		}
5016 
5017 		// Handle Metadata. Similarly to MIP tail in aspectRequirements, there are two cases to consider here:
5018 		//
5019 		// 1) VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is requested by the driver: each layer needs a separate tail.
5020 		// 2) otherwise:
5021 		if (metadataAspectIndex != noMatchFound)
5022 		{
5023 			const VkSparseImageMemoryRequirements	metadataAspectRequirements = sparseImageMemoryRequirements[metadataAspectIndex];
5024 
5025 			if (layerNdx == 0 || (metadataAspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) == 0)
5026 			{
5027 				const VkMemoryRequirements metadataAllocRequirements =
5028 				{
5029 					metadataAspectRequirements.imageMipTailSize,	// VkDeviceSize	size;
5030 					memoryRequirements.alignment,					// VkDeviceSize	alignment;
5031 					memoryRequirements.memoryTypeBits,				// uint32_t		memoryTypeBits;
5032 				};
5033 				const de::SharedPtr<Allocation>	metadataAllocation(allocator.allocate(metadataAllocRequirements, MemoryRequirement::Any).release());
5034 
5035 				const VkSparseMemoryBind metadataMipTailMemoryBind =
5036 				{
5037 					metadataAspectRequirements.imageMipTailOffset +
5038 					layerNdx * metadataAspectRequirements.imageMipTailStride,			// VkDeviceSize					resourceOffset;
5039 					metadataAspectRequirements.imageMipTailSize,						// VkDeviceSize					size;
5040 					metadataAllocation->getMemory(),									// VkDeviceMemory				memory;
5041 					metadataAllocation->getOffset(),									// VkDeviceSize					memoryOffset;
5042 					VK_SPARSE_MEMORY_BIND_METADATA_BIT									// VkSparseMemoryBindFlags		flags;
5043 				};
5044 
5045 				allocations.push_back(metadataAllocation);
5046 
5047 				imageMipTailMemoryBinds.push_back(metadataMipTailMemoryBind);
5048 			}
5049 		}
5050 	}
5051 
5052 	VkBindSparseInfo bindSparseInfo =
5053 	{
5054 		VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,			//VkStructureType							sType;
5055 		DE_NULL,									//const void*								pNext;
5056 		0u,											//deUint32									waitSemaphoreCount;
5057 		DE_NULL,									//const VkSemaphore*						pWaitSemaphores;
5058 		0u,											//deUint32									bufferBindCount;
5059 		DE_NULL,									//const VkSparseBufferMemoryBindInfo*		pBufferBinds;
5060 		0u,											//deUint32									imageOpaqueBindCount;
5061 		DE_NULL,									//const VkSparseImageOpaqueMemoryBindInfo*	pImageOpaqueBinds;
5062 		0u,											//deUint32									imageBindCount;
5063 		DE_NULL,									//const VkSparseImageMemoryBindInfo*		pImageBinds;
5064 		1u,											//deUint32									signalSemaphoreCount;
5065 		&signalSemaphore							//const VkSemaphore*						pSignalSemaphores;
5066 	};
5067 
5068 	VkSparseImageMemoryBindInfo			imageResidencyBindInfo;
5069 	VkSparseImageOpaqueMemoryBindInfo	imageMipTailBindInfo;
5070 
5071 	if (imageResidencyMemoryBinds.size() > 0)
5072 	{
5073 		imageResidencyBindInfo.image		= destImage;
5074 		imageResidencyBindInfo.bindCount	= static_cast<deUint32>(imageResidencyMemoryBinds.size());
5075 		imageResidencyBindInfo.pBinds		= &imageResidencyMemoryBinds[0];
5076 
5077 		bindSparseInfo.imageBindCount		= 1u;
5078 		bindSparseInfo.pImageBinds			= &imageResidencyBindInfo;
5079 	}
5080 
5081 	if (imageMipTailMemoryBinds.size() > 0)
5082 	{
5083 		imageMipTailBindInfo.image			= destImage;
5084 		imageMipTailBindInfo.bindCount		= static_cast<deUint32>(imageMipTailMemoryBinds.size());
5085 		imageMipTailBindInfo.pBinds			= &imageMipTailMemoryBinds[0];
5086 
5087 		bindSparseInfo.imageOpaqueBindCount	= 1u;
5088 		bindSparseInfo.pImageOpaqueBinds	= &imageMipTailBindInfo;
5089 	}
5090 
5091 	VK_CHECK(vk.queueBindSparse(queue, 1u, &bindSparseInfo, DE_NULL));
5092 }
5093 
checkSparseImageFormatSupport(const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,const VkFormat format,const VkImageType imageType,const VkSampleCountFlagBits sampleCount,const VkImageUsageFlags usageFlags,const VkImageTiling imageTiling)5094 bool checkSparseImageFormatSupport (const VkPhysicalDevice		physicalDevice,
5095 									const InstanceInterface&	instance,
5096 									const VkFormat				format,
5097 									const VkImageType			imageType,
5098 									const VkSampleCountFlagBits	sampleCount,
5099 									const VkImageUsageFlags		usageFlags,
5100 									const VkImageTiling			imageTiling)
5101 {
5102 	const auto propVec = getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, format, imageType, sampleCount, usageFlags, imageTiling);
5103 	return (propVec.size() != 0);
5104 }
5105 
checkSparseImageFormatSupport(const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,const VkImageCreateInfo & imageCreateInfo)5106 bool checkSparseImageFormatSupport (const VkPhysicalDevice		physicalDevice,
5107 									const InstanceInterface&	instance,
5108 									const VkImageCreateInfo&	imageCreateInfo)
5109 {
5110 	return checkSparseImageFormatSupport(physicalDevice, instance, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.samples, imageCreateInfo.usage, imageCreateInfo.tiling);
5111 }
5112 
5113 } // vk
5114