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