Merge branch 'vulkan-sc-cts-dev' into 'main'
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineImageTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Imagination Technologies Ltd.
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 Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineImageTests.hpp"
26 #include "vktPipelineImageSamplingInstance.hpp"
27 #include "vktPipelineImageUtil.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktTestCase.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkPrograms.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "deStringUtil.hpp"
34
35 #include <sstream>
36 #include <vector>
37
38 namespace vkt
39 {
40 namespace pipeline
41 {
42
43 using namespace vk;
44 using de::MovePtr;
45
46 namespace
47 {
48
49 class ImageTest : public vkt::TestCase
50 {
51 public:
52                                                         ImageTest                                                       (tcu::TestContext&      testContext,
53                                                                                                                                  const char*                            name,
54                                                                                                                                  const char*                            description,
55                                                                                                                                  AllocationKind                         allocationKind,
56                                                                                                                                  PipelineConstructionType       pipelineConstructionType,
57                                                                                                                                  VkDescriptorType                       samplingType,
58                                                                                                                                  VkImageViewType                        imageViewType,
59                                                                                                                                  VkFormat                                       imageFormat,
60                                                                                                                                  const tcu::IVec3&                      imageSize,
61                                                                                                                                  int                                            imageCount,
62                                                                                                                                  int                                            arraySize);
63
64         ImageSamplingInstanceParams     getImageSamplingInstanceParams  (AllocationKind         allocationKind,
65                                                                                                                                  VkDescriptorType       samplingType,
66                                                                                                                                  VkImageViewType        imageViewType,
67                                                                                                                                  VkFormat                       imageFormat,
68                                                                                                                                  const tcu::IVec3&      imageSize,
69                                                                                                                                  int                            imageCount,
70                                                                                                                                  int                            arraySize) const;
71
72         virtual void                    initPrograms                                            (SourceCollections& sourceCollections) const;
73         virtual void                    checkSupport                                            (Context& context) const;
74         virtual TestInstance*   createInstance                                          (Context& context) const;
75         static std::string              getGlslSamplerType                                      (const tcu::TextureFormat& format, VkImageViewType type);
76         static std::string              getGlslTextureType                                      (const tcu::TextureFormat& format, VkImageViewType type);
77         static std::string              getGlslSamplerDecl                                      (int imageCount);
78         static std::string              getGlslTextureDecl                                      (int imageCount);
79         static std::string              getGlslFragColorDecl                            (int imageCount);
80         static std::string              getGlslSampler                                          (const tcu::TextureFormat&      format,
81                                                                                                                                  VkImageViewType                        type,
82                                                                                                                                  VkDescriptorType                       samplingType,
83                                                                                                                                  int                                            imageCount);
84
85 private:
86         AllocationKind                          m_allocationKind;
87         PipelineConstructionType        m_pipelineConstructionType;
88         VkDescriptorType                        m_samplingType;
89         VkImageViewType                         m_imageViewType;
90         VkFormat                                        m_imageFormat;
91         tcu::IVec3                                      m_imageSize;
92         int                                                     m_imageCount;
93         int                                                     m_arraySize;
94 };
95
96 ImageTest::ImageTest (tcu::TestContext& testContext,
97                                           const char*                           name,
98                                           const char*                           description,
99                                           AllocationKind                        allocationKind,
100                                           PipelineConstructionType      pipelineConstructionType,
101                                           VkDescriptorType                      samplingType,
102                                           VkImageViewType                       imageViewType,
103                                           VkFormat                                      imageFormat,
104                                           const tcu::IVec3&                     imageSize,
105                                           int                                           imageCount,
106                                           int                                           arraySize)
107
108         : vkt::TestCase                                 (testContext, name, description)
109         , m_allocationKind                              (allocationKind)
110         , m_pipelineConstructionType    (pipelineConstructionType)
111         , m_samplingType                                (samplingType)
112         , m_imageViewType                               (imageViewType)
113         , m_imageFormat                                 (imageFormat)
114         , m_imageSize                                   (imageSize)
115         , m_imageCount                                  (imageCount)
116         , m_arraySize                                   (arraySize)
117 {
118 }
119
120 void ImageTest::checkSupport (Context& context) const
121 {
122         // Using a loop to index into an array of images requires shaderSampledImageArrayDynamicIndexing
123         if (m_imageCount > 1)
124                 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING);
125
126         checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
127         checkSupportImageSamplingInstance(context, getImageSamplingInstanceParams(m_allocationKind, m_samplingType, m_imageViewType, m_imageFormat, m_imageSize, m_imageCount, m_arraySize));
128 }
129
130 ImageSamplingInstanceParams ImageTest::getImageSamplingInstanceParams (AllocationKind           allocationKind,
131                                                                                                                                            VkDescriptorType             samplingType,
132                                                                                                                                            VkImageViewType              imageViewType,
133                                                                                                                                            VkFormat                             imageFormat,
134                                                                                                                                            const tcu::IVec3&    imageSize,
135                                                                                                                                            int                                  imageCount,
136                                                                                                                                            int                                  arraySize) const
137 {
138         tcu::UVec2 renderSize;
139
140         if (imageViewType == VK_IMAGE_VIEW_TYPE_1D || imageViewType == VK_IMAGE_VIEW_TYPE_2D)
141         {
142                 renderSize = tcu::UVec2((deUint32)imageSize.x(), (deUint32)imageSize.y());
143         }
144         else
145         {
146                 // Draw a 3x2 grid of texture layers
147                 renderSize = tcu::UVec2((deUint32)imageSize.x() * 3, (deUint32)imageSize.y() * 2);
148         }
149
150         const bool                                              separateStencilUsage    = false;
151         const std::vector<Vertex4Tex4>  vertices                                = createTestQuadMosaic(imageViewType);
152         const VkComponentMapping                componentMapping                = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
153         const VkImageSubresourceRange   subresourceRange                =
154         {
155                 VK_IMAGE_ASPECT_COLOR_BIT,
156                 0u,
157                 (deUint32)deLog2Floor32(deMax32(imageSize.x(), deMax32(imageSize.y(), imageSize.z()))) + 1,
158                 0u,
159                 (deUint32)arraySize,
160         };
161
162         const VkSamplerCreateInfo samplerParams =
163         {
164                 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,                                                          // VkStructureType                      sType;
165                 DE_NULL,                                                                                                                        // const void*                          pNext;
166                 0u,                                                                                                                                     // VkSamplerCreateFlags         flags;
167                 VK_FILTER_NEAREST,                                                                                                      // VkFilter                                     magFilter;
168                 VK_FILTER_NEAREST,                                                                                                      // VkFilter                                     minFilter;
169                 VK_SAMPLER_MIPMAP_MODE_NEAREST,                                                                         // VkSamplerMipmapMode          mipmapMode;
170                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                                                          // VkSamplerAddressMode         addressModeU;
171                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                                                          // VkSamplerAddressMode         addressModeV;
172                 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                                                          // VkSamplerAddressMode         addressModeW;
173                 0.0f,                                                                                                                           // float                                        mipLodBias;
174                 VK_FALSE,                                                                                                                       // VkBool32                                     anisotropyEnable;
175                 1.0f,                                                                                                                           // float                                        maxAnisotropy;
176                 false,                                                                                                                          // VkBool32                                     compareEnable;
177                 VK_COMPARE_OP_NEVER,                                                                                            // VkCompareOp                          compareOp;
178                 0.0f,                                                                                                                           // float                                        minLod;
179                 (float)(subresourceRange.levelCount - 1),                                                       // float                                        maxLod;
180                 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, imageFormat),      // VkBorderColor                        borderColor;
181                 false                                                                                                                           // VkBool32                                     unnormalizedCoordinates;
182         };
183
184         return ImageSamplingInstanceParams(m_pipelineConstructionType, renderSize, imageViewType, imageFormat, imageSize, arraySize, componentMapping, subresourceRange, samplerParams, 0.0f, vertices, separateStencilUsage, samplingType, imageCount, allocationKind);
185 }
186
187 void ImageTest::initPrograms (SourceCollections& sourceCollections) const
188 {
189         std::ostringstream                              vertexSrc;
190         std::ostringstream                              fragmentSrc;
191         const char*                                             texCoordSwizzle = DE_NULL;
192         const tcu::TextureFormat                format                  = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat))
193                                                                                                                                                                                   : mapVkFormat(m_imageFormat);
194
195         tcu::Vec4                                               lookupScale;
196         tcu::Vec4                                               lookupBias;
197
198         getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
199
200         switch (m_imageViewType)
201         {
202                 case VK_IMAGE_VIEW_TYPE_1D:
203                         texCoordSwizzle = "x";
204                         break;
205                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
206                 case VK_IMAGE_VIEW_TYPE_2D:
207                         texCoordSwizzle = "xy";
208                         break;
209                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
210                 case VK_IMAGE_VIEW_TYPE_3D:
211                 case VK_IMAGE_VIEW_TYPE_CUBE:
212                         texCoordSwizzle = "xyz";
213                         break;
214                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
215                         texCoordSwizzle = "xyzw";
216                         break;
217                 default:
218                         DE_ASSERT(false);
219                         break;
220         }
221
222         vertexSrc << "#version 440\n"
223                           << "layout(location = 0) in vec4 position;\n"
224                           << "layout(location = 1) in vec4 texCoords;\n"
225                           << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
226                           << "out gl_PerVertex {\n"
227                           << "  vec4 gl_Position;\n"
228                           << "};\n"
229                           << "void main (void)\n"
230                           << "{\n"
231                           << "  gl_Position = position;\n"
232                           << "  vtxTexCoords = texCoords;\n"
233                           << "}\n";
234
235         fragmentSrc << "#version 440\n";
236         switch (m_samplingType)
237         {
238                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
239                         fragmentSrc
240                                 << "layout(set = 0, binding = 0) uniform highp sampler texSampler;\n"
241                                 << "layout(set = 0, binding = 1) uniform highp " << getGlslTextureType(format, m_imageViewType) << " " << getGlslTextureDecl(m_imageCount) << ";\n";
242                         break;
243                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
244                 default:
245                         fragmentSrc
246                                 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " " << getGlslSamplerDecl(m_imageCount) << ";\n";
247         }
248         fragmentSrc << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
249                                 << "layout(location = 0) out highp vec4 " << getGlslFragColorDecl(m_imageCount) << ";\n"
250                                 << "void main (void)\n"
251                                 << "{\n";
252         if (m_imageCount > 1)
253                 fragmentSrc
254                                 << "    for (uint i = 0; i < " << m_imageCount << "; ++i)\n"
255                                 << "            fragColors[i] = (texture(" << getGlslSampler(format, m_imageViewType, m_samplingType, m_imageCount) << ", vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << lookupScale << ") + vec4" << lookupBias << "; \n";
256         else
257                 fragmentSrc
258                                 << "    fragColor = (texture(" << getGlslSampler(format, m_imageViewType, m_samplingType, m_imageCount) << ", vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << lookupScale << ") + vec4" << lookupBias << "; \n";
259         fragmentSrc << "}\n";
260
261         sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
262         sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
263 }
264
265 TestInstance* ImageTest::createInstance (Context& context) const
266 {
267         return new ImageSamplingInstance(context, getImageSamplingInstanceParams(m_allocationKind, m_samplingType, m_imageViewType, m_imageFormat, m_imageSize, m_imageCount, m_arraySize));
268 }
269
270 std::string ImageTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
271 {
272         std::ostringstream samplerType;
273
274         if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
275                 samplerType << "u";
276         else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
277                 samplerType << "i";
278
279         switch (type)
280         {
281                 case VK_IMAGE_VIEW_TYPE_1D:
282                         samplerType << "sampler1D";
283                         break;
284
285                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
286                         samplerType << "sampler1DArray";
287                         break;
288
289                 case VK_IMAGE_VIEW_TYPE_2D:
290                         samplerType << "sampler2D";
291                         break;
292
293                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
294                         samplerType << "sampler2DArray";
295                         break;
296
297                 case VK_IMAGE_VIEW_TYPE_3D:
298                         samplerType << "sampler3D";
299                         break;
300
301                 case VK_IMAGE_VIEW_TYPE_CUBE:
302                         samplerType << "samplerCube";
303                         break;
304
305                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
306                         samplerType << "samplerCubeArray";
307                         break;
308
309                 default:
310                         DE_FATAL("Unknown image view type");
311                         break;
312         }
313
314         return samplerType.str();
315 }
316
317 std::string ImageTest::getGlslTextureType (const tcu::TextureFormat& format, VkImageViewType type)
318 {
319         std::ostringstream textureType;
320
321         if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
322                 textureType << "u";
323         else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
324                 textureType << "i";
325
326         switch (type)
327         {
328                 case VK_IMAGE_VIEW_TYPE_1D:
329                         textureType << "texture1D";
330                         break;
331
332                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
333                         textureType << "texture1DArray";
334                         break;
335
336                 case VK_IMAGE_VIEW_TYPE_2D:
337                         textureType << "texture2D";
338                         break;
339
340                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
341                         textureType << "texture2DArray";
342                         break;
343
344                 case VK_IMAGE_VIEW_TYPE_3D:
345                         textureType << "texture3D";
346                         break;
347
348                 case VK_IMAGE_VIEW_TYPE_CUBE:
349                         textureType << "textureCube";
350                         break;
351
352                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
353                         textureType << "textureCubeArray";
354                         break;
355
356                 default:
357                         DE_FATAL("Unknown image view type");
358         }
359
360         return textureType.str();
361 }
362
363 std::string ImageTest::getGlslSamplerDecl (int imageCount)
364 {
365         std::ostringstream samplerArray;
366         samplerArray << "texSamplers[" << imageCount << "]";
367
368         return imageCount > 1 ? samplerArray.str() : "texSampler";
369 }
370
371 std::string ImageTest::getGlslTextureDecl (int imageCount)
372 {
373         std::ostringstream textureArray;
374         textureArray << "texImages[" << imageCount << "]";
375
376         return imageCount > 1 ? textureArray.str() : "texImage";
377 }
378
379 std::string ImageTest::getGlslFragColorDecl (int imageCount)
380 {
381         std::ostringstream samplerArray;
382         samplerArray << "fragColors[" << imageCount << "]";
383
384         return imageCount > 1 ? samplerArray.str() : "fragColor";
385 }
386
387 std::string ImageTest::getGlslSampler (const tcu::TextureFormat& format, VkImageViewType type, VkDescriptorType samplingType, int imageCount)
388 {
389         std::string texSampler  = imageCount > 1 ? "texSamplers[i]" : "texSampler";
390         std::string texImage    = imageCount > 1 ? "texImages[i]" : "texImage";
391
392         switch (samplingType)
393         {
394                 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
395                         return getGlslSamplerType(format, type) + "(" + texImage + ", texSampler)";
396                 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
397                 default:
398                         return texSampler;
399         }
400 }
401
402 std::string getFormatCaseName (const VkFormat format)
403 {
404         const std::string       fullName        = getFormatName(format);
405
406         DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
407
408         return de::toLower(fullName.substr(10));
409 }
410
411 std::string getSizeName (VkImageViewType viewType, const tcu::IVec3& size, int arraySize)
412 {
413         std::ostringstream      caseName;
414
415         switch (viewType)
416         {
417                 case VK_IMAGE_VIEW_TYPE_1D:
418                 case VK_IMAGE_VIEW_TYPE_2D:
419                 case VK_IMAGE_VIEW_TYPE_CUBE:
420                         caseName << size.x() << "x" << size.y();
421                         break;
422
423                 case VK_IMAGE_VIEW_TYPE_3D:
424                         caseName << size.x() << "x" << size.y() << "x" << size.z();
425                         break;
426
427                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
428                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
429                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
430                         caseName << size.x() << "x" << size.y() << "_array_of_" << arraySize;
431                         break;
432
433                 default:
434                         DE_ASSERT(false);
435                         break;
436         }
437
438         return caseName.str();
439 }
440
441 de::MovePtr<tcu::TestCaseGroup> createImageSizeTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType, VkImageViewType imageViewType, VkFormat imageFormat, int imageCount)
442 {
443         using tcu::IVec3;
444
445         std::vector<IVec3>                                      imageSizes;
446         std::vector<int>                                        arraySizes;
447         de::MovePtr<tcu::TestCaseGroup>         imageSizeTests  (new tcu::TestCaseGroup(testCtx, "size", ""));
448
449         // Select image imageSizes
450         switch (imageViewType)
451         {
452                 case VK_IMAGE_VIEW_TYPE_1D:
453                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
454                         // POT
455                         if (imageCount == 1)
456                         {
457                                 imageSizes.push_back(IVec3(1, 1, 1));
458                                 imageSizes.push_back(IVec3(2, 1, 1));
459                                 imageSizes.push_back(IVec3(32, 1, 1));
460                                 imageSizes.push_back(IVec3(128, 1, 1));
461                         }
462                         imageSizes.push_back(IVec3(512, 1, 1));
463
464                         // NPOT
465                         if (imageCount == 1)
466                         {
467                                 imageSizes.push_back(IVec3(3, 1, 1));
468                                 imageSizes.push_back(IVec3(13, 1, 1));
469                                 imageSizes.push_back(IVec3(127, 1, 1));
470                         }
471                         imageSizes.push_back(IVec3(443, 1, 1));
472                         break;
473
474                 case VK_IMAGE_VIEW_TYPE_2D:
475                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
476                         if (imageCount == 1)
477                         {
478                                 // POT
479                                 imageSizes.push_back(IVec3(1, 1, 1));
480                                 imageSizes.push_back(IVec3(2, 2, 1));
481                                 imageSizes.push_back(IVec3(32, 32, 1));
482
483                                 // NPOT
484                                 imageSizes.push_back(IVec3(3, 3, 1));
485                                 imageSizes.push_back(IVec3(13, 13, 1));
486                         }
487
488                         // POT rectangular
489                         if (imageCount == 1)
490                                 imageSizes.push_back(IVec3(8, 16, 1));
491                         imageSizes.push_back(IVec3(32, 16, 1));
492
493                         // NPOT rectangular
494                         imageSizes.push_back(IVec3(13, 23, 1));
495                         if (imageCount == 1)
496                                 imageSizes.push_back(IVec3(23, 8, 1));
497                         break;
498
499                 case VK_IMAGE_VIEW_TYPE_3D:
500                         // POT cube
501                         if (imageCount == 1)
502                         {
503                                 imageSizes.push_back(IVec3(1, 1, 1));
504                                 imageSizes.push_back(IVec3(2, 2, 2));
505                         }
506                         imageSizes.push_back(IVec3(16, 16, 16));
507
508                         // NPOT cube
509                         if (imageCount == 1)
510                         {
511                                 imageSizes.push_back(IVec3(3, 3, 3));
512                                 imageSizes.push_back(IVec3(5, 5, 5));
513                         }
514                         imageSizes.push_back(IVec3(11, 11, 11));
515
516                         // POT non-cube
517                         if (imageCount == 1)
518                                 imageSizes.push_back(IVec3(32, 16, 8));
519                         imageSizes.push_back(IVec3(8, 16, 32));
520
521                         // NPOT non-cube
522                         imageSizes.push_back(IVec3(17, 11, 5));
523                         if (imageCount == 1)
524                                 imageSizes.push_back(IVec3(5, 11, 17));
525                         break;
526
527                 case VK_IMAGE_VIEW_TYPE_CUBE:
528                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
529                         // POT
530                         imageSizes.push_back(IVec3(32, 32, 1));
531
532                         // NPOT
533                         imageSizes.push_back(IVec3(13, 13, 1));
534                         break;
535
536                 default:
537                         DE_ASSERT(false);
538                         break;
539         }
540
541         // Select array sizes
542         switch (imageViewType)
543         {
544                 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
545                 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
546                         if (imageCount == 1)
547                                 arraySizes.push_back(3);
548                         arraySizes.push_back(6);
549                         break;
550
551                 case VK_IMAGE_VIEW_TYPE_CUBE:
552                         arraySizes.push_back(6);
553                         break;
554
555                 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
556                         if (imageCount == 1)
557                                 arraySizes.push_back(6);
558                         arraySizes.push_back(6 * 6);
559                         break;
560
561                 default:
562                         arraySizes.push_back(1);
563                         break;
564         }
565
566         for (size_t sizeNdx = 0; sizeNdx < imageSizes.size(); sizeNdx++)
567         {
568                 for (size_t arraySizeNdx = 0; arraySizeNdx < arraySizes.size(); arraySizeNdx++)
569                 {
570                         imageSizeTests->addChild(new ImageTest(testCtx,
571                                                                                                    getSizeName(imageViewType, imageSizes[sizeNdx], arraySizes[arraySizeNdx]).c_str(),
572                                                                                                    "",
573                                                                                                    allocationKind,
574                                                                                                    pipelineConstructionType,
575                                                                                                    samplingType,
576                                                                                                    imageViewType,
577                                                                                                    imageFormat,
578                                                                                                    imageSizes[sizeNdx],
579                                                                                                    imageCount,
580                                                                                                    arraySizes[arraySizeNdx]));
581                 }
582         }
583
584         return imageSizeTests;
585 }
586
587 void createImageCountTests (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType, VkImageViewType imageViewType, VkFormat imageFormat)
588 {
589         const int               coreImageCounts[]                                       = { 1, 4, 8 };
590         const int               dedicatedAllocationImageCounts[]        = { 1 };
591         const int*              imageCounts                                                     = (allocationKind == ALLOCATION_KIND_DEDICATED)
592                                                                                                                   ? dedicatedAllocationImageCounts
593                                                                                                                   : coreImageCounts;
594         const size_t    imageCountsLength                                       = (allocationKind == ALLOCATION_KIND_DEDICATED)
595                                                                                                                   ? DE_LENGTH_OF_ARRAY(dedicatedAllocationImageCounts)
596                                                                                                                   : DE_LENGTH_OF_ARRAY(coreImageCounts);
597
598         for (size_t countNdx = 0; countNdx < imageCountsLength; countNdx++)
599         {
600                 std::ostringstream      caseName;
601                 caseName << "count_" << imageCounts[countNdx];
602                 de::MovePtr<tcu::TestCaseGroup> countGroup(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
603                 de::MovePtr<tcu::TestCaseGroup> sizeTests = createImageSizeTests(testCtx, allocationKind, pipelineConstructionType, samplingType, imageViewType, imageFormat, imageCounts[countNdx]);
604
605                 countGroup->addChild(sizeTests.release());
606                 parentGroup->addChild(countGroup.release());
607         }
608 }
609
610 de::MovePtr<tcu::TestCaseGroup> createImageFormatTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType, VkImageViewType imageViewType)
611 {
612         // All supported dEQP formats that are not intended for depth or stencil.
613         const VkFormat coreFormats[]                                    =
614         {
615                 VK_FORMAT_R4G4_UNORM_PACK8,
616                 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
617                 VK_FORMAT_R5G6B5_UNORM_PACK16,
618                 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
619                 VK_FORMAT_R8_UNORM,
620                 VK_FORMAT_R8_SNORM,
621                 VK_FORMAT_R8_USCALED,
622                 VK_FORMAT_R8_SSCALED,
623                 VK_FORMAT_R8_UINT,
624                 VK_FORMAT_R8_SINT,
625                 VK_FORMAT_R8_SRGB,
626                 VK_FORMAT_R8G8_UNORM,
627                 VK_FORMAT_R8G8_SNORM,
628                 VK_FORMAT_R8G8_USCALED,
629                 VK_FORMAT_R8G8_SSCALED,
630                 VK_FORMAT_R8G8_UINT,
631                 VK_FORMAT_R8G8_SINT,
632                 VK_FORMAT_R8G8_SRGB,
633                 VK_FORMAT_R8G8B8_UNORM,
634                 VK_FORMAT_R8G8B8_SNORM,
635                 VK_FORMAT_R8G8B8_USCALED,
636                 VK_FORMAT_R8G8B8_SSCALED,
637                 VK_FORMAT_R8G8B8_UINT,
638                 VK_FORMAT_R8G8B8_SINT,
639                 VK_FORMAT_R8G8B8_SRGB,
640                 VK_FORMAT_R8G8B8A8_UNORM,
641                 VK_FORMAT_R8G8B8A8_SNORM,
642                 VK_FORMAT_R8G8B8A8_USCALED,
643                 VK_FORMAT_R8G8B8A8_SSCALED,
644                 VK_FORMAT_R8G8B8A8_UINT,
645                 VK_FORMAT_R8G8B8A8_SINT,
646                 VK_FORMAT_R8G8B8A8_SRGB,
647                 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
648                 VK_FORMAT_A2R10G10B10_UINT_PACK32,
649                 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
650                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
651                 VK_FORMAT_A2B10G10R10_UINT_PACK32,
652                 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
653                 VK_FORMAT_R16_UNORM,
654                 VK_FORMAT_R16_SNORM,
655                 VK_FORMAT_R16_USCALED,
656                 VK_FORMAT_R16_SSCALED,
657                 VK_FORMAT_R16_UINT,
658                 VK_FORMAT_R16_SINT,
659                 VK_FORMAT_R16_SFLOAT,
660                 VK_FORMAT_R16G16_UNORM,
661                 VK_FORMAT_R16G16_SNORM,
662                 VK_FORMAT_R16G16_USCALED,
663                 VK_FORMAT_R16G16_SSCALED,
664                 VK_FORMAT_R16G16_UINT,
665                 VK_FORMAT_R16G16_SINT,
666                 VK_FORMAT_R16G16_SFLOAT,
667                 VK_FORMAT_R16G16B16_UNORM,
668                 VK_FORMAT_R16G16B16_SNORM,
669                 VK_FORMAT_R16G16B16_USCALED,
670                 VK_FORMAT_R16G16B16_SSCALED,
671                 VK_FORMAT_R16G16B16_UINT,
672                 VK_FORMAT_R16G16B16_SINT,
673                 VK_FORMAT_R16G16B16_SFLOAT,
674                 VK_FORMAT_R16G16B16A16_UNORM,
675                 VK_FORMAT_R16G16B16A16_SNORM,
676                 VK_FORMAT_R16G16B16A16_USCALED,
677                 VK_FORMAT_R16G16B16A16_SSCALED,
678                 VK_FORMAT_R16G16B16A16_UINT,
679                 VK_FORMAT_R16G16B16A16_SINT,
680                 VK_FORMAT_R16G16B16A16_SFLOAT,
681                 VK_FORMAT_R32_UINT,
682                 VK_FORMAT_R32_SINT,
683                 VK_FORMAT_R32_SFLOAT,
684                 VK_FORMAT_R32G32_UINT,
685                 VK_FORMAT_R32G32_SINT,
686                 VK_FORMAT_R32G32_SFLOAT,
687                 VK_FORMAT_R32G32B32_UINT,
688                 VK_FORMAT_R32G32B32_SINT,
689                 VK_FORMAT_R32G32B32_SFLOAT,
690                 VK_FORMAT_R32G32B32A32_UINT,
691                 VK_FORMAT_R32G32B32A32_SINT,
692                 VK_FORMAT_R32G32B32A32_SFLOAT,
693                 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
694                 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
695                 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
696                 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
697                 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
698                 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
699
700                 // Compressed formats
701                 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
702                 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
703                 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
704                 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
705                 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
706                 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
707                 VK_FORMAT_EAC_R11_UNORM_BLOCK,
708                 VK_FORMAT_EAC_R11_SNORM_BLOCK,
709                 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
710                 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
711                 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
712                 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
713                 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
714                 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
715                 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
716                 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
717                 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
718                 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
719                 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
720                 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
721                 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
722                 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
723                 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
724                 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
725                 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
726                 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
727                 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
728                 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
729                 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
730                 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
731                 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
732                 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
733                 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
734                 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
735                 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
736                 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
737                 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
738                 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
739         };
740         // Formats to test with dedicated allocation
741         const VkFormat  dedicatedAllocationFormats[]    =
742         {
743                 VK_FORMAT_R8G8B8A8_UNORM,
744                 VK_FORMAT_R16_SFLOAT,
745         };
746         const VkFormat* formats                                                 = (allocationKind == ALLOCATION_KIND_DEDICATED)
747                                                                                                           ? dedicatedAllocationFormats
748                                                                                                           : coreFormats;
749         const size_t    formatsLength                                   = (allocationKind == ALLOCATION_KIND_DEDICATED)
750                                                                                                           ? DE_LENGTH_OF_ARRAY(dedicatedAllocationFormats)
751                                                                                                           : DE_LENGTH_OF_ARRAY(coreFormats);
752
753         de::MovePtr<tcu::TestCaseGroup> imageFormatTests(new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
754
755         for (size_t formatNdx = 0; formatNdx < formatsLength; formatNdx++)
756         {
757                 const VkFormat  format = formats[formatNdx];
758
759                 if (isCompressedFormat(format))
760                 {
761                         // Do not use compressed formats with 1D and 1D array textures.
762                         if (imageViewType == VK_IMAGE_VIEW_TYPE_1D || imageViewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
763                                 break;
764                 }
765
766                 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx,
767                         getFormatCaseName(format).c_str(),
768                         (std::string("Samples a texture of format ") + getFormatName(format)).c_str()));
769                 createImageCountTests(formatGroup.get(), testCtx, allocationKind, pipelineConstructionType, samplingType, imageViewType, format);
770
771                 imageFormatTests->addChild(formatGroup.release());
772         }
773
774         return imageFormatTests;
775 }
776
777 de::MovePtr<tcu::TestCaseGroup> createImageViewTypeTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType)
778 {
779         const struct
780         {
781                 VkImageViewType         type;
782                 const char*                     name;
783         }
784         imageViewTypes[] =
785         {
786                 { VK_IMAGE_VIEW_TYPE_1D,                        "1d" },
787                 { VK_IMAGE_VIEW_TYPE_1D_ARRAY,          "1d_array" },
788                 { VK_IMAGE_VIEW_TYPE_2D,                        "2d" },
789                 { VK_IMAGE_VIEW_TYPE_2D_ARRAY,          "2d_array" },
790                 { VK_IMAGE_VIEW_TYPE_3D,                        "3d" },
791                 { VK_IMAGE_VIEW_TYPE_CUBE,                      "cube" },
792                 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,        "cube_array" }
793         };
794
795         de::MovePtr<tcu::TestCaseGroup> imageViewTypeTests(new tcu::TestCaseGroup(testCtx, "view_type", ""));
796
797         for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
798         {
799                 const VkImageViewType                   viewType = imageViewTypes[viewTypeNdx].type;
800                 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup(new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
801                 de::MovePtr<tcu::TestCaseGroup> formatTests = createImageFormatTests(testCtx, allocationKind, pipelineConstructionType, samplingType, viewType);
802
803                 viewTypeGroup->addChild(formatTests.release());
804                 imageViewTypeTests->addChild(viewTypeGroup.release());
805         }
806
807         return imageViewTypeTests;
808 }
809
810 de::MovePtr<tcu::TestCaseGroup> createImageSamplingTypeTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType)
811 {
812         VkDescriptorType samplingTypes[] =
813         {
814                 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
815                 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
816         };
817
818         de::MovePtr<tcu::TestCaseGroup> imageSamplingTypeTests(new tcu::TestCaseGroup(testCtx, "sampling_type", ""));
819
820         for (int smpTypeNdx = 0; smpTypeNdx < DE_LENGTH_OF_ARRAY(samplingTypes); smpTypeNdx++)
821         {
822                 const char* smpTypeName = samplingTypes[smpTypeNdx] == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ? "combined" : "separate";
823                 de::MovePtr<tcu::TestCaseGroup> samplingTypeGroup(new tcu::TestCaseGroup(testCtx, smpTypeName, (std::string("Uses a ") + smpTypeName + " sampler").c_str()));
824                 de::MovePtr<tcu::TestCaseGroup> viewTypeTests = createImageViewTypeTests(testCtx, allocationKind, pipelineConstructionType, samplingTypes[smpTypeNdx]);
825
826                 samplingTypeGroup->addChild(viewTypeTests.release());
827                 imageSamplingTypeTests->addChild(samplingTypeGroup.release());
828         }
829
830         return imageSamplingTypeTests;
831 }
832
833 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
834 {
835         de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation Image Tests"));
836         de::MovePtr<tcu::TestCaseGroup> samplingTypeTests = createImageSamplingTypeTests(testCtx, ALLOCATION_KIND_SUBALLOCATED, pipelineConstructionType);
837
838         suballocationTestsGroup->addChild(samplingTypeTests.release());
839
840         return suballocationTestsGroup;
841 }
842
843 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
844 {
845         de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "Image Tests For Dedicated Allocation"));
846         de::MovePtr<tcu::TestCaseGroup> samplingTypeTests = createImageSamplingTypeTests(testCtx, ALLOCATION_KIND_DEDICATED, pipelineConstructionType);
847
848         dedicatedAllocationTestsGroup->addChild(samplingTypeTests.release());
849
850         return dedicatedAllocationTestsGroup;
851 }
852 } // anonymous
853
854 tcu::TestCaseGroup* createImageTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
855 {
856         de::MovePtr<tcu::TestCaseGroup> imageTests(new tcu::TestCaseGroup(testCtx, "image", "Image tests"));
857         de::MovePtr<tcu::TestCaseGroup> imageSuballocationTests = createSuballocationTests(testCtx, pipelineConstructionType);
858         de::MovePtr<tcu::TestCaseGroup> imageDedicatedAllocationTests = createDedicatedAllocationTests(testCtx, pipelineConstructionType);
859
860         imageTests->addChild(imageSuballocationTests.release());
861         imageTests->addChild(imageDedicatedAllocationTests.release());
862
863         return imageTests.release();
864 }
865
866 } // pipeline
867 } // vkt