• 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  *
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