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