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
getTestFormats(const ImageType & imageType)40 std::vector<TestFormat> getTestFormats (const ImageType& imageType)
41 {
42 std::vector<TestFormat> results =
43 {
44 { VK_FORMAT_R32_SINT }, { VK_FORMAT_R16_SINT }, { VK_FORMAT_R8_SINT },
45 { VK_FORMAT_R32_UINT }, { VK_FORMAT_R16_UINT }, { VK_FORMAT_R8_UINT },
46 { VK_FORMAT_R16_UNORM }, { VK_FORMAT_R8_UNORM },
47 { VK_FORMAT_R16_SNORM }, { VK_FORMAT_R8_SNORM },
48 { VK_FORMAT_R32G32_SINT }, { VK_FORMAT_R16G16_SINT }, { VK_FORMAT_R8G8_SINT },
49 { VK_FORMAT_R32G32_UINT }, { VK_FORMAT_R16G16_UINT }, { VK_FORMAT_R8G8_UINT },
50 { VK_FORMAT_R16G16_UNORM }, { VK_FORMAT_R8G8_UNORM },
51 { VK_FORMAT_R16G16_SNORM }, { VK_FORMAT_R8G8_SNORM },
52 { VK_FORMAT_R32G32B32A32_SINT }, { VK_FORMAT_R16G16B16A16_SINT }, { VK_FORMAT_R8G8B8A8_SINT },
53 { VK_FORMAT_R32G32B32A32_UINT }, { VK_FORMAT_R16G16B16A16_UINT }, { VK_FORMAT_R8G8B8A8_UINT },
54 { VK_FORMAT_R16G16B16A16_UNORM }, { VK_FORMAT_R8G8B8A8_UNORM },
55 { VK_FORMAT_R16G16B16A16_SNORM }, { VK_FORMAT_R8G8B8A8_SNORM }
56 };
57
58 if (imageType == IMAGE_TYPE_2D || imageType == IMAGE_TYPE_2D_ARRAY)
59 {
60 std::vector<TestFormat> ycbcrFormats =
61 {
62 { VK_FORMAT_G8B8G8R8_422_UNORM },
63 { VK_FORMAT_B8G8R8G8_422_UNORM },
64 { VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM },
65 { VK_FORMAT_G8_B8R8_2PLANE_420_UNORM },
66 { VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM },
67 { VK_FORMAT_G8_B8R8_2PLANE_422_UNORM },
68 { VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM },
69 { VK_FORMAT_R10X6_UNORM_PACK16 },
70 { VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
71 { VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 },
72 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 },
73 { VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 },
74 { VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 },
75 { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 },
76 { VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 },
77 { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 },
78 { VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 },
79 { VK_FORMAT_R12X4_UNORM_PACK16 },
80 { VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
81 { VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 },
82 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 },
83 { VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 },
84 { VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 },
85 { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 },
86 { VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 },
87 { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 },
88 { VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 },
89 { VK_FORMAT_G16B16G16R16_422_UNORM },
90 { VK_FORMAT_B16G16R16G16_422_UNORM },
91 { VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM },
92 { VK_FORMAT_G16_B16R16_2PLANE_420_UNORM },
93 { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM },
94 { VK_FORMAT_G16_B16R16_2PLANE_422_UNORM },
95 { VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM }
96 };
97 std::copy(begin(ycbcrFormats), end(ycbcrFormats), std::back_inserter(results));
98 }
99
100 return results;
101 }
102
getShaderGridSize(const ImageType imageType,const tcu::UVec3 & imageSize,const deUint32 mipLevel)103 tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel)
104 {
105 const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
106 const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
107 const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u);
108
109 switch (imageType)
110 {
111 case IMAGE_TYPE_1D:
112 return tcu::UVec3(mipLevelX, 1u, 1u);
113
114 case IMAGE_TYPE_BUFFER:
115 return tcu::UVec3(imageSize.x(), 1u, 1u);
116
117 case IMAGE_TYPE_1D_ARRAY:
118 return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
119
120 case IMAGE_TYPE_2D:
121 return tcu::UVec3(mipLevelX, mipLevelY, 1u);
122
123 case IMAGE_TYPE_2D_ARRAY:
124 return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
125
126 case IMAGE_TYPE_3D:
127 return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
128
129 case IMAGE_TYPE_CUBE:
130 return tcu::UVec3(mipLevelX, mipLevelY, 6u);
131
132 case IMAGE_TYPE_CUBE_ARRAY:
133 return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
134
135 default:
136 DE_FATAL("Unknown image type");
137 return tcu::UVec3(1u, 1u, 1u);
138 }
139 }
140
getLayerSize(const ImageType imageType,const tcu::UVec3 & imageSize)141 tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize)
142 {
143 switch (imageType)
144 {
145 case IMAGE_TYPE_1D:
146 case IMAGE_TYPE_1D_ARRAY:
147 case IMAGE_TYPE_BUFFER:
148 return tcu::UVec3(imageSize.x(), 1u, 1u);
149
150 case IMAGE_TYPE_2D:
151 case IMAGE_TYPE_2D_ARRAY:
152 case IMAGE_TYPE_CUBE:
153 case IMAGE_TYPE_CUBE_ARRAY:
154 return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
155
156 case IMAGE_TYPE_3D:
157 return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
158
159 default:
160 DE_FATAL("Unknown image type");
161 return tcu::UVec3(1u, 1u, 1u);
162 }
163 }
164
getNumLayers(const ImageType imageType,const tcu::UVec3 & imageSize)165 deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize)
166 {
167 switch (imageType)
168 {
169 case IMAGE_TYPE_1D:
170 case IMAGE_TYPE_2D:
171 case IMAGE_TYPE_3D:
172 case IMAGE_TYPE_BUFFER:
173 return 1u;
174
175 case IMAGE_TYPE_1D_ARRAY:
176 case IMAGE_TYPE_2D_ARRAY:
177 return imageSize.z();
178
179 case IMAGE_TYPE_CUBE:
180 return 6u;
181
182 case IMAGE_TYPE_CUBE_ARRAY:
183 return imageSize.z() * 6u;
184
185 default:
186 DE_FATAL("Unknown image type");
187 return 0u;
188 }
189 }
190
getNumPixels(const ImageType imageType,const tcu::UVec3 & imageSize)191 deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize)
192 {
193 const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize);
194
195 return gridSize.x() * gridSize.y() * gridSize.z();
196 }
197
getDimensions(const ImageType imageType)198 deUint32 getDimensions (const ImageType imageType)
199 {
200 switch (imageType)
201 {
202 case IMAGE_TYPE_1D:
203 case IMAGE_TYPE_BUFFER:
204 return 1u;
205
206 case IMAGE_TYPE_1D_ARRAY:
207 case IMAGE_TYPE_2D:
208 return 2u;
209
210 case IMAGE_TYPE_2D_ARRAY:
211 case IMAGE_TYPE_CUBE:
212 case IMAGE_TYPE_CUBE_ARRAY:
213 case IMAGE_TYPE_3D:
214 return 3u;
215
216 default:
217 DE_FATAL("Unknown image type");
218 return 0u;
219 }
220 }
221
getLayerDimensions(const ImageType imageType)222 deUint32 getLayerDimensions (const ImageType imageType)
223 {
224 switch (imageType)
225 {
226 case IMAGE_TYPE_1D:
227 case IMAGE_TYPE_BUFFER:
228 case IMAGE_TYPE_1D_ARRAY:
229 return 1u;
230
231 case IMAGE_TYPE_2D:
232 case IMAGE_TYPE_2D_ARRAY:
233 case IMAGE_TYPE_CUBE:
234 case IMAGE_TYPE_CUBE_ARRAY:
235 return 2u;
236
237 case IMAGE_TYPE_3D:
238 return 3u;
239
240 default:
241 DE_FATAL("Unknown image type");
242 return 0u;
243 }
244 }
245
isImageSizeSupported(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType,const tcu::UVec3 & imageSize)246 bool isImageSizeSupported (const InstanceInterface& instance, const VkPhysicalDevice physicalDevice, const ImageType imageType, const tcu::UVec3& imageSize)
247 {
248 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
249
250 switch (imageType)
251 {
252 case IMAGE_TYPE_1D:
253 return imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
254 case IMAGE_TYPE_1D_ARRAY:
255 return imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
256 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
257 case IMAGE_TYPE_2D:
258 return imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
259 imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
260 case IMAGE_TYPE_2D_ARRAY:
261 return imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
262 imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
263 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
264 case IMAGE_TYPE_CUBE:
265 return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
266 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
267 case IMAGE_TYPE_CUBE_ARRAY:
268 return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
269 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
270 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
271 case IMAGE_TYPE_3D:
272 return imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
273 imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
274 imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
275 case IMAGE_TYPE_BUFFER:
276 return true;
277 default:
278 DE_FATAL("Unknown image type");
279 return false;
280 }
281 }
282
makeBufferImageCopy(const VkExtent3D extent,const deUint32 layerCount,const deUint32 mipmapLevel,const VkDeviceSize bufferOffset)283 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent,
284 const deUint32 layerCount,
285 const deUint32 mipmapLevel,
286 const VkDeviceSize bufferOffset)
287 {
288 const VkBufferImageCopy copyParams =
289 {
290 bufferOffset, // VkDeviceSize bufferOffset;
291 0u, // deUint32 bufferRowLength;
292 0u, // deUint32 bufferImageHeight;
293 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipmapLevel, 0u, layerCount), // VkImageSubresourceLayers imageSubresource;
294 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
295 extent, // VkExtent3D imageExtent;
296 };
297 return copyParams;
298 }
299
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule,const VkSpecializationInfo * specializationInfo)300 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
301 const VkDevice device,
302 const VkPipelineLayout pipelineLayout,
303 const VkShaderModule shaderModule,
304 const VkSpecializationInfo* specializationInfo)
305 {
306 const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
307 {
308 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
309 DE_NULL, // const void* pNext;
310 0u, // VkPipelineShaderStageCreateFlags flags;
311 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
312 shaderModule, // VkShaderModule module;
313 "main", // const char* pName;
314 specializationInfo, // const VkSpecializationInfo* pSpecializationInfo;
315 };
316 const VkComputePipelineCreateInfo pipelineCreateInfo =
317 {
318 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
319 DE_NULL, // const void* pNext;
320 0u, // VkPipelineCreateFlags flags;
321 pipelineShaderStageParams, // VkPipelineShaderStageCreateInfo stage;
322 pipelineLayout, // VkPipelineLayout layout;
323 DE_NULL, // VkPipeline basePipelineHandle;
324 0, // deInt32 basePipelineIndex;
325 };
326 return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
327 }
328
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)329 void submitCommands (const DeviceInterface& vk,
330 const VkQueue queue,
331 const VkCommandBuffer commandBuffer,
332 const deUint32 waitSemaphoreCount,
333 const VkSemaphore* pWaitSemaphores,
334 const VkPipelineStageFlags* pWaitDstStageMask,
335 const deUint32 signalSemaphoreCount,
336 const VkSemaphore* pSignalSemaphores)
337 {
338 const VkSubmitInfo submitInfo =
339 {
340 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
341 DE_NULL, // const void* pNext;
342 waitSemaphoreCount, // deUint32 waitSemaphoreCount;
343 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores;
344 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask;
345 1u, // deUint32 commandBufferCount;
346 &commandBuffer, // const VkCommandBuffer* pCommandBuffers;
347 signalSemaphoreCount, // deUint32 signalSemaphoreCount;
348 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores;
349 };
350
351 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
352 }
353
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)354 void submitCommandsAndWait (const DeviceInterface& vk,
355 const VkDevice device,
356 const VkQueue queue,
357 const VkCommandBuffer commandBuffer,
358 const deUint32 waitSemaphoreCount,
359 const VkSemaphore* pWaitSemaphores,
360 const VkPipelineStageFlags* pWaitDstStageMask,
361 const deUint32 signalSemaphoreCount,
362 const VkSemaphore* pSignalSemaphores,
363 const bool useDeviceGroups,
364 const deUint32 physicalDeviceID)
365 {
366 const VkFenceCreateInfo fenceParams =
367 {
368 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
369 DE_NULL, // const void* pNext;
370 0u, // VkFenceCreateFlags flags;
371 };
372 const Unique<VkFence> fence(createFence (vk, device, &fenceParams));
373
374 const deUint32 deviceMask = 1 << physicalDeviceID;
375 std::vector<deUint32> deviceIndices (waitSemaphoreCount, physicalDeviceID);
376 VkDeviceGroupSubmitInfo deviceGroupSubmitInfo =
377 {
378 VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR, //VkStructureType sType
379 DE_NULL, // const void* pNext
380 waitSemaphoreCount, // uint32_t waitSemaphoreCount
381 deviceIndices.size() ? &deviceIndices[0] : DE_NULL, // const uint32_t* pWaitSemaphoreDeviceIndices
382 1u, // uint32_t commandBufferCount
383 &deviceMask, // const uint32_t* pCommandBufferDeviceMasks
384 0u, // uint32_t signalSemaphoreCount
385 DE_NULL, // const uint32_t* pSignalSemaphoreDeviceIndices
386 };
387 const VkSubmitInfo submitInfo =
388 {
389 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
390 useDeviceGroups ? &deviceGroupSubmitInfo : DE_NULL, // const void* pNext;
391 waitSemaphoreCount, // deUint32 waitSemaphoreCount;
392 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores;
393 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask;
394 1u, // deUint32 commandBufferCount;
395 &commandBuffer, // const VkCommandBuffer* pCommandBuffers;
396 signalSemaphoreCount, // deUint32 signalSemaphoreCount;
397 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores;
398 };
399
400 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
401 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
402 }
403
mapImageType(const ImageType imageType)404 VkImageType mapImageType (const ImageType imageType)
405 {
406 switch (imageType)
407 {
408 case IMAGE_TYPE_1D:
409 case IMAGE_TYPE_1D_ARRAY:
410 case IMAGE_TYPE_BUFFER:
411 return VK_IMAGE_TYPE_1D;
412
413 case IMAGE_TYPE_2D:
414 case IMAGE_TYPE_2D_ARRAY:
415 case IMAGE_TYPE_CUBE:
416 case IMAGE_TYPE_CUBE_ARRAY:
417 return VK_IMAGE_TYPE_2D;
418
419 case IMAGE_TYPE_3D:
420 return VK_IMAGE_TYPE_3D;
421
422 default:
423 DE_FATAL("Unexpected image type");
424 return VK_IMAGE_TYPE_LAST;
425 }
426 }
427
mapImageViewType(const ImageType imageType)428 VkImageViewType mapImageViewType (const ImageType imageType)
429 {
430 switch (imageType)
431 {
432 case IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D;
433 case IMAGE_TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
434 case IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
435 case IMAGE_TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
436 case IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
437 case IMAGE_TYPE_CUBE: return VK_IMAGE_VIEW_TYPE_CUBE;
438 case IMAGE_TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
439
440 default:
441 DE_FATAL("Unexpected image type");
442 return VK_IMAGE_VIEW_TYPE_LAST;
443 }
444 }
445
getImageTypeName(const ImageType imageType)446 std::string getImageTypeName (const ImageType imageType)
447 {
448 switch (imageType)
449 {
450 case IMAGE_TYPE_1D: return "1d";
451 case IMAGE_TYPE_1D_ARRAY: return "1d_array";
452 case IMAGE_TYPE_2D: return "2d";
453 case IMAGE_TYPE_2D_ARRAY: return "2d_array";
454 case IMAGE_TYPE_3D: return "3d";
455 case IMAGE_TYPE_CUBE: return "cube";
456 case IMAGE_TYPE_CUBE_ARRAY: return "cube_array";
457 case IMAGE_TYPE_BUFFER: return "buffer";
458
459 default:
460 DE_FATAL("Unexpected image type");
461 return "";
462 }
463 }
464
getShaderImageType(const tcu::TextureFormat & format,const ImageType imageType)465 std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType)
466 {
467 std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
468 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : "";
469
470 std::string imageTypePart;
471 switch (imageType)
472 {
473 case IMAGE_TYPE_1D: imageTypePart = "1D"; break;
474 case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break;
475 case IMAGE_TYPE_2D: imageTypePart = "2D"; break;
476 case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break;
477 case IMAGE_TYPE_3D: imageTypePart = "3D"; break;
478 case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break;
479 case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break;
480 case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break;
481
482 default:
483 DE_FATAL("Unexpected image type");
484 }
485
486 return formatPart + "image" + imageTypePart;
487 }
488
getShaderImageType(const vk::PlanarFormatDescription & description,const ImageType imageType)489 std::string getShaderImageType (const vk::PlanarFormatDescription& description, const ImageType imageType)
490 {
491 std::string formatPart;
492 std::string imageTypePart;
493
494 // all PlanarFormatDescription types have at least one channel ( 0 ) and all channel types are the same :
495 switch (description.channels[0].type)
496 {
497 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
498 formatPart = "i";
499 break;
500 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
501 formatPart = "u";
502 break;
503 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
504 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
505 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
506 break;
507
508 default:
509 DE_FATAL("Unexpected channel type");
510 }
511
512 switch (imageType)
513 {
514 case IMAGE_TYPE_1D: imageTypePart = "1D"; break;
515 case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break;
516 case IMAGE_TYPE_2D: imageTypePart = "2D"; break;
517 case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break;
518 case IMAGE_TYPE_3D: imageTypePart = "3D"; break;
519 case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break;
520 case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break;
521 case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break;
522
523 default:
524 DE_FATAL("Unexpected image type");
525 }
526
527 return formatPart + "image" + imageTypePart;
528 }
529
getShaderImageDataType(const tcu::TextureFormat & format)530 std::string getShaderImageDataType(const tcu::TextureFormat& format)
531 {
532 switch (tcu::getTextureChannelClass(format.type))
533 {
534 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
535 return "uvec4";
536 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
537 return "ivec4";
538 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
539 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
540 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
541 return "vec4";
542 default:
543 DE_FATAL("Unexpected channel type");
544 return "";
545 }
546 }
547
getShaderImageDataType(const vk::PlanarFormatDescription & description)548 std::string getShaderImageDataType (const vk::PlanarFormatDescription& description)
549 {
550 switch (description.channels[0].type)
551 {
552 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
553 return "uvec4";
554 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
555 return "ivec4";
556 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
557 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
558 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
559 return "vec4";
560 default:
561 DE_FATAL("Unexpected channel type");
562 return "";
563 }
564 }
565
getShaderImageFormatQualifier(const tcu::TextureFormat & format)566 std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
567 {
568 const char* orderPart;
569 const char* typePart;
570
571 switch (format.order)
572 {
573 case tcu::TextureFormat::R: orderPart = "r"; break;
574 case tcu::TextureFormat::RG: orderPart = "rg"; break;
575 case tcu::TextureFormat::RGB: orderPart = "rgb"; break;
576 case tcu::TextureFormat::RGBA: orderPart = "rgba"; break;
577
578 default:
579 DE_FATAL("Unexpected channel order");
580 orderPart = DE_NULL;
581 }
582
583 switch (format.type)
584 {
585 case tcu::TextureFormat::FLOAT: typePart = "32f"; break;
586 case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break;
587
588 case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break;
589 case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break;
590 case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break;
591
592 case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break;
593 case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break;
594 case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break;
595
596 case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break;
597 case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break;
598
599 case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break;
600 case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break;
601
602 default:
603 DE_FATAL("Unexpected channel type");
604 typePart = DE_NULL;
605 }
606
607 return std::string() + orderPart + typePart;
608 }
609
getShaderImageFormatQualifier(VkFormat format)610 std::string getShaderImageFormatQualifier (VkFormat format)
611 {
612 switch (format)
613 {
614 case VK_FORMAT_R8_SINT: return "r8i";
615 case VK_FORMAT_R16_SINT: return "r16i";
616 case VK_FORMAT_R32_SINT: return "r32i";
617 case VK_FORMAT_R8_UINT: return "r8ui";
618 case VK_FORMAT_R16_UINT: return "r16ui";
619 case VK_FORMAT_R32_UINT: return "r32ui";
620 case VK_FORMAT_R8_SNORM: return "r8_snorm";
621 case VK_FORMAT_R16_SNORM: return "r16_snorm";
622 case VK_FORMAT_R8_UNORM: return "r8";
623 case VK_FORMAT_R16_UNORM: return "r16";
624
625 case VK_FORMAT_R8G8_SINT: return "rg8i";
626 case VK_FORMAT_R16G16_SINT: return "rg16i";
627 case VK_FORMAT_R32G32_SINT: return "rg32i";
628 case VK_FORMAT_R8G8_UINT: return "rg8ui";
629 case VK_FORMAT_R16G16_UINT: return "rg16ui";
630 case VK_FORMAT_R32G32_UINT: return "rg32ui";
631 case VK_FORMAT_R8G8_SNORM: return "rg8_snorm";
632 case VK_FORMAT_R16G16_SNORM: return "rg16_snorm";
633 case VK_FORMAT_R8G8_UNORM: return "rg8";
634 case VK_FORMAT_R16G16_UNORM: return "rg16";
635
636 case VK_FORMAT_R8G8B8A8_SINT: return "rgba8i";
637 case VK_FORMAT_R16G16B16A16_SINT: return "rgba16i";
638 case VK_FORMAT_R32G32B32A32_SINT: return "rgba32i";
639 case VK_FORMAT_R8G8B8A8_UINT: return "rgba8ui";
640 case VK_FORMAT_R16G16B16A16_UINT: return "rgba16ui";
641 case VK_FORMAT_R32G32B32A32_UINT: return "rgba32ui";
642 case VK_FORMAT_R8G8B8A8_SNORM: return "rgba8_snorm";
643 case VK_FORMAT_R16G16B16A16_SNORM: return "rgba16_snorm";
644 case VK_FORMAT_R8G8B8A8_UNORM: return "rgba8";
645 case VK_FORMAT_R16G16B16A16_UNORM: return "rgba16";
646
647 case VK_FORMAT_G8B8G8R8_422_UNORM: return "rgba8";
648 case VK_FORMAT_B8G8R8G8_422_UNORM: return "rgba8";
649 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: return "rgba8";
650 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: return "rgba8";
651 case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: return "rgba8";
652 case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: return "rgba8";
653 case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: return "rgba8";
654 case VK_FORMAT_R10X6_UNORM_PACK16: return "r16";
655 case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: return "rg16";
656 case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: return "rgba16";
657 case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: return "rgba16";
658 case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: return "rgba16";
659 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: return "rgba16";
660 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: return "rgba16";
661 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: return "rgba16";
662 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: return "rgba16";
663 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: return "rgba16";
664 case VK_FORMAT_R12X4_UNORM_PACK16: return "r16";
665 case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: return "rg16";
666 case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: return "rgba16";
667 case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: return "rgba16";
668 case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: return "rgba16";
669 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: return "rgba16";
670 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: return "rgba16";
671 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: return "rgba16";
672 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: return "rgba16";
673 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: return "rgba16";
674 case VK_FORMAT_G16B16G16R16_422_UNORM: return "rgba16";
675 case VK_FORMAT_B16G16R16G16_422_UNORM: return "rgba16";
676 case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: return "rgba16";
677 case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: return "rgba16";
678 case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: return "rgba16";
679 case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: return "rgba16";
680 case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: return "rgba16";
681
682 default:
683 DE_FATAL("Unexpected texture format");
684 return "error";
685 }
686 }
687
getImageFormatID(VkFormat format)688 std::string getImageFormatID (VkFormat format)
689 {
690 switch (format)
691 {
692 case VK_FORMAT_R8_SINT: return "r8i";
693 case VK_FORMAT_R16_SINT: return "r16i";
694 case VK_FORMAT_R32_SINT: return "r32i";
695 case VK_FORMAT_R8_UINT: return "r8ui";
696 case VK_FORMAT_R16_UINT: return "r16ui";
697 case VK_FORMAT_R32_UINT: return "r32ui";
698 case VK_FORMAT_R8_SNORM: return "r8_snorm";
699 case VK_FORMAT_R16_SNORM: return "r16_snorm";
700 case VK_FORMAT_R8_UNORM: return "r8";
701 case VK_FORMAT_R16_UNORM: return "r16";
702
703 case VK_FORMAT_R8G8_SINT: return "rg8i";
704 case VK_FORMAT_R16G16_SINT: return "rg16i";
705 case VK_FORMAT_R32G32_SINT: return "rg32i";
706 case VK_FORMAT_R8G8_UINT: return "rg8ui";
707 case VK_FORMAT_R16G16_UINT: return "rg16ui";
708 case VK_FORMAT_R32G32_UINT: return "rg32ui";
709 case VK_FORMAT_R8G8_SNORM: return "rg8_snorm";
710 case VK_FORMAT_R16G16_SNORM: return "rg16_snorm";
711 case VK_FORMAT_R8G8_UNORM: return "rg8";
712 case VK_FORMAT_R16G16_UNORM: return "rg16";
713
714 case VK_FORMAT_R8G8B8A8_SINT: return "rgba8i";
715 case VK_FORMAT_R16G16B16A16_SINT: return "rgba16i";
716 case VK_FORMAT_R32G32B32A32_SINT: return "rgba32i";
717 case VK_FORMAT_R8G8B8A8_UINT: return "rgba8ui";
718 case VK_FORMAT_R16G16B16A16_UINT: return "rgba16ui";
719 case VK_FORMAT_R32G32B32A32_UINT: return "rgba32ui";
720 case VK_FORMAT_R8G8B8A8_SNORM: return "rgba8_snorm";
721 case VK_FORMAT_R16G16B16A16_SNORM: return "rgba16_snorm";
722 case VK_FORMAT_R8G8B8A8_UNORM: return "rgba8";
723 case VK_FORMAT_R16G16B16A16_UNORM: return "rgba16";
724
725 case VK_FORMAT_G8B8G8R8_422_UNORM:
726 case VK_FORMAT_B8G8R8G8_422_UNORM:
727 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
728 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
729 case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
730 case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
731 case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
732 case VK_FORMAT_R10X6_UNORM_PACK16:
733 case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
734 case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
735 case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
736 case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
737 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
738 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
739 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
740 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
741 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
742 case VK_FORMAT_R12X4_UNORM_PACK16:
743 case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
744 case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
745 case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
746 case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
747 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
748 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
749 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
750 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
751 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
752 case VK_FORMAT_G16B16G16R16_422_UNORM:
753 case VK_FORMAT_B16G16R16G16_422_UNORM:
754 case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
755 case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
756 case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
757 case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
758 case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
759 return de::toLower(std::string(getFormatName(format)).substr(10));
760
761 default:
762 DE_FATAL("Unexpected texture format");
763 return "error";
764 }
765 }
766
getShaderImageCoordinates(const ImageType imageType,const std::string & x,const std::string & xy,const std::string & xyz)767 std::string getShaderImageCoordinates (const ImageType imageType,
768 const std::string& x,
769 const std::string& xy,
770 const std::string& xyz)
771 {
772 switch (imageType)
773 {
774 case IMAGE_TYPE_1D:
775 case IMAGE_TYPE_BUFFER:
776 return x;
777
778 case IMAGE_TYPE_1D_ARRAY:
779 case IMAGE_TYPE_2D:
780 return xy;
781
782 case IMAGE_TYPE_2D_ARRAY:
783 case IMAGE_TYPE_3D:
784 case IMAGE_TYPE_CUBE:
785 case IMAGE_TYPE_CUBE_ARRAY:
786 return xyz;
787
788 default:
789 DE_FATAL("Unexpected image type");
790 return "";
791 }
792 }
793
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)794 deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
795 {
796 const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
797
798 return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment);
799 }
800
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const tcu::TextureFormat & format,const deUint32 mipmapLevelsCount,const deUint32 mipmapMemoryAlignment)801 deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
802 {
803 deUint32 imageSizeInBytes = 0;
804 for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
805 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
806
807 return imageSizeInBytes;
808 }
809
getImageMipLevelSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const vk::PlanarFormatDescription & formatDescription,const deUint32 planeNdx,const deUint32 mipmapLevel,const deUint32 mipmapMemoryAlignment)810 deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
811 {
812 return layersCount * getPlaneSizeInBytes(formatDescription, baseExtents, planeNdx, mipmapLevel, mipmapMemoryAlignment);
813 }
814
getImageSizeInBytes(const VkExtent3D & baseExtents,const deUint32 layersCount,const vk::PlanarFormatDescription & formatDescription,const deUint32 planeNdx,const deUint32 mipmapLevelsCount,const deUint32 mipmapMemoryAlignment)815 deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
816 {
817 deUint32 imageSizeInBytes = 0;
818
819 for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
820 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, formatDescription, planeNdx, mipmapLevel, mipmapMemoryAlignment);
821
822 return imageSizeInBytes;
823 }
824
makeSparseImageMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkImageSubresource & subresource,const VkOffset3D & offset,const VkExtent3D & extent)825 VkSparseImageMemoryBind makeSparseImageMemoryBind (const DeviceInterface& vk,
826 const VkDevice device,
827 const VkDeviceSize allocationSize,
828 const deUint32 memoryType,
829 const VkImageSubresource& subresource,
830 const VkOffset3D& offset,
831 const VkExtent3D& extent)
832 {
833 const VkMemoryAllocateInfo allocInfo =
834 {
835 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
836 DE_NULL, // const void* pNext;
837 allocationSize, // VkDeviceSize allocationSize;
838 memoryType, // deUint32 memoryTypeIndex;
839 };
840
841 VkDeviceMemory deviceMemory = 0;
842 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
843
844 VkSparseImageMemoryBind imageMemoryBind;
845
846 imageMemoryBind.subresource = subresource;
847 imageMemoryBind.memory = deviceMemory;
848 imageMemoryBind.memoryOffset = 0u;
849 imageMemoryBind.flags = 0u;
850 imageMemoryBind.offset = offset;
851 imageMemoryBind.extent = extent;
852
853 return imageMemoryBind;
854 }
855
makeSparseMemoryBind(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize allocationSize,const deUint32 memoryType,const VkDeviceSize resourceOffset,const VkSparseMemoryBindFlags flags)856 VkSparseMemoryBind makeSparseMemoryBind (const DeviceInterface& vk,
857 const VkDevice device,
858 const VkDeviceSize allocationSize,
859 const deUint32 memoryType,
860 const VkDeviceSize resourceOffset,
861 const VkSparseMemoryBindFlags flags)
862 {
863 const VkMemoryAllocateInfo allocInfo =
864 {
865 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
866 DE_NULL, // const void* pNext;
867 allocationSize, // VkDeviceSize allocationSize;
868 memoryType, // deUint32 memoryTypeIndex;
869 };
870
871 VkDeviceMemory deviceMemory = 0;
872 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
873
874 VkSparseMemoryBind memoryBind;
875
876 memoryBind.resourceOffset = resourceOffset;
877 memoryBind.size = allocationSize;
878 memoryBind.memory = deviceMemory;
879 memoryBind.memoryOffset = 0u;
880 memoryBind.flags = flags;
881
882 return memoryBind;
883 }
884
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)885 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
886 {
887 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
888
889 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
890 throw tcu::NotSupportedError("Tessellation shader not supported");
891
892 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
893 throw tcu::NotSupportedError("Geometry shader not supported");
894
895 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
896 throw tcu::NotSupportedError("Double-precision floats not supported");
897
898 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
899 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
900
901 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
902 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
903
904 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
905 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
906 }
907
findMatchingMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkMemoryRequirements & objectMemoryRequirements,const MemoryRequirement & memoryRequirement)908 deUint32 findMatchingMemoryType (const InstanceInterface& instance,
909 const VkPhysicalDevice physicalDevice,
910 const VkMemoryRequirements& objectMemoryRequirements,
911 const MemoryRequirement& memoryRequirement)
912 {
913 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
914
915 for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
916 {
917 if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
918 memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
919 {
920 return memoryTypeNdx;
921 }
922 }
923
924 return NO_MATCH_FOUND;
925 }
926
getHeapIndexForMemoryType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const deUint32 memoryType)927 deUint32 getHeapIndexForMemoryType (const InstanceInterface& instance,
928 const VkPhysicalDevice physicalDevice,
929 const deUint32 memoryType)
930 {
931 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
932 DE_ASSERT(memoryType < deviceMemoryProperties.memoryTypeCount);
933 return deviceMemoryProperties.memoryTypes[memoryType].heapIndex;
934 }
935
checkSparseSupportForImageType(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const ImageType imageType)936 bool checkSparseSupportForImageType (const InstanceInterface& instance,
937 const VkPhysicalDevice physicalDevice,
938 const ImageType imageType)
939 {
940 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
941
942 if (!deviceFeatures.sparseBinding)
943 return false;
944
945 switch (mapImageType(imageType))
946 {
947 case VK_IMAGE_TYPE_2D:
948 return deviceFeatures.sparseResidencyImage2D == VK_TRUE;
949 case VK_IMAGE_TYPE_3D:
950 return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
951 default:
952 DE_FATAL("Unexpected image type");
953 return false;
954 };
955 }
956
checkSparseSupportForImageFormat(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkImageCreateInfo & imageInfo)957 bool checkSparseSupportForImageFormat (const InstanceInterface& instance,
958 const VkPhysicalDevice physicalDevice,
959 const VkImageCreateInfo& imageInfo)
960 {
961 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
962 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
963
964 return sparseImageFormatPropVec.size() > 0u;
965 }
966
checkImageFormatFeatureSupport(const InstanceInterface & instance,const VkPhysicalDevice physicalDevice,const VkFormat format,const VkFormatFeatureFlags featureFlags)967 bool checkImageFormatFeatureSupport (const InstanceInterface& instance,
968 const VkPhysicalDevice physicalDevice,
969 const VkFormat format,
970 const VkFormatFeatureFlags featureFlags)
971 {
972 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
973
974 return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags;
975 }
976
getSparseAspectRequirementsIndex(const std::vector<VkSparseImageMemoryRequirements> & requirements,const VkImageAspectFlags aspectFlags)977 deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>& requirements,
978 const VkImageAspectFlags aspectFlags)
979 {
980 for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx)
981 {
982 if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags)
983 return memoryReqNdx;
984 }
985
986 return NO_MATCH_FOUND;
987 }
988
getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription & formatInfo,deUint32 planeNdx)989 vk::VkFormat getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription& formatInfo, deUint32 planeNdx)
990 {
991 DE_ASSERT(planeNdx < formatInfo.numPlanes);
992 vk::VkFormat result = formatInfo.planes[planeNdx].planeCompatibleFormat;
993
994 // redirect result for some of the YCbCr image formats
995 static const std::pair<vk::VkFormat, vk::VkFormat> ycbcrFormats[] =
996 {
997 { VK_FORMAT_G8B8G8R8_422_UNORM_KHR, VK_FORMAT_R8G8B8A8_UNORM },
998 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR, VK_FORMAT_R16G16B16A16_UNORM },
999 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR, VK_FORMAT_R16G16B16A16_UNORM },
1000 { VK_FORMAT_G16B16G16R16_422_UNORM_KHR, VK_FORMAT_R16G16B16A16_UNORM },
1001 { VK_FORMAT_B8G8R8G8_422_UNORM_KHR, VK_FORMAT_R8G8B8A8_UNORM },
1002 { VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR, VK_FORMAT_R16G16B16A16_UNORM },
1003 { VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR, VK_FORMAT_R16G16B16A16_UNORM },
1004 { VK_FORMAT_B16G16R16G16_422_UNORM_KHR, VK_FORMAT_R16G16B16A16_UNORM }
1005 };
1006 auto it = std::find_if(std::begin(ycbcrFormats), std::end(ycbcrFormats), [result](const std::pair<vk::VkFormat, vk::VkFormat>& p) { return p.first == result; });
1007 if (it != std::end(ycbcrFormats))
1008 result = it->second;
1009 return result;
1010 }
1011
1012 } // sparse
1013 } // vkt
1014