• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,const bool useDeviceGroups,const uint32_t physicalDeviceID)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, const bool useDeviceGroups, const uint32_t physicalDeviceID)
320 {
321     const uint32_t deviceMask = 1 << physicalDeviceID;
322     std::vector<uint32_t> deviceIndices(waitSemaphoreCount, physicalDeviceID);
323     VkDeviceGroupSubmitInfo deviceGroupSubmitInfo = {
324         VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO,         //VkStructureType        sType
325         nullptr,                                            // const void*            pNext
326         waitSemaphoreCount,                                 // uint32_t                waitSemaphoreCount
327         deviceIndices.size() ? &deviceIndices[0] : nullptr, // const uint32_t*        pWaitSemaphoreDeviceIndices
328         1u,                                                 // uint32_t                commandBufferCount
329         &deviceMask,                                        // const uint32_t*        pCommandBufferDeviceMasks
330         0u,                                                 // uint32_t                signalSemaphoreCount
331         nullptr,                                            // const uint32_t*        pSignalSemaphoreDeviceIndices
332     };
333 
334     const VkSubmitInfo submitInfo = {
335         VK_STRUCTURE_TYPE_SUBMIT_INFO,                      // VkStructureType sType;
336         useDeviceGroups ? &deviceGroupSubmitInfo : nullptr, // const void* pNext;
337         waitSemaphoreCount,                                 // uint32_t waitSemaphoreCount;
338         pWaitSemaphores,                                    // const VkSemaphore* pWaitSemaphores;
339         pWaitDstStageMask,                                  // const VkPipelineStageFlags* pWaitDstStageMask;
340         1u,                                                 // uint32_t commandBufferCount;
341         &commandBuffer,                                     // const VkCommandBuffer* pCommandBuffers;
342         signalSemaphoreCount,                               // uint32_t signalSemaphoreCount;
343         pSignalSemaphores,                                  // const VkSemaphore* pSignalSemaphores;
344     };
345 
346     VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, VK_NULL_HANDLE));
347 }
348 
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)349 void submitCommandsAndWait(const DeviceInterface &vk, const VkDevice device, const VkQueue queue,
350                            const VkCommandBuffer commandBuffer, const uint32_t waitSemaphoreCount,
351                            const VkSemaphore *pWaitSemaphores, const VkPipelineStageFlags *pWaitDstStageMask,
352                            const uint32_t signalSemaphoreCount, const VkSemaphore *pSignalSemaphores,
353                            const bool useDeviceGroups, const uint32_t physicalDeviceID)
354 {
355     const VkFenceCreateInfo fenceParams = {
356         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
357         nullptr,                             // const void* pNext;
358         0u,                                  // VkFenceCreateFlags flags;
359     };
360     const Unique<VkFence> fence(createFence(vk, device, &fenceParams));
361 
362     const uint32_t deviceMask = 1 << physicalDeviceID;
363     std::vector<uint32_t> deviceIndices(waitSemaphoreCount, physicalDeviceID);
364     VkDeviceGroupSubmitInfo deviceGroupSubmitInfo = {
365         VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO,         //VkStructureType        sType
366         nullptr,                                            // const void*            pNext
367         waitSemaphoreCount,                                 // uint32_t                waitSemaphoreCount
368         deviceIndices.size() ? &deviceIndices[0] : nullptr, // const uint32_t*        pWaitSemaphoreDeviceIndices
369         1u,                                                 // uint32_t                commandBufferCount
370         &deviceMask,                                        // const uint32_t*        pCommandBufferDeviceMasks
371         0u,                                                 // uint32_t                signalSemaphoreCount
372         nullptr,                                            // const uint32_t*        pSignalSemaphoreDeviceIndices
373     };
374     const VkSubmitInfo submitInfo = {
375         VK_STRUCTURE_TYPE_SUBMIT_INFO,                      // VkStructureType sType;
376         useDeviceGroups ? &deviceGroupSubmitInfo : nullptr, // const void* pNext;
377         waitSemaphoreCount,                                 // uint32_t waitSemaphoreCount;
378         pWaitSemaphores,                                    // const VkSemaphore* pWaitSemaphores;
379         pWaitDstStageMask,                                  // const VkPipelineStageFlags* pWaitDstStageMask;
380         1u,                                                 // uint32_t commandBufferCount;
381         &commandBuffer,                                     // const VkCommandBuffer* pCommandBuffers;
382         signalSemaphoreCount,                               // uint32_t signalSemaphoreCount;
383         pSignalSemaphores,                                  // const VkSemaphore* pSignalSemaphores;
384     };
385 
386     VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
387     VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), true, ~0ull));
388 }
389 
mapImageType(const ImageType imageType)390 VkImageType mapImageType(const ImageType imageType)
391 {
392     switch (imageType)
393     {
394     case IMAGE_TYPE_1D:
395     case IMAGE_TYPE_1D_ARRAY:
396     case IMAGE_TYPE_BUFFER:
397         return VK_IMAGE_TYPE_1D;
398 
399     case IMAGE_TYPE_2D:
400     case IMAGE_TYPE_2D_ARRAY:
401     case IMAGE_TYPE_CUBE:
402     case IMAGE_TYPE_CUBE_ARRAY:
403         return VK_IMAGE_TYPE_2D;
404 
405     case IMAGE_TYPE_3D:
406         return VK_IMAGE_TYPE_3D;
407 
408     default:
409         DE_FATAL("Unexpected image type");
410         return VK_IMAGE_TYPE_LAST;
411     }
412 }
413 
mapImageViewType(const ImageType imageType)414 VkImageViewType mapImageViewType(const ImageType imageType)
415 {
416     switch (imageType)
417     {
418     case IMAGE_TYPE_1D:
419         return VK_IMAGE_VIEW_TYPE_1D;
420     case IMAGE_TYPE_1D_ARRAY:
421         return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
422     case IMAGE_TYPE_2D:
423         return VK_IMAGE_VIEW_TYPE_2D;
424     case IMAGE_TYPE_2D_ARRAY:
425         return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
426     case IMAGE_TYPE_3D:
427         return VK_IMAGE_VIEW_TYPE_3D;
428     case IMAGE_TYPE_CUBE:
429         return VK_IMAGE_VIEW_TYPE_CUBE;
430     case IMAGE_TYPE_CUBE_ARRAY:
431         return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
432 
433     default:
434         DE_FATAL("Unexpected image type");
435         return VK_IMAGE_VIEW_TYPE_LAST;
436     }
437 }
438 
getImageTypeName(const ImageType imageType)439 std::string getImageTypeName(const ImageType imageType)
440 {
441     switch (imageType)
442     {
443     case IMAGE_TYPE_1D:
444         return "1d";
445     case IMAGE_TYPE_1D_ARRAY:
446         return "1d_array";
447     case IMAGE_TYPE_2D:
448         return "2d";
449     case IMAGE_TYPE_2D_ARRAY:
450         return "2d_array";
451     case IMAGE_TYPE_3D:
452         return "3d";
453     case IMAGE_TYPE_CUBE:
454         return "cube";
455     case IMAGE_TYPE_CUBE_ARRAY:
456         return "cube_array";
457     case IMAGE_TYPE_BUFFER:
458         return "buffer";
459 
460     default:
461         DE_FATAL("Unexpected image type");
462         return "";
463     }
464 }
465 
getShaderImageType(const tcu::TextureFormat & format,const ImageType imageType)466 std::string getShaderImageType(const tcu::TextureFormat &format, const ImageType imageType)
467 {
468     std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ?
469                                  "u" :
470                              tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" :
471                                                                                                                    "";
472 
473     std::string imageTypePart;
474     switch (imageType)
475     {
476     case IMAGE_TYPE_1D:
477         imageTypePart = "1D";
478         break;
479     case IMAGE_TYPE_1D_ARRAY:
480         imageTypePart = "1DArray";
481         break;
482     case IMAGE_TYPE_2D:
483         imageTypePart = "2D";
484         break;
485     case IMAGE_TYPE_2D_ARRAY:
486         imageTypePart = "2DArray";
487         break;
488     case IMAGE_TYPE_3D:
489         imageTypePart = "3D";
490         break;
491     case IMAGE_TYPE_CUBE:
492         imageTypePart = "Cube";
493         break;
494     case IMAGE_TYPE_CUBE_ARRAY:
495         imageTypePart = "CubeArray";
496         break;
497     case IMAGE_TYPE_BUFFER:
498         imageTypePart = "Buffer";
499         break;
500 
501     default:
502         DE_FATAL("Unexpected image type");
503     }
504 
505     return formatPart + "image" + imageTypePart;
506 }
507 
getShaderImageType(const vk::PlanarFormatDescription & description,const ImageType imageType)508 std::string getShaderImageType(const vk::PlanarFormatDescription &description, const ImageType imageType)
509 {
510     std::string formatPart;
511     std::string imageTypePart;
512 
513     // all PlanarFormatDescription types have at least one channel ( 0 ) and all channel types are the same :
514     switch (description.channels[0].type)
515     {
516     case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
517         formatPart = "i";
518         break;
519     case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
520         formatPart = "u";
521         break;
522     case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
523     case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
524     case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
525         break;
526 
527     default:
528         DE_FATAL("Unexpected channel type");
529     }
530 
531     if (formatIsR64(description.planes[0].planeCompatibleFormat))
532         formatPart += "64";
533 
534     switch (imageType)
535     {
536     case IMAGE_TYPE_1D:
537         imageTypePart = "1D";
538         break;
539     case IMAGE_TYPE_1D_ARRAY:
540         imageTypePart = "1DArray";
541         break;
542     case IMAGE_TYPE_2D:
543         imageTypePart = "2D";
544         break;
545     case IMAGE_TYPE_2D_ARRAY:
546         imageTypePart = "2DArray";
547         break;
548     case IMAGE_TYPE_3D:
549         imageTypePart = "3D";
550         break;
551     case IMAGE_TYPE_CUBE:
552         imageTypePart = "Cube";
553         break;
554     case IMAGE_TYPE_CUBE_ARRAY:
555         imageTypePart = "CubeArray";
556         break;
557     case IMAGE_TYPE_BUFFER:
558         imageTypePart = "Buffer";
559         break;
560 
561     default:
562         DE_FATAL("Unexpected image type");
563     }
564 
565     return formatPart + "image" + imageTypePart;
566 }
567 
getShaderImageDataType(const tcu::TextureFormat & format)568 std::string getShaderImageDataType(const tcu::TextureFormat &format)
569 {
570     switch (tcu::getTextureChannelClass(format.type))
571     {
572     case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
573         return "uvec4";
574     case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
575         return "ivec4";
576     case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
577     case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
578     case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
579         return "vec4";
580     default:
581         DE_FATAL("Unexpected channel type");
582         return "";
583     }
584 }
585 
getShaderImageDataType(const vk::PlanarFormatDescription & description)586 std::string getShaderImageDataType(const vk::PlanarFormatDescription &description)
587 {
588     switch (description.channels[0].type)
589     {
590     case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
591         return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "u64vec4" : "uvec4");
592     case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
593         return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "i64vec4" : "ivec4");
594     case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
595     case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
596     case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
597         return "vec4";
598     default:
599         DE_FATAL("Unexpected channel type");
600         return "";
601     }
602 }
603 
getShaderImageFormatQualifier(const tcu::TextureFormat & format)604 std::string getShaderImageFormatQualifier(const tcu::TextureFormat &format)
605 {
606     const char *orderPart;
607     const char *typePart;
608 
609     switch (format.order)
610     {
611     case tcu::TextureFormat::R:
612         orderPart = "r";
613         break;
614     case tcu::TextureFormat::RG:
615         orderPart = "rg";
616         break;
617     case tcu::TextureFormat::RGB:
618         orderPart = "rgb";
619         break;
620     case tcu::TextureFormat::RGBA:
621         orderPart = "rgba";
622         break;
623 
624     default:
625         DE_FATAL("Unexpected channel order");
626         orderPart = nullptr;
627     }
628 
629     switch (format.type)
630     {
631     case tcu::TextureFormat::FLOAT:
632         typePart = "32f";
633         break;
634     case tcu::TextureFormat::HALF_FLOAT:
635         typePart = "16f";
636         break;
637 
638     case tcu::TextureFormat::UNSIGNED_INT32:
639         typePart = "32ui";
640         break;
641     case tcu::TextureFormat::UNSIGNED_INT16:
642         typePart = "16ui";
643         break;
644     case tcu::TextureFormat::UNSIGNED_INT8:
645         typePart = "8ui";
646         break;
647 
648     case tcu::TextureFormat::SIGNED_INT32:
649         typePart = "32i";
650         break;
651     case tcu::TextureFormat::SIGNED_INT16:
652         typePart = "16i";
653         break;
654     case tcu::TextureFormat::SIGNED_INT8:
655         typePart = "8i";
656         break;
657 
658     case tcu::TextureFormat::UNORM_INT16:
659         typePart = "16";
660         break;
661     case tcu::TextureFormat::UNORM_INT8:
662         typePart = "8";
663         break;
664 
665     case tcu::TextureFormat::SNORM_INT16:
666         typePart = "16_snorm";
667         break;
668     case tcu::TextureFormat::SNORM_INT8:
669         typePart = "8_snorm";
670         break;
671 
672     default:
673         DE_FATAL("Unexpected channel type");
674         typePart = nullptr;
675     }
676 
677     return std::string() + orderPart + typePart;
678 }
679 
getShaderImageFormatQualifier(VkFormat format)680 std::string getShaderImageFormatQualifier(VkFormat format)
681 {
682     switch (format)
683     {
684     case VK_FORMAT_R8_SINT:
685         return "r8i";
686     case VK_FORMAT_R16_SINT:
687         return "r16i";
688     case VK_FORMAT_R32_SINT:
689         return "r32i";
690     case VK_FORMAT_R64_SINT:
691         return "r64i";
692     case VK_FORMAT_R8_UINT:
693         return "r8ui";
694     case VK_FORMAT_R16_UINT:
695         return "r16ui";
696     case VK_FORMAT_R32_UINT:
697         return "r32ui";
698     case VK_FORMAT_R64_UINT:
699         return "r64ui";
700     case VK_FORMAT_R8_SNORM:
701         return "r8_snorm";
702     case VK_FORMAT_R16_SNORM:
703         return "r16_snorm";
704     case VK_FORMAT_R8_UNORM:
705         return "r8";
706     case VK_FORMAT_R16_UNORM:
707         return "r16";
708 
709     case VK_FORMAT_R8G8_SINT:
710         return "rg8i";
711     case VK_FORMAT_R16G16_SINT:
712         return "rg16i";
713     case VK_FORMAT_R32G32_SINT:
714         return "rg32i";
715     case VK_FORMAT_R8G8_UINT:
716         return "rg8ui";
717     case VK_FORMAT_R16G16_UINT:
718         return "rg16ui";
719     case VK_FORMAT_R32G32_UINT:
720         return "rg32ui";
721     case VK_FORMAT_R8G8_SNORM:
722         return "rg8_snorm";
723     case VK_FORMAT_R16G16_SNORM:
724         return "rg16_snorm";
725     case VK_FORMAT_R8G8_UNORM:
726         return "rg8";
727     case VK_FORMAT_R16G16_UNORM:
728         return "rg16";
729 
730     case VK_FORMAT_R8G8B8A8_SINT:
731         return "rgba8i";
732     case VK_FORMAT_R16G16B16A16_SINT:
733         return "rgba16i";
734     case VK_FORMAT_R32G32B32A32_SINT:
735         return "rgba32i";
736     case VK_FORMAT_R8G8B8A8_UINT:
737         return "rgba8ui";
738     case VK_FORMAT_R16G16B16A16_UINT:
739         return "rgba16ui";
740     case VK_FORMAT_R32G32B32A32_UINT:
741         return "rgba32ui";
742     case VK_FORMAT_R8G8B8A8_SNORM:
743         return "rgba8_snorm";
744     case VK_FORMAT_R16G16B16A16_SNORM:
745         return "rgba16_snorm";
746     case VK_FORMAT_R8G8B8A8_UNORM:
747         return "rgba8";
748     case VK_FORMAT_R16G16B16A16_UNORM:
749         return "rgba16";
750 
751     case VK_FORMAT_G8B8G8R8_422_UNORM:
752         return "rgba8";
753     case VK_FORMAT_B8G8R8G8_422_UNORM:
754         return "rgba8";
755     case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
756         return "rgba8";
757     case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
758         return "rgba8";
759     case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
760         return "rgba8";
761     case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
762         return "rgba8";
763     case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
764         return "rgba8";
765     case VK_FORMAT_R10X6_UNORM_PACK16:
766         return "r16";
767     case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
768         return "rg16";
769     case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
770         return "rgba16";
771     case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
772         return "rgba16";
773     case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
774         return "rgba16";
775     case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
776         return "rgba16";
777     case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
778         return "rgba16";
779     case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
780         return "rgba16";
781     case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
782         return "rgba16";
783     case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
784         return "rgba16";
785     case VK_FORMAT_R12X4_UNORM_PACK16:
786         return "r16";
787     case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
788         return "rg16";
789     case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
790         return "rgba16";
791     case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
792         return "rgba16";
793     case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
794         return "rgba16";
795     case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
796         return "rgba16";
797     case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
798         return "rgba16";
799     case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
800         return "rgba16";
801     case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
802         return "rgba16";
803     case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
804         return "rgba16";
805     case VK_FORMAT_G16B16G16R16_422_UNORM:
806         return "rgba16";
807     case VK_FORMAT_B16G16R16G16_422_UNORM:
808         return "rgba16";
809     case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
810         return "rgba16";
811     case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
812         return "rgba16";
813     case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
814         return "rgba16";
815     case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
816         return "rgba16";
817     case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
818         return "rgba16";
819     case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
820         return "rgba8";
821     case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
822         return "rgba16";
823     case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
824         return "rgba16";
825     case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
826         return "rgba16";
827 
828     default:
829         DE_FATAL("Unexpected texture format");
830         return "error";
831     }
832 }
833 
getImageFormatID(VkFormat format)834 std::string getImageFormatID(VkFormat format)
835 {
836     switch (format)
837     {
838     case VK_FORMAT_R8_SINT:
839         return "r8i";
840     case VK_FORMAT_R16_SINT:
841         return "r16i";
842     case VK_FORMAT_R32_SINT:
843         return "r32i";
844     case VK_FORMAT_R64_SINT:
845         return "r64i";
846     case VK_FORMAT_R8_UINT:
847         return "r8ui";
848     case VK_FORMAT_R16_UINT:
849         return "r16ui";
850     case VK_FORMAT_R32_UINT:
851         return "r32ui";
852     case VK_FORMAT_R64_UINT:
853         return "r64ui";
854     case VK_FORMAT_R8_SNORM:
855         return "r8_snorm";
856     case VK_FORMAT_R16_SNORM:
857         return "r16_snorm";
858     case VK_FORMAT_R8_UNORM:
859         return "r8";
860     case VK_FORMAT_R16_UNORM:
861         return "r16";
862     case VK_FORMAT_R32_SFLOAT:
863         return "r32f";
864 
865     case VK_FORMAT_R8G8_SINT:
866         return "rg8i";
867     case VK_FORMAT_R16G16_SINT:
868         return "rg16i";
869     case VK_FORMAT_R32G32_SINT:
870         return "rg32i";
871     case VK_FORMAT_R8G8_UINT:
872         return "rg8ui";
873     case VK_FORMAT_R16G16_UINT:
874         return "rg16ui";
875     case VK_FORMAT_R32G32_UINT:
876         return "rg32ui";
877     case VK_FORMAT_R8G8_SNORM:
878         return "rg8_snorm";
879     case VK_FORMAT_R16G16_SNORM:
880         return "rg16_snorm";
881     case VK_FORMAT_R8G8_UNORM:
882         return "rg8";
883     case VK_FORMAT_R16G16_UNORM:
884         return "rg16";
885 
886     case VK_FORMAT_R8G8B8A8_SINT:
887         return "rgba8i";
888     case VK_FORMAT_R16G16B16A16_SINT:
889         return "rgba16i";
890     case VK_FORMAT_R32G32B32A32_SINT:
891         return "rgba32i";
892     case VK_FORMAT_R8G8B8A8_UINT:
893         return "rgba8ui";
894     case VK_FORMAT_R16G16B16A16_UINT:
895         return "rgba16ui";
896     case VK_FORMAT_R32G32B32A32_UINT:
897         return "rgba32ui";
898     case VK_FORMAT_R8G8B8A8_SNORM:
899         return "rgba8_snorm";
900     case VK_FORMAT_R16G16B16A16_SNORM:
901         return "rgba16_snorm";
902     case VK_FORMAT_R8G8B8A8_UNORM:
903         return "rgba8";
904     case VK_FORMAT_R16G16B16A16_UNORM:
905         return "rgba16";
906     case VK_FORMAT_R16G16B16A16_SFLOAT:
907         return "rgba16f";
908     case VK_FORMAT_R32G32B32A32_SFLOAT:
909         return "rgba32f";
910 
911     case VK_FORMAT_G8B8G8R8_422_UNORM:
912     case VK_FORMAT_B8G8R8G8_422_UNORM:
913     case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
914     case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
915     case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
916     case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
917     case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
918     case VK_FORMAT_R10X6_UNORM_PACK16:
919     case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
920     case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
921     case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
922     case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
923     case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
924     case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
925     case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
926     case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
927     case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
928     case VK_FORMAT_R12X4_UNORM_PACK16:
929     case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
930     case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
931     case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
932     case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
933     case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
934     case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
935     case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
936     case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
937     case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
938     case VK_FORMAT_G16B16G16R16_422_UNORM:
939     case VK_FORMAT_B16G16R16G16_422_UNORM:
940     case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
941     case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
942     case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
943     case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
944     case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
945     case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
946     case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
947     case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
948     case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
949 #ifndef CTS_USES_VULKANSC
950     case VK_FORMAT_A8_UNORM_KHR:
951 #endif // CTS_USES_VULKANSC
952         return de::toLower(std::string(getFormatName(format)).substr(10));
953 
954     default:
955         DE_FATAL("Unexpected texture format");
956         return "error";
957     }
958 }
959 
getShaderImageCoordinates(const ImageType imageType,const std::string & x,const std::string & xy,const std::string & xyz)960 std::string getShaderImageCoordinates(const ImageType imageType, const std::string &x, const std::string &xy,
961                                       const std::string &xyz)
962 {
963     switch (imageType)
964     {
965     case IMAGE_TYPE_1D:
966     case IMAGE_TYPE_BUFFER:
967         return x;
968 
969     case IMAGE_TYPE_1D_ARRAY:
970     case IMAGE_TYPE_2D:
971         return xy;
972 
973     case IMAGE_TYPE_2D_ARRAY:
974     case IMAGE_TYPE_3D:
975     case IMAGE_TYPE_CUBE:
976     case IMAGE_TYPE_CUBE_ARRAY:
977         return xyz;
978 
979     default:
980         DE_FATAL("Unexpected image type");
981         return "";
982     }
983 }
984 
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const uint32_t layersCount,const tcu::TextureFormat & format,const uint32_t mipmapLevel,const uint32_t mipmapMemoryAlignment)985 uint32_t getImageMipLevelSizeInBytes(const VkExtent3D &baseExtents, const uint32_t layersCount,
986                                      const tcu::TextureFormat &format, const uint32_t mipmapLevel,
987                                      const uint32_t mipmapMemoryAlignment)
988 {
989     const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
990 
991     return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format),
992                      mipmapMemoryAlignment);
993 }
994 
getImageSizeInBytes(const VkExtent3D & baseExtents,const uint32_t layersCount,const tcu::TextureFormat & format,const uint32_t mipmapLevelsCount,const uint32_t mipmapMemoryAlignment)995 uint32_t getImageSizeInBytes(const VkExtent3D &baseExtents, const uint32_t layersCount,
996                              const tcu::TextureFormat &format, const uint32_t mipmapLevelsCount,
997                              const uint32_t mipmapMemoryAlignment)
998 {
999     uint32_t imageSizeInBytes = 0;
1000     for (uint32_t mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
1001         imageSizeInBytes +=
1002             getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
1003 
1004     return imageSizeInBytes;
1005 }
1006 
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const uint32_t layersCount,const vk::PlanarFormatDescription & formatDescription,const uint32_t planeNdx,const uint32_t mipmapLevel,const uint32_t mipmapMemoryAlignment)1007 uint32_t getImageMipLevelSizeInBytes(const VkExtent3D &baseExtents, const uint32_t layersCount,
1008                                      const vk::PlanarFormatDescription &formatDescription, const uint32_t planeNdx,
1009                                      const uint32_t mipmapLevel, const uint32_t mipmapMemoryAlignment)
1010 {
1011     return layersCount *
1012            getPlaneSizeInBytes(formatDescription, baseExtents, planeNdx, mipmapLevel, mipmapMemoryAlignment);
1013 }
1014 
getImageSizeInBytes(const VkExtent3D & baseExtents,const uint32_t layersCount,const vk::PlanarFormatDescription & formatDescription,const uint32_t planeNdx,const uint32_t mipmapLevelsCount,const uint32_t mipmapMemoryAlignment)1015 uint32_t getImageSizeInBytes(const VkExtent3D &baseExtents, const uint32_t layersCount,
1016                              const vk::PlanarFormatDescription &formatDescription, const uint32_t planeNdx,
1017                              const uint32_t mipmapLevelsCount, const uint32_t mipmapMemoryAlignment)
1018 {
1019     uint32_t imageSizeInBytes = 0;
1020 
1021     for (uint32_t mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
1022         imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, formatDescription, planeNdx,
1023                                                         mipmapLevel, mipmapMemoryAlignment);
1024 
1025     return imageSizeInBytes;
1026 }
1027 
makeSparseImageMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const uint32_t memoryType,const VkImageSubresource & subresource,const VkOffset3D & offset,const VkExtent3D & extent)1028 VkSparseImageMemoryBind makeSparseImageMemoryBind(const DeviceInterface &vk, const VkDevice device,
1029                                                   const VkDeviceSize allocationSize, const uint32_t memoryType,
1030                                                   const VkImageSubresource &subresource, const VkOffset3D &offset,
1031                                                   const VkExtent3D &extent)
1032 {
1033     const VkMemoryAllocateInfo allocInfo = {
1034         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
1035         nullptr,                                // const void* pNext;
1036         allocationSize,                         // VkDeviceSize allocationSize;
1037         memoryType,                             // uint32_t memoryTypeIndex;
1038     };
1039 
1040     VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
1041     VK_CHECK(vk.allocateMemory(device, &allocInfo, nullptr, &deviceMemory));
1042 
1043     VkSparseImageMemoryBind imageMemoryBind;
1044 
1045     imageMemoryBind.subresource  = subresource;
1046     imageMemoryBind.memory       = deviceMemory;
1047     imageMemoryBind.memoryOffset = 0u;
1048     imageMemoryBind.flags        = 0u;
1049     imageMemoryBind.offset       = offset;
1050     imageMemoryBind.extent       = extent;
1051 
1052     return imageMemoryBind;
1053 }
1054 
makeSparseMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const uint32_t memoryType,const VkDeviceSize resourceOffset,const VkSparseMemoryBindFlags flags)1055 VkSparseMemoryBind makeSparseMemoryBind(const DeviceInterface &vk, const VkDevice device,
1056                                         const VkDeviceSize allocationSize, const uint32_t memoryType,
1057                                         const VkDeviceSize resourceOffset, const VkSparseMemoryBindFlags flags)
1058 {
1059     const VkMemoryAllocateInfo allocInfo = {
1060         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
1061         nullptr,                                // const void* pNext;
1062         allocationSize,                         // VkDeviceSize allocationSize;
1063         memoryType,                             // uint32_t memoryTypeIndex;
1064     };
1065 
1066     VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
1067     VK_CHECK(vk.allocateMemory(device, &allocInfo, nullptr, &deviceMemory));
1068 
1069     VkSparseMemoryBind memoryBind;
1070 
1071     memoryBind.resourceOffset = resourceOffset;
1072     memoryBind.size           = allocationSize;
1073     memoryBind.memory         = deviceMemory;
1074     memoryBind.memoryOffset   = 0u;
1075     memoryBind.flags          = flags;
1076 
1077     return memoryBind;
1078 }
1079 
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)1080 void requireFeatures(const InstanceInterface &vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
1081 {
1082     const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
1083 
1084     if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
1085         throw tcu::NotSupportedError("Tessellation shader not supported");
1086 
1087     if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
1088         throw tcu::NotSupportedError("Geometry shader not supported");
1089 
1090     if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
1091         throw tcu::NotSupportedError("Double-precision floats not supported");
1092 
1093     if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
1094         throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
1095 
1096     if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
1097         throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
1098 
1099     if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) &&
1100         !features.shaderTessellationAndGeometryPointSize)
1101         throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
1102 }
1103 
findMatchingMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkMemoryRequirements & objectMemoryRequirements,const MemoryRequirement & memoryRequirement)1104 uint32_t findMatchingMemoryType(const InstanceInterface &instance, const VkPhysicalDevice physicalDevice,
1105                                 const VkMemoryRequirements &objectMemoryRequirements,
1106                                 const MemoryRequirement &memoryRequirement)
1107 {
1108     const VkPhysicalDeviceMemoryProperties deviceMemoryProperties =
1109         getPhysicalDeviceMemoryProperties(instance, physicalDevice);
1110 
1111     for (uint32_t memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
1112     {
1113         if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
1114             memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
1115         {
1116             return memoryTypeNdx;
1117         }
1118     }
1119 
1120     return NO_MATCH_FOUND;
1121 }
1122 
getHeapIndexForMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const uint32_t memoryType)1123 uint32_t getHeapIndexForMemoryType(const InstanceInterface &instance, const VkPhysicalDevice physicalDevice,
1124                                    const uint32_t memoryType)
1125 {
1126     const VkPhysicalDeviceMemoryProperties deviceMemoryProperties =
1127         getPhysicalDeviceMemoryProperties(instance, physicalDevice);
1128     DE_ASSERT(memoryType < deviceMemoryProperties.memoryTypeCount);
1129     return deviceMemoryProperties.memoryTypes[memoryType].heapIndex;
1130 }
1131 
checkSparseSupportForImageType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType)1132 bool checkSparseSupportForImageType(const InstanceInterface &instance, const VkPhysicalDevice physicalDevice,
1133                                     const ImageType imageType)
1134 {
1135     const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
1136 
1137     if (!deviceFeatures.sparseBinding)
1138         return false;
1139 
1140     switch (mapImageType(imageType))
1141     {
1142     case VK_IMAGE_TYPE_2D:
1143         return deviceFeatures.sparseResidencyImage2D == VK_TRUE;
1144     case VK_IMAGE_TYPE_3D:
1145         return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
1146     default:
1147         DE_FATAL("Unexpected image type");
1148         return false;
1149     }
1150 }
1151 
checkSparseSupportForImageFormat(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkImageCreateInfo & imageInfo)1152 bool checkSparseSupportForImageFormat(const InstanceInterface &instance, const VkPhysicalDevice physicalDevice,
1153                                       const VkImageCreateInfo &imageInfo)
1154 {
1155     const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec =
1156         getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, imageInfo.format, imageInfo.imageType,
1157                                                      imageInfo.samples, imageInfo.usage, imageInfo.tiling);
1158 
1159     return sparseImageFormatPropVec.size() > 0u;
1160 }
1161 
checkImageFormatFeatureSupport(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkFormat format,const VkFormatFeatureFlags featureFlags)1162 bool checkImageFormatFeatureSupport(const InstanceInterface &instance, const VkPhysicalDevice physicalDevice,
1163                                     const VkFormat format, const VkFormatFeatureFlags featureFlags)
1164 {
1165     const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
1166 
1167     return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags;
1168 }
1169 
getSparseAspectRequirementsIndex(const std::vector<VkSparseImageMemoryRequirements> & requirements,const VkImageAspectFlags aspectFlags)1170 uint32_t getSparseAspectRequirementsIndex(const std::vector<VkSparseImageMemoryRequirements> &requirements,
1171                                           const VkImageAspectFlags aspectFlags)
1172 {
1173     for (uint32_t memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx)
1174     {
1175         if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags)
1176             return memoryReqNdx;
1177     }
1178 
1179     return NO_MATCH_FOUND;
1180 }
1181 
getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription & formatInfo,uint32_t planeNdx)1182 vk::VkFormat getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription &formatInfo, uint32_t planeNdx)
1183 {
1184     DE_ASSERT(planeNdx < formatInfo.numPlanes);
1185     vk::VkFormat result = formatInfo.planes[planeNdx].planeCompatibleFormat;
1186 
1187     // redirect result for some of the YCbCr image formats
1188     static const std::pair<vk::VkFormat, vk::VkFormat> ycbcrFormats[] = {
1189         {VK_FORMAT_G8B8G8R8_422_UNORM, VK_FORMAT_R8G8B8A8_UNORM},
1190         {VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM},
1191         {VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM},
1192         {VK_FORMAT_G16B16G16R16_422_UNORM, VK_FORMAT_R16G16B16A16_UNORM},
1193         {VK_FORMAT_B8G8R8G8_422_UNORM, VK_FORMAT_R8G8B8A8_UNORM},
1194         {VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM},
1195         {VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM},
1196         {VK_FORMAT_B16G16R16G16_422_UNORM, VK_FORMAT_R16G16B16A16_UNORM}};
1197     auto it = std::find_if(std::begin(ycbcrFormats), std::end(ycbcrFormats),
1198                            [result](const std::pair<vk::VkFormat, vk::VkFormat> &p) { return p.first == result; });
1199     if (it != std::end(ycbcrFormats))
1200         result = it->second;
1201     return result;
1202 }
1203 
areLsb6BitsDontCare(vk::VkFormat format)1204 bool areLsb6BitsDontCare(vk::VkFormat format)
1205 {
1206     if ((format == vk::VK_FORMAT_R10X6_UNORM_PACK16) || (format == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16) ||
1207         (format == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16) ||
1208         (format == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16) ||
1209         (format == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16) ||
1210         (format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16) ||
1211         (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) ||
1212         (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) ||
1213         (format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16) ||
1214         (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16))
1215     {
1216         return true;
1217     }
1218 
1219     return false;
1220 }
1221 
areLsb4BitsDontCare(vk::VkFormat format)1222 bool areLsb4BitsDontCare(vk::VkFormat format)
1223 {
1224     if ((format == vk::VK_FORMAT_R12X4_UNORM_PACK16) || (format == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16) ||
1225         (format == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16) ||
1226         (format == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16) ||
1227         (format == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16) ||
1228         (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) ||
1229         (format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16) ||
1230         (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) ||
1231         (format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16) ||
1232         (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16))
1233     {
1234         return true;
1235     }
1236 
1237     return false;
1238 }
1239 
1240 } // namespace sparse
1241 } // namespace vkt
1242