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