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