xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageViewTests.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 View Tests
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vktPipelineImageViewTests.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 "tcuPlatform.hpp"
35 #include "tcuTextureUtil.hpp"
36 #include "deStringUtil.hpp"
37 #include "deMemory.h"
38 
39 #include <sstream>
40 #include <vector>
41 
42 namespace vkt
43 {
44 namespace pipeline
45 {
46 
47 using namespace vk;
48 using de::MovePtr;
49 
50 namespace
51 {
52 
53 class ImageViewTest : public vkt::TestCase
54 {
55 public:
56     ImageViewTest(tcu::TestContext &testContext, const char *name, PipelineConstructionType pipelineConstructionType,
57                   VkImageViewType imageViewType, VkFormat imageFormat, float samplerLod,
58                   const VkComponentMapping &componentMapping, const VkImageSubresourceRange &subresourceRange);
~ImageViewTest(void)59     virtual ~ImageViewTest(void)
60     {
61     }
62 
63     ImageSamplingInstanceParams getImageSamplingInstanceParams(VkImageViewType imageViewType, VkFormat imageFormat,
64                                                                float samplerLod,
65                                                                const VkComponentMapping &componentMapping,
66                                                                const VkImageSubresourceRange &subresourceRange) const;
67 
68     virtual void initPrograms(SourceCollections &sourceCollections) const;
69     virtual void checkSupport(Context &context) const;
70     virtual TestInstance *createInstance(Context &context) const;
71     static std::string getGlslSamplerType(const tcu::TextureFormat &format, VkImageViewType type);
72     static tcu::UVec2 getRenderSize(VkImageViewType viewType);
73     static tcu::IVec3 getImageSize(VkImageViewType viewType);
74     static int getArraySize(VkImageViewType viewType);
75     static int getNumLevels(VkImageViewType viewType);
76     static tcu::Vec4 swizzle(tcu::Vec4 inputData, VkComponentMapping componentMapping);
77 
78 private:
79     PipelineConstructionType m_pipelineConstructionType;
80     VkImageViewType m_imageViewType;
81     VkFormat m_imageFormat;
82     float m_samplerLod;
83     VkComponentMapping m_componentMapping;
84     VkImageSubresourceRange m_subresourceRange;
85 };
86 
ImageViewTest(tcu::TestContext & testContext,const char * name,PipelineConstructionType pipelineConstructionType,VkImageViewType imageViewType,VkFormat imageFormat,float samplerLod,const VkComponentMapping & componentMapping,const VkImageSubresourceRange & subresourceRange)87 ImageViewTest::ImageViewTest(tcu::TestContext &testContext, const char *name,
88                              PipelineConstructionType pipelineConstructionType, VkImageViewType imageViewType,
89                              VkFormat imageFormat, float samplerLod, const VkComponentMapping &componentMapping,
90                              const VkImageSubresourceRange &subresourceRange)
91 
92     : vkt::TestCase(testContext, name)
93     , m_pipelineConstructionType(pipelineConstructionType)
94     , m_imageViewType(imageViewType)
95     , m_imageFormat(imageFormat)
96     , m_samplerLod(samplerLod)
97     , m_componentMapping(componentMapping)
98     , m_subresourceRange(subresourceRange)
99 {
100 }
101 
getImageSamplingInstanceParams(VkImageViewType imageViewType,VkFormat imageFormat,float samplerLod,const VkComponentMapping & componentMapping,const VkImageSubresourceRange & subresourceRange) const102 ImageSamplingInstanceParams ImageViewTest::getImageSamplingInstanceParams(
103     VkImageViewType imageViewType, VkFormat imageFormat, float samplerLod, const VkComponentMapping &componentMapping,
104     const VkImageSubresourceRange &subresourceRange) const
105 {
106     const tcu::UVec2 renderSize             = getRenderSize(imageViewType);
107     const tcu::IVec3 imageSize              = getImageSize(imageViewType);
108     const int arraySize                     = getArraySize(imageViewType);
109     const std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(imageViewType);
110 
111     const VkSamplerCreateInfo samplerParams = {
112         VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,    // VkStructureType sType;
113         DE_NULL,                                  // const void* pNext;
114         0u,                                       // VkSamplerCreateFlags flags;
115         VK_FILTER_NEAREST,                        // VkFilter magFilter;
116         VK_FILTER_NEAREST,                        // VkFilter minFilter;
117         VK_SAMPLER_MIPMAP_MODE_NEAREST,           // VkSamplerMipmapMode mipmapMode;
118         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,    // VkSamplerAddressMode addressModeU;
119         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,    // VkSamplerAddressMode addressModeV;
120         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,    // VkSamplerAddressMode addressModeW;
121         0.0f,                                     // float mipLodBias;
122         VK_FALSE,                                 // VkBool32 anisotropyEnable;
123         1.0f,                                     // float maxAnisotropy;
124         false,                                    // VkBool32 compareEnable;
125         VK_COMPARE_OP_NEVER,                      // VkCompareOp compareOp;
126         0.0f,                                     // float minLod;
127         (float)(subresourceRange.levelCount - 1), // float maxLod;
128         getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, imageFormat,
129                              false), // VkBorderColor borderColor;
130         false                        // VkBool32 unnormalizedCoordinates;
131     };
132 
133     return ImageSamplingInstanceParams(m_pipelineConstructionType, renderSize, imageViewType, imageFormat, imageSize,
134                                        arraySize, componentMapping, subresourceRange, samplerParams, samplerLod,
135                                        vertices);
136 }
137 
checkSupport(Context & context) const138 void ImageViewTest::checkSupport(Context &context) const
139 {
140     checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(),
141                                           m_pipelineConstructionType);
142 
143 #ifndef CTS_USES_VULKANSC
144     if (m_imageFormat == VK_FORMAT_A8_UNORM_KHR || m_imageFormat == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
145         context.requireDeviceFunctionality("VK_KHR_maintenance5");
146 #endif // CTS_USES_VULKANSC
147 
148     checkSupportImageSamplingInstance(context,
149                                       getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_samplerLod,
150                                                                      m_componentMapping, m_subresourceRange));
151 }
152 
swizzle(tcu::Vec4 inputData,VkComponentMapping componentMapping)153 tcu::Vec4 ImageViewTest::swizzle(tcu::Vec4 inputData, VkComponentMapping componentMapping)
154 {
155     // array map with enum VkComponentSwizzle
156     const float channelValues[] = {-1.0f,         0.0f,          1.0f,          inputData.x(),
157                                    inputData.y(), inputData.z(), inputData.w(), -1.0f};
158 
159     return tcu::Vec4(channelValues[componentMapping.r], channelValues[componentMapping.g],
160                      channelValues[componentMapping.b], channelValues[componentMapping.a]);
161 }
162 
initPrograms(SourceCollections & sourceCollections) const163 void ImageViewTest::initPrograms(SourceCollections &sourceCollections) const
164 {
165     std::ostringstream vertexSrc;
166     std::ostringstream fragmentSrc;
167     const char *texCoordSwizzle     = DE_NULL;
168     const tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ?
169                                           tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat)) :
170                                           mapVkFormat(m_imageFormat);
171 
172     tcu::Vec4 lookupScale;
173     tcu::Vec4 lookupBias;
174 
175     getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
176 
177     tcu::Vec4 swizzledScale = swizzle(lookupScale, m_componentMapping);
178     tcu::Vec4 swizzledBias  = swizzle(lookupBias, m_componentMapping);
179 
180     switch (m_imageViewType)
181     {
182     case VK_IMAGE_VIEW_TYPE_1D:
183         texCoordSwizzle = "x";
184         break;
185     case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
186     case VK_IMAGE_VIEW_TYPE_2D:
187         texCoordSwizzle = "xy";
188         break;
189     case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
190     case VK_IMAGE_VIEW_TYPE_3D:
191     case VK_IMAGE_VIEW_TYPE_CUBE:
192         texCoordSwizzle = "xyz";
193         break;
194     case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
195         texCoordSwizzle = "xyzw";
196         break;
197     default:
198         DE_ASSERT(false);
199         break;
200     }
201 
202     vertexSrc << "#version 440\n"
203               << "layout(location = 0) in vec4 position;\n"
204               << "layout(location = 1) in vec4 texCoords;\n"
205               << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
206               << "out gl_PerVertex {\n"
207               << "    vec4 gl_Position;\n"
208               << "};\n"
209               << "void main (void)\n"
210               << "{\n"
211               << "    gl_Position = position;\n"
212               << "    vtxTexCoords = texCoords;\n"
213               << "}\n";
214 
215     fragmentSrc << "#version 440\n"
216                 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType)
217                 << " texSampler;\n"
218                 << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
219                 << "layout(location = 0) out highp vec4 fragColor;\n"
220                 << "void main (void)\n"
221                 << "{\n"
222                 << "    fragColor = ";
223 
224     if (m_samplerLod > 0.0f)
225         fragmentSrc << "textureLod(texSampler, vtxTexCoords." << texCoordSwizzle << ", " << std::fixed << m_samplerLod
226                     << ")";
227     else
228         fragmentSrc << "texture(texSampler, vtxTexCoords." << texCoordSwizzle << ")" << std::fixed;
229 
230     fragmentSrc << " * vec4" << std::scientific << swizzledScale << " + vec4" << swizzledBias << ";\n"
231                 << "}\n";
232 
233     sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
234     sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
235 }
236 
createInstance(Context & context) const237 TestInstance *ImageViewTest::createInstance(Context &context) const
238 {
239     return new ImageSamplingInstance(context,
240                                      getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_samplerLod,
241                                                                     m_componentMapping, m_subresourceRange));
242 }
243 
getGlslSamplerType(const tcu::TextureFormat & format,VkImageViewType type)244 std::string ImageViewTest::getGlslSamplerType(const tcu::TextureFormat &format, VkImageViewType type)
245 {
246     std::ostringstream samplerType;
247 
248     if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
249         samplerType << "u";
250     else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
251         samplerType << "i";
252 
253     switch (type)
254     {
255     case VK_IMAGE_VIEW_TYPE_1D:
256         samplerType << "sampler1D";
257         break;
258 
259     case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
260         samplerType << "sampler1DArray";
261         break;
262 
263     case VK_IMAGE_VIEW_TYPE_2D:
264         samplerType << "sampler2D";
265         break;
266 
267     case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
268         samplerType << "sampler2DArray";
269         break;
270 
271     case VK_IMAGE_VIEW_TYPE_3D:
272         samplerType << "sampler3D";
273         break;
274 
275     case VK_IMAGE_VIEW_TYPE_CUBE:
276         samplerType << "samplerCube";
277         break;
278 
279     case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
280         samplerType << "samplerCubeArray";
281         break;
282 
283     default:
284         DE_FATAL("Unknown image view type");
285         break;
286     }
287 
288     return samplerType.str();
289 }
290 
getRenderSize(VkImageViewType viewType)291 tcu::UVec2 ImageViewTest::getRenderSize(VkImageViewType viewType)
292 {
293     if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
294         return tcu::UVec2(16u, 16u);
295     else
296         return tcu::UVec2(16u * 3u, 16u * 2u);
297 }
298 
getImageSize(VkImageViewType viewType)299 tcu::IVec3 ImageViewTest::getImageSize(VkImageViewType viewType)
300 {
301     switch (viewType)
302     {
303     case VK_IMAGE_VIEW_TYPE_1D:
304     case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
305         return tcu::IVec3(16, 1, 1);
306 
307     case VK_IMAGE_VIEW_TYPE_3D:
308         return tcu::IVec3(16);
309 
310     default:
311         break;
312     }
313 
314     return tcu::IVec3(16, 16, 1);
315 }
316 
getArraySize(VkImageViewType viewType)317 int ImageViewTest::getArraySize(VkImageViewType viewType)
318 {
319     switch (viewType)
320     {
321     case VK_IMAGE_VIEW_TYPE_3D:
322         return 1;
323 
324     case VK_IMAGE_VIEW_TYPE_CUBE:
325     case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
326         return 18;
327 
328     default:
329         break;
330     }
331 
332     return 6;
333 }
334 
getNumLevels(VkImageViewType viewType)335 int ImageViewTest::getNumLevels(VkImageViewType viewType)
336 {
337     const tcu::IVec3 imageSize = getImageSize(viewType);
338 
339     return deLog2Floor32(deMax32(imageSize.x(), deMax32(imageSize.y(), imageSize.z()))) + 1;
340 }
341 
getFormatCaseName(const VkFormat format)342 static std::string getFormatCaseName(const VkFormat format)
343 {
344     const std::string fullName = getFormatName(format);
345 
346     DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
347 
348     return de::toLower(fullName.substr(10));
349 }
350 
createSubresourceRangeTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType,VkImageViewType viewType,VkFormat imageFormat)351 static de::MovePtr<tcu::TestCaseGroup> createSubresourceRangeTests(tcu::TestContext &testCtx,
352                                                                    PipelineConstructionType pipelineConstructionType,
353                                                                    VkImageViewType viewType, VkFormat imageFormat)
354 {
355     struct TestCaseConfig
356     {
357         const char *name;
358         float samplerLod;
359         VkImageSubresourceRange subresourceRange;
360     };
361 
362     const uint32_t numLevels                  = ImageViewTest::getNumLevels(viewType);
363     const uint32_t arraySize                  = ImageViewTest::getArraySize(viewType);
364     const VkImageAspectFlags imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
365     const VkComponentMapping componentMapping = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B,
366                                                  VK_COMPONENT_SWIZZLE_A};
367 
368     de::MovePtr<tcu::TestCaseGroup> rangeTests(new tcu::TestCaseGroup(testCtx, "subresource_range"));
369 
370 #define ADD_SUBRESOURCE_RANGE_TESTS(TEST_CASES)                                                              \
371     do                                                                                                       \
372     {                                                                                                        \
373         for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(TEST_CASES); configNdx++)                     \
374         {                                                                                                    \
375             const TestCaseConfig config = (TEST_CASES)[configNdx];                                           \
376             rangeTests->addChild(new ImageViewTest(testCtx, config.name, pipelineConstructionType, viewType, \
377                                                    imageFormat, config.samplerLod, componentMapping,         \
378                                                    config.subresourceRange));                                \
379         }                                                                                                    \
380     } while (false)
381 
382     if (viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY || viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY)
383     {
384         const TestCaseConfig mipLevelRangeCases[] = {
385             //    name                    samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
386             {"lod_base_mip_level", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 0u, arraySize}},
387             {"lod_mip_levels", 4.0f, {imageAspectFlags, 0u, 3u, 0u, arraySize}},
388         };
389 
390         const TestCaseConfig arrayRangeCases[] = {
391             //    name                    samplerLod        subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
392             {"base_array_layer", 0.0f, {imageAspectFlags, 0u, numLevels, 1u, arraySize - 1u}},
393             {"array_size", 0.0f, {imageAspectFlags, 0u, numLevels, 0u, 4u}},
394             {"array_base_and_size", 0.0f, {imageAspectFlags, 0u, numLevels, 2u, 3u}},
395         };
396 
397         const TestCaseConfig mipLevelAndArrayRangeCases[] = {
398             //    name                                        samplerLod        subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
399             {"lod_base_mip_level_base_array_layer", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 1u, 5u}},
400             {"lod_mip_levels_base_array_layer", 4.0f, {imageAspectFlags, 0u, 3u, 1u, 5u}},
401 
402             {"lod_base_mip_level_array_size", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 0u, 4u}},
403             {"lod_mip_levels_array_size", 4.0f, {imageAspectFlags, 0u, 3u, 0u, 4u}},
404 
405             {"lod_base_mip_level_array_base_and_size", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 2u, 3u}},
406             {"lod_mip_levels_array_base_and_size", 4.0f, {imageAspectFlags, 0u, 3u, 2u, 3u}},
407         };
408 
409         const TestCaseConfig mipLevelAndArrayRemainingRangeCases[] = {
410             //    name                                                                samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
411             {"lod_base_mip_level_remaining_levels",
412              0.0f,
413              {imageAspectFlags, 1u, VK_REMAINING_MIP_LEVELS, 0u, arraySize}},
414             {"base_array_layer_remaining_layers",
415              0.0f,
416              {imageAspectFlags, 0u, numLevels, 1u, VK_REMAINING_ARRAY_LAYERS}},
417             {"lod_base_mip_level_base_array_layer_remaining_levels_and_layers",
418              0.0f,
419              {imageAspectFlags, 2u, VK_REMAINING_MIP_LEVELS, 2u, VK_REMAINING_ARRAY_LAYERS}},
420         };
421 
422         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelRangeCases);
423         ADD_SUBRESOURCE_RANGE_TESTS(arrayRangeCases);
424         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRangeCases);
425         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRemainingRangeCases);
426     }
427     else if (viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
428     {
429         const TestCaseConfig mipLevelRangeCases[] = {
430             //    name                    samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
431             {"lod_base_mip_level", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 0u, arraySize}},
432             {"lod_mip_levels", 4.0f, {imageAspectFlags, 0u, 3u, 0u, arraySize}},
433         };
434 
435         const TestCaseConfig arrayRangeCases[] = {
436             //    name                    samplerLod        subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
437             {"base_array_layer", 0.0f, {imageAspectFlags, 0u, numLevels, 6u, arraySize - 6u}},
438             {"array_size", 0.0f, {imageAspectFlags, 0u, numLevels, 0u, 6u}},
439             {"array_base_and_size", 0.0f, {imageAspectFlags, 0u, numLevels, 12u, 6u}},
440         };
441 
442         const TestCaseConfig mipLevelAndArrayRangeCases[] = {
443             //    name                                        samplerLod        subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
444             {"lod_base_mip_level_base_array_layer", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 6u, arraySize - 6u}},
445             {"lod_mip_levels_base_array_layer", 4.0f, {imageAspectFlags, 0u, 3u, 6u, arraySize - 6u}},
446 
447             {"lod_base_mip_level_array_size", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 0u, 6u}},
448             {"lod_mip_levels_array_size", 4.0f, {imageAspectFlags, 0u, 3u, 0u, 6u}},
449 
450             {"lod_base_mip_level_array_base_and_size", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 12u, 6u}},
451             {"lod_mip_levels_array_base_and_size", 4.0f, {imageAspectFlags, 0u, 3u, 12u, 6u}},
452         };
453 
454         const TestCaseConfig mipLevelAndArrayRemainingRangeCases[] = {
455             //    name                                                                samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
456             {"lod_base_mip_level_remaining_levels",
457              0.0f,
458              {imageAspectFlags, 1u, VK_REMAINING_MIP_LEVELS, 0u, arraySize}},
459             {"base_array_layer_remaining_layers",
460              0.0f,
461              {imageAspectFlags, 0u, numLevels, 6u, VK_REMAINING_ARRAY_LAYERS}},
462             {"lod_base_mip_level_base_array_layer_remaining_levels_and_layers",
463              0.0f,
464              {imageAspectFlags, 2u, VK_REMAINING_MIP_LEVELS, 12u, VK_REMAINING_ARRAY_LAYERS}},
465         };
466 
467         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelRangeCases);
468         ADD_SUBRESOURCE_RANGE_TESTS(arrayRangeCases);
469         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRangeCases);
470         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRemainingRangeCases);
471     }
472     else if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
473     {
474         const TestCaseConfig mipLevelRangeCases[] = {
475             //    name                    samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
476             {"lod_base_mip_level", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 0u, 1u}},
477             {"lod_mip_levels", 4.0f, {imageAspectFlags, 0u, 3u, 0u, 1u}},
478         };
479 
480         const TestCaseConfig arrayRangeCases[] = {
481             //    name                    samplerLod        subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
482             {"array_layer_second", 0.0f, {imageAspectFlags, 0u, numLevels, 1u, 1u}},
483             {"array_layer_last", 0.0f, {imageAspectFlags, 0u, numLevels, arraySize - 1u, 1u}},
484         };
485 
486         const TestCaseConfig mipLevelAndArrayRangeCases[] = {
487             //    name                                    samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
488             {"lod_base_mip_level_array_layer_second", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 1u, 1u}},
489             {"lod_mip_levels_array_layer_second", 4.0f, {imageAspectFlags, 0u, 3u, arraySize - 1u, 1u}},
490 
491             {"lod_base_mip_level_array_layer_last", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 5u, 1u}},
492             {"lod_mip_levels_array_layer_last", 4.0f, {imageAspectFlags, 0u, 3u, arraySize - 1u, 1u}},
493         };
494 
495         const TestCaseConfig mipLevelAndArrayRemainingRangeCases[] = {
496             //    name                                                                samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
497             {"lod_base_mip_level_remaining_levels", 0.0f, {imageAspectFlags, 1u, VK_REMAINING_MIP_LEVELS, 0u, 1u}},
498             {"array_layer_last_remaining_layers",
499              0.0f,
500              {imageAspectFlags, 0u, numLevels, arraySize - 1u, VK_REMAINING_ARRAY_LAYERS}},
501             {"lod_base_mip_level_array_layer_last_remaining_levels_and_layers",
502              0.0f,
503              {imageAspectFlags, 2u, VK_REMAINING_MIP_LEVELS, arraySize - 1u, VK_REMAINING_ARRAY_LAYERS}},
504         };
505 
506         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelRangeCases);
507         ADD_SUBRESOURCE_RANGE_TESTS(arrayRangeCases);
508         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRangeCases);
509         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRemainingRangeCases);
510     }
511     else if (viewType == VK_IMAGE_VIEW_TYPE_CUBE)
512     {
513         const TestCaseConfig mipLevelRangeCases[] = {
514             //    name                    samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
515             {"lod_base_mip_level", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 0u, 6u}},
516             {"lod_mip_levels", 4.0f, {imageAspectFlags, 0u, 3u, 0u, 6u}},
517         };
518 
519         const TestCaseConfig arrayRangeCases[] = {
520             //    name                    samplerLod        subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
521             {"array_layer_second", 0.0f, {imageAspectFlags, 0u, numLevels, 6u, 6u}},
522             {"array_layer_last", 0.0f, {imageAspectFlags, 0u, numLevels, arraySize - 6u, 6u}},
523         };
524 
525         const TestCaseConfig mipLevelAndArrayRangeCases[] = {
526             //    name                                    samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
527             {"lod_base_mip_level_array_layer_second", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 6u, 6u}},
528             {"lod_mip_levels_array_layer_second", 4.0f, {imageAspectFlags, 0u, 3u, 6u, 6u}},
529 
530             {"lod_base_mip_level_array_layer_last", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, arraySize - 6u, 6u}},
531             {"lod_mip_levels_array_layer_last", 4.0f, {imageAspectFlags, 0u, 3u, arraySize - 6u, 6u}},
532         };
533 
534         const TestCaseConfig mipLevelAndArrayRemainingRangeCases[] = {
535             //    name                                                                samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
536             {"lod_base_mip_level_remaining_levels", 0.0f, {imageAspectFlags, 1u, VK_REMAINING_MIP_LEVELS, 0u, 6u}},
537             {"array_layer_last_remaining_layers",
538              0.0f,
539              {imageAspectFlags, 0u, numLevels, arraySize - 6u, VK_REMAINING_ARRAY_LAYERS}},
540             {"lod_base_mip_level_array_layer_last_remaining_levels_and_layers",
541              0.0f,
542              {imageAspectFlags, 2u, VK_REMAINING_MIP_LEVELS, arraySize - 6u, VK_REMAINING_ARRAY_LAYERS}},
543         };
544 
545         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelRangeCases);
546         ADD_SUBRESOURCE_RANGE_TESTS(arrayRangeCases);
547         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRangeCases);
548         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRemainingRangeCases);
549     }
550     else if (viewType == VK_IMAGE_VIEW_TYPE_3D)
551     {
552         const TestCaseConfig mipLevelRangeCases[] = {
553             //    name                    samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
554             {"lod_base_mip_level", 0.0f, {imageAspectFlags, 2u, numLevels - 2u, 0u, arraySize}},
555             {"lod_mip_levels", 4.0f, {imageAspectFlags, 0u, 3u, 0u, arraySize}},
556         };
557 
558         const TestCaseConfig mipLevelAndArrayRemainingRangeCases[] = {
559             //    name                                                                samplerLod    subresourceRange (aspectMask, baseMipLevel, mipLevels, baseArrayLayer, arraySize)
560             {"lod_base_mip_level_remaining_levels",
561              0.0f,
562              {imageAspectFlags, 1u, VK_REMAINING_MIP_LEVELS, 0u, arraySize}},
563             {"single_array_layer_remaining_layers",
564              0.0f,
565              {imageAspectFlags, 0u, numLevels, 0u, VK_REMAINING_ARRAY_LAYERS}},
566             {"lod_base_mip_level_single_array_layer_remaining_levels_and_layers",
567              0.0f,
568              {imageAspectFlags, 2u, VK_REMAINING_MIP_LEVELS, 0u, VK_REMAINING_ARRAY_LAYERS}},
569         };
570 
571         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelRangeCases);
572         ADD_SUBRESOURCE_RANGE_TESTS(mipLevelAndArrayRemainingRangeCases);
573     }
574 
575 #undef ADD_SUBRESOURCE_RANGE_TESTS
576 
577     return rangeTests;
578 }
579 
getComponentMappingPermutations(const VkComponentMapping & componentMapping)580 static std::vector<VkComponentMapping> getComponentMappingPermutations(const VkComponentMapping &componentMapping)
581 {
582     std::vector<VkComponentMapping> mappings;
583 
584     const VkComponentSwizzle channelSwizzles[4] = {componentMapping.r, componentMapping.g, componentMapping.b,
585                                                    componentMapping.a};
586 
587     // Rearranges the channels by shifting their positions.
588     for (int firstChannelNdx = 0; firstChannelNdx < 4; firstChannelNdx++)
589     {
590         VkComponentSwizzle currentChannel[4];
591 
592         for (int channelNdx = 0; channelNdx < 4; channelNdx++)
593             currentChannel[channelNdx] = channelSwizzles[(firstChannelNdx + channelNdx) % 4];
594 
595         const VkComponentMapping mappingPermutation = {currentChannel[0], currentChannel[1], currentChannel[2],
596                                                        currentChannel[3]};
597 
598         mappings.push_back(mappingPermutation);
599     }
600 
601     return mappings;
602 }
603 
getComponentSwizzleCaseName(VkComponentSwizzle componentSwizzle)604 static std::string getComponentSwizzleCaseName(VkComponentSwizzle componentSwizzle)
605 {
606     const std::string fullName = getComponentSwizzleName(componentSwizzle);
607 
608     DE_ASSERT(de::beginsWith(fullName, "VK_COMPONENT_SWIZZLE_"));
609 
610     return de::toLower(fullName.substr(21));
611 }
612 
getComponentMappingCaseName(const VkComponentMapping & componentMapping)613 static std::string getComponentMappingCaseName(const VkComponentMapping &componentMapping)
614 {
615     std::ostringstream name;
616 
617     name << getComponentSwizzleCaseName(componentMapping.r) << "_" << getComponentSwizzleCaseName(componentMapping.g)
618          << "_" << getComponentSwizzleCaseName(componentMapping.b) << "_"
619          << getComponentSwizzleCaseName(componentMapping.a);
620 
621     return name.str();
622 }
623 
createComponentSwizzleTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType,VkImageViewType viewType,VkFormat imageFormat)624 static de::MovePtr<tcu::TestCaseGroup> createComponentSwizzleTests(tcu::TestContext &testCtx,
625                                                                    PipelineConstructionType pipelineConstructionType,
626                                                                    VkImageViewType viewType, VkFormat imageFormat)
627 {
628     uint32_t arraySize = 0;
629 
630     switch (viewType)
631     {
632     case VK_IMAGE_VIEW_TYPE_1D:
633     case VK_IMAGE_VIEW_TYPE_2D:
634     case VK_IMAGE_VIEW_TYPE_3D:
635         arraySize = 1;
636         break;
637 
638     case VK_IMAGE_VIEW_TYPE_CUBE:
639         arraySize = 6;
640         break;
641 
642     case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
643     case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
644     case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
645         arraySize = ImageViewTest::getArraySize(viewType);
646         break;
647 
648     default:
649         break;
650     }
651 
652     const VkImageSubresourceRange subresourceRange = {
653         VK_IMAGE_ASPECT_COLOR_BIT,                       // VkImageAspectFlags aspectMask;
654         0u,                                              // uint32_t baseMipLevel;
655         (uint32_t)ImageViewTest::getNumLevels(viewType), // uint32_t mipLevels;
656         0u,                                              // uint32_t baseArrayLayer;
657         arraySize,                                       // uint32_t arraySize;
658     };
659 
660     const VkComponentMapping baseMapping = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B,
661                                             VK_COMPONENT_SWIZZLE_A};
662     const std::vector<VkComponentMapping> componentMappings = getComponentMappingPermutations(baseMapping);
663     de::MovePtr<tcu::TestCaseGroup> swizzleTests(new tcu::TestCaseGroup(testCtx, "component_swizzle"));
664 
665     for (size_t mappingNdx = 0; mappingNdx < componentMappings.size(); mappingNdx++)
666     {
667         swizzleTests->addChild(new ImageViewTest(
668             testCtx, getComponentMappingCaseName(componentMappings[mappingNdx]).c_str(), pipelineConstructionType,
669             viewType, imageFormat, 0.0f, componentMappings[mappingNdx], subresourceRange));
670     }
671 
672     return swizzleTests;
673 }
674 
675 } // namespace
676 
createImageViewTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)677 tcu::TestCaseGroup *createImageViewTests(tcu::TestContext &testCtx, PipelineConstructionType pipelineConstructionType)
678 {
679     const struct
680     {
681         VkImageViewType type;
682         const char *name;
683     } imageViewTypes[] = {{VK_IMAGE_VIEW_TYPE_1D, "1d"},
684                           {VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array"},
685                           {VK_IMAGE_VIEW_TYPE_2D, "2d"},
686                           {VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array"},
687                           {VK_IMAGE_VIEW_TYPE_3D, "3d"},
688                           {VK_IMAGE_VIEW_TYPE_CUBE, "cube"},
689                           {VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array"}};
690 
691     const VkFormat formats[] = {
692         VK_FORMAT_R4G4_UNORM_PACK8,
693         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
694         VK_FORMAT_R5G6B5_UNORM_PACK16,
695         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
696 #ifndef CTS_USES_VULKANSC
697         VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
698 #endif // CTS_USES_VULKANSC
699         VK_FORMAT_R8_UNORM,
700         VK_FORMAT_R8_SNORM,
701         VK_FORMAT_R8_USCALED,
702         VK_FORMAT_R8_SSCALED,
703         VK_FORMAT_R8_UINT,
704         VK_FORMAT_R8_SINT,
705         VK_FORMAT_R8_SRGB,
706 #ifndef CTS_USES_VULKANSC
707         VK_FORMAT_A8_UNORM_KHR,
708 #endif // CTS_USES_VULKANSC
709         VK_FORMAT_R8G8_UNORM,
710         VK_FORMAT_R8G8_SNORM,
711         VK_FORMAT_R8G8_USCALED,
712         VK_FORMAT_R8G8_SSCALED,
713         VK_FORMAT_R8G8_UINT,
714         VK_FORMAT_R8G8_SINT,
715         VK_FORMAT_R8G8_SRGB,
716         VK_FORMAT_R8G8B8_UNORM,
717         VK_FORMAT_R8G8B8_SNORM,
718         VK_FORMAT_R8G8B8_USCALED,
719         VK_FORMAT_R8G8B8_SSCALED,
720         VK_FORMAT_R8G8B8_UINT,
721         VK_FORMAT_R8G8B8_SINT,
722         VK_FORMAT_R8G8B8_SRGB,
723         VK_FORMAT_B8G8R8_UNORM,
724         VK_FORMAT_B8G8R8_SNORM,
725         VK_FORMAT_B8G8R8_USCALED,
726         VK_FORMAT_B8G8R8_SSCALED,
727         VK_FORMAT_B8G8R8_UINT,
728         VK_FORMAT_B8G8R8_SINT,
729         VK_FORMAT_B8G8R8_SRGB,
730         VK_FORMAT_R8G8B8A8_UNORM,
731         VK_FORMAT_R8G8B8A8_SNORM,
732         VK_FORMAT_R8G8B8A8_USCALED,
733         VK_FORMAT_R8G8B8A8_SSCALED,
734         VK_FORMAT_R8G8B8A8_UINT,
735         VK_FORMAT_R8G8B8A8_SINT,
736         VK_FORMAT_R8G8B8A8_SRGB,
737         VK_FORMAT_B8G8R8A8_UNORM,
738         VK_FORMAT_B8G8R8A8_SNORM,
739         VK_FORMAT_B8G8R8A8_USCALED,
740         VK_FORMAT_B8G8R8A8_SSCALED,
741         VK_FORMAT_B8G8R8A8_UINT,
742         VK_FORMAT_B8G8R8A8_SINT,
743         VK_FORMAT_B8G8R8A8_SRGB,
744         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
745         VK_FORMAT_A2R10G10B10_UINT_PACK32,
746         VK_FORMAT_A2B10G10R10_USCALED_PACK32,
747         VK_FORMAT_R16_UNORM,
748         VK_FORMAT_R16_SNORM,
749         VK_FORMAT_R16_USCALED,
750         VK_FORMAT_R16_SSCALED,
751         VK_FORMAT_R16_UINT,
752         VK_FORMAT_R16_SINT,
753         VK_FORMAT_R16_SFLOAT,
754         VK_FORMAT_R16G16_UNORM,
755         VK_FORMAT_R16G16_SNORM,
756         VK_FORMAT_R16G16_USCALED,
757         VK_FORMAT_R16G16_SSCALED,
758         VK_FORMAT_R16G16_UINT,
759         VK_FORMAT_R16G16_SINT,
760         VK_FORMAT_R16G16_SFLOAT,
761         VK_FORMAT_R16G16B16_UNORM,
762         VK_FORMAT_R16G16B16_SNORM,
763         VK_FORMAT_R16G16B16_USCALED,
764         VK_FORMAT_R16G16B16_SSCALED,
765         VK_FORMAT_R16G16B16_UINT,
766         VK_FORMAT_R16G16B16_SINT,
767         VK_FORMAT_R16G16B16_SFLOAT,
768         VK_FORMAT_R16G16B16A16_UNORM,
769         VK_FORMAT_R16G16B16A16_SNORM,
770         VK_FORMAT_R16G16B16A16_USCALED,
771         VK_FORMAT_R16G16B16A16_SSCALED,
772         VK_FORMAT_R16G16B16A16_UINT,
773         VK_FORMAT_R16G16B16A16_SINT,
774         VK_FORMAT_R16G16B16A16_SFLOAT,
775         VK_FORMAT_R32_UINT,
776         VK_FORMAT_R32_SINT,
777         VK_FORMAT_R32_SFLOAT,
778         VK_FORMAT_R32G32_UINT,
779         VK_FORMAT_R32G32_SINT,
780         VK_FORMAT_R32G32_SFLOAT,
781         VK_FORMAT_R32G32B32_UINT,
782         VK_FORMAT_R32G32B32_SINT,
783         VK_FORMAT_R32G32B32_SFLOAT,
784         VK_FORMAT_R32G32B32A32_UINT,
785         VK_FORMAT_R32G32B32A32_SINT,
786         VK_FORMAT_R32G32B32A32_SFLOAT,
787         VK_FORMAT_B10G11R11_UFLOAT_PACK32,
788         VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
789         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
790         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
791         VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
792         VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
793         VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
794 
795         // Compressed formats
796         VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
797         VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
798         VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
799         VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
800         VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
801         VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
802         VK_FORMAT_EAC_R11_UNORM_BLOCK,
803         VK_FORMAT_EAC_R11_SNORM_BLOCK,
804         VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
805         VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
806         VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
807         VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
808         VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
809         VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
810         VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
811         VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
812         VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
813         VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
814         VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
815         VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
816         VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
817         VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
818         VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
819         VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
820         VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
821         VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
822         VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
823         VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
824         VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
825         VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
826         VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
827         VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
828         VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
829         VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
830         VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
831         VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
832         VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
833         VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
834         VK_FORMAT_BC5_UNORM_BLOCK,
835         VK_FORMAT_BC5_SNORM_BLOCK,
836     };
837 
838     de::MovePtr<tcu::TestCaseGroup> imageTests(new tcu::TestCaseGroup(testCtx, "image_view"));
839     de::MovePtr<tcu::TestCaseGroup> viewTypeTests(new tcu::TestCaseGroup(testCtx, "view_type"));
840 
841     for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
842     {
843         const VkImageViewType viewType = imageViewTypes[viewTypeNdx].type;
844         de::MovePtr<tcu::TestCaseGroup> viewTypeGroup(
845             new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name));
846         // Uses samplable formats
847         de::MovePtr<tcu::TestCaseGroup> formatTests(new tcu::TestCaseGroup(testCtx, "format"));
848 
849         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
850         {
851             const VkFormat format = formats[formatNdx];
852 
853             if (isCompressedFormat(format))
854             {
855                 // Do not use compressed formats with 1D and 1D array textures.
856                 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
857                     break;
858             }
859 
860             de::MovePtr<tcu::TestCaseGroup> formatGroup(
861                 new tcu::TestCaseGroup(testCtx, getFormatCaseName(format).c_str()));
862 
863             de::MovePtr<tcu::TestCaseGroup> subresourceRangeTests =
864                 createSubresourceRangeTests(testCtx, pipelineConstructionType, viewType, format);
865             de::MovePtr<tcu::TestCaseGroup> componentSwizzleTests =
866                 createComponentSwizzleTests(testCtx, pipelineConstructionType, viewType, format);
867 
868             formatGroup->addChild(componentSwizzleTests.release());
869             formatGroup->addChild(subresourceRangeTests.release());
870             formatTests->addChild(formatGroup.release());
871         }
872 
873         viewTypeGroup->addChild(formatTests.release());
874         viewTypeTests->addChild(viewTypeGroup.release());
875     }
876 
877     imageTests->addChild(viewTypeTests.release());
878 
879     return imageTests.release();
880 }
881 
882 } // namespace pipeline
883 } // namespace vkt
884