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