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