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 Sampler Tests
     23  *//*--------------------------------------------------------------------*/
     24 
     25 #include "vktPipelineSamplerTests.hpp"
     26 #include "vktPipelineImageSamplingInstance.hpp"
     27 #include "vktPipelineImageUtil.hpp"
     28 #include "vktPipelineVertexUtil.hpp"
     29 #include "vktTestCase.hpp"
     30 #include "vkImageUtil.hpp"
     31 #include "vkPrograms.hpp"
     32 #include "tcuPlatform.hpp"
     33 #include "tcuTextureUtil.hpp"
     34 #include "deStringUtil.hpp"
     35 #include "deMemory.h"
     36 
     37 #include <iomanip>
     38 #include <sstream>
     39 #include <vector>
     40 
     41 namespace vkt
     42 {
     43 namespace pipeline
     44 {
     45 
     46 using namespace vk;
     47 using de::MovePtr;
     48 
     49 namespace
     50 {
     51 
     52 class SamplerTest : public vkt::TestCase
     53 {
     54 public:
     55 										SamplerTest				(tcu::TestContext&	testContext,
     56 																 const char*		name,
     57 																 const char*		description,
     58 																 VkImageViewType	imageViewType,
     59 																 VkFormat			imageFormat,
     60 																 int				imageSize,
     61 																 float				samplerLod);
     62 	virtual								~SamplerTest			(void) {}
     63 
     64 	virtual void						initPrograms			(SourceCollections& sourceCollections) const;
     65 	virtual TestInstance*				createInstance			(Context& context) const;
     66 	virtual tcu::UVec2					getRenderSize			(VkImageViewType viewType) const;
     67 	virtual std::vector<Vertex4Tex4>	createVertices			(void) const;
     68 	virtual VkSamplerCreateInfo			getSamplerCreateInfo	(void) const;
     69 
     70 	static std::string					getGlslSamplerType		(const tcu::TextureFormat& format, VkImageViewType type);
     71 	static tcu::IVec3					getImageSize			(VkImageViewType viewType, int size);
     72 	static int							getArraySize			(VkImageViewType viewType);
     73 
     74 protected:
     75 	VkImageViewType						m_imageViewType;
     76 	VkFormat							m_imageFormat;
     77 	int									m_imageSize;
     78 	VkImageViewCreateInfo				m_imageViewParams;
     79 	VkSamplerCreateInfo					m_samplerParams;
     80 	float								m_samplerLod;
     81 };
     82 
     83 class SamplerMagFilterTest : public SamplerTest
     84 {
     85 public:
     86 									SamplerMagFilterTest	(tcu::TestContext&	testContext,
     87 															 const char*		name,
     88 															 const char*		description,
     89 															 VkImageViewType	imageViewType,
     90 															 VkFormat			imageFormat,
     91 															 VkFilter			magFilter);
     92 	virtual							~SamplerMagFilterTest	(void) {}
     93 	virtual VkSamplerCreateInfo		getSamplerCreateInfo	(void) const;
     94 
     95 private:
     96 	VkFilter						m_magFilter;
     97 };
     98 
     99 class SamplerMinFilterTest : public SamplerTest
    100 {
    101 public:
    102 									SamplerMinFilterTest	(tcu::TestContext&	testContext,
    103 															 const char*		name,
    104 															 const char*		description,
    105 															 VkImageViewType	imageViewType,
    106 															 VkFormat			imageFormat,
    107 															 VkFilter			minFilter);
    108 	virtual							~SamplerMinFilterTest	(void) {}
    109 	virtual VkSamplerCreateInfo		getSamplerCreateInfo	(void) const;
    110 
    111 private:
    112 	VkFilter						m_minFilter;
    113 };
    114 
    115 class SamplerLodTest : public SamplerTest
    116 {
    117 public:
    118 									SamplerLodTest			(tcu::TestContext&		testContext,
    119 															 const char*			name,
    120 															 const char*			description,
    121 															 VkImageViewType		imageViewType,
    122 															 VkFormat				imageFormat,
    123 															 VkSamplerMipmapMode	mipmapMode,
    124 															 float					minLod,
    125 															 float					maxLod,
    126 															 float					mipLodBias,
    127 															 float					samplerLod);
    128 	virtual							~SamplerLodTest			(void) {}
    129 	virtual VkSamplerCreateInfo		getSamplerCreateInfo	(void) const;
    130 
    131 private:
    132 	VkSamplerMipmapMode				m_mipmapMode;
    133 	float							m_minLod;
    134 	float							m_maxLod;
    135 	float							m_mipLodBias;
    136 };
    137 
    138 class SamplerAddressModesTest : public SamplerTest
    139 {
    140 public:
    141 										SamplerAddressModesTest		(tcu::TestContext&		testContext,
    142 																	 const char*			name,
    143 																	 const char*			description,
    144 																	 VkImageViewType		imageViewType,
    145 																	 VkFormat				imageFormat,
    146 																	 VkSamplerAddressMode	addressU,
    147 																	 VkSamplerAddressMode	addressV,
    148 																	 VkSamplerAddressMode	addressW,
    149 																	 VkBorderColor			borderColor);
    150 	virtual								~SamplerAddressModesTest	(void) {}
    151 	virtual tcu::UVec2					getRenderSize				(VkImageViewType viewType) const;
    152 	virtual std::vector<Vertex4Tex4>	createVertices				(void) const;
    153 	virtual VkSamplerCreateInfo			getSamplerCreateInfo		(void) const;
    154 
    155 private:
    156 	VkSamplerAddressMode				m_addressU;
    157 	VkSamplerAddressMode				m_addressV;
    158 	VkSamplerAddressMode				m_addressW;
    159 	VkBorderColor						m_borderColor;
    160 };
    161 
    162 
    163 // SamplerTest
    164 
    165 SamplerTest::SamplerTest (tcu::TestContext&	testContext,
    166 						  const char*		name,
    167 						  const char*		description,
    168 						  VkImageViewType	imageViewType,
    169 						  VkFormat			imageFormat,
    170 						  int				imageSize,
    171 						  float				samplerLod)
    172 	: vkt::TestCase		(testContext, name, description)
    173 	, m_imageViewType	(imageViewType)
    174 	, m_imageFormat		(imageFormat)
    175 	, m_imageSize		(imageSize)
    176 	, m_samplerLod		(samplerLod)
    177 {
    178 }
    179 
    180 void SamplerTest::initPrograms (SourceCollections& sourceCollections) const
    181 {
    182 	std::ostringstream				vertexSrc;
    183 	std::ostringstream				fragmentSrc;
    184 	const char*						texCoordSwizzle	= DE_NULL;
    185 	tcu::TextureFormat				format			= (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat))
    186 																						  : mapVkFormat(m_imageFormat);
    187 	tcu::Vec4						lookupScale;
    188 	tcu::Vec4						lookupBias;
    189 
    190 	getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
    191 
    192 	switch (m_imageViewType)
    193 	{
    194 		case VK_IMAGE_VIEW_TYPE_1D:
    195 			texCoordSwizzle = "x";
    196 			break;
    197 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
    198 		case VK_IMAGE_VIEW_TYPE_2D:
    199 			texCoordSwizzle = "xy";
    200 			break;
    201 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
    202 		case VK_IMAGE_VIEW_TYPE_3D:
    203 		case VK_IMAGE_VIEW_TYPE_CUBE:
    204 			texCoordSwizzle = "xyz";
    205 			break;
    206 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
    207 			texCoordSwizzle = "xyzw";
    208 			break;
    209 		default:
    210 			DE_ASSERT(false);
    211 			break;
    212 	}
    213 
    214 	vertexSrc << "#version 440\n"
    215 			  << "layout(location = 0) in vec4 position;\n"
    216 			  << "layout(location = 1) in vec4 texCoords;\n"
    217 			  << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
    218 			  << "out gl_PerVertex {\n"
    219 			  << "	vec4 gl_Position;\n"
    220 			  << "};\n"
    221 			  << "void main (void)\n"
    222 			  << "{\n"
    223 			  << "	gl_Position = position;\n"
    224 			  << "	vtxTexCoords = texCoords;\n"
    225 			  << "}\n";
    226 
    227 	fragmentSrc << "#version 440\n"
    228 				<< "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " texSampler;\n"
    229 				<< "layout(location = 0) in highp vec4 vtxTexCoords;\n"
    230 				<< "layout(location = 0) out highp vec4 fragColor;\n"
    231 				<< "void main (void)\n"
    232 				<< "{\n"
    233 				<< "	fragColor = ";
    234 
    235 	if (m_samplerLod > 0.0f)
    236 		fragmentSrc << "textureLod(texSampler, vtxTexCoords." << texCoordSwizzle << ", " << std::fixed <<  m_samplerLod << ")";
    237 	else
    238 		fragmentSrc << "texture(texSampler, vtxTexCoords." << texCoordSwizzle << ")" << std::fixed;
    239 
    240 	fragmentSrc << " * vec4" << std::scientific << lookupScale << " + vec4" << lookupBias << ";\n"
    241 				<< "}\n";
    242 
    243 	sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
    244 	sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
    245 }
    246 
    247 TestInstance* SamplerTest::createInstance (Context& context) const
    248 {
    249 	const tcu::UVec2				renderSize			= getRenderSize(m_imageViewType);
    250 	const std::vector<Vertex4Tex4>	vertices			= createVertices();
    251 	const VkSamplerCreateInfo		samplerParams		= getSamplerCreateInfo();
    252 	const VkComponentMapping		componentMapping	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
    253 	const VkImageSubresourceRange	subresourceRange	=
    254 	{
    255 		VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags	aspectMask;
    256 		0u,														// deUint32				baseMipLevel;
    257 		(deUint32)deLog2Floor32(m_imageSize) + 1,				// deUint32				mipLevels;
    258 		0u,														// deUint32				baseArrayLayer;
    259 		(deUint32)SamplerTest::getArraySize(m_imageViewType)	// deUint32				arraySize;
    260 	};
    261 
    262 
    263 
    264 	return new ImageSamplingInstance(context, renderSize, m_imageViewType, m_imageFormat,
    265 									 getImageSize(m_imageViewType, m_imageSize),
    266 									 getArraySize(m_imageViewType),
    267 									 componentMapping, subresourceRange,
    268 									 samplerParams, m_samplerLod,vertices);
    269 }
    270 
    271 tcu::UVec2 SamplerTest::getRenderSize (VkImageViewType viewType) const
    272 {
    273 	if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
    274 	{
    275 		return tcu::UVec2(16u, 16u);
    276 	}
    277 	else
    278 	{
    279 		return tcu::UVec2(16u * 3u, 16u * 2u);
    280 	}
    281 }
    282 
    283 std::vector<Vertex4Tex4> SamplerTest::createVertices (void) const
    284 {
    285 	std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(m_imageViewType);
    286 	// Adjust texture coordinate to avoid doing NEAREST filtering exactly on texel boundaries.
    287 	// TODO: Would be nice to base this on number of texels and subtexel precision. But this
    288 	// seems to work.
    289 	for (unsigned int i = 0; i < vertices.size(); ++i) {
    290 		vertices[i].texCoord += tcu::Vec4(0.002f, 0.002f, 0.002f, 0.0f);
    291 	}
    292 	return vertices;
    293 }
    294 
    295 VkSamplerCreateInfo SamplerTest::getSamplerCreateInfo (void) const
    296 {
    297 	const VkSamplerCreateInfo defaultSamplerParams =
    298 	{
    299 		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,									// VkStructureType			sType;
    300 		DE_NULL,																// const void*				pNext;
    301 		0u,																		// VkSamplerCreateFlags		flags;
    302 		VK_FILTER_NEAREST,														// VkFilter					magFilter;
    303 		VK_FILTER_NEAREST,														// VkFilter					minFilter;
    304 		VK_SAMPLER_MIPMAP_MODE_NEAREST,											// VkSamplerMipmapMode		mipmapMode;
    305 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeU;
    306 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeV;
    307 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeW;
    308 		0.0f,																	// float					mipLodBias;
    309 		VK_FALSE,																// VkBool32					anisotropyEnable;
    310 		1.0f,																	// float					maxAnisotropy;
    311 		false,																	// VkBool32					compareEnable;
    312 		VK_COMPARE_OP_NEVER,													// VkCompareOp				compareOp;
    313 		0.0f,																	// float					minLod;
    314 		0.25f,																	// float					maxLod;
    315 		getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat),	// VkBorderColor			borderColor;
    316 		false																	// VkBool32					unnormalizedCoordinates;
    317 	};
    318 
    319 	return defaultSamplerParams;
    320 }
    321 
    322 std::string SamplerTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
    323 {
    324 	std::ostringstream samplerType;
    325 
    326 	if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
    327 		samplerType << "u";
    328 	else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
    329 		samplerType << "i";
    330 
    331 	switch (type)
    332 	{
    333 		case VK_IMAGE_VIEW_TYPE_1D:
    334 			samplerType << "sampler1D";
    335 			break;
    336 
    337 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
    338 			samplerType << "sampler1DArray";
    339 			break;
    340 
    341 		case VK_IMAGE_VIEW_TYPE_2D:
    342 			samplerType << "sampler2D";
    343 			break;
    344 
    345 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
    346 			samplerType << "sampler2DArray";
    347 			break;
    348 
    349 		case VK_IMAGE_VIEW_TYPE_3D:
    350 			samplerType << "sampler3D";
    351 			break;
    352 
    353 		case VK_IMAGE_VIEW_TYPE_CUBE:
    354 			samplerType << "samplerCube";
    355 			break;
    356 
    357 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
    358 			samplerType << "samplerCubeArray";
    359 			break;
    360 
    361 		default:
    362 			DE_FATAL("Unknown image view type");
    363 			break;
    364 	}
    365 
    366 	return samplerType.str();
    367 }
    368 
    369 tcu::IVec3 SamplerTest::getImageSize (VkImageViewType viewType, int size)
    370 {
    371 	switch (viewType)
    372 	{
    373 		case VK_IMAGE_VIEW_TYPE_1D:
    374 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
    375 			return tcu::IVec3(size, 1, 1);
    376 
    377 		case VK_IMAGE_VIEW_TYPE_3D:
    378 			return tcu::IVec3(size, size, 4);
    379 
    380 		default:
    381 			break;
    382 	}
    383 
    384 	return tcu::IVec3(size, size, 1);
    385 }
    386 
    387 int SamplerTest::getArraySize (VkImageViewType viewType)
    388 {
    389 	switch (viewType)
    390 	{
    391 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
    392 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
    393 		case VK_IMAGE_VIEW_TYPE_CUBE:
    394 			return 6;
    395 
    396 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
    397 			return 36;
    398 
    399 		default:
    400 			break;
    401 	}
    402 
    403 	return 1;
    404 }
    405 
    406 
    407 // SamplerMagFilterTest
    408 
    409 SamplerMagFilterTest::SamplerMagFilterTest (tcu::TestContext&	testContext,
    410 											const char*			name,
    411 											const char*			description,
    412 											VkImageViewType		imageViewType,
    413 											VkFormat			imageFormat,
    414 											VkFilter			magFilter)
    415 	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 8, 0.0f)
    416 	, m_magFilter	(magFilter)
    417 {
    418 }
    419 
    420 VkSamplerCreateInfo SamplerMagFilterTest::getSamplerCreateInfo (void) const
    421 {
    422 	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
    423 	samplerParams.magFilter = m_magFilter;
    424 
    425 	return samplerParams;
    426 }
    427 
    428 
    429 // SamplerMinFilterTest
    430 
    431 SamplerMinFilterTest::SamplerMinFilterTest (tcu::TestContext&	testContext,
    432 											const char*			name,
    433 											const char*			description,
    434 											VkImageViewType		imageViewType,
    435 											VkFormat			imageFormat,
    436 											VkFilter			minFilter)
    437 	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 32, 0.0f)
    438 	, m_minFilter	(minFilter)
    439 {
    440 }
    441 
    442 VkSamplerCreateInfo SamplerMinFilterTest::getSamplerCreateInfo (void) const
    443 {
    444 	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
    445 	samplerParams.minFilter = m_minFilter;
    446 	// set minLod to epsilon, to force use of the minFilter
    447 	samplerParams.minLod = 0.01f;
    448 
    449 	return samplerParams;
    450 }
    451 
    452 
    453 // SamplerLodTest
    454 
    455 SamplerLodTest::SamplerLodTest (tcu::TestContext&	testContext,
    456 								const char*			name,
    457 								const char*			description,
    458 								VkImageViewType		imageViewType,
    459 								VkFormat			imageFormat,
    460 								VkSamplerMipmapMode	mipmapMode,
    461 								float				minLod,
    462 								float				maxLod,
    463 								float				mipLodBias,
    464 								float				samplerLod)
    465 	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 32, samplerLod)
    466 	, m_mipmapMode	(mipmapMode)
    467 	, m_minLod		(minLod)
    468 	, m_maxLod		(maxLod)
    469 	, m_mipLodBias	(mipLodBias)
    470 {
    471 }
    472 
    473 VkSamplerCreateInfo SamplerLodTest::getSamplerCreateInfo (void) const
    474 {
    475 	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
    476 
    477 	samplerParams.mipmapMode	= m_mipmapMode;
    478 	samplerParams.minLod		= m_minLod;
    479 	samplerParams.maxLod		= m_maxLod;
    480 	samplerParams.mipLodBias	= m_mipLodBias;
    481 
    482 	return samplerParams;
    483 }
    484 
    485 
    486 // SamplerAddressModesTest
    487 
    488 SamplerAddressModesTest::SamplerAddressModesTest (tcu::TestContext&		testContext,
    489 												  const char*			name,
    490 												  const char*			description,
    491 												  VkImageViewType		imageViewType,
    492 												  VkFormat				imageFormat,
    493 												  VkSamplerAddressMode	addressU,
    494 												  VkSamplerAddressMode	addressV,
    495 												  VkSamplerAddressMode	addressW,
    496 												  VkBorderColor			borderColor)
    497 	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 8, 0.0f)
    498 	, m_addressU	(addressU)
    499 	, m_addressV	(addressV)
    500 	, m_addressW	(addressW)
    501 	, m_borderColor	(borderColor)
    502 {
    503 }
    504 
    505 tcu::UVec2 SamplerAddressModesTest::getRenderSize (VkImageViewType viewType) const
    506 {
    507 	return 4u * SamplerTest::getRenderSize(viewType);
    508 }
    509 
    510 std::vector<Vertex4Tex4> SamplerAddressModesTest::createVertices (void) const
    511 {
    512 	std::vector<Vertex4Tex4> vertices = SamplerTest::createVertices();
    513 
    514 	switch (m_imageViewType)
    515 	{
    516 		case VK_IMAGE_VIEW_TYPE_1D: case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
    517 			for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
    518 				vertices[vertexNdx].texCoord.x() = (vertices[vertexNdx].texCoord.x() - 0.5f) * 4.0f;
    519 
    520 			break;
    521 
    522 		case VK_IMAGE_VIEW_TYPE_2D:
    523 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
    524 			for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
    525 				vertices[vertexNdx].texCoord.xy() = (vertices[vertexNdx].texCoord.swizzle(0, 1) - tcu::Vec2(0.5f)) * 4.0f;
    526 
    527 			break;
    528 
    529 		case VK_IMAGE_VIEW_TYPE_3D:
    530 			for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
    531 				vertices[vertexNdx].texCoord.xyz() = (vertices[vertexNdx].texCoord.swizzle(0, 1, 2) - tcu::Vec3(0.5f)) * 4.0f;
    532 
    533 			break;
    534 
    535 		case VK_IMAGE_VIEW_TYPE_CUBE:
    536 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
    537 			break;
    538 
    539 		default:
    540 			DE_ASSERT(false);
    541 	}
    542 
    543 	return vertices;
    544 }
    545 
    546 VkSamplerCreateInfo SamplerAddressModesTest::getSamplerCreateInfo (void) const
    547 {
    548 	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
    549 	samplerParams.addressModeU	= m_addressU;
    550 	samplerParams.addressModeV	= m_addressV;
    551 	samplerParams.addressModeW	= m_addressW;
    552 	samplerParams.borderColor	= m_borderColor;
    553 
    554 	return samplerParams;
    555 }
    556 
    557 
    558 // Utilities to create test nodes
    559 
    560 std::string getFormatCaseName (const VkFormat format)
    561 {
    562 	const std::string fullName = getFormatName(format);
    563 
    564 	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
    565 
    566 	return de::toLower(fullName.substr(10));
    567 }
    568 
    569 MovePtr<tcu::TestCaseGroup> createSamplerMagFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
    570 {
    571 	MovePtr<tcu::TestCaseGroup> samplerMagFilterTests (new tcu::TestCaseGroup(testCtx, "mag_filter", "Tests for magnification filter"));
    572 
    573 	if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
    574 		samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "linear", "Magnifies image using VK_TEX_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR));
    575 	samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "nearest", "Magnifies image using VK_TEX_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST));
    576 
    577 	return samplerMagFilterTests;
    578 }
    579 
    580 MovePtr<tcu::TestCaseGroup> createSamplerMinFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
    581 {
    582 	MovePtr<tcu::TestCaseGroup> samplerMinFilterTests (new tcu::TestCaseGroup(testCtx, "min_filter", "Tests for minification filter"));
    583 
    584 	if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
    585 		samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "linear", "Minifies image using VK_TEX_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR));
    586 	samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "nearest", "Minifies image using VK_TEX_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST));
    587 
    588 	return samplerMinFilterTests;
    589 }
    590 
    591 MovePtr<tcu::TestCaseGroup> createSamplerLodTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat, VkSamplerMipmapMode mipmapMode)
    592 {
    593 	struct TestCaseConfig
    594 	{
    595 		const char*	name;
    596 		const char*	description;
    597 		float		minLod;
    598 		float		maxLod;
    599 		float		mipLodBias;
    600 		float		lod;
    601 	};
    602 
    603 	TestCaseConfig testCaseConfigs [] =
    604 	{
    605 		{ "equal_min_3_max_3",		"minLod = 3, maxLod = 3, mipLodBias = 0, lod = 0",		3.0f, 3.0f, 0.0f, 0.0f },
    606 		{ "select_min_1",			"minLod = 1, maxLod = 5, mipLodBias = 0, lod = 0",		1.0f, 5.0f, 0.0f, 0.0f },
    607 		{ "select_max_4",			"minLod = 0, maxLod = 4, mipLodBias = 0, lod = 5",		0.0f, 4.0f, 0.0f, 5.0f },
    608 		{ "select_bias_2_1",		"minLod = 0, maxLod = 2.1, mipLodBias = 5.0, lod = 0",	0.0f, 2.1f, 5.0f, 0.0f },
    609 		{ "select_bias_2_5",		"minLod = 0, maxLod = 5, mipLodBias = 2.5, lod = 0",	0.0f, 5.0f, 2.5f, 0.00001f },
    610 		{ "select_bias_3_1",		"minLod = 0, maxLod = 5, mipLodBias = -0.9, lod = 4.0",	0.0f, 5.0f, -0.9f, 4.0f },
    611 		{ "select_bias_3_7",		"minLod = 0, maxLod = 5, mipLodBias = 3.0, lod = 0.7",	0.0f, 5.0f, 3.0f, 0.7f },
    612 	};
    613 
    614 	MovePtr<tcu::TestCaseGroup> samplerLodTests (new tcu::TestCaseGroup(testCtx, "lod", "Tests for sampler LOD"));
    615 
    616 	for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
    617 	{
    618 		const TestCaseConfig& config = testCaseConfigs[configNdx];
    619 
    620 		samplerLodTests->addChild(new SamplerLodTest(testCtx, config.name, config.description, imageViewType, imageFormat, mipmapMode, config.minLod, config.maxLod, config.mipLodBias, config.lod));
    621 	}
    622 
    623 	return samplerLodTests;
    624 }
    625 
    626 MovePtr<tcu::TestCaseGroup> createSamplerMipmapTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
    627 {
    628 	MovePtr<tcu::TestCaseGroup> samplerMipmapTests (new tcu::TestCaseGroup(testCtx, "mipmap", "Tests for mipmap modes"));
    629 
    630 	// Mipmap mode: nearest
    631 	MovePtr<tcu::TestCaseGroup> mipmapNearestTests (new tcu::TestCaseGroup(testCtx, "nearest", "Uses VK_TEX_MIPMAP_MODE_NEAREST"));
    632 	mipmapNearestTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_NEAREST).release());
    633 	samplerMipmapTests->addChild(mipmapNearestTests.release());
    634 
    635 	// Mipmap mode: linear
    636 	if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
    637 	{
    638 		MovePtr<tcu::TestCaseGroup> mipmapLinearTests(new tcu::TestCaseGroup(testCtx, "linear", "Uses VK_TEX_MIPMAP_MODE_LINEAR"));
    639 		mipmapLinearTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_LINEAR).release());
    640 		samplerMipmapTests->addChild(mipmapLinearTests.release());
    641 	}
    642 
    643 	return samplerMipmapTests;
    644 }
    645 
    646 std::string getAddressModesCaseName (VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w, BorderColor border)
    647 {
    648 	static const char* borderColorNames[BORDER_COLOR_COUNT] =
    649 	{
    650 		"opaque_black",
    651 		"opaque_white",
    652 		"transparent_black",
    653 	};
    654 
    655 	std::ostringstream caseName;
    656 
    657 	if (u == v && v == w)
    658 	{
    659 		const std::string fullName = getSamplerAddressModeName(u);
    660 		DE_ASSERT(de::beginsWith(fullName, "VK_SAMPLER_ADDRESS_"));
    661 
    662 		caseName << "all_";
    663 		caseName << de::toLower(fullName.substr(19));
    664 
    665 		if (u == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)
    666 		{
    667 			caseName << "_" << borderColorNames[border];
    668 		}
    669 	}
    670 	else
    671 	{
    672 		const std::string fullNameU = getSamplerAddressModeName(u);
    673 		const std::string fullNameV = getSamplerAddressModeName(v);
    674 		const std::string fullNameW = getSamplerAddressModeName(w);
    675 
    676 		DE_ASSERT(de::beginsWith(fullNameU, "VK_SAMPLER_ADDRESS_"));
    677 		DE_ASSERT(de::beginsWith(fullNameV, "VK_SAMPLER_ADDRESS_"));
    678 		DE_ASSERT(de::beginsWith(fullNameW, "VK_SAMPLER_ADDRESS_"));
    679 
    680 		caseName << "uvw"
    681 				 << "_" << de::toLower(fullNameU.substr(19))
    682 				 << "_" << de::toLower(fullNameV.substr(19))
    683 				 << "_" << de::toLower(fullNameW.substr(19));
    684 	}
    685 
    686 	return caseName.str();
    687 }
    688 
    689 MovePtr<tcu::TestCaseGroup> createSamplerAddressModesTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
    690 {
    691 	struct TestCaseConfig
    692 	{
    693 		VkSamplerAddressMode	u;
    694 		VkSamplerAddressMode	v;
    695 		VkSamplerAddressMode	w;
    696 		BorderColor				border;
    697 	};
    698 
    699 	const TestCaseConfig testCaseConfigs[] =
    700 	{
    701 		// All address modes equal
    702 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_TRANSPARENT_BLACK },
    703 		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_TRANSPARENT_BLACK },
    704 		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_TRANSPARENT_BLACK },
    705 		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_TRANSPARENT_BLACK },
    706 
    707 		// All address modes equal using border color
    708 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_TRANSPARENT_BLACK },
    709 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_BLACK },
    710 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },
    711 
    712 		// Pairwise combinations of address modes not covered by previous tests
    713 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE},
    714 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_OPAQUE_WHITE },
    715 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_OPAQUE_WHITE },
    716 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
    717 		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_OPAQUE_WHITE },
    718 		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },
    719 		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE },
    720 		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_OPAQUE_WHITE },
    721 		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
    722 		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_OPAQUE_WHITE },
    723 		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_OPAQUE_WHITE },
    724 		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },
    725 		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE },
    726 		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
    727 		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },
    728 		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_OPAQUE_WHITE },
    729 		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
    730 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },
    731 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE },
    732 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_OPAQUE_WHITE },
    733 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
    734 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_OPAQUE_WHITE },
    735 	};
    736 
    737 	MovePtr<tcu::TestCaseGroup> samplerAddressModesTests (new tcu::TestCaseGroup(testCtx, "address_modes", "Tests for address modes"));
    738 
    739 	for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
    740 	{
    741 		const TestCaseConfig& config = testCaseConfigs[configNdx];
    742 
    743 		samplerAddressModesTests->addChild(new SamplerAddressModesTest(testCtx,
    744 																	   getAddressModesCaseName(config.u, config.v, config.w, config.border).c_str(),
    745 																	   "",
    746 																	   imageViewType,
    747 																	   imageFormat,
    748 																	   config.u, config.v, config.w,
    749 																	   getFormatBorderColor(config.border, imageFormat)));
    750 	}
    751 
    752 	return samplerAddressModesTests;
    753 }
    754 
    755 } // anonymous
    756 
    757 tcu::TestCaseGroup* createSamplerTests (tcu::TestContext& testCtx)
    758 {
    759 	const struct
    760 	{
    761 		VkImageViewType		type;
    762 		const char*			name;
    763 	}
    764 	imageViewTypes[] =
    765 	{
    766 		{ VK_IMAGE_VIEW_TYPE_1D,			"1d" },
    767 		{ VK_IMAGE_VIEW_TYPE_1D_ARRAY,		"1d_array" },
    768 		{ VK_IMAGE_VIEW_TYPE_2D,			"2d" },
    769 		{ VK_IMAGE_VIEW_TYPE_2D_ARRAY,		"2d_array" },
    770 		{ VK_IMAGE_VIEW_TYPE_3D,			"3d" },
    771 		{ VK_IMAGE_VIEW_TYPE_CUBE,			"cube" },
    772 		{ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,	"cube_array" }
    773 	};
    774 
    775 	const VkFormat formats[] =
    776 	{
    777 		// Packed formats
    778 		VK_FORMAT_R4G4_UNORM_PACK8,
    779 		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
    780 		VK_FORMAT_R5G6B5_UNORM_PACK16,
    781 		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
    782 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
    783 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
    784 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
    785 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
    786 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
    787 		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
    788 
    789 		// Pairwise combinations of 8-bit channel formats, UNORM/SNORM/SINT/UINT/SRGB type x 1-to-4 channels x RGBA/BGRA order
    790 		VK_FORMAT_R8_SRGB,
    791 		VK_FORMAT_R8G8B8_UINT,
    792 		VK_FORMAT_B8G8R8A8_SINT,
    793 		VK_FORMAT_R8G8_UNORM,
    794 		VK_FORMAT_B8G8R8_SNORM,
    795 		VK_FORMAT_R8G8B8A8_SNORM,
    796 		VK_FORMAT_R8G8_UINT,
    797 		VK_FORMAT_R8_SINT,
    798 		VK_FORMAT_R8G8B8A8_SRGB,
    799 		VK_FORMAT_R8G8B8A8_UNORM,
    800 		VK_FORMAT_B8G8R8A8_UNORM,
    801 		VK_FORMAT_B8G8R8_SRGB,
    802 		VK_FORMAT_R8G8_SRGB,
    803 		VK_FORMAT_R8_UINT,
    804 		VK_FORMAT_R8G8B8A8_UINT,
    805 		VK_FORMAT_R8G8_SINT,
    806 		VK_FORMAT_R8_SNORM,
    807 		VK_FORMAT_B8G8R8_SINT,
    808 		VK_FORMAT_R8G8_SNORM,
    809 		VK_FORMAT_B8G8R8_UNORM,
    810 		VK_FORMAT_R8_UNORM,
    811 
    812 		// Pairwise combinations of 16/32-bit channel formats x SINT/UINT/SFLOAT type x 1-to-4 channels
    813 		VK_FORMAT_R32G32_SFLOAT,
    814 		VK_FORMAT_R32G32B32_UINT,
    815 		VK_FORMAT_R16G16B16A16_SFLOAT,
    816 		VK_FORMAT_R16G16_UINT,
    817 		VK_FORMAT_R32G32B32A32_SINT,
    818 		VK_FORMAT_R16G16B16_SINT,
    819 		VK_FORMAT_R16_SFLOAT,
    820 		VK_FORMAT_R32_SINT,
    821 		VK_FORMAT_R32_UINT,
    822 		VK_FORMAT_R16G16B16_SFLOAT,
    823 		VK_FORMAT_R16G16_SINT,
    824 
    825 		// Scaled formats
    826 		VK_FORMAT_R8G8B8A8_SSCALED,
    827 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
    828 
    829 		// Compressed formats
    830 		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
    831 		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
    832 		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
    833 		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
    834 		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
    835 		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
    836 		VK_FORMAT_EAC_R11_UNORM_BLOCK,
    837 		VK_FORMAT_EAC_R11_SNORM_BLOCK,
    838 		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
    839 		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
    840 		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
    841 		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
    842 		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
    843 		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
    844 		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
    845 		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
    846 		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
    847 		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
    848 		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
    849 		VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
    850 	};
    851 
    852 	de::MovePtr<tcu::TestCaseGroup> samplerTests		(new tcu::TestCaseGroup(testCtx, "sampler", "Sampler tests"));
    853 	de::MovePtr<tcu::TestCaseGroup> viewTypeTests		(new tcu::TestCaseGroup(testCtx, "view_type", ""));
    854 
    855 	for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
    856 	{
    857 		const VkImageViewType			viewType		= imageViewTypes[viewTypeNdx].type;
    858 		de::MovePtr<tcu::TestCaseGroup>	viewTypeGroup	(new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
    859 		de::MovePtr<tcu::TestCaseGroup>	formatTests		(new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
    860 
    861 		for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
    862 		{
    863 			const VkFormat	format			= formats[formatNdx];
    864 			const bool		isCompressed	= isCompressedFormat(format);
    865 
    866 			if (isCompressed)
    867 			{
    868 				// Do not use compressed formats with 1D and 1D array textures.
    869 				if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
    870 					break;
    871 			}
    872 
    873 			de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx,
    874 																				getFormatCaseName(format).c_str(),
    875 																				(std::string("Samples a texture of format ") + getFormatName(format)).c_str()));
    876 
    877 			if (!isCompressed)
    878 			{
    879 				// Do not include minFilter tests with compressed formats.
    880 				// Randomly generated compressed textures are too noisy and will derive in false positives.
    881 				de::MovePtr<tcu::TestCaseGroup>	minFilterTests		= createSamplerMinFilterTests(testCtx, viewType, format);
    882 				formatGroup->addChild(minFilterTests.release());
    883 			}
    884 
    885 			de::MovePtr<tcu::TestCaseGroup>	magFilterTests		= createSamplerMagFilterTests(testCtx, viewType, format);
    886 			de::MovePtr<tcu::TestCaseGroup>	mipmapTests			= createSamplerMipmapTests(testCtx, viewType, format);
    887 
    888 			formatGroup->addChild(magFilterTests.release());
    889 			formatGroup->addChild(mipmapTests.release());
    890 
    891 			if (viewType != VK_IMAGE_VIEW_TYPE_CUBE && viewType != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
    892 			{
    893 				de::MovePtr<tcu::TestCaseGroup>	addressModesTests	= createSamplerAddressModesTests(testCtx, viewType, format);
    894 				formatGroup->addChild(addressModesTests.release());
    895 			}
    896 
    897 			formatTests->addChild(formatGroup.release());
    898 		}
    899 
    900 		viewTypeGroup->addChild(formatTests.release());
    901 		viewTypeTests->addChild(viewTypeGroup.release());
    902 	}
    903 
    904 	samplerTests->addChild(viewTypeTests.release());
    905 
    906 	return samplerTests.release();
    907 }
    908 
    909 } // pipeline
    910 } // vkt
    911