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