Update Vulkan CTS to version 1.0.2.3 am: 148890e79f
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / sparse_resources / vktSparseResourcesTestsUtil.cpp
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 "vkTypeUtil.hpp"
27 #include "tcuTextureUtil.hpp"
28
29 #include <deMath.h>
30
31 using namespace vk;
32
33 namespace vkt
34 {
35 namespace sparse
36 {
37
38 tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel)
39 {
40         const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
41         const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
42         const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u);
43
44         switch (imageType)
45         {
46         case IMAGE_TYPE_1D:
47                 return tcu::UVec3(mipLevelX, 1u, 1u);
48
49         case IMAGE_TYPE_BUFFER:
50                 return tcu::UVec3(imageSize.x(), 1u, 1u);
51
52         case IMAGE_TYPE_1D_ARRAY:
53                 return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
54
55         case IMAGE_TYPE_2D:
56                 return tcu::UVec3(mipLevelX, mipLevelY, 1u);
57
58         case IMAGE_TYPE_2D_ARRAY:
59                 return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
60
61         case IMAGE_TYPE_3D:
62                 return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
63
64         case IMAGE_TYPE_CUBE:
65                 return tcu::UVec3(mipLevelX, mipLevelY, 6u);
66
67         case IMAGE_TYPE_CUBE_ARRAY:
68                 return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
69
70         default:
71                 DE_FATAL("Unknown image type");
72                 return tcu::UVec3(1u, 1u, 1u);
73         }
74 }
75
76 tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize)
77 {
78         switch (imageType)
79         {
80         case IMAGE_TYPE_1D:
81         case IMAGE_TYPE_1D_ARRAY:
82         case IMAGE_TYPE_BUFFER:
83                 return tcu::UVec3(imageSize.x(), 1u, 1u);
84
85         case IMAGE_TYPE_2D:
86         case IMAGE_TYPE_2D_ARRAY:
87         case IMAGE_TYPE_CUBE:
88         case IMAGE_TYPE_CUBE_ARRAY:
89                 return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
90
91         case IMAGE_TYPE_3D:
92                 return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
93
94         default:
95                 DE_FATAL("Unknown image type");
96                 return tcu::UVec3(1u, 1u, 1u);
97         }
98 }
99
100 deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize)
101 {
102         switch (imageType)
103         {
104         case IMAGE_TYPE_1D:
105         case IMAGE_TYPE_2D:
106         case IMAGE_TYPE_3D:
107         case IMAGE_TYPE_BUFFER:
108                 return 1u;
109
110         case IMAGE_TYPE_1D_ARRAY:
111         case IMAGE_TYPE_2D_ARRAY:
112                 return imageSize.z();
113
114         case IMAGE_TYPE_CUBE:
115                 return 6u;
116
117         case IMAGE_TYPE_CUBE_ARRAY:
118                 return imageSize.z() * 6u;
119
120         default:
121                 DE_FATAL("Unknown image type");
122                 return 0u;
123         }
124 }
125
126 deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize)
127 {
128         const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize);
129
130         return gridSize.x() * gridSize.y() * gridSize.z();
131 }
132
133 deUint32 getDimensions (const ImageType imageType)
134 {
135         switch (imageType)
136         {
137         case IMAGE_TYPE_1D:
138         case IMAGE_TYPE_BUFFER:
139                 return 1u;
140
141         case IMAGE_TYPE_1D_ARRAY:
142         case IMAGE_TYPE_2D:
143                 return 2u;
144
145         case IMAGE_TYPE_2D_ARRAY:
146         case IMAGE_TYPE_CUBE:
147         case IMAGE_TYPE_CUBE_ARRAY:
148         case IMAGE_TYPE_3D:
149                 return 3u;
150
151         default:
152                 DE_FATAL("Unknown image type");
153                 return 0u;
154         }
155 }
156
157 deUint32 getLayerDimensions (const ImageType imageType)
158 {
159         switch (imageType)
160         {
161         case IMAGE_TYPE_1D:
162         case IMAGE_TYPE_BUFFER:
163         case IMAGE_TYPE_1D_ARRAY:
164                 return 1u;
165
166         case IMAGE_TYPE_2D:
167         case IMAGE_TYPE_2D_ARRAY:
168         case IMAGE_TYPE_CUBE:
169         case IMAGE_TYPE_CUBE_ARRAY:
170                 return 2u;
171
172         case IMAGE_TYPE_3D:
173                 return 3u;
174
175         default:
176                 DE_FATAL("Unknown image type");
177                 return 0u;
178         }
179 }
180
181 bool isImageSizeSupported (const InstanceInterface& instance, const VkPhysicalDevice physicalDevice, const ImageType imageType, const tcu::UVec3& imageSize)
182 {
183         const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
184
185         switch (imageType)
186         {
187                 case IMAGE_TYPE_1D:
188                         return  imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
189                 case IMAGE_TYPE_1D_ARRAY:
190                         return  imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
191                                         imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
192                 case IMAGE_TYPE_2D:
193                         return  imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
194                                         imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
195                 case IMAGE_TYPE_2D_ARRAY:
196                         return  imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
197                                         imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
198                                         imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
199                 case IMAGE_TYPE_CUBE:
200                         return  imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
201                                         imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
202                 case IMAGE_TYPE_CUBE_ARRAY:
203                         return  imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
204                                         imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
205                                         imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
206                 case IMAGE_TYPE_3D:
207                         return  imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
208                                         imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
209                                         imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
210                 case IMAGE_TYPE_BUFFER:
211                         return true;
212                 default:
213                         DE_FATAL("Unknown image type");
214                         return false;
215         }
216 }
217
218 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize                     bufferSize,
219                                                                                  const VkBufferUsageFlags       usage)
220 {
221         const VkBufferCreateInfo bufferCreateInfo =
222         {
223                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
224                 DE_NULL,                                                                // const void*                  pNext;
225                 0u,                                                                             // VkBufferCreateFlags  flags;
226                 bufferSize,                                                             // VkDeviceSize                 size;
227                 usage,                                                                  // VkBufferUsageFlags   usage;
228                 VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
229                 0u,                                                                             // deUint32                             queueFamilyIndexCount;
230                 DE_NULL,                                                                // const deUint32*              pQueueFamilyIndices;
231         };
232         return bufferCreateInfo;
233 }
234
235 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D         extent,
236                                                                            const deUint32               layerCount,
237                                                                            const deUint32               mipmapLevel,
238                                                                            const VkDeviceSize   bufferOffset)
239 {
240         const VkBufferImageCopy copyParams =
241         {
242                 bufferOffset,                                                                                                                                           //      VkDeviceSize                            bufferOffset;
243                 0u,                                                                                                                                                                     //      deUint32                                        bufferRowLength;
244                 0u,                                                                                                                                                                     //      deUint32                                        bufferImageHeight;
245                 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipmapLevel, 0u, layerCount),     //      VkImageSubresourceLayers        imageSubresource;
246                 makeOffset3D(0, 0, 0),                                                                                                                          //      VkOffset3D                                      imageOffset;
247                 extent,                                                                                                                                                         //      VkExtent3D                                      imageExtent;
248         };
249         return copyParams;
250 }
251
252 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
253 {
254         const VkCommandPoolCreateInfo commandPoolParams =
255         {
256                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType                      sType;
257                 DE_NULL,                                                                                        // const void*                          pNext;
258                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // VkCommandPoolCreateFlags     flags;
259                 queueFamilyIndex,                                                                       // deUint32                                     queueFamilyIndex;
260         };
261         return createCommandPool(vk, device, &commandPoolParams);
262 }
263
264 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&               vk,
265                                                                                    const VkDevice                               device,
266                                                                                    const VkDescriptorSetLayout  descriptorSetLayout)
267 {
268         const VkPipelineLayoutCreateInfo pipelineLayoutParams =
269         {
270                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                                          // VkStructureType                                      sType;
271                 DE_NULL,                                                                                                                        // const void*                                          pNext;
272                 0u,                                                                                                                                     // VkPipelineLayoutCreateFlags          flags;
273                 (descriptorSetLayout != DE_NULL ? 1u : 0u),                                                     // deUint32                                                     setLayoutCount;
274                 (descriptorSetLayout != DE_NULL ? &descriptorSetLayout : DE_NULL),      // const VkDescriptorSetLayout*         pSetLayouts;
275                 0u,                                                                                                                                     // deUint32                                                     pushConstantRangeCount;
276                 DE_NULL,                                                                                                                        // const VkPushConstantRange*           pPushConstantRanges;
277         };
278         return createPipelineLayout(vk, device, &pipelineLayoutParams);
279 }
280
281 Move<VkPipeline> makeComputePipeline (const DeviceInterface&            vk,
282                                                                           const VkDevice                                device,
283                                                                           const VkPipelineLayout                pipelineLayout,
284                                                                           const VkShaderModule                  shaderModule,
285                                                                           const VkSpecializationInfo*   specializationInfo)
286 {
287         const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
288         {
289                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
290                 DE_NULL,                                                                                                // const void*                                                  pNext;
291                 0u,                                                                                                             // VkPipelineShaderStageCreateFlags             flags;
292                 VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits                                stage;
293                 shaderModule,                                                                                   // VkShaderModule                                               module;
294                 "main",                                                                                                 // const char*                                                  pName;
295                 specializationInfo,                                                                             // const VkSpecializationInfo*                  pSpecializationInfo;
296         };
297         const VkComputePipelineCreateInfo pipelineCreateInfo =
298         {
299                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,         // VkStructureType                                      sType;
300                 DE_NULL,                                                                                        // const void*                                          pNext;
301                 0u,                                                                                                     // VkPipelineCreateFlags                        flags;
302                 pipelineShaderStageParams,                                                      // VkPipelineShaderStageCreateInfo      stage;
303                 pipelineLayout,                                                                         // VkPipelineLayout                                     layout;
304                 DE_NULL,                                                                                        // VkPipeline                                           basePipelineHandle;
305                 0,                                                                                                      // deInt32                                                      basePipelineIndex;
306         };
307         return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
308 }
309
310 Move<VkBufferView> makeBufferView (const DeviceInterface&       vk,
311                                                                    const VkDevice                       vkDevice,
312                                                                    const VkBuffer                       buffer,
313                                                                    const VkFormat                       format,
314                                                                    const VkDeviceSize           offset,
315                                                                    const VkDeviceSize           size)
316 {
317         const VkBufferViewCreateInfo bufferViewParams =
318         {
319                 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,      // VkStructureType                      sType;
320                 DE_NULL,                                                                        // const void*                          pNext;
321                 0u,                                                                                     // VkBufferViewCreateFlags      flags;
322                 buffer,                                                                         // VkBuffer                                     buffer;
323                 format,                                                                         // VkFormat                                     format;
324                 offset,                                                                         // VkDeviceSize                         offset;
325                 size,                                                                           // VkDeviceSize                         range;
326         };
327         return createBufferView(vk, vkDevice, &bufferViewParams);
328 }
329
330 Move<VkImageView> makeImageView (const DeviceInterface&                 vk,
331                                                                  const VkDevice                                 vkDevice,
332                                                                  const VkImage                                  image,
333                                                                  const VkImageViewType                  imageViewType,
334                                                                  const VkFormat                                 format,
335                                                                  const VkImageSubresourceRange  subresourceRange)
336 {
337         const VkImageViewCreateInfo imageViewParams =
338         {
339                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
340                 DE_NULL,                                                                                // const void*                          pNext;
341                 0u,                                                                                             // VkImageViewCreateFlags       flags;
342                 image,                                                                                  // VkImage                                      image;
343                 imageViewType,                                                                  // VkImageViewType                      viewType;
344                 format,                                                                                 // VkFormat                                     format;
345                 makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
346                 subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
347         };
348         return createImageView(vk, vkDevice, &imageViewParams);
349 }
350
351 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&                 vk,
352                                                                                  const VkDevice                                 device,
353                                                                                  const VkDescriptorPool                 descriptorPool,
354                                                                                  const VkDescriptorSetLayout    setLayout)
355 {
356         const VkDescriptorSetAllocateInfo allocateParams =
357         {
358                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // VkStructureType                              sType;
359                 DE_NULL,                                                                                        // const void*                                  pNext;
360                 descriptorPool,                                                                         // VkDescriptorPool                             descriptorPool;
361                 1u,                                                                                                     // deUint32                                             setLayoutCount;
362                 &setLayout,                                                                                     // const VkDescriptorSetLayout* pSetLayouts;
363         };
364         return allocateDescriptorSet(vk, device, &allocateParams);
365 }
366
367 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&             vk,
368                                                                          const VkDevice                         device,
369                                                                          const VkRenderPass                     renderPass,
370                                                                          const deUint32                         attachmentCount,
371                                                                          const VkImageView*                     pAttachments,
372                                                                          const deUint32                         width,
373                                                                          const deUint32                         height,
374                                                                          const deUint32                         layers)
375 {
376         const VkFramebufferCreateInfo framebufferInfo =
377         {
378                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType                             sType;
379                 DE_NULL,                                                                                // const void*                                 pNext;
380                 (VkFramebufferCreateFlags)0,                                    // VkFramebufferCreateFlags                    flags;
381                 renderPass,                                                                             // VkRenderPass                                renderPass;
382                 attachmentCount,                                                                // uint32_t                                    attachmentCount;
383                 pAttachments,                                                                   // const VkImageView*                          pAttachments;
384                 width,                                                                                  // uint32_t                                    width;
385                 height,                                                                                 // uint32_t                                    height;
386                 layers,                                                                                 // uint32_t                                    layers;
387         };
388
389         return createFramebuffer(vk, device, &framebufferInfo);
390 }
391
392 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags      srcAccessMask,
393                                                                                            const VkAccessFlags  dstAccessMask,
394                                                                                            const VkBuffer               buffer,
395                                                                                            const VkDeviceSize   offset,
396                                                                                            const VkDeviceSize   bufferSizeBytes)
397 {
398         const VkBufferMemoryBarrier barrier =
399         {
400                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
401                 DE_NULL,                                                                        // const void*          pNext;
402                 srcAccessMask,                                                          // VkAccessFlags        srcAccessMask;
403                 dstAccessMask,                                                          // VkAccessFlags        dstAccessMask;
404                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
405                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     destQueueFamilyIndex;
406                 buffer,                                                                         // VkBuffer                     buffer;
407                 offset,                                                                         // VkDeviceSize         offset;
408                 bufferSizeBytes,                                                        // VkDeviceSize         size;
409         };
410         return barrier;
411 }
412
413 VkImageMemoryBarrier makeImageMemoryBarrier     (const VkAccessFlags                    srcAccessMask,
414                                                                                          const VkAccessFlags                    dstAccessMask,
415                                                                                          const VkImageLayout                    oldLayout,
416                                                                                          const VkImageLayout                    newLayout,
417                                                                                          const VkImage                                  image,
418                                                                                          const VkImageSubresourceRange  subresourceRange)
419 {
420         const VkImageMemoryBarrier barrier =
421         {
422                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
423                 DE_NULL,                                                                // const void*                          pNext;
424                 srcAccessMask,                                                  // VkAccessFlags                        outputMask;
425                 dstAccessMask,                                                  // VkAccessFlags                        inputMask;
426                 oldLayout,                                                              // VkImageLayout                        oldLayout;
427                 newLayout,                                                              // VkImageLayout                        newLayout;
428                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     srcQueueFamilyIndex;
429                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     destQueueFamilyIndex;
430                 image,                                                                  // VkImage                                      image;
431                 subresourceRange,                                               // VkImageSubresourceRange      subresourceRange;
432         };
433         return barrier;
434 }
435
436 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags                        srcAccessMask,
437                                                                                          const VkAccessFlags                    dstAccessMask,
438                                                                                          const VkImageLayout                    oldLayout,
439                                                                                          const VkImageLayout                    newLayout,
440                                                                                          const deUint32                                 srcQueueFamilyIndex,
441                                                                                          const deUint32                                 destQueueFamilyIndex,
442                                                                                          const VkImage                                  image,
443                                                                                          const VkImageSubresourceRange  subresourceRange)
444 {
445         const VkImageMemoryBarrier barrier =
446         {
447                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
448                 DE_NULL,                                                                // const void*                          pNext;
449                 srcAccessMask,                                                  // VkAccessFlags                        outputMask;
450                 dstAccessMask,                                                  // VkAccessFlags                        inputMask;
451                 oldLayout,                                                              // VkImageLayout                        oldLayout;
452                 newLayout,                                                              // VkImageLayout                        newLayout;
453                 srcQueueFamilyIndex,                                    // deUint32                                     srcQueueFamilyIndex;
454                 destQueueFamilyIndex,                                   // deUint32                                     destQueueFamilyIndex;
455                 image,                                                                  // VkImage                                      image;
456                 subresourceRange,                                               // VkImageSubresourceRange      subresourceRange;
457         };
458         return barrier;
459 }
460
461 VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags  srcAccessMask,
462                                                                            const VkAccessFlags  dstAccessMask)
463 {
464         const VkMemoryBarrier barrier =
465         {
466                 VK_STRUCTURE_TYPE_MEMORY_BARRIER,       // VkStructureType                      sType;
467                 DE_NULL,                                                        // const void*                          pNext;
468                 srcAccessMask,                                          // VkAccessFlags                        outputMask;
469                 dstAccessMask,                                          // VkAccessFlags                        inputMask;
470         };
471         return barrier;
472 }
473
474 de::MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
475 {
476         de::MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
477         VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
478         return alloc;
479 }
480
481 de::MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
482 {
483         de::MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
484         VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
485         return alloc;
486 }
487
488 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
489 {
490         const VkCommandBufferBeginInfo commandBufBeginParams =
491         {
492                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
493                 DE_NULL,                                                                                // const void*                                          pNext;
494                 0u,                                                                                             // VkCommandBufferUsageFlags            flags;
495                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
496         };
497         VK_CHECK(vk.beginCommandBuffer(commandBuffer, &commandBufBeginParams));
498 }
499
500 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
501 {
502         VK_CHECK(vk.endCommandBuffer(commandBuffer));
503 }
504
505 void submitCommands (const DeviceInterface&                     vk,
506                                          const VkQueue                                  queue,
507                                          const VkCommandBuffer                  commandBuffer,
508                                          const deUint32                                 waitSemaphoreCount,
509                                          const VkSemaphore*                             pWaitSemaphores,
510                                          const VkPipelineStageFlags*    pWaitDstStageMask,
511                                          const deUint32                                 signalSemaphoreCount,
512                                          const VkSemaphore*                             pSignalSemaphores)
513 {
514         const VkSubmitInfo submitInfo =
515         {
516                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                              sType;
517                 DE_NULL,                                                // const void*                                  pNext;
518                 waitSemaphoreCount,                             // deUint32                                             waitSemaphoreCount;
519                 pWaitSemaphores,                                // const VkSemaphore*                   pWaitSemaphores;
520                 pWaitDstStageMask,                              // const VkPipelineStageFlags*  pWaitDstStageMask;
521                 1u,                                                             // deUint32                                             commandBufferCount;
522                 &commandBuffer,                                 // const VkCommandBuffer*               pCommandBuffers;
523                 signalSemaphoreCount,                   // deUint32                                             signalSemaphoreCount;
524                 pSignalSemaphores,                              // const VkSemaphore*                   pSignalSemaphores;
525         };
526
527         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
528 }
529
530 void submitCommandsAndWait (const DeviceInterface&              vk,
531                                                         const VkDevice                          device,
532                                                         const VkQueue                           queue,
533                                                         const VkCommandBuffer           commandBuffer,
534                                                         const deUint32                          waitSemaphoreCount,
535                                                         const VkSemaphore*                      pWaitSemaphores,
536                                                         const VkPipelineStageFlags*     pWaitDstStageMask,
537                                                         const deUint32                          signalSemaphoreCount,
538                                                         const VkSemaphore*                      pSignalSemaphores)
539 {
540         const VkFenceCreateInfo fenceParams =
541         {
542                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
543                 DE_NULL,                                                                // const void*                  pNext;
544                 0u,                                                                             // VkFenceCreateFlags   flags;
545         };
546         const Unique<VkFence> fence(createFence(vk, device, &fenceParams));
547
548         const VkSubmitInfo submitInfo =
549         {
550                 VK_STRUCTURE_TYPE_SUBMIT_INFO,          // VkStructureType                              sType;
551                 DE_NULL,                                                        // const void*                                  pNext;
552                 waitSemaphoreCount,                                     // deUint32                                             waitSemaphoreCount;
553                 pWaitSemaphores,                                        // const VkSemaphore*                   pWaitSemaphores;
554                 pWaitDstStageMask,                                      // const VkPipelineStageFlags*  pWaitDstStageMask;
555                 1u,                                                                     // deUint32                                             commandBufferCount;
556                 &commandBuffer,                                         // const VkCommandBuffer*               pCommandBuffers;
557                 signalSemaphoreCount,                           // deUint32                                             signalSemaphoreCount;
558                 pSignalSemaphores,                                      // const VkSemaphore*                   pSignalSemaphores;
559         };
560
561         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
562         VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
563 }
564
565 VkImageType     mapImageType (const ImageType imageType)
566 {
567         switch (imageType)
568         {
569                 case IMAGE_TYPE_1D:
570                 case IMAGE_TYPE_1D_ARRAY:
571                 case IMAGE_TYPE_BUFFER:
572                         return VK_IMAGE_TYPE_1D;
573
574                 case IMAGE_TYPE_2D:
575                 case IMAGE_TYPE_2D_ARRAY:
576                 case IMAGE_TYPE_CUBE:
577                 case IMAGE_TYPE_CUBE_ARRAY:
578                         return VK_IMAGE_TYPE_2D;
579
580                 case IMAGE_TYPE_3D:
581                         return VK_IMAGE_TYPE_3D;
582
583                 default:
584                         DE_ASSERT(false);
585                         return VK_IMAGE_TYPE_LAST;
586         }
587 }
588
589 VkImageViewType mapImageViewType (const ImageType imageType)
590 {
591         switch (imageType)
592         {
593                 case IMAGE_TYPE_1D:                     return VK_IMAGE_VIEW_TYPE_1D;
594                 case IMAGE_TYPE_1D_ARRAY:       return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
595                 case IMAGE_TYPE_2D:                     return VK_IMAGE_VIEW_TYPE_2D;
596                 case IMAGE_TYPE_2D_ARRAY:       return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
597                 case IMAGE_TYPE_3D:                     return VK_IMAGE_VIEW_TYPE_3D;
598                 case IMAGE_TYPE_CUBE:           return VK_IMAGE_VIEW_TYPE_CUBE;
599                 case IMAGE_TYPE_CUBE_ARRAY:     return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
600
601                 default:
602                         DE_ASSERT(false);
603                         return VK_IMAGE_VIEW_TYPE_LAST;
604         }
605 }
606
607 std::string getImageTypeName (const ImageType imageType)
608 {
609         switch (imageType)
610         {
611                 case IMAGE_TYPE_1D:                     return "1d";
612                 case IMAGE_TYPE_1D_ARRAY:       return "1d_array";
613                 case IMAGE_TYPE_2D:                     return "2d";
614                 case IMAGE_TYPE_2D_ARRAY:       return "2d_array";
615                 case IMAGE_TYPE_3D:                     return "3d";
616                 case IMAGE_TYPE_CUBE:           return "cube";
617                 case IMAGE_TYPE_CUBE_ARRAY:     return "cube_array";
618                 case IMAGE_TYPE_BUFFER:         return "buffer";
619
620                 default:
621                         DE_ASSERT(false);
622                         return "";
623         }
624 }
625
626 std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType)
627 {
628         std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
629                                                          tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER   ? "i" : "";
630
631         std::string imageTypePart;
632         switch (imageType)
633         {
634                 case IMAGE_TYPE_1D:                     imageTypePart = "1D";                   break;
635                 case IMAGE_TYPE_1D_ARRAY:       imageTypePart = "1DArray";              break;
636                 case IMAGE_TYPE_2D:                     imageTypePart = "2D";                   break;
637                 case IMAGE_TYPE_2D_ARRAY:       imageTypePart = "2DArray";              break;
638                 case IMAGE_TYPE_3D:                     imageTypePart = "3D";                   break;
639                 case IMAGE_TYPE_CUBE:           imageTypePart = "Cube";                 break;
640                 case IMAGE_TYPE_CUBE_ARRAY:     imageTypePart = "CubeArray";    break;
641                 case IMAGE_TYPE_BUFFER:         imageTypePart = "Buffer";               break;
642
643                 default:
644                         DE_ASSERT(false);
645         }
646
647         return formatPart + "image" + imageTypePart;
648 }
649
650
651 std::string getShaderImageDataType(const tcu::TextureFormat& format)
652 {
653         switch (tcu::getTextureChannelClass(format.type))
654         {
655                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
656                         return "uvec4";
657                 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
658                         return "ivec4";
659                 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
660                         return "vec4";
661                 default:
662                         DE_ASSERT(false);
663                         return "";
664         }
665 }
666
667
668 std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
669 {
670         const char* orderPart;
671         const char* typePart;
672
673         switch (format.order)
674         {
675                 case tcu::TextureFormat::R:             orderPart = "r";        break;
676                 case tcu::TextureFormat::RG:    orderPart = "rg";       break;
677                 case tcu::TextureFormat::RGB:   orderPart = "rgb";      break;
678                 case tcu::TextureFormat::RGBA:  orderPart = "rgba";     break;
679
680                 default:
681                         DE_ASSERT(false);
682                         orderPart = DE_NULL;
683         }
684
685         switch (format.type)
686         {
687                 case tcu::TextureFormat::FLOAT:                         typePart = "32f";               break;
688                 case tcu::TextureFormat::HALF_FLOAT:            typePart = "16f";               break;
689
690                 case tcu::TextureFormat::UNSIGNED_INT32:        typePart = "32ui";              break;
691                 case tcu::TextureFormat::UNSIGNED_INT16:        typePart = "16ui";              break;
692                 case tcu::TextureFormat::UNSIGNED_INT8:         typePart = "8ui";               break;
693
694                 case tcu::TextureFormat::SIGNED_INT32:          typePart = "32i";               break;
695                 case tcu::TextureFormat::SIGNED_INT16:          typePart = "16i";               break;
696                 case tcu::TextureFormat::SIGNED_INT8:           typePart = "8i";                break;
697
698                 case tcu::TextureFormat::UNORM_INT16:           typePart = "16";                break;
699                 case tcu::TextureFormat::UNORM_INT8:            typePart = "8";                 break;
700
701                 case tcu::TextureFormat::SNORM_INT16:           typePart = "16_snorm";  break;
702                 case tcu::TextureFormat::SNORM_INT8:            typePart = "8_snorm";   break;
703
704                 default:
705                         DE_ASSERT(false);
706                         typePart = DE_NULL;
707         }
708
709         return std::string() + orderPart + typePart;
710 }
711
712 std::string getShaderImageCoordinates   (const ImageType        imageType,
713                                                                                  const std::string&     x,
714                                                                                  const std::string&     xy,
715                                                                                  const std::string&     xyz)
716 {
717         switch (imageType)
718         {
719                 case IMAGE_TYPE_1D:
720                 case IMAGE_TYPE_BUFFER:
721                         return x;
722
723                 case IMAGE_TYPE_1D_ARRAY:
724                 case IMAGE_TYPE_2D:
725                         return xy;
726
727                 case IMAGE_TYPE_2D_ARRAY:
728                 case IMAGE_TYPE_3D:
729                 case IMAGE_TYPE_CUBE:
730                 case IMAGE_TYPE_CUBE_ARRAY:
731                         return xyz;
732
733                 default:
734                         DE_ASSERT(0);
735                         return "";
736         }
737 }
738
739 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel)
740 {
741         VkExtent3D result;
742
743         result.width    = std::max(baseExtents.width  >> mipLevel, 1u);
744         result.height   = std::max(baseExtents.height >> mipLevel, 1u);
745         result.depth    = std::max(baseExtents.depth  >> mipLevel, 1u);
746
747         return result;
748 }
749
750 deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent)
751 {
752         const deUint32 widestEdge = std::max(std::max(extent.width, extent.height), extent.depth);
753
754         return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels);
755 }
756
757 deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
758 {
759         const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
760
761         return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment);
762 }
763
764 deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
765 {
766         deUint32 imageSizeInBytes = 0;
767         for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
768                 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
769
770         return imageSizeInBytes;
771 }
772
773 VkSparseImageMemoryBind makeSparseImageMemoryBind  (const DeviceInterface&                      vk,
774                                                                                                         const VkDevice                                  device,
775                                                                                                         const VkDeviceSize                              allocationSize,
776                                                                                                         const deUint32                                  memoryType,
777                                                                                                         const VkImageSubresource&               subresource,
778                                                                                                         const VkOffset3D&                               offset,
779                                                                                                         const VkExtent3D&                               extent)
780 {
781         const VkMemoryAllocateInfo      allocInfo =
782         {
783                 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, //      VkStructureType                 sType;
784                 DE_NULL,                                                                //      const void*                             pNext;
785                 allocationSize,                                                 //      VkDeviceSize                    allocationSize;
786                 memoryType,                                                             //      deUint32                                memoryTypeIndex;
787         };
788
789         VkDeviceMemory deviceMemory = 0;
790         VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
791
792         VkSparseImageMemoryBind imageMemoryBind;
793
794         imageMemoryBind.subresource             = subresource;
795         imageMemoryBind.memory                  = deviceMemory;
796         imageMemoryBind.memoryOffset    = 0u;
797         imageMemoryBind.flags                   = 0u;
798         imageMemoryBind.offset                  = offset;
799         imageMemoryBind.extent                  = extent;
800
801         return imageMemoryBind;
802 }
803
804 VkSparseMemoryBind makeSparseMemoryBind (const DeviceInterface&                 vk,
805                                                                                  const VkDevice                                 device,
806                                                                                  const VkDeviceSize                             allocationSize,
807                                                                                  const deUint32                                 memoryType,
808                                                                                  const VkDeviceSize                             resourceOffset,
809                                                                                  const VkSparseMemoryBindFlags  flags)
810 {
811         const VkMemoryAllocateInfo allocInfo =
812         {
813                 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, //      VkStructureType sType;
814                 DE_NULL,                                                                //      const void*             pNext;
815                 allocationSize,                                                 //      VkDeviceSize    allocationSize;
816                 memoryType,                                                             //      deUint32                memoryTypeIndex;
817         };
818
819         VkDeviceMemory deviceMemory = 0;
820         VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory));
821
822         VkSparseMemoryBind memoryBind;
823
824         memoryBind.resourceOffset       = resourceOffset;
825         memoryBind.size                         = allocationSize;
826         memoryBind.memory                       = deviceMemory;
827         memoryBind.memoryOffset         = 0u;
828         memoryBind.flags                        = flags;
829
830         return memoryBind;
831 }
832
833 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
834 {
835         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
836
837         if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
838                 throw tcu::NotSupportedError("Tessellation shader not supported");
839
840         if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
841                 throw tcu::NotSupportedError("Geometry shader not supported");
842
843         if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
844                 throw tcu::NotSupportedError("Double-precision floats not supported");
845
846         if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
847                 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
848
849         if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
850                 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
851
852         if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
853                 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
854 }
855
856 deUint32 findMatchingMemoryType (const InstanceInterface&               instance,
857                                                                  const VkPhysicalDevice                 physicalDevice,
858                                                                  const VkMemoryRequirements&    objectMemoryRequirements,
859                                                                  const MemoryRequirement&               memoryRequirement)
860 {
861         const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
862
863         for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
864         {
865                 if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
866                         memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
867                 {
868                         return memoryTypeNdx;
869                 }
870         }
871
872         return NO_MATCH_FOUND;
873 }
874
875 bool checkSparseSupportForImageType (const InstanceInterface&   instance,
876                                                                          const VkPhysicalDevice         physicalDevice,
877                                                                          const ImageType                        imageType)
878 {
879         const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
880
881         if (!deviceFeatures.sparseBinding)
882                 return false;
883
884         switch (mapImageType(imageType))
885         {
886                 case VK_IMAGE_TYPE_2D:
887                         return deviceFeatures.sparseResidencyImage2D == VK_TRUE;
888                 case VK_IMAGE_TYPE_3D:
889                         return deviceFeatures.sparseResidencyImage3D == VK_TRUE;
890                 default:
891                         DE_ASSERT(0);
892                         return false;
893         };
894 }
895
896 bool checkSparseSupportForImageFormat (const InstanceInterface& instance,
897                                                                            const VkPhysicalDevice       physicalDevice,
898                                                                            const VkImageCreateInfo&     imageInfo)
899 {
900         const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties(
901                 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling);
902
903         return sparseImageFormatPropVec.size() > 0u;
904 }
905
906 bool checkImageFormatFeatureSupport (const InstanceInterface&   instance,
907                                                                          const VkPhysicalDevice         physicalDevice,
908                                                                          const VkFormat                         format,
909                                                                          const VkFormatFeatureFlags     featureFlags)
910 {
911         const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
912
913         return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags;
914 }
915
916 deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>&  requirements,
917                                                                                    const VkImageAspectFlags                                                             aspectFlags)
918 {
919         for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx)
920         {
921                 if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags)
922                         return memoryReqNdx;
923         }
924
925         return NO_MATCH_FOUND;
926 }
927
928 } // sparse
929 } // vkt