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