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