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 Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktPipelineImageTests.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 "tcuTextureUtil.hpp"
33 #include "deStringUtil.hpp"
34 
35 #include <sstream>
36 #include <vector>
37 
38 namespace vkt
39 {
40 namespace pipeline
41 {
42 
43 using namespace vk;
44 using de::MovePtr;
45 
46 namespace
47 {
48 
49 class ImageTest : public vkt::TestCase
50 {
51 public:
52 							ImageTest				(tcu::TestContext&	testContext,
53 													 const char*		name,
54 													 const char*		description,
55 													 VkDescriptorType	samplingType,
56 													 VkImageViewType	imageViewType,
57 													 VkFormat			imageFormat,
58 													 const tcu::IVec3&	imageSize,
59 													 int				imageCount,
60 													 int				arraySize);
61 
62 	virtual void			initPrograms			(SourceCollections& sourceCollections) const;
63 	virtual TestInstance*	createInstance			(Context& context) const;
64 	static std::string		getGlslSamplerType		(const tcu::TextureFormat& format, VkImageViewType type);
65 	static std::string		getGlslTextureType		(const tcu::TextureFormat& format, VkImageViewType type);
66 	static std::string		getGlslSamplerDecl		(int imageCount);
67 	static std::string		getGlslTextureDecl		(int imageCount);
68 	static std::string		getGlslFragColorDecl	(int imageCount);
69 	static std::string		getGlslSampler			(const tcu::TextureFormat& format,
70 													 VkImageViewType type,
71 													 VkDescriptorType samplingType,
72 													 int imageCount);
73 
74 private:
75 	VkDescriptorType		m_samplingType;
76 	VkImageViewType			m_imageViewType;
77 	VkFormat				m_imageFormat;
78 	tcu::IVec3				m_imageSize;
79 	int						m_imageCount;
80 	int						m_arraySize;
81 };
82 
ImageTest(tcu::TestContext & testContext,const char * name,const char * description,VkDescriptorType samplingType,VkImageViewType imageViewType,VkFormat imageFormat,const tcu::IVec3 & imageSize,int imageCount,int arraySize)83 ImageTest::ImageTest (tcu::TestContext&	testContext,
84 					  const char*		name,
85 					  const char*		description,
86 					  VkDescriptorType	samplingType,
87 					  VkImageViewType	imageViewType,
88 					  VkFormat			imageFormat,
89 					  const tcu::IVec3&	imageSize,
90 					  int				imageCount,
91 					  int				arraySize)
92 
93 	: vkt::TestCase		(testContext, name, description)
94 	, m_samplingType	(samplingType)
95 	, m_imageViewType	(imageViewType)
96 	, m_imageFormat		(imageFormat)
97 	, m_imageSize		(imageSize)
98 	, m_imageCount		(imageCount)
99 	, m_arraySize		(arraySize)
100 {
101 }
102 
initPrograms(SourceCollections & sourceCollections) const103 void ImageTest::initPrograms (SourceCollections& sourceCollections) const
104 {
105 	std::ostringstream				vertexSrc;
106 	std::ostringstream				fragmentSrc;
107 	const char*						texCoordSwizzle	= DE_NULL;
108 	const tcu::TextureFormat		format			= (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat))
109 																						  : mapVkFormat(m_imageFormat);
110 
111 	tcu::Vec4						lookupScale;
112 	tcu::Vec4						lookupBias;
113 
114 	getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
115 
116 	switch (m_imageViewType)
117 	{
118 		case VK_IMAGE_VIEW_TYPE_1D:
119 			texCoordSwizzle = "x";
120 			break;
121 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
122 		case VK_IMAGE_VIEW_TYPE_2D:
123 			texCoordSwizzle = "xy";
124 			break;
125 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
126 		case VK_IMAGE_VIEW_TYPE_3D:
127 		case VK_IMAGE_VIEW_TYPE_CUBE:
128 			texCoordSwizzle = "xyz";
129 			break;
130 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
131 			texCoordSwizzle = "xyzw";
132 			break;
133 		default:
134 			DE_ASSERT(false);
135 			break;
136 	}
137 
138 	vertexSrc << "#version 440\n"
139 			  << "layout(location = 0) in vec4 position;\n"
140 			  << "layout(location = 1) in vec4 texCoords;\n"
141 			  << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
142 			  << "out gl_PerVertex {\n"
143 			  << "	vec4 gl_Position;\n"
144 			  << "};\n"
145 			  << "void main (void)\n"
146 			  << "{\n"
147 			  << "	gl_Position = position;\n"
148 			  << "	vtxTexCoords = texCoords;\n"
149 			  << "}\n";
150 
151 	fragmentSrc << "#version 440\n";
152 	switch (m_samplingType)
153 	{
154 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
155 			fragmentSrc
156 				<< "layout(set = 0, binding = 0) uniform highp sampler texSampler;\n"
157 				<< "layout(set = 0, binding = 1) uniform highp " << getGlslTextureType(format, m_imageViewType) << " " << getGlslTextureDecl(m_imageCount) << ";\n";
158 			break;
159 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
160 		default:
161 			fragmentSrc
162 				<< "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " " << getGlslSamplerDecl(m_imageCount) << ";\n";
163 	}
164 	fragmentSrc << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
165 				<< "layout(location = 0) out highp vec4 " << getGlslFragColorDecl(m_imageCount) << ";\n"
166 				<< "void main (void)\n"
167 				<< "{\n";
168 	if (m_imageCount > 1)
169 		fragmentSrc
170 				<< "	for (uint i = 0; i < " << m_imageCount << "; ++i)\n"
171 				<< "		fragColors[i] = (texture(" << getGlslSampler(format, m_imageViewType, m_samplingType, m_imageCount) << ", vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << lookupScale << ") + vec4" << lookupBias << "; \n";
172 	else
173 		fragmentSrc
174 				<< "	fragColor = (texture(" << getGlslSampler(format, m_imageViewType, m_samplingType, m_imageCount) << ", vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << lookupScale << ") + vec4" << lookupBias << "; \n";
175 	fragmentSrc << "}\n";
176 
177 	sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
178 	sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
179 }
180 
createInstance(Context & context) const181 TestInstance* ImageTest::createInstance (Context& context) const
182 {
183 	tcu::UVec2 renderSize;
184 	const VkPhysicalDeviceFeatures&	features = context.getDeviceFeatures();
185 
186 	// Using an loop to index into an array of images requires shaderSampledImageArrayDynamicIndexing
187 	if (m_imageCount > 1 && features.shaderSampledImageArrayDynamicIndexing == VK_FALSE)
188 	{
189 		TCU_THROW(NotSupportedError, "shaderSampledImageArrayDynamicIndexing feature is not supported");
190 	}
191 
192 	if (m_imageViewType == VK_IMAGE_VIEW_TYPE_1D || m_imageViewType == VK_IMAGE_VIEW_TYPE_2D)
193 	{
194 		renderSize = tcu::UVec2((deUint32)m_imageSize.x(), (deUint32)m_imageSize.y());
195 	}
196 	else
197 	{
198 		// Draw a 3x2 grid of texture layers
199 		renderSize = tcu::UVec2((deUint32)m_imageSize.x() * 3, (deUint32)m_imageSize.y() * 2);
200 	}
201 
202 	const std::vector<Vertex4Tex4>	vertices			= createTestQuadMosaic(m_imageViewType);
203 	const VkComponentMapping		componentMapping	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
204 	const VkImageSubresourceRange	subresourceRange	=
205 	{
206 		VK_IMAGE_ASPECT_COLOR_BIT,
207 		0u,
208 		(deUint32)deLog2Floor32(deMax32(m_imageSize.x(), deMax32(m_imageSize.y(), m_imageSize.z()))) + 1,
209 		0u,
210 		(deUint32)m_arraySize,
211 	};
212 
213 	const VkSamplerCreateInfo samplerParams =
214 	{
215 		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,									// VkStructureType			sType;
216 		DE_NULL,																// const void*				pNext;
217 		0u,																		// VkSamplerCreateFlags		flags;
218 		VK_FILTER_NEAREST,														// VkFilter					magFilter;
219 		VK_FILTER_NEAREST,														// VkFilter					minFilter;
220 		VK_SAMPLER_MIPMAP_MODE_NEAREST,											// VkSamplerMipmapMode		mipmapMode;
221 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeU;
222 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeV;
223 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeW;
224 		0.0f,																	// float					mipLodBias;
225 		VK_FALSE,																// VkBool32					anisotropyEnable;
226 		1.0f,																	// float					maxAnisotropy;
227 		false,																	// VkBool32					compareEnable;
228 		VK_COMPARE_OP_NEVER,													// VkCompareOp				compareOp;
229 		0.0f,																	// float					minLod;
230 		(float)(subresourceRange.levelCount - 1),								// float					maxLod;
231 		getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat),	// VkBorderColor			borderColor;
232 		false																	// VkBool32					unnormalizedCoordinates;
233 	};
234 
235 	return new ImageSamplingInstance(context, renderSize, m_imageViewType, m_imageFormat, m_imageSize, m_arraySize, componentMapping, subresourceRange, samplerParams, 0.0f, vertices, m_samplingType, m_imageCount);
236 }
237 
getGlslSamplerType(const tcu::TextureFormat & format,VkImageViewType type)238 std::string ImageTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
239 {
240 	std::ostringstream samplerType;
241 
242 	if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
243 		samplerType << "u";
244 	else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
245 		samplerType << "i";
246 
247 	switch (type)
248 	{
249 		case VK_IMAGE_VIEW_TYPE_1D:
250 			samplerType << "sampler1D";
251 			break;
252 
253 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
254 			samplerType << "sampler1DArray";
255 			break;
256 
257 		case VK_IMAGE_VIEW_TYPE_2D:
258 			samplerType << "sampler2D";
259 			break;
260 
261 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
262 			samplerType << "sampler2DArray";
263 			break;
264 
265 		case VK_IMAGE_VIEW_TYPE_3D:
266 			samplerType << "sampler3D";
267 			break;
268 
269 		case VK_IMAGE_VIEW_TYPE_CUBE:
270 			samplerType << "samplerCube";
271 			break;
272 
273 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
274 			samplerType << "samplerCubeArray";
275 			break;
276 
277 		default:
278 			DE_FATAL("Unknown image view type");
279 			break;
280 	}
281 
282 	return samplerType.str();
283 }
284 
getGlslTextureType(const tcu::TextureFormat & format,VkImageViewType type)285 std::string ImageTest::getGlslTextureType (const tcu::TextureFormat& format, VkImageViewType type)
286 {
287 	std::ostringstream textureType;
288 
289 	if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
290 		textureType << "u";
291 	else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
292 		textureType << "i";
293 
294 	switch (type)
295 	{
296 		case VK_IMAGE_VIEW_TYPE_1D:
297 			textureType << "texture1D";
298 			break;
299 
300 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
301 			textureType << "texture1DArray";
302 			break;
303 
304 		case VK_IMAGE_VIEW_TYPE_2D:
305 			textureType << "texture2D";
306 			break;
307 
308 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
309 			textureType << "texture2DArray";
310 			break;
311 
312 		case VK_IMAGE_VIEW_TYPE_3D:
313 			textureType << "texture3D";
314 			break;
315 
316 		case VK_IMAGE_VIEW_TYPE_CUBE:
317 			textureType << "textureCube";
318 			break;
319 
320 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
321 			textureType << "textureCubeArray";
322 			break;
323 
324 		default:
325 			DE_FATAL("Unknown image view type");
326 	}
327 
328 	return textureType.str();
329 }
330 
getGlslSamplerDecl(int imageCount)331 std::string ImageTest::getGlslSamplerDecl (int imageCount)
332 {
333 	std::ostringstream samplerArray;
334 	samplerArray << "texSamplers[" << imageCount << "]";
335 
336 	return imageCount > 1 ? samplerArray.str() : "texSampler";
337 }
338 
getGlslTextureDecl(int imageCount)339 std::string ImageTest::getGlslTextureDecl (int imageCount)
340 {
341 	std::ostringstream textureArray;
342 	textureArray << "texImages[" << imageCount << "]";
343 
344 	return imageCount > 1 ? textureArray.str() : "texImage";
345 }
346 
getGlslFragColorDecl(int imageCount)347 std::string ImageTest::getGlslFragColorDecl (int imageCount)
348 {
349 	std::ostringstream samplerArray;
350 	samplerArray << "fragColors[" << imageCount << "]";
351 
352 	return imageCount > 1 ? samplerArray.str() : "fragColor";
353 }
354 
getGlslSampler(const tcu::TextureFormat & format,VkImageViewType type,VkDescriptorType samplingType,int imageCount)355 std::string ImageTest::getGlslSampler (const tcu::TextureFormat& format, VkImageViewType type, VkDescriptorType samplingType, int imageCount)
356 {
357 	std::string texSampler	= imageCount > 1 ? "texSamplers[i]" : "texSampler";
358 	std::string texImage	= imageCount > 1 ? "texImages[i]" : "texImage";
359 
360 	switch (samplingType)
361 	{
362 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
363 			return getGlslSamplerType(format, type) + "(" + texImage + ", texSampler)";
364 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
365 		default:
366 			return texSampler;
367 	}
368 }
369 
getFormatCaseName(const VkFormat format)370 std::string getFormatCaseName (const VkFormat format)
371 {
372 	const std::string	fullName	= getFormatName(format);
373 
374 	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
375 
376 	return de::toLower(fullName.substr(10));
377 }
378 
getSizeName(VkImageViewType viewType,const tcu::IVec3 & size,int arraySize)379 std::string getSizeName (VkImageViewType viewType, const tcu::IVec3& size, int arraySize)
380 {
381 	std::ostringstream	caseName;
382 
383 	switch (viewType)
384 	{
385 		case VK_IMAGE_VIEW_TYPE_1D:
386 		case VK_IMAGE_VIEW_TYPE_2D:
387 		case VK_IMAGE_VIEW_TYPE_CUBE:
388 			caseName << size.x() << "x" << size.y();
389 			break;
390 
391 		case VK_IMAGE_VIEW_TYPE_3D:
392 			caseName << size.x() << "x" << size.y() << "x" << size.z();
393 			break;
394 
395 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
396 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
397 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
398 			caseName << size.x() << "x" << size.y() << "_array_of_" << arraySize;
399 			break;
400 
401 		default:
402 			DE_ASSERT(false);
403 			break;
404 	}
405 
406 	return caseName.str();
407 }
408 
createImageSizeTests(tcu::TestContext & testCtx,VkDescriptorType samplingType,VkImageViewType imageViewType,VkFormat imageFormat,int imageCount)409 de::MovePtr<tcu::TestCaseGroup> createImageSizeTests (tcu::TestContext& testCtx, VkDescriptorType samplingType, VkImageViewType imageViewType, VkFormat imageFormat, int imageCount)
410 {
411 	using tcu::IVec3;
412 
413 	std::vector<IVec3>					imageSizes;
414 	std::vector<int>					arraySizes;
415 	de::MovePtr<tcu::TestCaseGroup>		imageSizeTests	(new tcu::TestCaseGroup(testCtx, "size", ""));
416 
417 	// Select image imageSizes
418 	switch (imageViewType)
419 	{
420 		case VK_IMAGE_VIEW_TYPE_1D:
421 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
422 			// POT
423 			if (imageCount == 1)
424 			{
425 				imageSizes.push_back(IVec3(1, 1, 1));
426 				imageSizes.push_back(IVec3(2, 1, 1));
427 				imageSizes.push_back(IVec3(32, 1, 1));
428 				imageSizes.push_back(IVec3(128, 1, 1));
429 			}
430 			imageSizes.push_back(IVec3(512, 1, 1));
431 
432 			// NPOT
433 			if (imageCount == 1)
434 			{
435 				imageSizes.push_back(IVec3(3, 1, 1));
436 				imageSizes.push_back(IVec3(13, 1, 1));
437 				imageSizes.push_back(IVec3(127, 1, 1));
438 			}
439 			imageSizes.push_back(IVec3(443, 1, 1));
440 			break;
441 
442 		case VK_IMAGE_VIEW_TYPE_2D:
443 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
444 			if (imageCount == 1)
445 			{
446 				// POT
447 				imageSizes.push_back(IVec3(1, 1, 1));
448 				imageSizes.push_back(IVec3(2, 2, 1));
449 				imageSizes.push_back(IVec3(32, 32, 1));
450 
451 				// NPOT
452 				imageSizes.push_back(IVec3(3, 3, 1));
453 				imageSizes.push_back(IVec3(13, 13, 1));
454 			}
455 
456 			// POT rectangular
457 			if (imageCount == 1)
458 				imageSizes.push_back(IVec3(8, 16, 1));
459 			imageSizes.push_back(IVec3(32, 16, 1));
460 
461 			// NPOT rectangular
462 			imageSizes.push_back(IVec3(13, 23, 1));
463 			if (imageCount == 1)
464 				imageSizes.push_back(IVec3(23, 8, 1));
465 			break;
466 
467 		case VK_IMAGE_VIEW_TYPE_3D:
468 			// POT cube
469 			if (imageCount == 1)
470 			{
471 				imageSizes.push_back(IVec3(1, 1, 1));
472 				imageSizes.push_back(IVec3(2, 2, 2));
473 			}
474 			imageSizes.push_back(IVec3(16, 16, 16));
475 
476 			// NPOT cube
477 			if (imageCount == 1)
478 			{
479 				imageSizes.push_back(IVec3(3, 3, 3));
480 				imageSizes.push_back(IVec3(5, 5, 5));
481 			}
482 			imageSizes.push_back(IVec3(11, 11, 11));
483 
484 			// POT non-cube
485 			if (imageCount == 1)
486 				imageSizes.push_back(IVec3(32, 16, 8));
487 			imageSizes.push_back(IVec3(8, 16, 32));
488 
489 			// NPOT non-cube
490 			imageSizes.push_back(IVec3(17, 11, 5));
491 			if (imageCount == 1)
492 				imageSizes.push_back(IVec3(5, 11, 17));
493 			break;
494 
495 		case VK_IMAGE_VIEW_TYPE_CUBE:
496 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
497 			// POT
498 			imageSizes.push_back(IVec3(32, 32, 1));
499 
500 			// NPOT
501 			imageSizes.push_back(IVec3(13, 13, 1));
502 			break;
503 
504 		default:
505 			DE_ASSERT(false);
506 			break;
507 	}
508 
509 	// Select array sizes
510 	switch (imageViewType)
511 	{
512 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
513 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
514 			if (imageCount == 1)
515 				arraySizes.push_back(3);
516 			arraySizes.push_back(6);
517 			break;
518 
519 		case VK_IMAGE_VIEW_TYPE_CUBE:
520 			arraySizes.push_back(6);
521 			break;
522 
523 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
524 			if (imageCount == 1)
525 				arraySizes.push_back(6);
526 			arraySizes.push_back(6 * 6);
527 			break;
528 
529 		default:
530 			arraySizes.push_back(1);
531 			break;
532 	}
533 
534 	for (size_t sizeNdx = 0; sizeNdx < imageSizes.size(); sizeNdx++)
535 	{
536 		for (size_t arraySizeNdx = 0; arraySizeNdx < arraySizes.size(); arraySizeNdx++)
537 		{
538 			imageSizeTests->addChild(new ImageTest(testCtx,
539 												   getSizeName(imageViewType, imageSizes[sizeNdx], arraySizes[arraySizeNdx]).c_str(),
540 												   "",
541 												   samplingType,
542 												   imageViewType,
543 												   imageFormat,
544 												   imageSizes[sizeNdx],
545 												   imageCount,
546 												   arraySizes[arraySizeNdx]));
547 		}
548 	}
549 
550 	return imageSizeTests;
551 }
552 
createImageCountTests(tcu::TestCaseGroup * parentGroup,tcu::TestContext & testCtx,VkDescriptorType samplingType,VkImageViewType imageViewType,VkFormat imageFormat)553 void createImageCountTests (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, VkDescriptorType samplingType, VkImageViewType imageViewType, VkFormat imageFormat)
554 {
555 	const int imageCounts[] = { 1, 4, 8 };
556 
557 	for (size_t countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(imageCounts); countNdx++)
558 	{
559 		std::ostringstream	caseName;
560 		caseName << "count_" << imageCounts[countNdx];
561 		de::MovePtr<tcu::TestCaseGroup>	countGroup(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
562 		de::MovePtr<tcu::TestCaseGroup> sizeTests = createImageSizeTests(testCtx, samplingType, imageViewType, imageFormat, imageCounts[countNdx]);
563 
564 		countGroup->addChild(sizeTests.release());
565 		parentGroup->addChild(countGroup.release());
566 	}
567 }
568 
createImageFormatTests(tcu::TestContext & testCtx,VkDescriptorType samplingType,VkImageViewType imageViewType)569 de::MovePtr<tcu::TestCaseGroup> createImageFormatTests (tcu::TestContext& testCtx, VkDescriptorType samplingType, VkImageViewType imageViewType)
570 {
571 	// All supported dEQP formats that are not intended for depth or stencil.
572 	const VkFormat formats[] =
573 	{
574 		VK_FORMAT_R4G4_UNORM_PACK8,
575 		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
576 		VK_FORMAT_R5G6B5_UNORM_PACK16,
577 		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
578 		VK_FORMAT_R8_UNORM,
579 		VK_FORMAT_R8_SNORM,
580 		VK_FORMAT_R8_USCALED,
581 		VK_FORMAT_R8_SSCALED,
582 		VK_FORMAT_R8_UINT,
583 		VK_FORMAT_R8_SINT,
584 		VK_FORMAT_R8_SRGB,
585 		VK_FORMAT_R8G8_UNORM,
586 		VK_FORMAT_R8G8_SNORM,
587 		VK_FORMAT_R8G8_USCALED,
588 		VK_FORMAT_R8G8_SSCALED,
589 		VK_FORMAT_R8G8_UINT,
590 		VK_FORMAT_R8G8_SINT,
591 		VK_FORMAT_R8G8_SRGB,
592 		VK_FORMAT_R8G8B8_UNORM,
593 		VK_FORMAT_R8G8B8_SNORM,
594 		VK_FORMAT_R8G8B8_USCALED,
595 		VK_FORMAT_R8G8B8_SSCALED,
596 		VK_FORMAT_R8G8B8_UINT,
597 		VK_FORMAT_R8G8B8_SINT,
598 		VK_FORMAT_R8G8B8_SRGB,
599 		VK_FORMAT_R8G8B8A8_UNORM,
600 		VK_FORMAT_R8G8B8A8_SNORM,
601 		VK_FORMAT_R8G8B8A8_USCALED,
602 		VK_FORMAT_R8G8B8A8_SSCALED,
603 		VK_FORMAT_R8G8B8A8_UINT,
604 		VK_FORMAT_R8G8B8A8_SINT,
605 		VK_FORMAT_R8G8B8A8_SRGB,
606 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
607 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
608 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
609 		VK_FORMAT_R16_UNORM,
610 		VK_FORMAT_R16_SNORM,
611 		VK_FORMAT_R16_USCALED,
612 		VK_FORMAT_R16_SSCALED,
613 		VK_FORMAT_R16_UINT,
614 		VK_FORMAT_R16_SINT,
615 		VK_FORMAT_R16_SFLOAT,
616 		VK_FORMAT_R16G16_UNORM,
617 		VK_FORMAT_R16G16_SNORM,
618 		VK_FORMAT_R16G16_USCALED,
619 		VK_FORMAT_R16G16_SSCALED,
620 		VK_FORMAT_R16G16_UINT,
621 		VK_FORMAT_R16G16_SINT,
622 		VK_FORMAT_R16G16_SFLOAT,
623 		VK_FORMAT_R16G16B16_UNORM,
624 		VK_FORMAT_R16G16B16_SNORM,
625 		VK_FORMAT_R16G16B16_USCALED,
626 		VK_FORMAT_R16G16B16_SSCALED,
627 		VK_FORMAT_R16G16B16_UINT,
628 		VK_FORMAT_R16G16B16_SINT,
629 		VK_FORMAT_R16G16B16_SFLOAT,
630 		VK_FORMAT_R16G16B16A16_UNORM,
631 		VK_FORMAT_R16G16B16A16_SNORM,
632 		VK_FORMAT_R16G16B16A16_USCALED,
633 		VK_FORMAT_R16G16B16A16_SSCALED,
634 		VK_FORMAT_R16G16B16A16_UINT,
635 		VK_FORMAT_R16G16B16A16_SINT,
636 		VK_FORMAT_R16G16B16A16_SFLOAT,
637 		VK_FORMAT_R32_UINT,
638 		VK_FORMAT_R32_SINT,
639 		VK_FORMAT_R32_SFLOAT,
640 		VK_FORMAT_R32G32_UINT,
641 		VK_FORMAT_R32G32_SINT,
642 		VK_FORMAT_R32G32_SFLOAT,
643 		VK_FORMAT_R32G32B32_UINT,
644 		VK_FORMAT_R32G32B32_SINT,
645 		VK_FORMAT_R32G32B32_SFLOAT,
646 		VK_FORMAT_R32G32B32A32_UINT,
647 		VK_FORMAT_R32G32B32A32_SINT,
648 		VK_FORMAT_R32G32B32A32_SFLOAT,
649 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
650 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
651 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
652 		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
653 
654 		// Compressed formats
655 		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
656 		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
657 		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
658 		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
659 		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
660 		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
661 		VK_FORMAT_EAC_R11_UNORM_BLOCK,
662 		VK_FORMAT_EAC_R11_SNORM_BLOCK,
663 		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
664 		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
665 		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
666 		VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
667 		VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
668 		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
669 		VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
670 		VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
671 		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
672 		VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
673 		VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
674 		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
675 		VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
676 		VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
677 		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
678 		VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
679 		VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
680 		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
681 		VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
682 		VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
683 		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
684 		VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
685 		VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
686 		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
687 		VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
688 		VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
689 		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
690 		VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
691 		VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
692 		VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
693 	};
694 
695 	de::MovePtr<tcu::TestCaseGroup>	imageFormatTests(new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
696 
697 	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
698 	{
699 		const VkFormat	format = formats[formatNdx];
700 
701 		if (isCompressedFormat(format))
702 		{
703 			// Do not use compressed formats with 1D and 1D array textures.
704 			if (imageViewType == VK_IMAGE_VIEW_TYPE_1D || imageViewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
705 				break;
706 		}
707 
708 		de::MovePtr<tcu::TestCaseGroup>	formatGroup(new tcu::TestCaseGroup(testCtx,
709 			getFormatCaseName(format).c_str(),
710 			(std::string("Samples a texture of format ") + getFormatName(format)).c_str()));
711 		createImageCountTests(formatGroup.get(), testCtx, samplingType, imageViewType, format);
712 
713 		imageFormatTests->addChild(formatGroup.release());
714 	}
715 
716 	return imageFormatTests;
717 }
718 
createImageViewTypeTests(tcu::TestContext & testCtx,VkDescriptorType samplingType)719 de::MovePtr<tcu::TestCaseGroup> createImageViewTypeTests (tcu::TestContext& testCtx, VkDescriptorType samplingType)
720 {
721 	const struct
722 	{
723 		VkImageViewType		type;
724 		const char*			name;
725 	}
726 	imageViewTypes[] =
727 	{
728 		{ VK_IMAGE_VIEW_TYPE_1D,			"1d" },
729 		{ VK_IMAGE_VIEW_TYPE_1D_ARRAY,		"1d_array" },
730 		{ VK_IMAGE_VIEW_TYPE_2D,			"2d" },
731 		{ VK_IMAGE_VIEW_TYPE_2D_ARRAY,		"2d_array" },
732 		{ VK_IMAGE_VIEW_TYPE_3D,			"3d" },
733 		{ VK_IMAGE_VIEW_TYPE_CUBE,			"cube" },
734 		{ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,	"cube_array" }
735 	};
736 
737 	de::MovePtr<tcu::TestCaseGroup> imageViewTypeTests(new tcu::TestCaseGroup(testCtx, "view_type", ""));
738 
739 	for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
740 	{
741 		const VkImageViewType			viewType = imageViewTypes[viewTypeNdx].type;
742 		de::MovePtr<tcu::TestCaseGroup>	viewTypeGroup(new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
743 		de::MovePtr<tcu::TestCaseGroup>	formatTests = createImageFormatTests(testCtx, samplingType, viewType);
744 
745 		viewTypeGroup->addChild(formatTests.release());
746 		imageViewTypeTests->addChild(viewTypeGroup.release());
747 	}
748 
749 	return imageViewTypeTests;
750 }
751 
createImageSamplingTypeTests(tcu::TestContext & testCtx)752 de::MovePtr<tcu::TestCaseGroup> createImageSamplingTypeTests (tcu::TestContext& testCtx)
753 {
754 	VkDescriptorType samplingTypes[] =
755 	{
756 		VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
757 		VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
758 	};
759 
760 	de::MovePtr<tcu::TestCaseGroup> imageSamplingTypeTests(new tcu::TestCaseGroup(testCtx, "sampling_type", ""));
761 
762 	for (int smpTypeNdx = 0; smpTypeNdx < DE_LENGTH_OF_ARRAY(samplingTypes); smpTypeNdx++)
763 	{
764 		const char* smpTypeName = samplingTypes[smpTypeNdx] == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ? "combined" : "separate";
765 		de::MovePtr<tcu::TestCaseGroup>	samplingTypeGroup(new tcu::TestCaseGroup(testCtx, smpTypeName, (std::string("Uses a ") + smpTypeName + " sampler").c_str()));
766 		de::MovePtr<tcu::TestCaseGroup>	viewTypeTests = createImageViewTypeTests(testCtx, samplingTypes[smpTypeNdx]);
767 
768 		samplingTypeGroup->addChild(viewTypeTests.release());
769 		imageSamplingTypeTests->addChild(samplingTypeGroup.release());
770 	}
771 
772 	return imageSamplingTypeTests;
773 }
774 
775 } // anonymous
776 
createImageTests(tcu::TestContext & testCtx)777 tcu::TestCaseGroup* createImageTests (tcu::TestContext& testCtx)
778 {
779 	de::MovePtr<tcu::TestCaseGroup> imageTests(new tcu::TestCaseGroup(testCtx, "image", "Image tests"));
780 	de::MovePtr<tcu::TestCaseGroup> samplingTypeTests = createImageSamplingTypeTests(testCtx);
781 
782 	imageTests->addChild(samplingTypeTests.release());
783 
784 	return imageTests.release();
785 }
786 
787 } // pipeline
788 } // vkt
789