Add the support to device connection via TCP/IP
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / sparse_resources / vktSparseResourcesImageSparseBinding.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  vktSparseResourcesImageSparseBinding.cpp
21  * \brief Sparse fully resident images with mipmaps tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktSparseResourcesBufferSparseBinding.hpp"
25 #include "vktSparseResourcesTestsUtil.hpp"
26 #include "vktSparseResourcesBase.hpp"
27 #include "vktTestCaseUtil.hpp"
28
29 #include "vkDefs.hpp"
30 #include "vkRef.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkPlatform.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkQueryUtil.hpp"
38 #include "vkTypeUtil.hpp"
39
40 #include "deUniquePtr.hpp"
41 #include "deStringUtil.hpp"
42
43 #include <string>
44 #include <vector>
45
46 using namespace vk;
47
48 namespace vkt
49 {
50 namespace sparse
51 {
52 namespace
53 {
54
55 class ImageSparseBindingCase : public TestCase
56 {
57 public:
58                                         ImageSparseBindingCase  (tcu::TestContext&                      testCtx,
59                                                                                          const std::string&                     name,
60                                                                                          const std::string&                     description,
61                                                                                          const ImageType                        imageType,
62                                                                                          const tcu::UVec3&                      imageSize,
63                                                                                          const tcu::TextureFormat&      format);
64
65         TestInstance*   createInstance                  (Context&                       context) const;
66
67 private:
68         const ImageType                         m_imageType;
69         const tcu::UVec3                        m_imageSize;
70         const tcu::TextureFormat        m_format;
71 };
72
73 ImageSparseBindingCase::ImageSparseBindingCase (tcu::TestContext&                       testCtx,
74                                                                                                 const std::string&                      name,
75                                                                                                 const std::string&                      description,
76                                                                                                 const ImageType                         imageType,
77                                                                                                 const tcu::UVec3&                       imageSize,
78                                                                                                 const tcu::TextureFormat&       format)
79         : TestCase                              (testCtx, name, description)
80         , m_imageType                   (imageType)
81         , m_imageSize                   (imageSize)
82         , m_format                              (format)
83 {
84 }
85
86 class ImageSparseBindingInstance : public SparseResourcesBaseInstance
87 {
88 public:
89                                         ImageSparseBindingInstance      (Context&                                       context,
90                                                                                                  const ImageType                        imageType,
91                                                                                                  const tcu::UVec3&                      imageSize,
92                                                                                                  const tcu::TextureFormat&      format);
93
94         tcu::TestStatus iterate                                         (void);
95
96 private:
97         const ImageType                         m_imageType;
98         const tcu::UVec3                        m_imageSize;
99         const tcu::TextureFormat        m_format;
100 };
101
102 ImageSparseBindingInstance::ImageSparseBindingInstance (Context&                                        context,
103                                                                                                                 const ImageType                         imageType,
104                                                                                                                 const tcu::UVec3&                       imageSize,
105                                                                                                                 const tcu::TextureFormat&       format)
106         : SparseResourcesBaseInstance   (context)
107         , m_imageType                                   (imageType)
108         , m_imageSize                                   (imageSize)
109         , m_format                                              (format)
110 {
111 }
112
113 tcu::TestStatus ImageSparseBindingInstance::iterate (void)
114 {
115         const InstanceInterface&        instance                = m_context.getInstanceInterface();
116         const DeviceInterface&          deviceInterface = m_context.getDeviceInterface();
117         const VkPhysicalDevice          physicalDevice  = m_context.getPhysicalDevice();
118
119         // Check if device supports sparse binding
120         const VkPhysicalDeviceFeatures  deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice);
121
122         if (deviceFeatures.sparseBinding == false)
123         {
124                 return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Device does not support sparse binding");
125         }
126
127         // Check if image size does not exceed device limits
128         const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
129
130         if (isImageSizeSupported(m_imageType, m_imageSize, deviceProperties.limits) == false)
131         {
132                 return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Image size not supported for device");
133         }
134
135         QueueRequirementsVec queueRequirements;
136         queueRequirements.push_back(QueueRequirements(VK_QUEUE_SPARSE_BINDING_BIT, 1u));
137         queueRequirements.push_back(QueueRequirements(VK_QUEUE_COMPUTE_BIT, 1u));
138
139         // Create logical device supporting both sparse and compute queues
140         if (!createDeviceSupportingQueues(queueRequirements))
141         {
142                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Could not create device supporting sparse and compute queue");
143         }
144
145         const VkPhysicalDeviceMemoryProperties  deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
146
147         // Create memory allocator for logical device
148         const de::UniquePtr<Allocator> allocator(new SimpleAllocator(deviceInterface, *m_logicalDevice, deviceMemoryProperties));
149
150         // Create queue supporting sparse binding operations
151         const Queue& sparseQueue = getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
152
153         // Create queue supporting compute and transfer operations
154         const Queue& computeQueue = getQueue(VK_QUEUE_COMPUTE_BIT, 0);
155
156         VkImageCreateInfo imageSparseInfo;
157
158         imageSparseInfo.sType                                   = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;                                  //VkStructureType               sType;
159         imageSparseInfo.pNext                                   = DE_NULL;                                                                                              //const void*                   pNext;
160         imageSparseInfo.flags                                   = VK_IMAGE_CREATE_SPARSE_BINDING_BIT;                                   //VkImageCreateFlags    flags;
161         imageSparseInfo.imageType                               = mapImageType(m_imageType);                                                    //VkImageType                   imageType;
162         imageSparseInfo.format                                  = mapTextureFormat(m_format);                                                   //VkFormat                              format;
163         imageSparseInfo.extent                                  = makeExtent3D(getLayerSize(m_imageType, m_imageSize)); //VkExtent3D                    extent;
164         imageSparseInfo.arrayLayers                             = getNumLayers(m_imageType, m_imageSize);                               //deUint32                              arrayLayers;
165         imageSparseInfo.samples                                 = VK_SAMPLE_COUNT_1_BIT;                                                                //VkSampleCountFlagBits samples;
166         imageSparseInfo.tiling                                  = VK_IMAGE_TILING_OPTIMAL;                                                              //VkImageTiling                 tiling;
167         imageSparseInfo.initialLayout                   = VK_IMAGE_LAYOUT_UNDEFINED;                                                    //VkImageLayout                 initialLayout;
168         imageSparseInfo.usage                                   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
169                                                                                           VK_IMAGE_USAGE_TRANSFER_DST_BIT;                                              //VkImageUsageFlags             usage;
170         imageSparseInfo.sharingMode                             = VK_SHARING_MODE_EXCLUSIVE;                                                    //VkSharingMode                 sharingMode;
171         imageSparseInfo.queueFamilyIndexCount   = 0u;                                                                                                   //deUint32                              queueFamilyIndexCount;
172         imageSparseInfo.pQueueFamilyIndices             = DE_NULL;                                                                                              //const deUint32*               pQueueFamilyIndices;
173
174         if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
175         {
176                 imageSparseInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
177         }
178
179         VkImageFormatProperties imageFormatProperties;
180         instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
181                                                                                                         imageSparseInfo.format,
182                                                                                                         imageSparseInfo.imageType,
183                                                                                                         imageSparseInfo.tiling,
184                                                                                                         imageSparseInfo.usage,
185                                                                                                         imageSparseInfo.flags,
186                                                                                                         &imageFormatProperties);
187
188         imageSparseInfo.mipLevels = getImageMaxMipLevels(imageFormatProperties, imageSparseInfo);
189
190         // Allow sharing of sparse image by two different queue families (if necessary)
191         const deUint32 queueFamilyIndices[] = { sparseQueue.queueFamilyIndex, computeQueue.queueFamilyIndex };
192
193         if (sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex)
194         {
195                 imageSparseInfo.sharingMode = VK_SHARING_MODE_CONCURRENT;       //VkSharingMode                 sharingMode;
196                 imageSparseInfo.queueFamilyIndexCount = 2u;                                     //deUint32                              queueFamilyIndexCount;
197                 imageSparseInfo.pQueueFamilyIndices = queueFamilyIndices;       //const deUint32*               pQueueFamilyIndices;
198         }
199
200         // Create sparse image
201         const Unique<VkImage> imageSparse(createImage(deviceInterface, *m_logicalDevice, &imageSparseInfo));
202
203         // Get sparse image general memory requirements
204         const VkMemoryRequirements imageSparseMemRequirements = getImageMemoryRequirements(deviceInterface, *m_logicalDevice, *imageSparse);
205
206         // Check if required image memory size does not exceed device limits
207         if (imageSparseMemRequirements.size > deviceProperties.limits.sparseAddressSpaceSize)
208         {
209                 return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Required memory size for sparse resource exceeds device limits");
210         }
211
212         DE_ASSERT((imageSparseMemRequirements.size % imageSparseMemRequirements.alignment) == 0);
213
214         typedef de::SharedPtr< Unique<VkDeviceMemory> > DeviceMemoryUniquePtr;
215
216         std::vector<VkSparseMemoryBind>         sparseMemoryBinds;
217         std::vector<DeviceMemoryUniquePtr>      deviceMemUniquePtrVec;
218         const deUint32                                          numSparseBinds  = static_cast<deUint32>(imageSparseMemRequirements.size / imageSparseMemRequirements.alignment);
219         const deUint32                                          memoryType              = findMatchingMemoryType(deviceMemoryProperties, imageSparseMemRequirements, MemoryRequirement::Any);
220
221         if (memoryType == NO_MATCH_FOUND)
222         {
223                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "No matching memory type found");
224         }
225
226         for (deUint32 sparseBindNdx = 0; sparseBindNdx < numSparseBinds; ++sparseBindNdx)
227         {
228                 const VkMemoryAllocateInfo allocInfo =
229                 {
230                         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, //      VkStructureType                 sType;
231                         DE_NULL,                                                                //      const void*                             pNext;
232                         imageSparseMemRequirements.alignment,   //      VkDeviceSize                    allocationSize;
233                         memoryType,                                                             //      deUint32                                memoryTypeIndex;
234                 };
235
236                 VkDeviceMemory deviceMemory = 0;
237                 VK_CHECK(deviceInterface.allocateMemory(*m_logicalDevice, &allocInfo, DE_NULL, &deviceMemory));
238
239                 deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(deviceMemory), Deleter<VkDeviceMemory>(deviceInterface, *m_logicalDevice, DE_NULL))));
240
241                 const VkSparseMemoryBind sparseMemoryBind = makeSparseMemoryBind
242                 (
243                         imageSparseMemRequirements.alignment * sparseBindNdx,   //VkDeviceSize                          resourceOffset
244                         imageSparseMemRequirements.alignment,                                   //VkDeviceSize                          size
245                         deviceMemory,                                                                                   //VkDeviceMemory                        memory;
246                         0u,                                                                                                             //VkDeviceSize                          memoryOffset;
247                         0u                                                                                                              //VkSparseMemoryBindFlags       flags;
248                 );
249
250                 sparseMemoryBinds.push_back(sparseMemoryBind);
251         }
252
253         const VkSparseImageOpaqueMemoryBindInfo opaqueBindInfo = makeSparseImageOpaqueMemoryBindInfo
254         (
255                 *imageSparse,                   // VkImage                                              image
256                 numSparseBinds,                 // deUint32                                             bindCount
257                 &sparseMemoryBinds[0]   // const VkSparseMemoryBind*    pBinds
258         );
259
260         const Unique<VkSemaphore> imageMemoryBindSemaphore(makeSemaphore(deviceInterface, *m_logicalDevice));
261
262         const VkBindSparseInfo bindSparseInfo =
263         {
264                 VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,                     //VkStructureType                                                       sType;
265                 DE_NULL,                                                                        //const void*                                                           pNext;
266                 0u,                                                                                     //deUint32                                                                      waitSemaphoreCount;
267                 DE_NULL,                                                                        //const VkSemaphore*                                            pWaitSemaphores;
268                 0u,                                                                                     //deUint32                                                                      bufferBindCount;
269                 DE_NULL,                                                                        //const VkSparseBufferMemoryBindInfo*           pBufferBinds;
270                 1u,                                                                                     //deUint32                                                                      imageOpaqueBindCount;
271                 &opaqueBindInfo,                                                        //const VkSparseImageOpaqueMemoryBindInfo*      pImageOpaqueBinds;
272                 0u,                                                                                     //deUint32                                                                      imageBindCount;
273                 DE_NULL,                                                                        //const VkSparseImageMemoryBindInfo*            pImageBinds;
274                 1u,                                                                                     //deUint32                                                                      signalSemaphoreCount;
275                 &imageMemoryBindSemaphore.get()                         //const VkSemaphore*                                            pSignalSemaphores;
276         };
277
278         // Submit sparse bind commands for execution
279         VK_CHECK(deviceInterface.queueBindSparse(sparseQueue.queueHandle, 1u, &bindSparseInfo, DE_NULL));
280
281         // Create command buffer for compute and transfer oparations
282         const Unique<VkCommandPool>       commandPool(makeCommandPool(deviceInterface, *m_logicalDevice, computeQueue.queueFamilyIndex));
283         const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, *m_logicalDevice, *commandPool));
284
285         // Start recording commands
286         beginCommandBuffer(deviceInterface, *commandBuffer);
287
288         const deUint32                          imageSizeInBytes = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels);
289         const VkBufferCreateInfo        inputBufferCreateInfo = makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
290
291         const de::UniquePtr<Buffer>     inputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, inputBufferCreateInfo, MemoryRequirement::HostVisible));
292
293         std::vector<deUint8> referenceData;
294         referenceData.resize(imageSizeInBytes);
295
296         for (deUint32 valueNdx = 0; valueNdx < imageSizeInBytes; ++valueNdx)
297         {
298                 referenceData[valueNdx] = static_cast<deUint8>((valueNdx % imageSparseMemRequirements.alignment) + 1u);
299         }
300
301         deMemcpy(inputBuffer->getAllocation().getHostPtr(), &referenceData[0], imageSizeInBytes);
302
303         flushMappedMemoryRange(deviceInterface, *m_logicalDevice, inputBuffer->getAllocation().getMemory(), inputBuffer->getAllocation().getOffset(), imageSizeInBytes);
304
305         const VkBufferMemoryBarrier inputBufferBarrier
306                 = makeBufferMemoryBarrier(
307                 VK_ACCESS_HOST_WRITE_BIT,
308                 VK_ACCESS_TRANSFER_READ_BIT,
309                 inputBuffer->get(),
310                 0u,
311                 imageSizeInBytes);
312
313         const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
314
315         const VkImageMemoryBarrier imageSparseTransferDstBarrier
316                 = makeImageMemoryBarrier(
317                 0u,
318                 VK_ACCESS_TRANSFER_WRITE_BIT,
319                 VK_IMAGE_LAYOUT_UNDEFINED,
320                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
321                 *imageSparse,
322                 fullImageSubresourceRange);
323
324         deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 1u, &inputBufferBarrier, 1u, &imageSparseTransferDstBarrier);
325
326         std::vector <VkBufferImageCopy> bufferImageCopy;
327         bufferImageCopy.resize(imageSparseInfo.mipLevels);
328
329         VkDeviceSize bufferOffset = 0;
330         for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; mipmapNdx++)
331         {
332                 bufferImageCopy[mipmapNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipmapNdx), imageSparseInfo.arrayLayers, mipmapNdx, bufferOffset);
333
334                 bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx);
335         }
336
337         deviceInterface.cmdCopyBufferToImage(*commandBuffer, inputBuffer->get(), *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
338
339         const VkImageMemoryBarrier imageSparseTransferSrcBarrier
340                 = makeImageMemoryBarrier(
341                 VK_ACCESS_TRANSFER_WRITE_BIT,
342                 VK_ACCESS_TRANSFER_READ_BIT,
343                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
344                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
345                 *imageSparse,
346                 fullImageSubresourceRange);
347
348         deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferSrcBarrier);
349
350         const VkBufferCreateInfo        outputBufferCreateInfo = makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
351         const de::UniquePtr<Buffer>     outputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, outputBufferCreateInfo, MemoryRequirement::HostVisible));
352
353         deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, outputBuffer->get(), static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
354
355         const VkBufferMemoryBarrier outputBufferBarrier
356                 = makeBufferMemoryBarrier(
357                 VK_ACCESS_TRANSFER_WRITE_BIT,
358                 VK_ACCESS_HOST_READ_BIT,
359                 outputBuffer->get(),
360                 0u,
361                 imageSizeInBytes);
362
363         deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &outputBufferBarrier, 0u, DE_NULL);
364
365         // End recording commands
366         endCommandBuffer(deviceInterface, *commandBuffer);
367
368         const VkPipelineStageFlags stageBits[] = { VK_PIPELINE_STAGE_TRANSFER_BIT };
369
370         // Submit commands for execution and wait for completion
371         submitCommandsAndWait(deviceInterface, *m_logicalDevice, computeQueue.queueHandle, *commandBuffer, 1u, &imageMemoryBindSemaphore.get(), stageBits);
372
373         // Retrieve data from buffer to host memory
374         const Allocation& allocation = outputBuffer->getAllocation();
375
376         invalidateMappedMemoryRange(deviceInterface, *m_logicalDevice, allocation.getMemory(), allocation.getOffset(), imageSizeInBytes);
377
378         const deUint8*  outputData = static_cast<const deUint8*>(allocation.getHostPtr());
379         tcu::TestStatus testStatus = tcu::TestStatus::pass("Passed");
380
381         if (deMemCmp(outputData, &referenceData[0], imageSizeInBytes) != 0)
382         {
383                 testStatus = tcu::TestStatus::fail("Failed");
384         }
385
386         // Wait for sparse queue to become idle
387         deviceInterface.queueWaitIdle(sparseQueue.queueHandle);
388
389         return testStatus;
390 }
391
392 TestInstance* ImageSparseBindingCase::createInstance (Context& context) const
393 {
394         return new ImageSparseBindingInstance(context, m_imageType, m_imageSize, m_format);
395 }
396
397 } // anonymous ns
398
399 tcu::TestCaseGroup* createImageSparseBindingTests(tcu::TestContext& testCtx)
400 {
401         de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "image_sparse_binding", "Buffer Sparse Binding"));
402
403         static const deUint32 sizeCountPerImageType = 3u;
404
405         struct ImageParameters
406         {
407                 ImageType       imageType;
408                 tcu::UVec3      imageSizes[sizeCountPerImageType];
409         };
410
411         static const ImageParameters imageParametersArray[] =
412         {
413                 { IMAGE_TYPE_1D,                { tcu::UVec3(512u, 1u,   1u ), tcu::UVec3(1024u, 1u,   1u), tcu::UVec3(11u, 1u,   1u) } },
414                 { IMAGE_TYPE_1D_ARRAY,  { tcu::UVec3(512u, 1u,   64u), tcu::UVec3(1024u, 1u,   8u), tcu::UVec3(11u, 1u,   3u) } },
415                 { IMAGE_TYPE_2D,                { tcu::UVec3(512u, 256u, 1u ), tcu::UVec3(1024u, 128u, 1u), tcu::UVec3(11u, 137u, 1u) } },
416                 { IMAGE_TYPE_2D_ARRAY,  { tcu::UVec3(512u, 256u, 6u ), tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u, 137u, 3u) } },
417                 { IMAGE_TYPE_3D,                { tcu::UVec3(512u, 256u, 6u ), tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u, 137u, 3u) } },
418                 { IMAGE_TYPE_CUBE,              { tcu::UVec3(512u, 256u, 1u ), tcu::UVec3(1024u, 128u, 1u), tcu::UVec3(11u, 137u, 1u) } },
419                 { IMAGE_TYPE_CUBE_ARRAY,{ tcu::UVec3(512u, 256u, 6u ), tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u, 137u, 3u) } }
420         };
421
422         static const tcu::TextureFormat formats[] =
423         {
424                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::SIGNED_INT32),
425                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::SIGNED_INT16),
426                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::SIGNED_INT8),
427                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT32),
428                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT16),
429                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT8)
430         };
431
432         for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray); ++imageTypeNdx)
433         {
434                 const ImageType                                 imageType = imageParametersArray[imageTypeNdx].imageType;
435                 de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
436
437                 for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
438                 {
439                         const tcu::TextureFormat&               format = formats[formatNdx];
440                         de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, getShaderImageFormatQualifier(format).c_str(), ""));
441
442                         for (deInt32 imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray[imageTypeNdx].imageSizes); ++imageSizeNdx)
443                         {
444                                 const tcu::UVec3 imageSize = imageParametersArray[imageTypeNdx].imageSizes[imageSizeNdx];
445
446                                 std::ostringstream stream;
447                                 stream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
448
449                                 formatGroup->addChild(new ImageSparseBindingCase(testCtx, stream.str(), "", imageType, imageSize, format));
450                         }
451                         imageTypeGroup->addChild(formatGroup.release());
452                 }
453                 testGroup->addChild(imageTypeGroup.release());
454         }
455
456         return testGroup.release();
457 }
458
459 } // sparse
460 } // vkt