• 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 "tcuTextureUtil.hpp"
31 
32 namespace vk
33 {
34 
isFloatFormat(VkFormat format)35 bool isFloatFormat (VkFormat format)
36 {
37 	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
38 }
39 
isUnormFormat(VkFormat format)40 bool isUnormFormat (VkFormat format)
41 {
42 	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
43 }
44 
isSnormFormat(VkFormat format)45 bool isSnormFormat (VkFormat format)
46 {
47 	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
48 }
49 
isIntFormat(VkFormat format)50 bool isIntFormat (VkFormat format)
51 {
52 	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
53 }
54 
isUintFormat(VkFormat format)55 bool isUintFormat (VkFormat format)
56 {
57 	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
58 }
59 
isDepthStencilFormat(VkFormat format)60 bool isDepthStencilFormat (VkFormat format)
61 {
62 	if (isCompressedFormat(format))
63 		return false;
64 
65 	if (isYCbCrFormat(format))
66 		return false;
67 
68 	const tcu::TextureFormat tcuFormat = mapVkFormat(format);
69 	return tcuFormat.order == tcu::TextureFormat::D || tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS;
70 }
71 
isSrgbFormat(VkFormat format)72 bool isSrgbFormat (VkFormat format)
73 {
74 	switch (mapVkFormat(format).order)
75 	{
76 		case tcu::TextureFormat::sR:
77 		case tcu::TextureFormat::sRG:
78 		case tcu::TextureFormat::sRGB:
79 		case tcu::TextureFormat::sRGBA:
80 		case tcu::TextureFormat::sBGR:
81 		case tcu::TextureFormat::sBGRA:
82 			return true;
83 
84 		default:
85 			return false;
86 	}
87 }
88 
isCompressedFormat(VkFormat format)89 bool isCompressedFormat (VkFormat format)
90 {
91 	// update this mapping if VkFormat changes
92 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
93 
94 	switch (format)
95 	{
96 		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
97 		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
98 		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
99 		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
100 		case VK_FORMAT_BC2_UNORM_BLOCK:
101 		case VK_FORMAT_BC2_SRGB_BLOCK:
102 		case VK_FORMAT_BC3_UNORM_BLOCK:
103 		case VK_FORMAT_BC3_SRGB_BLOCK:
104 		case VK_FORMAT_BC4_UNORM_BLOCK:
105 		case VK_FORMAT_BC4_SNORM_BLOCK:
106 		case VK_FORMAT_BC5_UNORM_BLOCK:
107 		case VK_FORMAT_BC5_SNORM_BLOCK:
108 		case VK_FORMAT_BC6H_UFLOAT_BLOCK:
109 		case VK_FORMAT_BC6H_SFLOAT_BLOCK:
110 		case VK_FORMAT_BC7_UNORM_BLOCK:
111 		case VK_FORMAT_BC7_SRGB_BLOCK:
112 		case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
113 		case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
114 		case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
115 		case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
116 		case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
117 		case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
118 		case VK_FORMAT_EAC_R11_UNORM_BLOCK:
119 		case VK_FORMAT_EAC_R11_SNORM_BLOCK:
120 		case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
121 		case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
122 		case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
123 		case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
124 		case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
125 		case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
126 		case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
127 		case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
128 		case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
129 		case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
130 		case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
131 		case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
132 		case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
133 		case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
134 		case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
135 		case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
136 		case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
137 		case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
138 		case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
139 		case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
140 		case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
141 		case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
142 		case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
143 		case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
144 		case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
145 		case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
146 		case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
147 		case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
148 		case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
149 		case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
150 			return true;
151 
152 		default:
153 			return false;
154 	}
155 }
156 
isYCbCrFormat(VkFormat format)157 bool isYCbCrFormat (VkFormat format)
158 {
159 	switch (format)
160 	{
161 		case VK_FORMAT_G8B8G8R8_422_UNORM_KHR:
162 		case VK_FORMAT_B8G8R8G8_422_UNORM_KHR:
163 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
164 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
165 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR:
166 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR:
167 		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR:
168 		case VK_FORMAT_R10X6_UNORM_PACK16_KHR:
169 		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR:
170 		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR:
171 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR:
172 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR:
173 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
174 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
175 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR:
176 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR:
177 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR:
178 		case VK_FORMAT_R12X4_UNORM_PACK16_KHR:
179 		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR:
180 		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR:
181 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR:
182 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR:
183 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
184 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
185 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR:
186 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR:
187 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR:
188 		case VK_FORMAT_G16B16G16R16_422_UNORM_KHR:
189 		case VK_FORMAT_B16G16R16G16_422_UNORM_KHR:
190 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
191 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
192 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR:
193 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR:
194 		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR:
195 			return true;
196 
197 		default:
198 			return false;
199 	}
200 }
201 
isYCbCr420Format(VkFormat format)202 bool isYCbCr420Format (VkFormat format)
203 {
204 	switch (format)
205 	{
206 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
207 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
208 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
209 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
210 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
211 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
212 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
213 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
214 			return true;
215 
216 		default:
217 			return false;
218 	}
219 }
220 
isYCbCr422Format(VkFormat format)221 bool isYCbCr422Format (VkFormat format)
222 {
223 	switch (format)
224 	{
225 		case VK_FORMAT_G8B8G8R8_422_UNORM_KHR:
226 		case VK_FORMAT_B8G8R8G8_422_UNORM_KHR:
227 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR:
228 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR:
229 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR:
230 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR:
231 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR:
232 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR:
233 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR:
234 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR:
235 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR:
236 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR:
237 		case VK_FORMAT_G16B16G16R16_422_UNORM_KHR:
238 		case VK_FORMAT_B16G16R16G16_422_UNORM_KHR:
239 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR:
240 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR:
241 			return true;
242 
243 		default:
244 			return false;
245 	}
246 }
247 
getYCbCrPlanarFormatDescription(VkFormat format)248 const PlanarFormatDescription& getYCbCrPlanarFormatDescription (VkFormat format)
249 {
250 	using tcu::TextureFormat;
251 
252 	const deUint32	chanR			= PlanarFormatDescription::CHANNEL_R;
253 	const deUint32	chanG			= PlanarFormatDescription::CHANNEL_G;
254 	const deUint32	chanB			= PlanarFormatDescription::CHANNEL_B;
255 	const deUint32	chanA			= PlanarFormatDescription::CHANNEL_A;
256 
257 	const deUint8	unorm			= (deUint8)tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
258 
259 	static const PlanarFormatDescription s_formatInfo[] =
260 	{
261 		// VK_FORMAT_G8B8G8R8_422_UNORM_KHR
262 		{
263 			1, // planes
264 			chanR|chanG|chanB,
265 			{
266 			//		Size	WDiv	HDiv
267 				{	4,		2,		1	},
268 				{	0,		0,		0	},
269 				{	0,		0,		0	},
270 			},
271 			{
272 			//		Plane	Type	Offs	Size	Stride
273 				{	0,		unorm,	24,		8,		4 },	// R
274 				{	0,		unorm,	0,		8,		2 },	// G
275 				{	0,		unorm,	8,		8,		4 },	// B
276 				{ 0, 0, 0, 0, 0 }
277 			}
278 		},
279 		// VK_FORMAT_B8G8R8G8_422_UNORM_KHR
280 		{
281 			1, // planes
282 			chanR|chanG|chanB,
283 			{
284 			//		Size	WDiv	HDiv
285 				{	4,		2,		1 },
286 				{	0,		0,		0 },
287 				{	0,		0,		0 },
288 			},
289 			{
290 			//		Plane	Type	Offs	Size	Stride
291 				{	0,		unorm,	16,		8,		4 },	// R
292 				{	0,		unorm,	8,		8,		2 },	// G
293 				{	0,		unorm,	0,		8,		4 },	// B
294 				{ 0, 0, 0, 0, 0 }
295 			}
296 		},
297 		// VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR
298 		{
299 			3, // planes
300 			chanR|chanG|chanB,
301 			{
302 			//		Size	WDiv	HDiv
303 				{  1, 1, 1 },
304 				{  1, 2, 2 },
305 				{  1, 2, 2 },
306 			},
307 			{
308 			//		Plane	Type	Offs	Size	Stride
309 				{	2,		unorm,	0,		8,		1 },	// R
310 				{	0,		unorm,	0,		8,		1 },	// G
311 				{	1,		unorm,	0,		8,		1 },	// B
312 				{ 0, 0, 0, 0, 0 }
313 			}
314 		},
315 		// VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR
316 		{
317 			2, // planes
318 			chanR|chanG|chanB,
319 			{
320 			//		Size	WDiv	HDiv
321 				{  1, 1, 1 },
322 				{  2, 2, 2 },
323 				{  0, 0, 0 },
324 			},
325 			{
326 			//		Plane	Type	Offs	Size	Stride
327 				{	1,		unorm,	8,		8,		2 },	// R
328 				{	0,		unorm,	0,		8,		1 },	// G
329 				{	1,		unorm,	0,		8,		2 },	// B
330 				{ 0, 0, 0, 0, 0 }
331 			}
332 		},
333 		// VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR
334 		{
335 			3, // planes
336 			chanR|chanG|chanB,
337 			{
338 			//		Size	WDiv	HDiv
339 				{  1, 1, 1 },
340 				{  1, 2, 1 },
341 				{  1, 2, 1 },
342 			},
343 			{
344 			//		Plane	Type	Offs	Size	Stride
345 				{	2,		unorm,	0,		8,		1 },	// R
346 				{	0,		unorm,	0,		8,		1 },	// G
347 				{	1,		unorm,	0,		8,		1 },	// B
348 				{ 0, 0, 0, 0, 0 }
349 			}
350 		},
351 		// VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR
352 		{
353 			2, // planes
354 			chanR|chanG|chanB,
355 			{
356 			//		Size	WDiv	HDiv
357 				{  1, 1, 1 },
358 				{  2, 2, 1 },
359 				{  0, 0, 0 },
360 			},
361 			{
362 			//		Plane	Type	Offs	Size	Stride
363 				{	1,		unorm,	8,		8,		2 },	// R
364 				{	0,		unorm,	0,		8,		1 },	// G
365 				{	1,		unorm,	0,		8,		2 },	// B
366 				{ 0, 0, 0, 0, 0 }
367 			}
368 		},
369 		// VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR
370 		{
371 			3, // planes
372 			chanR|chanG|chanB,
373 			{
374 			//		Size	WDiv	HDiv
375 				{  1, 1, 1 },
376 				{  1, 1, 1 },
377 				{  1, 1, 1 },
378 			},
379 			{
380 			//		Plane	Type	Offs	Size	Stride
381 				{	2,		unorm,	0,		8,		1 },	// R
382 				{	0,		unorm,	0,		8,		1 },	// G
383 				{	1,		unorm,	0,		8,		1 },	// B
384 				{ 0, 0, 0, 0, 0 }
385 			}
386 		},
387 		// VK_FORMAT_R10X6_UNORM_PACK16_KHR
388 		{
389 			1, // planes
390 			chanR,
391 			{
392 			//		Size	WDiv	HDiv
393 				{	2,		1,		1 },
394 				{	0,		0,		0 },
395 				{	0,		0,		0 },
396 			},
397 			{
398 			//		Plane	Type	Offs	Size	Stride
399 				{	0,		unorm,	6,		10,		2 },	// R
400 				{ 0, 0, 0, 0, 0 },
401 				{ 0, 0, 0, 0, 0 },
402 				{ 0, 0, 0, 0, 0 },
403 			}
404 		},
405 		// VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR
406 		{
407 			1, // planes
408 			chanR|chanG,
409 			{
410 			//		Size	WDiv	HDiv
411 				{	4,		1,		1 },
412 				{	0,		0,		0 },
413 				{	0,		0,		0 },
414 			},
415 			{
416 			//		Plane	Type	Offs	Size	Stride
417 				{	0,		unorm,	6,		10,		4 },	// R
418 				{	0,		unorm,	22,		10,		4 },	// G
419 				{ 0, 0, 0, 0, 0 },
420 				{ 0, 0, 0, 0, 0 },
421 			}
422 		},
423 		// VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR
424 		{
425 			1, // planes
426 			chanR|chanG|chanB|chanA,
427 			{
428 			//		Size	WDiv	HDiv
429 				{	8,		1,		1 },
430 				{	0,		0,		0 },
431 				{	0,		0,		0 },
432 			},
433 			{
434 			//		Plane	Type	Offs	Size	Stride
435 				{	0,		unorm,	6,		10,		8 },	// R
436 				{	0,		unorm,	22,		10,		8 },	// G
437 				{	0,		unorm,	38,		10,		8 },	// B
438 				{	0,		unorm,	54,		10,		8 },	// A
439 			}
440 		},
441 		// VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR
442 		{
443 			1, // planes
444 			chanR|chanG|chanB,
445 			{
446 			//		Size	WDiv	HDiv
447 				{	8,		2,		1 },
448 				{	0,		0,		0 },
449 				{	0,		0,		0 },
450 			},
451 			{
452 			//		Plane	Type	Offs	Size	Stride
453 				{	0,		unorm,	54,		10,		8 },	// R
454 				{	0,		unorm,	6,		10,		4 },	// G
455 				{	0,		unorm,	22,		10,		8 },	// B
456 				{ 0, 0, 0, 0, 0 }
457 			}
458 		},
459 		// VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR
460 		{
461 			1, // planes
462 			chanR|chanG|chanB,
463 			{
464 			//		Size	WDiv	HDiv
465 				{	8,		2,		1 },
466 				{	0,		0,		0 },
467 				{	0,		0,		0 },
468 			},
469 			{
470 			//		Plane	Type	Offs	Size	Stride
471 				{	0,		unorm,	38,		10,		8 },	// R
472 				{	0,		unorm,	22,		10,		4 },	// G
473 				{	0,		unorm,	6,		10,		8 },	// B
474 				{ 0, 0, 0, 0, 0 }
475 			}
476 		},
477 		// VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR
478 		{
479 			3, // planes
480 			chanR|chanG|chanB,
481 			{
482 			//		Size	WDiv	HDiv
483 				{	2,		1,		1 },
484 				{	2,		2,		2 },
485 				{	2,		2,		2 },
486 			},
487 			{
488 			//		Plane	Type	Offs	Size	Stride
489 				{	2,		unorm,	6,		10,		2 },	// R
490 				{	0,		unorm,	6,		10,		2 },	// G
491 				{	1,		unorm,	6,		10,		2 },	// B
492 				{ 0, 0, 0, 0, 0 }
493 			}
494 		},
495 		// VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR
496 		{
497 			2, // planes
498 			chanR|chanG|chanB,
499 			{
500 			//		Size	WDiv	HDiv
501 				{	2,		1,		1 },
502 				{	4,		2,		2 },
503 				{	0,		0,		0 },
504 			},
505 			{
506 			//		Plane	Type	Offs	Size	Stride
507 				{	1,		unorm,	22,		10,		4 },	// R
508 				{	0,		unorm,	6,		10,		2 },	// G
509 				{	1,		unorm,	6,		10,		4 },	// B
510 				{ 0, 0, 0, 0, 0 }
511 			}
512 		},
513 		// VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR
514 		{
515 			3, // planes
516 			chanR|chanG|chanB,
517 			{
518 			//		Size	WDiv	HDiv
519 				{	2,		1,		1 },
520 				{	2,		2,		1 },
521 				{	2,		2,		1 },
522 			},
523 			{
524 			//		Plane	Type	Offs	Size	Stride
525 				{	2,		unorm,	6,		10,		2 },	// R
526 				{	0,		unorm,	6,		10,		2 },	// G
527 				{	1,		unorm,	6,		10,		2 },	// B
528 				{ 0, 0, 0, 0, 0 }
529 			}
530 		},
531 		// VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR
532 		{
533 			2, // planes
534 			chanR|chanG|chanB,
535 			{
536 			//		Size	WDiv	HDiv
537 				{	2,		1,		1 },
538 				{	4,		2,		1 },
539 				{	0,		0,		0 },
540 			},
541 			{
542 			//		Plane	Type	Offs	Size	Stride
543 				{	1,		unorm,	22,		10,		4 },	// R
544 				{	0,		unorm,	6,		10,		2 },	// G
545 				{	1,		unorm,	6,		10,		4 },	// B
546 				{ 0, 0, 0, 0, 0 }
547 			}
548 		},
549 		// VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR
550 		{
551 			3, // planes
552 			chanR|chanG|chanB,
553 			{
554 			//		Size	WDiv	HDiv
555 				{	2,		1,		1 },
556 				{	2,		1,		1 },
557 				{	2,		1,		1 },
558 			},
559 			{
560 			//		Plane	Type	Offs	Size	Stride
561 				{	2,		unorm,	6,		10,		2 },	// R
562 				{	0,		unorm,	6,		10,		2 },	// G
563 				{	1,		unorm,	6,		10,		2 },	// B
564 				{ 0, 0, 0, 0, 0 }
565 			}
566 		},
567 		// VK_FORMAT_R12X4_UNORM_PACK16_KHR
568 		{
569 			1, // planes
570 			chanR,
571 			{
572 			//		Size	WDiv	HDiv
573 				{	2,		1,		1 },
574 				{	0,		0,		0 },
575 				{	0,		0,		0 },
576 			},
577 			{
578 			//		Plane	Type	Offs	Size	Stride
579 				{	0,		unorm,	4,		12,		2 },	// R
580 				{ 0, 0, 0, 0, 0 },
581 				{ 0, 0, 0, 0, 0 },
582 				{ 0, 0, 0, 0, 0 },
583 			}
584 		},
585 		// VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR
586 		{
587 			1, // planes
588 			chanR|chanG,
589 			{
590 			//		Size	WDiv	HDiv
591 				{	4,		1,		1 },
592 				{	0,		0,		0 },
593 				{	0,		0,		0 },
594 			},
595 			{
596 			//		Plane	Type	Offs	Size	Stride
597 				{	0,		unorm,	4,		12,		4 },	// R
598 				{	0,		unorm,	20,		12,		4 },	// G
599 				{ 0, 0, 0, 0, 0 },
600 				{ 0, 0, 0, 0, 0 },
601 			}
602 		},
603 		// VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR
604 		{
605 			1, // planes
606 			chanR|chanG|chanB|chanA,
607 			{
608 			//		Size	WDiv	HDiv
609 				{	8,		1,		1 },
610 				{	0,		0,		0 },
611 				{	0,		0,		0 },
612 			},
613 			{
614 			//		Plane	Type	Offs	Size	Stride
615 				{	0,		unorm,	4,		12,		8 },	// R
616 				{	0,		unorm,	20,		12,		8 },	// G
617 				{	0,		unorm,	36,		12,		8 },	// B
618 				{	0,		unorm,	52,		12,		8 },	// A
619 			}
620 		},
621 		// VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR
622 		{
623 			1, // planes
624 			chanR|chanG|chanB,
625 			{
626 			//		Size	WDiv	HDiv
627 				{	8,		2,		1 },
628 				{	0,		0,		0 },
629 				{	0,		0,		0 },
630 			},
631 			{
632 			//		Plane	Type	Offs	Size	Stride
633 				{	0,		unorm,	52,		12,		8 },	// R
634 				{	0,		unorm,	4,		12,		4 },	// G
635 				{	0,		unorm,	20,		12,		8 },	// B
636 				{ 0, 0, 0, 0, 0 }
637 			}
638 		},
639 		// VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR
640 		{
641 			1, // planes
642 			chanR|chanG|chanB,
643 			{
644 			//		Size	WDiv	HDiv
645 				{	8,		2,		1 },
646 				{	0,		0,		0 },
647 				{	0,		0,		0 },
648 			},
649 			{
650 			//		Plane	Type	Offs	Size	Stride
651 				{	0,		unorm,	36,		12,		8 },	// R
652 				{	0,		unorm,	20,		12,		4 },	// G
653 				{	0,		unorm,	4,		12,		8 },	// B
654 				{ 0, 0, 0, 0, 0 }
655 			}
656 		},
657 		// VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR
658 		{
659 			3, // planes
660 			chanR|chanG|chanB,
661 			{
662 			//		Size	WDiv	HDiv
663 				{	2,		1,		1 },
664 				{	2,		2,		2 },
665 				{	2,		2,		2 },
666 			},
667 			{
668 			//		Plane	Type	Offs	Size	Stride
669 				{	2,		unorm,	4,		12,		2 },	// R
670 				{	0,		unorm,	4,		12,		2 },	// G
671 				{	1,		unorm,	4,		12,		2 },	// B
672 				{ 0, 0, 0, 0, 0 }
673 			}
674 		},
675 		// VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR
676 		{
677 			2, // planes
678 			chanR|chanG|chanB,
679 			{
680 			//		Size	WDiv	HDiv
681 				{	2,		1,		1 },
682 				{	4,		2,		2 },
683 				{	0,		0,		0 },
684 			},
685 			{
686 			//		Plane	Type	Offs	Size	Stride
687 				{	1,		unorm,	20,		12,		4 },	// R
688 				{	0,		unorm,	4,		12,		2 },	// G
689 				{	1,		unorm,	4,		12,		4 },	// B
690 				{ 0, 0, 0, 0, 0 }
691 			}
692 		},
693 		// VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR
694 		{
695 			3, // planes
696 			chanR|chanG|chanB,
697 			{
698 			//		Size	WDiv	HDiv
699 				{	2,		1,		1 },
700 				{	2,		2,		1 },
701 				{	2,		2,		1 },
702 			},
703 			{
704 			//		Plane	Type	Offs	Size	Stride
705 				{	2,		unorm,	4,		12,		2 },	// R
706 				{	0,		unorm,	4,		12,		2 },	// G
707 				{	1,		unorm,	4,		12,		2 },	// B
708 				{ 0, 0, 0, 0, 0 }
709 			}
710 		},
711 		// VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR
712 		{
713 			2, // planes
714 			chanR|chanG|chanB,
715 			{
716 			//		Size	WDiv	HDiv
717 				{	2,		1,		1 },
718 				{	4,		2,		1 },
719 				{	0,		0,		0 },
720 			},
721 			{
722 			//		Plane	Type	Offs	Size	Stride
723 				{	1,		unorm,	20,		12,		4 },	// R
724 				{	0,		unorm,	4,		12,		2 },	// G
725 				{	1,		unorm,	4,		12,		4 },	// B
726 				{ 0, 0, 0, 0, 0 }
727 			}
728 		},
729 		// VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR
730 		{
731 			3, // planes
732 			chanR|chanG|chanB,
733 			{
734 			//		Size	WDiv	HDiv
735 				{	2,		1,		1 },
736 				{	2,		1,		1 },
737 				{	2,		1,		1 },
738 			},
739 			{
740 			//		Plane	Type	Offs	Size	Stride
741 				{	2,		unorm,	4,		12,		2 },	// R
742 				{	0,		unorm,	4,		12,		2 },	// G
743 				{	1,		unorm,	4,		12,		2 },	// B
744 				{ 0, 0, 0, 0, 0 }
745 			}
746 		},
747 		// VK_FORMAT_G16B16G16R16_422_UNORM_KHR
748 		{
749 			1, // planes
750 			chanR|chanG|chanB,
751 			{
752 			//		Size	WDiv	HDiv
753 				{	8,		2,		1 },
754 				{	0,		0,		0 },
755 				{	0,		0,		0 },
756 			},
757 			{
758 			//		Plane	Type	Offs	Size	Stride
759 				{	0,		unorm,	48,		16,		8 },	// R
760 				{	0,		unorm,	0,		16,		4 },	// G
761 				{	0,		unorm,	16,		16,		8 },	// B
762 				{ 0, 0, 0, 0, 0 }
763 			}
764 		},
765 		// VK_FORMAT_B16G16R16G16_422_UNORM_KHR
766 		{
767 			1, // planes
768 			chanR|chanG|chanB,
769 			{
770 			//		Size	WDiv	HDiv
771 				{	8,		2,		1 },
772 				{	0,		0,		0 },
773 				{	0,		0,		0 },
774 			},
775 			{
776 			//		Plane	Type	Offs	Size	Stride
777 				{	0,		unorm,	32,		16,		8 },	// R
778 				{	0,		unorm,	16,		16,		4 },	// G
779 				{	0,		unorm,	0,		16,		8 },	// B
780 				{ 0, 0, 0, 0, 0 }
781 			}
782 		},
783 		// VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR
784 		{
785 			3, // planes
786 			chanR|chanG|chanB,
787 			{
788 			//		Size	WDiv	HDiv
789 				{	2,		1,		1 },
790 				{	2,		2,		2 },
791 				{	2,		2,		2 },
792 			},
793 			{
794 			//		Plane	Type	Offs	Size	Stride
795 				{	2,		unorm,	0,		16,		2 },	// R
796 				{	0,		unorm,	0,		16,		2 },	// G
797 				{	1,		unorm,	0,		16,		2 },	// B
798 				{ 0, 0, 0, 0, 0 }
799 			}
800 		},
801 		// VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR
802 		{
803 			2, // planes
804 			chanR|chanG|chanB,
805 			{
806 			//		Size	WDiv	HDiv
807 				{	2,		1,		1 },
808 				{	4,		2,		2 },
809 				{	0,		0,		0 },
810 			},
811 			{
812 			//		Plane	Type	Offs	Size	Stride
813 				{	1,		unorm,	16,		16,		4 },	// R
814 				{	0,		unorm,	0,		16,		2 },	// G
815 				{	1,		unorm,	0,		16,		4 },	// B
816 				{ 0, 0, 0, 0, 0 }
817 			}
818 		},
819 		// VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR
820 		{
821 			3, // planes
822 			chanR|chanG|chanB,
823 			{
824 			//		Size	WDiv	HDiv
825 				{	2,		1,		1 },
826 				{	2,		2,		1 },
827 				{	2,		2,		1 },
828 			},
829 			{
830 			//		Plane	Type	Offs	Size	Stride
831 				{	2,		unorm,	0,		16,		2 },	// R
832 				{	0,		unorm,	0,		16,		2 },	// G
833 				{	1,		unorm,	0,		16,		2 },	// B
834 				{ 0, 0, 0, 0, 0 }
835 			}
836 		},
837 		// VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR
838 		{
839 			2, // planes
840 			chanR|chanG|chanB,
841 			{
842 			//		Size	WDiv	HDiv
843 				{	2,		1,		1 },
844 				{	4,		2,		1 },
845 				{	0,		0,		0 },
846 			},
847 			{
848 			//		Plane	Type	Offs	Size	Stride
849 				{	1,		unorm,	16,		16,		4 },	// R
850 				{	0,		unorm,	0,		16,		2 },	// G
851 				{	1,		unorm,	0,		16,		4 },	// B
852 				{ 0, 0, 0, 0, 0 }
853 			}
854 		},
855 		// VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR
856 		{
857 			3, // planes
858 			chanR|chanG|chanB,
859 			{
860 			//		Size	WDiv	HDiv
861 				{	2,		1,		1 },
862 				{	2,		1,		1 },
863 				{	2,		1,		1 },
864 			},
865 			{
866 			//		Plane	Type	Offs	Size	Stride
867 				{	2,		unorm,	0,		16,		2 },	// R
868 				{	0,		unorm,	0,		16,		2 },	// G
869 				{	1,		unorm,	0,		16,		2 },	// B
870 				{ 0, 0, 0, 0, 0 }
871 			}
872 		},
873 	};
874 
875 	const size_t	offset	= (size_t)VK_FORMAT_G8B8G8R8_422_UNORM_KHR;
876 
877 	DE_ASSERT(de::inBounds<size_t>((size_t)format, offset, offset+(size_t)DE_LENGTH_OF_ARRAY(s_formatInfo)));
878 
879 	return s_formatInfo[(size_t)format-offset];
880 }
881 
getCorePlanarFormatDescription(VkFormat format)882 PlanarFormatDescription getCorePlanarFormatDescription (VkFormat format)
883 {
884 	const deUint8			unorm	= (deUint8)tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
885 
886 	const deUint8			chanR	= (deUint8)PlanarFormatDescription::CHANNEL_R;
887 	const deUint8			chanG	= (deUint8)PlanarFormatDescription::CHANNEL_G;
888 	const deUint8			chanB	= (deUint8)PlanarFormatDescription::CHANNEL_B;
889 	const deUint8			chanA	= (deUint8)PlanarFormatDescription::CHANNEL_A;
890 
891 	DE_ASSERT(de::inBounds<deUint32>(format, VK_FORMAT_UNDEFINED+1, VK_CORE_FORMAT_LAST));
892 
893 #if (DE_ENDIANNESS != DE_LITTLE_ENDIAN)
894 #	error "Big-endian is not supported"
895 #endif
896 
897 	switch (format)
898 	{
899 		case VK_FORMAT_R8_UNORM:
900 		{
901 			const PlanarFormatDescription	desc	=
902 			{
903 				1, // planes
904 				chanR,
905 				{
906 				//		Size	WDiv	HDiv
907 					{	1,		1,		1 },
908 					{	0,		0,		0 },
909 					{	0,		0,		0 },
910 				},
911 				{
912 				//		Plane	Type	Offs	Size	Stride
913 					{	0,		unorm,	0,		8,		1 },	// R
914 					{	0,		0,		0,		0,		0 },	// G
915 					{	0,		0,		0,		0,		0 },	// B
916 					{	0,		0,		0,		0,		0 }		// A
917 				}
918 			};
919 			return desc;
920 		}
921 
922 		case VK_FORMAT_R8G8_UNORM:
923 		{
924 			const PlanarFormatDescription	desc	=
925 			{
926 				1, // planes
927 				chanR|chanG,
928 				{
929 				//		Size	WDiv	HDiv
930 					{	2,		1,		1 },
931 					{	0,		0,		0 },
932 					{	0,		0,		0 },
933 				},
934 				{
935 				//		Plane	Type	Offs	Size	Stride
936 					{	0,		unorm,	0,		8,		2 },	// R
937 					{	0,		unorm,	8,		8,		2 },	// G
938 					{	0,		0,		0,		0,		0 },	// B
939 					{	0,		0,		0,		0,		0 }		// A
940 				}
941 			};
942 			return desc;
943 		}
944 
945 		case VK_FORMAT_R16_UNORM:
946 		{
947 			const PlanarFormatDescription	desc	=
948 			{
949 				1, // planes
950 				chanR,
951 				{
952 				//		Size	WDiv	HDiv
953 					{	2,		1,		1 },
954 					{	0,		0,		0 },
955 					{	0,		0,		0 },
956 				},
957 				{
958 				//		Plane	Type	Offs	Size	Stride
959 					{	0,		unorm,	0,		16,		2 },	// R
960 					{	0,		0,		0,		0,		0 },	// G
961 					{	0,		0,		0,		0,		0 },	// B
962 					{	0,		0,		0,		0,		0 }		// A
963 				}
964 			};
965 			return desc;
966 		}
967 
968 		case VK_FORMAT_R16G16_UNORM:
969 		{
970 			const PlanarFormatDescription	desc	=
971 			{
972 				1, // planes
973 				chanR|chanG,
974 				{
975 				//		Size	WDiv	HDiv
976 					{	4,		1,		1 },
977 					{	0,		0,		0 },
978 					{	0,		0,		0 },
979 				},
980 				{
981 				//		Plane	Type	Offs	Size	Stride
982 					{	0,		unorm,	0,		16,		4 },	// R
983 					{	0,		unorm,	16,		16,		4 },	// G
984 					{	0,		0,		0,		0,		0 },	// B
985 					{	0,		0,		0,		0,		0 }		// A
986 				}
987 			};
988 			return desc;
989 		}
990 
991 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
992 		{
993 			const PlanarFormatDescription	desc	=
994 			{
995 				1, // planes
996 				chanR|chanG|chanB,
997 				{
998 				//		Size	WDiv	HDiv
999 					{	4,		1,		1 },
1000 					{	0,		0,		0 },
1001 					{	0,		0,		0 },
1002 				},
1003 				{
1004 				//		Plane	Type	Offs	Size	Stride
1005 					{	0,		unorm,	0,		11,		4 },	// R
1006 					{	0,		unorm,	11,		11,		4 },	// G
1007 					{	0,		unorm,	22,		10,		4 },	// B
1008 					{	0,		0,		0,		0,		0 }		// A
1009 				}
1010 			};
1011 			return desc;
1012 		}
1013 
1014 		case VK_FORMAT_R4G4_UNORM_PACK8:
1015 		{
1016 			const PlanarFormatDescription	desc	=
1017 			{
1018 				1, // planes
1019 				chanR|chanG,
1020 				{
1021 				//		Size	WDiv	HDiv
1022 					{	1,		1,		1 },
1023 					{	0,		0,		0 },
1024 					{	0,		0,		0 },
1025 				},
1026 				{
1027 				//		Plane	Type	Offs	Size	Stride
1028 					{	0,		unorm,	4,		4,		1 },	// R
1029 					{	0,		unorm,	0,		4,		1 },	// G
1030 					{	0,		0,		0,		0,		0 },	// B
1031 					{	0,		0,		0,		0,		0 }		// A
1032 				}
1033 			};
1034 			return desc;
1035 		}
1036 
1037 		case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
1038 		{
1039 			const PlanarFormatDescription	desc	=
1040 			{
1041 				1, // planes
1042 				chanR|chanG|chanB|chanA,
1043 				{
1044 				//		Size	WDiv	HDiv
1045 					{	2,		1,		1 },
1046 					{	0,		0,		0 },
1047 					{	0,		0,		0 },
1048 				},
1049 				{
1050 				//		Plane	Type	Offs	Size	Stride
1051 					{	0,		unorm,	12,		4,		2 },	// R
1052 					{	0,		unorm,	8,		4,		2 },	// G
1053 					{	0,		unorm,	4,		4,		2 },	// B
1054 					{	0,		unorm,	0,		4,		2 }		// A
1055 				}
1056 			};
1057 			return desc;
1058 		}
1059 
1060 		case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
1061 		{
1062 			const PlanarFormatDescription	desc	=
1063 			{
1064 				1, // planes
1065 				chanR|chanG|chanB|chanA,
1066 				{
1067 				//		Size	WDiv	HDiv
1068 					{	2,		1,		1 },
1069 					{	0,		0,		0 },
1070 					{	0,		0,		0 },
1071 				},
1072 				{
1073 				//		Plane	Type	Offs	Size	Stride
1074 					{	0,		unorm,	4,		4,		2 },	// R
1075 					{	0,		unorm,	8,		4,		2 },	// G
1076 					{	0,		unorm,	12,		4,		2 },	// B
1077 					{	0,		unorm,	0,		4,		2 }		// A
1078 				}
1079 			};
1080 			return desc;
1081 		}
1082 
1083 		case VK_FORMAT_R5G6B5_UNORM_PACK16:
1084 		{
1085 			const PlanarFormatDescription	desc	=
1086 			{
1087 				1, // planes
1088 				chanR|chanG|chanB,
1089 				{
1090 				//		Size	WDiv	HDiv
1091 					{	2,		1,		1 },
1092 					{	0,		0,		0 },
1093 					{	0,		0,		0 },
1094 				},
1095 				{
1096 				//		Plane	Type	Offs	Size	Stride
1097 					{	0,		unorm,	11,		5,		2 },	// R
1098 					{	0,		unorm,	5,		6,		2 },	// G
1099 					{	0,		unorm,	0,		5,		2 },	// B
1100 					{	0,		0,		0,		0,		0 }		// A
1101 				}
1102 			};
1103 			return desc;
1104 		}
1105 
1106 		case VK_FORMAT_B5G6R5_UNORM_PACK16:
1107 		{
1108 			const PlanarFormatDescription	desc	=
1109 			{
1110 				1, // planes
1111 				chanR|chanG|chanB,
1112 				{
1113 				//		Size	WDiv	HDiv
1114 					{	2,		1,		1 },
1115 					{	0,		0,		0 },
1116 					{	0,		0,		0 },
1117 				},
1118 				{
1119 				//		Plane	Type	Offs	Size	Stride
1120 					{	0,		unorm,	0,		5,		2 },	// R
1121 					{	0,		unorm,	5,		6,		2 },	// G
1122 					{	0,		unorm,	11,		5,		2 },	// B
1123 					{	0,		0,		0,		0,		0 }		// A
1124 				}
1125 			};
1126 			return desc;
1127 		}
1128 
1129 		case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
1130 		{
1131 			const PlanarFormatDescription	desc	=
1132 			{
1133 				1, // planes
1134 				chanR|chanG|chanB|chanA,
1135 				{
1136 				//		Size	WDiv	HDiv
1137 					{	2,		1,		1 },
1138 					{	0,		0,		0 },
1139 					{	0,		0,		0 },
1140 				},
1141 				{
1142 				//		Plane	Type	Offs	Size	Stride
1143 					{	0,		unorm,	11,		5,		2 },	// R
1144 					{	0,		unorm,	6,		5,		2 },	// G
1145 					{	0,		unorm,	1,		5,		2 },	// B
1146 					{	0,		unorm,	0,		1,		2 }		// A
1147 				}
1148 			};
1149 			return desc;
1150 		}
1151 
1152 		case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
1153 		{
1154 			const PlanarFormatDescription	desc	=
1155 			{
1156 				1, // planes
1157 				chanR|chanG|chanB|chanA,
1158 				{
1159 				//		Size	WDiv	HDiv
1160 					{	2,		1,		1 },
1161 					{	0,		0,		0 },
1162 					{	0,		0,		0 },
1163 				},
1164 				{
1165 				//		Plane	Type	Offs	Size	Stride
1166 					{	0,		unorm,	1,		5,		2 },	// R
1167 					{	0,		unorm,	6,		5,		2 },	// G
1168 					{	0,		unorm,	11,		5,		2 },	// B
1169 					{	0,		unorm,	0,		1,		2 }		// A
1170 				}
1171 			};
1172 			return desc;
1173 		}
1174 
1175 		case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
1176 		{
1177 			const PlanarFormatDescription	desc	=
1178 			{
1179 				1, // planes
1180 				chanR|chanG|chanB|chanA,
1181 				{
1182 				//		Size	WDiv	HDiv
1183 					{	2,		1,		1 },
1184 					{	0,		0,		0 },
1185 					{	0,		0,		0 },
1186 				},
1187 				{
1188 				//		Plane	Type	Offs	Size	Stride
1189 					{	0,		unorm,	10,		5,		2 },	// R
1190 					{	0,		unorm,	5,		5,		2 },	// G
1191 					{	0,		unorm,	0,		5,		2 },	// B
1192 					{	0,		unorm,	15,		1,		2 }		// A
1193 				}
1194 			};
1195 			return desc;
1196 		}
1197 
1198 		case VK_FORMAT_R8G8B8_UNORM:
1199 		{
1200 			const PlanarFormatDescription	desc	=
1201 			{
1202 				1, // planes
1203 				chanR|chanG|chanB,
1204 				{
1205 				//		Size	WDiv	HDiv
1206 					{	3,		1,		1 },
1207 					{	0,		0,		0 },
1208 					{	0,		0,		0 },
1209 				},
1210 				{
1211 				//		Plane	Type	Offs	Size	Stride
1212 					{	0,		unorm,	0,		8,		3 },	// R
1213 					{	0,		unorm,	8,		8,		3 },	// G
1214 					{	0,		unorm,	16,		8,		3 },	// B
1215 					{	0,		0,		0,		0,		0 }		// A
1216 				}
1217 			};
1218 			return desc;
1219 		}
1220 
1221 		case VK_FORMAT_B8G8R8_UNORM:
1222 		{
1223 			const PlanarFormatDescription	desc	=
1224 			{
1225 				1, // planes
1226 				chanR|chanG|chanB,
1227 				{
1228 				//		Size	WDiv	HDiv
1229 					{	3,		1,		1 },
1230 					{	0,		0,		0 },
1231 					{	0,		0,		0 },
1232 				},
1233 				{
1234 				//		Plane	Type	Offs	Size	Stride
1235 					{	0,		unorm,	16,		8,		3 },	// R
1236 					{	0,		unorm,	8,		8,		3 },	// G
1237 					{	0,		unorm,	0,		8,		3 },	// B
1238 					{	0,		0,		0,		0,		0 }		// A
1239 				}
1240 			};
1241 			return desc;
1242 		}
1243 
1244 		case VK_FORMAT_R8G8B8A8_UNORM:
1245 		case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
1246 		{
1247 			const PlanarFormatDescription	desc	=
1248 			{
1249 				1, // planes
1250 				chanR|chanG|chanB|chanA,
1251 				{
1252 				//		Size	WDiv	HDiv
1253 					{	4,		1,		1 },
1254 					{	0,		0,		0 },
1255 					{	0,		0,		0 },
1256 				},
1257 				{
1258 				//		Plane	Type	Offs	Size	Stride
1259 					{	0,		unorm,	0,		8,		4 },	// R
1260 					{	0,		unorm,	8,		8,		4 },	// G
1261 					{	0,		unorm,	16,		8,		4 },	// B
1262 					{	0,		unorm,	24,		8,		4 }		// A
1263 				}
1264 			};
1265 			return desc;
1266 		}
1267 
1268 		case VK_FORMAT_B8G8R8A8_UNORM:
1269 		{
1270 			const PlanarFormatDescription	desc	=
1271 			{
1272 				1, // planes
1273 				chanR|chanG|chanB|chanA,
1274 				{
1275 				//		Size	WDiv	HDiv
1276 					{	4,		1,		1 },
1277 					{	0,		0,		0 },
1278 					{	0,		0,		0 },
1279 				},
1280 				{
1281 				//		Plane	Type	Offs	Size	Stride
1282 					{	0,		unorm,	16,		8,		4 },	// R
1283 					{	0,		unorm,	8,		8,		4 },	// G
1284 					{	0,		unorm,	0,		8,		4 },	// B
1285 					{	0,		unorm,	24,		8,		4 }		// A
1286 				}
1287 			};
1288 			return desc;
1289 		}
1290 
1291 		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
1292 		{
1293 			const PlanarFormatDescription	desc	=
1294 			{
1295 				1, // planes
1296 				chanR|chanG|chanB|chanA,
1297 				{
1298 				//		Size	WDiv	HDiv
1299 					{	4,		1,		1 },
1300 					{	0,		0,		0 },
1301 					{	0,		0,		0 },
1302 				},
1303 				{
1304 				//		Plane	Type	Offs	Size	Stride
1305 					{	0,		unorm,	20,		10,		4 },	// R
1306 					{	0,		unorm,	10,		10,		4 },	// G
1307 					{	0,		unorm,	0,		10,		4 },	// B
1308 					{	0,		unorm,	30,		2,		4 }		// A
1309 				}
1310 			};
1311 			return desc;
1312 		}
1313 
1314 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1315 		{
1316 			const PlanarFormatDescription	desc	=
1317 			{
1318 				1, // planes
1319 				chanR|chanG|chanB|chanA,
1320 				{
1321 				//		Size	WDiv	HDiv
1322 					{	4,		1,		1 },
1323 					{	0,		0,		0 },
1324 					{	0,		0,		0 },
1325 				},
1326 				{
1327 				//		Plane	Type	Offs	Size	Stride
1328 					{	0,		unorm,	0,		10,		4 },	// R
1329 					{	0,		unorm,	10,		10,		4 },	// G
1330 					{	0,		unorm,	20,		10,		4 },	// B
1331 					{	0,		unorm,	30,		2,		4 }		// A
1332 				}
1333 			};
1334 			return desc;
1335 		}
1336 
1337 		case VK_FORMAT_R16G16B16_UNORM:
1338 		{
1339 			const PlanarFormatDescription	desc	=
1340 			{
1341 				1, // planes
1342 				chanR|chanG|chanB,
1343 				{
1344 				//		Size	WDiv	HDiv
1345 					{	6,		1,		1 },
1346 					{	0,		0,		0 },
1347 					{	0,		0,		0 },
1348 				},
1349 				{
1350 				//		Plane	Type	Offs	Size	Stride
1351 					{	0,		unorm,	0,		16,		6 },	// R
1352 					{	0,		unorm,	16,		16,		6 },	// G
1353 					{	0,		unorm,	32,		16,		6 },	// B
1354 					{	0,		0,		0,		0,		0 }		// A
1355 				}
1356 			};
1357 			return desc;
1358 		}
1359 
1360 		case VK_FORMAT_R16G16B16A16_UNORM:
1361 		{
1362 			const PlanarFormatDescription	desc	=
1363 			{
1364 				1, // planes
1365 				chanR|chanG|chanB|chanA,
1366 				{
1367 				//		Size	WDiv	HDiv
1368 					{	8,		1,		1 },
1369 					{	0,		0,		0 },
1370 					{	0,		0,		0 },
1371 				},
1372 				{
1373 				//		Plane	Type	Offs	Size	Stride
1374 					{	0,		unorm,	0,		16,		8 },	// R
1375 					{	0,		unorm,	16,		16,		8 },	// G
1376 					{	0,		unorm,	32,		16,		8 },	// B
1377 					{	0,		unorm,	48,		16,		8 }		// A
1378 				}
1379 			};
1380 			return desc;
1381 		}
1382 
1383 		default:
1384 			TCU_THROW(InternalError, "Not implemented");
1385 	}
1386 }
1387 
getPlanarFormatDescription(VkFormat format)1388 PlanarFormatDescription getPlanarFormatDescription (VkFormat format)
1389 {
1390 	if (isYCbCrFormat(format))
1391 		return getYCbCrPlanarFormatDescription(format);
1392 	else
1393 		return getCorePlanarFormatDescription(format);
1394 }
1395 
getPlaneCount(VkFormat format)1396 int getPlaneCount (VkFormat format)
1397 {
1398 	switch (format)
1399 	{
1400 		case VK_FORMAT_G8B8G8R8_422_UNORM_KHR:
1401 		case VK_FORMAT_B8G8R8G8_422_UNORM_KHR:
1402 		case VK_FORMAT_R10X6_UNORM_PACK16_KHR:
1403 		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR:
1404 		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR:
1405 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR:
1406 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR:
1407 		case VK_FORMAT_R12X4_UNORM_PACK16_KHR:
1408 		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR:
1409 		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR:
1410 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR:
1411 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR:
1412 		case VK_FORMAT_G16B16G16R16_422_UNORM_KHR:
1413 		case VK_FORMAT_B16G16R16G16_422_UNORM_KHR:
1414 			return 1;
1415 
1416 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
1417 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR:
1418 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
1419 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR:
1420 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
1421 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR:
1422 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
1423 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR:
1424 			return 2;
1425 
1426 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
1427 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR:
1428 		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR:
1429 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
1430 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR:
1431 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR:
1432 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
1433 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR:
1434 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR:
1435 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
1436 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR:
1437 		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR:
1438 			return 3;
1439 
1440 		default:
1441 			DE_FATAL("Not YCbCr format");
1442 			return 0;
1443 	}
1444 }
1445 
getPlaneAspect(deUint32 planeNdx)1446 VkImageAspectFlagBits getPlaneAspect (deUint32 planeNdx)
1447 {
1448 	DE_ASSERT(de::inBounds(planeNdx, 0u, 3u));
1449 	return (VkImageAspectFlagBits)(VK_IMAGE_ASPECT_PLANE_0_BIT_KHR << planeNdx);
1450 }
1451 
getAspectPlaneNdx(VkImageAspectFlagBits flags)1452 deUint32 getAspectPlaneNdx (VkImageAspectFlagBits flags)
1453 {
1454 	switch (flags)
1455 	{
1456 		case VK_IMAGE_ASPECT_PLANE_0_BIT_KHR:	return 0;
1457 		case VK_IMAGE_ASPECT_PLANE_1_BIT_KHR:	return 1;
1458 		case VK_IMAGE_ASPECT_PLANE_2_BIT_KHR:	return 2;
1459 		default:
1460 			DE_FATAL("Invalid plane aspect");
1461 			return 0;
1462 	}
1463 }
1464 
isChromaSubsampled(VkFormat format)1465 bool isChromaSubsampled (VkFormat format)
1466 {
1467 	switch (format)
1468 	{
1469 		case VK_FORMAT_G8B8G8R8_422_UNORM_KHR:
1470 		case VK_FORMAT_B8G8R8G8_422_UNORM_KHR:
1471 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
1472 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
1473 		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR:
1474 		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR:
1475 		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR:
1476 		case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR:
1477 		case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR:
1478 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
1479 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
1480 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR:
1481 		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR:
1482 		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR:
1483 		case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR:
1484 		case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR:
1485 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
1486 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
1487 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR:
1488 		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR:
1489 		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR:
1490 		case VK_FORMAT_G16B16G16R16_422_UNORM_KHR:
1491 		case VK_FORMAT_B16G16R16G16_422_UNORM_KHR:
1492 		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
1493 		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
1494 		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR:
1495 		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR:
1496 		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR:
1497 			return true;
1498 
1499 		default:
1500 			return false;
1501 	}
1502 }
1503 
isSupportedByFramework(VkFormat format)1504 bool isSupportedByFramework (VkFormat format)
1505 {
1506 	if (format == VK_FORMAT_UNDEFINED || format > VK_CORE_FORMAT_LAST)
1507 		return false;
1508 
1509 	switch (format)
1510 	{
1511 		case VK_FORMAT_R64_UINT:
1512 		case VK_FORMAT_R64_SINT:
1513 		case VK_FORMAT_R64_SFLOAT:
1514 		case VK_FORMAT_R64G64_UINT:
1515 		case VK_FORMAT_R64G64_SINT:
1516 		case VK_FORMAT_R64G64_SFLOAT:
1517 		case VK_FORMAT_R64G64B64_UINT:
1518 		case VK_FORMAT_R64G64B64_SINT:
1519 		case VK_FORMAT_R64G64B64_SFLOAT:
1520 		case VK_FORMAT_R64G64B64A64_UINT:
1521 		case VK_FORMAT_R64G64B64A64_SINT:
1522 		case VK_FORMAT_R64G64B64A64_SFLOAT:
1523 			// \todo [2016-12-01 pyry] Support 64-bit channel types
1524 			return false;
1525 
1526 		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
1527 		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
1528 		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
1529 		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
1530 		case VK_FORMAT_BC2_UNORM_BLOCK:
1531 		case VK_FORMAT_BC2_SRGB_BLOCK:
1532 		case VK_FORMAT_BC3_UNORM_BLOCK:
1533 		case VK_FORMAT_BC3_SRGB_BLOCK:
1534 		case VK_FORMAT_BC4_UNORM_BLOCK:
1535 		case VK_FORMAT_BC4_SNORM_BLOCK:
1536 		case VK_FORMAT_BC5_UNORM_BLOCK:
1537 		case VK_FORMAT_BC5_SNORM_BLOCK:
1538 		case VK_FORMAT_BC6H_UFLOAT_BLOCK:
1539 		case VK_FORMAT_BC6H_SFLOAT_BLOCK:
1540 		case VK_FORMAT_BC7_UNORM_BLOCK:
1541 		case VK_FORMAT_BC7_SRGB_BLOCK:
1542 			return false;
1543 
1544 		default:
1545 			return true;
1546 	}
1547 }
1548 
mapTextureFormat(const tcu::TextureFormat & format)1549 VkFormat mapTextureFormat (const tcu::TextureFormat& format)
1550 {
1551 	DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST < (1<<16));
1552 	DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELTYPE_LAST < (1<<16));
1553 
1554 #define PACK_FMT(ORDER, TYPE) ((int(ORDER) << 16) | int(TYPE))
1555 #define FMT_CASE(ORDER, TYPE) PACK_FMT(tcu::TextureFormat::ORDER, tcu::TextureFormat::TYPE)
1556 
1557 	// update this mapping if VkFormat changes
1558 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
1559 
1560 	switch (PACK_FMT(format.order, format.type))
1561 	{
1562 		case FMT_CASE(RG, UNORM_BYTE_44):					return VK_FORMAT_R4G4_UNORM_PACK8;
1563 		case FMT_CASE(RGB, UNORM_SHORT_565):				return VK_FORMAT_R5G6B5_UNORM_PACK16;
1564 		case FMT_CASE(RGBA, UNORM_SHORT_4444):				return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
1565 		case FMT_CASE(RGBA, UNORM_SHORT_5551):				return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
1566 
1567 		case FMT_CASE(BGR, UNORM_SHORT_565):				return VK_FORMAT_B5G6R5_UNORM_PACK16;
1568 		case FMT_CASE(BGRA, UNORM_SHORT_4444):				return VK_FORMAT_B4G4R4A4_UNORM_PACK16;
1569 		case FMT_CASE(BGRA, UNORM_SHORT_5551):				return VK_FORMAT_B5G5R5A1_UNORM_PACK16;
1570 
1571 		case FMT_CASE(ARGB, UNORM_SHORT_1555):				return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
1572 
1573 		case FMT_CASE(R, UNORM_INT8):						return VK_FORMAT_R8_UNORM;
1574 		case FMT_CASE(R, SNORM_INT8):						return VK_FORMAT_R8_SNORM;
1575 		case FMT_CASE(R, UNSIGNED_INT8):					return VK_FORMAT_R8_UINT;
1576 		case FMT_CASE(R, SIGNED_INT8):						return VK_FORMAT_R8_SINT;
1577 		case FMT_CASE(sR, UNORM_INT8):						return VK_FORMAT_R8_SRGB;
1578 
1579 		case FMT_CASE(RG, UNORM_INT8):						return VK_FORMAT_R8G8_UNORM;
1580 		case FMT_CASE(RG, SNORM_INT8):						return VK_FORMAT_R8G8_SNORM;
1581 		case FMT_CASE(RG, UNSIGNED_INT8):					return VK_FORMAT_R8G8_UINT;
1582 		case FMT_CASE(RG, SIGNED_INT8):						return VK_FORMAT_R8G8_SINT;
1583 		case FMT_CASE(sRG, UNORM_INT8):						return VK_FORMAT_R8G8_SRGB;
1584 
1585 		case FMT_CASE(RGB, UNORM_INT8):						return VK_FORMAT_R8G8B8_UNORM;
1586 		case FMT_CASE(RGB, SNORM_INT8):						return VK_FORMAT_R8G8B8_SNORM;
1587 		case FMT_CASE(RGB, UNSIGNED_INT8):					return VK_FORMAT_R8G8B8_UINT;
1588 		case FMT_CASE(RGB, SIGNED_INT8):					return VK_FORMAT_R8G8B8_SINT;
1589 		case FMT_CASE(sRGB, UNORM_INT8):					return VK_FORMAT_R8G8B8_SRGB;
1590 
1591 		case FMT_CASE(RGBA, UNORM_INT8):					return VK_FORMAT_R8G8B8A8_UNORM;
1592 		case FMT_CASE(RGBA, SNORM_INT8):					return VK_FORMAT_R8G8B8A8_SNORM;
1593 		case FMT_CASE(RGBA, UNSIGNED_INT8):					return VK_FORMAT_R8G8B8A8_UINT;
1594 		case FMT_CASE(RGBA, SIGNED_INT8):					return VK_FORMAT_R8G8B8A8_SINT;
1595 		case FMT_CASE(sRGBA, UNORM_INT8):					return VK_FORMAT_R8G8B8A8_SRGB;
1596 
1597 		case FMT_CASE(RGBA, UNORM_INT_1010102_REV):			return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
1598 		case FMT_CASE(RGBA, SNORM_INT_1010102_REV):			return VK_FORMAT_A2B10G10R10_SNORM_PACK32;
1599 		case FMT_CASE(RGBA, UNSIGNED_INT_1010102_REV):		return VK_FORMAT_A2B10G10R10_UINT_PACK32;
1600 		case FMT_CASE(RGBA, SIGNED_INT_1010102_REV):		return VK_FORMAT_A2B10G10R10_SINT_PACK32;
1601 
1602 		case FMT_CASE(R, UNORM_INT16):						return VK_FORMAT_R16_UNORM;
1603 		case FMT_CASE(R, SNORM_INT16):						return VK_FORMAT_R16_SNORM;
1604 		case FMT_CASE(R, UNSIGNED_INT16):					return VK_FORMAT_R16_UINT;
1605 		case FMT_CASE(R, SIGNED_INT16):						return VK_FORMAT_R16_SINT;
1606 		case FMT_CASE(R, HALF_FLOAT):						return VK_FORMAT_R16_SFLOAT;
1607 
1608 		case FMT_CASE(RG, UNORM_INT16):						return VK_FORMAT_R16G16_UNORM;
1609 		case FMT_CASE(RG, SNORM_INT16):						return VK_FORMAT_R16G16_SNORM;
1610 		case FMT_CASE(RG, UNSIGNED_INT16):					return VK_FORMAT_R16G16_UINT;
1611 		case FMT_CASE(RG, SIGNED_INT16):					return VK_FORMAT_R16G16_SINT;
1612 		case FMT_CASE(RG, HALF_FLOAT):						return VK_FORMAT_R16G16_SFLOAT;
1613 
1614 		case FMT_CASE(RGB, UNORM_INT16):					return VK_FORMAT_R16G16B16_UNORM;
1615 		case FMT_CASE(RGB, SNORM_INT16):					return VK_FORMAT_R16G16B16_SNORM;
1616 		case FMT_CASE(RGB, UNSIGNED_INT16):					return VK_FORMAT_R16G16B16_UINT;
1617 		case FMT_CASE(RGB, SIGNED_INT16):					return VK_FORMAT_R16G16B16_SINT;
1618 		case FMT_CASE(RGB, HALF_FLOAT):						return VK_FORMAT_R16G16B16_SFLOAT;
1619 
1620 		case FMT_CASE(RGBA, UNORM_INT16):					return VK_FORMAT_R16G16B16A16_UNORM;
1621 		case FMT_CASE(RGBA, SNORM_INT16):					return VK_FORMAT_R16G16B16A16_SNORM;
1622 		case FMT_CASE(RGBA, UNSIGNED_INT16):				return VK_FORMAT_R16G16B16A16_UINT;
1623 		case FMT_CASE(RGBA, SIGNED_INT16):					return VK_FORMAT_R16G16B16A16_SINT;
1624 		case FMT_CASE(RGBA, HALF_FLOAT):					return VK_FORMAT_R16G16B16A16_SFLOAT;
1625 
1626 		case FMT_CASE(R, UNSIGNED_INT32):					return VK_FORMAT_R32_UINT;
1627 		case FMT_CASE(R, SIGNED_INT32):						return VK_FORMAT_R32_SINT;
1628 		case FMT_CASE(R, FLOAT):							return VK_FORMAT_R32_SFLOAT;
1629 
1630 		case FMT_CASE(RG, UNSIGNED_INT32):					return VK_FORMAT_R32G32_UINT;
1631 		case FMT_CASE(RG, SIGNED_INT32):					return VK_FORMAT_R32G32_SINT;
1632 		case FMT_CASE(RG, FLOAT):							return VK_FORMAT_R32G32_SFLOAT;
1633 
1634 		case FMT_CASE(RGB, UNSIGNED_INT32):					return VK_FORMAT_R32G32B32_UINT;
1635 		case FMT_CASE(RGB, SIGNED_INT32):					return VK_FORMAT_R32G32B32_SINT;
1636 		case FMT_CASE(RGB, FLOAT):							return VK_FORMAT_R32G32B32_SFLOAT;
1637 
1638 		case FMT_CASE(RGBA, UNSIGNED_INT32):				return VK_FORMAT_R32G32B32A32_UINT;
1639 		case FMT_CASE(RGBA, SIGNED_INT32):					return VK_FORMAT_R32G32B32A32_SINT;
1640 		case FMT_CASE(RGBA, FLOAT):							return VK_FORMAT_R32G32B32A32_SFLOAT;
1641 
1642 		case FMT_CASE(R, FLOAT64):							return VK_FORMAT_R64_SFLOAT;
1643 		case FMT_CASE(RG, FLOAT64):							return VK_FORMAT_R64G64_SFLOAT;
1644 		case FMT_CASE(RGB, FLOAT64):						return VK_FORMAT_R64G64B64_SFLOAT;
1645 		case FMT_CASE(RGBA, FLOAT64):						return VK_FORMAT_R64G64B64A64_SFLOAT;
1646 
1647 		case FMT_CASE(RGB, UNSIGNED_INT_11F_11F_10F_REV):	return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
1648 		case FMT_CASE(RGB, UNSIGNED_INT_999_E5_REV):		return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;
1649 
1650 		case FMT_CASE(BGR, UNORM_INT8):						return VK_FORMAT_B8G8R8_UNORM;
1651 		case FMT_CASE(BGR, SNORM_INT8):						return VK_FORMAT_B8G8R8_SNORM;
1652 		case FMT_CASE(BGR, UNSIGNED_INT8):					return VK_FORMAT_B8G8R8_UINT;
1653 		case FMT_CASE(BGR, SIGNED_INT8):					return VK_FORMAT_B8G8R8_SINT;
1654 		case FMT_CASE(sBGR, UNORM_INT8):					return VK_FORMAT_B8G8R8_SRGB;
1655 
1656 		case FMT_CASE(BGRA, UNORM_INT8):					return VK_FORMAT_B8G8R8A8_UNORM;
1657 		case FMT_CASE(BGRA, SNORM_INT8):					return VK_FORMAT_B8G8R8A8_SNORM;
1658 		case FMT_CASE(BGRA, UNSIGNED_INT8):					return VK_FORMAT_B8G8R8A8_UINT;
1659 		case FMT_CASE(BGRA, SIGNED_INT8):					return VK_FORMAT_B8G8R8A8_SINT;
1660 		case FMT_CASE(sBGRA, UNORM_INT8):					return VK_FORMAT_B8G8R8A8_SRGB;
1661 
1662 		case FMT_CASE(BGRA, UNORM_INT_1010102_REV):			return VK_FORMAT_A2R10G10B10_UNORM_PACK32;
1663 		case FMT_CASE(BGRA, SNORM_INT_1010102_REV):			return VK_FORMAT_A2R10G10B10_SNORM_PACK32;
1664 		case FMT_CASE(BGRA, UNSIGNED_INT_1010102_REV):		return VK_FORMAT_A2R10G10B10_UINT_PACK32;
1665 		case FMT_CASE(BGRA, SIGNED_INT_1010102_REV):		return VK_FORMAT_A2R10G10B10_SINT_PACK32;
1666 
1667 		case FMT_CASE(D, UNORM_INT16):						return VK_FORMAT_D16_UNORM;
1668 		case FMT_CASE(D, UNSIGNED_INT_24_8_REV):			return VK_FORMAT_X8_D24_UNORM_PACK32;
1669 		case FMT_CASE(D, FLOAT):							return VK_FORMAT_D32_SFLOAT;
1670 
1671 		case FMT_CASE(S, UNSIGNED_INT8):					return VK_FORMAT_S8_UINT;
1672 
1673 		case FMT_CASE(DS, UNSIGNED_INT_16_8_8):				return VK_FORMAT_D16_UNORM_S8_UINT;
1674 		case FMT_CASE(DS, UNSIGNED_INT_24_8_REV):			return VK_FORMAT_D24_UNORM_S8_UINT;
1675 		case FMT_CASE(DS, FLOAT_UNSIGNED_INT_24_8_REV):		return VK_FORMAT_D32_SFLOAT_S8_UINT;
1676 
1677 
1678 		case FMT_CASE(R,	UNORM_SHORT_10):				return VK_FORMAT_R10X6_UNORM_PACK16_KHR;
1679 		case FMT_CASE(RG,	UNORM_SHORT_10):				return VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR;
1680 		case FMT_CASE(RGBA,	UNORM_SHORT_10):				return VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR;
1681 
1682 		case FMT_CASE(R,	UNORM_SHORT_12):				return VK_FORMAT_R12X4_UNORM_PACK16_KHR;
1683 		case FMT_CASE(RG,	UNORM_SHORT_12):				return VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR;
1684 		case FMT_CASE(RGBA,	UNORM_SHORT_12):				return VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR;
1685 
1686 		default:
1687 			TCU_THROW(InternalError, "Unknown texture format");
1688 	}
1689 
1690 #undef PACK_FMT
1691 #undef FMT_CASE
1692 }
1693 
mapCompressedTextureFormat(const tcu::CompressedTexFormat format)1694 VkFormat mapCompressedTextureFormat (const tcu::CompressedTexFormat format)
1695 {
1696 	// update this mapping if CompressedTexFormat changes
1697 	DE_STATIC_ASSERT(tcu::COMPRESSEDTEXFORMAT_LAST == 55);
1698 
1699 	switch (format)
1700 	{
1701 		case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:						return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
1702 		case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:						return VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
1703 		case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:	return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
1704 		case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:	return VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
1705 		case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:					return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
1706 		case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:			return VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
1707 
1708 		case tcu::COMPRESSEDTEXFORMAT_EAC_R11:							return VK_FORMAT_EAC_R11_UNORM_BLOCK;
1709 		case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:					return VK_FORMAT_EAC_R11_SNORM_BLOCK;
1710 		case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:							return VK_FORMAT_EAC_R11G11_UNORM_BLOCK;
1711 		case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:					return VK_FORMAT_EAC_R11G11_SNORM_BLOCK;
1712 
1713 		case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:					return VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
1714 		case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_4x4_SRGB_BLOCK;
1715 		case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:					return VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
1716 		case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_5x4_SRGB_BLOCK;
1717 		case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:					return VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
1718 		case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_5x5_SRGB_BLOCK;
1719 		case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:					return VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
1720 		case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_6x5_SRGB_BLOCK;
1721 		case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:					return VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
1722 		case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
1723 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:					return VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
1724 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_8x5_SRGB_BLOCK;
1725 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:					return VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
1726 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_8x6_SRGB_BLOCK;
1727 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:					return VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
1728 		case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_8x8_SRGB_BLOCK;
1729 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:					return VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
1730 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_10x5_SRGB_BLOCK;
1731 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:					return VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
1732 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_10x6_SRGB_BLOCK;
1733 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:					return VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
1734 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_10x8_SRGB_BLOCK;
1735 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:					return VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
1736 		case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
1737 		case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:					return VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
1738 		case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
1739 		case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:					return VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
1740 		case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:			return VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
1741 
1742 		case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:				return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
1743 		case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:				return VK_FORMAT_BC1_RGB_SRGB_BLOCK;
1744 		case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:				return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
1745 		case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:				return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
1746 		case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:					return VK_FORMAT_BC2_UNORM_BLOCK;
1747 		case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:					return VK_FORMAT_BC2_SRGB_BLOCK;
1748 		case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:					return VK_FORMAT_BC3_UNORM_BLOCK;
1749 		case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:					return VK_FORMAT_BC3_SRGB_BLOCK;
1750 		case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:					return VK_FORMAT_BC4_UNORM_BLOCK;
1751 		case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:					return VK_FORMAT_BC4_SNORM_BLOCK;
1752 		case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:					return VK_FORMAT_BC5_UNORM_BLOCK;
1753 		case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:					return VK_FORMAT_BC5_SNORM_BLOCK;
1754 		case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:				return VK_FORMAT_BC6H_UFLOAT_BLOCK;
1755 		case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:				return VK_FORMAT_BC6H_SFLOAT_BLOCK;
1756 		case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:					return VK_FORMAT_BC7_UNORM_BLOCK;
1757 		case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:					return VK_FORMAT_BC7_SRGB_BLOCK;
1758 
1759 		default:
1760 			TCU_THROW(InternalError, "Unknown texture format");
1761 			return VK_FORMAT_UNDEFINED;
1762 	}
1763 }
1764 
mapVkFormat(VkFormat format)1765 tcu::TextureFormat mapVkFormat (VkFormat format)
1766 {
1767 	using tcu::TextureFormat;
1768 
1769 	// update this mapping if VkFormat changes
1770 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
1771 
1772 	switch (format)
1773 	{
1774 		case VK_FORMAT_R4G4_UNORM_PACK8:		return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_BYTE_44);
1775 		case VK_FORMAT_R5G6B5_UNORM_PACK16:		return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_SHORT_565);
1776 		case VK_FORMAT_R4G4B4A4_UNORM_PACK16:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_4444);
1777 		case VK_FORMAT_R5G5B5A1_UNORM_PACK16:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_5551);
1778 
1779 		case VK_FORMAT_B5G6R5_UNORM_PACK16:		return TextureFormat(TextureFormat::BGR,	TextureFormat::UNORM_SHORT_565);
1780 		case VK_FORMAT_B4G4R4A4_UNORM_PACK16:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_SHORT_4444);
1781 		case VK_FORMAT_B5G5R5A1_UNORM_PACK16:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_SHORT_5551);
1782 
1783 		case VK_FORMAT_A1R5G5B5_UNORM_PACK16:	return TextureFormat(TextureFormat::ARGB,	TextureFormat::UNORM_SHORT_1555);
1784 
1785 		case VK_FORMAT_R8_UNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::UNORM_INT8);
1786 		case VK_FORMAT_R8_SNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::SNORM_INT8);
1787 		case VK_FORMAT_R8_USCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT8);
1788 		case VK_FORMAT_R8_SSCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT8);
1789 		case VK_FORMAT_R8_UINT:					return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT8);
1790 		case VK_FORMAT_R8_SINT:					return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT8);
1791 		case VK_FORMAT_R8_SRGB:					return TextureFormat(TextureFormat::sR,		TextureFormat::UNORM_INT8);
1792 
1793 		case VK_FORMAT_R8G8_UNORM:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_INT8);
1794 		case VK_FORMAT_R8G8_SNORM:				return TextureFormat(TextureFormat::RG,		TextureFormat::SNORM_INT8);
1795 		case VK_FORMAT_R8G8_USCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT8);
1796 		case VK_FORMAT_R8G8_SSCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT8);
1797 		case VK_FORMAT_R8G8_UINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT8);
1798 		case VK_FORMAT_R8G8_SINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT8);
1799 		case VK_FORMAT_R8G8_SRGB:				return TextureFormat(TextureFormat::sRG,	TextureFormat::UNORM_INT8);
1800 
1801 		case VK_FORMAT_R8G8B8_UNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT8);
1802 		case VK_FORMAT_R8G8B8_SNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SNORM_INT8);
1803 		case VK_FORMAT_R8G8B8_USCALED:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT8);
1804 		case VK_FORMAT_R8G8B8_SSCALED:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT8);
1805 		case VK_FORMAT_R8G8B8_UINT:				return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT8);
1806 		case VK_FORMAT_R8G8B8_SINT:				return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT8);
1807 		case VK_FORMAT_R8G8B8_SRGB:				return TextureFormat(TextureFormat::sRGB,	TextureFormat::UNORM_INT8);
1808 
1809 		case VK_FORMAT_R8G8B8A8_UNORM:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
1810 		case VK_FORMAT_R8G8B8A8_SNORM:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT8);
1811 		case VK_FORMAT_R8G8B8A8_USCALED:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT8);
1812 		case VK_FORMAT_R8G8B8A8_SSCALED:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT8);
1813 		case VK_FORMAT_R8G8B8A8_UINT:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT8);
1814 		case VK_FORMAT_R8G8B8A8_SINT:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT8);
1815 		case VK_FORMAT_R8G8B8A8_SRGB:			return TextureFormat(TextureFormat::sRGBA,	TextureFormat::UNORM_INT8);
1816 
1817 		case VK_FORMAT_R16_UNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::UNORM_INT16);
1818 		case VK_FORMAT_R16_SNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::SNORM_INT16);
1819 		case VK_FORMAT_R16_USCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT16);
1820 		case VK_FORMAT_R16_SSCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT16);
1821 		case VK_FORMAT_R16_UINT:				return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT16);
1822 		case VK_FORMAT_R16_SINT:				return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT16);
1823 		case VK_FORMAT_R16_SFLOAT:				return TextureFormat(TextureFormat::R,		TextureFormat::HALF_FLOAT);
1824 
1825 		case VK_FORMAT_R16G16_UNORM:			return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_INT16);
1826 		case VK_FORMAT_R16G16_SNORM:			return TextureFormat(TextureFormat::RG,		TextureFormat::SNORM_INT16);
1827 		case VK_FORMAT_R16G16_USCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT16);
1828 		case VK_FORMAT_R16G16_SSCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT16);
1829 		case VK_FORMAT_R16G16_UINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT16);
1830 		case VK_FORMAT_R16G16_SINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT16);
1831 		case VK_FORMAT_R16G16_SFLOAT:			return TextureFormat(TextureFormat::RG,		TextureFormat::HALF_FLOAT);
1832 
1833 		case VK_FORMAT_R16G16B16_UNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT16);
1834 		case VK_FORMAT_R16G16B16_SNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SNORM_INT16);
1835 		case VK_FORMAT_R16G16B16_USCALED:		return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT16);
1836 		case VK_FORMAT_R16G16B16_SSCALED:		return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT16);
1837 		case VK_FORMAT_R16G16B16_UINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT16);
1838 		case VK_FORMAT_R16G16B16_SINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT16);
1839 		case VK_FORMAT_R16G16B16_SFLOAT:		return TextureFormat(TextureFormat::RGB,	TextureFormat::HALF_FLOAT);
1840 
1841 		case VK_FORMAT_R16G16B16A16_UNORM:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT16);
1842 		case VK_FORMAT_R16G16B16A16_SNORM:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT16);
1843 		case VK_FORMAT_R16G16B16A16_USCALED:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT16);
1844 		case VK_FORMAT_R16G16B16A16_SSCALED:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT16);
1845 		case VK_FORMAT_R16G16B16A16_UINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT16);
1846 		case VK_FORMAT_R16G16B16A16_SINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT16);
1847 		case VK_FORMAT_R16G16B16A16_SFLOAT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::HALF_FLOAT);
1848 
1849 		case VK_FORMAT_R32_UINT:				return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT32);
1850 		case VK_FORMAT_R32_SINT:				return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT32);
1851 		case VK_FORMAT_R32_SFLOAT:				return TextureFormat(TextureFormat::R,		TextureFormat::FLOAT);
1852 
1853 		case VK_FORMAT_R32G32_UINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT32);
1854 		case VK_FORMAT_R32G32_SINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT32);
1855 		case VK_FORMAT_R32G32_SFLOAT:			return TextureFormat(TextureFormat::RG,		TextureFormat::FLOAT);
1856 
1857 		case VK_FORMAT_R32G32B32_UINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT32);
1858 		case VK_FORMAT_R32G32B32_SINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT32);
1859 		case VK_FORMAT_R32G32B32_SFLOAT:		return TextureFormat(TextureFormat::RGB,	TextureFormat::FLOAT);
1860 
1861 		case VK_FORMAT_R32G32B32A32_UINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT32);
1862 		case VK_FORMAT_R32G32B32A32_SINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT32);
1863 		case VK_FORMAT_R32G32B32A32_SFLOAT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::FLOAT);
1864 
1865 		case VK_FORMAT_R64_SFLOAT:				return TextureFormat(TextureFormat::R,		TextureFormat::FLOAT64);
1866 		case VK_FORMAT_R64G64_SFLOAT:			return TextureFormat(TextureFormat::RG,		TextureFormat::FLOAT64);
1867 		case VK_FORMAT_R64G64B64_SFLOAT:		return TextureFormat(TextureFormat::RGB,	TextureFormat::FLOAT64);
1868 		case VK_FORMAT_R64G64B64A64_SFLOAT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::FLOAT64);
1869 
1870 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:	return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT_11F_11F_10F_REV);
1871 		case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:	return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT_999_E5_REV);
1872 
1873 		case VK_FORMAT_B8G8R8_UNORM:			return TextureFormat(TextureFormat::BGR,	TextureFormat::UNORM_INT8);
1874 		case VK_FORMAT_B8G8R8_SNORM:			return TextureFormat(TextureFormat::BGR,	TextureFormat::SNORM_INT8);
1875 		case VK_FORMAT_B8G8R8_USCALED:			return TextureFormat(TextureFormat::BGR,	TextureFormat::UNSIGNED_INT8);
1876 		case VK_FORMAT_B8G8R8_SSCALED:			return TextureFormat(TextureFormat::BGR,	TextureFormat::SIGNED_INT8);
1877 		case VK_FORMAT_B8G8R8_UINT:				return TextureFormat(TextureFormat::BGR,	TextureFormat::UNSIGNED_INT8);
1878 		case VK_FORMAT_B8G8R8_SINT:				return TextureFormat(TextureFormat::BGR,	TextureFormat::SIGNED_INT8);
1879 		case VK_FORMAT_B8G8R8_SRGB:				return TextureFormat(TextureFormat::sBGR,	TextureFormat::UNORM_INT8);
1880 
1881 		case VK_FORMAT_B8G8R8A8_UNORM:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_INT8);
1882 		case VK_FORMAT_B8G8R8A8_SNORM:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::SNORM_INT8);
1883 		case VK_FORMAT_B8G8R8A8_USCALED:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNSIGNED_INT8);
1884 		case VK_FORMAT_B8G8R8A8_SSCALED:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::SIGNED_INT8);
1885 		case VK_FORMAT_B8G8R8A8_UINT:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNSIGNED_INT8);
1886 		case VK_FORMAT_B8G8R8A8_SINT:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::SIGNED_INT8);
1887 		case VK_FORMAT_B8G8R8A8_SRGB:			return TextureFormat(TextureFormat::sBGRA,	TextureFormat::UNORM_INT8);
1888 
1889 		case VK_FORMAT_D16_UNORM:				return TextureFormat(TextureFormat::D,		TextureFormat::UNORM_INT16);
1890 		case VK_FORMAT_X8_D24_UNORM_PACK32:		return TextureFormat(TextureFormat::D,		TextureFormat::UNSIGNED_INT_24_8_REV);
1891 		case VK_FORMAT_D32_SFLOAT:				return TextureFormat(TextureFormat::D,		TextureFormat::FLOAT);
1892 
1893 		case VK_FORMAT_S8_UINT:					return TextureFormat(TextureFormat::S,		TextureFormat::UNSIGNED_INT8);
1894 
1895 		// \note There is no standard interleaved memory layout for DS formats; buffer-image copies
1896 		//		 will always operate on either D or S aspect only. See Khronos bug 12998
1897 		case VK_FORMAT_D16_UNORM_S8_UINT:		return TextureFormat(TextureFormat::DS,		TextureFormat::UNSIGNED_INT_16_8_8);
1898 		case VK_FORMAT_D24_UNORM_S8_UINT:		return TextureFormat(TextureFormat::DS,		TextureFormat::UNSIGNED_INT_24_8_REV);
1899 		case VK_FORMAT_D32_SFLOAT_S8_UINT:		return TextureFormat(TextureFormat::DS,		TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV);
1900 
1901 #if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
1902 		case VK_FORMAT_A8B8G8R8_UNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
1903 		case VK_FORMAT_A8B8G8R8_SNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT8);
1904 		case VK_FORMAT_A8B8G8R8_USCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT8);
1905 		case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT8);
1906 		case VK_FORMAT_A8B8G8R8_UINT_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT8);
1907 		case VK_FORMAT_A8B8G8R8_SINT_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT8);
1908 		case VK_FORMAT_A8B8G8R8_SRGB_PACK32:	return TextureFormat(TextureFormat::sRGBA,	TextureFormat::UNORM_INT8);
1909 #else
1910 #	error "Big-endian not supported"
1911 #endif
1912 
1913 		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_INT_1010102_REV);
1914 		case VK_FORMAT_A2R10G10B10_SNORM_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::SNORM_INT_1010102_REV);
1915 		case VK_FORMAT_A2R10G10B10_USCALED_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNSIGNED_INT_1010102_REV);
1916 		case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::SIGNED_INT_1010102_REV);
1917 		case VK_FORMAT_A2R10G10B10_UINT_PACK32:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNSIGNED_INT_1010102_REV);
1918 		case VK_FORMAT_A2R10G10B10_SINT_PACK32:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::SIGNED_INT_1010102_REV);
1919 
1920 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT_1010102_REV);
1921 		case VK_FORMAT_A2B10G10R10_SNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT_1010102_REV);
1922 		case VK_FORMAT_A2B10G10R10_USCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT_1010102_REV);
1923 		case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT_1010102_REV);
1924 		case VK_FORMAT_A2B10G10R10_UINT_PACK32:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT_1010102_REV);
1925 		case VK_FORMAT_A2B10G10R10_SINT_PACK32:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT_1010102_REV);
1926 
1927 		// YCbCr formats that can be mapped
1928 		case VK_FORMAT_R10X6_UNORM_PACK16_KHR:					return TextureFormat(TextureFormat::R,		TextureFormat::UNORM_SHORT_10);
1929 		case VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR:			return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_SHORT_10);
1930 		case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_10);
1931 
1932 		case VK_FORMAT_R12X4_UNORM_PACK16_KHR:					return TextureFormat(TextureFormat::R,		TextureFormat::UNORM_SHORT_12);
1933 		case VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR:			return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_SHORT_12);
1934 		case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_12);
1935 
1936 		default:
1937 			TCU_THROW(InternalError, "Unknown image format");
1938 	}
1939 }
1940 
mapVkCompressedFormat(VkFormat format)1941 tcu::CompressedTexFormat mapVkCompressedFormat (VkFormat format)
1942 {
1943 	// update this mapping if VkFormat changes
1944 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
1945 
1946 	switch (format)
1947 	{
1948 		case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8;
1949 		case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8;
1950 		case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1;
1951 		case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1;
1952 		case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8;
1953 		case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8;
1954 
1955 		case VK_FORMAT_EAC_R11_UNORM_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_EAC_R11;
1956 		case VK_FORMAT_EAC_R11_SNORM_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11;
1957 		case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_EAC_RG11;
1958 		case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11;
1959 
1960 		case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA;
1961 		case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8;
1962 		case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA;
1963 		case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8;
1964 		case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA;
1965 		case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8;
1966 		case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA;
1967 		case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8;
1968 		case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA;
1969 		case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8;
1970 		case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA;
1971 		case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8;
1972 		case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA;
1973 		case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8;
1974 		case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA;
1975 		case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8;
1976 		case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA;
1977 		case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8;
1978 		case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA;
1979 		case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8;
1980 		case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA;
1981 		case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8;
1982 		case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA;
1983 		case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8;
1984 		case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA;
1985 		case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8;
1986 		case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA;
1987 		case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8;
1988 
1989 		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK;
1990 		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK;
1991 		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK;
1992 		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK;
1993 		case VK_FORMAT_BC2_UNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK;
1994 		case VK_FORMAT_BC2_SRGB_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK;
1995 		case VK_FORMAT_BC3_UNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK;
1996 		case VK_FORMAT_BC3_SRGB_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK;
1997 		case VK_FORMAT_BC4_UNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK;
1998 		case VK_FORMAT_BC4_SNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK;
1999 		case VK_FORMAT_BC5_UNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK;
2000 		case VK_FORMAT_BC5_SNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK;
2001 		case VK_FORMAT_BC6H_UFLOAT_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK;
2002 		case VK_FORMAT_BC6H_SFLOAT_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK;
2003 		case VK_FORMAT_BC7_UNORM_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK;
2004 		case VK_FORMAT_BC7_SRGB_BLOCK:				return tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK;
2005 
2006 		default:
2007 			TCU_THROW(InternalError, "Unknown image format");
2008 			return tcu::COMPRESSEDTEXFORMAT_LAST;
2009 	}
2010 }
2011 
isScaledFormat(VkFormat format)2012 static bool isScaledFormat (VkFormat format)
2013 {
2014 	// update this mapping if VkFormat changes
2015 	DE_STATIC_ASSERT(VK_CORE_FORMAT_LAST == 185);
2016 
2017 	switch (format)
2018 	{
2019 		case VK_FORMAT_R8_USCALED:
2020 		case VK_FORMAT_R8_SSCALED:
2021 		case VK_FORMAT_R8G8_USCALED:
2022 		case VK_FORMAT_R8G8_SSCALED:
2023 		case VK_FORMAT_R8G8B8_USCALED:
2024 		case VK_FORMAT_R8G8B8_SSCALED:
2025 		case VK_FORMAT_R8G8B8A8_USCALED:
2026 		case VK_FORMAT_R8G8B8A8_SSCALED:
2027 		case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
2028 		case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
2029 		case VK_FORMAT_R16_USCALED:
2030 		case VK_FORMAT_R16_SSCALED:
2031 		case VK_FORMAT_R16G16_USCALED:
2032 		case VK_FORMAT_R16G16_SSCALED:
2033 		case VK_FORMAT_R16G16B16_USCALED:
2034 		case VK_FORMAT_R16G16B16_SSCALED:
2035 		case VK_FORMAT_R16G16B16A16_USCALED:
2036 		case VK_FORMAT_R16G16B16A16_SSCALED:
2037 		case VK_FORMAT_B8G8R8_USCALED:
2038 		case VK_FORMAT_B8G8R8_SSCALED:
2039 		case VK_FORMAT_B8G8R8A8_USCALED:
2040 		case VK_FORMAT_B8G8R8A8_SSCALED:
2041 		case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
2042 		case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
2043 			return true;
2044 
2045 		default:
2046 			return false;
2047 	}
2048 }
2049 
fullTextureFormatRoundTripSupported(VkFormat format)2050 static bool fullTextureFormatRoundTripSupported (VkFormat format)
2051 {
2052 	if (isScaledFormat(format))
2053 	{
2054 		// *SCALED formats get mapped to correspoding (u)int formats since
2055 		// accessing them through (float) getPixel/setPixel has same behavior
2056 		// as in shader access in Vulkan.
2057 		// Unfortunately full round-trip between tcu::TextureFormat and VkFormat
2058 		// for most SCALED formats is not supported though.
2059 
2060 		const tcu::TextureFormat	tcuFormat	= mapVkFormat(format);
2061 
2062 		switch (tcuFormat.type)
2063 		{
2064 			case tcu::TextureFormat::UNSIGNED_INT8:
2065 			case tcu::TextureFormat::UNSIGNED_INT16:
2066 			case tcu::TextureFormat::UNSIGNED_INT32:
2067 			case tcu::TextureFormat::SIGNED_INT8:
2068 			case tcu::TextureFormat::SIGNED_INT16:
2069 			case tcu::TextureFormat::SIGNED_INT32:
2070 			case tcu::TextureFormat::UNSIGNED_INT_1010102_REV:
2071 			case tcu::TextureFormat::SIGNED_INT_1010102_REV:
2072 				return false;
2073 
2074 			default:
2075 				return true;
2076 		}
2077 	}
2078 	else
2079 	{
2080 		switch (format)
2081 		{
2082 			case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
2083 			case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
2084 			case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
2085 			case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
2086 			case VK_FORMAT_A8B8G8R8_UINT_PACK32:
2087 			case VK_FORMAT_A8B8G8R8_SINT_PACK32:
2088 			case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
2089 				return false; // These map to regular byte array formats
2090 
2091 			default:
2092 				break;
2093 		}
2094 
2095 		return (format != VK_FORMAT_UNDEFINED);
2096 	}
2097 }
2098 
getChannelAccessFormat(tcu::TextureChannelClass type,deUint32 offsetBits,deUint32 sizeBits)2099 tcu::TextureFormat getChannelAccessFormat (tcu::TextureChannelClass	type,
2100 										   deUint32					offsetBits,
2101 										   deUint32					sizeBits)
2102 {
2103 	using tcu::TextureFormat;
2104 
2105 	if (offsetBits == 0)
2106 	{
2107 		static const TextureFormat::ChannelType	s_size8[tcu::TEXTURECHANNELCLASS_LAST] =
2108 		{
2109 			TextureFormat::SNORM_INT8,			// snorm
2110 			TextureFormat::UNORM_INT8,			// unorm
2111 			TextureFormat::SIGNED_INT8,			// sint
2112 			TextureFormat::UNSIGNED_INT8,		// uint
2113 			TextureFormat::CHANNELTYPE_LAST,	// float
2114 		};
2115 		static const TextureFormat::ChannelType	s_size16[tcu::TEXTURECHANNELCLASS_LAST] =
2116 		{
2117 			TextureFormat::SNORM_INT16,			// snorm
2118 			TextureFormat::UNORM_INT16,			// unorm
2119 			TextureFormat::SIGNED_INT16,		// sint
2120 			TextureFormat::UNSIGNED_INT16,		// uint
2121 			TextureFormat::HALF_FLOAT,			// float
2122 		};
2123 		static const TextureFormat::ChannelType	s_size32[tcu::TEXTURECHANNELCLASS_LAST] =
2124 		{
2125 			TextureFormat::SNORM_INT32,			// snorm
2126 			TextureFormat::UNORM_INT32,			// unorm
2127 			TextureFormat::SIGNED_INT32,		// sint
2128 			TextureFormat::UNSIGNED_INT32,		// uint
2129 			TextureFormat::FLOAT,				// float
2130 		};
2131 
2132 		TextureFormat::ChannelType	chnType		= TextureFormat::CHANNELTYPE_LAST;
2133 
2134 		if (sizeBits == 8)
2135 			chnType = s_size8[type];
2136 		else if (sizeBits == 16)
2137 			chnType = s_size16[type];
2138 		else if (sizeBits == 32)
2139 			chnType = s_size32[type];
2140 
2141 		if (chnType != TextureFormat::CHANNELTYPE_LAST)
2142 			return TextureFormat(TextureFormat::R, chnType);
2143 	}
2144 	else
2145 	{
2146 		if (type		== tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT	&&
2147 			offsetBits	== 6												&&
2148 			sizeBits	== 10)
2149 			return TextureFormat(TextureFormat::R, TextureFormat::UNORM_SHORT_10);
2150 		else if (type		== tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT	&&
2151 				 offsetBits	== 4												&&
2152 				 sizeBits	== 12)
2153 			return TextureFormat(TextureFormat::R, TextureFormat::UNORM_SHORT_12);
2154 	}
2155 
2156 	TCU_THROW(InternalError, "Channel access format is not supported");
2157 }
2158 
getChannelAccess(const PlanarFormatDescription & formatInfo,const tcu::UVec2 & size,const deUint32 * planeRowPitches,void * const * planePtrs,deUint32 channelNdx)2159 tcu::PixelBufferAccess getChannelAccess (const PlanarFormatDescription&	formatInfo,
2160 										 const tcu::UVec2&				size,
2161 										 const deUint32*				planeRowPitches,
2162 										 void* const*					planePtrs,
2163 										 deUint32						channelNdx)
2164 {
2165 	DE_ASSERT(formatInfo.hasChannelNdx(channelNdx));
2166 
2167 	const deUint32	planeNdx			= formatInfo.channels[channelNdx].planeNdx;
2168 	const deUint32	planeOffsetBytes	= formatInfo.channels[channelNdx].offsetBits / 8;
2169 	const deUint32	valueOffsetBits		= formatInfo.channels[channelNdx].offsetBits % 8;
2170 	const deUint32	pixelStrideBytes	= formatInfo.channels[channelNdx].strideBytes;
2171 
2172 	DE_ASSERT(size.x() % formatInfo.planes[planeNdx].widthDivisor == 0);
2173 	DE_ASSERT(size.y() % formatInfo.planes[planeNdx].heightDivisor == 0);
2174 
2175 	deUint32		accessWidth			= size.x() / formatInfo.planes[planeNdx].widthDivisor;
2176 	const deUint32	accessHeight		= size.y() / formatInfo.planes[planeNdx].heightDivisor;
2177 	const deUint32	elementSizeBytes	= formatInfo.planes[planeNdx].elementSizeBytes;
2178 
2179 	const deUint32	rowPitch			= planeRowPitches[planeNdx];
2180 
2181 	if (pixelStrideBytes != elementSizeBytes)
2182 	{
2183 		DE_ASSERT(elementSizeBytes % pixelStrideBytes == 0);
2184 		accessWidth *= elementSizeBytes/pixelStrideBytes;
2185 	}
2186 
2187 	return tcu::PixelBufferAccess(getChannelAccessFormat((tcu::TextureChannelClass)formatInfo.channels[channelNdx].type,
2188 														 valueOffsetBits,
2189 														 formatInfo.channels[channelNdx].sizeBits),
2190 								  tcu::IVec3((int)accessWidth, (int)accessHeight, 1),
2191 								  tcu::IVec3((int)pixelStrideBytes, (int)rowPitch, 0),
2192 								  (deUint8*)planePtrs[planeNdx] + planeOffsetBytes);
2193 }
2194 
2195 
getChannelAccess(const PlanarFormatDescription & formatInfo,const tcu::UVec2 & size,const deUint32 * planeRowPitches,const void * const * planePtrs,deUint32 channelNdx)2196 tcu::ConstPixelBufferAccess getChannelAccess (const PlanarFormatDescription&	formatInfo,
2197 											  const tcu::UVec2&					size,
2198 											  const deUint32*					planeRowPitches,
2199 											  const void* const*				planePtrs,
2200 											  deUint32							channelNdx)
2201 {
2202 	return getChannelAccess(formatInfo, size, planeRowPitches, const_cast<void* const*>(planePtrs), channelNdx);
2203 }
2204 
imageUtilSelfTest(void)2205 void imageUtilSelfTest (void)
2206 {
2207 	for (int formatNdx = 0; formatNdx < VK_CORE_FORMAT_LAST; formatNdx++)
2208 	{
2209 		const VkFormat	format	= (VkFormat)formatNdx;
2210 
2211 		if (format == VK_FORMAT_R64_UINT			||
2212 			format == VK_FORMAT_R64_SINT			||
2213 			format == VK_FORMAT_R64G64_UINT			||
2214 			format == VK_FORMAT_R64G64_SINT			||
2215 			format == VK_FORMAT_R64G64B64_UINT		||
2216 			format == VK_FORMAT_R64G64B64_SINT		||
2217 			format == VK_FORMAT_R64G64B64A64_UINT	||
2218 			format == VK_FORMAT_R64G64B64A64_SINT)
2219 			continue; // \todo [2015-12-05 pyry] Add framework support for (u)int64 channel type
2220 
2221 		if (format != VK_FORMAT_UNDEFINED && !isCompressedFormat(format))
2222 		{
2223 			const tcu::TextureFormat	tcuFormat		= mapVkFormat(format);
2224 			const VkFormat				remappedFormat	= mapTextureFormat(tcuFormat);
2225 
2226 			DE_TEST_ASSERT(isValid(tcuFormat));
2227 
2228 			if (fullTextureFormatRoundTripSupported(format))
2229 				DE_TEST_ASSERT(format == remappedFormat);
2230 		}
2231 	}
2232 
2233 	for (int formatNdx = VK_FORMAT_G8B8G8R8_422_UNORM_KHR; formatNdx <= VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR; formatNdx++)
2234 	{
2235 		const VkFormat					format	= (VkFormat)formatNdx;
2236 		const PlanarFormatDescription&	info	= getPlanarFormatDescription(format);
2237 
2238 		DE_TEST_ASSERT(isYCbCrFormat(format));
2239 		DE_TEST_ASSERT(de::inRange<deUint8>(info.numPlanes, 1u, 3u));
2240 		DE_TEST_ASSERT(info.numPlanes == getPlaneCount(format));
2241 	}
2242 }
2243 
2244 struct CompressedFormatParameters
2245 {
2246 	VkFormat	format;
2247 	deUint32	blockBytes;
2248 	deUint32	blockWidth;
2249 	deUint32	blockHeight;
2250 };
2251 
2252 CompressedFormatParameters	compressedFormatParameters[VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_BC1_RGB_UNORM_BLOCK + 1] =
2253 {
2254 	{ VK_FORMAT_BC1_RGB_UNORM_BLOCK,		8,	4,	4 },
2255 	{ VK_FORMAT_BC1_RGB_SRGB_BLOCK,			8,	4,	4 },
2256 	{ VK_FORMAT_BC1_RGBA_UNORM_BLOCK,		8,	4,	4 },
2257 	{ VK_FORMAT_BC1_RGBA_SRGB_BLOCK,		8,	4,	4 },
2258 	{ VK_FORMAT_BC2_UNORM_BLOCK,			16,	4,	4 },
2259 	{ VK_FORMAT_BC2_SRGB_BLOCK,				16,	4,	4 },
2260 	{ VK_FORMAT_BC3_UNORM_BLOCK,			16,	4,	4 },
2261 	{ VK_FORMAT_BC3_SRGB_BLOCK,				16,	4,	4 },
2262 	{ VK_FORMAT_BC4_UNORM_BLOCK,			8,	4,	4 },
2263 	{ VK_FORMAT_BC4_SNORM_BLOCK,			8,	4,	4 },
2264 	{ VK_FORMAT_BC5_UNORM_BLOCK,			16,	4,	4 },
2265 	{ VK_FORMAT_BC5_SNORM_BLOCK,			16,	4,	4 },
2266 	{ VK_FORMAT_BC6H_UFLOAT_BLOCK,			16,	4,	4 },
2267 	{ VK_FORMAT_BC6H_SFLOAT_BLOCK,			16,	4,	4 },
2268 	{ VK_FORMAT_BC7_UNORM_BLOCK,			16,	4,	4 },
2269 	{ VK_FORMAT_BC7_SRGB_BLOCK,				16,	4,	4 },
2270 	{ VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,	8,	4,	4 },
2271 	{ VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,		8,	4,	4 },
2272 	{ VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,	8,	4,	4 },
2273 	{ VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,	8,	4,	4 },
2274 	{ VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,	16,	4,	4 },
2275 	{ VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,	16,	4,	4 },
2276 	{ VK_FORMAT_EAC_R11_UNORM_BLOCK,		8,	4,	4 },
2277 	{ VK_FORMAT_EAC_R11_SNORM_BLOCK,		8,	4,	4 },
2278 	{ VK_FORMAT_EAC_R11G11_UNORM_BLOCK,		16,	4,	4 },
2279 	{ VK_FORMAT_EAC_R11G11_SNORM_BLOCK,		16,	4,	4 },
2280 	{ VK_FORMAT_ASTC_4x4_UNORM_BLOCK,		16,	4,	4 },
2281 	{ VK_FORMAT_ASTC_4x4_SRGB_BLOCK,		16,	4,	4 },
2282 	{ VK_FORMAT_ASTC_5x4_UNORM_BLOCK,		16,	5,	4 },
2283 	{ VK_FORMAT_ASTC_5x4_SRGB_BLOCK,		16,	5,	4 },
2284 	{ VK_FORMAT_ASTC_5x5_UNORM_BLOCK,		16,	5,	5 },
2285 	{ VK_FORMAT_ASTC_5x5_SRGB_BLOCK,		16,	5,	5 },
2286 	{ VK_FORMAT_ASTC_6x5_UNORM_BLOCK,		16,	6,	5 },
2287 	{ VK_FORMAT_ASTC_6x5_SRGB_BLOCK,		16,	6,	5 },
2288 	{ VK_FORMAT_ASTC_6x6_UNORM_BLOCK,		16,	6,	6 },
2289 	{ VK_FORMAT_ASTC_6x6_SRGB_BLOCK,		16,	6,	6 },
2290 	{ VK_FORMAT_ASTC_8x5_UNORM_BLOCK,		16,	8,	5 },
2291 	{ VK_FORMAT_ASTC_8x5_SRGB_BLOCK,		16,	8,	5 },
2292 	{ VK_FORMAT_ASTC_8x6_UNORM_BLOCK,		16,	8,	6 },
2293 	{ VK_FORMAT_ASTC_8x6_SRGB_BLOCK,		16,	8,	6 },
2294 	{ VK_FORMAT_ASTC_8x8_UNORM_BLOCK,		16,	8,	8 },
2295 	{ VK_FORMAT_ASTC_8x8_SRGB_BLOCK,		16,	8,	8 },
2296 	{ VK_FORMAT_ASTC_10x5_UNORM_BLOCK,		16,	10,	5 },
2297 	{ VK_FORMAT_ASTC_10x5_SRGB_BLOCK,		16,	10,	5 },
2298 	{ VK_FORMAT_ASTC_10x6_UNORM_BLOCK,		16,	10,	6 },
2299 	{ VK_FORMAT_ASTC_10x6_SRGB_BLOCK,		16,	10,	6 },
2300 	{ VK_FORMAT_ASTC_10x8_UNORM_BLOCK,		16,	10,	8 },
2301 	{ VK_FORMAT_ASTC_10x8_SRGB_BLOCK,		16,	10,	8 },
2302 	{ VK_FORMAT_ASTC_10x10_UNORM_BLOCK,		16,	10,	10 },
2303 	{ VK_FORMAT_ASTC_10x10_SRGB_BLOCK,		16,	10,	10 },
2304 	{ VK_FORMAT_ASTC_12x10_UNORM_BLOCK,		16,	12,	10 },
2305 	{ VK_FORMAT_ASTC_12x10_SRGB_BLOCK,		16,	12,	10 },
2306 	{ VK_FORMAT_ASTC_12x12_UNORM_BLOCK,		16,	12,	12 },
2307 	{ VK_FORMAT_ASTC_12x12_SRGB_BLOCK,		16,	12,	12 }
2308 };
2309 
getFormatComponentWidth(const VkFormat format,const deUint32 componentNdx)2310 deUint32 getFormatComponentWidth (const VkFormat format, const deUint32 componentNdx)
2311 {
2312 	const tcu::TextureFormat	tcuFormat		(mapVkFormat(format));
2313 	const deUint32				componentCount	(tcu::getNumUsedChannels(tcuFormat.order));
2314 
2315 	if (componentNdx >= componentCount)
2316 		DE_FATAL("Component index out of range");
2317 	else
2318 	{
2319 		switch (tcuFormat.type)
2320 		{
2321 			case tcu::TextureFormat::UNORM_INT8:
2322 			case tcu::TextureFormat::SNORM_INT8:
2323 			case tcu::TextureFormat::UNSIGNED_INT8:
2324 			case tcu::TextureFormat::SIGNED_INT8:
2325 				return 8;
2326 
2327 			case tcu::TextureFormat::UNORM_SHORT_12:
2328 				return 12;
2329 
2330 			case tcu::TextureFormat::UNORM_INT16:
2331 			case tcu::TextureFormat::SNORM_INT16:
2332 			case tcu::TextureFormat::UNSIGNED_INT16:
2333 			case tcu::TextureFormat::SIGNED_INT16:
2334 				return 16;
2335 
2336 			case tcu::TextureFormat::UNORM_INT24:
2337 			case tcu::TextureFormat::UNSIGNED_INT24:
2338 				return 24;
2339 
2340 			case tcu::TextureFormat::UNORM_INT32:
2341 			case tcu::TextureFormat::SNORM_INT32:
2342 			case tcu::TextureFormat::UNSIGNED_INT32:
2343 			case tcu::TextureFormat::SIGNED_INT32:
2344 				return 32;
2345 
2346 			case tcu::TextureFormat::FLOAT64:
2347 			return 64;
2348 
2349 			// Packed formats
2350 			case tcu::TextureFormat::UNORM_SHORT_4444:
2351 			case tcu::TextureFormat::UNSIGNED_SHORT_4444:
2352 			return 4;
2353 
2354 			case tcu::TextureFormat::UNORM_SHORT_565:
2355 			case tcu::TextureFormat::UNSIGNED_SHORT_565:
2356 				return (componentNdx == 1 ? 6 : 5);
2357 
2358 			case tcu::TextureFormat::UNSIGNED_INT_24_8:
2359 			case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
2360 			case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
2361 				return (componentNdx == 0 ? 24 : 8);
2362 
2363 			case tcu::TextureFormat::UNORM_SHORT_1555:
2364 				return (componentNdx == 0 ? 1 : 5);
2365 
2366 			case tcu::TextureFormat::UNORM_INT_1010102_REV:
2367 			case tcu::TextureFormat::SNORM_INT_1010102_REV:
2368 			case tcu::TextureFormat::UNSIGNED_INT_1010102_REV:
2369 			case tcu::TextureFormat::SIGNED_INT_1010102_REV:
2370 				return (componentNdx == 3 ? 2 : 10);
2371 
2372 			default:
2373 				DE_FATAL("Format unimplemented");
2374 		}
2375 	}
2376 
2377 	return 0;
2378 }
2379 
getRepresentableDiffUnorm(const VkFormat format,const deUint32 componentNdx)2380 float getRepresentableDiffUnorm (const VkFormat format, const deUint32 componentNdx)
2381 {
2382 	const deUint32 size (getFormatComponentWidth(format, componentNdx));
2383 
2384 	return 1.0f / float((1 << (size)) - 1);
2385 }
2386 
getRepresentableDiffSnorm(const VkFormat format,const deUint32 componentNdx)2387 float getRepresentableDiffSnorm (const VkFormat format, const deUint32 componentNdx)
2388 {
2389 	const deUint32 size (getFormatComponentWidth(format, componentNdx));
2390 
2391 	return 1.0f / float((1 << (size - 1)) - 1);
2392 }
2393 
getBlockSizeInBytes(const VkFormat compressedFormat)2394 deUint32 getBlockSizeInBytes (const VkFormat compressedFormat)
2395 {
2396 	deUint32 formatNdx = static_cast<deUint32>(compressedFormat - VK_FORMAT_BC1_RGB_UNORM_BLOCK);
2397 
2398 	DE_ASSERT(deInRange32(formatNdx, 0, DE_LENGTH_OF_ARRAY(compressedFormatParameters)));
2399 	DE_ASSERT(compressedFormatParameters[formatNdx].format == compressedFormat);
2400 
2401 	return compressedFormatParameters[formatNdx].blockBytes;
2402 }
2403 
getBlockWidth(const VkFormat compressedFormat)2404 deUint32 getBlockWidth (const VkFormat compressedFormat)
2405 {
2406 	deUint32 formatNdx = static_cast<deUint32>(compressedFormat - VK_FORMAT_BC1_RGB_UNORM_BLOCK);
2407 
2408 	DE_ASSERT(deInRange32(formatNdx, 0, DE_LENGTH_OF_ARRAY(compressedFormatParameters)));
2409 	DE_ASSERT(compressedFormatParameters[formatNdx].format == compressedFormat);
2410 
2411 	return compressedFormatParameters[formatNdx].blockWidth;
2412 }
2413 
getBlockHeight(const VkFormat compressedFormat)2414 deUint32 getBlockHeight (const VkFormat compressedFormat)
2415 {
2416 	deUint32 formatNdx = static_cast<deUint32>(compressedFormat - VK_FORMAT_BC1_RGB_UNORM_BLOCK);
2417 
2418 	DE_ASSERT(deInRange32(formatNdx, 0, DE_LENGTH_OF_ARRAY(compressedFormatParameters)));
2419 	DE_ASSERT(compressedFormatParameters[formatNdx].format == compressedFormat);
2420 
2421 	return compressedFormatParameters[formatNdx].blockHeight;
2422 }
2423 
mapFilterMode(tcu::Sampler::FilterMode filterMode)2424 VkFilter mapFilterMode (tcu::Sampler::FilterMode filterMode)
2425 {
2426 	DE_STATIC_ASSERT(tcu::Sampler::FILTERMODE_LAST == 6);
2427 
2428 	switch (filterMode)
2429 	{
2430 		case tcu::Sampler::NEAREST:					return VK_FILTER_NEAREST;
2431 		case tcu::Sampler::LINEAR:					return VK_FILTER_LINEAR;
2432 		case tcu::Sampler::NEAREST_MIPMAP_NEAREST:	return VK_FILTER_NEAREST;
2433 		case tcu::Sampler::NEAREST_MIPMAP_LINEAR:	return VK_FILTER_NEAREST;
2434 		case tcu::Sampler::LINEAR_MIPMAP_NEAREST:	return VK_FILTER_LINEAR;
2435 		case tcu::Sampler::LINEAR_MIPMAP_LINEAR:	return VK_FILTER_LINEAR;
2436 		default:
2437 			DE_FATAL("Illegal filter mode");
2438 			return (VkFilter)0;
2439 	}
2440 }
2441 
mapMipmapMode(tcu::Sampler::FilterMode filterMode)2442 VkSamplerMipmapMode mapMipmapMode (tcu::Sampler::FilterMode filterMode)
2443 {
2444 	DE_STATIC_ASSERT(tcu::Sampler::FILTERMODE_LAST == 6);
2445 
2446 	// \note VkSamplerCreateInfo doesn't have a flag for disabling mipmapping. Instead
2447 	//		 minLod = 0 and maxLod = 0.25 should be used to match OpenGL NEAREST and LINEAR
2448 	//		 filtering mode behavior.
2449 
2450 	switch (filterMode)
2451 	{
2452 		case tcu::Sampler::NEAREST:					return VK_SAMPLER_MIPMAP_MODE_NEAREST;
2453 		case tcu::Sampler::LINEAR:					return VK_SAMPLER_MIPMAP_MODE_NEAREST;
2454 		case tcu::Sampler::NEAREST_MIPMAP_NEAREST:	return VK_SAMPLER_MIPMAP_MODE_NEAREST;
2455 		case tcu::Sampler::NEAREST_MIPMAP_LINEAR:	return VK_SAMPLER_MIPMAP_MODE_LINEAR;
2456 		case tcu::Sampler::LINEAR_MIPMAP_NEAREST:	return VK_SAMPLER_MIPMAP_MODE_NEAREST;
2457 		case tcu::Sampler::LINEAR_MIPMAP_LINEAR:	return VK_SAMPLER_MIPMAP_MODE_LINEAR;
2458 		default:
2459 			DE_FATAL("Illegal filter mode");
2460 			return (VkSamplerMipmapMode)0;
2461 	}
2462 }
2463 
mapWrapMode(tcu::Sampler::WrapMode wrapMode)2464 VkSamplerAddressMode mapWrapMode (tcu::Sampler::WrapMode wrapMode)
2465 {
2466 	switch (wrapMode)
2467 	{
2468 		case tcu::Sampler::CLAMP_TO_EDGE:		return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
2469 		case tcu::Sampler::CLAMP_TO_BORDER:		return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
2470 		case tcu::Sampler::REPEAT_GL:			return VK_SAMPLER_ADDRESS_MODE_REPEAT;
2471 		case tcu::Sampler::MIRRORED_REPEAT_GL:	return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
2472 		case tcu::Sampler::MIRRORED_ONCE:		return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
2473 		default:
2474 			DE_FATAL("Wrap mode can't be mapped to Vulkan");
2475 			return (vk::VkSamplerAddressMode)0;
2476 	}
2477 }
2478 
mapCompareMode(tcu::Sampler::CompareMode mode)2479 vk::VkCompareOp mapCompareMode (tcu::Sampler::CompareMode mode)
2480 {
2481 	switch (mode)
2482 	{
2483 		case tcu::Sampler::COMPAREMODE_NONE:				return vk::VK_COMPARE_OP_NEVER;
2484 		case tcu::Sampler::COMPAREMODE_LESS:				return vk::VK_COMPARE_OP_LESS;
2485 		case tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL:		return vk::VK_COMPARE_OP_LESS_OR_EQUAL;
2486 		case tcu::Sampler::COMPAREMODE_GREATER:				return vk::VK_COMPARE_OP_GREATER;
2487 		case tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL:	return vk::VK_COMPARE_OP_GREATER_OR_EQUAL;
2488 		case tcu::Sampler::COMPAREMODE_EQUAL:				return vk::VK_COMPARE_OP_EQUAL;
2489 		case tcu::Sampler::COMPAREMODE_NOT_EQUAL:			return vk::VK_COMPARE_OP_NOT_EQUAL;
2490 		case tcu::Sampler::COMPAREMODE_ALWAYS:				return vk::VK_COMPARE_OP_ALWAYS;
2491 		case tcu::Sampler::COMPAREMODE_NEVER:				return vk::VK_COMPARE_OP_NEVER;
2492 		default:
2493 			DE_FATAL("Illegal compare mode");
2494 			return (vk::VkCompareOp)0;
2495 	}
2496 }
2497 
mapBorderColor(tcu::TextureChannelClass channelClass,const rr::GenericVec4 & color)2498 static VkBorderColor mapBorderColor (tcu::TextureChannelClass channelClass, const rr::GenericVec4& color)
2499 {
2500 	if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
2501 	{
2502 		const tcu::UVec4	uColor	= color.get<deUint32>();
2503 
2504 		if (uColor		== tcu::UVec4(0, 0, 0, 0)) return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
2505 		else if (uColor	== tcu::UVec4(0, 0, 0, 1)) return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
2506 		else if (uColor == tcu::UVec4(1, 1, 1, 1)) return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
2507 	}
2508 	else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2509 	{
2510 		const tcu::IVec4	sColor	= color.get<deInt32>();
2511 
2512 		if (sColor		== tcu::IVec4(0, 0, 0, 0)) return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
2513 		else if (sColor	== tcu::IVec4(0, 0, 0, 1)) return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
2514 		else if (sColor == tcu::IVec4(1, 1, 1, 1)) return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
2515 	}
2516 	else
2517 	{
2518 		const tcu::Vec4		fColor	= color.get<float>();
2519 
2520 		if (fColor		== tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)) return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
2521 		else if (fColor == tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)) return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
2522 		else if (fColor == tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)) return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
2523 	}
2524 
2525 	DE_FATAL("Unsupported border color");
2526 	return VK_BORDER_COLOR_LAST;
2527 }
2528 
mapSampler(const tcu::Sampler & sampler,const tcu::TextureFormat & format,float minLod,float maxLod,bool unnormal)2529 VkSamplerCreateInfo mapSampler (const tcu::Sampler& sampler, const tcu::TextureFormat& format, float minLod, float maxLod, bool unnormal)
2530 {
2531 	const bool					compareEnabled	= (sampler.compare != tcu::Sampler::COMPAREMODE_NONE);
2532 	const VkCompareOp			compareOp		= (compareEnabled) ? (mapCompareMode(sampler.compare)) : (VK_COMPARE_OP_ALWAYS);
2533 	const VkBorderColor			borderColor		= mapBorderColor(getTextureChannelClass(format.type), sampler.borderColor);
2534 	const bool					isMipmapEnabled	= (sampler.minFilter != tcu::Sampler::NEAREST && sampler.minFilter != tcu::Sampler::LINEAR);
2535 
2536 	const VkSamplerCreateInfo	createInfo		=
2537 	{
2538 		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
2539 		DE_NULL,
2540 		(VkSamplerCreateFlags)0,
2541 		mapFilterMode(sampler.magFilter),							// magFilter
2542 		mapFilterMode(sampler.minFilter),							// minFilter
2543 		mapMipmapMode(sampler.minFilter),							// mipMode
2544 		mapWrapMode(sampler.wrapS),									// addressU
2545 		mapWrapMode(sampler.wrapT),									// addressV
2546 		mapWrapMode(sampler.wrapR),									// addressW
2547 		0.0f,														// mipLodBias
2548 		VK_FALSE,													// anisotropyEnable
2549 		1.0f,														// maxAnisotropy
2550 		(VkBool32)(compareEnabled ? VK_TRUE : VK_FALSE),			// compareEnable
2551 		compareOp,													// compareOp
2552 		(isMipmapEnabled ? minLod : 0.0f),							// minLod
2553 		(isMipmapEnabled ? maxLod : (unnormal ? 0.0f : 0.25f)),		// maxLod
2554 		borderColor,												// borderColor
2555 		(VkBool32)(sampler.normalizedCoords ? VK_FALSE : VK_TRUE),	// unnormalizedCoords
2556 	};
2557 
2558 	return createInfo;
2559 }
2560 
mapVkSampler(const VkSamplerCreateInfo & samplerCreateInfo)2561 tcu::Sampler mapVkSampler (const VkSamplerCreateInfo& samplerCreateInfo)
2562 {
2563 	// \note minLod & maxLod are not supported by tcu::Sampler. LOD must be clamped
2564 	//       before passing it to tcu::Texture*::sample*()
2565 
2566 	tcu::Sampler::ReductionMode reductionMode = tcu::Sampler::WEIGHTED_AVERAGE;
2567 
2568 	void const *pNext = samplerCreateInfo.pNext;
2569 	while (pNext != DE_NULL)
2570 	{
2571 		const VkStructureType nextType = *reinterpret_cast<const VkStructureType*>(pNext);
2572 		switch (nextType)
2573 		{
2574 			case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT:
2575 			{
2576 				const VkSamplerReductionModeCreateInfoEXT reductionModeCreateInfo = *reinterpret_cast<const VkSamplerReductionModeCreateInfoEXT*>(pNext);
2577 				reductionMode = mapVkSamplerReductionMode(reductionModeCreateInfo.reductionMode);
2578 				pNext = reinterpret_cast<const VkSamplerReductionModeCreateInfoEXT*>(pNext)->pNext;
2579 				break;
2580 			}
2581 			case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
2582 				pNext = reinterpret_cast<const VkSamplerYcbcrConversionInfo*>(pNext)->pNext;
2583 				break;
2584 			default:
2585 				TCU_FAIL("Unrecognized sType in chained sampler create info");
2586 		}
2587 	}
2588 
2589 
2590 
2591 	tcu::Sampler sampler(mapVkSamplerAddressMode(samplerCreateInfo.addressModeU),
2592 						 mapVkSamplerAddressMode(samplerCreateInfo.addressModeV),
2593 						 mapVkSamplerAddressMode(samplerCreateInfo.addressModeW),
2594 						 mapVkMinTexFilter(samplerCreateInfo.minFilter, samplerCreateInfo.mipmapMode),
2595 						 mapVkMagTexFilter(samplerCreateInfo.magFilter),
2596 						 0.0f,
2597 						 !samplerCreateInfo.unnormalizedCoordinates,
2598 						 samplerCreateInfo.compareEnable ? mapVkSamplerCompareOp(samplerCreateInfo.compareOp)
2599 														 : tcu::Sampler::COMPAREMODE_NONE,
2600 						 0,
2601 						 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
2602 						 true,
2603 						 tcu::Sampler::MODE_DEPTH,
2604 						 reductionMode);
2605 
2606 	if (samplerCreateInfo.anisotropyEnable)
2607 		TCU_THROW(InternalError, "Anisotropic filtering is not supported by tcu::Sampler");
2608 
2609 	switch (samplerCreateInfo.borderColor)
2610 	{
2611 		case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
2612 			sampler.borderColor = tcu::UVec4(0,0,0,1);
2613 			break;
2614 		case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
2615 			sampler.borderColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
2616 			break;
2617 		case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
2618 			sampler.borderColor = tcu::UVec4(1, 1, 1, 1);
2619 			break;
2620 		case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
2621 			sampler.borderColor = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
2622 			break;
2623 		case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
2624 			sampler.borderColor = tcu::UVec4(0,0,0,0);
2625 			break;
2626 		case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
2627 			sampler.borderColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
2628 			break;
2629 
2630 		default:
2631 			DE_ASSERT(false);
2632 			break;
2633 	}
2634 
2635 	return sampler;
2636 }
2637 
mapVkSamplerCompareOp(VkCompareOp compareOp)2638 tcu::Sampler::CompareMode mapVkSamplerCompareOp (VkCompareOp compareOp)
2639 {
2640 	switch (compareOp)
2641 	{
2642 		case VK_COMPARE_OP_NEVER:				return tcu::Sampler::COMPAREMODE_NEVER;
2643 		case VK_COMPARE_OP_LESS:				return tcu::Sampler::COMPAREMODE_LESS;
2644 		case VK_COMPARE_OP_EQUAL:				return tcu::Sampler::COMPAREMODE_EQUAL;
2645 		case VK_COMPARE_OP_LESS_OR_EQUAL:		return tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL;
2646 		case VK_COMPARE_OP_GREATER:				return tcu::Sampler::COMPAREMODE_GREATER;
2647 		case VK_COMPARE_OP_NOT_EQUAL:			return tcu::Sampler::COMPAREMODE_NOT_EQUAL;
2648 		case VK_COMPARE_OP_GREATER_OR_EQUAL:	return tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL;
2649 		case VK_COMPARE_OP_ALWAYS:				return tcu::Sampler::COMPAREMODE_ALWAYS;
2650 		default:
2651 			break;
2652 	}
2653 
2654 	DE_ASSERT(false);
2655 	return tcu::Sampler::COMPAREMODE_LAST;
2656 }
2657 
mapVkSamplerAddressMode(VkSamplerAddressMode addressMode)2658 tcu::Sampler::WrapMode mapVkSamplerAddressMode (VkSamplerAddressMode addressMode)
2659 {
2660 	switch (addressMode)
2661 	{
2662 		case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:			return tcu::Sampler::CLAMP_TO_EDGE;
2663 		case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:		return tcu::Sampler::CLAMP_TO_BORDER;
2664 		case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:		return tcu::Sampler::MIRRORED_REPEAT_GL;
2665 		case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:	return tcu::Sampler::MIRRORED_ONCE;
2666 		case VK_SAMPLER_ADDRESS_MODE_REPEAT:				return tcu::Sampler::REPEAT_GL;
2667 		default:
2668 			break;
2669 	}
2670 
2671 	DE_ASSERT(false);
2672 	return tcu::Sampler::WRAPMODE_LAST;
2673 }
2674 
mapVkSamplerReductionMode(VkSamplerReductionModeEXT reductionMode)2675 tcu::Sampler::ReductionMode mapVkSamplerReductionMode (VkSamplerReductionModeEXT reductionMode)
2676 {
2677 	switch (reductionMode)
2678 	{
2679 		case VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT:	return tcu::Sampler::WEIGHTED_AVERAGE;
2680 		case VK_SAMPLER_REDUCTION_MODE_MIN_EXT:					return tcu::Sampler::MIN;
2681 		case VK_SAMPLER_REDUCTION_MODE_MAX_EXT:					return tcu::Sampler::MAX;
2682 		default:
2683 			break;
2684 	}
2685 
2686 	DE_ASSERT(false);
2687 	return tcu::Sampler::REDUCTIONMODE_LAST;
2688 }
2689 
mapVkMinTexFilter(VkFilter filter,VkSamplerMipmapMode mipMode)2690 tcu::Sampler::FilterMode mapVkMinTexFilter (VkFilter filter, VkSamplerMipmapMode mipMode)
2691 {
2692 	switch (filter)
2693 	{
2694 		case VK_FILTER_LINEAR:
2695 			switch (mipMode)
2696 			{
2697 				case VK_SAMPLER_MIPMAP_MODE_LINEAR:		return tcu::Sampler::LINEAR_MIPMAP_LINEAR;
2698 				case VK_SAMPLER_MIPMAP_MODE_NEAREST:	return tcu::Sampler::LINEAR_MIPMAP_NEAREST;
2699 				default:
2700 					break;
2701 			}
2702 			break;
2703 
2704 		case VK_FILTER_NEAREST:
2705 			switch (mipMode)
2706 			{
2707 				case VK_SAMPLER_MIPMAP_MODE_LINEAR:		return tcu::Sampler::NEAREST_MIPMAP_LINEAR;
2708 				case VK_SAMPLER_MIPMAP_MODE_NEAREST:	return tcu::Sampler::NEAREST_MIPMAP_NEAREST;
2709 				default:
2710 					break;
2711 			}
2712 			break;
2713 
2714 		default:
2715 			break;
2716 	}
2717 
2718 	DE_ASSERT(false);
2719 	return tcu::Sampler::FILTERMODE_LAST;
2720 }
2721 
mapVkMagTexFilter(VkFilter filter)2722 tcu::Sampler::FilterMode mapVkMagTexFilter (VkFilter filter)
2723 {
2724 	switch (filter)
2725 	{
2726 		case VK_FILTER_LINEAR:		return tcu::Sampler::LINEAR;
2727 		case VK_FILTER_NEAREST:		return tcu::Sampler::NEAREST;
2728 		default:
2729 			break;
2730 	}
2731 
2732 	DE_ASSERT(false);
2733 	return tcu::Sampler::FILTERMODE_LAST;
2734 }
2735 
2736 //! Get a format the matches the layout in buffer memory used for a
2737 //! buffer<->image copy on a depth/stencil format.
getDepthCopyFormat(VkFormat combinedFormat)2738 tcu::TextureFormat getDepthCopyFormat (VkFormat combinedFormat)
2739 {
2740 	switch (combinedFormat)
2741 	{
2742 		case VK_FORMAT_D16_UNORM:
2743 		case VK_FORMAT_X8_D24_UNORM_PACK32:
2744 		case VK_FORMAT_D32_SFLOAT:
2745 			return mapVkFormat(combinedFormat);
2746 
2747 		case VK_FORMAT_D16_UNORM_S8_UINT:
2748 			return mapVkFormat(VK_FORMAT_D16_UNORM);
2749 		case VK_FORMAT_D24_UNORM_S8_UINT:
2750 			return mapVkFormat(VK_FORMAT_X8_D24_UNORM_PACK32);
2751 		case VK_FORMAT_D32_SFLOAT_S8_UINT:
2752 			return mapVkFormat(VK_FORMAT_D32_SFLOAT);
2753 
2754 		case VK_FORMAT_S8_UINT:
2755 		default:
2756 			DE_FATAL("Unexpected depth/stencil format");
2757 			return tcu::TextureFormat();
2758 	}
2759 }
2760 
2761 //! Get a format the matches the layout in buffer memory used for a
2762 //! buffer<->image copy on a depth/stencil format.
getStencilCopyFormat(VkFormat combinedFormat)2763 tcu::TextureFormat getStencilCopyFormat (VkFormat combinedFormat)
2764 {
2765 	switch (combinedFormat)
2766 	{
2767 		case VK_FORMAT_D16_UNORM_S8_UINT:
2768 		case VK_FORMAT_D24_UNORM_S8_UINT:
2769 		case VK_FORMAT_D32_SFLOAT_S8_UINT:
2770 		case VK_FORMAT_S8_UINT:
2771 			return mapVkFormat(VK_FORMAT_S8_UINT);
2772 
2773 		case VK_FORMAT_D16_UNORM:
2774 		case VK_FORMAT_X8_D24_UNORM_PACK32:
2775 		case VK_FORMAT_D32_SFLOAT:
2776 		default:
2777 			DE_FATAL("Unexpected depth/stencil format");
2778 			return tcu::TextureFormat();
2779 	}
2780 }
2781 
getImageAspectFlags(const tcu::TextureFormat textureFormat)2782 VkImageAspectFlags getImageAspectFlags (const tcu::TextureFormat textureFormat)
2783 {
2784 	VkImageAspectFlags imageAspectFlags = 0;
2785 
2786 	if (tcu::hasDepthComponent(textureFormat.order))
2787 		imageAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
2788 
2789 	if (tcu::hasStencilComponent(textureFormat.order))
2790 		imageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
2791 
2792 	if (imageAspectFlags == 0)
2793 		imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
2794 
2795 	return imageAspectFlags;
2796 }
2797 
mipLevelExtents(const VkExtent3D & baseExtents,const deUint32 mipLevel)2798 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel)
2799 {
2800 	VkExtent3D result;
2801 
2802 	result.width	= std::max(baseExtents.width >> mipLevel, 1u);
2803 	result.height	= std::max(baseExtents.height >> mipLevel, 1u);
2804 	result.depth	= std::max(baseExtents.depth >> mipLevel, 1u);
2805 
2806 	return result;
2807 }
2808 
alignedDivide(const VkExtent3D & extent,const VkExtent3D & divisor)2809 tcu::UVec3 alignedDivide (const VkExtent3D& extent, const VkExtent3D& divisor)
2810 {
2811 	tcu::UVec3 result;
2812 
2813 	result.x() = extent.width  / divisor.width  + ((extent.width  % divisor.width != 0)  ? 1u : 0u);
2814 	result.y() = extent.height / divisor.height + ((extent.height % divisor.height != 0) ? 1u : 0u);
2815 	result.z() = extent.depth  / divisor.depth  + ((extent.depth  % divisor.depth != 0)  ? 1u : 0u);
2816 
2817 	return result;
2818 }
2819 
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)2820 void copyBufferToImage (const DeviceInterface&					vk,
2821 						const VkCommandBuffer&					cmdBuffer,
2822 						const VkBuffer&							buffer,
2823 						VkDeviceSize							bufferSize,
2824 						const std::vector<VkBufferImageCopy>&	copyRegions,
2825 						VkImageAspectFlags						imageAspectFlags,
2826 						deUint32								mipLevels,
2827 						deUint32								arrayLayers,
2828 						VkImage									destImage,
2829 						VkImageLayout							destImageLayout,
2830 						VkPipelineStageFlags					destImageDstStageFlags)
2831 {
2832 	// Barriers for copying buffer to image
2833 	const VkBufferMemoryBarrier preBufferBarrier =
2834 	{
2835 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2836 		DE_NULL,									// const void*		pNext;
2837 		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
2838 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
2839 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
2840 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
2841 		buffer,										// VkBuffer			buffer;
2842 		0u,											// VkDeviceSize		offset;
2843 		bufferSize									// VkDeviceSize		size;
2844 	};
2845 
2846 	const VkImageMemoryBarrier preImageBarrier =
2847 	{
2848 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
2849 		DE_NULL,										// const void*				pNext;
2850 		0u,												// VkAccessFlags			srcAccessMask;
2851 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
2852 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
2853 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
2854 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
2855 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
2856 		destImage,										// VkImage					image;
2857 		{												// VkImageSubresourceRange	subresourceRange;
2858 			imageAspectFlags,							// VkImageAspectFlags		aspect;
2859 			0u,											// deUint32					baseMipLevel;
2860 			mipLevels,									// deUint32					mipLevels;
2861 			0u,											// deUint32					baseArraySlice;
2862 			arrayLayers									// deUint32					arraySize;
2863 		}
2864 	};
2865 
2866 	const VkImageMemoryBarrier postImageBarrier =
2867 	{
2868 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
2869 		DE_NULL,										// const void*				pNext;
2870 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
2871 		VK_ACCESS_SHADER_READ_BIT,						// VkAccessFlags			dstAccessMask;
2872 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
2873 		destImageLayout,								// VkImageLayout			newLayout;
2874 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
2875 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
2876 		destImage,										// VkImage					image;
2877 		{												// VkImageSubresourceRange	subresourceRange;
2878 			imageAspectFlags,							// VkImageAspectFlags		aspect;
2879 			0u,											// deUint32					baseMipLevel;
2880 			mipLevels,									// deUint32					mipLevels;
2881 			0u,											// deUint32					baseArraySlice;
2882 			arrayLayers									// deUint32					arraySize;
2883 		}
2884 	};
2885 
2886 	// Copy buffer to image
2887 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
2888 	vk.cmdCopyBufferToImage(cmdBuffer, buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
2889 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, destImageDstStageFlags, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
2890 }
2891 
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)2892 void copyBufferToImage (const DeviceInterface&					vk,
2893 						VkDevice								device,
2894 						VkQueue									queue,
2895 						deUint32								queueFamilyIndex,
2896 						const VkBuffer&							buffer,
2897 						VkDeviceSize							bufferSize,
2898 						const std::vector<VkBufferImageCopy>&	copyRegions,
2899 						const VkSemaphore*						waitSemaphore,
2900 						VkImageAspectFlags						imageAspectFlags,
2901 						deUint32								mipLevels,
2902 						deUint32								arrayLayers,
2903 						VkImage									destImage,
2904 						VkImageLayout							destImageLayout,
2905 						VkPipelineStageFlags					destImageDstStageFlags)
2906 {
2907 	Move<VkCommandPool>		cmdPool		= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2908 	Move<VkCommandBuffer>	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2909 	Move<VkFence>			fence		= createFence(vk, device);
2910 
2911 	const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2912 	{
2913 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
2914 		DE_NULL,										// const void*						pNext;
2915 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags		flags;
2916 		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2917 	};
2918 
2919 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2920 	copyBufferToImage(vk, *cmdBuffer, buffer, bufferSize, copyRegions, imageAspectFlags, mipLevels, arrayLayers, destImage, destImageLayout, destImageDstStageFlags);
2921 	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2922 
2923 	const VkPipelineStageFlags pipelineStageFlags = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
2924 
2925 	const VkSubmitInfo submitInfo =
2926 	{
2927 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
2928 		DE_NULL,						// const void*					pNext;
2929 		waitSemaphore ? 1u : 0u,		// deUint32						waitSemaphoreCount;
2930 		waitSemaphore,					// const VkSemaphore*			pWaitSemaphores;
2931 		&pipelineStageFlags,			// const VkPipelineStageFlags*	pWaitDstStageMask;
2932 		1u,								// deUint32						commandBufferCount;
2933 		&cmdBuffer.get(),				// const VkCommandBuffer*		pCommandBuffers;
2934 		0u,								// deUint32						signalSemaphoreCount;
2935 		DE_NULL							// const VkSemaphore*			pSignalSemaphores;
2936 	};
2937 
2938 	try
2939 	{
2940 		VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2941 		VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
2942 	}
2943 	catch (...)
2944 	{
2945 		VK_CHECK(vk.deviceWaitIdle(device));
2946 		throw;
2947 	}
2948 }
2949 
copyImageToBuffer(const DeviceInterface & vk,VkCommandBuffer cmdBuffer,VkImage image,VkBuffer buffer,tcu::IVec2 size,VkAccessFlags srcAccessMask,VkImageLayout oldLayout,deUint32 numLayers)2950 void copyImageToBuffer (const DeviceInterface&	vk,
2951 						VkCommandBuffer			cmdBuffer,
2952 						VkImage					image,
2953 						VkBuffer				buffer,
2954 						tcu::IVec2				size,
2955 						VkAccessFlags			srcAccessMask,
2956 						VkImageLayout			oldLayout,
2957 						deUint32				numLayers)
2958 {
2959 	const VkImageMemoryBarrier	imageBarrier	=
2960 	{
2961 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,										// VkStructureType			sType;
2962 		DE_NULL,																	// const void*				pNext;
2963 		srcAccessMask,																// VkAccessFlags			srcAccessMask;
2964 		VK_ACCESS_TRANSFER_READ_BIT,												// VkAccessFlags			dstAccessMask;
2965 		oldLayout,																	// VkImageLayout			oldLayout;
2966 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,										// VkImageLayout			newLayout;
2967 		VK_QUEUE_FAMILY_IGNORED,													// deUint32					srcQueueFamilyIndex;
2968 		VK_QUEUE_FAMILY_IGNORED,													// deUint32					destQueueFamilyIndex;
2969 		image,																		// VkImage					image;
2970 		makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, numLayers)	// VkImageSubresourceRange	subresourceRange;
2971 	};
2972 
2973 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
2974 						  0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
2975 
2976 	const VkImageSubresourceLayers	subresource	=
2977 	{
2978 		VK_IMAGE_ASPECT_COLOR_BIT,					// VkImageAspectFlags	aspectMask;
2979 		0u,											// deUint32				mipLevel;
2980 		0u,											// deUint32				baseArrayLayer;
2981 		numLayers									// deUint32				layerCount;
2982 	};
2983 
2984 	const VkBufferImageCopy			region		=
2985 	{
2986 		0ull,										// VkDeviceSize					bufferOffset;
2987 		0u,											// deUint32						bufferRowLength;
2988 		0u,											// deUint32						bufferImageHeight;
2989 		subresource,								// VkImageSubresourceLayers		imageSubresource;
2990 		makeOffset3D(0, 0, 0),						// VkOffset3D					imageOffset;
2991 		makeExtent3D(size.x(), size.y(), 1u)		// VkExtent3D					imageExtent;
2992 	};
2993 
2994 	vk.cmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, &region);
2995 
2996 	const VkBufferMemoryBarrier	bufferBarrier =
2997 	{
2998 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2999 		DE_NULL,									// const void*		pNext;
3000 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
3001 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
3002 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
3003 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
3004 		buffer,										// VkBuffer			buffer;
3005 		0ull,										// VkDeviceSize		offset;
3006 		VK_WHOLE_SIZE								// VkDeviceSize		size;
3007 	};
3008 
3009 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
3010 						  0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
3011 }
3012 
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)3013 void allocateAndBindSparseImage (const DeviceInterface&						vk,
3014 								 VkDevice									device,
3015 								 const VkPhysicalDevice						physicalDevice,
3016 								 const InstanceInterface&					instance,
3017 								 const VkImageCreateInfo&					imageCreateInfo,
3018 								 const VkSemaphore&							signalSemaphore,
3019 								 VkQueue									queue,
3020 								 Allocator&									allocator,
3021 								 std::vector<de::SharedPtr<Allocation> >&	allocations,
3022 								 tcu::TextureFormat							format,
3023 								 VkImage									destImage)
3024 {
3025 	const VkImageAspectFlags				imageAspectFlags		= getImageAspectFlags(format);
3026 	const VkPhysicalDeviceProperties		deviceProperties		= getPhysicalDeviceProperties(instance, physicalDevice);
3027 	const VkPhysicalDeviceMemoryProperties	deviceMemoryProperties	= getPhysicalDeviceMemoryProperties(instance, physicalDevice);
3028 	deUint32								sparseMemoryReqCount	= 0;
3029 
3030 	// Check if the image format supports sparse operations
3031 	if (!checkSparseImageFormatSupport(physicalDevice, instance, imageCreateInfo))
3032 		TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");
3033 
3034 	vk.getImageSparseMemoryRequirements(device, destImage, &sparseMemoryReqCount, DE_NULL);
3035 
3036 	DE_ASSERT(sparseMemoryReqCount != 0);
3037 
3038 	std::vector<VkSparseImageMemoryRequirements> sparseImageMemoryRequirements;
3039 	sparseImageMemoryRequirements.resize(sparseMemoryReqCount);
3040 
3041 	vk.getImageSparseMemoryRequirements(device, destImage, &sparseMemoryReqCount, &sparseImageMemoryRequirements[0]);
3042 
3043 	const deUint32 noMatchFound = ~((deUint32)0);
3044 
3045 	deUint32 aspectIndex = noMatchFound;
3046 	for (deUint32 memoryReqNdx = 0; memoryReqNdx < sparseMemoryReqCount; ++memoryReqNdx)
3047 	{
3048 		if (sparseImageMemoryRequirements[memoryReqNdx].formatProperties.aspectMask == imageAspectFlags)
3049 		{
3050 			aspectIndex = memoryReqNdx;
3051 			break;
3052 		}
3053 	}
3054 
3055 	deUint32 metadataAspectIndex = noMatchFound;
3056 	for (deUint32 memoryReqNdx = 0; memoryReqNdx < sparseMemoryReqCount; ++memoryReqNdx)
3057 	{
3058 		if (sparseImageMemoryRequirements[memoryReqNdx].formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)
3059 		{
3060 			metadataAspectIndex = memoryReqNdx;
3061 			break;
3062 		}
3063 	}
3064 
3065 	if (aspectIndex == noMatchFound)
3066 		TCU_THROW(NotSupportedError, "Required image aspect not supported.");
3067 
3068 	const VkMemoryRequirements	memoryRequirements	= getImageMemoryRequirements(vk, device, destImage);
3069 
3070 	deUint32 memoryType = noMatchFound;
3071 	for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
3072 	{
3073 		if ((memoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
3074 			MemoryRequirement::Any.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
3075 		{
3076 			memoryType = memoryTypeNdx;
3077 			break;
3078 		}
3079 	}
3080 
3081 	if (memoryType == noMatchFound)
3082 		TCU_THROW(NotSupportedError, "No matching memory type found.");
3083 
3084 	if (memoryRequirements.size > deviceProperties.limits.sparseAddressSpaceSize)
3085 		TCU_THROW(NotSupportedError, "Required memory size for sparse resource exceeds device limits.");
3086 
3087 	const VkSparseImageMemoryRequirements		aspectRequirements	= sparseImageMemoryRequirements[aspectIndex];
3088 	const VkExtent3D							imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
3089 
3090 	std::vector<VkSparseImageMemoryBind>		imageResidencyMemoryBinds;
3091 	std::vector<VkSparseMemoryBind>				imageMipTailMemoryBinds;
3092 
3093 	for (deUint32 layerNdx = 0; layerNdx < imageCreateInfo.arrayLayers; ++layerNdx)
3094 	{
3095 		for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
3096 		{
3097 			const VkExtent3D	mipExtent		= mipLevelExtents(imageCreateInfo.extent, mipLevelNdx);
3098 			const tcu::UVec3	numSparseBinds	= alignedDivide(mipExtent, imageGranularity);
3099 			const tcu::UVec3	lastBlockExtent	= tcu::UVec3(mipExtent.width  % imageGranularity.width  ? mipExtent.width  % imageGranularity.width  : imageGranularity.width,
3100 															 mipExtent.height % imageGranularity.height ? mipExtent.height % imageGranularity.height : imageGranularity.height,
3101 															 mipExtent.depth  % imageGranularity.depth  ? mipExtent.depth  % imageGranularity.depth  : imageGranularity.depth );
3102 
3103 			for (deUint32 z = 0; z < numSparseBinds.z(); ++z)
3104 			for (deUint32 y = 0; y < numSparseBinds.y(); ++y)
3105 			for (deUint32 x = 0; x < numSparseBinds.x(); ++x)
3106 			{
3107 				const VkMemoryRequirements allocRequirements =
3108 				{
3109 					// 28.7.5 alignment shows the block size in bytes
3110 					memoryRequirements.alignment,		// VkDeviceSize	size;
3111 					memoryRequirements.alignment,		// VkDeviceSize	alignment;
3112 					memoryRequirements.memoryTypeBits,	// uint32_t		memoryTypeBits;
3113 				};
3114 
3115 				de::SharedPtr<Allocation> allocation(allocator.allocate(allocRequirements, MemoryRequirement::Any).release());
3116 				allocations.push_back(allocation);
3117 
3118 				VkOffset3D offset;
3119 				offset.x = x*imageGranularity.width;
3120 				offset.y = y*imageGranularity.height;
3121 				offset.z = z*imageGranularity.depth;
3122 
3123 				VkExtent3D extent;
3124 				extent.width	= (x == numSparseBinds.x() - 1) ? lastBlockExtent.x() : imageGranularity.width;
3125 				extent.height	= (y == numSparseBinds.y() - 1) ? lastBlockExtent.y() : imageGranularity.height;
3126 				extent.depth	= (z == numSparseBinds.z() - 1) ? lastBlockExtent.z() : imageGranularity.depth;
3127 
3128 				const VkSparseImageMemoryBind imageMemoryBind =
3129 				{
3130 					{
3131 						imageAspectFlags,	// VkImageAspectFlags	aspectMask;
3132 						mipLevelNdx,		// uint32_t				mipLevel;
3133 						layerNdx,			// uint32_t				arrayLayer;
3134 					},							// VkImageSubresource		subresource;
3135 					offset,						// VkOffset3D				offset;
3136 					extent,						// VkExtent3D				extent;
3137 					allocation->getMemory(),	// VkDeviceMemory			memory;
3138 					allocation->getOffset(),	// VkDeviceSize				memoryOffset;
3139 					0u,							// VkSparseMemoryBindFlags	flags;
3140 				};
3141 
3142 				imageResidencyMemoryBinds.push_back(imageMemoryBind);
3143 			}
3144 		}
3145 
3146 		// Handle MIP tail. There are two cases to consider here:
3147 		//
3148 		// 1) VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is requested by the driver: each layer needs a separate tail.
3149 		// 2) otherwise:                                                            only one tail is needed.
3150 		if (aspectRequirements.imageMipTailSize > 0)
3151 		{
3152 			if (layerNdx == 0 || (aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) == 0)
3153 			{
3154 				const VkMemoryRequirements allocRequirements =
3155 				{
3156 					aspectRequirements.imageMipTailSize,	// VkDeviceSize	size;
3157 					memoryRequirements.alignment,			// VkDeviceSize	alignment;
3158 					memoryRequirements.memoryTypeBits,		// uint32_t		memoryTypeBits;
3159 				};
3160 
3161 				const de::SharedPtr<Allocation> allocation(allocator.allocate(allocRequirements, MemoryRequirement::Any).release());
3162 
3163 				const VkSparseMemoryBind imageMipTailMemoryBind =
3164 				{
3165 					aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride,	// VkDeviceSize					resourceOffset;
3166 					aspectRequirements.imageMipTailSize,														// VkDeviceSize					size;
3167 					allocation->getMemory(),																	// VkDeviceMemory				memory;
3168 					allocation->getOffset(),																	// VkDeviceSize					memoryOffset;
3169 					0u,																							// VkSparseMemoryBindFlags		flags;
3170 				};
3171 
3172 				allocations.push_back(allocation);
3173 
3174 				imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
3175 			}
3176 		}
3177 
3178 		// Handle Metadata. Similarly to MIP tail in aspectRequirements, there are two cases to consider here:
3179 		//
3180 		// 1) VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT is requested by the driver: each layer needs a separate tail.
3181 		// 2) otherwise:
3182 		if (metadataAspectIndex != noMatchFound)
3183 		{
3184 			const VkSparseImageMemoryRequirements	metadataAspectRequirements = sparseImageMemoryRequirements[metadataAspectIndex];
3185 
3186 			if (layerNdx == 0 || (metadataAspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) == 0)
3187 			{
3188 				const VkMemoryRequirements metadataAllocRequirements =
3189 				{
3190 					metadataAspectRequirements.imageMipTailSize,	// VkDeviceSize	size;
3191 					memoryRequirements.alignment,					// VkDeviceSize	alignment;
3192 					memoryRequirements.memoryTypeBits,				// uint32_t		memoryTypeBits;
3193 				};
3194 				const de::SharedPtr<Allocation>	metadataAllocation(allocator.allocate(metadataAllocRequirements, MemoryRequirement::Any).release());
3195 
3196 				const VkSparseMemoryBind metadataMipTailMemoryBind =
3197 				{
3198 					metadataAspectRequirements.imageMipTailOffset +
3199 					layerNdx * metadataAspectRequirements.imageMipTailStride,			// VkDeviceSize					resourceOffset;
3200 					metadataAspectRequirements.imageMipTailSize,						// VkDeviceSize					size;
3201 					metadataAllocation->getMemory(),									// VkDeviceMemory				memory;
3202 					metadataAllocation->getOffset(),									// VkDeviceSize					memoryOffset;
3203 					VK_SPARSE_MEMORY_BIND_METADATA_BIT									// VkSparseMemoryBindFlags		flags;
3204 				};
3205 
3206 				allocations.push_back(metadataAllocation);
3207 
3208 				imageMipTailMemoryBinds.push_back(metadataMipTailMemoryBind);
3209 			}
3210 		}
3211 	}
3212 
3213 	VkBindSparseInfo bindSparseInfo =
3214 	{
3215 		VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,			//VkStructureType							sType;
3216 		DE_NULL,									//const void*								pNext;
3217 		0u,											//deUint32									waitSemaphoreCount;
3218 		DE_NULL,									//const VkSemaphore*						pWaitSemaphores;
3219 		0u,											//deUint32									bufferBindCount;
3220 		DE_NULL,									//const VkSparseBufferMemoryBindInfo*		pBufferBinds;
3221 		0u,											//deUint32									imageOpaqueBindCount;
3222 		DE_NULL,									//const VkSparseImageOpaqueMemoryBindInfo*	pImageOpaqueBinds;
3223 		0u,											//deUint32									imageBindCount;
3224 		DE_NULL,									//const VkSparseImageMemoryBindInfo*		pImageBinds;
3225 		1u,											//deUint32									signalSemaphoreCount;
3226 		&signalSemaphore							//const VkSemaphore*						pSignalSemaphores;
3227 	};
3228 
3229 	VkSparseImageMemoryBindInfo			imageResidencyBindInfo;
3230 	VkSparseImageOpaqueMemoryBindInfo	imageMipTailBindInfo;
3231 
3232 	if (imageResidencyMemoryBinds.size() > 0)
3233 	{
3234 		imageResidencyBindInfo.image		= destImage;
3235 		imageResidencyBindInfo.bindCount	= static_cast<deUint32>(imageResidencyMemoryBinds.size());
3236 		imageResidencyBindInfo.pBinds		= &imageResidencyMemoryBinds[0];
3237 
3238 		bindSparseInfo.imageBindCount		= 1u;
3239 		bindSparseInfo.pImageBinds			= &imageResidencyBindInfo;
3240 	}
3241 
3242 	if (imageMipTailMemoryBinds.size() > 0)
3243 	{
3244 		imageMipTailBindInfo.image			= destImage;
3245 		imageMipTailBindInfo.bindCount		= static_cast<deUint32>(imageMipTailMemoryBinds.size());
3246 		imageMipTailBindInfo.pBinds			= &imageMipTailMemoryBinds[0];
3247 
3248 		bindSparseInfo.imageOpaqueBindCount	= 1u;
3249 		bindSparseInfo.pImageOpaqueBinds	= &imageMipTailBindInfo;
3250 	}
3251 
3252 	VK_CHECK(vk.queueBindSparse(queue, 1u, &bindSparseInfo, DE_NULL));
3253 }
3254 
checkSparseImageFormatSupport(const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,const VkImageCreateInfo & imageCreateInfo)3255 bool checkSparseImageFormatSupport (const VkPhysicalDevice		physicalDevice,
3256 									const InstanceInterface&	instance,
3257 									const VkImageCreateInfo&	imageCreateInfo)
3258 {
3259 	const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec =
3260 		getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.samples, imageCreateInfo.usage, imageCreateInfo.tiling);
3261 
3262 	return (sparseImageFormatPropVec.size() != 0);
3263 }
3264 
3265 } // vk
3266