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);
~SamplerTest(void)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);
~SamplerMagFilterTest(void)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);
~SamplerMinFilterTest(void)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);
~SamplerLodTest(void)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);
~SamplerAddressModesTest(void)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 
SamplerTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,int imageSize,float samplerLod)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 
initPrograms(SourceCollections & sourceCollections) const180 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 
createInstance(Context & context) const250 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 
getRenderSize(VkImageViewType viewType) const274 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 
createVertices(void) const286 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 
getSamplerCreateInfo(void) const298 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 
getGlslSamplerType(const tcu::TextureFormat & format,VkImageViewType type)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 
getImageSize(VkImageViewType viewType,int size)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 
getArraySize(VkImageViewType viewType)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 
SamplerMagFilterTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkFilter magFilter)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 
getSamplerCreateInfo(void) const423 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 
SamplerMinFilterTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkFilter minFilter)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 
getSamplerCreateInfo(void) const445 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 
SamplerLodTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkSamplerMipmapMode mipmapMode,float minLod,float maxLod,float mipLodBias,float samplerLod)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 
getSamplerCreateInfo(void) const476 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 
SamplerAddressModesTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkSamplerAddressMode addressU,VkSamplerAddressMode addressV,VkSamplerAddressMode addressW,VkBorderColor borderColor)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 
getRenderSize(VkImageViewType viewType) const508 tcu::UVec2 SamplerAddressModesTest::getRenderSize (VkImageViewType viewType) const
509 {
510 	return 4u * SamplerTest::getRenderSize(viewType);
511 }
512 
createVertices(void) const513 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 
getSamplerCreateInfo(void) const549 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 
getFormatCaseName(const VkFormat format)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 
createSamplerMagFilterTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)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 
createSamplerMinFilterTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)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 
createSamplerLodTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat,VkSamplerMipmapMode mipmapMode)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 
createSamplerMipmapTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)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 
getAddressModesCaseName(VkSamplerAddressMode u,VkSamplerAddressMode v,VkSamplerAddressMode w,BorderColor border)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 
createSamplerAddressModesTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)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 
createSamplerTests(tcu::TestContext & testCtx)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