1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file vktSparseResourcesTestsUtil.cpp
21 * \brief Sparse Resources Tests Utility Classes
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktSparseResourcesTestsUtil.hpp"
25 #include "vkQueryUtil.hpp"
26 #include "vkDeviceUtil.hpp"
27 #include "vkTypeUtil.hpp"
28 #include "tcuTextureUtil.hpp"
29 #include "deStringUtil.hpp"
30
31 #include <deMath.h>
32
33 using namespace vk;
34
35 namespace vkt
36 {
37 namespace sparse
38 {
39
formatIsR64(const VkFormat & format)40 bool formatIsR64(const VkFormat &format)
41 {
42 switch (format)
43 {
44 case VK_FORMAT_R64_SINT:
45 case VK_FORMAT_R64_UINT:
46 return true;
47 default:
48 return false;
49 }
50 }
51
getTestFormats(const ImageType & imageType)52 std::vector<TestFormat> getTestFormats(const ImageType &imageType)
53 {
54 std::vector<TestFormat> results = {{VK_FORMAT_R64_SINT}, {VK_FORMAT_R32_SINT},
55 {VK_FORMAT_R16_SINT}, {VK_FORMAT_R8_SINT},
56 {VK_FORMAT_R64_UINT}, {VK_FORMAT_R32_UINT},
57 {VK_FORMAT_R16_UINT}, {VK_FORMAT_R8_UINT},
58
59 {VK_FORMAT_R16_UNORM}, {VK_FORMAT_R8_UNORM},
60 {VK_FORMAT_R16_SNORM}, {VK_FORMAT_R8_SNORM},
61 {VK_FORMAT_R32G32_SINT}, {VK_FORMAT_R16G16_SINT},
62 {VK_FORMAT_R8G8_SINT}, {VK_FORMAT_R32G32_UINT},
63 {VK_FORMAT_R16G16_UINT}, {VK_FORMAT_R8G8_UINT},
64 {VK_FORMAT_R16G16_UNORM}, {VK_FORMAT_R8G8_UNORM},
65 {VK_FORMAT_R16G16_SNORM}, {VK_FORMAT_R8G8_SNORM},
66 {VK_FORMAT_R32G32B32A32_SINT}, {VK_FORMAT_R16G16B16A16_SINT},
67 {VK_FORMAT_R8G8B8A8_SINT}, {VK_FORMAT_R32G32B32A32_UINT},
68 {VK_FORMAT_R16G16B16A16_UINT}, {VK_FORMAT_R8G8B8A8_UINT},
69 {VK_FORMAT_R16G16B16A16_UNORM}, {VK_FORMAT_R8G8B8A8_UNORM},
70 {VK_FORMAT_R16G16B16A16_SNORM}, {VK_FORMAT_R8G8B8A8_SNORM}};
71
72 if (imageType == IMAGE_TYPE_2D || imageType == IMAGE_TYPE_2D_ARRAY)
73 {
74 std::vector<TestFormat> ycbcrFormats = {
75 {VK_FORMAT_G8B8G8R8_422_UNORM},
76 {VK_FORMAT_B8G8R8G8_422_UNORM},
77 {VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM},
78 {VK_FORMAT_G8_B8R8_2PLANE_420_UNORM},
79 {VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM},
80 {VK_FORMAT_G8_B8R8_2PLANE_422_UNORM},
81 {VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM},
82 {VK_FORMAT_R10X6_UNORM_PACK16},
83 {VK_FORMAT_R10X6G10X6_UNORM_2PACK16},
84 {VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16},
85 {VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16},
86 {VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16},
87 {VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16},
88 {VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16},
89 {VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16},
90 {VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16},
91 {VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16},
92 {VK_FORMAT_R12X4_UNORM_PACK16},
93 {VK_FORMAT_R12X4G12X4_UNORM_2PACK16},
94 {VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16},
95 {VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16},
96 {VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16},
97 {VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16},
98 {VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16},
99 {VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16},
100 {VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16},
101 {VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16},
102 {VK_FORMAT_G16B16G16R16_422_UNORM},
103 {VK_FORMAT_B16G16R16G16_422_UNORM},
104 {VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM},
105 {VK_FORMAT_G16_B16R16_2PLANE_420_UNORM},
106 {VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM},
107 {VK_FORMAT_G16_B16R16_2PLANE_422_UNORM},
108 {VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM},
109 {VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT},
110 {VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT},
111 {VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT},
112 {VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT},
113 };
114 std::copy(begin(ycbcrFormats), end(ycbcrFormats), std::back_inserter(results));
115 }
116
117 return results;
118 }
119
getShaderGridSize(const ImageType imageType,const tcu::UVec3 & imageSize,const uint32_t mipLevel)120 tcu::UVec3 getShaderGridSize(const ImageType imageType, const tcu::UVec3 &imageSize, const uint32_t mipLevel)
121 {
122 const uint32_t mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
123 const uint32_t mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
124 const uint32_t mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u);
125
126 switch (imageType)
127 {
128 case IMAGE_TYPE_1D:
129 return tcu::UVec3(mipLevelX, 1u, 1u);
130
131 case IMAGE_TYPE_BUFFER:
132 return tcu::UVec3(imageSize.x(), 1u, 1u);
133
134 case IMAGE_TYPE_1D_ARRAY:
135 return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
136
137 case IMAGE_TYPE_2D:
138 return tcu::UVec3(mipLevelX, mipLevelY, 1u);
139
140 case IMAGE_TYPE_2D_ARRAY:
141 return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
142
143 case IMAGE_TYPE_3D:
144 return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
145
146 case IMAGE_TYPE_CUBE:
147 return tcu::UVec3(mipLevelX, mipLevelY, 6u);
148
149 case IMAGE_TYPE_CUBE_ARRAY:
150 return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
151
152 default:
153 DE_FATAL("Unknown image type");
154 return tcu::UVec3(1u, 1u, 1u);
155 }
156 }
157
getLayerSize(const ImageType imageType,const tcu::UVec3 & imageSize)158 tcu::UVec3 getLayerSize(const ImageType imageType, const tcu::UVec3 &imageSize)
159 {
160 switch (imageType)
161 {
162 case IMAGE_TYPE_1D:
163 case IMAGE_TYPE_1D_ARRAY:
164 case IMAGE_TYPE_BUFFER:
165 return tcu::UVec3(imageSize.x(), 1u, 1u);
166
167 case IMAGE_TYPE_2D:
168 case IMAGE_TYPE_2D_ARRAY:
169 case IMAGE_TYPE_CUBE:
170 case IMAGE_TYPE_CUBE_ARRAY:
171 return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
172
173 case IMAGE_TYPE_3D:
174 return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
175
176 default:
177 DE_FATAL("Unknown image type");
178 return tcu::UVec3(1u, 1u, 1u);
179 }
180 }
181
getNumLayers(const ImageType imageType,const tcu::UVec3 & imageSize)182 uint32_t getNumLayers(const ImageType imageType, const tcu::UVec3 &imageSize)
183 {
184 switch (imageType)
185 {
186 case IMAGE_TYPE_1D:
187 case IMAGE_TYPE_2D:
188 case IMAGE_TYPE_3D:
189 case IMAGE_TYPE_BUFFER:
190 return 1u;
191
192 case IMAGE_TYPE_1D_ARRAY:
193 case IMAGE_TYPE_2D_ARRAY:
194 return imageSize.z();
195
196 case IMAGE_TYPE_CUBE:
197 return 6u;
198
199 case IMAGE_TYPE_CUBE_ARRAY:
200 return imageSize.z() * 6u;
201
202 default:
203 DE_FATAL("Unknown image type");
204 return 0u;
205 }
206 }
207
getNumPixels(const ImageType imageType,const tcu::UVec3 & imageSize)208 uint32_t getNumPixels(const ImageType imageType, const tcu::UVec3 &imageSize)
209 {
210 const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize);
211
212 return gridSize.x() * gridSize.y() * gridSize.z();
213 }
214
getDimensions(const ImageType imageType)215 uint32_t getDimensions(const ImageType imageType)
216 {
217 switch (imageType)
218 {
219 case IMAGE_TYPE_1D:
220 case IMAGE_TYPE_BUFFER:
221 return 1u;
222
223 case IMAGE_TYPE_1D_ARRAY:
224 case IMAGE_TYPE_2D:
225 return 2u;
226
227 case IMAGE_TYPE_2D_ARRAY:
228 case IMAGE_TYPE_CUBE:
229 case IMAGE_TYPE_CUBE_ARRAY:
230 case IMAGE_TYPE_3D:
231 return 3u;
232
233 default:
234 DE_FATAL("Unknown image type");
235 return 0u;
236 }
237 }
238
getLayerDimensions(const ImageType imageType)239 uint32_t getLayerDimensions(const ImageType imageType)
240 {
241 switch (imageType)
242 {
243 case IMAGE_TYPE_1D:
244 case IMAGE_TYPE_BUFFER:
245 case IMAGE_TYPE_1D_ARRAY:
246 return 1u;
247
248 case IMAGE_TYPE_2D:
249 case IMAGE_TYPE_2D_ARRAY:
250 case IMAGE_TYPE_CUBE:
251 case IMAGE_TYPE_CUBE_ARRAY:
252 return 2u;
253
254 case IMAGE_TYPE_3D:
255 return 3u;
256
257 default:
258 DE_FATAL("Unknown image type");
259 return 0u;
260 }
261 }
262
isImageSizeSupported(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType,const tcu::UVec3 & imageSize)263 bool isImageSizeSupported(const InstanceInterface &instance, const VkPhysicalDevice physicalDevice,
264 const ImageType imageType, const tcu::UVec3 &imageSize)
265 {
266 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
267
268 switch (imageType)
269 {
270 case IMAGE_TYPE_1D:
271 return imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
272 case IMAGE_TYPE_1D_ARRAY:
273 return imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
274 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
275 case IMAGE_TYPE_2D:
276 return imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
277 imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
278 case IMAGE_TYPE_2D_ARRAY:
279 return imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
280 imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
281 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
282 case IMAGE_TYPE_CUBE:
283 return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
284 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
285 case IMAGE_TYPE_CUBE_ARRAY:
286 return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
287 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
288 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
289 case IMAGE_TYPE_3D:
290 return imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
291 imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
292 imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
293 case IMAGE_TYPE_BUFFER:
294 return true;
295 default:
296 DE_FATAL("Unknown image type");
297 return false;
298 }
299 }
300
makeBufferImageCopy(const VkExtent3D extent,const uint32_t layerCount,const uint32_t mipmapLevel,const VkDeviceSize bufferOffset)301 VkBufferImageCopy makeBufferImageCopy(const VkExtent3D extent, const uint32_t layerCount, const uint32_t mipmapLevel,
302 const VkDeviceSize bufferOffset)
303 {
304 const VkBufferImageCopy copyParams = {
305 bufferOffset, // VkDeviceSize bufferOffset;
306 0u, // uint32_t bufferRowLength;
307 0u, // uint32_t bufferImageHeight;
308 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipmapLevel, 0u,
309 layerCount), // VkImageSubresourceLayers imageSubresource;
310 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
311 extent, // VkExtent3D imageExtent;
312 };
313 return copyParams;
314 }
315
submitCommands(const DeviceInterface & vk,const VkQueue queue,const VkCommandBuffer commandBuffer,const uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,const VkPipelineStageFlags * pWaitDstStageMask,const uint32_t signalSemaphoreCount,const VkSemaphore * pSignalSemaphores)316 void submitCommands(const DeviceInterface &vk, const VkQueue queue, const VkCommandBuffer commandBuffer,
317 const uint32_t waitSemaphoreCount, const VkSemaphore *pWaitSemaphores,
318 const VkPipelineStageFlags *pWaitDstStageMask, const uint32_t signalSemaphoreCount,
319 const VkSemaphore *pSignalSemaphores)
320 {
321 const VkSubmitInfo submitInfo = {
322 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
323 DE_NULL, // const void* pNext;
324 waitSemaphoreCount, // uint32_t waitSemaphoreCount;
325 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores;
326 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask;
327 1u, // uint32_t commandBufferCount;
328 &commandBuffer, // const VkCommandBuffer* pCommandBuffers;
329 signalSemaphoreCount, // uint32_t signalSemaphoreCount;
330 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores;
331 };
332
333 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
334 }
335
submitCommandsAndWait(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,const VkCommandBuffer commandBuffer,const uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,const VkPipelineStageFlags * pWaitDstStageMask,const uint32_t signalSemaphoreCount,const VkSemaphore * pSignalSemaphores,const bool useDeviceGroups,const uint32_t physicalDeviceID)336 void submitCommandsAndWait(const DeviceInterface &vk, const VkDevice device, const VkQueue queue,
337 const VkCommandBuffer commandBuffer, const uint32_t waitSemaphoreCount,
338 const VkSemaphore *pWaitSemaphores, const VkPipelineStageFlags *pWaitDstStageMask,
339 const uint32_t signalSemaphoreCount, const VkSemaphore *pSignalSemaphores,
340 const bool useDeviceGroups, const uint32_t physicalDeviceID)
341 {
342 const VkFenceCreateInfo fenceParams = {
343 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
344 DE_NULL, // const void* pNext;
345 0u, // VkFenceCreateFlags flags;
346 };
347 const Unique<VkFence> fence(createFence(vk, device, &fenceParams));
348
349 const uint32_t deviceMask = 1 << physicalDeviceID;
350 std::vector<uint32_t> deviceIndices(waitSemaphoreCount, physicalDeviceID);
351 VkDeviceGroupSubmitInfo deviceGroupSubmitInfo = {
352 VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO, //VkStructureType sType
353 DE_NULL, // const void* pNext
354 waitSemaphoreCount, // uint32_t waitSemaphoreCount
355 deviceIndices.size() ? &deviceIndices[0] : DE_NULL, // const uint32_t* pWaitSemaphoreDeviceIndices
356 1u, // uint32_t commandBufferCount
357 &deviceMask, // const uint32_t* pCommandBufferDeviceMasks
358 0u, // uint32_t signalSemaphoreCount
359 DE_NULL, // const uint32_t* pSignalSemaphoreDeviceIndices
360 };
361 const VkSubmitInfo submitInfo = {
362 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
363 useDeviceGroups ? &deviceGroupSubmitInfo : DE_NULL, // const void* pNext;
364 waitSemaphoreCount, // uint32_t waitSemaphoreCount;
365 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores;
366 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask;
367 1u, // uint32_t commandBufferCount;
368 &commandBuffer, // const VkCommandBuffer* pCommandBuffers;
369 signalSemaphoreCount, // uint32_t signalSemaphoreCount;
370 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores;
371 };
372
373 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
374 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), true, ~0ull));
375 }
376
mapImageType(const ImageType imageType)377 VkImageType mapImageType(const ImageType imageType)
378 {
379 switch (imageType)
380 {
381 case IMAGE_TYPE_1D:
382 case IMAGE_TYPE_1D_ARRAY:
383 case IMAGE_TYPE_BUFFER:
384 return VK_IMAGE_TYPE_1D;
385
386 case IMAGE_TYPE_2D:
387 case IMAGE_TYPE_2D_ARRAY:
388 case IMAGE_TYPE_CUBE:
389 case IMAGE_TYPE_CUBE_ARRAY:
390 return VK_IMAGE_TYPE_2D;
391
392 case IMAGE_TYPE_3D:
393 return VK_IMAGE_TYPE_3D;
394
395 default:
396 DE_FATAL("Unexpected image type");
397 return VK_IMAGE_TYPE_LAST;
398 }
399 }
400
mapImageViewType(const ImageType imageType)401 VkImageViewType mapImageViewType(const ImageType imageType)
402 {
403 switch (imageType)
404 {
405 case IMAGE_TYPE_1D:
406 return VK_IMAGE_VIEW_TYPE_1D;
407 case IMAGE_TYPE_1D_ARRAY:
408 return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
409 case IMAGE_TYPE_2D:
410 return VK_IMAGE_VIEW_TYPE_2D;
411 case IMAGE_TYPE_2D_ARRAY:
412 return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
413 case IMAGE_TYPE_3D:
414 return VK_IMAGE_VIEW_TYPE_3D;
415 case IMAGE_TYPE_CUBE:
416 return VK_IMAGE_VIEW_TYPE_CUBE;
417 case IMAGE_TYPE_CUBE_ARRAY:
418 return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
419
420 default:
421 DE_FATAL("Unexpected image type");
422 return VK_IMAGE_VIEW_TYPE_LAST;
423 }
424 }
425
getImageTypeName(const ImageType imageType)426 std::string getImageTypeName(const ImageType imageType)
427 {
428 switch (imageType)
429 {
430 case IMAGE_TYPE_1D:
431 return "1d";
432 case IMAGE_TYPE_1D_ARRAY:
433 return "1d_array";
434 case IMAGE_TYPE_2D:
435 return "2d";
436 case IMAGE_TYPE_2D_ARRAY:
437 return "2d_array";
438 case IMAGE_TYPE_3D:
439 return "3d";
440 case IMAGE_TYPE_CUBE:
441 return "cube";
442 case IMAGE_TYPE_CUBE_ARRAY:
443 return "cube_array";
444 case IMAGE_TYPE_BUFFER:
445 return "buffer";
446
447 default:
448 DE_FATAL("Unexpected image type");
449 return "";
450 }
451 }
452
getShaderImageType(const tcu::TextureFormat & format,const ImageType imageType)453 std::string getShaderImageType(const tcu::TextureFormat &format, const ImageType imageType)
454 {
455 std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ?
456 "u" :
457 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" :
458 "";
459
460 std::string imageTypePart;
461 switch (imageType)
462 {
463 case IMAGE_TYPE_1D:
464 imageTypePart = "1D";
465 break;
466 case IMAGE_TYPE_1D_ARRAY:
467 imageTypePart = "1DArray";
468 break;
469 case IMAGE_TYPE_2D:
470 imageTypePart = "2D";
471 break;
472 case IMAGE_TYPE_2D_ARRAY:
473 imageTypePart = "2DArray";
474 break;
475 case IMAGE_TYPE_3D:
476 imageTypePart = "3D";
477 break;
478 case IMAGE_TYPE_CUBE:
479 imageTypePart = "Cube";
480 break;
481 case IMAGE_TYPE_CUBE_ARRAY:
482 imageTypePart = "CubeArray";
483 break;
484 case IMAGE_TYPE_BUFFER:
485 imageTypePart = "Buffer";
486 break;
487
488 default:
489 DE_FATAL("Unexpected image type");
490 }
491
492 return formatPart + "image" + imageTypePart;
493 }
494
getShaderImageType(const vk::PlanarFormatDescription & description,const ImageType imageType)495 std::string getShaderImageType(const vk::PlanarFormatDescription &description, const ImageType imageType)
496 {
497 std::string formatPart;
498 std::string imageTypePart;
499
500 // all PlanarFormatDescription types have at least one channel ( 0 ) and all channel types are the same :
501 switch (description.channels[0].type)
502 {
503 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
504 formatPart = "i";
505 break;
506 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
507 formatPart = "u";
508 break;
509 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
510 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
511 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
512 break;
513
514 default:
515 DE_FATAL("Unexpected channel type");
516 }
517
518 if (formatIsR64(description.planes[0].planeCompatibleFormat))
519 formatPart += "64";
520
521 switch (imageType)
522 {
523 case IMAGE_TYPE_1D:
524 imageTypePart = "1D";
525 break;
526 case IMAGE_TYPE_1D_ARRAY:
527 imageTypePart = "1DArray";
528 break;
529 case IMAGE_TYPE_2D:
530 imageTypePart = "2D";
531 break;
532 case IMAGE_TYPE_2D_ARRAY:
533 imageTypePart = "2DArray";
534 break;
535 case IMAGE_TYPE_3D:
536 imageTypePart = "3D";
537 break;
538 case IMAGE_TYPE_CUBE:
539 imageTypePart = "Cube";
540 break;
541 case IMAGE_TYPE_CUBE_ARRAY:
542 imageTypePart = "CubeArray";
543 break;
544 case IMAGE_TYPE_BUFFER:
545 imageTypePart = "Buffer";
546 break;
547
548 default:
549 DE_FATAL("Unexpected image type");
550 }
551
552 return formatPart + "image" + imageTypePart;
553 }
554
getShaderImageDataType(const tcu::TextureFormat & format)555 std::string getShaderImageDataType(const tcu::TextureFormat &format)
556 {
557 switch (tcu::getTextureChannelClass(format.type))
558 {
559 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
560 return "uvec4";
561 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
562 return "ivec4";
563 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
564 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
565 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
566 return "vec4";
567 default:
568 DE_FATAL("Unexpected channel type");
569 return "";
570 }
571 }
572
getShaderImageDataType(const vk::PlanarFormatDescription & description)573 std::string getShaderImageDataType(const vk::PlanarFormatDescription &description)
574 {
575 switch (description.channels[0].type)
576 {
577 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
578 return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "u64vec4" : "uvec4");
579 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
580 return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "i64vec4" : "ivec4");
581 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
582 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
583 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
584 return "vec4";
585 default:
586 DE_FATAL("Unexpected channel type");
587 return "";
588 }
589 }
590
getShaderImageFormatQualifier(const tcu::TextureFormat & format)591 std::string getShaderImageFormatQualifier(const tcu::TextureFormat &format)
592 {
593 const char *orderPart;
594 const char *typePart;
595
596 switch (format.order)
597 {
598 case tcu::TextureFormat::R:
599 orderPart = "r";
600 break;
601 case tcu::TextureFormat::RG:
602 orderPart = "rg";
603 break;
604 case tcu::TextureFormat::RGB:
605 orderPart = "rgb";
606 break;
607 case tcu::TextureFormat::RGBA:
608 orderPart = "rgba";
609 break;
610
611 default:
612 DE_FATAL("Unexpected channel order");
613 orderPart = DE_NULL;
614 }
615
616 switch (format.type)
617 {
618 case tcu::TextureFormat::FLOAT:
619 typePart = "32f";
620 break;
621 case tcu::TextureFormat::HALF_FLOAT:
622 typePart = "16f";
623 break;
624
625 case tcu::TextureFormat::UNSIGNED_INT32:
626 typePart = "32ui";
627 break;
628 case tcu::TextureFormat::UNSIGNED_INT16:
629 typePart = "16ui";
630 break;
631 case tcu::TextureFormat::UNSIGNED_INT8:
632 typePart = "8ui";
633 break;
634
635 case tcu::TextureFormat::SIGNED_INT32:
636 typePart = "32i";
637 break;
638 case tcu::TextureFormat::SIGNED_INT16:
639 typePart = "16i";
640 break;
641 case tcu::TextureFormat::SIGNED_INT8:
642 typePart = "8i";
643 break;
644
645 case tcu::TextureFormat::UNORM_INT16:
646 typePart = "16";
647 break;
648 case tcu::TextureFormat::UNORM_INT8:
649 typePart = "8";
650 break;
651
652 case tcu::TextureFormat::SNORM_INT16:
653 typePart = "16_snorm";
654 break;
655 case tcu::TextureFormat::SNORM_INT8:
656 typePart = "8_snorm";
657 break;
658
659 default:
660 DE_FATAL("Unexpected channel type");
661 typePart = DE_NULL;
662 }
663
664 return std::string() + orderPart + typePart;
665 }
666
getShaderImageFormatQualifier(VkFormat format)667 std::string getShaderImageFormatQualifier(VkFormat format)
668 {
669 switch (format)
670 {
671 case VK_FORMAT_R8_SINT:
672 return "r8i";
673 case VK_FORMAT_R16_SINT:
674 return "r16i";
675 case VK_FORMAT_R32_SINT:
676 return "r32i";
677 case VK_FORMAT_R64_SINT:
678 return "r64i";
679 case VK_FORMAT_R8_UINT:
680 return "r8ui";
681 case VK_FORMAT_R16_UINT:
682 return "r16ui";
683 case VK_FORMAT_R32_UINT:
684 return "r32ui";
685 case VK_FORMAT_R64_UINT:
686 return "r64ui";
687 case VK_FORMAT_R8_SNORM:
688 return "r8_snorm";
689 case VK_FORMAT_R16_SNORM:
690 return "r16_snorm";
691 case VK_FORMAT_R8_UNORM:
692 return "r8";
693 case VK_FORMAT_R16_UNORM:
694 return "r16";
695
696 case VK_FORMAT_R8G8_SINT:
697 return "rg8i";
698 case VK_FORMAT_R16G16_SINT:
699 return "rg16i";
700 case VK_FORMAT_R32G32_SINT:
701 return "rg32i";
702 case VK_FORMAT_R8G8_UINT:
703 return "rg8ui";
704 case VK_FORMAT_R16G16_UINT:
705 return "rg16ui";
706 case VK_FORMAT_R32G32_UINT:
707 return "rg32ui";
708 case VK_FORMAT_R8G8_SNORM:
709 return "rg8_snorm";
710 case VK_FORMAT_R16G16_SNORM:
711 return "rg16_snorm";
712 case VK_FORMAT_R8G8_UNORM:
713 return "rg8";
714 case VK_FORMAT_R16G16_UNORM:
715 return "rg16";
716
717 case VK_FORMAT_R8G8B8A8_SINT:
718 return "rgba8i";
719 case VK_FORMAT_R16G16B16A16_SINT:
720 return "rgba16i";
721 case VK_FORMAT_R32G32B32A32_SINT:
722 return "rgba32i";
723 case VK_FORMAT_R8G8B8A8_UINT:
724 return "rgba8ui";
725 case VK_FORMAT_R16G16B16A16_UINT:
726 return "rgba16ui";
727 case VK_FORMAT_R32G32B32A32_UINT:
728 return "rgba32ui";
729 case VK_FORMAT_R8G8B8A8_SNORM:
730 return "rgba8_snorm";
731 case VK_FORMAT_R16G16B16A16_SNORM:
732 return "rgba16_snorm";
733 case VK_FORMAT_R8G8B8A8_UNORM:
734 return "rgba8";
735 case VK_FORMAT_R16G16B16A16_UNORM:
736 return "rgba16";
737
738 case VK_FORMAT_G8B8G8R8_422_UNORM:
739 return "rgba8";
740 case VK_FORMAT_B8G8R8G8_422_UNORM:
741 return "rgba8";
742 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
743 return "rgba8";
744 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
745 return "rgba8";
746 case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
747 return "rgba8";
748 case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
749 return "rgba8";
750 case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
751 return "rgba8";
752 case VK_FORMAT_R10X6_UNORM_PACK16:
753 return "r16";
754 case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
755 return "rg16";
756 case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
757 return "rgba16";
758 case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
759 return "rgba16";
760 case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
761 return "rgba16";
762 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
763 return "rgba16";
764 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
765 return "rgba16";
766 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
767 return "rgba16";
768 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
769 return "rgba16";
770 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
771 return "rgba16";
772 case VK_FORMAT_R12X4_UNORM_PACK16:
773 return "r16";
774 case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
775 return "rg16";
776 case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
777 return "rgba16";
778 case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
779 return "rgba16";
780 case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
781 return "rgba16";
782 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
783 return "rgba16";
784 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
785 return "rgba16";
786 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
787 return "rgba16";
788 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
789 return "rgba16";
790 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
791 return "rgba16";
792 case VK_FORMAT_G16B16G16R16_422_UNORM:
793 return "rgba16";
794 case VK_FORMAT_B16G16R16G16_422_UNORM:
795 return "rgba16";
796 case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
797 return "rgba16";
798 case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
799 return "rgba16";
800 case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
801 return "rgba16";
802 case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
803 return "rgba16";
804 case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
805 return "rgba16";
806 case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
807 return "rgba8";
808 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
809 return "rgba16";
810 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
811 return "rgba16";
812 case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
813 return "rgba16";
814
815 default:
816 DE_FATAL("Unexpected texture format");
817 return "error";
818 }
819 }
820
getImageFormatID(VkFormat format)821 std::string getImageFormatID(VkFormat format)
822 {
823 switch (format)
824 {
825 case VK_FORMAT_R8_SINT:
826 return "r8i";
827 case VK_FORMAT_R16_SINT:
828 return "r16i";
829 case VK_FORMAT_R32_SINT:
830 return "r32i";
831 case VK_FORMAT_R64_SINT:
832 return "r64i";
833 case VK_FORMAT_R8_UINT:
834 return "r8ui";
835 case VK_FORMAT_R16_UINT:
836 return "r16ui";
837 case VK_FORMAT_R32_UINT:
838 return "r32ui";
839 case VK_FORMAT_R64_UINT:
840 return "r64ui";
841 case VK_FORMAT_R8_SNORM:
842 return "r8_snorm";
843 case VK_FORMAT_R16_SNORM:
844 return "r16_snorm";
845 case VK_FORMAT_R8_UNORM:
846 return "r8";
847 case VK_FORMAT_R16_UNORM:
848 return "r16";
849
850 case VK_FORMAT_R8G8_SINT:
851 return "rg8i";
852 case VK_FORMAT_R16G16_SINT:
853 return "rg16i";
854 case VK_FORMAT_R32G32_SINT:
855 return "rg32i";
856 case VK_FORMAT_R8G8_UINT:
857 return "rg8ui";
858 case VK_FORMAT_R16G16_UINT:
859 return "rg16ui";
860 case VK_FORMAT_R32G32_UINT:
861 return "rg32ui";
862 case VK_FORMAT_R8G8_SNORM:
863 return "rg8_snorm";
864 case VK_FORMAT_R16G16_SNORM:
865 return "rg16_snorm";
866 case VK_FORMAT_R8G8_UNORM:
867 return "rg8";
868 case VK_FORMAT_R16G16_UNORM:
869 return "rg16";
870
871 case VK_FORMAT_R8G8B8A8_SINT:
872 return "rgba8i";
873 case VK_FORMAT_R16G16B16A16_SINT:
874 return "rgba16i";
875 case VK_FORMAT_R32G32B32A32_SINT:
876 return "rgba32i";
877 case VK_FORMAT_R8G8B8A8_UINT:
878 return "rgba8ui";
879 case VK_FORMAT_R16G16B16A16_UINT:
880 return "rgba16ui";
881 case VK_FORMAT_R32G32B32A32_UINT:
882 return "rgba32ui";
883 case VK_FORMAT_R8G8B8A8_SNORM:
884 return "rgba8_snorm";
885 case VK_FORMAT_R16G16B16A16_SNORM:
886 return "rgba16_snorm";
887 case VK_FORMAT_R8G8B8A8_UNORM:
888 return "rgba8";
889 case VK_FORMAT_R16G16B16A16_UNORM:
890 return "rgba16";
891
892 case VK_FORMAT_G8B8G8R8_422_UNORM:
893 case VK_FORMAT_B8G8R8G8_422_UNORM:
894 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
895 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
896 case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
897 case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
898 case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
899 case VK_FORMAT_R10X6_UNORM_PACK16:
900 case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
901 case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
902 case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
903 case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
904 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
905 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
906 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
907 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
908 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
909 case VK_FORMAT_R12X4_UNORM_PACK16:
910 case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
911 case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
912 case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
913 case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
914 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
915 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
916 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
917 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
918 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
919 case VK_FORMAT_G16B16G16R16_422_UNORM:
920 case VK_FORMAT_B16G16R16G16_422_UNORM:
921 case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
922 case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
923 case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
924 case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
925 case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
926 case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
927 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
928 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
929 case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
930 #ifndef CTS_USES_VULKANSC
931 case VK_FORMAT_A8_UNORM_KHR:
932 #endif // CTS_USES_VULKANSC
933 return de::toLower(std::string(getFormatName(format)).substr(10));
934
935 default:
936 DE_FATAL("Unexpected texture format");
937 return "error";
938 }
939 }
940
getShaderImageCoordinates(const ImageType imageType,const std::string & x,const std::string & xy,const std::string & xyz)941 std::string getShaderImageCoordinates(const ImageType imageType, const std::string &x, const std::string &xy,
942 const std::string &xyz)
943 {
944 switch (imageType)
945 {
946 case IMAGE_TYPE_1D:
947 case IMAGE_TYPE_BUFFER:
948 return x;
949
950 case IMAGE_TYPE_1D_ARRAY:
951 case IMAGE_TYPE_2D:
952 return xy;
953
954 case IMAGE_TYPE_2D_ARRAY:
955 case IMAGE_TYPE_3D:
956 case IMAGE_TYPE_CUBE:
957 case IMAGE_TYPE_CUBE_ARRAY:
958 return xyz;
959
960 default:
961 DE_FATAL("Unexpected image type");
962 return "";
963 }
964 }
965
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const uint32_t layersCount,const tcu::TextureFormat & format,const uint32_t mipmapLevel,const uint32_t mipmapMemoryAlignment)966 uint32_t getImageMipLevelSizeInBytes(const VkExtent3D &baseExtents, const uint32_t layersCount,
967 const tcu::TextureFormat &format, const uint32_t mipmapLevel,
968 const uint32_t mipmapMemoryAlignment)
969 {
970 const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
971
972 return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format),
973 mipmapMemoryAlignment);
974 }
975
getImageSizeInBytes(const VkExtent3D & baseExtents,const uint32_t layersCount,const tcu::TextureFormat & format,const uint32_t mipmapLevelsCount,const uint32_t mipmapMemoryAlignment)976 uint32_t getImageSizeInBytes(const VkExtent3D &baseExtents, const uint32_t layersCount,
977 const tcu::TextureFormat &format, const uint32_t mipmapLevelsCount,
978 const uint32_t mipmapMemoryAlignment)
979 {
980 uint32_t imageSizeInBytes = 0;
981 for (uint32_t mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
982 imageSizeInBytes +=
983 getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
984
985 return imageSizeInBytes;
986 }
987
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const uint32_t layersCount,const vk::PlanarFormatDescription & formatDescription,const uint32_t planeNdx,const uint32_t mipmapLevel,const uint32_t mipmapMemoryAlignment)988 uint32_t getImageMipLevelSizeInBytes(const VkExtent3D &baseExtents, const uint32_t layersCount,
989 const vk::PlanarFormatDescription &formatDescription, const uint32_t planeNdx,
990 const uint32_t mipmapLevel, const uint32_t mipmapMemoryAlignment)
991 {
992 return layersCount *
993 getPlaneSizeInBytes(formatDescription, baseExtents, planeNdx, mipmapLevel, mipmapMemoryAlignment);
994 }
995
getImageSizeInBytes(const VkExtent3D & baseExtents,const uint32_t layersCount,const vk::PlanarFormatDescription & formatDescription,const uint32_t planeNdx,const uint32_t mipmapLevelsCount,const uint32_t mipmapMemoryAlignment)996 uint32_t getImageSizeInBytes(const VkExtent3D &baseExtents, const uint32_t layersCount,
997 const vk::PlanarFormatDescription &formatDescription, const uint32_t planeNdx,
998 const uint32_t mipmapLevelsCount, const uint32_t mipmapMemoryAlignment)
999 {
1000 uint32_t imageSizeInBytes = 0;
1001
1002 for (uint32_t mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
1003 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, formatDescription, planeNdx,
1004 mipmapLevel, mipmapMemoryAlignment);
1005
1006 return imageSizeInBytes;
1007 }
1008
makeSparseImageMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const uint32_t memoryType,const VkImageSubresource & subresource,const VkOffset3D & offset,const VkExtent3D & extent)1009 VkSparseImageMemoryBind makeSparseImageMemoryBind(const DeviceInterface &vk, const VkDevice device,
1010 const VkDeviceSize allocationSize, const uint32_t memoryType,
1011 const VkImageSubresource &subresource, const VkOffset3D &offset,
1012 const VkExtent3D &extent)
1013 {
1014 const VkMemoryAllocateInfo allocInfo = {
1015 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
1016 DE_NULL, // const void* pNext;
1017 allocationSize, // VkDeviceSize allocationSize;
1018 memoryType, // uint32_t memoryTypeIndex;
1019 };
1020
1021 VkDeviceMemory deviceMemory = 0;
1022 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
1023
1024 VkSparseImageMemoryBind imageMemoryBind;
1025
1026 imageMemoryBind.subresource = subresource;
1027 imageMemoryBind.memory = deviceMemory;
1028 imageMemoryBind.memoryOffset = 0u;
1029 imageMemoryBind.flags = 0u;
1030 imageMemoryBind.offset = offset;
1031 imageMemoryBind.extent = extent;
1032
1033 return imageMemoryBind;
1034 }
1035
makeSparseMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const uint32_t memoryType,const VkDeviceSize resourceOffset,const VkSparseMemoryBindFlags flags)1036 VkSparseMemoryBind makeSparseMemoryBind(const DeviceInterface &vk, const VkDevice device,
1037 const VkDeviceSize allocationSize, const uint32_t memoryType,
1038 const VkDeviceSize resourceOffset, const VkSparseMemoryBindFlags flags)
1039 {
1040 const VkMemoryAllocateInfo allocInfo = {
1041 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
1042 DE_NULL, // const void* pNext;
1043 allocationSize, // VkDeviceSize allocationSize;
1044 memoryType, // uint32_t memoryTypeIndex;
1045 };
1046
1047 VkDeviceMemory deviceMemory = 0;
1048 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
1049
1050 VkSparseMemoryBind memoryBind;
1051
1052 memoryBind.resourceOffset = resourceOffset;
1053 memoryBind.size = allocationSize;
1054 memoryBind.memory = deviceMemory;
1055 memoryBind.memoryOffset = 0u;
1056 memoryBind.flags = flags;
1057
1058 return memoryBind;
1059 }
1060
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)1061 void requireFeatures(const InstanceInterface &vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
1062 {
1063 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
1064
1065 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
1066 throw tcu::NotSupportedError("Tessellation shader not supported");
1067
1068 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
1069 throw tcu::NotSupportedError("Geometry shader not supported");
1070
1071 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
1072 throw tcu::NotSupportedError("Double-precision floats not supported");
1073
1074 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
1075 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
1076
1077 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
1078 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
1079
1080 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) &&
1081 !features.shaderTessellationAndGeometryPointSize)
1082 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
1083 }
1084
findMatchingMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkMemoryRequirements & objectMemoryRequirements,const MemoryRequirement & memoryRequirement)1085 uint32_t findMatchingMemoryType(const InstanceInterface &instance, const VkPhysicalDevice physicalDevice,
1086 const VkMemoryRequirements &objectMemoryRequirements,
1087 const MemoryRequirement &memoryRequirement)
1088 {
1089 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties =
1090 getPhysicalDeviceMemoryProperties(instance, physicalDevice);
1091
1092 for (uint32_t memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
1093 {
1094 if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
1095 memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
1096 {
1097 return memoryTypeNdx;
1098 }
1099 }
1100
1101 return NO_MATCH_FOUND;
1102 }
1103
getHeapIndexForMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const uint32_t memoryType)1104 uint32_t getHeapIndexForMemoryType(const InstanceInterface &instance, const VkPhysicalDevice physicalDevice,
1105 const uint32_t memoryType)
1106 {
1107 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties =
1108 getPhysicalDeviceMemoryProperties(instance, physicalDevice);
1109 DE_ASSERT(memoryType < deviceMemoryProperties.memoryTypeCount);
1110 return deviceMemoryProperties.memoryTypes[memoryType].heapIndex;
1111 }
1112
checkSparseSupportForImageType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType)1113 bool checkSparseSupportForImageType(const InstanceInterface &instance, const VkPhysicalDevice physicalDevice,
1114 const ImageType imageType)
1115 {
1116 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
1117
1118 if (!deviceFeatures.sparseBinding)
1119 return false;
1120
1121 switch (mapImageType(imageType))
1122 {
1123 case VK_IMAGE_TYPE_2D:
1124 return deviceFeatures.sparseResidencyImage2D == VK_TRUE;
1125 case VK_IMAGE_TYPE_3D:
1126 return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
1127 default:
1128 DE_FATAL("Unexpected image type");
1129 return false;
1130 }
1131 }
1132
checkSparseSupportForImageFormat(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkImageCreateInfo & imageInfo)1133 bool checkSparseSupportForImageFormat(const InstanceInterface &instance, const VkPhysicalDevice physicalDevice,
1134 const VkImageCreateInfo &imageInfo)
1135 {
1136 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec =
1137 getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, imageInfo.format, imageInfo.imageType,
1138 imageInfo.samples, imageInfo.usage, imageInfo.tiling);
1139
1140 return sparseImageFormatPropVec.size() > 0u;
1141 }
1142
checkImageFormatFeatureSupport(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkFormat format,const VkFormatFeatureFlags featureFlags)1143 bool checkImageFormatFeatureSupport(const InstanceInterface &instance, const VkPhysicalDevice physicalDevice,
1144 const VkFormat format, const VkFormatFeatureFlags featureFlags)
1145 {
1146 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
1147
1148 return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags;
1149 }
1150
getSparseAspectRequirementsIndex(const std::vector<VkSparseImageMemoryRequirements> & requirements,const VkImageAspectFlags aspectFlags)1151 uint32_t getSparseAspectRequirementsIndex(const std::vector<VkSparseImageMemoryRequirements> &requirements,
1152 const VkImageAspectFlags aspectFlags)
1153 {
1154 for (uint32_t memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx)
1155 {
1156 if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags)
1157 return memoryReqNdx;
1158 }
1159
1160 return NO_MATCH_FOUND;
1161 }
1162
getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription & formatInfo,uint32_t planeNdx)1163 vk::VkFormat getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription &formatInfo, uint32_t planeNdx)
1164 {
1165 DE_ASSERT(planeNdx < formatInfo.numPlanes);
1166 vk::VkFormat result = formatInfo.planes[planeNdx].planeCompatibleFormat;
1167
1168 // redirect result for some of the YCbCr image formats
1169 static const std::pair<vk::VkFormat, vk::VkFormat> ycbcrFormats[] = {
1170 {VK_FORMAT_G8B8G8R8_422_UNORM, VK_FORMAT_R8G8B8A8_UNORM},
1171 {VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM},
1172 {VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM},
1173 {VK_FORMAT_G16B16G16R16_422_UNORM, VK_FORMAT_R16G16B16A16_UNORM},
1174 {VK_FORMAT_B8G8R8G8_422_UNORM, VK_FORMAT_R8G8B8A8_UNORM},
1175 {VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM},
1176 {VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM},
1177 {VK_FORMAT_B16G16R16G16_422_UNORM, VK_FORMAT_R16G16B16A16_UNORM}};
1178 auto it = std::find_if(std::begin(ycbcrFormats), std::end(ycbcrFormats),
1179 [result](const std::pair<vk::VkFormat, vk::VkFormat> &p) { return p.first == result; });
1180 if (it != std::end(ycbcrFormats))
1181 result = it->second;
1182 return result;
1183 }
1184
areLsb6BitsDontCare(vk::VkFormat format)1185 bool areLsb6BitsDontCare(vk::VkFormat format)
1186 {
1187 if ((format == vk::VK_FORMAT_R10X6_UNORM_PACK16) || (format == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16) ||
1188 (format == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16) ||
1189 (format == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16) ||
1190 (format == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16) ||
1191 (format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16) ||
1192 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) ||
1193 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) ||
1194 (format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16) ||
1195 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16))
1196 {
1197 return true;
1198 }
1199
1200 return false;
1201 }
1202
areLsb4BitsDontCare(vk::VkFormat format)1203 bool areLsb4BitsDontCare(vk::VkFormat format)
1204 {
1205 if ((format == vk::VK_FORMAT_R12X4_UNORM_PACK16) || (format == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16) ||
1206 (format == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16) ||
1207 (format == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16) ||
1208 (format == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16) ||
1209 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) ||
1210 (format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16) ||
1211 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) ||
1212 (format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16) ||
1213 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16))
1214 {
1215 return true;
1216 }
1217
1218 return false;
1219 }
1220
1221 } // namespace sparse
1222 } // namespace vkt
1223