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