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