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