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