• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Imagination Technologies Ltd.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief 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 	tcu::Vec4							swizzle					(tcu::Vec4 inputData, VkComponentMapping componentMapping, float zeroOrOneValue) const;
65 	virtual void						initPrograms			(SourceCollections& sourceCollections) const;
66 	virtual TestInstance*				createInstance			(Context& context) const;
67 	virtual tcu::UVec2					getRenderSize			(VkImageViewType viewType) const;
68 	virtual std::vector<Vertex4Tex4>	createVertices			(void) const;
69 	virtual VkSamplerCreateInfo			getSamplerCreateInfo	(void) const;
70 	virtual VkComponentMapping			getComponentMapping		(void) const;
71 
72 	static std::string					getGlslSamplerType		(const tcu::TextureFormat& format, VkImageViewType type);
73 	static tcu::IVec3					getImageSize			(VkImageViewType viewType, int size);
74 	static int							getArraySize			(VkImageViewType viewType);
75 
76 protected:
77 	VkImageViewType						m_imageViewType;
78 	VkFormat							m_imageFormat;
79 	int									m_imageSize;
80 	VkImageViewCreateInfo				m_imageViewParams;
81 	VkSamplerCreateInfo					m_samplerParams;
82 	float								m_samplerLod;
83 };
84 
85 class SamplerMagFilterTest : public SamplerTest
86 {
87 public:
88 									SamplerMagFilterTest	(tcu::TestContext&	testContext,
89 															 const char*		name,
90 															 const char*		description,
91 															 VkImageViewType	imageViewType,
92 															 VkFormat			imageFormat,
93 															 VkFilter			magFilter);
~SamplerMagFilterTest(void)94 	virtual							~SamplerMagFilterTest	(void) {}
95 	virtual VkSamplerCreateInfo		getSamplerCreateInfo	(void) const;
96 
97 private:
98 	VkFilter						m_magFilter;
99 };
100 
101 class SamplerMinFilterTest : public SamplerTest
102 {
103 public:
104 									SamplerMinFilterTest	(tcu::TestContext&	testContext,
105 															 const char*		name,
106 															 const char*		description,
107 															 VkImageViewType	imageViewType,
108 															 VkFormat			imageFormat,
109 															 VkFilter			minFilter);
~SamplerMinFilterTest(void)110 	virtual							~SamplerMinFilterTest	(void) {}
111 	virtual VkSamplerCreateInfo		getSamplerCreateInfo	(void) const;
112 
113 private:
114 	VkFilter						m_minFilter;
115 };
116 
117 class SamplerMagReduceFilterTest : public SamplerMagFilterTest
118 {
119 public:
120 												SamplerMagReduceFilterTest	(tcu::TestContext&			testContext,
121 																			const char*					name,
122 																			const char*					description,
123 																			VkImageViewType				imageViewType,
124 																			VkFormat					imageFormat,
125 																			VkComponentMapping			componentMapping,
126 																			VkSamplerReductionModeEXT	reductionMode);
127 
~SamplerMagReduceFilterTest(void)128 	virtual										~SamplerMagReduceFilterTest	(void) {}
129 	virtual VkSamplerCreateInfo					getSamplerCreateInfo		(void) const;
130 	virtual VkComponentMapping					getComponentMapping			(void) const;
131 
132 private:
133 	const VkSamplerReductionModeCreateInfoEXT	m_reductionCreaterInfo;
134 	VkComponentMapping							m_componentMapping;
135 };
136 
137 class SamplerMinReduceFilterTest : public SamplerMinFilterTest
138 {
139 public:
140 												SamplerMinReduceFilterTest	(tcu::TestContext&			testContext,
141 																			 const char*				name,
142 																			 const char*				description,
143 																			 VkImageViewType			imageViewType,
144 																			 VkFormat					imageFormat,
145 																			 VkComponentMapping			componentMapping,
146 																			 VkSamplerReductionModeEXT	reductionMode);
147 
~SamplerMinReduceFilterTest(void)148 	virtual										~SamplerMinReduceFilterTest	(void) {}
149 	virtual VkSamplerCreateInfo					getSamplerCreateInfo		(void) const;
150 	virtual VkComponentMapping					getComponentMapping			(void) const;
151 
152 private:
153 	const VkSamplerReductionModeCreateInfoEXT	m_reductionCreaterInfo;
154 	VkComponentMapping							m_componentMapping;
155 };
156 
157 class SamplerLodTest : public SamplerTest
158 {
159 public:
160 									SamplerLodTest			(tcu::TestContext&		testContext,
161 															 const char*			name,
162 															 const char*			description,
163 															 VkImageViewType		imageViewType,
164 															 VkFormat				imageFormat,
165 															 VkSamplerMipmapMode	mipmapMode,
166 															 float					minLod,
167 															 float					maxLod,
168 															 float					mipLodBias,
169 															 float					samplerLod);
~SamplerLodTest(void)170 	virtual							~SamplerLodTest			(void) {}
171 	virtual VkSamplerCreateInfo		getSamplerCreateInfo	(void) const;
172 
173 private:
174 	VkSamplerMipmapMode				m_mipmapMode;
175 	float							m_minLod;
176 	float							m_maxLod;
177 	float							m_mipLodBias;
178 };
179 
180 class SamplerAddressModesTest : public SamplerTest
181 {
182 public:
183 										SamplerAddressModesTest		(tcu::TestContext&		testContext,
184 																	 const char*			name,
185 																	 const char*			description,
186 																	 VkImageViewType		imageViewType,
187 																	 VkFormat				imageFormat,
188 																	 VkSamplerAddressMode	addressU,
189 																	 VkSamplerAddressMode	addressV,
190 																	 VkSamplerAddressMode	addressW,
191 																	 VkBorderColor			borderColor);
~SamplerAddressModesTest(void)192 	virtual								~SamplerAddressModesTest	(void) {}
193 	virtual tcu::UVec2					getRenderSize				(VkImageViewType viewType) const;
194 	virtual std::vector<Vertex4Tex4>	createVertices				(void) const;
195 	virtual VkSamplerCreateInfo			getSamplerCreateInfo		(void) const;
196 
197 private:
198 	VkSamplerAddressMode				m_addressU;
199 	VkSamplerAddressMode				m_addressV;
200 	VkSamplerAddressMode				m_addressW;
201 	VkBorderColor						m_borderColor;
202 };
203 
204 
205 // SamplerTest
206 
SamplerTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,int imageSize,float samplerLod)207 SamplerTest::SamplerTest (tcu::TestContext&	testContext,
208 						  const char*		name,
209 						  const char*		description,
210 						  VkImageViewType	imageViewType,
211 						  VkFormat			imageFormat,
212 						  int				imageSize,
213 						  float				samplerLod)
214 	: vkt::TestCase		(testContext, name, description)
215 	, m_imageViewType	(imageViewType)
216 	, m_imageFormat		(imageFormat)
217 	, m_imageSize		(imageSize)
218 	, m_samplerLod		(samplerLod)
219 {
220 }
221 
swizzle(tcu::Vec4 inputData,VkComponentMapping componentMapping,float zeroOrOneValue) const222 tcu::Vec4 SamplerTest::swizzle (tcu::Vec4 inputData, VkComponentMapping componentMapping, float zeroOrOneValue) const
223 {
224 	// Remove VK_COMPONENT_SWIZZLE_IDENTITY to avoid addressing channelValues[0]
225 	const vk::VkComponentMapping nonIdentityMapping =
226 	{
227 		componentMapping.r == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_R : componentMapping.r,
228 		componentMapping.g == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_G : componentMapping.g,
229 		componentMapping.b == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_B : componentMapping.b,
230 		componentMapping.a == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_A : componentMapping.a
231 
232 	};
233 	// array map with enum VkComponentSwizzle
234 	const float channelValues[] =
235 	{
236 		-1.0f,					// impossible
237 		zeroOrOneValue,			// SWIZZLE_0
238 		zeroOrOneValue,			// SWIZZLE_1
239 		inputData.x(),
240 		inputData.y(),
241 		inputData.z(),
242 		inputData.w(),
243 		-1.0f
244 	};
245 
246 	return tcu::Vec4(channelValues[nonIdentityMapping.r],
247 					 channelValues[nonIdentityMapping.g],
248 					 channelValues[nonIdentityMapping.b],
249 					 channelValues[nonIdentityMapping.a]);
250 }
251 
initPrograms(SourceCollections & sourceCollections) const252 void SamplerTest::initPrograms (SourceCollections& sourceCollections) const
253 {
254 	std::ostringstream				vertexSrc;
255 	std::ostringstream				fragmentSrc;
256 	const char*						texCoordSwizzle	= DE_NULL;
257 	tcu::TextureFormat				format			= (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat))
258 																						  : mapVkFormat(m_imageFormat);
259 	tcu::Vec4						lookupScale;
260 	tcu::Vec4						lookupBias;
261 
262 	getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
263 
264 	tcu::Vec4						swizzledScale	= swizzle(lookupScale,	getComponentMapping(), 1.0f);
265 	tcu::Vec4						swizzledBias	= swizzle(lookupBias,	getComponentMapping(), 0.0f);
266 
267 	switch (m_imageViewType)
268 	{
269 		case VK_IMAGE_VIEW_TYPE_1D:
270 			texCoordSwizzle = "x";
271 			break;
272 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
273 		case VK_IMAGE_VIEW_TYPE_2D:
274 			texCoordSwizzle = "xy";
275 			break;
276 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
277 		case VK_IMAGE_VIEW_TYPE_3D:
278 		case VK_IMAGE_VIEW_TYPE_CUBE:
279 			texCoordSwizzle = "xyz";
280 			break;
281 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
282 			texCoordSwizzle = "xyzw";
283 			break;
284 		default:
285 			DE_ASSERT(false);
286 			break;
287 	}
288 
289 	vertexSrc << "#version 440\n"
290 			  << "layout(location = 0) in vec4 position;\n"
291 			  << "layout(location = 1) in vec4 texCoords;\n"
292 			  << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
293 			  << "out gl_PerVertex {\n"
294 			  << "	vec4 gl_Position;\n"
295 			  << "};\n"
296 			  << "void main (void)\n"
297 			  << "{\n"
298 			  << "	gl_Position = position;\n"
299 			  << "	vtxTexCoords = texCoords;\n"
300 			  << "}\n";
301 
302 	fragmentSrc << "#version 440\n"
303 				<< "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " texSampler;\n"
304 				<< "layout(location = 0) in highp vec4 vtxTexCoords;\n"
305 				<< "layout(location = 0) out highp vec4 fragColor;\n"
306 				<< "void main (void)\n"
307 				<< "{\n"
308 				<< "	fragColor = ";
309 
310 	if (m_samplerLod > 0.0f)
311 		fragmentSrc << "textureLod(texSampler, vtxTexCoords." << texCoordSwizzle << ", " << std::fixed <<  m_samplerLod << ")";
312 	else
313 		fragmentSrc << "texture(texSampler, vtxTexCoords." << texCoordSwizzle << ")" << std::fixed;
314 
315 	fragmentSrc << " * vec4" << std::scientific << swizzledScale << " + vec4" << swizzledBias << ";\n"
316 				<< "}\n";
317 
318 	sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
319 	sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
320 }
321 
createInstance(Context & context) const322 TestInstance* SamplerTest::createInstance (Context& context) const
323 {
324 	const tcu::UVec2				renderSize			= getRenderSize(m_imageViewType);
325 	const std::vector<Vertex4Tex4>	vertices			= createVertices();
326 	const VkSamplerCreateInfo		samplerParams		= getSamplerCreateInfo();
327 	const VkComponentMapping		componentMapping	= getComponentMapping();
328 
329 	const VkImageAspectFlags		imageAspect			= (!isCompressedFormat(m_imageFormat) && hasDepthComponent(mapVkFormat(m_imageFormat).order)) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
330 
331 	const VkImageSubresourceRange	subresourceRange	=
332 	{
333 		imageAspect,											// VkImageAspectFlags	aspectMask;
334 		0u,														// deUint32				baseMipLevel;
335 		(deUint32)deLog2Floor32(m_imageSize) + 1,				// deUint32				mipLevels;
336 		0u,														// deUint32				baseArrayLayer;
337 		(deUint32)SamplerTest::getArraySize(m_imageViewType)	// deUint32				arraySize;
338 	};
339 
340 
341 
342 	return new ImageSamplingInstance(context, renderSize, m_imageViewType, m_imageFormat,
343 									 getImageSize(m_imageViewType, m_imageSize),
344 									 getArraySize(m_imageViewType),
345 									 componentMapping, subresourceRange,
346 									 samplerParams, m_samplerLod,vertices);
347 }
348 
getRenderSize(VkImageViewType viewType) const349 tcu::UVec2 SamplerTest::getRenderSize (VkImageViewType viewType) const
350 {
351 	if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
352 	{
353 		return tcu::UVec2(16u, 16u);
354 	}
355 	else
356 	{
357 		return tcu::UVec2(16u * 3u, 16u * 2u);
358 	}
359 }
360 
createVertices(void) const361 std::vector<Vertex4Tex4> SamplerTest::createVertices (void) const
362 {
363 	std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(m_imageViewType);
364 	// Adjust texture coordinate to avoid doing NEAREST filtering exactly on texel boundaries.
365 	// TODO: Would be nice to base this on number of texels and subtexel precision. But this
366 	// seems to work.
367 	for (unsigned int i = 0; i < vertices.size(); ++i) {
368 		vertices[i].texCoord += tcu::Vec4(0.002f, 0.002f, 0.002f, 0.0f);
369 	}
370 	return vertices;
371 }
372 
getSamplerCreateInfo(void) const373 VkSamplerCreateInfo SamplerTest::getSamplerCreateInfo (void) const
374 {
375 	const VkSamplerCreateInfo defaultSamplerParams =
376 	{
377 		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,									// VkStructureType			sType;
378 		DE_NULL,																// const void*				pNext;
379 		0u,																		// VkSamplerCreateFlags		flags;
380 		VK_FILTER_NEAREST,														// VkFilter					magFilter;
381 		VK_FILTER_NEAREST,														// VkFilter					minFilter;
382 		VK_SAMPLER_MIPMAP_MODE_NEAREST,											// VkSamplerMipmapMode		mipmapMode;
383 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeU;
384 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeV;
385 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,									// VkSamplerAddressMode		addressModeW;
386 		0.0f,																	// float					mipLodBias;
387 		VK_FALSE,																// VkBool32					anisotropyEnable;
388 		1.0f,																	// float					maxAnisotropy;
389 		false,																	// VkBool32					compareEnable;
390 		VK_COMPARE_OP_NEVER,													// VkCompareOp				compareOp;
391 		0.0f,																	// float					minLod;
392 		0.25f,																	// float					maxLod;
393 		getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat),	// VkBorderColor			borderColor;
394 		false																	// VkBool32					unnormalizedCoordinates;
395 	};
396 
397 	return defaultSamplerParams;
398 }
399 
getComponentMapping(void) const400 VkComponentMapping SamplerTest::getComponentMapping (void) const
401 {
402 	const VkComponentMapping	componentMapping	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
403 	return componentMapping;
404 }
405 
getGlslSamplerType(const tcu::TextureFormat & format,VkImageViewType type)406 std::string SamplerTest::getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
407 {
408 	std::ostringstream samplerType;
409 
410 	if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
411 		samplerType << "u";
412 	else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
413 		samplerType << "i";
414 
415 	switch (type)
416 	{
417 		case VK_IMAGE_VIEW_TYPE_1D:
418 			samplerType << "sampler1D";
419 			break;
420 
421 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
422 			samplerType << "sampler1DArray";
423 			break;
424 
425 		case VK_IMAGE_VIEW_TYPE_2D:
426 			samplerType << "sampler2D";
427 			break;
428 
429 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
430 			samplerType << "sampler2DArray";
431 			break;
432 
433 		case VK_IMAGE_VIEW_TYPE_3D:
434 			samplerType << "sampler3D";
435 			break;
436 
437 		case VK_IMAGE_VIEW_TYPE_CUBE:
438 			samplerType << "samplerCube";
439 			break;
440 
441 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
442 			samplerType << "samplerCubeArray";
443 			break;
444 
445 		default:
446 			DE_FATAL("Unknown image view type");
447 			break;
448 	}
449 
450 	return samplerType.str();
451 }
452 
getImageSize(VkImageViewType viewType,int size)453 tcu::IVec3 SamplerTest::getImageSize (VkImageViewType viewType, int size)
454 {
455 	switch (viewType)
456 	{
457 		case VK_IMAGE_VIEW_TYPE_1D:
458 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
459 			return tcu::IVec3(size, 1, 1);
460 
461 		case VK_IMAGE_VIEW_TYPE_3D:
462 			return tcu::IVec3(size, size, 4);
463 
464 		default:
465 			break;
466 	}
467 
468 	return tcu::IVec3(size, size, 1);
469 }
470 
getArraySize(VkImageViewType viewType)471 int SamplerTest::getArraySize (VkImageViewType viewType)
472 {
473 	switch (viewType)
474 	{
475 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
476 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
477 		case VK_IMAGE_VIEW_TYPE_CUBE:
478 			return 6;
479 
480 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
481 			return 36;
482 
483 		default:
484 			break;
485 	}
486 
487 	return 1;
488 }
489 
490 
491 // SamplerMagFilterTest
492 
SamplerMagFilterTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkFilter magFilter)493 SamplerMagFilterTest::SamplerMagFilterTest (tcu::TestContext&	testContext,
494 											const char*			name,
495 											const char*			description,
496 											VkImageViewType		imageViewType,
497 											VkFormat			imageFormat,
498 											VkFilter			magFilter)
499 	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 8, 0.0f)
500 	, m_magFilter	(magFilter)
501 {
502 }
503 
getSamplerCreateInfo(void) const504 VkSamplerCreateInfo SamplerMagFilterTest::getSamplerCreateInfo (void) const
505 {
506 	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
507 	samplerParams.magFilter = m_magFilter;
508 
509 	return samplerParams;
510 }
511 
512 
513 // SamplerMinFilterTest
514 
SamplerMinFilterTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkFilter minFilter)515 SamplerMinFilterTest::SamplerMinFilterTest (tcu::TestContext&	testContext,
516 											const char*			name,
517 											const char*			description,
518 											VkImageViewType		imageViewType,
519 											VkFormat			imageFormat,
520 											VkFilter			minFilter)
521 	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 32, 0.0f)
522 	, m_minFilter	(minFilter)
523 {
524 }
525 
getSamplerCreateInfo(void) const526 VkSamplerCreateInfo SamplerMinFilterTest::getSamplerCreateInfo (void) const
527 {
528 	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
529 	samplerParams.minFilter = m_minFilter;
530 	// set minLod to epsilon, to force use of the minFilter
531 	samplerParams.minLod = 0.01f;
532 
533 	return samplerParams;
534 }
535 
536 
537 namespace
538 {
539 
getSamplerReductionCreateInfo(VkSamplerReductionModeEXT reductionMode)540 VkSamplerReductionModeCreateInfoEXT getSamplerReductionCreateInfo (VkSamplerReductionModeEXT reductionMode)
541 {
542 	const VkSamplerReductionModeCreateInfoEXT	 ret =
543 	{
544 		VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT,	// VkStructureType				sType
545 		DE_NULL,													// const void*					pNext
546 		reductionMode												// VkSamplerReductionModeEXT	reductionMode
547 	};
548 	return ret;
549 }
550 
551 }
552 
553 
554 // SamplerMagReduceFilterTest
555 
SamplerMagReduceFilterTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkComponentMapping componentMapping,VkSamplerReductionModeEXT reductionMode)556 SamplerMagReduceFilterTest::SamplerMagReduceFilterTest (tcu::TestContext&	testContext,
557 														const char*					name,
558 														const char*					description,
559 														VkImageViewType				imageViewType,
560 														VkFormat					imageFormat,
561 														VkComponentMapping			componentMapping,
562 														VkSamplerReductionModeEXT	reductionMode)
563 	: SamplerMagFilterTest		(testContext, name, description, imageViewType, imageFormat, VK_FILTER_LINEAR)
564 	, m_reductionCreaterInfo	(getSamplerReductionCreateInfo(reductionMode))
565 	, m_componentMapping		(componentMapping)
566 {
567 }
568 
getSamplerCreateInfo(void) const569 VkSamplerCreateInfo SamplerMagReduceFilterTest::getSamplerCreateInfo (void) const
570 {
571 	VkSamplerCreateInfo samplerParams	= SamplerMagFilterTest::getSamplerCreateInfo();
572 
573 	samplerParams.pNext					= &m_reductionCreaterInfo;
574 
575 	return samplerParams;
576 }
577 
getComponentMapping(void) const578 VkComponentMapping SamplerMagReduceFilterTest::getComponentMapping (void) const
579 {
580 	return m_componentMapping;
581 }
582 
583 // SamplerMinReduceFilterTest
584 
SamplerMinReduceFilterTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkComponentMapping componentMapping,VkSamplerReductionModeEXT reductionMode)585 SamplerMinReduceFilterTest::SamplerMinReduceFilterTest (tcu::TestContext&	testContext,
586 														const char*					name,
587 														const char*					description,
588 														VkImageViewType				imageViewType,
589 														VkFormat					imageFormat,
590 														VkComponentMapping			componentMapping,
591 														VkSamplerReductionModeEXT	reductionMode)
592 	: SamplerMinFilterTest		(testContext, name, description, imageViewType, imageFormat, VK_FILTER_LINEAR)
593 	, m_reductionCreaterInfo	(getSamplerReductionCreateInfo(reductionMode))
594 	, m_componentMapping		(componentMapping)
595 {
596 }
597 
getSamplerCreateInfo(void) const598 VkSamplerCreateInfo SamplerMinReduceFilterTest::getSamplerCreateInfo (void) const
599 {
600 	VkSamplerCreateInfo samplerParams	= SamplerMinFilterTest::getSamplerCreateInfo();
601 
602 	samplerParams.pNext					= &m_reductionCreaterInfo;
603 
604 	return samplerParams;
605 }
606 
getComponentMapping(void) const607 VkComponentMapping SamplerMinReduceFilterTest::getComponentMapping (void) const
608 {
609 	return m_componentMapping;
610 }
611 
612 // SamplerLodTest
613 
SamplerLodTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkSamplerMipmapMode mipmapMode,float minLod,float maxLod,float mipLodBias,float samplerLod)614 SamplerLodTest::SamplerLodTest (tcu::TestContext&	testContext,
615 								const char*			name,
616 								const char*			description,
617 								VkImageViewType		imageViewType,
618 								VkFormat			imageFormat,
619 								VkSamplerMipmapMode	mipmapMode,
620 								float				minLod,
621 								float				maxLod,
622 								float				mipLodBias,
623 								float				samplerLod)
624 	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 32, samplerLod)
625 	, m_mipmapMode	(mipmapMode)
626 	, m_minLod		(minLod)
627 	, m_maxLod		(maxLod)
628 	, m_mipLodBias	(mipLodBias)
629 {
630 }
631 
getSamplerCreateInfo(void) const632 VkSamplerCreateInfo SamplerLodTest::getSamplerCreateInfo (void) const
633 {
634 	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
635 
636 	samplerParams.mipmapMode	= m_mipmapMode;
637 	samplerParams.minLod		= m_minLod;
638 	samplerParams.maxLod		= m_maxLod;
639 	samplerParams.mipLodBias	= m_mipLodBias;
640 
641 	return samplerParams;
642 }
643 
644 
645 // SamplerAddressModesTest
646 
SamplerAddressModesTest(tcu::TestContext & testContext,const char * name,const char * description,VkImageViewType imageViewType,VkFormat imageFormat,VkSamplerAddressMode addressU,VkSamplerAddressMode addressV,VkSamplerAddressMode addressW,VkBorderColor borderColor)647 SamplerAddressModesTest::SamplerAddressModesTest (tcu::TestContext&		testContext,
648 												  const char*			name,
649 												  const char*			description,
650 												  VkImageViewType		imageViewType,
651 												  VkFormat				imageFormat,
652 												  VkSamplerAddressMode	addressU,
653 												  VkSamplerAddressMode	addressV,
654 												  VkSamplerAddressMode	addressW,
655 												  VkBorderColor			borderColor)
656 	: SamplerTest	(testContext, name, description, imageViewType, imageFormat, 8, 0.0f)
657 	, m_addressU	(addressU)
658 	, m_addressV	(addressV)
659 	, m_addressW	(addressW)
660 	, m_borderColor	(borderColor)
661 {
662 }
663 
getRenderSize(VkImageViewType viewType) const664 tcu::UVec2 SamplerAddressModesTest::getRenderSize (VkImageViewType viewType) const
665 {
666 	return 4u * SamplerTest::getRenderSize(viewType);
667 }
668 
createVertices(void) const669 std::vector<Vertex4Tex4> SamplerAddressModesTest::createVertices (void) const
670 {
671 	std::vector<Vertex4Tex4> vertices = SamplerTest::createVertices();
672 
673 	switch (m_imageViewType)
674 	{
675 		case VK_IMAGE_VIEW_TYPE_1D: case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
676 			for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
677 				vertices[vertexNdx].texCoord.x() = (vertices[vertexNdx].texCoord.x() - 0.5f) * 4.0f;
678 
679 			break;
680 
681 		case VK_IMAGE_VIEW_TYPE_2D:
682 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
683 			for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
684 				vertices[vertexNdx].texCoord.xy() = (vertices[vertexNdx].texCoord.swizzle(0, 1) - tcu::Vec2(0.5f)) * 4.0f;
685 
686 			break;
687 
688 		case VK_IMAGE_VIEW_TYPE_3D:
689 			for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
690 				vertices[vertexNdx].texCoord.xyz() = (vertices[vertexNdx].texCoord.swizzle(0, 1, 2) - tcu::Vec3(0.5f)) * 4.0f;
691 
692 			break;
693 
694 		case VK_IMAGE_VIEW_TYPE_CUBE:
695 		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
696 			break;
697 
698 		default:
699 			DE_ASSERT(false);
700 	}
701 
702 	return vertices;
703 }
704 
getSamplerCreateInfo(void) const705 VkSamplerCreateInfo SamplerAddressModesTest::getSamplerCreateInfo (void) const
706 {
707 	VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
708 	samplerParams.addressModeU	= m_addressU;
709 	samplerParams.addressModeV	= m_addressV;
710 	samplerParams.addressModeW	= m_addressW;
711 	samplerParams.borderColor	= m_borderColor;
712 
713 	return samplerParams;
714 }
715 
716 
717 // Utilities to create test nodes
718 
getFormatCaseName(const VkFormat format)719 std::string getFormatCaseName (const VkFormat format)
720 {
721 	const std::string fullName = getFormatName(format);
722 
723 	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
724 
725 	return de::toLower(fullName.substr(10));
726 }
727 
createSamplerMagFilterTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)728 MovePtr<tcu::TestCaseGroup> createSamplerMagFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
729 {
730 	MovePtr<tcu::TestCaseGroup> samplerMagFilterTests (new tcu::TestCaseGroup(testCtx, "mag_filter", "Tests for magnification filter"));
731 
732 	if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
733 		samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "linear", "Magnifies image using VK_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR));
734 	samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "nearest", "Magnifies image using VK_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST));
735 
736 	return samplerMagFilterTests;
737 }
738 
createSamplerMinFilterTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)739 MovePtr<tcu::TestCaseGroup> createSamplerMinFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
740 {
741 	MovePtr<tcu::TestCaseGroup> samplerMinFilterTests (new tcu::TestCaseGroup(testCtx, "min_filter", "Tests for minification filter"));
742 
743 	if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
744 		samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "linear", "Minifies image using VK_FILTER_LINEAR", imageViewType, imageFormat, VK_FILTER_LINEAR));
745 	samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "nearest", "Minifies image using VK_FILTER_NEAREST", imageViewType, imageFormat, VK_FILTER_NEAREST));
746 
747 	return samplerMinFilterTests;
748 }
749 
750 const VkComponentMapping reduceFilterComponentMappings[]	=
751 {
752 	// filterMinmaxImageComponentMapping  == false - compatible mapping:
753 	{ VK_COMPONENT_SWIZZLE_IDENTITY,	VK_COMPONENT_SWIZZLE_ZERO,	VK_COMPONENT_SWIZZLE_ZERO,		VK_COMPONENT_SWIZZLE_ZERO	},
754 
755 	// other mappings
756 	{ VK_COMPONENT_SWIZZLE_R,			VK_COMPONENT_SWIZZLE_G,		VK_COMPONENT_SWIZZLE_B,			VK_COMPONENT_SWIZZLE_A		},
757 	{ VK_COMPONENT_SWIZZLE_B,			VK_COMPONENT_SWIZZLE_G,		VK_COMPONENT_SWIZZLE_R,			VK_COMPONENT_SWIZZLE_A		},
758 	{ VK_COMPONENT_SWIZZLE_ONE,			VK_COMPONENT_SWIZZLE_R,		VK_COMPONENT_SWIZZLE_R,			VK_COMPONENT_SWIZZLE_R		},
759 };
760 
getShortComponentSwizzleName(VkComponentSwizzle componentSwizzle)761 static std::string getShortComponentSwizzleName (VkComponentSwizzle componentSwizzle)
762 {
763 	const std::string	fullName	= getComponentSwizzleName(componentSwizzle);
764 	const char*			prefix		= "VK_COMPONENT_SWIZZLE_";
765 
766 	DE_ASSERT(de::beginsWith(fullName, prefix));
767 
768 	return de::toLower(fullName.substr(deStrnlen(prefix, -1)));
769 }
770 
getComponentMappingGroupName(const VkComponentMapping & componentMapping)771 static std::string getComponentMappingGroupName (const VkComponentMapping& componentMapping)
772 {
773 	std::ostringstream name;
774 
775 	name << "comp_";
776 
777 	name << getShortComponentSwizzleName(componentMapping.r) << "_"
778 		 << getShortComponentSwizzleName(componentMapping.g) << "_"
779 		 << getShortComponentSwizzleName(componentMapping.b) << "_"
780 		 << getShortComponentSwizzleName(componentMapping.a);
781 
782 	return name.str();
783 }
784 
createSamplerMagReduceFilterTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)785 MovePtr<tcu::TestCaseGroup> createSamplerMagReduceFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
786 {
787 	MovePtr<tcu::TestCaseGroup> samplerMagReduceFilterTests (new tcu::TestCaseGroup(testCtx, "mag_reduce", "Tests for magnification reduce filter"));
788 
789 	for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(reduceFilterComponentMappings); ++i)
790 	{
791 		const VkComponentMapping&	mapping		= reduceFilterComponentMappings[i];
792 
793 		MovePtr<tcu::TestCaseGroup> componentGroup (new tcu::TestCaseGroup(testCtx, getComponentMappingGroupName(mapping).c_str(), "Group for given view component mapping"));
794 
795 		if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
796 		{
797 			componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "average", "Magnifies image using VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT));
798 		}
799 		componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "min", "Magnifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MIN_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MIN_EXT));
800 		componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "max", "Magnifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MAX_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MAX_EXT));
801 		samplerMagReduceFilterTests->addChild(componentGroup.release());
802 	}
803 	return samplerMagReduceFilterTests;
804 }
805 
createSamplerMinReduceFilterTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)806 MovePtr<tcu::TestCaseGroup> createSamplerMinReduceFilterTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
807 {
808 	MovePtr<tcu::TestCaseGroup> samplerMinReduceFilterTests (new tcu::TestCaseGroup(testCtx, "min_reduce", "Tests for minification reduce filter"));
809 
810 	for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(reduceFilterComponentMappings); ++i)
811 	{
812 		const VkComponentMapping&	mapping = reduceFilterComponentMappings[i];
813 
814 		MovePtr<tcu::TestCaseGroup> componentGroup (new tcu::TestCaseGroup(testCtx, getComponentMappingGroupName(mapping).c_str(), "Group for given view component mapping"));
815 
816 		if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
817 		{
818 			componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "average", "Minifies image using VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT));
819 		}
820 		componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "min", "Minifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MIN_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MIN_EXT));
821 		componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "max", "Minifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MAX_EXT", imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MAX_EXT));
822 		samplerMinReduceFilterTests->addChild(componentGroup.release());
823 	}
824 	return samplerMinReduceFilterTests;
825 }
826 
createSamplerLodTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat,VkSamplerMipmapMode mipmapMode)827 MovePtr<tcu::TestCaseGroup> createSamplerLodTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat, VkSamplerMipmapMode mipmapMode)
828 {
829 	struct TestCaseConfig
830 	{
831 		const char*	name;
832 		const char*	description;
833 		float		minLod;
834 		float		maxLod;
835 		float		mipLodBias;
836 		float		lod;
837 	};
838 
839 	TestCaseConfig testCaseConfigs [] =
840 	{
841 		{ "equal_min_3_max_3",		"minLod = 3, maxLod = 3, mipLodBias = 0, lod = 0",		3.0f, 3.0f, 0.0f, 0.0f },
842 		{ "select_min_1",			"minLod = 1, maxLod = 5, mipLodBias = 0, lod = 0",		1.0f, 5.0f, 0.0f, 0.0f },
843 		{ "select_max_4",			"minLod = 0, maxLod = 4, mipLodBias = 0, lod = 5",		0.0f, 4.0f, 0.0f, 5.0f },
844 		{ "select_bias_2_1",		"minLod = 0, maxLod = 2.1, mipLodBias = 5.0, lod = 0",	0.0f, 2.1f, 5.0f, 0.0f },
845 		{ "select_bias_2_5",		"minLod = 0, maxLod = 5, mipLodBias = 2.5, lod = 0",	0.0f, 5.0f, 2.5f, 0.00001f },
846 		{ "select_bias_3_1",		"minLod = 0, maxLod = 5, mipLodBias = -0.9, lod = 4.0",	0.0f, 5.0f, -0.9f, 4.0f },
847 		{ "select_bias_3_7",		"minLod = 0, maxLod = 5, mipLodBias = 3.0, lod = 0.7",	0.0f, 5.0f, 3.0f, 0.7f },
848 	};
849 
850 	MovePtr<tcu::TestCaseGroup> samplerLodTests (new tcu::TestCaseGroup(testCtx, "lod", "Tests for sampler LOD"));
851 
852 	for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
853 	{
854 		const TestCaseConfig& config = testCaseConfigs[configNdx];
855 
856 		samplerLodTests->addChild(new SamplerLodTest(testCtx, config.name, config.description, imageViewType, imageFormat, mipmapMode, config.minLod, config.maxLod, config.mipLodBias, config.lod));
857 	}
858 
859 	return samplerLodTests;
860 }
861 
createSamplerMipmapTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)862 MovePtr<tcu::TestCaseGroup> createSamplerMipmapTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
863 {
864 	MovePtr<tcu::TestCaseGroup> samplerMipmapTests (new tcu::TestCaseGroup(testCtx, "mipmap", "Tests for mipmap modes"));
865 
866 	// Mipmap mode: nearest
867 	MovePtr<tcu::TestCaseGroup> mipmapNearestTests (new tcu::TestCaseGroup(testCtx, "nearest", "Uses VK_TEX_MIPMAP_MODE_NEAREST"));
868 	mipmapNearestTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_NEAREST).release());
869 	samplerMipmapTests->addChild(mipmapNearestTests.release());
870 
871 	// Mipmap mode: linear
872 	if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
873 	{
874 		MovePtr<tcu::TestCaseGroup> mipmapLinearTests(new tcu::TestCaseGroup(testCtx, "linear", "Uses VK_TEX_MIPMAP_MODE_LINEAR"));
875 		mipmapLinearTests->addChild(createSamplerLodTests(testCtx, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_LINEAR).release());
876 		samplerMipmapTests->addChild(mipmapLinearTests.release());
877 	}
878 
879 	return samplerMipmapTests;
880 }
881 
getAddressModesCaseName(VkSamplerAddressMode u,VkSamplerAddressMode v,VkSamplerAddressMode w,BorderColor border)882 std::string getAddressModesCaseName (VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w, BorderColor border)
883 {
884 	static const char* borderColorNames[BORDER_COLOR_COUNT] =
885 	{
886 		"opaque_black",
887 		"opaque_white",
888 		"transparent_black",
889 	};
890 
891 	std::ostringstream caseName;
892 
893 	if (u == v && v == w)
894 	{
895 		const std::string fullName = getSamplerAddressModeName(u);
896 		DE_ASSERT(de::beginsWith(fullName, "VK_SAMPLER_ADDRESS_"));
897 
898 		caseName << "all_";
899 		caseName << de::toLower(fullName.substr(19));
900 
901 		if (u == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)
902 		{
903 			caseName << "_" << borderColorNames[border];
904 		}
905 	}
906 	else
907 	{
908 		const std::string fullNameU = getSamplerAddressModeName(u);
909 		const std::string fullNameV = getSamplerAddressModeName(v);
910 		const std::string fullNameW = getSamplerAddressModeName(w);
911 
912 		DE_ASSERT(de::beginsWith(fullNameU, "VK_SAMPLER_ADDRESS_"));
913 		DE_ASSERT(de::beginsWith(fullNameV, "VK_SAMPLER_ADDRESS_"));
914 		DE_ASSERT(de::beginsWith(fullNameW, "VK_SAMPLER_ADDRESS_"));
915 
916 		caseName << "uvw"
917 				 << "_" << de::toLower(fullNameU.substr(19))
918 				 << "_" << de::toLower(fullNameV.substr(19))
919 				 << "_" << de::toLower(fullNameW.substr(19));
920 	}
921 
922 	return caseName.str();
923 }
924 
createSamplerAddressModesTests(tcu::TestContext & testCtx,VkImageViewType imageViewType,VkFormat imageFormat)925 MovePtr<tcu::TestCaseGroup> createSamplerAddressModesTests (tcu::TestContext& testCtx, VkImageViewType imageViewType, VkFormat imageFormat)
926 {
927 	struct TestCaseConfig
928 	{
929 		VkSamplerAddressMode	u;
930 		VkSamplerAddressMode	v;
931 		VkSamplerAddressMode	w;
932 		BorderColor				border;
933 	};
934 
935 	const TestCaseConfig testCaseConfigs[] =
936 	{
937 		// All address modes equal
938 		{ 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 },
939 		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_TRANSPARENT_BLACK },
940 		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_TRANSPARENT_BLACK },
941 		{ 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 },
942 
943 		// All address modes equal using border color
944 		{ 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 },
945 		{ 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 },
946 		{ 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 },
947 
948 		// Pairwise combinations of address modes not covered by previous tests
949 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE},
950 		{ 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 },
951 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_OPAQUE_WHITE },
952 		{ 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 },
953 		{ 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 },
954 		{ 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 },
955 		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE },
956 		{ 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 },
957 		{ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
958 		{ 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 },
959 		{ 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 },
960 		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },
961 		{ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE },
962 		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
963 		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		BORDER_COLOR_OPAQUE_WHITE },
964 		{ VK_SAMPLER_ADDRESS_MODE_REPEAT,				VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		BORDER_COLOR_OPAQUE_WHITE },
965 		{ 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 },
966 		{ 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 },
967 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					BORDER_COLOR_OPAQUE_WHITE },
968 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_REPEAT,					VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,	BORDER_COLOR_OPAQUE_WHITE },
969 		{ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			BORDER_COLOR_OPAQUE_WHITE },
970 		{ 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 },
971 	};
972 
973 	MovePtr<tcu::TestCaseGroup> samplerAddressModesTests (new tcu::TestCaseGroup(testCtx, "address_modes", "Tests for address modes"));
974 
975 	for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
976 	{
977 		const TestCaseConfig& config = testCaseConfigs[configNdx];
978 
979 		samplerAddressModesTests->addChild(new SamplerAddressModesTest(testCtx,
980 																	   getAddressModesCaseName(config.u, config.v, config.w, config.border).c_str(),
981 																	   "",
982 																	   imageViewType,
983 																	   imageFormat,
984 																	   config.u, config.v, config.w,
985 																	   getFormatBorderColor(config.border, imageFormat)));
986 	}
987 
988 	return samplerAddressModesTests;
989 }
990 
991 } // anonymous
992 
createSamplerTests(tcu::TestContext & testCtx)993 tcu::TestCaseGroup* createSamplerTests (tcu::TestContext& testCtx)
994 {
995 	const struct
996 	{
997 		VkImageViewType		type;
998 		const char*			name;
999 	}
1000 	imageViewTypes[] =
1001 	{
1002 		{ VK_IMAGE_VIEW_TYPE_1D,			"1d" },
1003 		{ VK_IMAGE_VIEW_TYPE_1D_ARRAY,		"1d_array" },
1004 		{ VK_IMAGE_VIEW_TYPE_2D,			"2d" },
1005 		{ VK_IMAGE_VIEW_TYPE_2D_ARRAY,		"2d_array" },
1006 		{ VK_IMAGE_VIEW_TYPE_3D,			"3d" },
1007 		{ VK_IMAGE_VIEW_TYPE_CUBE,			"cube" },
1008 		{ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,	"cube_array" }
1009 	};
1010 
1011 	const VkFormat formats[] =
1012 	{
1013 		// Packed formats
1014 		VK_FORMAT_R4G4_UNORM_PACK8,
1015 		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1016 		VK_FORMAT_R5G6B5_UNORM_PACK16,
1017 		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1018 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1019 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
1020 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1021 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1022 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1023 		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1024 
1025 		// Pairwise combinations of 8-bit channel formats, UNORM/SNORM/SINT/UINT/SRGB type x 1-to-4 channels x RGBA/BGRA order
1026 		VK_FORMAT_R8_SRGB,
1027 		VK_FORMAT_R8G8B8_UINT,
1028 		VK_FORMAT_B8G8R8A8_SINT,
1029 		VK_FORMAT_R8G8_UNORM,
1030 		VK_FORMAT_B8G8R8_SNORM,
1031 		VK_FORMAT_R8G8B8A8_SNORM,
1032 		VK_FORMAT_R8G8_UINT,
1033 		VK_FORMAT_R8_SINT,
1034 		VK_FORMAT_R8G8B8A8_SRGB,
1035 		VK_FORMAT_R8G8B8A8_UNORM,
1036 		VK_FORMAT_B8G8R8A8_UNORM,
1037 		VK_FORMAT_B8G8R8_SRGB,
1038 		VK_FORMAT_R8G8_SRGB,
1039 		VK_FORMAT_R8_UINT,
1040 		VK_FORMAT_R8G8B8A8_UINT,
1041 		VK_FORMAT_R8G8_SINT,
1042 		VK_FORMAT_R8_SNORM,
1043 		VK_FORMAT_B8G8R8_SINT,
1044 		VK_FORMAT_R8G8_SNORM,
1045 		VK_FORMAT_B8G8R8_UNORM,
1046 		VK_FORMAT_R8_UNORM,
1047 
1048 		// Pairwise combinations of 16/32-bit channel formats x SINT/UINT/SFLOAT type x 1-to-4 channels
1049 		VK_FORMAT_R32G32_SFLOAT,
1050 		VK_FORMAT_R32G32B32_UINT,
1051 		VK_FORMAT_R16G16B16A16_SFLOAT,
1052 		VK_FORMAT_R16G16_UINT,
1053 		VK_FORMAT_R32G32B32A32_SINT,
1054 		VK_FORMAT_R16G16B16_SINT,
1055 		VK_FORMAT_R16_SFLOAT,
1056 		VK_FORMAT_R32_SINT,
1057 		VK_FORMAT_R32_UINT,
1058 		VK_FORMAT_R16G16B16_SFLOAT,
1059 		VK_FORMAT_R16G16_SINT,
1060 
1061 		// More 16/32-bit formats required for testing VK_EXT_sampler_filter_minmax
1062 		VK_FORMAT_R16_SNORM,
1063 		VK_FORMAT_R32_SFLOAT,
1064 
1065 		// Scaled formats
1066 		VK_FORMAT_R8G8B8A8_SSCALED,
1067 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1068 
1069 		// Compressed formats
1070 		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
1071 		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
1072 		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
1073 		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
1074 		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
1075 		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
1076 		VK_FORMAT_EAC_R11_UNORM_BLOCK,
1077 		VK_FORMAT_EAC_R11_SNORM_BLOCK,
1078 		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
1079 		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
1080 		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
1081 		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
1082 		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
1083 		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
1084 		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
1085 		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
1086 		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
1087 		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
1088 		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
1089 		VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
1090 
1091 		// Depth formats required for testing VK_EXT_sampler_filter_minmax
1092 		VK_FORMAT_D16_UNORM,
1093 		VK_FORMAT_X8_D24_UNORM_PACK32,
1094 		VK_FORMAT_D32_SFLOAT,
1095 		VK_FORMAT_D16_UNORM_S8_UINT,
1096 		VK_FORMAT_D24_UNORM_S8_UINT,
1097 		VK_FORMAT_D32_SFLOAT_S8_UINT,
1098 	};
1099 
1100 	de::MovePtr<tcu::TestCaseGroup> samplerTests		(new tcu::TestCaseGroup(testCtx, "sampler", "Sampler tests"));
1101 	de::MovePtr<tcu::TestCaseGroup> viewTypeTests		(new tcu::TestCaseGroup(testCtx, "view_type", ""));
1102 
1103 	for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
1104 	{
1105 		const VkImageViewType			viewType		= imageViewTypes[viewTypeNdx].type;
1106 		de::MovePtr<tcu::TestCaseGroup>	viewTypeGroup	(new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
1107 		de::MovePtr<tcu::TestCaseGroup>	formatTests		(new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
1108 
1109 		for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1110 		{
1111 			const VkFormat	format			= formats[formatNdx];
1112 			const bool		isCompressed	= isCompressedFormat(format);
1113 
1114 			if (isCompressed)
1115 			{
1116 				// Do not use compressed formats with 1D and 1D array textures.
1117 				if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
1118 					break;
1119 			}
1120 
1121 			de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx,
1122 																				getFormatCaseName(format).c_str(),
1123 																				(std::string("Samples a texture of format ") + getFormatName(format)).c_str()));
1124 
1125 			if (!isCompressed)
1126 			{
1127 				// Do not include minFilter tests with compressed formats.
1128 				// Randomly generated compressed textures are too noisy and will derive in false positives.
1129 				de::MovePtr<tcu::TestCaseGroup>	minFilterTests			= createSamplerMinFilterTests(testCtx, viewType, format);
1130 				de::MovePtr<tcu::TestCaseGroup>	minReduceFilterTests	= createSamplerMinReduceFilterTests(testCtx, viewType, format);
1131 				formatGroup->addChild(minFilterTests.release());
1132 				formatGroup->addChild(minReduceFilterTests.release());
1133 			}
1134 
1135 			de::MovePtr<tcu::TestCaseGroup>	magFilterTests			= createSamplerMagFilterTests(testCtx, viewType, format);
1136 			de::MovePtr<tcu::TestCaseGroup>	magReduceFilterTests	= createSamplerMagReduceFilterTests(testCtx, viewType, format);
1137 			de::MovePtr<tcu::TestCaseGroup>	mipmapTests				= createSamplerMipmapTests(testCtx, viewType, format);
1138 
1139 			formatGroup->addChild(magFilterTests.release());
1140 			formatGroup->addChild(magReduceFilterTests.release());
1141 			formatGroup->addChild(mipmapTests.release());
1142 
1143 			if (viewType != VK_IMAGE_VIEW_TYPE_CUBE && viewType != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
1144 			{
1145 				de::MovePtr<tcu::TestCaseGroup>	addressModesTests	= createSamplerAddressModesTests(testCtx, viewType, format);
1146 				formatGroup->addChild(addressModesTests.release());
1147 			}
1148 
1149 			formatTests->addChild(formatGroup.release());
1150 		}
1151 
1152 		viewTypeGroup->addChild(formatTests.release());
1153 		viewTypeTests->addChild(viewTypeGroup.release());
1154 	}
1155 
1156 	samplerTests->addChild(viewTypeTests.release());
1157 
1158 	return samplerTests.release();
1159 }
1160 
1161 } // pipeline
1162 } // vkt
1163