• 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 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 																 AllocationKind				allocationKind,
56 																 PipelineConstructionType	pipelineConstructionType,
57 																 VkDescriptorType			samplingType,
58 																 VkImageViewType			imageViewType,
59 																 VkFormat					imageFormat,
60 																 const tcu::IVec3&			imageSize,
61 																 int						imageCount,
62 																 int						arraySize,
63 																 bool						pipelineProtectedAccess,
64 																 bool						pipelineProtectedFlag);
65 
66 	ImageSamplingInstanceParams	getImageSamplingInstanceParams	(AllocationKind		allocationKind,
67 																 VkDescriptorType	samplingType,
68 																 VkImageViewType	imageViewType,
69 																 VkFormat			imageFormat,
70 																 const tcu::IVec3&	imageSize,
71 																 int				imageCount,
72 																 int				arraySize) const;
73 
74 	virtual void			initPrograms						(SourceCollections& sourceCollections) const;
75 	virtual void			checkSupport						(Context& context) const;
76 	virtual TestInstance*	createInstance						(Context& context) const;
77 	static std::string		getGlslSamplerType					(const tcu::TextureFormat& format, VkImageViewType type);
78 	static std::string		getGlslTextureType					(const tcu::TextureFormat& format, VkImageViewType type);
79 	static std::string		getGlslSamplerDecl					(int imageCount);
80 	static std::string		getGlslTextureDecl					(int imageCount);
81 	static std::string		getGlslFragColorDecl				(int imageCount);
82 	static std::string		getGlslSampler						(const tcu::TextureFormat&	format,
83 																 VkImageViewType			type,
84 																 VkDescriptorType			samplingType,
85 																 int						imageCount);
86 
87 private:
88 	AllocationKind				m_allocationKind;
89 	PipelineConstructionType	m_pipelineConstructionType;
90 	VkDescriptorType			m_samplingType;
91 	VkImageViewType				m_imageViewType;
92 	VkFormat					m_imageFormat;
93 	tcu::IVec3					m_imageSize;
94 	int							m_imageCount;
95 	int							m_arraySize;
96 	bool						m_pipelineProtectedAccess;
97 	bool						m_pipelineProtectedFlag;
98 };
99 
ImageTest(tcu::TestContext & testContext,const char * name,const char * description,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType,VkDescriptorType samplingType,VkImageViewType imageViewType,VkFormat imageFormat,const tcu::IVec3 & imageSize,int imageCount,int arraySize,bool pipelineProtectedAccess,bool pipelineProtectedFlag)100 ImageTest::ImageTest (tcu::TestContext&	testContext,
101 					  const char*				name,
102 					  const char*				description,
103 					  AllocationKind			allocationKind,
104 					  PipelineConstructionType	pipelineConstructionType,
105 					  VkDescriptorType			samplingType,
106 					  VkImageViewType			imageViewType,
107 					  VkFormat					imageFormat,
108 					  const tcu::IVec3&			imageSize,
109 					  int						imageCount,
110 					  int						arraySize,
111 					  bool						pipelineProtectedAccess,
112 					  bool						pipelineProtectedFlag)
113 
114 	: vkt::TestCase					(testContext, name, description)
115 	, m_allocationKind				(allocationKind)
116 	, m_pipelineConstructionType	(pipelineConstructionType)
117 	, m_samplingType				(samplingType)
118 	, m_imageViewType				(imageViewType)
119 	, m_imageFormat					(imageFormat)
120 	, m_imageSize					(imageSize)
121 	, m_imageCount					(imageCount)
122 	, m_arraySize					(arraySize)
123 	, m_pipelineProtectedAccess		(pipelineProtectedAccess)
124 	, m_pipelineProtectedFlag		(pipelineProtectedFlag)
125 {
126 }
127 
checkSupport(Context & context) const128 void ImageTest::checkSupport (Context& context) const
129 {
130 	// Using a loop to index into an array of images requires shaderSampledImageArrayDynamicIndexing
131 	if (m_imageCount > 1)
132 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING);
133 
134 	checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
135 	checkSupportImageSamplingInstance(context, getImageSamplingInstanceParams(m_allocationKind, m_samplingType, m_imageViewType, m_imageFormat, m_imageSize, m_imageCount, m_arraySize));
136 
137 	if (m_pipelineProtectedAccess) {
138 #ifndef CTS_USES_VULKANSC
139 		context.requireDeviceFunctionality("VK_EXT_pipeline_protected_access");
140 
141 		if (!context.getPipelineProtectedAccessFeaturesEXT().pipelineProtectedAccess)
142 		{
143 			throw tcu::NotSupportedError("pipelineProtectedAccess feature is not supported");
144 		}
145 #else // CTS_USES_VULKANSC
146 		throw tcu::NotSupportedError("pipeline protected access is not supported");
147 #endif // CTS_USES_VULKANSC
148 	}
149 }
150 
getImageSamplingInstanceParams(AllocationKind allocationKind,VkDescriptorType samplingType,VkImageViewType imageViewType,VkFormat imageFormat,const tcu::IVec3 & imageSize,int imageCount,int arraySize) const151 ImageSamplingInstanceParams ImageTest::getImageSamplingInstanceParams (AllocationKind		allocationKind,
152 																	   VkDescriptorType		samplingType,
153 																	   VkImageViewType		imageViewType,
154 																	   VkFormat				imageFormat,
155 																	   const tcu::IVec3&	imageSize,
156 																	   int					imageCount,
157 																	   int					arraySize) const
158 {
159 	tcu::UVec2 renderSize;
160 
161 	if (imageViewType == VK_IMAGE_VIEW_TYPE_1D || imageViewType == VK_IMAGE_VIEW_TYPE_2D)
162 	{
163 		renderSize = tcu::UVec2((deUint32)imageSize.x(), (deUint32)imageSize.y());
164 	}
165 	else
166 	{
167 		// Draw a 3x2 grid of texture layers
168 		renderSize = tcu::UVec2((deUint32)imageSize.x() * 3, (deUint32)imageSize.y() * 2);
169 	}
170 
171 	const bool						separateStencilUsage	= false;
172 	const std::vector<Vertex4Tex4>	vertices				= createTestQuadMosaic(imageViewType);
173 	const VkComponentMapping		componentMapping		= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
174 	const VkImageSubresourceRange	subresourceRange		=
175 	{
176 		VK_IMAGE_ASPECT_COLOR_BIT,
177 		0u,
178 		(deUint32)deLog2Floor32(deMax32(imageSize.x(), deMax32(imageSize.y(), imageSize.z()))) + 1,
179 		0u,
180 		(deUint32)arraySize,
181 	};
182 
183 	const VkSamplerCreateInfo samplerParams =
184 	{
185 		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,										// VkStructureType			sType;
186 		DE_NULL,																	// const void*				pNext;
187 		0u,																			// VkSamplerCreateFlags		flags;
188 		VK_FILTER_NEAREST,															// VkFilter					magFilter;
189 		VK_FILTER_NEAREST,															// VkFilter					minFilter;
190 		VK_SAMPLER_MIPMAP_MODE_NEAREST,												// VkSamplerMipmapMode		mipmapMode;
191 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,										// VkSamplerAddressMode		addressModeU;
192 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,										// VkSamplerAddressMode		addressModeV;
193 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,										// VkSamplerAddressMode		addressModeW;
194 		0.0f,																		// float					mipLodBias;
195 		VK_FALSE,																	// VkBool32					anisotropyEnable;
196 		1.0f,																		// float					maxAnisotropy;
197 		false,																		// VkBool32					compareEnable;
198 		VK_COMPARE_OP_NEVER,														// VkCompareOp				compareOp;
199 		0.0f,																		// float					minLod;
200 		(float)(subresourceRange.levelCount - 1),									// float					maxLod;
201 		getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, imageFormat, false),	// VkBorderColor			borderColor;
202 		false																		// VkBool32					unnormalizedCoordinates;
203 	};
204 
205 #ifdef CTS_USES_VULKANSC
206 	const vk::VkPipelineCreateFlags pipelineFlags = (vk::VkPipelineCreateFlagBits)0u;
207 	(void)m_pipelineProtectedFlag;
208 #else // CTS_USES_VULKANSC
209 	const vk::VkPipelineCreateFlags pipelineFlags = m_pipelineProtectedFlag ? vk::VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT : (vk::VkPipelineCreateFlagBits)0u;
210 #endif // CTS_USES_VULKANSC
211 
212 	return ImageSamplingInstanceParams(m_pipelineConstructionType, renderSize, imageViewType, imageFormat, imageSize, arraySize, componentMapping, subresourceRange, samplerParams, 0.0f, vertices, separateStencilUsage, samplingType, imageCount, allocationKind, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, pipelineFlags);
213 }
214 
initPrograms(SourceCollections & sourceCollections) const215 void ImageTest::initPrograms (SourceCollections& sourceCollections) const
216 {
217 	std::ostringstream				vertexSrc;
218 	std::ostringstream				fragmentSrc;
219 	const char*						texCoordSwizzle	= DE_NULL;
220 	const tcu::TextureFormat		format			= (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat))
221 																						  : mapVkFormat(m_imageFormat);
222 
223 	tcu::Vec4						lookupScale;
224 	tcu::Vec4						lookupBias;
225 
226 	getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
227 
228 	switch (m_imageViewType)
229 	{
230 		case VK_IMAGE_VIEW_TYPE_1D:
231 			texCoordSwizzle = "x";
232 			break;
233 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
234 		case VK_IMAGE_VIEW_TYPE_2D:
235 			texCoordSwizzle = "xy";
236 			break;
237 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
238 		case VK_IMAGE_VIEW_TYPE_3D:
239 		case VK_IMAGE_VIEW_TYPE_CUBE:
240 			texCoordSwizzle = "xyz";
241 			break;
242 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
243 			texCoordSwizzle = "xyzw";
244 			break;
245 		default:
246 			DE_ASSERT(false);
247 			break;
248 	}
249 
250 	vertexSrc << "#version 440\n"
251 			  << "layout(location = 0) in vec4 position;\n"
252 			  << "layout(location = 1) in vec4 texCoords;\n"
253 			  << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
254 			  << "out gl_PerVertex {\n"
255 			  << "	vec4 gl_Position;\n"
256 			  << "};\n"
257 			  << "void main (void)\n"
258 			  << "{\n"
259 			  << "	gl_Position = position;\n"
260 			  << "	vtxTexCoords = texCoords;\n"
261 			  << "}\n";
262 
263 	fragmentSrc << "#version 440\n";
264 	switch (m_samplingType)
265 	{
266 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
267 			fragmentSrc
268 				<< "layout(set = 0, binding = 0) uniform highp sampler texSampler;\n"
269 				<< "layout(set = 0, binding = 1) uniform highp " << getGlslTextureType(format, m_imageViewType) << " " << getGlslTextureDecl(m_imageCount) << ";\n";
270 			break;
271 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
272 		default:
273 			fragmentSrc
274 				<< "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " " << getGlslSamplerDecl(m_imageCount) << ";\n";
275 	}
276 	fragmentSrc << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
277 				<< "layout(location = 0) out highp vec4 " << getGlslFragColorDecl(m_imageCount) << ";\n"
278 				<< "void main (void)\n"
279 				<< "{\n";
280 	if (m_imageCount > 1)
281 		fragmentSrc
282 				<< "	for (uint i = 0; i < " << m_imageCount << "; ++i)\n"
283 				<< "		fragColors[i] = (texture(" << getGlslSampler(format, m_imageViewType, m_samplingType, m_imageCount) << ", vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << lookupScale << ") + vec4" << lookupBias << "; \n";
284 	else
285 		fragmentSrc
286 				<< "	fragColor = (texture(" << getGlslSampler(format, m_imageViewType, m_samplingType, m_imageCount) << ", vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << lookupScale << ") + vec4" << lookupBias << "; \n";
287 	fragmentSrc << "}\n";
288 
289 	sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
290 	sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
291 }
292 
createInstance(Context & context) const293 TestInstance* ImageTest::createInstance (Context& context) const
294 {
295 	return new ImageSamplingInstance(context, getImageSamplingInstanceParams(m_allocationKind, m_samplingType, m_imageViewType, m_imageFormat, m_imageSize, m_imageCount, m_arraySize));
296 }
297 
getGlslSamplerType(const tcu::TextureFormat & format,VkImageViewType type)298 std::string ImageTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
299 {
300 	std::ostringstream samplerType;
301 
302 	if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
303 		samplerType << "u";
304 	else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
305 		samplerType << "i";
306 
307 	switch (type)
308 	{
309 		case VK_IMAGE_VIEW_TYPE_1D:
310 			samplerType << "sampler1D";
311 			break;
312 
313 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
314 			samplerType << "sampler1DArray";
315 			break;
316 
317 		case VK_IMAGE_VIEW_TYPE_2D:
318 			samplerType << "sampler2D";
319 			break;
320 
321 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
322 			samplerType << "sampler2DArray";
323 			break;
324 
325 		case VK_IMAGE_VIEW_TYPE_3D:
326 			samplerType << "sampler3D";
327 			break;
328 
329 		case VK_IMAGE_VIEW_TYPE_CUBE:
330 			samplerType << "samplerCube";
331 			break;
332 
333 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
334 			samplerType << "samplerCubeArray";
335 			break;
336 
337 		default:
338 			DE_FATAL("Unknown image view type");
339 			break;
340 	}
341 
342 	return samplerType.str();
343 }
344 
getGlslTextureType(const tcu::TextureFormat & format,VkImageViewType type)345 std::string ImageTest::getGlslTextureType (const tcu::TextureFormat& format, VkImageViewType type)
346 {
347 	std::ostringstream textureType;
348 
349 	if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
350 		textureType << "u";
351 	else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
352 		textureType << "i";
353 
354 	switch (type)
355 	{
356 		case VK_IMAGE_VIEW_TYPE_1D:
357 			textureType << "texture1D";
358 			break;
359 
360 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
361 			textureType << "texture1DArray";
362 			break;
363 
364 		case VK_IMAGE_VIEW_TYPE_2D:
365 			textureType << "texture2D";
366 			break;
367 
368 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
369 			textureType << "texture2DArray";
370 			break;
371 
372 		case VK_IMAGE_VIEW_TYPE_3D:
373 			textureType << "texture3D";
374 			break;
375 
376 		case VK_IMAGE_VIEW_TYPE_CUBE:
377 			textureType << "textureCube";
378 			break;
379 
380 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
381 			textureType << "textureCubeArray";
382 			break;
383 
384 		default:
385 			DE_FATAL("Unknown image view type");
386 	}
387 
388 	return textureType.str();
389 }
390 
getGlslSamplerDecl(int imageCount)391 std::string ImageTest::getGlslSamplerDecl (int imageCount)
392 {
393 	std::ostringstream samplerArray;
394 	samplerArray << "texSamplers[" << imageCount << "]";
395 
396 	return imageCount > 1 ? samplerArray.str() : "texSampler";
397 }
398 
getGlslTextureDecl(int imageCount)399 std::string ImageTest::getGlslTextureDecl (int imageCount)
400 {
401 	std::ostringstream textureArray;
402 	textureArray << "texImages[" << imageCount << "]";
403 
404 	return imageCount > 1 ? textureArray.str() : "texImage";
405 }
406 
getGlslFragColorDecl(int imageCount)407 std::string ImageTest::getGlslFragColorDecl (int imageCount)
408 {
409 	std::ostringstream samplerArray;
410 	samplerArray << "fragColors[" << imageCount << "]";
411 
412 	return imageCount > 1 ? samplerArray.str() : "fragColor";
413 }
414 
getGlslSampler(const tcu::TextureFormat & format,VkImageViewType type,VkDescriptorType samplingType,int imageCount)415 std::string ImageTest::getGlslSampler (const tcu::TextureFormat& format, VkImageViewType type, VkDescriptorType samplingType, int imageCount)
416 {
417 	std::string texSampler	= imageCount > 1 ? "texSamplers[i]" : "texSampler";
418 	std::string texImage	= imageCount > 1 ? "texImages[i]" : "texImage";
419 
420 	switch (samplingType)
421 	{
422 		case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
423 			return getGlslSamplerType(format, type) + "(" + texImage + ", texSampler)";
424 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
425 		default:
426 			return texSampler;
427 	}
428 }
429 
getFormatCaseName(const VkFormat format)430 std::string getFormatCaseName (const VkFormat format)
431 {
432 	const std::string	fullName	= getFormatName(format);
433 
434 	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
435 
436 	return de::toLower(fullName.substr(10));
437 }
438 
getSizeName(VkImageViewType viewType,const tcu::IVec3 & size,int arraySize,bool pipelineProtectedAccess,bool pipelineProtectedFlag)439 std::string getSizeName (VkImageViewType viewType, const tcu::IVec3& size, int arraySize, bool pipelineProtectedAccess, bool pipelineProtectedFlag)
440 {
441 	std::ostringstream	caseName;
442 
443 	if (pipelineProtectedAccess) {
444 		caseName << "pipeline_protected_access_";
445 	}
446 	if (pipelineProtectedFlag) {
447 		caseName << "pipeline_protected_flag_";
448 	}
449 
450 	switch (viewType)
451 	{
452 		case VK_IMAGE_VIEW_TYPE_1D:
453 		case VK_IMAGE_VIEW_TYPE_2D:
454 		case VK_IMAGE_VIEW_TYPE_CUBE:
455 			caseName << size.x() << "x" << size.y();
456 			break;
457 
458 		case VK_IMAGE_VIEW_TYPE_3D:
459 			caseName << size.x() << "x" << size.y() << "x" << size.z();
460 			break;
461 
462 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
463 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
464 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
465 			caseName << size.x() << "x" << size.y() << "_array_of_" << arraySize;
466 			break;
467 
468 		default:
469 			DE_ASSERT(false);
470 			break;
471 	}
472 
473 	return caseName.str();
474 }
475 
createImageSizeTests(tcu::TestContext & testCtx,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType,VkDescriptorType samplingType,VkImageViewType imageViewType,VkFormat imageFormat,int imageCount)476 de::MovePtr<tcu::TestCaseGroup> createImageSizeTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType, VkImageViewType imageViewType, VkFormat imageFormat, int imageCount)
477 {
478 	using tcu::IVec3;
479 
480 	std::vector<IVec3>					imageSizes;
481 	std::vector<int>					arraySizes;
482 	de::MovePtr<tcu::TestCaseGroup>		imageSizeTests	(new tcu::TestCaseGroup(testCtx, "size", ""));
483 
484 	const bool pipelineProtectedAccess[] = {
485 		false,
486 #ifndef CTS_USES_VULKANSC
487 		true,
488 #endif
489 	};
490 	const bool pipelineProtectedFlag[] = {
491 		false,
492 #ifndef CTS_USES_VULKANSC
493 		true,
494 #endif
495 	};
496 
497 	// Select image imageSizes
498 	switch (imageViewType)
499 	{
500 		case VK_IMAGE_VIEW_TYPE_1D:
501 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
502 			// POT
503 			if (imageCount == 1)
504 			{
505 				imageSizes.push_back(IVec3(1, 1, 1));
506 				imageSizes.push_back(IVec3(2, 1, 1));
507 				imageSizes.push_back(IVec3(32, 1, 1));
508 				imageSizes.push_back(IVec3(128, 1, 1));
509 			}
510 			imageSizes.push_back(IVec3(512, 1, 1));
511 
512 			// NPOT
513 			if (imageCount == 1)
514 			{
515 				imageSizes.push_back(IVec3(3, 1, 1));
516 				imageSizes.push_back(IVec3(13, 1, 1));
517 				imageSizes.push_back(IVec3(127, 1, 1));
518 			}
519 			imageSizes.push_back(IVec3(443, 1, 1));
520 			break;
521 
522 		case VK_IMAGE_VIEW_TYPE_2D:
523 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
524 			if (imageCount == 1)
525 			{
526 				// POT
527 				imageSizes.push_back(IVec3(1, 1, 1));
528 				imageSizes.push_back(IVec3(2, 2, 1));
529 				imageSizes.push_back(IVec3(32, 32, 1));
530 
531 				// NPOT
532 				imageSizes.push_back(IVec3(3, 3, 1));
533 				imageSizes.push_back(IVec3(13, 13, 1));
534 			}
535 
536 			// POT rectangular
537 			if (imageCount == 1)
538 				imageSizes.push_back(IVec3(8, 16, 1));
539 			imageSizes.push_back(IVec3(32, 16, 1));
540 
541 			// NPOT rectangular
542 			imageSizes.push_back(IVec3(13, 23, 1));
543 			if (imageCount == 1)
544 				imageSizes.push_back(IVec3(23, 8, 1));
545 			break;
546 
547 		case VK_IMAGE_VIEW_TYPE_3D:
548 			// POT cube
549 			if (imageCount == 1)
550 			{
551 				imageSizes.push_back(IVec3(1, 1, 1));
552 				imageSizes.push_back(IVec3(2, 2, 2));
553 			}
554 			imageSizes.push_back(IVec3(16, 16, 16));
555 
556 			// NPOT cube
557 			if (imageCount == 1)
558 			{
559 				imageSizes.push_back(IVec3(3, 3, 3));
560 				imageSizes.push_back(IVec3(5, 5, 5));
561 			}
562 			imageSizes.push_back(IVec3(11, 11, 11));
563 
564 			// POT non-cube
565 			if (imageCount == 1)
566 				imageSizes.push_back(IVec3(32, 16, 8));
567 			imageSizes.push_back(IVec3(8, 16, 32));
568 
569 			// NPOT non-cube
570 			imageSizes.push_back(IVec3(17, 11, 5));
571 			if (imageCount == 1)
572 				imageSizes.push_back(IVec3(5, 11, 17));
573 			break;
574 
575 		case VK_IMAGE_VIEW_TYPE_CUBE:
576 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
577 			// POT
578 			imageSizes.push_back(IVec3(32, 32, 1));
579 
580 			// NPOT
581 			imageSizes.push_back(IVec3(13, 13, 1));
582 			break;
583 
584 		default:
585 			DE_ASSERT(false);
586 			break;
587 	}
588 
589 	// Select array sizes
590 	switch (imageViewType)
591 	{
592 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
593 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
594 			if (imageCount == 1)
595 				arraySizes.push_back(3);
596 			arraySizes.push_back(6);
597 			break;
598 
599 		case VK_IMAGE_VIEW_TYPE_CUBE:
600 			arraySizes.push_back(6);
601 			break;
602 
603 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
604 			if (imageCount == 1)
605 				arraySizes.push_back(6);
606 			arraySizes.push_back(6 * 6);
607 			break;
608 
609 		default:
610 			arraySizes.push_back(1);
611 			break;
612 	}
613 
614 	for (size_t protectedNdx = 0; protectedNdx < DE_LENGTH_OF_ARRAY(pipelineProtectedAccess); ++protectedNdx) {
615 		for (size_t flagNdx = 0; flagNdx < DE_LENGTH_OF_ARRAY(pipelineProtectedAccess); ++flagNdx) {
616 			if (!pipelineProtectedAccess[protectedNdx] && pipelineProtectedFlag[flagNdx]) continue;
617 
618 			for (size_t sizeNdx = 0; sizeNdx < imageSizes.size(); sizeNdx++)
619 			{
620 				for (size_t arraySizeNdx = 0; arraySizeNdx < arraySizes.size(); arraySizeNdx++)
621 				{
622 					imageSizeTests->addChild(new ImageTest(testCtx,
623 														   getSizeName(imageViewType, imageSizes[sizeNdx], arraySizes[arraySizeNdx], pipelineProtectedAccess[protectedNdx], pipelineProtectedFlag[flagNdx]).c_str(),
624 														   "",
625 														   allocationKind,
626 														   pipelineConstructionType,
627 														   samplingType,
628 														   imageViewType,
629 														   imageFormat,
630 														   imageSizes[sizeNdx],
631 														   imageCount,
632 														   arraySizes[arraySizeNdx],
633 														   pipelineProtectedAccess[protectedNdx],
634 														   pipelineProtectedFlag[flagNdx]));
635 				}
636 			}
637 		}
638 	}
639 
640 	return imageSizeTests;
641 }
642 
createImageCountTests(tcu::TestCaseGroup * parentGroup,tcu::TestContext & testCtx,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType,VkDescriptorType samplingType,VkImageViewType imageViewType,VkFormat imageFormat)643 void createImageCountTests (tcu::TestCaseGroup* parentGroup, tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType, VkImageViewType imageViewType, VkFormat imageFormat)
644 {
645 	const int		coreImageCounts[]					= { 1, 4, 8 };
646 	const int		dedicatedAllocationImageCounts[]	= { 1 };
647 	const int*		imageCounts							= (allocationKind == ALLOCATION_KIND_DEDICATED)
648 														  ? dedicatedAllocationImageCounts
649 														  : coreImageCounts;
650 	const size_t	imageCountsLength					= (allocationKind == ALLOCATION_KIND_DEDICATED)
651 														  ? DE_LENGTH_OF_ARRAY(dedicatedAllocationImageCounts)
652 														  : DE_LENGTH_OF_ARRAY(coreImageCounts);
653 
654 	for (size_t countNdx = 0; countNdx < imageCountsLength; countNdx++)
655 	{
656 		std::ostringstream	caseName;
657 		caseName << "count_" << imageCounts[countNdx];
658 		de::MovePtr<tcu::TestCaseGroup>	countGroup(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
659 		de::MovePtr<tcu::TestCaseGroup> sizeTests = createImageSizeTests(testCtx, allocationKind, pipelineConstructionType, samplingType, imageViewType, imageFormat, imageCounts[countNdx]);
660 
661 		countGroup->addChild(sizeTests.release());
662 		parentGroup->addChild(countGroup.release());
663 	}
664 }
665 
createImageFormatTests(tcu::TestContext & testCtx,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType,VkDescriptorType samplingType,VkImageViewType imageViewType)666 de::MovePtr<tcu::TestCaseGroup> createImageFormatTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType, VkImageViewType imageViewType)
667 {
668 	// All supported dEQP formats that are not intended for depth or stencil.
669 	const VkFormat coreFormats[]					=
670 	{
671 		VK_FORMAT_R4G4_UNORM_PACK8,
672 		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
673 		VK_FORMAT_R5G6B5_UNORM_PACK16,
674 		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
675 		VK_FORMAT_R8_UNORM,
676 		VK_FORMAT_R8_SNORM,
677 		VK_FORMAT_R8_USCALED,
678 		VK_FORMAT_R8_SSCALED,
679 		VK_FORMAT_R8_UINT,
680 		VK_FORMAT_R8_SINT,
681 		VK_FORMAT_R8_SRGB,
682 		VK_FORMAT_R8G8_UNORM,
683 		VK_FORMAT_R8G8_SNORM,
684 		VK_FORMAT_R8G8_USCALED,
685 		VK_FORMAT_R8G8_SSCALED,
686 		VK_FORMAT_R8G8_UINT,
687 		VK_FORMAT_R8G8_SINT,
688 		VK_FORMAT_R8G8_SRGB,
689 		VK_FORMAT_R8G8B8_UNORM,
690 		VK_FORMAT_R8G8B8_SNORM,
691 		VK_FORMAT_R8G8B8_USCALED,
692 		VK_FORMAT_R8G8B8_SSCALED,
693 		VK_FORMAT_R8G8B8_UINT,
694 		VK_FORMAT_R8G8B8_SINT,
695 		VK_FORMAT_R8G8B8_SRGB,
696 		VK_FORMAT_R8G8B8A8_UNORM,
697 		VK_FORMAT_R8G8B8A8_SNORM,
698 		VK_FORMAT_R8G8B8A8_USCALED,
699 		VK_FORMAT_R8G8B8A8_SSCALED,
700 		VK_FORMAT_R8G8B8A8_UINT,
701 		VK_FORMAT_R8G8B8A8_SINT,
702 		VK_FORMAT_R8G8B8A8_SRGB,
703 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
704 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
705 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
706 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
707 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
708 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
709 		VK_FORMAT_R16_UNORM,
710 		VK_FORMAT_R16_SNORM,
711 		VK_FORMAT_R16_USCALED,
712 		VK_FORMAT_R16_SSCALED,
713 		VK_FORMAT_R16_UINT,
714 		VK_FORMAT_R16_SINT,
715 		VK_FORMAT_R16_SFLOAT,
716 		VK_FORMAT_R16G16_UNORM,
717 		VK_FORMAT_R16G16_SNORM,
718 		VK_FORMAT_R16G16_USCALED,
719 		VK_FORMAT_R16G16_SSCALED,
720 		VK_FORMAT_R16G16_UINT,
721 		VK_FORMAT_R16G16_SINT,
722 		VK_FORMAT_R16G16_SFLOAT,
723 		VK_FORMAT_R16G16B16_UNORM,
724 		VK_FORMAT_R16G16B16_SNORM,
725 		VK_FORMAT_R16G16B16_USCALED,
726 		VK_FORMAT_R16G16B16_SSCALED,
727 		VK_FORMAT_R16G16B16_UINT,
728 		VK_FORMAT_R16G16B16_SINT,
729 		VK_FORMAT_R16G16B16_SFLOAT,
730 		VK_FORMAT_R16G16B16A16_UNORM,
731 		VK_FORMAT_R16G16B16A16_SNORM,
732 		VK_FORMAT_R16G16B16A16_USCALED,
733 		VK_FORMAT_R16G16B16A16_SSCALED,
734 		VK_FORMAT_R16G16B16A16_UINT,
735 		VK_FORMAT_R16G16B16A16_SINT,
736 		VK_FORMAT_R16G16B16A16_SFLOAT,
737 		VK_FORMAT_R32_UINT,
738 		VK_FORMAT_R32_SINT,
739 		VK_FORMAT_R32_SFLOAT,
740 		VK_FORMAT_R32G32_UINT,
741 		VK_FORMAT_R32G32_SINT,
742 		VK_FORMAT_R32G32_SFLOAT,
743 		VK_FORMAT_R32G32B32_UINT,
744 		VK_FORMAT_R32G32B32_SINT,
745 		VK_FORMAT_R32G32B32_SFLOAT,
746 		VK_FORMAT_R32G32B32A32_UINT,
747 		VK_FORMAT_R32G32B32A32_SINT,
748 		VK_FORMAT_R32G32B32A32_SFLOAT,
749 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
750 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
751 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
752 		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
753 		VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
754 		VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
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 	// Formats to test with dedicated allocation
797 	const VkFormat	dedicatedAllocationFormats[]	=
798 	{
799 		VK_FORMAT_R8G8B8A8_UNORM,
800 		VK_FORMAT_R16_SFLOAT,
801 	};
802 	const VkFormat*	formats							= (allocationKind == ALLOCATION_KIND_DEDICATED)
803 													  ? dedicatedAllocationFormats
804 													  : coreFormats;
805 	const size_t	formatsLength					= (allocationKind == ALLOCATION_KIND_DEDICATED)
806 													  ? DE_LENGTH_OF_ARRAY(dedicatedAllocationFormats)
807 													  : DE_LENGTH_OF_ARRAY(coreFormats);
808 
809 	de::MovePtr<tcu::TestCaseGroup>	imageFormatTests(new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
810 
811 	for (size_t formatNdx = 0; formatNdx < formatsLength; formatNdx++)
812 	{
813 		const VkFormat	format = formats[formatNdx];
814 
815 		if (isCompressedFormat(format))
816 		{
817 			// Do not use compressed formats with 1D and 1D array textures.
818 			if (imageViewType == VK_IMAGE_VIEW_TYPE_1D || imageViewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
819 				break;
820 		}
821 
822 		de::MovePtr<tcu::TestCaseGroup>	formatGroup(new tcu::TestCaseGroup(testCtx,
823 			getFormatCaseName(format).c_str(),
824 			(std::string("Samples a texture of format ") + getFormatName(format)).c_str()));
825 		createImageCountTests(formatGroup.get(), testCtx, allocationKind, pipelineConstructionType, samplingType, imageViewType, format);
826 
827 		imageFormatTests->addChild(formatGroup.release());
828 	}
829 
830 	return imageFormatTests;
831 }
832 
createImageViewTypeTests(tcu::TestContext & testCtx,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType,VkDescriptorType samplingType)833 de::MovePtr<tcu::TestCaseGroup> createImageViewTypeTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType)
834 {
835 	const struct
836 	{
837 		VkImageViewType		type;
838 		const char*			name;
839 	}
840 	imageViewTypes[] =
841 	{
842 		{ VK_IMAGE_VIEW_TYPE_1D,			"1d" },
843 		{ VK_IMAGE_VIEW_TYPE_1D_ARRAY,		"1d_array" },
844 		{ VK_IMAGE_VIEW_TYPE_2D,			"2d" },
845 		{ VK_IMAGE_VIEW_TYPE_2D_ARRAY,		"2d_array" },
846 		{ VK_IMAGE_VIEW_TYPE_3D,			"3d" },
847 		{ VK_IMAGE_VIEW_TYPE_CUBE,			"cube" },
848 		{ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,	"cube_array" }
849 	};
850 
851 	de::MovePtr<tcu::TestCaseGroup> imageViewTypeTests(new tcu::TestCaseGroup(testCtx, "view_type", ""));
852 
853 	for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
854 	{
855 		const VkImageViewType			viewType = imageViewTypes[viewTypeNdx].type;
856 		de::MovePtr<tcu::TestCaseGroup>	viewTypeGroup(new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
857 		de::MovePtr<tcu::TestCaseGroup>	formatTests = createImageFormatTests(testCtx, allocationKind, pipelineConstructionType, samplingType, viewType);
858 
859 		viewTypeGroup->addChild(formatTests.release());
860 		imageViewTypeTests->addChild(viewTypeGroup.release());
861 	}
862 
863 	return imageViewTypeTests;
864 }
865 
createImageSamplingTypeTests(tcu::TestContext & testCtx,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType)866 de::MovePtr<tcu::TestCaseGroup> createImageSamplingTypeTests (tcu::TestContext& testCtx, AllocationKind allocationKind, PipelineConstructionType pipelineConstructionType)
867 {
868 	VkDescriptorType samplingTypes[] =
869 	{
870 		VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
871 		VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
872 	};
873 
874 	de::MovePtr<tcu::TestCaseGroup> imageSamplingTypeTests(new tcu::TestCaseGroup(testCtx, "sampling_type", ""));
875 
876 	for (int smpTypeNdx = 0; smpTypeNdx < DE_LENGTH_OF_ARRAY(samplingTypes); smpTypeNdx++)
877 	{
878 		const char* smpTypeName = samplingTypes[smpTypeNdx] == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ? "combined" : "separate";
879 		de::MovePtr<tcu::TestCaseGroup>	samplingTypeGroup(new tcu::TestCaseGroup(testCtx, smpTypeName, (std::string("Uses a ") + smpTypeName + " sampler").c_str()));
880 		de::MovePtr<tcu::TestCaseGroup>	viewTypeTests = createImageViewTypeTests(testCtx, allocationKind, pipelineConstructionType, samplingTypes[smpTypeNdx]);
881 
882 		samplingTypeGroup->addChild(viewTypeTests.release());
883 		imageSamplingTypeTests->addChild(samplingTypeGroup.release());
884 	}
885 
886 	return imageSamplingTypeTests;
887 }
888 
createSuballocationTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)889 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
890 {
891 	de::MovePtr<tcu::TestCaseGroup>	suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation Image Tests"));
892 	de::MovePtr<tcu::TestCaseGroup>	samplingTypeTests = createImageSamplingTypeTests(testCtx, ALLOCATION_KIND_SUBALLOCATED, pipelineConstructionType);
893 
894 	suballocationTestsGroup->addChild(samplingTypeTests.release());
895 
896 	return suballocationTestsGroup;
897 }
898 
createDedicatedAllocationTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)899 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
900 {
901 	de::MovePtr<tcu::TestCaseGroup>	dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "Image Tests For Dedicated Allocation"));
902 	de::MovePtr<tcu::TestCaseGroup>	samplingTypeTests = createImageSamplingTypeTests(testCtx, ALLOCATION_KIND_DEDICATED, pipelineConstructionType);
903 
904 	dedicatedAllocationTestsGroup->addChild(samplingTypeTests.release());
905 
906 	return dedicatedAllocationTestsGroup;
907 }
908 } // anonymous
909 
createImageTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)910 tcu::TestCaseGroup* createImageTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
911 {
912 	de::MovePtr<tcu::TestCaseGroup> imageTests(new tcu::TestCaseGroup(testCtx, "image", "Image tests"));
913 	de::MovePtr<tcu::TestCaseGroup> imageSuballocationTests = createSuballocationTests(testCtx, pipelineConstructionType);
914 	de::MovePtr<tcu::TestCaseGroup> imageDedicatedAllocationTests = createDedicatedAllocationTests(testCtx, pipelineConstructionType);
915 
916 	imageTests->addChild(imageSuballocationTests.release());
917 	imageTests->addChild(imageDedicatedAllocationTests.release());
918 
919 	return imageTests.release();
920 }
921 
922 } // pipeline
923 } // vkt
924