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