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