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