dEQP-VK.renderpass: Set IMAGE_USAGE_TRANSFER_SRC_BIT when needed
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / image / vktImageSizeTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Mobica Ltd.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and/or associated documentation files (the
9  * "Materials"), to deal in the Materials without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Materials, and to
12  * permit persons to whom the Materials are furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice(s) and this permission notice shall be included
16  * in all copies or substantial portions of the Materials.
17  *
18  * The Materials are Confidential Information as defined by the
19  * Khronos Membership Agreement until designated non-confidential by Khronos,
20  * at which point this condition clause shall be removed.
21  *
22  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
29  *
30  *//*!
31  * \file
32  * \brief Image size Tests
33  *//*--------------------------------------------------------------------*/
34
35 #include "vktImageSizeTests.hpp"
36 #include "vktTestCaseUtil.hpp"
37 #include "vktImageTestsUtil.hpp"
38 #include "vktImageTexture.hpp"
39
40 #include "vkDefs.hpp"
41 #include "vkRef.hpp"
42 #include "vkRefUtil.hpp"
43 #include "vkPlatform.hpp"
44 #include "vkPrograms.hpp"
45 #include "vkMemUtil.hpp"
46 #include "vkBuilderUtil.hpp"
47 #include "vkImageUtil.hpp"
48
49 #include "deUniquePtr.hpp"
50 #include "deStringUtil.hpp"
51
52 #include <string>
53
54 using namespace vk;
55
56 namespace vkt
57 {
58 namespace image
59 {
60 namespace
61 {
62
63 //! Get a texture based on image type and suggested size.
64 Texture getTexture (const ImageType imageType, const tcu::IVec3& size)
65 {
66         switch (imageType)
67         {
68                 case IMAGE_TYPE_1D:
69                 case IMAGE_TYPE_BUFFER:
70                         return Texture(imageType, tcu::IVec3(size.x(), 1, 1), 1);
71
72                 case IMAGE_TYPE_1D_ARRAY:
73                         return Texture(imageType, tcu::IVec3(size.x(), 1, 1), size.y());
74
75                 case IMAGE_TYPE_2D:
76                         return Texture(imageType, tcu::IVec3(size.x(), size.y(), 1), 1);
77
78                 case IMAGE_TYPE_2D_ARRAY:
79                         return Texture(imageType, tcu::IVec3(size.x(), size.y(), 1), size.z());
80
81                 case IMAGE_TYPE_CUBE:
82                         return Texture(imageType, tcu::IVec3(size.x(), size.x(), 1), 6);
83
84                 case IMAGE_TYPE_CUBE_ARRAY:
85                         return Texture(imageType, tcu::IVec3(size.x(), size.x(), 1), 2*6);
86
87                 case IMAGE_TYPE_3D:
88                         return Texture(imageType, size, 1);
89
90                 default:
91                         DE_FATAL("Internal error");
92                         return Texture(IMAGE_TYPE_LAST, tcu::IVec3(), 0);
93         }
94 }
95
96 inline VkImageCreateInfo makeImageCreateInfo (const Texture& texture, const VkFormat format)
97 {
98         const VkImageCreateInfo imageParams =
99         {
100                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                                            // VkStructureType                      sType;
101                 DE_NULL,                                                                                                                                                        // const void*                          pNext;
102                 (isCube(texture) ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0u),       // VkImageCreateFlags           flags;
103                 mapImageType(texture.type()),                                                                                                           // VkImageType                          imageType;
104                 format,                                                                                                                                                         // VkFormat                                     format;
105                 makeExtent3D(texture.layerSize()),                                                                                                      // VkExtent3D                           extent;
106                 1u,                                                                                                                                                                     // deUint32                                     mipLevels;
107                 (deUint32)texture.numLayers(),                                                                                                          // deUint32                                     arrayLayers;
108                 VK_SAMPLE_COUNT_1_BIT,                                                                                                                          // VkSampleCountFlagBits        samples;
109                 VK_IMAGE_TILING_OPTIMAL,                                                                                                                        // VkImageTiling                        tiling;
110                 VK_IMAGE_USAGE_STORAGE_BIT,                                                                                                                     // VkImageUsageFlags            usage;
111                 VK_SHARING_MODE_EXCLUSIVE,                                                                                                                      // VkSharingMode                        sharingMode;
112                 0u,                                                                                                                                                                     // deUint32                                     queueFamilyIndexCount;
113                 DE_NULL,                                                                                                                                                        // const deUint32*                      pQueueFamilyIndices;
114                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                                      // VkImageLayout                        initialLayout;
115         };
116         return imageParams;
117 }
118
119 //! Interpret the memory as IVec3
120 inline tcu::IVec3 readIVec3 (const void* const data)
121 {
122         const int* const p = reinterpret_cast<const int* const>(data);
123         return tcu::IVec3(p[0], p[1], p[2]);
124 }
125
126 tcu::IVec3 getExpectedImageSizeResult (const Texture& texture)
127 {
128         // GLSL imageSize() function returns:
129         // z = 0 for cubes
130         // z = N for cube arrays, where N is the number of cubes
131         // y or z = L where L is the number of layers for other array types (e.g. 1D array, 2D array)
132         // z = D where D is the depth of 3d image
133
134         const tcu::IVec3 size = texture.size();
135         const int numCubeFaces = 6;
136
137         switch (texture.type())
138         {
139                 case IMAGE_TYPE_1D:
140                 case IMAGE_TYPE_BUFFER:
141                         return tcu::IVec3(size.x(), 0, 0);
142
143                 case IMAGE_TYPE_1D_ARRAY:
144                 case IMAGE_TYPE_2D:
145                 case IMAGE_TYPE_CUBE:
146                         return tcu::IVec3(size.x(), size.y(), 0);
147
148                 case IMAGE_TYPE_2D_ARRAY:
149                 case IMAGE_TYPE_3D:
150                         return size;
151
152                 case IMAGE_TYPE_CUBE_ARRAY:
153                         return tcu::IVec3(size.x(), size.y(), size.z() / numCubeFaces);
154
155                 default:
156                         DE_FATAL("Internal error");
157                         return tcu::IVec3();
158         }
159 }
160
161 class SizeTest : public TestCase
162 {
163 public:
164         enum TestFlags
165         {
166                 FLAG_READONLY_IMAGE             = 1u << 0,
167                 FLAG_WRITEONLY_IMAGE    = 1u << 1,
168         };
169
170                                                 SizeTest                        (tcu::TestContext&      testCtx,
171                                                                                          const std::string&     name,
172                                                                                          const std::string&     description,
173                                                                                          const Texture&         texture,
174                                                                                          const VkFormat         format,
175                                                                                          const deUint32         flags = 0);
176
177         void                            initPrograms            (SourceCollections& programCollection) const;
178         TestInstance*           createInstance          (Context&                       context) const;
179
180 private:
181         const Texture           m_texture;
182         const VkFormat          m_format;
183         const bool                      m_useReadonly;
184         const bool                      m_useWriteonly;
185 };
186
187 SizeTest::SizeTest (tcu::TestContext&           testCtx,
188                                         const std::string&              name,
189                                         const std::string&              description,
190                                         const Texture&                  texture,
191                                         const VkFormat                  format,
192                                         const deUint32                  flags)
193         : TestCase                      (testCtx, name, description)
194         , m_texture                     (texture)
195         , m_format                      (format)
196         , m_useReadonly         ((flags & FLAG_READONLY_IMAGE) != 0)
197         , m_useWriteonly        ((flags & FLAG_WRITEONLY_IMAGE) != 0)
198 {
199         // We expect at least one flag to be set.
200         DE_ASSERT(m_useReadonly || m_useWriteonly);
201 }
202
203 void SizeTest::initPrograms (SourceCollections& programCollection) const
204 {
205         const std::string formatQualifierStr = getShaderImageFormatQualifier(mapVkFormat(m_format));
206         const std::string imageTypeStr = getShaderImageType(mapVkFormat(m_format), m_texture.type());
207         const int dimension = m_texture.dimension();
208
209         std::ostringstream accessQualifier;
210         if (m_useReadonly)
211                 accessQualifier << " readonly";
212         if (m_useWriteonly)
213                 accessQualifier << " writeonly";
214
215         std::ostringstream src;
216         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
217                 << "\n"
218                 << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
219                 << "layout (binding = 0, " << formatQualifierStr << ")" << accessQualifier.str() << " uniform highp " << imageTypeStr << " u_image;\n"
220                 << "layout (binding = 1) writeonly buffer Output {\n"
221                 << "    ivec3 size;\n"
222                 << "} sb_out;\n"
223                 << "\n"
224                 << "void main (void)\n"
225                 << "{\n"
226                 << (dimension == 1 ?
227                         "    sb_out.size = ivec3(imageSize(u_image), 0, 0);\n"
228                         : dimension == 2 || m_texture.type() == IMAGE_TYPE_CUBE ?               // cubes return ivec2
229                         "    sb_out.size = ivec3(imageSize(u_image), 0);\n"
230                         : dimension == 3 ?                                                                                              // cube arrays return ivec3
231                         "    sb_out.size = imageSize(u_image);\n"
232                         : "")
233                 << "}\n";
234
235         programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
236 }
237
238 //! Build a case name, e.g. "readonly_writeonly_32x32"
239 std::string getCaseName (const Texture& texture, const deUint32 flags)
240 {
241         std::ostringstream str;
242         str << ((flags & SizeTest::FLAG_READONLY_IMAGE) != 0 ? "readonly_" : "")
243                 << ((flags & SizeTest::FLAG_WRITEONLY_IMAGE) != 0 ? "writeonly_" : "");
244
245         const int numComponents = texture.dimension();
246         for (int i = 0; i < numComponents; ++i)
247                 str << (i == 0 ? "" : "x") << texture.size()[i];
248
249         return str.str();
250 }
251
252 //! Base test instance for image and buffer tests
253 class SizeTestInstance : public TestInstance
254 {
255 public:
256                                                                         SizeTestInstance                        (Context&                               context,
257                                                                                                                                  const Texture&                 texture,
258                                                                                                                                  const VkFormat                 format);
259
260         tcu::TestStatus                 iterate                                         (void);
261
262         virtual                                                 ~SizeTestInstance                       (void) {}
263
264 protected:
265         virtual VkDescriptorSetLayout   prepareDescriptors                      (void) = 0;
266         virtual VkDescriptorSet         getDescriptorSet                        (void) const = 0;
267         virtual void                                    commandBeforeCompute            (const VkCommandBuffer  cmdBuffer) = 0;
268
269         const Texture                                   m_texture;
270         const VkFormat                                  m_format;
271         const VkDeviceSize                              m_resultBufferSizeBytes;
272         de::MovePtr<Buffer>                             m_resultBuffer;                         //!< Shader writes the output here.
273 };
274
275 SizeTestInstance::SizeTestInstance (Context& context, const Texture& texture, const VkFormat format)
276         : TestInstance                          (context)
277         , m_texture                                     (texture)
278         , m_format                                      (format)
279         , m_resultBufferSizeBytes       (3 * sizeof(deUint32))  // ivec3 in shader
280 {
281         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
282         const VkDevice                  device          = m_context.getDevice();
283         Allocator&                              allocator       = m_context.getDefaultAllocator();
284
285         // Create an SSBO for shader output.
286
287         m_resultBuffer = de::MovePtr<Buffer>(new Buffer(
288                 vk, device, allocator,
289                 makeBufferCreateInfo(m_resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
290                 MemoryRequirement::HostVisible));
291 }
292
293 tcu::TestStatus SizeTestInstance::iterate (void)
294 {
295         const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
296         const VkDevice                  device                          = m_context.getDevice();
297         const VkQueue                   queue                           = m_context.getUniversalQueue();
298         const deUint32                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
299
300         // Create memory barriers.
301
302         const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier(
303                 VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
304                 m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
305
306         const void* const barriersAfter[] = { &shaderWriteBarrier };
307
308         // Create the pipeline.
309
310         const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
311
312         const VkDescriptorSetLayout descriptorSetLayout = prepareDescriptors();
313         const VkDescriptorSet descriptorSet = getDescriptorSet();
314
315         const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, descriptorSetLayout));
316         const Unique<VkPipeline> pipeline(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
317
318         const Unique<VkCommandPool> cmdPool(makeCommandPool(vk, device, queueFamilyIndex));
319         const Unique<VkCommandBuffer> cmdBuffer(makeCommandBuffer(vk, device, *cmdPool));
320
321         beginCommandBuffer(vk, *cmdBuffer);
322
323         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
324         vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
325
326         commandBeforeCompute(*cmdBuffer);
327         vk.cmdDispatch(*cmdBuffer, 1, 1, 1);
328         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, DE_FALSE, DE_LENGTH_OF_ARRAY(barriersAfter), barriersAfter);
329
330         endCommandBuffer(vk, *cmdBuffer);
331
332         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
333
334         // Compare the result.
335
336         const Allocation& bufferAlloc = m_resultBuffer->getAllocation();
337         invalidateMappedMemoryRange(vk, device, bufferAlloc.getMemory(), bufferAlloc.getOffset(), m_resultBufferSizeBytes);
338
339         const tcu::IVec3 resultSize = readIVec3(bufferAlloc.getHostPtr());
340         const tcu::IVec3 expectedSize = getExpectedImageSizeResult(m_texture);
341
342         if (resultSize != expectedSize)
343                 return tcu::TestStatus::fail("Incorrect imageSize(): expected " + de::toString(expectedSize) + " but got " + de::toString(resultSize));
344         else
345                 return tcu::TestStatus::pass("Passed");
346 }
347
348 class ImageSizeTestInstance : public SizeTestInstance
349 {
350 public:
351                                                                         ImageSizeTestInstance           (Context&                               context,
352                                                                                                                                  const Texture&                 texture,
353                                                                                                                                  const VkFormat                 format);
354
355 protected:
356         VkDescriptorSetLayout                   prepareDescriptors                      (void);
357         void                                                    commandBeforeCompute            (const VkCommandBuffer  cmdBuffer);
358
359         VkDescriptorSet                 getDescriptorSet                        (void) const { return *m_descriptorSet; }
360
361         de::MovePtr<Image>                              m_image;
362         Move<VkImageView>                               m_imageView;
363         Move<VkDescriptorSetLayout>             m_descriptorSetLayout;
364         Move<VkDescriptorPool>                  m_descriptorPool;
365         Move<VkDescriptorSet>                   m_descriptorSet;
366 };
367
368 ImageSizeTestInstance::ImageSizeTestInstance (Context& context, const Texture& texture, const VkFormat format)
369         : SizeTestInstance      (context, texture, format)
370 {
371         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
372         const VkDevice                  device          = m_context.getDevice();
373         Allocator&                              allocator       = m_context.getDefaultAllocator();
374
375         // Create an image. Its data be uninitialized, as we're not reading from it.
376
377         m_image = de::MovePtr<Image>(new Image(vk, device, allocator, makeImageCreateInfo(m_texture, m_format), MemoryRequirement::Any));
378
379         const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_texture.numLayers());
380         m_imageView = makeImageView(vk, device, m_image->get(), mapImageViewType(m_texture.type()), m_format, subresourceRange);
381 }
382
383 VkDescriptorSetLayout ImageSizeTestInstance::prepareDescriptors (void)
384 {
385         const DeviceInterface&  vk              = m_context.getDeviceInterface();
386         const VkDevice                  device  = m_context.getDevice();
387
388         m_descriptorSetLayout = DescriptorSetLayoutBuilder()
389                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
390                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
391                 .build(vk, device);
392
393         m_descriptorPool = DescriptorPoolBuilder()
394                 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
395                 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
396                 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
397
398         m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
399
400         const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, *m_imageView, VK_IMAGE_LAYOUT_GENERAL);
401         const VkDescriptorBufferInfo descriptorBufferInfo = makeDescriptorBufferInfo(m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
402
403         DescriptorSetUpdateBuilder()
404                 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
405                 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo)
406                 .update(vk, device);
407
408         return *m_descriptorSetLayout;
409 }
410
411 void ImageSizeTestInstance::commandBeforeCompute (const VkCommandBuffer cmdBuffer)
412 {
413         const DeviceInterface& vk = m_context.getDeviceInterface();
414
415         const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_texture.numLayers());
416         const VkImageMemoryBarrier barrierSetImageLayout = makeImageMemoryBarrier(
417                 0u, 0u,
418                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
419                 m_image->get(), subresourceRange);
420
421         const void* const barriers[] = { &barrierSetImageLayout };
422
423         vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, DE_FALSE, DE_LENGTH_OF_ARRAY(barriers), barriers);
424 }
425
426 class BufferSizeTestInstance : public SizeTestInstance
427 {
428 public:
429                                                                         BufferSizeTestInstance          (Context&                               context,
430                                                                                                                                  const Texture&                 texture,
431                                                                                                                                  const VkFormat                 format);
432
433 protected:
434         VkDescriptorSetLayout                   prepareDescriptors                      (void);
435
436         void                                                    commandBeforeCompute            (const VkCommandBuffer) {}
437         VkDescriptorSet                                 getDescriptorSet                        (void) const { return *m_descriptorSet; }
438
439         de::MovePtr<Buffer>                             m_imageBuffer;
440         Move<VkBufferView>                              m_bufferView;
441         Move<VkDescriptorSetLayout>             m_descriptorSetLayout;
442         Move<VkDescriptorPool>                  m_descriptorPool;
443         Move<VkDescriptorSet>                   m_descriptorSet;
444 };
445
446 BufferSizeTestInstance::BufferSizeTestInstance (Context& context, const Texture& texture, const VkFormat format)
447         : SizeTestInstance      (context, texture, format)
448 {
449         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
450         const VkDevice                  device          = m_context.getDevice();
451         Allocator&                              allocator       = m_context.getDefaultAllocator();
452
453         // Create a texel storage buffer. Its data be uninitialized, as we're not reading from it.
454
455         const VkDeviceSize imageSizeBytes = getImageSizeBytes(m_texture.size(), m_format);
456         m_imageBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
457                 makeBufferCreateInfo(imageSizeBytes, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT), MemoryRequirement::Any));
458
459         m_bufferView = makeBufferView(vk, device, m_imageBuffer->get(), m_format, 0ull, imageSizeBytes);
460 }
461
462 VkDescriptorSetLayout BufferSizeTestInstance::prepareDescriptors (void)
463 {
464         const DeviceInterface&  vk              = m_context.getDeviceInterface();
465         const VkDevice                  device  = m_context.getDevice();
466
467         m_descriptorSetLayout = DescriptorSetLayoutBuilder()
468                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
469                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
470                 .build(vk, device);
471
472         m_descriptorPool = DescriptorPoolBuilder()
473                 .addType(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
474                 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
475                 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
476
477         m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
478
479         const VkDescriptorBufferInfo descriptorBufferInfo = makeDescriptorBufferInfo(m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
480
481         DescriptorSetUpdateBuilder()
482                 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, &m_bufferView.get())
483                 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo)
484                 .update(vk, device);
485
486         return *m_descriptorSetLayout;
487 }
488
489 TestInstance* SizeTest::createInstance (Context& context) const
490 {
491         if (m_texture.type() == IMAGE_TYPE_BUFFER)
492                 return new BufferSizeTestInstance(context, m_texture, m_format);
493         else
494                 return new ImageSizeTestInstance(context, m_texture, m_format);
495 }
496
497 static const ImageType s_imageTypes[] =
498 {
499         IMAGE_TYPE_1D,
500         IMAGE_TYPE_1D_ARRAY,
501         IMAGE_TYPE_2D,
502         IMAGE_TYPE_2D_ARRAY,
503         IMAGE_TYPE_3D,
504         IMAGE_TYPE_CUBE,
505         IMAGE_TYPE_CUBE_ARRAY,
506         IMAGE_TYPE_BUFFER,
507 };
508
509 //! Base sizes used to generate actual image/buffer sizes in the test.
510 static const tcu::IVec3 s_baseImageSizes[] =
511 {
512         tcu::IVec3(32, 32, 32),
513         tcu::IVec3(12, 34, 56),
514         tcu::IVec3(1,   1,  1),
515         tcu::IVec3(7,   1,  1),
516 };
517
518 static const deUint32 s_flags[] =
519 {
520         SizeTest::FLAG_READONLY_IMAGE,
521         SizeTest::FLAG_WRITEONLY_IMAGE,
522         SizeTest::FLAG_READONLY_IMAGE | SizeTest::FLAG_WRITEONLY_IMAGE,
523 };
524
525 } // anonymous ns
526
527 tcu::TestCaseGroup* createImageSizeTests (tcu::TestContext& testCtx)
528 {
529         de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "image_size", "imageSize() cases"));
530
531         const VkFormat format = VK_FORMAT_R32G32B32A32_SFLOAT;
532
533         for (int imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++imageTypeNdx)
534         {
535                 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(s_imageTypes[imageTypeNdx]).c_str(), ""));
536
537                 for (int flagNdx = 0; flagNdx < DE_LENGTH_OF_ARRAY(s_flags); ++flagNdx)
538                 for (int imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(s_baseImageSizes); ++imageSizeNdx)
539                 {
540                         const Texture texture = getTexture(s_imageTypes[imageTypeNdx], s_baseImageSizes[imageSizeNdx]);
541                         imageGroup->addChild(new SizeTest(testCtx, getCaseName(texture, s_flags[flagNdx]), "", texture, format, s_flags[flagNdx]));
542                 }
543
544                 testGroup->addChild(imageGroup.release());
545         }
546         return testGroup.release();
547 }
548
549 } // image
550 } // vkt