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