• 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 Multisample Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktPipelineMultisampleTests.hpp"
26 #include "vktPipelineMultisampleImageTests.hpp"
27 #include "vktPipelineClearUtil.hpp"
28 #include "vktPipelineImageUtil.hpp"
29 #include "vktPipelineVertexUtil.hpp"
30 #include "vktPipelineReferenceRenderer.hpp"
31 #include "vktTestCase.hpp"
32 #include "vktTestCaseUtil.hpp"
33 #include "vkImageUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "tcuImageCompare.hpp"
40 #include "deUniquePtr.hpp"
41 #include "deSharedPtr.hpp"
42 #include "deStringUtil.hpp"
43 #include "deMemory.h"
44 
45 #include <sstream>
46 #include <vector>
47 #include <map>
48 
49 namespace vkt
50 {
51 namespace pipeline
52 {
53 
54 using namespace vk;
55 
56 namespace
57 {
58 enum GeometryType
59 {
60 	GEOMETRY_TYPE_OPAQUE_TRIANGLE,
61 	GEOMETRY_TYPE_OPAQUE_LINE,
62 	GEOMETRY_TYPE_OPAQUE_POINT,
63 	GEOMETRY_TYPE_OPAQUE_QUAD,
64 	GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH,	//!< placed at z = 0.5
65 	GEOMETRY_TYPE_TRANSLUCENT_QUAD,
66 	GEOMETRY_TYPE_INVISIBLE_TRIANGLE,
67 	GEOMETRY_TYPE_INVISIBLE_QUAD,
68 	GEOMETRY_TYPE_GRADIENT_QUAD
69 };
70 
71 enum TestModeBits
72 {
73 	TEST_MODE_DEPTH_BIT		= 1u,
74 	TEST_MODE_STENCIL_BIT	= 2u,
75 };
76 typedef deUint32 TestModeFlags;
77 
78 void									initMultisamplePrograms				(SourceCollections& sources, GeometryType geometryType);
79 bool									isSupportedSampleCount				(const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples);
80 bool									isSupportedDepthStencilFormat		(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format);
81 VkPipelineColorBlendAttachmentState		getDefaultColorBlendAttachmentState	(void);
82 deUint32								getUniqueColorsCount				(const tcu::ConstPixelBufferAccess& image);
83 VkImageAspectFlags						getImageAspectFlags					(const VkFormat format);
84 VkPrimitiveTopology						getPrimitiveTopology				(const GeometryType geometryType);
85 std::vector<Vertex4RGBA>				generateVertices					(const GeometryType geometryType);
86 VkFormat								findSupportedDepthStencilFormat		(Context& context, const bool useDepth, const bool useStencil);
87 
88 class MultisampleTest : public vkt::TestCase
89 {
90 public:
91 
92 												MultisampleTest						(tcu::TestContext&								testContext,
93 																					 const std::string&								name,
94 																					 const std::string&								description,
95 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
96 																					 const VkPipelineColorBlendAttachmentState&		blendState,
97 																					 GeometryType									geometryType);
~MultisampleTest(void)98 	virtual										~MultisampleTest					(void) {}
99 
100 	virtual void								initPrograms						(SourceCollections& programCollection) const;
101 	virtual TestInstance*						createInstance						(Context& context) const;
102 
103 protected:
104 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
105 																					 VkPrimitiveTopology							topology,
106 																					 const std::vector<Vertex4RGBA>&				vertices,
107 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
108 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const = 0;
109 	VkPipelineMultisampleStateCreateInfo		m_multisampleStateParams;
110 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
111 	const GeometryType							m_geometryType;
112 	std::vector<VkSampleMask>					m_sampleMask;
113 };
114 
115 class RasterizationSamplesTest : public MultisampleTest
116 {
117 public:
118 												RasterizationSamplesTest			(tcu::TestContext&		testContext,
119 																					 const std::string&		name,
120 																					 const std::string&		description,
121 																					 VkSampleCountFlagBits	rasterizationSamples,
122 																					 GeometryType			geometryType,
123 																					 TestModeFlags			modeFlags				= 0u);
~RasterizationSamplesTest(void)124 	virtual										~RasterizationSamplesTest			(void) {}
125 
126 protected:
127 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
128 																					 VkPrimitiveTopology							topology,
129 																					 const std::vector<Vertex4RGBA>&				vertices,
130 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
131 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
132 
133 	static VkPipelineMultisampleStateCreateInfo	getRasterizationSamplesStateParams	(VkSampleCountFlagBits rasterizationSamples);
134 
135 	const TestModeFlags							m_modeFlags;
136 };
137 
138 class MinSampleShadingTest : public MultisampleTest
139 {
140 public:
141 												MinSampleShadingTest				(tcu::TestContext&		testContext,
142 																					 const std::string&		name,
143 																					 const std::string&		description,
144 																					 VkSampleCountFlagBits	rasterizationSamples,
145 																					 float					minSampleShading,
146 																					 GeometryType			geometryType);
~MinSampleShadingTest(void)147 	virtual										~MinSampleShadingTest				(void) {}
148 
149 protected:
150 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
151 																					 VkPrimitiveTopology							topology,
152 																					 const std::vector<Vertex4RGBA>&				vertices,
153 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
154 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
155 
156 	static VkPipelineMultisampleStateCreateInfo	getMinSampleShadingStateParams		(VkSampleCountFlagBits rasterizationSamples, float minSampleShading);
157 };
158 
159 class SampleMaskTest : public MultisampleTest
160 {
161 public:
162 												SampleMaskTest						(tcu::TestContext&					testContext,
163 																					 const std::string&					name,
164 																					 const std::string&					description,
165 																					 VkSampleCountFlagBits				rasterizationSamples,
166 																					 const std::vector<VkSampleMask>&	sampleMask,
167 																					 GeometryType						geometryType);
168 
~SampleMaskTest(void)169 	virtual										~SampleMaskTest						(void) {}
170 
171 protected:
172 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
173 																					 VkPrimitiveTopology							topology,
174 																					 const std::vector<Vertex4RGBA>&				vertices,
175 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
176 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
177 
178 	static VkPipelineMultisampleStateCreateInfo	getSampleMaskStateParams			(VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask);
179 };
180 
181 class AlphaToOneTest : public MultisampleTest
182 {
183 public:
184 												AlphaToOneTest					(tcu::TestContext&					testContext,
185 																				 const std::string&					name,
186 																				 const std::string&					description,
187 																				 VkSampleCountFlagBits				rasterizationSamples);
188 
~AlphaToOneTest(void)189 	virtual										~AlphaToOneTest					(void) {}
190 
191 protected:
192 	virtual TestInstance*						createMultisampleTestInstance	(Context&										context,
193 																				 VkPrimitiveTopology							topology,
194 																				 const std::vector<Vertex4RGBA>&				vertices,
195 																				 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
196 																				 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
197 
198 	static VkPipelineMultisampleStateCreateInfo	getAlphaToOneStateParams		(VkSampleCountFlagBits rasterizationSamples);
199 	static VkPipelineColorBlendAttachmentState	getAlphaToOneBlendState			(void);
200 };
201 
202 class AlphaToCoverageTest : public MultisampleTest
203 {
204 public:
205 												AlphaToCoverageTest				(tcu::TestContext&		testContext,
206 																				 const std::string&		name,
207 																				 const std::string&		description,
208 																				 VkSampleCountFlagBits	rasterizationSamples,
209 																				 GeometryType			geometryType);
210 
~AlphaToCoverageTest(void)211 	virtual										~AlphaToCoverageTest			(void) {}
212 
213 protected:
214 	virtual TestInstance*						createMultisampleTestInstance	(Context&										context,
215 																				 VkPrimitiveTopology							topology,
216 																				 const std::vector<Vertex4RGBA>&				vertices,
217 																				 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
218 																				 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
219 
220 	static VkPipelineMultisampleStateCreateInfo	getAlphaToCoverageStateParams	(VkSampleCountFlagBits rasterizationSamples);
221 
222 	GeometryType								m_geometryType;
223 };
224 
225 typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp;
226 
227 class MultisampleRenderer
228 {
229 public:
230 												MultisampleRenderer			(Context&										context,
231 																			 const VkFormat									colorFormat,
232 																			 const tcu::IVec2&								renderSize,
233 																			 const VkPrimitiveTopology						topology,
234 																			 const std::vector<Vertex4RGBA>&				vertices,
235 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
236 																			 const VkPipelineColorBlendAttachmentState&		blendState);
237 
238 												MultisampleRenderer			(Context&										context,
239 																			 const VkFormat									colorFormat,
240 																			 const VkFormat									depthStencilFormat,
241 																			 const tcu::IVec2&								renderSize,
242 																			 const bool										useDepth,
243 																			 const bool										useStencil,
244 																			 const deUint32									numTopologies,
245 																			 const VkPrimitiveTopology*						pTopology,
246 																			 const std::vector<Vertex4RGBA>*				pVertices,
247 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
248 																			 const VkPipelineColorBlendAttachmentState&		blendState);
249 
250 	virtual										~MultisampleRenderer		(void);
251 
252 	de::MovePtr<tcu::TextureLevel>				render						(void);
253 
254 protected:
255 	void										initialize					(Context&										context,
256 																			 const deUint32									numTopologies,
257 																			 const VkPrimitiveTopology*						pTopology,
258 																			 const std::vector<Vertex4RGBA>*				pVertices);
259 
260 	Context&									m_context;
261 
262 	const VkFormat								m_colorFormat;
263 	const VkFormat								m_depthStencilFormat;
264 	tcu::IVec2									m_renderSize;
265 	const bool									m_useDepth;
266 	const bool									m_useStencil;
267 
268 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
269 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
270 
271 	Move<VkImage>								m_colorImage;
272 	de::MovePtr<Allocation>						m_colorImageAlloc;
273 	Move<VkImageView>							m_colorAttachmentView;
274 
275 	Move<VkImage>								m_resolveImage;
276 	de::MovePtr<Allocation>						m_resolveImageAlloc;
277 	Move<VkImageView>							m_resolveAttachmentView;
278 
279 	Move<VkImage>								m_depthStencilImage;
280 	de::MovePtr<Allocation>						m_depthStencilImageAlloc;
281 	Move<VkImageView>							m_depthStencilAttachmentView;
282 
283 	Move<VkRenderPass>							m_renderPass;
284 	Move<VkFramebuffer>							m_framebuffer;
285 
286 	Move<VkShaderModule>						m_vertexShaderModule;
287 	Move<VkShaderModule>						m_fragmentShaderModule;
288 
289 	Move<VkBuffer>								m_vertexBuffer;
290 	de::MovePtr<Allocation>						m_vertexBufferAlloc;
291 
292 	Move<VkPipelineLayout>						m_pipelineLayout;
293 	std::vector<VkPipelineSp>					m_graphicsPipelines;
294 
295 	Move<VkCommandPool>							m_cmdPool;
296 	Move<VkCommandBuffer>						m_cmdBuffer;
297 
298 	Move<VkFence>								m_fence;
299 };
300 
301 class RasterizationSamplesInstance : public vkt::TestInstance
302 {
303 public:
304 										RasterizationSamplesInstance	(Context&										context,
305 																		 VkPrimitiveTopology							topology,
306 																		 const std::vector<Vertex4RGBA>&				vertices,
307 																		 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
308 																		 const VkPipelineColorBlendAttachmentState&		blendState,
309 																		 const TestModeFlags							modeFlags);
~RasterizationSamplesInstance(void)310 	virtual								~RasterizationSamplesInstance	(void) {}
311 
312 	virtual tcu::TestStatus				iterate							(void);
313 
314 protected:
315 	virtual tcu::TestStatus				verifyImage						(const tcu::ConstPixelBufferAccess& result);
316 
317 	const VkFormat						m_colorFormat;
318 	const tcu::IVec2					m_renderSize;
319 	const VkPrimitiveTopology			m_primitiveTopology;
320 	const std::vector<Vertex4RGBA>		m_vertices;
321 	const std::vector<Vertex4RGBA>		m_fullQuadVertices;			//!< used by depth/stencil case
322 	const TestModeFlags					m_modeFlags;
323 	de::MovePtr<MultisampleRenderer>	m_multisampleRenderer;
324 };
325 
326 class MinSampleShadingInstance : public vkt::TestInstance
327 {
328 public:
329 												MinSampleShadingInstance	(Context&										context,
330 																			 VkPrimitiveTopology							topology,
331 																			 const std::vector<Vertex4RGBA>&				vertices,
332 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
333 																			 const VkPipelineColorBlendAttachmentState&		blendState);
~MinSampleShadingInstance(void)334 	virtual										~MinSampleShadingInstance	(void) {}
335 
336 	virtual tcu::TestStatus						iterate						(void);
337 
338 protected:
339 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& testShadingImage,
340 																			 const tcu::ConstPixelBufferAccess& minShadingImage,
341 																			 const tcu::ConstPixelBufferAccess& maxShadingImage);
342 	const VkFormat								m_colorFormat;
343 	const tcu::IVec2							m_renderSize;
344 	const VkPrimitiveTopology					m_primitiveTopology;
345 	const std::vector<Vertex4RGBA>				m_vertices;
346 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
347 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
348 };
349 
350 class SampleMaskInstance : public vkt::TestInstance
351 {
352 public:
353 												SampleMaskInstance			(Context&										context,
354 																			 VkPrimitiveTopology							topology,
355 																			 const std::vector<Vertex4RGBA>&				vertices,
356 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
357 																			 const VkPipelineColorBlendAttachmentState&		blendState);
~SampleMaskInstance(void)358 	virtual										~SampleMaskInstance			(void) {}
359 
360 	virtual tcu::TestStatus						iterate						(void);
361 
362 protected:
363 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& testShadingImage,
364 																			 const tcu::ConstPixelBufferAccess& minShadingImage,
365 																			 const tcu::ConstPixelBufferAccess& maxShadingImage);
366 	const VkFormat								m_colorFormat;
367 	const tcu::IVec2							m_renderSize;
368 	const VkPrimitiveTopology					m_primitiveTopology;
369 	const std::vector<Vertex4RGBA>				m_vertices;
370 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
371 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
372 };
373 
374 class AlphaToOneInstance : public vkt::TestInstance
375 {
376 public:
377 												AlphaToOneInstance			(Context&										context,
378 																			 VkPrimitiveTopology							topology,
379 																			 const std::vector<Vertex4RGBA>&				vertices,
380 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
381 																			 const VkPipelineColorBlendAttachmentState&		blendState);
~AlphaToOneInstance(void)382 	virtual										~AlphaToOneInstance			(void) {}
383 
384 	virtual tcu::TestStatus						iterate						(void);
385 
386 protected:
387 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& alphaOneImage,
388 																			 const tcu::ConstPixelBufferAccess& noAlphaOneImage);
389 	const VkFormat								m_colorFormat;
390 	const tcu::IVec2							m_renderSize;
391 	const VkPrimitiveTopology					m_primitiveTopology;
392 	const std::vector<Vertex4RGBA>				m_vertices;
393 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
394 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
395 };
396 
397 class AlphaToCoverageInstance : public vkt::TestInstance
398 {
399 public:
400 												AlphaToCoverageInstance		(Context&										context,
401 																			 VkPrimitiveTopology							topology,
402 																			 const std::vector<Vertex4RGBA>&				vertices,
403 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
404 																			 const VkPipelineColorBlendAttachmentState&		blendState,
405 																			 GeometryType									geometryType);
~AlphaToCoverageInstance(void)406 	virtual										~AlphaToCoverageInstance	(void) {}
407 
408 	virtual tcu::TestStatus						iterate						(void);
409 
410 protected:
411 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& result);
412 	const VkFormat								m_colorFormat;
413 	const tcu::IVec2							m_renderSize;
414 	const VkPrimitiveTopology					m_primitiveTopology;
415 	const std::vector<Vertex4RGBA>				m_vertices;
416 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
417 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
418 	const GeometryType							m_geometryType;
419 };
420 
421 
422 // Helper functions
423 
initMultisamplePrograms(SourceCollections & sources,GeometryType geometryType)424 void initMultisamplePrograms (SourceCollections& sources, GeometryType geometryType)
425 {
426 	std::ostringstream vertexSource;
427 
428 	vertexSource <<
429 		"#version 310 es\n"
430 		"layout(location = 0) in vec4 position;\n"
431 		"layout(location = 1) in vec4 color;\n"
432 		"layout(location = 0) out highp vec4 vtxColor;\n"
433 		"void main (void)\n"
434 		"{\n"
435 		"	gl_Position = position;\n"
436 		"	vtxColor = color;\n"
437 		<< (geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? "	gl_PointSize = 3.0f;\n"
438 														 : "" )
439 		<< "}\n";
440 
441 	static const char* fragmentSource =
442 		"#version 310 es\n"
443 		"layout(location = 0) in highp vec4 vtxColor;\n"
444 		"layout(location = 0) out highp vec4 fragColor;\n"
445 		"void main (void)\n"
446 		"{\n"
447 		"	fragColor = vtxColor;\n"
448 		"}\n";
449 
450 	sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
451 	sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
452 }
453 
isSupportedSampleCount(const InstanceInterface & instanceInterface,VkPhysicalDevice physicalDevice,VkSampleCountFlagBits rasterizationSamples)454 bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples)
455 {
456 	VkPhysicalDeviceProperties deviceProperties;
457 
458 	instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties);
459 
460 	return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples);
461 }
462 
getDefaultColorBlendAttachmentState(void)463 VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void)
464 {
465 	const VkPipelineColorBlendAttachmentState colorBlendState =
466 	{
467 		false,														// VkBool32					blendEnable;
468 		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcColorBlendFactor;
469 		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstColorBlendFactor;
470 		VK_BLEND_OP_ADD,											// VkBlendOp				colorBlendOp;
471 		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcAlphaBlendFactor;
472 		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstAlphaBlendFactor;
473 		VK_BLEND_OP_ADD,											// VkBlendOp				alphaBlendOp;
474 		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
475 			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
476 	};
477 
478 	return colorBlendState;
479 }
480 
getUniqueColorsCount(const tcu::ConstPixelBufferAccess & image)481 deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image)
482 {
483 	DE_ASSERT(image.getFormat().getPixelSize() == 4);
484 
485 	std::map<deUint32, deUint32>	histogram; // map<pixel value, number of occurrences>
486 	const deUint32					pixelCount	= image.getWidth() * image.getHeight() * image.getDepth();
487 
488 	for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
489 	{
490 		const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx);
491 
492 		if (histogram.find(pixelValue) != histogram.end())
493 			histogram[pixelValue]++;
494 		else
495 			histogram[pixelValue] = 1;
496 	}
497 
498 	return (deUint32)histogram.size();
499 }
500 
getImageAspectFlags(const VkFormat format)501 VkImageAspectFlags getImageAspectFlags (const VkFormat format)
502 {
503 	const tcu::TextureFormat tcuFormat = mapVkFormat(format);
504 
505 	if      (tcuFormat.order == tcu::TextureFormat::DS)		return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
506 	else if (tcuFormat.order == tcu::TextureFormat::D)		return VK_IMAGE_ASPECT_DEPTH_BIT;
507 	else if (tcuFormat.order == tcu::TextureFormat::S)		return VK_IMAGE_ASPECT_STENCIL_BIT;
508 
509 	DE_ASSERT(false);
510 	return 0u;
511 }
512 
generateVertices(const GeometryType geometryType)513 std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType)
514 {
515 	std::vector<Vertex4RGBA> vertices;
516 
517 	switch (geometryType)
518 	{
519 		case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
520 		case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:
521 		{
522 			Vertex4RGBA vertexData[3] =
523 			{
524 				{
525 					tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
526 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
527 				},
528 				{
529 					tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
530 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
531 				},
532 				{
533 					tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
534 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
535 				}
536 			};
537 
538 			if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE)
539 			{
540 				for (int i = 0; i < 3; i++)
541 					vertexData[i].color = tcu::Vec4();
542 			}
543 
544 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3);
545 			break;
546 		}
547 
548 		case GEOMETRY_TYPE_OPAQUE_LINE:
549 		{
550 			const Vertex4RGBA vertexData[2] =
551 			{
552 				{
553 					tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f),
554 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
555 				},
556 				{
557 					tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f),
558 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
559 				}
560 			};
561 
562 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2);
563 			break;
564 		}
565 
566 		case GEOMETRY_TYPE_OPAQUE_POINT:
567 		{
568 			const Vertex4RGBA vertex =
569 			{
570 				tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
571 				tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
572 			};
573 
574 			vertices = std::vector<Vertex4RGBA>(1, vertex);
575 			break;
576 		}
577 
578 		case GEOMETRY_TYPE_OPAQUE_QUAD:
579 		case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
580 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
581 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
582 		case GEOMETRY_TYPE_GRADIENT_QUAD:
583 		{
584 			Vertex4RGBA vertexData[4] =
585 			{
586 				{
587 					tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
588 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
589 				},
590 				{
591 					tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),
592 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
593 				},
594 				{
595 					tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
596 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
597 				},
598 				{
599 					tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
600 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
601 				}
602 			};
603 
604 			if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD)
605 			{
606 				for (int i = 0; i < 4; i++)
607 					vertexData[i].color.w() = 0.25f;
608 			}
609 			else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD)
610 			{
611 				for (int i = 0; i < 4; i++)
612 					vertexData[i].color.w() = 0.0f;
613 			}
614 			else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD)
615 			{
616 				vertexData[0].color.w() = 0.0f;
617 				vertexData[2].color.w() = 0.0f;
618 			}
619 			else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)
620 			{
621 				for (int i = 0; i < 4; i++)
622 					vertexData[i].position.z() = 0.5f;
623 			}
624 
625 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 4);
626 			break;
627 		}
628 
629 		default:
630 			DE_ASSERT(false);
631 	}
632 	return vertices;
633 }
634 
getPrimitiveTopology(const GeometryType geometryType)635 VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType)
636 {
637 	switch (geometryType)
638 	{
639 		case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
640 		case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:			return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
641 
642 		case GEOMETRY_TYPE_OPAQUE_LINE:					return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
643 		case GEOMETRY_TYPE_OPAQUE_POINT:				return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
644 
645 		case GEOMETRY_TYPE_OPAQUE_QUAD:
646 		case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
647 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
648 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
649 		case GEOMETRY_TYPE_GRADIENT_QUAD:				return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
650 
651 		default:
652 			DE_ASSERT(false);
653 			return VK_PRIMITIVE_TOPOLOGY_LAST;
654 	}
655 }
656 
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)657 bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
658 {
659 	VkFormatProperties formatProps;
660 	vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
661 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
662 }
663 
findSupportedDepthStencilFormat(Context & context,const bool useDepth,const bool useStencil)664 VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil)
665 {
666 	if (useDepth && !useStencil)
667 		return VK_FORMAT_D16_UNORM;		// must be supported
668 
669 	const InstanceInterface&	vki			= context.getInstanceInterface();
670 	const VkPhysicalDevice		physDevice	= context.getPhysicalDevice();
671 
672 	// One of these formats must be supported.
673 
674 	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
675 		return VK_FORMAT_D24_UNORM_S8_UINT;
676 
677 	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT))
678 		return VK_FORMAT_D32_SFLOAT_S8_UINT;
679 
680 	return VK_FORMAT_UNDEFINED;
681 }
682 
683 
684 // MultisampleTest
685 
MultisampleTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType)686 MultisampleTest::MultisampleTest (tcu::TestContext&								testContext,
687 								  const std::string&							name,
688 								  const std::string&							description,
689 								  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
690 								  const VkPipelineColorBlendAttachmentState&	blendState,
691 								  GeometryType									geometryType)
692 	: vkt::TestCase				(testContext, name, description)
693 	, m_multisampleStateParams	(multisampleStateParams)
694 	, m_colorBlendState			(blendState)
695 	, m_geometryType			(geometryType)
696 {
697 	if (m_multisampleStateParams.pSampleMask)
698 	{
699 		// Copy pSampleMask to avoid dependencies with other classes
700 
701 		const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32);
702 
703 		for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++)
704 			m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]);
705 
706 		m_multisampleStateParams.pSampleMask = m_sampleMask.data();
707 	}
708 }
709 
initPrograms(SourceCollections & programCollection) const710 void MultisampleTest::initPrograms (SourceCollections& programCollection) const
711 {
712 	initMultisamplePrograms(programCollection, m_geometryType);
713 }
714 
createInstance(Context & context) const715 TestInstance* MultisampleTest::createInstance (Context& context) const
716 {
717 	return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState);
718 }
719 
720 
721 // RasterizationSamplesTest
722 
RasterizationSamplesTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType,TestModeFlags modeFlags)723 RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext&		testContext,
724 													const std::string&		name,
725 													const std::string&		description,
726 													VkSampleCountFlagBits	rasterizationSamples,
727 													GeometryType			geometryType,
728 													TestModeFlags			modeFlags)
729 	: MultisampleTest	(testContext, name, description, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType)
730 	, m_modeFlags		(modeFlags)
731 {
732 }
733 
getRasterizationSamplesStateParams(VkSampleCountFlagBits rasterizationSamples)734 VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples)
735 {
736 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
737 	{
738 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
739 		DE_NULL,													// const void*								pNext;
740 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
741 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
742 		false,														// VkBool32									sampleShadingEnable;
743 		0.0f,														// float									minSampleShading;
744 		DE_NULL,													// const VkSampleMask*						pSampleMask;
745 		false,														// VkBool32									alphaToCoverageEnable;
746 		false														// VkBool32									alphaToOneEnable;
747 	};
748 
749 	return multisampleStateParams;
750 }
751 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const752 TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context&										context,
753 																	   VkPrimitiveTopology							topology,
754 																	   const std::vector<Vertex4RGBA>&				vertices,
755 																	   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
756 																	   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
757 {
758 	return new RasterizationSamplesInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_modeFlags);
759 }
760 
761 
762 // MinSampleShadingTest
763 
MinSampleShadingTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,float minSampleShading,GeometryType geometryType)764 MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext&		testContext,
765 											const std::string&		name,
766 											const std::string&		description,
767 											VkSampleCountFlagBits	rasterizationSamples,
768 											float					minSampleShading,
769 											GeometryType			geometryType)
770 	: MultisampleTest	(testContext, name, description, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading), getDefaultColorBlendAttachmentState(), geometryType)
771 {
772 }
773 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const774 TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context&										context,
775 																   VkPrimitiveTopology							topology,
776 																   const std::vector<Vertex4RGBA>&				vertices,
777 																   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
778 																   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
779 {
780 	return new MinSampleShadingInstance(context, topology, vertices, multisampleStateParams, colorBlendState);
781 }
782 
getMinSampleShadingStateParams(VkSampleCountFlagBits rasterizationSamples,float minSampleShading)783 VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading)
784 {
785 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
786 	{
787 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
788 		DE_NULL,													// const void*								pNext;
789 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
790 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
791 		true,														// VkBool32									sampleShadingEnable;
792 		minSampleShading,											// float									minSampleShading;
793 		DE_NULL,													// const VkSampleMask*						pSampleMask;
794 		false,														//  VkBool32								alphaToCoverageEnable;
795 		false														//  VkBool32								alphaToOneEnable;
796 	};
797 
798 	return multisampleStateParams;
799 }
800 
801 
802 // SampleMaskTest
803 
SampleMaskTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,const std::vector<VkSampleMask> & sampleMask,GeometryType geometryType)804 SampleMaskTest::SampleMaskTest (tcu::TestContext&					testContext,
805 								const std::string&					name,
806 								const std::string&					description,
807 								VkSampleCountFlagBits				rasterizationSamples,
808 								const std::vector<VkSampleMask>&	sampleMask,
809 								GeometryType						geometryType)
810 	: MultisampleTest	(testContext, name, description, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType)
811 {
812 }
813 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const814 TestInstance* SampleMaskTest::createMultisampleTestInstance (Context&										context,
815 															 VkPrimitiveTopology							topology,
816 															 const std::vector<Vertex4RGBA>&				vertices,
817 															 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
818 															 const VkPipelineColorBlendAttachmentState&		colorBlendState) const
819 {
820 	return new SampleMaskInstance(context, topology,vertices, multisampleStateParams, colorBlendState);
821 }
822 
getSampleMaskStateParams(VkSampleCountFlagBits rasterizationSamples,const std::vector<VkSampleMask> & sampleMask)823 VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask)
824 {
825 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
826 	{
827 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
828 		DE_NULL,													// const void*								pNext;
829 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
830 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
831 		false,														// VkBool32									sampleShadingEnable;
832 		0.0f,														// float									minSampleShading;
833 		sampleMask.data(),											// const VkSampleMask*						pSampleMask;
834 		false,														// VkBool32									alphaToCoverageEnable;
835 		false														// VkBool32									alphaToOneEnable;
836 	};
837 
838 	return multisampleStateParams;
839 }
840 
841 
842 // AlphaToOneTest
843 
AlphaToOneTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples)844 AlphaToOneTest::AlphaToOneTest (tcu::TestContext&		testContext,
845 								const std::string&		name,
846 								const std::string&		description,
847 								VkSampleCountFlagBits	rasterizationSamples)
848 	: MultisampleTest	(testContext, name, description, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD)
849 {
850 }
851 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const852 TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context&										context,
853 															 VkPrimitiveTopology							topology,
854 															 const std::vector<Vertex4RGBA>&				vertices,
855 															 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
856 															 const VkPipelineColorBlendAttachmentState&		colorBlendState) const
857 {
858 	return new AlphaToOneInstance(context, topology, vertices, multisampleStateParams, colorBlendState);
859 }
860 
getAlphaToOneStateParams(VkSampleCountFlagBits rasterizationSamples)861 VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples)
862 {
863 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
864 	{
865 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
866 		DE_NULL,													// const void*								pNext;
867 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
868 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
869 		false,														// VkBool32									sampleShadingEnable;
870 		0.0f,														// float									minSampleShading;
871 		DE_NULL,													// const VkSampleMask*						pSampleMask;
872 		false,														// VkBool32									alphaToCoverageEnable;
873 		true														// VkBool32									alphaToOneEnable;
874 	};
875 
876 	return multisampleStateParams;
877 }
878 
getAlphaToOneBlendState(void)879 VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void)
880 {
881 	const VkPipelineColorBlendAttachmentState colorBlendState =
882 	{
883 		true,														// VkBool32					blendEnable;
884 		VK_BLEND_FACTOR_SRC_ALPHA,									// VkBlendFactor			srcColorBlendFactor;
885 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,						// VkBlendFactor			dstColorBlendFactor;
886 		VK_BLEND_OP_ADD,											// VkBlendOp				colorBlendOp;
887 		VK_BLEND_FACTOR_SRC_ALPHA,									// VkBlendFactor			srcAlphaBlendFactor;
888 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,						// VkBlendFactor			dstAlphaBlendFactor;
889 		VK_BLEND_OP_ADD,											// VkBlendOp				alphaBlendOp;
890 		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
891 			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
892 	};
893 
894 	return colorBlendState;
895 }
896 
897 
898 // AlphaToCoverageTest
899 
AlphaToCoverageTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType)900 AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext&			testContext,
901 										  const std::string&		name,
902 										  const std::string&		description,
903 										  VkSampleCountFlagBits		rasterizationSamples,
904 										  GeometryType				geometryType)
905 	: MultisampleTest	(testContext, name, description, getAlphaToCoverageStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType)
906 	, m_geometryType	(geometryType)
907 {
908 }
909 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const910 TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context&										context,
911 																  VkPrimitiveTopology							topology,
912 																  const std::vector<Vertex4RGBA>&				vertices,
913 																  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
914 																  const VkPipelineColorBlendAttachmentState&	colorBlendState) const
915 {
916 	return new AlphaToCoverageInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType);
917 }
918 
getAlphaToCoverageStateParams(VkSampleCountFlagBits rasterizationSamples)919 VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples)
920 {
921 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
922 	{
923 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
924 		DE_NULL,													// const void*								pNext;
925 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
926 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
927 		false,														// VkBool32									sampleShadingEnable;
928 		0.0f,														// float									minSampleShading;
929 		DE_NULL,													// const VkSampleMask*						pSampleMask;
930 		true,														// VkBool32									alphaToCoverageEnable;
931 		false														// VkBool32									alphaToOneEnable;
932 	};
933 
934 	return multisampleStateParams;
935 }
936 
937 // RasterizationSamplesInstance
938 
RasterizationSamplesInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,const TestModeFlags modeFlags)939 RasterizationSamplesInstance::RasterizationSamplesInstance (Context&										context,
940 															VkPrimitiveTopology								topology,
941 															const std::vector<Vertex4RGBA>&					vertices,
942 															const VkPipelineMultisampleStateCreateInfo&		multisampleStateParams,
943 															const VkPipelineColorBlendAttachmentState&		blendState,
944 															const TestModeFlags								modeFlags)
945 	: vkt::TestInstance		(context)
946 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
947 	, m_renderSize			(32, 32)
948 	, m_primitiveTopology	(topology)
949 	, m_vertices			(vertices)
950 	, m_fullQuadVertices	(generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH))
951 	, m_modeFlags			(modeFlags)
952 {
953 	if (m_modeFlags != 0)
954 	{
955 		const bool		useDepth			= (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0;
956 		const bool		useStencil			= (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0;
957 		const VkFormat	depthStencilFormat	= findSupportedDepthStencilFormat(context, useDepth, useStencil);
958 
959 		if (depthStencilFormat == VK_FORMAT_UNDEFINED)
960 			TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported");
961 
962 		const VkPrimitiveTopology		pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };
963 		const std::vector<Vertex4RGBA>	pVertices[2] = { m_vertices, m_fullQuadVertices };
964 
965 		m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
966 			new MultisampleRenderer(
967 				context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState));
968 	}
969 	else
970 	{
971 		m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
972 			new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState));
973 	}
974 }
975 
iterate(void)976 tcu::TestStatus RasterizationSamplesInstance::iterate (void)
977 {
978 	de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render());
979 	return verifyImage(level->getAccess());
980 }
981 
verifyImage(const tcu::ConstPixelBufferAccess & result)982 tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
983 {
984 	// Verify range of unique pixels
985 	{
986 		const deUint32	numUniqueColors = getUniqueColorsCount(result);
987 		const deUint32	minUniqueColors	= 3;
988 
989 		tcu::TestLog& log = m_context.getTestContext().getLog();
990 
991 		log << tcu::TestLog::Message
992 			<< "\nMin. unique colors expected: " << minUniqueColors << "\n"
993 			<< "Unique colors found: " << numUniqueColors << "\n"
994 			<< tcu::TestLog::EndMessage;
995 
996 		if (numUniqueColors < minUniqueColors)
997 			return tcu::TestStatus::fail("Unique colors out of expected bounds");
998 	}
999 
1000 	// Verify shape of the rendered primitive (fuzzy-compare)
1001 	{
1002 		const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
1003 		const tcu::TextureFormat	tcuDepthFormat	= tcu::TextureFormat();
1004 		const ColorVertexShader		vertexShader;
1005 		const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
1006 		const rr::Program			program			(&vertexShader, &fragmentShader);
1007 		ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
1008 		rr::RenderState				renderState		(refRenderer.getViewportState());
1009 
1010 		if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
1011 		{
1012 			VkPhysicalDeviceProperties deviceProperties;
1013 
1014 			m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
1015 
1016 			// gl_PointSize is clamped to pointSizeRange
1017 			renderState.point.pointSize = deFloatMin(3.0f, deviceProperties.limits.pointSizeRange[1]);
1018 		}
1019 
1020 		if (m_modeFlags == 0)
1021 		{
1022 			refRenderer.colorClear(tcu::Vec4(0.0f));
1023 			refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
1024 		}
1025 		else
1026 		{
1027 			// For depth/stencil case the primitive is invisible and the surroundings are filled red.
1028 			refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1029 			refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
1030 		}
1031 
1032 		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT))
1033 			return tcu::TestStatus::fail("Primitive has unexpected shape");
1034 	}
1035 
1036 	return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds");
1037 }
1038 
1039 
1040 // MinSampleShadingInstance
1041 
MinSampleShadingInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState)1042 MinSampleShadingInstance::MinSampleShadingInstance (Context&									context,
1043 													VkPrimitiveTopology							topology,
1044 													const std::vector<Vertex4RGBA>&				vertices,
1045 													const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1046 													const VkPipelineColorBlendAttachmentState&	colorBlendState)
1047 	: vkt::TestInstance			(context)
1048 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
1049 	, m_renderSize				(32, 32)
1050 	, m_primitiveTopology		(topology)
1051 	, m_vertices				(vertices)
1052 	, m_multisampleStateParams	(multisampleStateParams)
1053 	, m_colorBlendState			(colorBlendState)
1054 {
1055 	VkPhysicalDeviceFeatures deviceFeatures;
1056 
1057 	m_context.getInstanceInterface().getPhysicalDeviceFeatures(m_context.getPhysicalDevice(), &deviceFeatures);
1058 
1059 	if (!deviceFeatures.sampleRateShading)
1060 		throw tcu::NotSupportedError("Sample shading is not supported");
1061 }
1062 
iterate(void)1063 tcu::TestStatus MinSampleShadingInstance::iterate (void)
1064 {
1065 	de::MovePtr<tcu::TextureLevel>				testShadingImage;
1066 	de::MovePtr<tcu::TextureLevel>				minShadingImage;
1067 	de::MovePtr<tcu::TextureLevel>				maxShadingImage;
1068 
1069 	// Render with test minSampleShading
1070 	{
1071 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
1072 		testShadingImage = renderer.render();
1073 	}
1074 
1075 	// Render with minSampleShading = 0.0f
1076 	{
1077 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
1078 		multisampleParams.minSampleShading = 0.0f;
1079 
1080 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
1081 		minShadingImage = renderer.render();
1082 	}
1083 
1084 	// Render with minSampleShading = 1.0f
1085 	{
1086 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
1087 		multisampleParams.minSampleShading = 1.0f;
1088 
1089 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
1090 		maxShadingImage = renderer.render();
1091 	}
1092 
1093 	return verifyImage(testShadingImage->getAccess(), minShadingImage->getAccess(), maxShadingImage->getAccess());
1094 }
1095 
verifyImage(const tcu::ConstPixelBufferAccess & testShadingImage,const tcu::ConstPixelBufferAccess & minShadingImage,const tcu::ConstPixelBufferAccess & maxShadingImage)1096 tcu::TestStatus MinSampleShadingInstance::verifyImage (const tcu::ConstPixelBufferAccess& testShadingImage, const tcu::ConstPixelBufferAccess& minShadingImage, const tcu::ConstPixelBufferAccess& maxShadingImage)
1097 {
1098 	const deUint32	testColorCount	= getUniqueColorsCount(testShadingImage);
1099 	const deUint32	minColorCount	= getUniqueColorsCount(minShadingImage);
1100 	const deUint32	maxColorCount	= getUniqueColorsCount(maxShadingImage);
1101 
1102 	tcu::TestLog& log = m_context.getTestContext().getLog();
1103 
1104 	log << tcu::TestLog::Message
1105 		<< "\nColors found: " << testColorCount << "\n"
1106 		<< "Min. colors expected: " << minColorCount << "\n"
1107 		<< "Max. colors expected: " << maxColorCount << "\n"
1108 		<< tcu::TestLog::EndMessage;
1109 
1110 	if (minColorCount > testColorCount || testColorCount > maxColorCount)
1111 		return tcu::TestStatus::fail("Unique colors out of expected bounds");
1112 	else
1113 		return tcu::TestStatus::pass("Unique colors within expected bounds");
1114 }
1115 
SampleMaskInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState)1116 SampleMaskInstance::SampleMaskInstance (Context&										context,
1117 										VkPrimitiveTopology								topology,
1118 										const std::vector<Vertex4RGBA>&					vertices,
1119 										const VkPipelineMultisampleStateCreateInfo&		multisampleStateParams,
1120 										const VkPipelineColorBlendAttachmentState&		blendState)
1121 	: vkt::TestInstance			(context)
1122 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
1123 	, m_renderSize				(32, 32)
1124 	, m_primitiveTopology		(topology)
1125 	, m_vertices				(vertices)
1126 	, m_multisampleStateParams	(multisampleStateParams)
1127 	, m_colorBlendState			(blendState)
1128 {
1129 }
1130 
iterate(void)1131 tcu::TestStatus SampleMaskInstance::iterate (void)
1132 {
1133 	de::MovePtr<tcu::TextureLevel>				testSampleMaskImage;
1134 	de::MovePtr<tcu::TextureLevel>				minSampleMaskImage;
1135 	de::MovePtr<tcu::TextureLevel>				maxSampleMaskImage;
1136 
1137 	// Render with test flags
1138 	{
1139 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
1140 		testSampleMaskImage = renderer.render();
1141 	}
1142 
1143 	// Render with all flags off
1144 	{
1145 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
1146 		const std::vector<VkSampleMask>			sampleMask			(multisampleParams.rasterizationSamples / 32, (VkSampleMask)0);
1147 
1148 		multisampleParams.pSampleMask = sampleMask.data();
1149 
1150 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
1151 		minSampleMaskImage = renderer.render();
1152 	}
1153 
1154 	// Render with all flags on
1155 	{
1156 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
1157 		const std::vector<VkSampleMask>			sampleMask			(multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0));
1158 
1159 		multisampleParams.pSampleMask = sampleMask.data();
1160 
1161 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
1162 		maxSampleMaskImage = renderer.render();
1163 	}
1164 
1165 	return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess());
1166 }
1167 
verifyImage(const tcu::ConstPixelBufferAccess & testSampleMaskImage,const tcu::ConstPixelBufferAccess & minSampleMaskImage,const tcu::ConstPixelBufferAccess & maxSampleMaskImage)1168 tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage,
1169 												 const tcu::ConstPixelBufferAccess& minSampleMaskImage,
1170 												 const tcu::ConstPixelBufferAccess& maxSampleMaskImage)
1171 {
1172 	const deUint32	testColorCount	= getUniqueColorsCount(testSampleMaskImage);
1173 	const deUint32	minColorCount	= getUniqueColorsCount(minSampleMaskImage);
1174 	const deUint32	maxColorCount	= getUniqueColorsCount(maxSampleMaskImage);
1175 
1176 	tcu::TestLog& log = m_context.getTestContext().getLog();
1177 
1178 	log << tcu::TestLog::Message
1179 		<< "\nColors found: " << testColorCount << "\n"
1180 		<< "Min. colors expected: " << minColorCount << "\n"
1181 		<< "Max. colors expected: " << maxColorCount << "\n"
1182 		<< tcu::TestLog::EndMessage;
1183 
1184 	if (minColorCount > testColorCount || testColorCount > maxColorCount)
1185 		return tcu::TestStatus::fail("Unique colors out of expected bounds");
1186 	else
1187 		return tcu::TestStatus::pass("Unique colors within expected bounds");
1188 }
1189 
testRasterSamplesConsistency(Context & context,GeometryType geometryType)1190 tcu::TestStatus testRasterSamplesConsistency (Context& context, GeometryType geometryType)
1191 {
1192 	// Use triangle only.
1193 	DE_UNREF(geometryType);
1194 
1195 	const VkSampleCountFlagBits samples[] =
1196 	{
1197 		VK_SAMPLE_COUNT_1_BIT,
1198 		VK_SAMPLE_COUNT_2_BIT,
1199 		VK_SAMPLE_COUNT_4_BIT,
1200 		VK_SAMPLE_COUNT_8_BIT,
1201 		VK_SAMPLE_COUNT_16_BIT,
1202 		VK_SAMPLE_COUNT_32_BIT,
1203 		VK_SAMPLE_COUNT_64_BIT
1204 	};
1205 
1206 	const Vertex4RGBA vertexData[3] =
1207 	{
1208 		{
1209 			tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
1210 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1211 		},
1212 		{
1213 			tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
1214 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1215 		},
1216 		{
1217 			tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
1218 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1219 		}
1220 	};
1221 
1222 	const std::vector<Vertex4RGBA>	vertices			(vertexData, vertexData + 3);
1223 	deUint32						prevUniqueColors	= 2;
1224 	int								renderCount			= 0;
1225 
1226 	// Do not render with 1 sample (start with samplesNdx = 1).
1227 	for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
1228 	{
1229 		if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx]))
1230 			continue;
1231 
1232 		const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1233 		{
1234 			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1235 			DE_NULL,													// const void*								pNext;
1236 			0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1237 			samples[samplesNdx],										// VkSampleCountFlagBits					rasterizationSamples;
1238 			false,														// VkBool32									sampleShadingEnable;
1239 			0.0f,														// float									minSampleShading;
1240 			DE_NULL,													// const VkSampleMask*						pSampleMask;
1241 			false,														// VkBool32									alphaToCoverageEnable;
1242 			false														// VkBool32									alphaToOneEnable;
1243 		};
1244 
1245 		MultisampleRenderer				renderer		(context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState());
1246 		de::MovePtr<tcu::TextureLevel>	result			= renderer.render();
1247 		const deUint32					uniqueColors	= getUniqueColorsCount(result->getAccess());
1248 
1249 		renderCount++;
1250 
1251 		if (prevUniqueColors > uniqueColors)
1252 		{
1253 			std::ostringstream message;
1254 
1255 			message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx];
1256 			return tcu::TestStatus::fail(message.str());
1257 		}
1258 
1259 		prevUniqueColors = uniqueColors;
1260 	}
1261 
1262 	if (renderCount == 0)
1263 		throw tcu::NotSupportedError("Multisampling is unsupported");
1264 
1265 	return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases");
1266 }
1267 
1268 
1269 // AlphaToOneInstance
1270 
AlphaToOneInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState)1271 AlphaToOneInstance::AlphaToOneInstance (Context&									context,
1272 										VkPrimitiveTopology							topology,
1273 										const std::vector<Vertex4RGBA>&				vertices,
1274 										const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1275 										const VkPipelineColorBlendAttachmentState&	blendState)
1276 	: vkt::TestInstance			(context)
1277 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
1278 	, m_renderSize				(32, 32)
1279 	, m_primitiveTopology		(topology)
1280 	, m_vertices				(vertices)
1281 	, m_multisampleStateParams	(multisampleStateParams)
1282 	, m_colorBlendState			(blendState)
1283 {
1284 	VkPhysicalDeviceFeatures deviceFeatures;
1285 
1286 	context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &deviceFeatures);
1287 
1288 	if (!deviceFeatures.alphaToOne)
1289 		throw tcu::NotSupportedError("Alpha-to-one is not supported");
1290 }
1291 
iterate(void)1292 tcu::TestStatus AlphaToOneInstance::iterate	(void)
1293 {
1294 	DE_ASSERT(m_multisampleStateParams.alphaToOneEnable);
1295 	DE_ASSERT(m_colorBlendState.blendEnable);
1296 
1297 	de::MovePtr<tcu::TextureLevel>	alphaOneImage;
1298 	de::MovePtr<tcu::TextureLevel>	noAlphaOneImage;
1299 
1300 	// Render with blend enabled and alpha to one on
1301 	{
1302 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
1303 		alphaOneImage = renderer.render();
1304 	}
1305 
1306 	// Render with blend enabled and alpha to one off
1307 	{
1308 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
1309 		multisampleParams.alphaToOneEnable = false;
1310 
1311 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
1312 		noAlphaOneImage = renderer.render();
1313 	}
1314 
1315 	return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess());
1316 }
1317 
verifyImage(const tcu::ConstPixelBufferAccess & alphaOneImage,const tcu::ConstPixelBufferAccess & noAlphaOneImage)1318 tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess&	alphaOneImage,
1319 												 const tcu::ConstPixelBufferAccess&	noAlphaOneImage)
1320 {
1321 	for (int y = 0; y < m_renderSize.y(); y++)
1322 	{
1323 		for (int x = 0; x < m_renderSize.x(); x++)
1324 		{
1325 			if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y))))
1326 			{
1327 				std::ostringstream message;
1328 				message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y);
1329 				return tcu::TestStatus::fail(message.str());
1330 			}
1331 		}
1332 	}
1333 
1334 	return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one");
1335 }
1336 
1337 
1338 // AlphaToCoverageInstance
1339 
AlphaToCoverageInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType)1340 AlphaToCoverageInstance::AlphaToCoverageInstance (Context&										context,
1341 												  VkPrimitiveTopology							topology,
1342 												  const std::vector<Vertex4RGBA>&				vertices,
1343 												  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1344 												  const VkPipelineColorBlendAttachmentState&	blendState,
1345 												  GeometryType									geometryType)
1346 	: vkt::TestInstance			(context)
1347 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
1348 	, m_renderSize				(32, 32)
1349 	, m_primitiveTopology		(topology)
1350 	, m_vertices				(vertices)
1351 	, m_multisampleStateParams	(multisampleStateParams)
1352 	, m_colorBlendState			(blendState)
1353 	, m_geometryType			(geometryType)
1354 {
1355 }
1356 
iterate(void)1357 tcu::TestStatus AlphaToCoverageInstance::iterate (void)
1358 {
1359 	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
1360 
1361 	de::MovePtr<tcu::TextureLevel>	result;
1362 	MultisampleRenderer				renderer	(m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
1363 
1364 	result = renderer.render();
1365 
1366 	return verifyImage(result->getAccess());
1367 }
1368 
verifyImage(const tcu::ConstPixelBufferAccess & result)1369 tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
1370 {
1371 	float maxColorValue;
1372 
1373 	switch (m_geometryType)
1374 	{
1375 		case GEOMETRY_TYPE_OPAQUE_QUAD:
1376 			maxColorValue = 1.01f;
1377 			break;
1378 
1379 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
1380 			maxColorValue = 0.52f;
1381 			break;
1382 
1383 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
1384 			maxColorValue = 0.01f;
1385 			break;
1386 
1387 		default:
1388 			maxColorValue = 0.0f;
1389 			DE_ASSERT(false);
1390 	}
1391 
1392 	for (int y = 0; y < m_renderSize.y(); y++)
1393 	{
1394 		for (int x = 0; x < m_renderSize.x(); x++)
1395 		{
1396 			if (result.getPixel(x, y).x() > maxColorValue)
1397 			{
1398 				std::ostringstream message;
1399 				message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")";
1400 				return tcu::TestStatus::fail(message.str());
1401 			}
1402 		}
1403 	}
1404 
1405 	return tcu::TestStatus::pass("Image matches reference value");
1406 }
1407 
1408 
1409 // MultisampleRenderer
1410 
MultisampleRenderer(Context & context,const VkFormat colorFormat,const tcu::IVec2 & renderSize,const VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState)1411 MultisampleRenderer::MultisampleRenderer (Context&										context,
1412 										  const VkFormat								colorFormat,
1413 										  const tcu::IVec2&								renderSize,
1414 										  const VkPrimitiveTopology						topology,
1415 										  const std::vector<Vertex4RGBA>&				vertices,
1416 										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1417 										  const VkPipelineColorBlendAttachmentState&	blendState)
1418 	: m_context					(context)
1419 	, m_colorFormat				(colorFormat)
1420 	, m_depthStencilFormat		(VK_FORMAT_UNDEFINED)
1421 	, m_renderSize				(renderSize)
1422 	, m_useDepth				(false)
1423 	, m_useStencil				(false)
1424 	, m_multisampleStateParams	(multisampleStateParams)
1425 	, m_colorBlendState			(blendState)
1426 {
1427 	initialize(context, 1u, &topology, &vertices);
1428 }
1429 
MultisampleRenderer(Context & context,const VkFormat colorFormat,const VkFormat depthStencilFormat,const tcu::IVec2 & renderSize,const bool useDepth,const bool useStencil,const deUint32 numTopologies,const VkPrimitiveTopology * pTopology,const std::vector<Vertex4RGBA> * pVertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState)1430 MultisampleRenderer::MultisampleRenderer (Context&										context,
1431 										  const VkFormat								colorFormat,
1432 										  const VkFormat								depthStencilFormat,
1433 										  const tcu::IVec2&								renderSize,
1434 										  const bool									useDepth,
1435 										  const bool									useStencil,
1436 										  const deUint32								numTopologies,
1437 										  const VkPrimitiveTopology*					pTopology,
1438 										  const std::vector<Vertex4RGBA>*				pVertices,
1439 										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1440 										  const VkPipelineColorBlendAttachmentState&	blendState)
1441 	: m_context					(context)
1442 	, m_colorFormat				(colorFormat)
1443 	, m_depthStencilFormat		(depthStencilFormat)
1444 	, m_renderSize				(renderSize)
1445 	, m_useDepth				(useDepth)
1446 	, m_useStencil				(useStencil)
1447 	, m_multisampleStateParams	(multisampleStateParams)
1448 	, m_colorBlendState			(blendState)
1449 {
1450 	initialize(context, numTopologies, pTopology, pVertices);
1451 }
1452 
initialize(Context & context,const deUint32 numTopologies,const VkPrimitiveTopology * pTopology,const std::vector<Vertex4RGBA> * pVertices)1453 void MultisampleRenderer::initialize (Context&									context,
1454 									  const deUint32							numTopologies,
1455 									  const VkPrimitiveTopology*				pTopology,
1456 									  const std::vector<Vertex4RGBA>*			pVertices)
1457 {
1458 	if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples))
1459 		throw tcu::NotSupportedError("Unsupported number of rasterization samples");
1460 
1461 	const DeviceInterface&		vk						= context.getDeviceInterface();
1462 	const VkDevice				vkDevice				= context.getDevice();
1463 	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
1464 	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
1465 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
1466 
1467 	// Create color image
1468 	{
1469 		const VkImageCreateInfo colorImageParams =
1470 		{
1471 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
1472 			DE_NULL,																	// const void*				pNext;
1473 			0u,																			// VkImageCreateFlags		flags;
1474 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
1475 			m_colorFormat,																// VkFormat					format;
1476 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },				// VkExtent3D				extent;
1477 			1u,																			// deUint32					mipLevels;
1478 			1u,																			// deUint32					arrayLayers;
1479 			m_multisampleStateParams.rasterizationSamples,								// VkSampleCountFlagBits	samples;
1480 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
1481 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
1482 			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
1483 			1u,																			// deUint32					queueFamilyIndexCount;
1484 			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
1485 			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
1486 		};
1487 
1488 		m_colorImage			= createImage(vk, vkDevice, &colorImageParams);
1489 
1490 		// Allocate and bind color image memory
1491 		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
1492 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
1493 	}
1494 
1495 	// Create resolve image
1496 	{
1497 		const VkImageCreateInfo resolveImageParams =
1498 		{
1499 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
1500 			DE_NULL,																		// const void*				pNext;
1501 			0u,																				// VkImageCreateFlags		flags;
1502 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
1503 			m_colorFormat,																	// VkFormat					format;
1504 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
1505 			1u,																				// deUint32					mipLevels;
1506 			1u,																				// deUint32					arrayLayers;
1507 			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
1508 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
1509 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |			// VkImageUsageFlags		usage;
1510 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1511 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
1512 			1u,																				// deUint32					queueFamilyIndexCount;
1513 			&queueFamilyIndex,																// const deUint32*			pQueueFamilyIndices;
1514 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
1515 		};
1516 
1517 		m_resolveImage = createImage(vk, vkDevice, &resolveImageParams);
1518 
1519 		// Allocate and bind resolve image memory
1520 		m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any);
1521 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset()));
1522 	}
1523 
1524 	// Create a depth/stencil image
1525 	if (m_useDepth || m_useStencil)
1526 	{
1527 		const VkImageCreateInfo depthStencilImageParams =
1528 		{
1529 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
1530 			DE_NULL,																		// const void*				pNext;
1531 			0u,																				// VkImageCreateFlags		flags;
1532 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
1533 			m_depthStencilFormat,															// VkFormat					format;
1534 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
1535 			1u,																				// deUint32					mipLevels;
1536 			1u,																				// deUint32					arrayLayers;
1537 			m_multisampleStateParams.rasterizationSamples,									// VkSampleCountFlagBits	samples;
1538 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
1539 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,									// VkImageUsageFlags		usage;
1540 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
1541 			1u,																				// deUint32					queueFamilyIndexCount;
1542 			&queueFamilyIndex,																// const deUint32*			pQueueFamilyIndices;
1543 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
1544 		};
1545 
1546 		m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams);
1547 
1548 		// Allocate and bind depth/stencil image memory
1549 		m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any);
1550 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset()));
1551 	}
1552 
1553 	// Create color attachment view
1554 	{
1555 		const VkImageViewCreateInfo colorAttachmentViewParams =
1556 		{
1557 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
1558 			DE_NULL,										// const void*				pNext;
1559 			0u,												// VkImageViewCreateFlags	flags;
1560 			*m_colorImage,									// VkImage					image;
1561 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
1562 			m_colorFormat,									// VkFormat					format;
1563 			componentMappingRGBA,							// VkComponentMapping		components;
1564 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
1565 		};
1566 
1567 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
1568 	}
1569 
1570 	// Create resolve attachment view
1571 	{
1572 		const VkImageViewCreateInfo resolveAttachmentViewParams =
1573 		{
1574 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
1575 			DE_NULL,										// const void*				pNext;
1576 			0u,												// VkImageViewCreateFlags	flags;
1577 			*m_resolveImage,								// VkImage					image;
1578 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
1579 			m_colorFormat,									// VkFormat					format;
1580 			componentMappingRGBA,							// VkComponentMapping		components;
1581 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
1582 		};
1583 
1584 		m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
1585 	}
1586 
1587 	VkImageAspectFlags	depthStencilAttachmentAspect	= (VkImageAspectFlagBits)0;
1588 	const deUint32		numUsedAttachments				= (m_useDepth || m_useStencil ? 3u : 2u);
1589 
1590 	// Create depth/stencil attachment view
1591 	if (m_useDepth || m_useStencil)
1592 	{
1593 		depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat);
1594 
1595 		const VkImageViewCreateInfo depthStencilAttachmentViewParams =
1596 		{
1597 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
1598 			DE_NULL,											// const void*				pNext;
1599 			0u,													// VkImageViewCreateFlags	flags;
1600 			*m_depthStencilImage,								// VkImage					image;
1601 			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
1602 			m_depthStencilFormat,								// VkFormat					format;
1603 			componentMappingRGBA,								// VkComponentMapping		components;
1604 			{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
1605 		};
1606 
1607 		m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
1608 	}
1609 
1610 	// Create render pass
1611 	{
1612 		const VkAttachmentDescription attachmentDescriptions[3] =
1613 		{
1614 			{
1615 				0u,													// VkAttachmentDescriptionFlags		flags;
1616 				m_colorFormat,										// VkFormat							format;
1617 				m_multisampleStateParams.rasterizationSamples,		// VkSampleCountFlagBits			samples;
1618 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
1619 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
1620 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
1621 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
1622 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
1623 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
1624 			},
1625 			{
1626 				0u,													// VkAttachmentDescriptionFlags		flags;
1627 				m_colorFormat,										// VkFormat							format;
1628 				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
1629 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
1630 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
1631 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
1632 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
1633 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
1634 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
1635 			},
1636 			{
1637 				0u,																					// VkAttachmentDescriptionFlags		flags;
1638 				m_depthStencilFormat,																// VkFormat							format;
1639 				m_multisampleStateParams.rasterizationSamples,										// VkSampleCountFlagBits			samples;
1640 				(m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentLoadOp				loadOp;
1641 				(m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),		// VkAttachmentStoreOp				storeOp;
1642 				(m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentStoreOp				stencilLoadOp;
1643 				(m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),	// VkAttachmentStoreOp				stencilStoreOp;
1644 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,									// VkImageLayout					initialLayout;
1645 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL									// VkImageLayout					finalLayout;
1646 			},
1647 		};
1648 
1649 		const VkAttachmentReference colorAttachmentReference =
1650 		{
1651 			0u,													// deUint32			attachment;
1652 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
1653 		};
1654 
1655 		const VkAttachmentReference resolveAttachmentReference =
1656 		{
1657 			1u,													// deUint32			attachment;
1658 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
1659 		};
1660 
1661 		const VkAttachmentReference depthStencilAttachmentReference =
1662 		{
1663 			2u,													// deUint32			attachment;
1664 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
1665 		};
1666 
1667 		const VkSubpassDescription subpassDescription =
1668 		{
1669 			0u,																			// VkSubpassDescriptionFlags	flags;
1670 			VK_PIPELINE_BIND_POINT_GRAPHICS,											// VkPipelineBindPoint			pipelineBindPoint;
1671 			0u,																			// deUint32						inputAttachmentCount;
1672 			DE_NULL,																	// const VkAttachmentReference*	pInputAttachments;
1673 			1u,																			// deUint32						colorAttachmentCount;
1674 			&colorAttachmentReference,													// const VkAttachmentReference*	pColorAttachments;
1675 			&resolveAttachmentReference,												// const VkAttachmentReference*	pResolveAttachments;
1676 			(m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL),	// const VkAttachmentReference*	pDepthStencilAttachment;
1677 			0u,																			// deUint32						preserveAttachmentCount;
1678 			DE_NULL																		// const VkAttachmentReference*	pPreserveAttachments;
1679 		};
1680 
1681 		const VkRenderPassCreateInfo renderPassParams =
1682 		{
1683 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
1684 			DE_NULL,											// const void*						pNext;
1685 			0u,													// VkRenderPassCreateFlags			flags;
1686 			numUsedAttachments,									// deUint32							attachmentCount;
1687 			attachmentDescriptions,								// const VkAttachmentDescription*	pAttachments;
1688 			1u,													// deUint32							subpassCount;
1689 			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
1690 			0u,													// deUint32							dependencyCount;
1691 			DE_NULL												// const VkSubpassDependency*		pDependencies;
1692 		};
1693 
1694 		m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1695 	}
1696 
1697 	// Create framebuffer
1698 	{
1699 		const VkImageView attachments[3] =
1700 		{
1701 			*m_colorAttachmentView,
1702 			*m_resolveAttachmentView,
1703 			*m_depthStencilAttachmentView
1704 		};
1705 
1706 		const VkFramebufferCreateInfo framebufferParams =
1707 		{
1708 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
1709 			DE_NULL,											// const void*					pNext;
1710 			0u,													// VkFramebufferCreateFlags		flags;
1711 			*m_renderPass,										// VkRenderPass					renderPass;
1712 			numUsedAttachments,									// deUint32						attachmentCount;
1713 			attachments,										// const VkImageView*			pAttachments;
1714 			(deUint32)m_renderSize.x(),							// deUint32						width;
1715 			(deUint32)m_renderSize.y(),							// deUint32						height;
1716 			1u													// deUint32						layers;
1717 		};
1718 
1719 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1720 	}
1721 
1722 	// Create pipeline layout
1723 	{
1724 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1725 		{
1726 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
1727 			DE_NULL,											// const void*						pNext;
1728 			0u,													// VkPipelineLayoutCreateFlags		flags;
1729 			0u,													// deUint32							setLayoutCount;
1730 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
1731 			0u,													// deUint32							pushConstantRangeCount;
1732 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
1733 		};
1734 
1735 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1736 	}
1737 
1738 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
1739 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
1740 
1741 	// Create pipeline
1742 	{
1743 		const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
1744 		{
1745 			{
1746 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
1747 				DE_NULL,													// const void*							pNext;
1748 				0u,															// VkPipelineShaderStageCreateFlags		flags;
1749 				VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits				stage;
1750 				*m_vertexShaderModule,										// VkShaderModule						module;
1751 				"main",														// const char*							pName;
1752 				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
1753 			},
1754 			{
1755 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
1756 				DE_NULL,													// const void*							pNext;
1757 				0u,															// VkPipelineShaderStageCreateFlags		flags;
1758 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits				stage;
1759 				*m_fragmentShaderModule,									// VkShaderModule						module;
1760 				"main",														// const char*							pName;
1761 				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
1762 			}
1763 		};
1764 
1765 		const VkVertexInputBindingDescription vertexInputBindingDescription =
1766 		{
1767 			0u,									// deUint32				binding;
1768 			sizeof(Vertex4RGBA),				// deUint32				stride;
1769 			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputRate	inputRate;
1770 		};
1771 
1772 		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1773 		{
1774 			{
1775 				0u,									// deUint32	location;
1776 				0u,									// deUint32	binding;
1777 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
1778 				0u									// deUint32	offset;
1779 			},
1780 			{
1781 				1u,									// deUint32	location;
1782 				0u,									// deUint32	binding;
1783 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
1784 				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
1785 			}
1786 		};
1787 
1788 		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1789 		{
1790 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
1791 			DE_NULL,														// const void*								pNext;
1792 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
1793 			1u,																// deUint32									vertexBindingDescriptionCount;
1794 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
1795 			2u,																// deUint32									vertexAttributeDescriptionCount;
1796 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
1797 		};
1798 
1799 		// Topology is set before the pipeline creation.
1800 		VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1801 		{
1802 			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
1803 			DE_NULL,														// const void*								pNext;
1804 			0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
1805 			VK_PRIMITIVE_TOPOLOGY_LAST,										// VkPrimitiveTopology						topology;
1806 			false															// VkBool32									primitiveRestartEnable;
1807 		};
1808 
1809 		const VkViewport viewport =
1810 		{
1811 			0.0f,						// float	x;
1812 			0.0f,						// float	y;
1813 			(float)m_renderSize.x(),	// float	width;
1814 			(float)m_renderSize.y(),	// float	height;
1815 			0.0f,						// float	minDepth;
1816 			1.0f						// float	maxDepth;
1817 		};
1818 
1819 		const VkRect2D scissor =
1820 		{
1821 			{ 0, 0 },													// VkOffset2D  offset;
1822 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }	// VkExtent2D  extent;
1823 		};
1824 
1825 		const VkPipelineViewportStateCreateInfo viewportStateParams =
1826 		{
1827 			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType						sType;
1828 			DE_NULL,														// const void*							pNext;
1829 			0u,																// VkPipelineViewportStateCreateFlags	flags;
1830 			1u,																// deUint32								viewportCount;
1831 			&viewport,														// const VkViewport*					pViewports;
1832 			1u,																// deUint32								scissorCount;
1833 			&scissor														// const VkRect2D*						pScissors;
1834 		};
1835 
1836 		const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1837 		{
1838 			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
1839 			DE_NULL,														// const void*								pNext;
1840 			0u,																// VkPipelineRasterizationStateCreateFlags	flags;
1841 			false,															// VkBool32									depthClampEnable;
1842 			false,															// VkBool32									rasterizerDiscardEnable;
1843 			VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
1844 			VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
1845 			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
1846 			VK_FALSE,														// VkBool32									depthBiasEnable;
1847 			0.0f,															// float									depthBiasConstantFactor;
1848 			0.0f,															// float									depthBiasClamp;
1849 			0.0f,															// float									depthBiasSlopeFactor;
1850 			1.0f															// float									lineWidth;
1851 		};
1852 
1853 		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1854 		{
1855 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
1856 			DE_NULL,													// const void*									pNext;
1857 			0u,															// VkPipelineColorBlendStateCreateFlags			flags;
1858 			false,														// VkBool32										logicOpEnable;
1859 			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
1860 			1u,															// deUint32										attachmentCount;
1861 			&m_colorBlendState,											// const VkPipelineColorBlendAttachmentState*	pAttachments;
1862 			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
1863 		};
1864 
1865 		const VkStencilOpState stencilOpState =
1866 		{
1867 			VK_STENCIL_OP_KEEP,						// VkStencilOp	failOp;
1868 			VK_STENCIL_OP_REPLACE,					// VkStencilOp	passOp;
1869 			VK_STENCIL_OP_KEEP,						// VkStencilOp	depthFailOp;
1870 			VK_COMPARE_OP_GREATER,					// VkCompareOp	compareOp;
1871 			1u,										// deUint32		compareMask;
1872 			1u,										// deUint32		writeMask;
1873 			1u,										// deUint32		reference;
1874 		};
1875 
1876 		const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
1877 		{
1878 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
1879 			DE_NULL,													// const void*								pNext;
1880 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
1881 			m_useDepth,													// VkBool32									depthTestEnable;
1882 			m_useDepth,													// VkBool32									depthWriteEnable;
1883 			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
1884 			false,														// VkBool32									depthBoundsTestEnable;
1885 			m_useStencil,												// VkBool32									stencilTestEnable;
1886 			stencilOpState,												// VkStencilOpState	front;
1887 			stencilOpState,												// VkStencilOpState	back;
1888 			0.0f,														// float			minDepthBounds;
1889 			1.0f,														// float			maxDepthBounds;
1890 		};
1891 
1892 		const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1893 		{
1894 			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
1895 			DE_NULL,											// const void*										pNext;
1896 			0u,													// VkPipelineCreateFlags							flags;
1897 			2u,													// deUint32											stageCount;
1898 			shaderStageParams,									// const VkPipelineShaderStageCreateInfo*			pStages;
1899 			&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
1900 			&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
1901 			DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
1902 			&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
1903 			&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
1904 			&m_multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
1905 			&depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
1906 			&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
1907 			(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
1908 			*m_pipelineLayout,									// VkPipelineLayout									layout;
1909 			*m_renderPass,										// VkRenderPass										renderPass;
1910 			0u,													// deUint32											subpass;
1911 			0u,													// VkPipeline										basePipelineHandle;
1912 			0u													// deInt32											basePipelineIndex;
1913 		};
1914 
1915 		for (deUint32 i = 0u; i < numTopologies; ++i)
1916 		{
1917 			inputAssemblyStateParams.topology = pTopology[i];
1918 			m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams))));
1919 		}
1920 	}
1921 
1922 	// Create vertex buffer
1923 	{
1924 		const VkBufferCreateInfo vertexBufferParams =
1925 		{
1926 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1927 			DE_NULL,									// const void*			pNext;
1928 			0u,											// VkBufferCreateFlags	flags;
1929 			1024u,										// VkDeviceSize			size;
1930 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
1931 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1932 			1u,											// deUint32				queueFamilyIndexCount;
1933 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
1934 		};
1935 
1936 		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
1937 		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
1938 
1939 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
1940 
1941 		// Load vertices into vertex buffer
1942 		{
1943 			Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr());
1944 			for (deUint32 i = 0u; i < numTopologies; ++i)
1945 			{
1946 				deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA));
1947 				pDst += pVertices[i].size();
1948 			}
1949 		}
1950 		flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
1951 	}
1952 
1953 	// Create command pool
1954 	{
1955 		const VkCommandPoolCreateInfo cmdPoolParams =
1956 		{
1957 			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType				sType;
1958 			DE_NULL,										// const void*					pNext;
1959 			VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,			// VkCommandPoolCreateFlags		flags;
1960 			queueFamilyIndex,								// deUint32						queueFamilyIndex;
1961 		};
1962 
1963 		m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1964 	}
1965 
1966 	// Create command buffer
1967 	{
1968 		const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
1969 		{
1970 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
1971 			DE_NULL,										// const void*				pNext;
1972 			*m_cmdPool,										// VkCommandPool			commandPool;
1973 			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel	level;
1974 			1u												// deUint32				bufferCount;
1975 		};
1976 
1977 		const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1978 		{
1979 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
1980 			DE_NULL,										// const void*						pNext;
1981 			0u,												// VkCommandBufferUsageFlags		flags;
1982 			(const VkCommandBufferInheritanceInfo*)DE_NULL,
1983 		};
1984 
1985 		VkClearValue colorClearValue;
1986 		colorClearValue.color.float32[0] = 0.0f;
1987 		colorClearValue.color.float32[1] = 0.0f;
1988 		colorClearValue.color.float32[2] = 0.0f;
1989 		colorClearValue.color.float32[3] = 0.0f;
1990 
1991 		VkClearValue depthStencilClearValue;
1992 		depthStencilClearValue.depthStencil.depth = 1.0f;
1993 		depthStencilClearValue.depthStencil.stencil = 0u;
1994 
1995 		const VkClearValue clearValues[3] =
1996 		{
1997 			colorClearValue,
1998 			colorClearValue,
1999 			depthStencilClearValue
2000 		};
2001 
2002 		const VkRenderPassBeginInfo renderPassBeginInfo =
2003 		{
2004 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
2005 			DE_NULL,												// const void*			pNext;
2006 			*m_renderPass,											// VkRenderPass			renderPass;
2007 			*m_framebuffer,											// VkFramebuffer		framebuffer;
2008 			{
2009 				{ 0, 0 },
2010 				{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }
2011 			},														// VkRect2D				renderArea;
2012 			numUsedAttachments,										// deUint32				clearValueCount;
2013 			clearValues												// const VkClearValue*	pClearValues;
2014 		};
2015 
2016 		const VkImageMemoryBarrier imageLayoutBarriers[] =
2017 		{
2018 			// color attachment image
2019 			{
2020 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
2021 				DE_NULL,										// const void*				pNext;
2022 				0u,												// VkAccessFlags			srcAccessMask;
2023 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
2024 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
2025 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
2026 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
2027 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
2028 				*m_colorImage,									// VkImage					image;
2029 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
2030 			},
2031 			// resolve attachment image
2032 			{
2033 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
2034 				DE_NULL,										// const void*				pNext;
2035 				0u,												// VkAccessFlags			srcAccessMask;
2036 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
2037 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
2038 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
2039 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
2040 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
2041 				*m_resolveImage,								// VkImage					image;
2042 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
2043 			},
2044 			// depth/stencil attachment image
2045 			{
2046 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
2047 				DE_NULL,											// const void*				pNext;
2048 				0u,													// VkAccessFlags			srcAccessMask;
2049 				VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
2050 				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
2051 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
2052 				VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
2053 				VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
2054 				*m_depthStencilImage,								// VkImage					image;
2055 				{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
2056 			},
2057 		};
2058 
2059 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
2060 
2061 		VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
2062 
2063 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
2064 			0u, DE_NULL, 0u, DE_NULL, numUsedAttachments, imageLayoutBarriers);
2065 
2066 		vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2067 
2068 		VkDeviceSize vertexBufferOffset = 0u;
2069 
2070 		for (deUint32 i = 0u; i < numTopologies; ++i)
2071 		{
2072 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[i]);
2073 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
2074 			vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0);
2075 
2076 			vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA));
2077 		}
2078 
2079 		vk.cmdEndRenderPass(*m_cmdBuffer);
2080 
2081 		VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
2082 	}
2083 
2084 	// Create fence
2085 	{
2086 		const VkFenceCreateInfo fenceParams =
2087 		{
2088 			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
2089 			DE_NULL,								// const void*			pNext;
2090 			0u										// VkFenceCreateFlags	flags;
2091 		};
2092 
2093 		m_fence = createFence(vk, vkDevice, &fenceParams);
2094 	}
2095 }
2096 
~MultisampleRenderer(void)2097 MultisampleRenderer::~MultisampleRenderer (void)
2098 {
2099 }
2100 
render(void)2101 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void)
2102 {
2103 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
2104 	const VkDevice				vkDevice			= m_context.getDevice();
2105 	const VkQueue				queue				= m_context.getUniversalQueue();
2106 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
2107 	SimpleAllocator				allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
2108 	const VkSubmitInfo			submitInfo	=
2109 	{
2110 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
2111 		DE_NULL,						// const void*				pNext;
2112 		0u,								// deUint32					waitSemaphoreCount;
2113 		DE_NULL,						// const VkSemaphore*		pWaitSemaphores;
2114 		(const VkPipelineStageFlags*)DE_NULL,
2115 		1u,								// deUint32					commandBufferCount;
2116 		&m_cmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
2117 		0u,								// deUint32					signalSemaphoreCount;
2118 		DE_NULL							// const VkSemaphore*		pSignalSemaphores;
2119 	};
2120 
2121 	VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
2122 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
2123 	VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
2124 
2125 	return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
2126 }
2127 
2128 } // anonymous
2129 
createMultisampleTests(tcu::TestContext & testCtx)2130 tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx)
2131 {
2132 	const VkSampleCountFlagBits samples[] =
2133 	{
2134 		VK_SAMPLE_COUNT_2_BIT,
2135 		VK_SAMPLE_COUNT_4_BIT,
2136 		VK_SAMPLE_COUNT_8_BIT,
2137 		VK_SAMPLE_COUNT_16_BIT,
2138 		VK_SAMPLE_COUNT_32_BIT,
2139 		VK_SAMPLE_COUNT_64_BIT
2140 	};
2141 
2142 	de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, "multisample", ""));
2143 
2144 	// Rasterization samples tests
2145 	{
2146 		de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", ""));
2147 
2148 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2149 		{
2150 			std::ostringstream caseName;
2151 			caseName << "samples_" << samples[samplesNdx];
2152 
2153 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
2154 
2155 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE));
2156 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE));
2157 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT));
2158 
2159 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_DEPTH_BIT));
2160 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_STENCIL_BIT));
2161 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil", "",	samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT));
2162 
2163 			rasterizationSamplesTests->addChild(samplesTests.release());
2164 		}
2165 
2166 		multisampleTests->addChild(rasterizationSamplesTests.release());
2167 	}
2168 
2169 	// Raster samples consistency check
2170 	{
2171 		de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests(new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", ""));
2172 
2173 		addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
2174 									"unique_colors_check",
2175 									"",
2176 									initMultisamplePrograms,
2177 									testRasterSamplesConsistency,
2178 									GEOMETRY_TYPE_OPAQUE_TRIANGLE);
2179 
2180 		multisampleTests->addChild(rasterSamplesConsistencyTests.release());
2181 	}
2182 
2183 	// minSampleShading tests
2184 	{
2185 		struct TestConfig
2186 		{
2187 			const char*	name;
2188 			float		minSampleShading;
2189 		};
2190 
2191 		const TestConfig testConfigs[] =
2192 		{
2193 			{ "min_0_0",	0.0f },
2194 			{ "min_0_25",	0.25f },
2195 			{ "min_0_5",	0.5f },
2196 			{ "min_0_75",	0.75f },
2197 			{ "min_1_0",	1.0f }
2198 		};
2199 
2200 		de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", ""));
2201 
2202 		for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
2203 		{
2204 			const TestConfig&				testConfig				= testConfigs[configNdx];
2205 			de::MovePtr<tcu::TestCaseGroup>	minShadingValueTests	(new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
2206 
2207 			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2208 			{
2209 				std::ostringstream caseName;
2210 				caseName << "samples_" << samples[samplesNdx];
2211 
2212 				de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
2213 
2214 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE));
2215 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE));
2216 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT));
2217 
2218 				minShadingValueTests->addChild(samplesTests.release());
2219 			}
2220 
2221 			minSampleShadingTests->addChild(minShadingValueTests.release());
2222 		}
2223 
2224 		multisampleTests->addChild(minSampleShadingTests.release());
2225 	}
2226 
2227 	// pSampleMask tests
2228 	{
2229 		struct TestConfig
2230 		{
2231 			const char*		name;
2232 			const char*		description;
2233 			VkSampleMask	sampleMask;
2234 		};
2235 
2236 		const TestConfig testConfigs[] =
2237 		{
2238 			{ "mask_all_on",	"All mask bits are off",			0x0 },
2239 			{ "mask_all_off",	"All mask bits are on",				0xFFFFFFFF },
2240 			{ "mask_one",		"All mask elements are 0x1",		0x1},
2241 			{ "mask_random",	"All mask elements are 0xAAAAAAAA",	0xAAAAAAAA },
2242 		};
2243 
2244 		de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", ""));
2245 
2246 		for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
2247 		{
2248 			const TestConfig&				testConfig				= testConfigs[configNdx];
2249 			de::MovePtr<tcu::TestCaseGroup>	sampleMaskValueTests	(new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description));
2250 
2251 			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2252 			{
2253 				std::ostringstream caseName;
2254 				caseName << "samples_" << samples[samplesNdx];
2255 
2256 				const deUint32					sampleMaskCount	= samples[samplesNdx] / 32;
2257 				de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
2258 
2259 				std::vector<VkSampleMask> mask;
2260 				for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++)
2261 					mask.push_back(testConfig.sampleMask);
2262 
2263 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE));
2264 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE));
2265 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT));
2266 
2267 				sampleMaskValueTests->addChild(samplesTests.release());
2268 			}
2269 
2270 			sampleMaskTests->addChild(sampleMaskValueTests.release());
2271 		}
2272 
2273 		multisampleTests->addChild(sampleMaskTests.release());
2274 
2275 	}
2276 
2277 	// AlphaToOne tests
2278 	{
2279 		de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", ""));
2280 
2281 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2282 		{
2283 			std::ostringstream caseName;
2284 			caseName << "samples_" << samples[samplesNdx];
2285 
2286 			alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx]));
2287 		}
2288 
2289 		multisampleTests->addChild(alphaToOneTests.release());
2290 	}
2291 
2292 	// AlphaToCoverageEnable tests
2293 	{
2294 		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", ""));
2295 
2296 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2297 		{
2298 			std::ostringstream caseName;
2299 			caseName << "samples_" << samples[samplesNdx];
2300 
2301 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
2302 
2303 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD));
2304 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD));
2305 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD));
2306 
2307 			alphaToCoverageTests->addChild(samplesTests.release());
2308 		}
2309 		multisampleTests->addChild(alphaToCoverageTests.release());
2310 	}
2311 
2312 	// Sampling from a multisampled image texture (texelFetch)
2313 	{
2314 		multisampleTests->addChild(createMultisampleSampledImageTests(testCtx));
2315 	}
2316 
2317 	// Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.)
2318 	{
2319 		multisampleTests->addChild(createMultisampleStorageImageTests(testCtx));
2320 	}
2321 
2322 	return multisampleTests.release();
2323 }
2324 
2325 } // pipeline
2326 } // vkt
2327