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