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 =
55 {
56 { VK_FORMAT_R64_SINT }, { VK_FORMAT_R32_SINT }, { VK_FORMAT_R16_SINT }, { VK_FORMAT_R8_SINT },
57 { VK_FORMAT_R64_UINT }, { VK_FORMAT_R32_UINT }, { 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 }, { VK_FORMAT_R8G8_SINT },
62 { VK_FORMAT_R32G32_UINT }, { VK_FORMAT_R16G16_UINT }, { VK_FORMAT_R8G8_UINT },
63 { VK_FORMAT_R16G16_UNORM }, { VK_FORMAT_R8G8_UNORM },
64 { VK_FORMAT_R16G16_SNORM }, { VK_FORMAT_R8G8_SNORM },
65 { VK_FORMAT_R32G32B32A32_SINT }, { VK_FORMAT_R16G16B16A16_SINT }, { VK_FORMAT_R8G8B8A8_SINT },
66 { VK_FORMAT_R32G32B32A32_UINT }, { VK_FORMAT_R16G16B16A16_UINT }, { VK_FORMAT_R8G8B8A8_UINT },
67 { VK_FORMAT_R16G16B16A16_UNORM }, { VK_FORMAT_R8G8B8A8_UNORM },
68 { VK_FORMAT_R16G16B16A16_SNORM }, { VK_FORMAT_R8G8B8A8_SNORM }
69 };
70
71 if (imageType == IMAGE_TYPE_2D || imageType == IMAGE_TYPE_2D_ARRAY)
72 {
73 std::vector<TestFormat> ycbcrFormats =
74 {
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 deUint32 mipLevel)120 tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel)
121 {
122 const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
123 const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
124 const deUint32 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 deUint32 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 deUint32 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 deUint32 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 deUint32 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, const ImageType imageType, const tcu::UVec3& imageSize)
264 {
265 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
266
267 switch (imageType)
268 {
269 case IMAGE_TYPE_1D:
270 return imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
271 case IMAGE_TYPE_1D_ARRAY:
272 return imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
273 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
274 case IMAGE_TYPE_2D:
275 return imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
276 imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
277 case IMAGE_TYPE_2D_ARRAY:
278 return imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
279 imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
280 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
281 case IMAGE_TYPE_CUBE:
282 return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
283 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
284 case IMAGE_TYPE_CUBE_ARRAY:
285 return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
286 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
287 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
288 case IMAGE_TYPE_3D:
289 return imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
290 imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
291 imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
292 case IMAGE_TYPE_BUFFER:
293 return true;
294 default:
295 DE_FATAL("Unknown image type");
296 return false;
297 }
298 }
299
makeBufferImageCopy(const VkExtent3D extent,const deUint32 layerCount,const deUint32 mipmapLevel,const VkDeviceSize bufferOffset)300 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent,
301 const deUint32 layerCount,
302 const deUint32 mipmapLevel,
303 const VkDeviceSize bufferOffset)
304 {
305 const VkBufferImageCopy copyParams =
306 {
307 bufferOffset, // VkDeviceSize bufferOffset;
308 0u, // deUint32 bufferRowLength;
309 0u, // deUint32 bufferImageHeight;
310 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipmapLevel, 0u, layerCount), // VkImageSubresourceLayers imageSubresource;
311 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
312 extent, // VkExtent3D imageExtent;
313 };
314 return copyParams;
315 }
316
submitCommands(const DeviceInterface & vk,const VkQueue queue,const VkCommandBuffer commandBuffer,const deUint32 waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,const VkPipelineStageFlags * pWaitDstStageMask,const deUint32 signalSemaphoreCount,const VkSemaphore * pSignalSemaphores)317 void submitCommands (const DeviceInterface& vk,
318 const VkQueue queue,
319 const VkCommandBuffer commandBuffer,
320 const deUint32 waitSemaphoreCount,
321 const VkSemaphore* pWaitSemaphores,
322 const VkPipelineStageFlags* pWaitDstStageMask,
323 const deUint32 signalSemaphoreCount,
324 const VkSemaphore* pSignalSemaphores)
325 {
326 const VkSubmitInfo submitInfo =
327 {
328 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
329 DE_NULL, // const void* pNext;
330 waitSemaphoreCount, // deUint32 waitSemaphoreCount;
331 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores;
332 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask;
333 1u, // deUint32 commandBufferCount;
334 &commandBuffer, // const VkCommandBuffer* pCommandBuffers;
335 signalSemaphoreCount, // deUint32 signalSemaphoreCount;
336 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores;
337 };
338
339 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
340 }
341
submitCommandsAndWait(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,const VkCommandBuffer commandBuffer,const deUint32 waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,const VkPipelineStageFlags * pWaitDstStageMask,const deUint32 signalSemaphoreCount,const VkSemaphore * pSignalSemaphores,const bool useDeviceGroups,const deUint32 physicalDeviceID)342 void submitCommandsAndWait (const DeviceInterface& vk,
343 const VkDevice device,
344 const VkQueue queue,
345 const VkCommandBuffer commandBuffer,
346 const deUint32 waitSemaphoreCount,
347 const VkSemaphore* pWaitSemaphores,
348 const VkPipelineStageFlags* pWaitDstStageMask,
349 const deUint32 signalSemaphoreCount,
350 const VkSemaphore* pSignalSemaphores,
351 const bool useDeviceGroups,
352 const deUint32 physicalDeviceID)
353 {
354 const VkFenceCreateInfo fenceParams =
355 {
356 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
357 DE_NULL, // const void* pNext;
358 0u, // VkFenceCreateFlags flags;
359 };
360 const Unique<VkFence> fence(createFence (vk, device, &fenceParams));
361
362 const deUint32 deviceMask = 1 << physicalDeviceID;
363 std::vector<deUint32> deviceIndices (waitSemaphoreCount, physicalDeviceID);
364 VkDeviceGroupSubmitInfo deviceGroupSubmitInfo =
365 {
366 VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO, //VkStructureType sType
367 DE_NULL, // const void* pNext
368 waitSemaphoreCount, // uint32_t waitSemaphoreCount
369 deviceIndices.size() ? &deviceIndices[0] : DE_NULL, // const uint32_t* pWaitSemaphoreDeviceIndices
370 1u, // uint32_t commandBufferCount
371 &deviceMask, // const uint32_t* pCommandBufferDeviceMasks
372 0u, // uint32_t signalSemaphoreCount
373 DE_NULL, // const uint32_t* pSignalSemaphoreDeviceIndices
374 };
375 const VkSubmitInfo submitInfo =
376 {
377 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
378 useDeviceGroups ? &deviceGroupSubmitInfo : DE_NULL, // const void* pNext;
379 waitSemaphoreCount, // deUint32 waitSemaphoreCount;
380 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores;
381 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask;
382 1u, // deUint32 commandBufferCount;
383 &commandBuffer, // const VkCommandBuffer* pCommandBuffers;
384 signalSemaphoreCount, // deUint32 signalSemaphoreCount;
385 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores;
386 };
387
388 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
389 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
390 }
391
mapImageType(const ImageType imageType)392 VkImageType mapImageType (const ImageType imageType)
393 {
394 switch (imageType)
395 {
396 case IMAGE_TYPE_1D:
397 case IMAGE_TYPE_1D_ARRAY:
398 case IMAGE_TYPE_BUFFER:
399 return VK_IMAGE_TYPE_1D;
400
401 case IMAGE_TYPE_2D:
402 case IMAGE_TYPE_2D_ARRAY:
403 case IMAGE_TYPE_CUBE:
404 case IMAGE_TYPE_CUBE_ARRAY:
405 return VK_IMAGE_TYPE_2D;
406
407 case IMAGE_TYPE_3D:
408 return VK_IMAGE_TYPE_3D;
409
410 default:
411 DE_FATAL("Unexpected image type");
412 return VK_IMAGE_TYPE_LAST;
413 }
414 }
415
mapImageViewType(const ImageType imageType)416 VkImageViewType mapImageViewType (const ImageType imageType)
417 {
418 switch (imageType)
419 {
420 case IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D;
421 case IMAGE_TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
422 case IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
423 case IMAGE_TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
424 case IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
425 case IMAGE_TYPE_CUBE: return VK_IMAGE_VIEW_TYPE_CUBE;
426 case IMAGE_TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
427
428 default:
429 DE_FATAL("Unexpected image type");
430 return VK_IMAGE_VIEW_TYPE_LAST;
431 }
432 }
433
getImageTypeName(const ImageType imageType)434 std::string getImageTypeName (const ImageType imageType)
435 {
436 switch (imageType)
437 {
438 case IMAGE_TYPE_1D: return "1d";
439 case IMAGE_TYPE_1D_ARRAY: return "1d_array";
440 case IMAGE_TYPE_2D: return "2d";
441 case IMAGE_TYPE_2D_ARRAY: return "2d_array";
442 case IMAGE_TYPE_3D: return "3d";
443 case IMAGE_TYPE_CUBE: return "cube";
444 case IMAGE_TYPE_CUBE_ARRAY: return "cube_array";
445 case IMAGE_TYPE_BUFFER: 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 ? "u" :
456 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : "";
457
458 std::string imageTypePart;
459 switch (imageType)
460 {
461 case IMAGE_TYPE_1D: imageTypePart = "1D"; break;
462 case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break;
463 case IMAGE_TYPE_2D: imageTypePart = "2D"; break;
464 case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break;
465 case IMAGE_TYPE_3D: imageTypePart = "3D"; break;
466 case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break;
467 case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break;
468 case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break;
469
470 default:
471 DE_FATAL("Unexpected image type");
472 }
473
474 return formatPart + "image" + imageTypePart;
475 }
476
getShaderImageType(const vk::PlanarFormatDescription & description,const ImageType imageType)477 std::string getShaderImageType (const vk::PlanarFormatDescription& description, const ImageType imageType)
478 {
479 std::string formatPart;
480 std::string imageTypePart;
481
482 // all PlanarFormatDescription types have at least one channel ( 0 ) and all channel types are the same :
483 switch (description.channels[0].type)
484 {
485 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
486 formatPart = "i";
487 break;
488 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
489 formatPart = "u";
490 break;
491 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
492 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
493 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
494 break;
495
496 default:
497 DE_FATAL("Unexpected channel type");
498 }
499
500 if (formatIsR64(description.planes[0].planeCompatibleFormat))
501 formatPart += "64";
502
503 switch (imageType)
504 {
505 case IMAGE_TYPE_1D: imageTypePart = "1D"; break;
506 case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break;
507 case IMAGE_TYPE_2D: imageTypePart = "2D"; break;
508 case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break;
509 case IMAGE_TYPE_3D: imageTypePart = "3D"; break;
510 case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break;
511 case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break;
512 case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break;
513
514 default:
515 DE_FATAL("Unexpected image type");
516 }
517
518 return formatPart + "image" + imageTypePart;
519 }
520
getShaderImageDataType(const tcu::TextureFormat & format)521 std::string getShaderImageDataType(const tcu::TextureFormat& format)
522 {
523 switch (tcu::getTextureChannelClass(format.type))
524 {
525 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
526 return "uvec4";
527 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
528 return "ivec4";
529 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
530 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
531 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
532 return "vec4";
533 default:
534 DE_FATAL("Unexpected channel type");
535 return "";
536 }
537 }
538
getShaderImageDataType(const vk::PlanarFormatDescription & description)539 std::string getShaderImageDataType (const vk::PlanarFormatDescription& description)
540 {
541 switch (description.channels[0].type)
542 {
543 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
544 return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "u64vec4" : "uvec4");
545 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
546 return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "i64vec4" : "ivec4");
547 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
548 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
549 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
550 return "vec4";
551 default:
552 DE_FATAL("Unexpected channel type");
553 return "";
554 }
555 }
556
getShaderImageFormatQualifier(const tcu::TextureFormat & format)557 std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
558 {
559 const char* orderPart;
560 const char* typePart;
561
562 switch (format.order)
563 {
564 case tcu::TextureFormat::R: orderPart = "r"; break;
565 case tcu::TextureFormat::RG: orderPart = "rg"; break;
566 case tcu::TextureFormat::RGB: orderPart = "rgb"; break;
567 case tcu::TextureFormat::RGBA: orderPart = "rgba"; break;
568
569 default:
570 DE_FATAL("Unexpected channel order");
571 orderPart = DE_NULL;
572 }
573
574 switch (format.type)
575 {
576 case tcu::TextureFormat::FLOAT: typePart = "32f"; break;
577 case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break;
578
579 case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break;
580 case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break;
581 case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break;
582
583 case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break;
584 case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break;
585 case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break;
586
587 case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break;
588 case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break;
589
590 case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break;
591 case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break;
592
593 default:
594 DE_FATAL("Unexpected channel type");
595 typePart = DE_NULL;
596 }
597
598 return std::string() + orderPart + typePart;
599 }
600
getShaderImageFormatQualifier(VkFormat format)601 std::string getShaderImageFormatQualifier (VkFormat format)
602 {
603 switch (format)
604 {
605 case VK_FORMAT_R8_SINT: return "r8i";
606 case VK_FORMAT_R16_SINT: return "r16i";
607 case VK_FORMAT_R32_SINT: return "r32i";
608 case VK_FORMAT_R64_SINT: return "r64i";
609 case VK_FORMAT_R8_UINT: return "r8ui";
610 case VK_FORMAT_R16_UINT: return "r16ui";
611 case VK_FORMAT_R32_UINT: return "r32ui";
612 case VK_FORMAT_R64_UINT: return "r64ui";
613 case VK_FORMAT_R8_SNORM: return "r8_snorm";
614 case VK_FORMAT_R16_SNORM: return "r16_snorm";
615 case VK_FORMAT_R8_UNORM: return "r8";
616 case VK_FORMAT_R16_UNORM: return "r16";
617
618 case VK_FORMAT_R8G8_SINT: return "rg8i";
619 case VK_FORMAT_R16G16_SINT: return "rg16i";
620 case VK_FORMAT_R32G32_SINT: return "rg32i";
621 case VK_FORMAT_R8G8_UINT: return "rg8ui";
622 case VK_FORMAT_R16G16_UINT: return "rg16ui";
623 case VK_FORMAT_R32G32_UINT: return "rg32ui";
624 case VK_FORMAT_R8G8_SNORM: return "rg8_snorm";
625 case VK_FORMAT_R16G16_SNORM: return "rg16_snorm";
626 case VK_FORMAT_R8G8_UNORM: return "rg8";
627 case VK_FORMAT_R16G16_UNORM: return "rg16";
628
629 case VK_FORMAT_R8G8B8A8_SINT: return "rgba8i";
630 case VK_FORMAT_R16G16B16A16_SINT: return "rgba16i";
631 case VK_FORMAT_R32G32B32A32_SINT: return "rgba32i";
632 case VK_FORMAT_R8G8B8A8_UINT: return "rgba8ui";
633 case VK_FORMAT_R16G16B16A16_UINT: return "rgba16ui";
634 case VK_FORMAT_R32G32B32A32_UINT: return "rgba32ui";
635 case VK_FORMAT_R8G8B8A8_SNORM: return "rgba8_snorm";
636 case VK_FORMAT_R16G16B16A16_SNORM: return "rgba16_snorm";
637 case VK_FORMAT_R8G8B8A8_UNORM: return "rgba8";
638 case VK_FORMAT_R16G16B16A16_UNORM: return "rgba16";
639
640 case VK_FORMAT_G8B8G8R8_422_UNORM: return "rgba8";
641 case VK_FORMAT_B8G8R8G8_422_UNORM: return "rgba8";
642 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: return "rgba8";
643 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: return "rgba8";
644 case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: return "rgba8";
645 case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: return "rgba8";
646 case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: return "rgba8";
647 case VK_FORMAT_R10X6_UNORM_PACK16: return "r16";
648 case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: return "rg16";
649 case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: return "rgba16";
650 case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: return "rgba16";
651 case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: return "rgba16";
652 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: return "rgba16";
653 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: return "rgba16";
654 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: return "rgba16";
655 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: return "rgba16";
656 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: return "rgba16";
657 case VK_FORMAT_R12X4_UNORM_PACK16: return "r16";
658 case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: return "rg16";
659 case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: return "rgba16";
660 case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: return "rgba16";
661 case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: return "rgba16";
662 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: return "rgba16";
663 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: return "rgba16";
664 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: return "rgba16";
665 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: return "rgba16";
666 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: return "rgba16";
667 case VK_FORMAT_G16B16G16R16_422_UNORM: return "rgba16";
668 case VK_FORMAT_B16G16R16G16_422_UNORM: return "rgba16";
669 case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: return "rgba16";
670 case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: return "rgba16";
671 case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: return "rgba16";
672 case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: return "rgba16";
673 case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: return "rgba16";
674 case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT: return "rgba8";
675 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:return "rgba16";
676 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:return "rgba16";
677 case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT: return "rgba16";
678
679 default:
680 DE_FATAL("Unexpected texture format");
681 return "error";
682 }
683 }
684
getImageFormatID(VkFormat format)685 std::string getImageFormatID (VkFormat format)
686 {
687 switch (format)
688 {
689 case VK_FORMAT_R8_SINT: return "r8i";
690 case VK_FORMAT_R16_SINT: return "r16i";
691 case VK_FORMAT_R32_SINT: return "r32i";
692 case VK_FORMAT_R64_SINT: return "r64i";
693 case VK_FORMAT_R8_UINT: return "r8ui";
694 case VK_FORMAT_R16_UINT: return "r16ui";
695 case VK_FORMAT_R32_UINT: return "r32ui";
696 case VK_FORMAT_R64_UINT: return "r64ui";
697 case VK_FORMAT_R8_SNORM: return "r8_snorm";
698 case VK_FORMAT_R16_SNORM: return "r16_snorm";
699 case VK_FORMAT_R8_UNORM: return "r8";
700 case VK_FORMAT_R16_UNORM: return "r16";
701
702 case VK_FORMAT_R8G8_SINT: return "rg8i";
703 case VK_FORMAT_R16G16_SINT: return "rg16i";
704 case VK_FORMAT_R32G32_SINT: return "rg32i";
705 case VK_FORMAT_R8G8_UINT: return "rg8ui";
706 case VK_FORMAT_R16G16_UINT: return "rg16ui";
707 case VK_FORMAT_R32G32_UINT: return "rg32ui";
708 case VK_FORMAT_R8G8_SNORM: return "rg8_snorm";
709 case VK_FORMAT_R16G16_SNORM: return "rg16_snorm";
710 case VK_FORMAT_R8G8_UNORM: return "rg8";
711 case VK_FORMAT_R16G16_UNORM: return "rg16";
712
713 case VK_FORMAT_R8G8B8A8_SINT: return "rgba8i";
714 case VK_FORMAT_R16G16B16A16_SINT: return "rgba16i";
715 case VK_FORMAT_R32G32B32A32_SINT: return "rgba32i";
716 case VK_FORMAT_R8G8B8A8_UINT: return "rgba8ui";
717 case VK_FORMAT_R16G16B16A16_UINT: return "rgba16ui";
718 case VK_FORMAT_R32G32B32A32_UINT: return "rgba32ui";
719 case VK_FORMAT_R8G8B8A8_SNORM: return "rgba8_snorm";
720 case VK_FORMAT_R16G16B16A16_SNORM: return "rgba16_snorm";
721 case VK_FORMAT_R8G8B8A8_UNORM: return "rgba8";
722 case VK_FORMAT_R16G16B16A16_UNORM: return "rgba16";
723
724 case VK_FORMAT_G8B8G8R8_422_UNORM:
725 case VK_FORMAT_B8G8R8G8_422_UNORM:
726 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
727 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
728 case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
729 case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
730 case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
731 case VK_FORMAT_R10X6_UNORM_PACK16:
732 case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
733 case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
734 case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
735 case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
736 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
737 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
738 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
739 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
740 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
741 case VK_FORMAT_R12X4_UNORM_PACK16:
742 case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
743 case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
744 case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
745 case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
746 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
747 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
748 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
749 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
750 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
751 case VK_FORMAT_G16B16G16R16_422_UNORM:
752 case VK_FORMAT_B16G16R16G16_422_UNORM:
753 case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
754 case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
755 case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
756 case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
757 case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
758 case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
759 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
760 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
761 case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
762 #ifndef CTS_USES_VULKANSC
763 case VK_FORMAT_A8_UNORM_KHR:
764 #endif // CTS_USES_VULKANSC
765 return de::toLower(std::string(getFormatName(format)).substr(10));
766
767 default:
768 DE_FATAL("Unexpected texture format");
769 return "error";
770 }
771 }
772
getShaderImageCoordinates(const ImageType imageType,const std::string & x,const std::string & xy,const std::string & xyz)773 std::string getShaderImageCoordinates (const ImageType imageType,
774 const std::string& x,
775 const std::string& xy,
776 const std::string& xyz)
777 {
778 switch (imageType)
779 {
780 case IMAGE_TYPE_1D:
781 case IMAGE_TYPE_BUFFER:
782 return x;
783
784 case IMAGE_TYPE_1D_ARRAY:
785 case IMAGE_TYPE_2D:
786 return xy;
787
788 case IMAGE_TYPE_2D_ARRAY:
789 case IMAGE_TYPE_3D:
790 case IMAGE_TYPE_CUBE:
791 case IMAGE_TYPE_CUBE_ARRAY:
792 return xyz;
793
794 default:
795 DE_FATAL("Unexpected image type");
796 return "";
797 }
798 }
799
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)800 deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
801 {
802 const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
803
804 return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment);
805 }
806
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevelsCount,const deUint32 mipmapMemoryAlignment)807 deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
808 {
809 deUint32 imageSizeInBytes = 0;
810 for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
811 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
812
813 return imageSizeInBytes;
814 }
815
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const vk::PlanarFormatDescription & formatDescription,const deUint32 planeNdx,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)816 deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
817 {
818 return layersCount * getPlaneSizeInBytes(formatDescription, baseExtents, planeNdx, mipmapLevel, mipmapMemoryAlignment);
819 }
820
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const vk::PlanarFormatDescription & formatDescription,const deUint32 planeNdx,const deUint32 mipmapLevelsCount,const deUint32 mipmapMemoryAlignment)821 deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
822 {
823 deUint32 imageSizeInBytes = 0;
824
825 for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
826 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, formatDescription, planeNdx, mipmapLevel, mipmapMemoryAlignment);
827
828 return imageSizeInBytes;
829 }
830
makeSparseImageMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkImageSubresource & subresource,const VkOffset3D & offset,const VkExtent3D & extent)831 VkSparseImageMemoryBind makeSparseImageMemoryBind (const DeviceInterface& vk,
832 const VkDevice device,
833 const VkDeviceSize allocationSize,
834 const deUint32 memoryType,
835 const VkImageSubresource& subresource,
836 const VkOffset3D& offset,
837 const VkExtent3D& extent)
838 {
839 const VkMemoryAllocateInfo allocInfo =
840 {
841 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
842 DE_NULL, // const void* pNext;
843 allocationSize, // VkDeviceSize allocationSize;
844 memoryType, // deUint32 memoryTypeIndex;
845 };
846
847 VkDeviceMemory deviceMemory = 0;
848 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
849
850 VkSparseImageMemoryBind imageMemoryBind;
851
852 imageMemoryBind.subresource = subresource;
853 imageMemoryBind.memory = deviceMemory;
854 imageMemoryBind.memoryOffset = 0u;
855 imageMemoryBind.flags = 0u;
856 imageMemoryBind.offset = offset;
857 imageMemoryBind.extent = extent;
858
859 return imageMemoryBind;
860 }
861
makeSparseMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkDeviceSize resourceOffset,const VkSparseMemoryBindFlags flags)862 VkSparseMemoryBind makeSparseMemoryBind (const DeviceInterface& vk,
863 const VkDevice device,
864 const VkDeviceSize allocationSize,
865 const deUint32 memoryType,
866 const VkDeviceSize resourceOffset,
867 const VkSparseMemoryBindFlags flags)
868 {
869 const VkMemoryAllocateInfo allocInfo =
870 {
871 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
872 DE_NULL, // const void* pNext;
873 allocationSize, // VkDeviceSize allocationSize;
874 memoryType, // deUint32 memoryTypeIndex;
875 };
876
877 VkDeviceMemory deviceMemory = 0;
878 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
879
880 VkSparseMemoryBind memoryBind;
881
882 memoryBind.resourceOffset = resourceOffset;
883 memoryBind.size = allocationSize;
884 memoryBind.memory = deviceMemory;
885 memoryBind.memoryOffset = 0u;
886 memoryBind.flags = flags;
887
888 return memoryBind;
889 }
890
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)891 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
892 {
893 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
894
895 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
896 throw tcu::NotSupportedError("Tessellation shader not supported");
897
898 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
899 throw tcu::NotSupportedError("Geometry shader not supported");
900
901 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
902 throw tcu::NotSupportedError("Double-precision floats not supported");
903
904 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
905 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
906
907 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
908 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
909
910 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
911 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
912 }
913
findMatchingMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkMemoryRequirements & objectMemoryRequirements,const MemoryRequirement & memoryRequirement)914 deUint32 findMatchingMemoryType (const InstanceInterface& instance,
915 const VkPhysicalDevice physicalDevice,
916 const VkMemoryRequirements& objectMemoryRequirements,
917 const MemoryRequirement& memoryRequirement)
918 {
919 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
920
921 for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
922 {
923 if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
924 memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
925 {
926 return memoryTypeNdx;
927 }
928 }
929
930 return NO_MATCH_FOUND;
931 }
932
getHeapIndexForMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const deUint32 memoryType)933 deUint32 getHeapIndexForMemoryType (const InstanceInterface& instance,
934 const VkPhysicalDevice physicalDevice,
935 const deUint32 memoryType)
936 {
937 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
938 DE_ASSERT(memoryType < deviceMemoryProperties.memoryTypeCount);
939 return deviceMemoryProperties.memoryTypes[memoryType].heapIndex;
940 }
941
checkSparseSupportForImageType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType)942 bool checkSparseSupportForImageType (const InstanceInterface& instance,
943 const VkPhysicalDevice physicalDevice,
944 const ImageType imageType)
945 {
946 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
947
948 if (!deviceFeatures.sparseBinding)
949 return false;
950
951 switch (mapImageType(imageType))
952 {
953 case VK_IMAGE_TYPE_2D:
954 return deviceFeatures.sparseResidencyImage2D == VK_TRUE;
955 case VK_IMAGE_TYPE_3D:
956 return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
957 default:
958 DE_FATAL("Unexpected image type");
959 return false;
960 }
961 }
962
checkSparseSupportForImageFormat(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkImageCreateInfo & imageInfo)963 bool checkSparseSupportForImageFormat (const InstanceInterface& instance,
964 const VkPhysicalDevice physicalDevice,
965 const VkImageCreateInfo& imageInfo)
966 {
967 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
968 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
969
970 return sparseImageFormatPropVec.size() > 0u;
971 }
972
checkImageFormatFeatureSupport(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkFormat format,const VkFormatFeatureFlags featureFlags)973 bool checkImageFormatFeatureSupport (const InstanceInterface& instance,
974 const VkPhysicalDevice physicalDevice,
975 const VkFormat format,
976 const VkFormatFeatureFlags featureFlags)
977 {
978 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
979
980 return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags;
981 }
982
getSparseAspectRequirementsIndex(const std::vector<VkSparseImageMemoryRequirements> & requirements,const VkImageAspectFlags aspectFlags)983 deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>& requirements,
984 const VkImageAspectFlags aspectFlags)
985 {
986 for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx)
987 {
988 if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags)
989 return memoryReqNdx;
990 }
991
992 return NO_MATCH_FOUND;
993 }
994
getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription & formatInfo,deUint32 planeNdx)995 vk::VkFormat getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription& formatInfo, deUint32 planeNdx)
996 {
997 DE_ASSERT(planeNdx < formatInfo.numPlanes);
998 vk::VkFormat result = formatInfo.planes[planeNdx].planeCompatibleFormat;
999
1000 // redirect result for some of the YCbCr image formats
1001 static const std::pair<vk::VkFormat, vk::VkFormat> ycbcrFormats[] =
1002 {
1003 { VK_FORMAT_G8B8G8R8_422_UNORM, VK_FORMAT_R8G8B8A8_UNORM },
1004 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM },
1005 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM },
1006 { VK_FORMAT_G16B16G16R16_422_UNORM, VK_FORMAT_R16G16B16A16_UNORM },
1007 { VK_FORMAT_B8G8R8G8_422_UNORM, VK_FORMAT_R8G8B8A8_UNORM },
1008 { VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM },
1009 { VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM },
1010 { VK_FORMAT_B16G16R16G16_422_UNORM, VK_FORMAT_R16G16B16A16_UNORM }
1011 };
1012 auto it = std::find_if(std::begin(ycbcrFormats), std::end(ycbcrFormats), [result](const std::pair<vk::VkFormat, vk::VkFormat>& p) { return p.first == result; });
1013 if (it != std::end(ycbcrFormats))
1014 result = it->second;
1015 return result;
1016 }
1017
areLsb6BitsDontCare(vk::VkFormat format)1018 bool areLsb6BitsDontCare(vk::VkFormat format)
1019 {
1020 if ((format == vk::VK_FORMAT_R10X6_UNORM_PACK16) ||
1021 (format == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16) ||
1022 (format == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16) ||
1023 (format == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16) ||
1024 (format == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16) ||
1025 (format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16) ||
1026 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) ||
1027 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) ||
1028 (format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16) ||
1029 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16))
1030 {
1031 return true;
1032 }
1033
1034 return false;
1035 }
1036
areLsb4BitsDontCare(vk::VkFormat format)1037 bool areLsb4BitsDontCare(vk::VkFormat format)
1038 {
1039 if ((format == vk::VK_FORMAT_R12X4_UNORM_PACK16) ||
1040 (format == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16) ||
1041 (format == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16) ||
1042 (format == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16) ||
1043 (format == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16) ||
1044 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) ||
1045 (format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16) ||
1046 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) ||
1047 (format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16) ||
1048 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16))
1049 {
1050 return true;
1051 }
1052
1053 return false;
1054 }
1055
1056 } // sparse
1057 } // vkt
1058