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