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