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 return de::toLower(std::string(getFormatName(format)).substr(10));
763
764 default:
765 DE_FATAL("Unexpected texture format");
766 return "error";
767 }
768 }
769
getShaderImageCoordinates(const ImageType imageType,const std::string & x,const std::string & xy,const std::string & xyz)770 std::string getShaderImageCoordinates (const ImageType imageType,
771 const std::string& x,
772 const std::string& xy,
773 const std::string& xyz)
774 {
775 switch (imageType)
776 {
777 case IMAGE_TYPE_1D:
778 case IMAGE_TYPE_BUFFER:
779 return x;
780
781 case IMAGE_TYPE_1D_ARRAY:
782 case IMAGE_TYPE_2D:
783 return xy;
784
785 case IMAGE_TYPE_2D_ARRAY:
786 case IMAGE_TYPE_3D:
787 case IMAGE_TYPE_CUBE:
788 case IMAGE_TYPE_CUBE_ARRAY:
789 return xyz;
790
791 default:
792 DE_FATAL("Unexpected image type");
793 return "";
794 }
795 }
796
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)797 deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
798 {
799 const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
800
801 return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment);
802 }
803
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevelsCount,const deUint32 mipmapMemoryAlignment)804 deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
805 {
806 deUint32 imageSizeInBytes = 0;
807 for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
808 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
809
810 return imageSizeInBytes;
811 }
812
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const vk::PlanarFormatDescription & formatDescription,const deUint32 planeNdx,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)813 deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
814 {
815 return layersCount * getPlaneSizeInBytes(formatDescription, baseExtents, planeNdx, mipmapLevel, mipmapMemoryAlignment);
816 }
817
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const vk::PlanarFormatDescription & formatDescription,const deUint32 planeNdx,const deUint32 mipmapLevelsCount,const deUint32 mipmapMemoryAlignment)818 deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
819 {
820 deUint32 imageSizeInBytes = 0;
821
822 for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
823 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, formatDescription, planeNdx, mipmapLevel, mipmapMemoryAlignment);
824
825 return imageSizeInBytes;
826 }
827
makeSparseImageMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkImageSubresource & subresource,const VkOffset3D & offset,const VkExtent3D & extent)828 VkSparseImageMemoryBind makeSparseImageMemoryBind (const DeviceInterface& vk,
829 const VkDevice device,
830 const VkDeviceSize allocationSize,
831 const deUint32 memoryType,
832 const VkImageSubresource& subresource,
833 const VkOffset3D& offset,
834 const VkExtent3D& extent)
835 {
836 const VkMemoryAllocateInfo allocInfo =
837 {
838 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
839 DE_NULL, // const void* pNext;
840 allocationSize, // VkDeviceSize allocationSize;
841 memoryType, // deUint32 memoryTypeIndex;
842 };
843
844 VkDeviceMemory deviceMemory = 0;
845 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
846
847 VkSparseImageMemoryBind imageMemoryBind;
848
849 imageMemoryBind.subresource = subresource;
850 imageMemoryBind.memory = deviceMemory;
851 imageMemoryBind.memoryOffset = 0u;
852 imageMemoryBind.flags = 0u;
853 imageMemoryBind.offset = offset;
854 imageMemoryBind.extent = extent;
855
856 return imageMemoryBind;
857 }
858
makeSparseMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkDeviceSize resourceOffset,const VkSparseMemoryBindFlags flags)859 VkSparseMemoryBind makeSparseMemoryBind (const DeviceInterface& vk,
860 const VkDevice device,
861 const VkDeviceSize allocationSize,
862 const deUint32 memoryType,
863 const VkDeviceSize resourceOffset,
864 const VkSparseMemoryBindFlags flags)
865 {
866 const VkMemoryAllocateInfo allocInfo =
867 {
868 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
869 DE_NULL, // const void* pNext;
870 allocationSize, // VkDeviceSize allocationSize;
871 memoryType, // deUint32 memoryTypeIndex;
872 };
873
874 VkDeviceMemory deviceMemory = 0;
875 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
876
877 VkSparseMemoryBind memoryBind;
878
879 memoryBind.resourceOffset = resourceOffset;
880 memoryBind.size = allocationSize;
881 memoryBind.memory = deviceMemory;
882 memoryBind.memoryOffset = 0u;
883 memoryBind.flags = flags;
884
885 return memoryBind;
886 }
887
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)888 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
889 {
890 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
891
892 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
893 throw tcu::NotSupportedError("Tessellation shader not supported");
894
895 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
896 throw tcu::NotSupportedError("Geometry shader not supported");
897
898 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
899 throw tcu::NotSupportedError("Double-precision floats not supported");
900
901 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
902 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
903
904 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
905 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
906
907 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
908 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
909 }
910
findMatchingMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkMemoryRequirements & objectMemoryRequirements,const MemoryRequirement & memoryRequirement)911 deUint32 findMatchingMemoryType (const InstanceInterface& instance,
912 const VkPhysicalDevice physicalDevice,
913 const VkMemoryRequirements& objectMemoryRequirements,
914 const MemoryRequirement& memoryRequirement)
915 {
916 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
917
918 for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
919 {
920 if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
921 memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
922 {
923 return memoryTypeNdx;
924 }
925 }
926
927 return NO_MATCH_FOUND;
928 }
929
getHeapIndexForMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const deUint32 memoryType)930 deUint32 getHeapIndexForMemoryType (const InstanceInterface& instance,
931 const VkPhysicalDevice physicalDevice,
932 const deUint32 memoryType)
933 {
934 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
935 DE_ASSERT(memoryType < deviceMemoryProperties.memoryTypeCount);
936 return deviceMemoryProperties.memoryTypes[memoryType].heapIndex;
937 }
938
checkSparseSupportForImageType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType)939 bool checkSparseSupportForImageType (const InstanceInterface& instance,
940 const VkPhysicalDevice physicalDevice,
941 const ImageType imageType)
942 {
943 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
944
945 if (!deviceFeatures.sparseBinding)
946 return false;
947
948 switch (mapImageType(imageType))
949 {
950 case VK_IMAGE_TYPE_2D:
951 return deviceFeatures.sparseResidencyImage2D == VK_TRUE;
952 case VK_IMAGE_TYPE_3D:
953 return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
954 default:
955 DE_FATAL("Unexpected image type");
956 return false;
957 }
958 }
959
checkSparseSupportForImageFormat(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkImageCreateInfo & imageInfo)960 bool checkSparseSupportForImageFormat (const InstanceInterface& instance,
961 const VkPhysicalDevice physicalDevice,
962 const VkImageCreateInfo& imageInfo)
963 {
964 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
965 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
966
967 return sparseImageFormatPropVec.size() > 0u;
968 }
969
checkImageFormatFeatureSupport(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkFormat format,const VkFormatFeatureFlags featureFlags)970 bool checkImageFormatFeatureSupport (const InstanceInterface& instance,
971 const VkPhysicalDevice physicalDevice,
972 const VkFormat format,
973 const VkFormatFeatureFlags featureFlags)
974 {
975 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
976
977 return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags;
978 }
979
getSparseAspectRequirementsIndex(const std::vector<VkSparseImageMemoryRequirements> & requirements,const VkImageAspectFlags aspectFlags)980 deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>& requirements,
981 const VkImageAspectFlags aspectFlags)
982 {
983 for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx)
984 {
985 if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags)
986 return memoryReqNdx;
987 }
988
989 return NO_MATCH_FOUND;
990 }
991
getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription & formatInfo,deUint32 planeNdx)992 vk::VkFormat getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription& formatInfo, deUint32 planeNdx)
993 {
994 DE_ASSERT(planeNdx < formatInfo.numPlanes);
995 vk::VkFormat result = formatInfo.planes[planeNdx].planeCompatibleFormat;
996
997 // redirect result for some of the YCbCr image formats
998 static const std::pair<vk::VkFormat, vk::VkFormat> ycbcrFormats[] =
999 {
1000 { VK_FORMAT_G8B8G8R8_422_UNORM, VK_FORMAT_R8G8B8A8_UNORM },
1001 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM },
1002 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM },
1003 { VK_FORMAT_G16B16G16R16_422_UNORM, VK_FORMAT_R16G16B16A16_UNORM },
1004 { VK_FORMAT_B8G8R8G8_422_UNORM, VK_FORMAT_R8G8B8A8_UNORM },
1005 { VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM },
1006 { VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM },
1007 { VK_FORMAT_B16G16R16G16_422_UNORM, VK_FORMAT_R16G16B16A16_UNORM }
1008 };
1009 auto it = std::find_if(std::begin(ycbcrFormats), std::end(ycbcrFormats), [result](const std::pair<vk::VkFormat, vk::VkFormat>& p) { return p.first == result; });
1010 if (it != std::end(ycbcrFormats))
1011 result = it->second;
1012 return result;
1013 }
1014
areLsb6BitsDontCare(vk::VkFormat format)1015 bool areLsb6BitsDontCare(vk::VkFormat format)
1016 {
1017 if ((format == vk::VK_FORMAT_R10X6_UNORM_PACK16) ||
1018 (format == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16) ||
1019 (format == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16) ||
1020 (format == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16) ||
1021 (format == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16) ||
1022 (format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16) ||
1023 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) ||
1024 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) ||
1025 (format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16) ||
1026 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16))
1027 {
1028 return true;
1029 }
1030
1031 return false;
1032 }
1033
areLsb4BitsDontCare(vk::VkFormat format)1034 bool areLsb4BitsDontCare(vk::VkFormat format)
1035 {
1036 if ((format == vk::VK_FORMAT_R12X4_UNORM_PACK16) ||
1037 (format == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16) ||
1038 (format == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16) ||
1039 (format == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16) ||
1040 (format == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16) ||
1041 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) ||
1042 (format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16) ||
1043 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) ||
1044 (format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16) ||
1045 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16))
1046 {
1047 return true;
1048 }
1049
1050 return false;
1051 }
1052
1053 } // sparse
1054 } // vkt
1055