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