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