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