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