1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Imagination Technologies Ltd.
7  * Copyright (c) 2017 Google Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Multisample Tests
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktPipelineMultisampleTests.hpp"
27 #include "vktPipelineMultisampleImageTests.hpp"
28 #include "vktPipelineMultisampleSampleLocationsExtTests.hpp"
29 #include "vktPipelineClearUtil.hpp"
30 #include "vktPipelineImageUtil.hpp"
31 #include "vktPipelineVertexUtil.hpp"
32 #include "vktPipelineReferenceRenderer.hpp"
33 #include "vktTestCase.hpp"
34 #include "vktTestCaseUtil.hpp"
35 #include "vkImageUtil.hpp"
36 #include "vkMemUtil.hpp"
37 #include "vkPrograms.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "vkRef.hpp"
40 #include "vkRefUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 #include "vkTypeUtil.hpp"
43 #include "vkObjUtil.hpp"
44 #include "tcuImageCompare.hpp"
45 #include "tcuTestLog.hpp"
46 #include "deUniquePtr.hpp"
47 #include "deSharedPtr.hpp"
48 #include "deStringUtil.hpp"
49 #include "deMemory.h"
50 
51 #include <sstream>
52 #include <vector>
53 #include <map>
54 
55 namespace vkt
56 {
57 namespace pipeline
58 {
59 
60 using namespace vk;
61 
62 namespace
63 {
64 enum GeometryType
65 {
66 	GEOMETRY_TYPE_OPAQUE_TRIANGLE,
67 	GEOMETRY_TYPE_OPAQUE_LINE,
68 	GEOMETRY_TYPE_OPAQUE_POINT,
69 	GEOMETRY_TYPE_OPAQUE_QUAD,
70 	GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH,	//!< placed at z = 0.5
71 	GEOMETRY_TYPE_TRANSLUCENT_QUAD,
72 	GEOMETRY_TYPE_INVISIBLE_TRIANGLE,
73 	GEOMETRY_TYPE_INVISIBLE_QUAD,
74 	GEOMETRY_TYPE_GRADIENT_QUAD
75 };
76 
77 enum TestModeBits
78 {
79 	TEST_MODE_DEPTH_BIT		= 1u,
80 	TEST_MODE_STENCIL_BIT	= 2u,
81 };
82 typedef deUint32 TestModeFlags;
83 
84 enum RenderType
85 {
86 	// resolve multisample rendering to single sampled image
87 	RENDER_TYPE_RESOLVE		= 0u,
88 
89 	// copy samples to an array of single sampled images
90 	RENDER_TYPE_COPY_SAMPLES
91 };
92 
93 enum ImageBackingMode
94 {
95 	IMAGE_BACKING_MODE_REGULAR	= 0u,
96 	IMAGE_BACKING_MODE_SPARSE
97 };
98 
99 struct MultisampleTestParams
100 {
101 	GeometryType		geometryType;
102 	float				pointSize;
103 	ImageBackingMode	backingMode;
104 };
105 
checkLargePointsSupport(Context & context,VkPrimitiveTopology topology,float pointSize)106 void checkLargePointsSupport (Context& context, VkPrimitiveTopology topology, float pointSize)
107 {
108 	if (topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && pointSize > 1.0f && !context.getDeviceFeatures().largePoints)
109 		TCU_THROW(NotSupportedError, "Large points feature not supported.");
110 }
111 
112 void									initMultisamplePrograms				(SourceCollections& sources, MultisampleTestParams params);
113 bool									isSupportedSampleCount				(const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples);
114 bool									isSupportedDepthStencilFormat		(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format);
115 VkPipelineColorBlendAttachmentState		getDefaultColorBlendAttachmentState	(void);
116 deUint32								getUniqueColorsCount				(const tcu::ConstPixelBufferAccess& image);
117 VkImageAspectFlags						getImageAspectFlags					(const VkFormat format);
118 VkPrimitiveTopology						getPrimitiveTopology				(const GeometryType geometryType);
119 std::vector<Vertex4RGBA>				generateVertices					(const GeometryType geometryType);
120 VkFormat								findSupportedDepthStencilFormat		(Context& context, const bool useDepth, const bool useStencil);
121 
122 class MultisampleTest : public vkt::TestCase
123 {
124 public:
125 
126 												MultisampleTest						(tcu::TestContext&								testContext,
127 																					 const std::string&								name,
128 																					 const std::string&								description,
129 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
130 																					 const VkPipelineColorBlendAttachmentState&		blendState,
131 																					 GeometryType									geometryType,
132 																					 float											pointSize,
133 																					 ImageBackingMode								backingMode);
~MultisampleTest(void)134 	virtual										~MultisampleTest					(void) {}
135 
136 	virtual void								initPrograms						(SourceCollections& programCollection) const;
137 	virtual TestInstance*						createInstance						(Context& context) const;
138 
139 protected:
140 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
141 																					 VkPrimitiveTopology							topology,
142 																					 float											pointSize,
143 																					 const std::vector<Vertex4RGBA>&				vertices,
144 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
145 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const = 0;
146 	VkPipelineMultisampleStateCreateInfo		m_multisampleStateParams;
147 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
148 	const GeometryType							m_geometryType;
149 	const float									m_pointSize;
150 	const ImageBackingMode						m_backingMode;
151 	std::vector<VkSampleMask>					m_sampleMask;
152 };
153 
154 class RasterizationSamplesTest : public MultisampleTest
155 {
156 public:
157 												RasterizationSamplesTest			(tcu::TestContext&		testContext,
158 																					 const std::string&		name,
159 																					 const std::string&		description,
160 																					 VkSampleCountFlagBits	rasterizationSamples,
161 																					 GeometryType			geometryType,
162 																					 float					pointSize,
163 																					 ImageBackingMode		backingMode,
164 																					 TestModeFlags			modeFlags				= 0u);
~RasterizationSamplesTest(void)165 	virtual										~RasterizationSamplesTest			(void) {}
166 
167 protected:
168 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
169 																					 VkPrimitiveTopology							topology,
170 																					 float											pointSize,
171 																					 const std::vector<Vertex4RGBA>&				vertices,
172 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
173 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
174 
175 	static VkPipelineMultisampleStateCreateInfo	getRasterizationSamplesStateParams	(VkSampleCountFlagBits rasterizationSamples);
176 
177 	const ImageBackingMode						m_backingMode;
178 	const TestModeFlags							m_modeFlags;
179 };
180 
181 class MinSampleShadingTest : public MultisampleTest
182 {
183 public:
184 												MinSampleShadingTest				(tcu::TestContext&		testContext,
185 																					 const std::string&		name,
186 																					 const std::string&		description,
187 																					 VkSampleCountFlagBits	rasterizationSamples,
188 																					 float					minSampleShading,
189 																					 GeometryType			geometryType,
190 																					 float					pointSize,
191 																					 ImageBackingMode		backingMode);
~MinSampleShadingTest(void)192 	virtual										~MinSampleShadingTest				(void) {}
193 
194 protected:
195 	virtual void								initPrograms						(SourceCollections& programCollection) const;
196 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
197 																					 VkPrimitiveTopology							topology,
198 																					 float											pointSize,
199 																					 const std::vector<Vertex4RGBA>&				vertices,
200 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
201 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
202 
203 	static VkPipelineMultisampleStateCreateInfo	getMinSampleShadingStateParams		(VkSampleCountFlagBits rasterizationSamples, float minSampleShading);
204 
205 	const float									m_pointSize;
206 	const ImageBackingMode						m_backingMode;
207 };
208 
209 class SampleMaskTest : public MultisampleTest
210 {
211 public:
212 												SampleMaskTest						(tcu::TestContext&					testContext,
213 																					 const std::string&					name,
214 																					 const std::string&					description,
215 																					 VkSampleCountFlagBits				rasterizationSamples,
216 																					 const std::vector<VkSampleMask>&	sampleMask,
217 																					 GeometryType						geometryType,
218 																					 float								pointSize,
219 																					 ImageBackingMode					backingMode);
220 
~SampleMaskTest(void)221 	virtual										~SampleMaskTest						(void) {}
222 
223 protected:
224 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
225 																					 VkPrimitiveTopology							topology,
226 																					 float											pointSize,
227 																					 const std::vector<Vertex4RGBA>&				vertices,
228 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
229 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
230 
231 	static VkPipelineMultisampleStateCreateInfo	getSampleMaskStateParams			(VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask);
232 
233 	const ImageBackingMode						m_backingMode;
234 };
235 
236 class AlphaToOneTest : public MultisampleTest
237 {
238 public:
239 												AlphaToOneTest					(tcu::TestContext&					testContext,
240 																				 const std::string&					name,
241 																				 const std::string&					description,
242 																				 VkSampleCountFlagBits				rasterizationSamples,
243 																				 ImageBackingMode					backingMode);
244 
~AlphaToOneTest(void)245 	virtual										~AlphaToOneTest					(void) {}
246 
247 protected:
248 	virtual TestInstance*						createMultisampleTestInstance	(Context&										context,
249 																				 VkPrimitiveTopology							topology,
250 																				 float											pointSize,
251 																				 const std::vector<Vertex4RGBA>&				vertices,
252 																				 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
253 																				 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
254 
255 	static VkPipelineMultisampleStateCreateInfo	getAlphaToOneStateParams		(VkSampleCountFlagBits rasterizationSamples);
256 	static VkPipelineColorBlendAttachmentState	getAlphaToOneBlendState			(void);
257 
258 	const ImageBackingMode						m_backingMode;
259 };
260 
261 class AlphaToCoverageTest : public MultisampleTest
262 {
263 public:
264 												AlphaToCoverageTest				(tcu::TestContext&		testContext,
265 																				 const std::string&		name,
266 																				 const std::string&		description,
267 																				 VkSampleCountFlagBits	rasterizationSamples,
268 																				 GeometryType			geometryType,
269 																				 ImageBackingMode		backingMode);
270 
~AlphaToCoverageTest(void)271 	virtual										~AlphaToCoverageTest			(void) {}
272 
273 protected:
274 	virtual TestInstance*						createMultisampleTestInstance	(Context&										context,
275 																				 VkPrimitiveTopology							topology,
276 																				 float											pointSize,
277 																				 const std::vector<Vertex4RGBA>&				vertices,
278 																				 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
279 																				 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
280 
281 	static VkPipelineMultisampleStateCreateInfo	getAlphaToCoverageStateParams	(VkSampleCountFlagBits rasterizationSamples);
282 
283 	GeometryType								m_geometryType;
284 	const ImageBackingMode						m_backingMode;
285 };
286 
287 class SampleMaskWithDepthTestTest : public vkt::TestCase
288 {
289 public:
290 												SampleMaskWithDepthTestTest		(tcu::TestContext&				testContext,
291 																				 const std::string&				name,
292 																				 const std::string&				description,
293 																				 const VkSampleCountFlagBits	rasterizationSamples,
294 																				 const bool						enablePostDepthCoverage		= false);
295 
~SampleMaskWithDepthTestTest(void)296 												~SampleMaskWithDepthTestTest	(void) {}
297 
298 	void										initPrograms					(SourceCollections&		programCollection)	const;
299 	TestInstance*								createInstance					(Context&				context)			const;
300 private:
301 	const VkSampleCountFlagBits					m_rasterizationSamples;
302 	const bool									m_enablePostDepthCoverage;
303 };
304 
305 typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp;
306 
307 class MultisampleRenderer
308 {
309 public:
310 												MultisampleRenderer			(Context&										context,
311 																			 const VkFormat									colorFormat,
312 																			 const tcu::IVec2&								renderSize,
313 																			 const VkPrimitiveTopology						topology,
314 																			 const std::vector<Vertex4RGBA>&				vertices,
315 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
316 																			 const VkPipelineColorBlendAttachmentState&		blendState,
317 																			 const RenderType								renderType,
318 																			 const ImageBackingMode							backingMode);
319 
320 												MultisampleRenderer			(Context&										context,
321 																			 const VkFormat									colorFormat,
322 																			 const VkFormat									depthStencilFormat,
323 																			 const tcu::IVec2&								renderSize,
324 																			 const bool										useDepth,
325 																			 const bool										useStencil,
326 																			 const deUint32									numTopologies,
327 																			 const VkPrimitiveTopology*						pTopology,
328 																			 const std::vector<Vertex4RGBA>*				pVertices,
329 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
330 																			 const VkPipelineColorBlendAttachmentState&		blendState,
331 																			 const RenderType								renderType,
332 																			 const ImageBackingMode							backingMode,
333 																			 const float									depthClearValue			= 1.0f);
334 
335 	virtual										~MultisampleRenderer		(void);
336 
337 	de::MovePtr<tcu::TextureLevel>				render						(void);
338 	de::MovePtr<tcu::TextureLevel>				getSingleSampledImage		(deUint32 sampleId);
339 
340 protected:
341 	void										initialize					(Context&										context,
342 																			 const deUint32									numTopologies,
343 																			 const VkPrimitiveTopology*						pTopology,
344 																			 const std::vector<Vertex4RGBA>*				pVertices);
345 
346 	Context&									m_context;
347 
348 	const Unique<VkSemaphore>					m_bindSemaphore;
349 
350 	const VkFormat								m_colorFormat;
351 	const VkFormat								m_depthStencilFormat;
352 	tcu::IVec2									m_renderSize;
353 	const bool									m_useDepth;
354 	const bool									m_useStencil;
355 
356 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
357 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
358 
359 	const RenderType							m_renderType;
360 
361 	Move<VkImage>								m_colorImage;
362 	de::MovePtr<Allocation>						m_colorImageAlloc;
363 	Move<VkImageView>							m_colorAttachmentView;
364 
365 	Move<VkImage>								m_resolveImage;
366 	de::MovePtr<Allocation>						m_resolveImageAlloc;
367 	Move<VkImageView>							m_resolveAttachmentView;
368 
369 	struct PerSampleImage
370 	{
371 		Move<VkImage>								m_image;
372 		de::MovePtr<Allocation>						m_imageAlloc;
373 		Move<VkImageView>							m_attachmentView;
374 	};
375 	std::vector<de::SharedPtr<PerSampleImage> >	m_perSampleImages;
376 
377 	Move<VkImage>								m_depthStencilImage;
378 	de::MovePtr<Allocation>						m_depthStencilImageAlloc;
379 	Move<VkImageView>							m_depthStencilAttachmentView;
380 
381 	Move<VkRenderPass>							m_renderPass;
382 	Move<VkFramebuffer>							m_framebuffer;
383 
384 	Move<VkShaderModule>						m_vertexShaderModule;
385 	Move<VkShaderModule>						m_fragmentShaderModule;
386 
387 	Move<VkShaderModule>						m_copySampleVertexShaderModule;
388 	Move<VkShaderModule>						m_copySampleFragmentShaderModule;
389 
390 	Move<VkBuffer>								m_vertexBuffer;
391 	de::MovePtr<Allocation>						m_vertexBufferAlloc;
392 
393 	Move<VkPipelineLayout>						m_pipelineLayout;
394 	std::vector<VkPipelineSp>					m_graphicsPipelines;
395 
396 	Move<VkDescriptorSetLayout>					m_copySampleDesciptorLayout;
397 	Move<VkDescriptorPool>						m_copySampleDesciptorPool;
398 	Move<VkDescriptorSet>						m_copySampleDesciptorSet;
399 
400 	Move<VkPipelineLayout>						m_copySamplePipelineLayout;
401 	std::vector<VkPipelineSp>					m_copySamplePipelines;
402 
403 	Move<VkCommandPool>							m_cmdPool;
404 	Move<VkCommandBuffer>						m_cmdBuffer;
405 
406 	std::vector<de::SharedPtr<Allocation> >		m_allocations;
407 
408 	ImageBackingMode							m_backingMode;
409 	const float									m_depthClearValue;
410 };
411 
412 class RasterizationSamplesInstance : public vkt::TestInstance
413 {
414 public:
415 										RasterizationSamplesInstance	(Context&										context,
416 																		 VkPrimitiveTopology							topology,
417 																		 float											pointSize,
418 																		 const std::vector<Vertex4RGBA>&				vertices,
419 																		 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
420 																		 const VkPipelineColorBlendAttachmentState&		blendState,
421 																		 const TestModeFlags							modeFlags,
422 																		 ImageBackingMode								backingMode);
~RasterizationSamplesInstance(void)423 	virtual								~RasterizationSamplesInstance	(void) {}
424 
425 	virtual tcu::TestStatus				iterate							(void);
426 
427 protected:
428 	virtual tcu::TestStatus				verifyImage						(const tcu::ConstPixelBufferAccess& result);
429 
430 	const VkFormat						m_colorFormat;
431 	const tcu::IVec2					m_renderSize;
432 	const VkPrimitiveTopology			m_primitiveTopology;
433 	const float							m_pointSize;
434 	const std::vector<Vertex4RGBA>		m_vertices;
435 	const std::vector<Vertex4RGBA>		m_fullQuadVertices;			//!< used by depth/stencil case
436 	const TestModeFlags					m_modeFlags;
437 	de::MovePtr<MultisampleRenderer>	m_multisampleRenderer;
438 };
439 
440 class MinSampleShadingInstance : public vkt::TestInstance
441 {
442 public:
443 												MinSampleShadingInstance	(Context&										context,
444 																			 VkPrimitiveTopology							topology,
445 																			 float											pointSize,
446 																			 const std::vector<Vertex4RGBA>&				vertices,
447 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
448 																			 const VkPipelineColorBlendAttachmentState&		blendState,
449 																			 ImageBackingMode								backingMode);
~MinSampleShadingInstance(void)450 	virtual										~MinSampleShadingInstance	(void) {}
451 
452 	virtual tcu::TestStatus						iterate						(void);
453 
454 protected:
455 	virtual tcu::TestStatus						verifySampleShadedImage		(const std::vector<tcu::TextureLevel>& testShadingImages,
456 																			 const tcu::ConstPixelBufferAccess& noSampleshadingImage);
457 
458 	const VkFormat								m_colorFormat;
459 	const tcu::IVec2							m_renderSize;
460 	const VkPrimitiveTopology					m_primitiveTopology;
461 	const std::vector<Vertex4RGBA>				m_vertices;
462 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
463 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
464 	const ImageBackingMode						m_backingMode;
465 };
466 
467 class SampleMaskInstance : public vkt::TestInstance
468 {
469 public:
470 												SampleMaskInstance			(Context&										context,
471 																			 VkPrimitiveTopology							topology,
472 																			 float											pointSize,
473 																			 const std::vector<Vertex4RGBA>&				vertices,
474 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
475 																			 const VkPipelineColorBlendAttachmentState&		blendState,
476 																			 ImageBackingMode								backingMode);
~SampleMaskInstance(void)477 	virtual										~SampleMaskInstance			(void) {}
478 
479 	virtual tcu::TestStatus						iterate						(void);
480 
481 protected:
482 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& testShadingImage,
483 																			 const tcu::ConstPixelBufferAccess& minShadingImage,
484 																			 const tcu::ConstPixelBufferAccess& maxShadingImage);
485 	const VkFormat								m_colorFormat;
486 	const tcu::IVec2							m_renderSize;
487 	const VkPrimitiveTopology					m_primitiveTopology;
488 	const std::vector<Vertex4RGBA>				m_vertices;
489 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
490 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
491 	const ImageBackingMode						m_backingMode;
492 };
493 
494 class AlphaToOneInstance : public vkt::TestInstance
495 {
496 public:
497 												AlphaToOneInstance			(Context&										context,
498 																			 VkPrimitiveTopology							topology,
499 																			 const std::vector<Vertex4RGBA>&				vertices,
500 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
501 																			 const VkPipelineColorBlendAttachmentState&		blendState,
502 																			 ImageBackingMode								backingMode);
~AlphaToOneInstance(void)503 	virtual										~AlphaToOneInstance			(void) {}
504 
505 	virtual tcu::TestStatus						iterate						(void);
506 
507 protected:
508 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& alphaOneImage,
509 																			 const tcu::ConstPixelBufferAccess& noAlphaOneImage);
510 	const VkFormat								m_colorFormat;
511 	const tcu::IVec2							m_renderSize;
512 	const VkPrimitiveTopology					m_primitiveTopology;
513 	const std::vector<Vertex4RGBA>				m_vertices;
514 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
515 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
516 	const ImageBackingMode						m_backingMode;
517 };
518 
519 class AlphaToCoverageInstance : public vkt::TestInstance
520 {
521 public:
522 												AlphaToCoverageInstance		(Context&										context,
523 																			 VkPrimitiveTopology							topology,
524 																			 const std::vector<Vertex4RGBA>&				vertices,
525 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
526 																			 const VkPipelineColorBlendAttachmentState&		blendState,
527 																			 GeometryType									geometryType,
528 																			 ImageBackingMode								backingMode);
~AlphaToCoverageInstance(void)529 	virtual										~AlphaToCoverageInstance	(void) {}
530 
531 	virtual tcu::TestStatus						iterate						(void);
532 
533 protected:
534 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& result);
535 	const VkFormat								m_colorFormat;
536 	const tcu::IVec2							m_renderSize;
537 	const VkPrimitiveTopology					m_primitiveTopology;
538 	const std::vector<Vertex4RGBA>				m_vertices;
539 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
540 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
541 	const GeometryType							m_geometryType;
542 	const ImageBackingMode						m_backingMode;
543 };
544 
545 class SampleMaskWithDepthTestInstance : public vkt::TestInstance
546 {
547 public:
548 													SampleMaskWithDepthTestInstance		(Context&							context,
549 																						 const VkSampleCountFlagBits		rasterizationSamples,
550 																						 const bool							enablePostDepthCoverage);
~SampleMaskWithDepthTestInstance(void)551 													~SampleMaskWithDepthTestInstance	(void) {}
552 
553 	tcu::TestStatus									iterate								(void);
554 
555 protected:
556 	VkPipelineMultisampleStateCreateInfo			getMultisampleState					(const VkSampleCountFlagBits		rasterizationSamples);
557 	std::vector<Vertex4RGBA>						generateVertices					(void);
558 	tcu::TestStatus									verifyImage							(const tcu::ConstPixelBufferAccess&	result);
559 
560 	struct SampleCoverage
561 	{
SampleCoveragevkt::pipeline::__anonc7ef40ef0111::SampleMaskWithDepthTestInstance::SampleCoverage562 		SampleCoverage() {};
SampleCoveragevkt::pipeline::__anonc7ef40ef0111::SampleMaskWithDepthTestInstance::SampleCoverage563 		SampleCoverage(deUint32 min_, deUint32 max_)
564 			: min(min_), max(max_) {};
565 
566 		deUint32	min;
567 		deUint32	max;
568 	};
569 
570 	const VkSampleCountFlagBits						m_rasterizationSamples;
571 	const bool										m_enablePostDepthCoverage;
572 	const VkFormat									m_colorFormat;
573 	const VkFormat									m_depthStencilFormat;
574 	const tcu::IVec2								m_renderSize;
575 	const bool										m_useDepth;
576 	const bool										m_useStencil;
577 	const VkPrimitiveTopology						m_topology;
578 	const tcu::Vec4									m_renderColor;
579 	const std::vector<Vertex4RGBA>					m_vertices;
580 	const VkPipelineMultisampleStateCreateInfo		m_multisampleStateParams;
581 	const VkPipelineColorBlendAttachmentState		m_blendState;
582 	const RenderType								m_renderType;
583 	const ImageBackingMode							m_imageBackingMode;
584 	const float										m_depthClearValue;
585 	std::map<VkSampleCountFlagBits, SampleCoverage>	m_refCoverageAfterDepthTest;
586 };
587 
588 
589 // Helper functions
590 
initMultisamplePrograms(SourceCollections & sources,MultisampleTestParams params)591 void initMultisamplePrograms (SourceCollections& sources, MultisampleTestParams params)
592 {
593 	const std::string	pointSize		= params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string("	gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string("");
594 	std::ostringstream	vertexSource;
595 
596 	vertexSource <<
597 		"#version 310 es\n"
598 		"layout(location = 0) in vec4 position;\n"
599 		"layout(location = 1) in vec4 color;\n"
600 		"layout(location = 0) out highp vec4 vtxColor;\n"
601 		"void main (void)\n"
602 		"{\n"
603 		"	gl_Position = position;\n"
604 		"	vtxColor = color;\n"
605 		<< pointSize
606 		<< "}\n";
607 
608 	static const char* fragmentSource =
609 		"#version 310 es\n"
610 		"layout(location = 0) in highp vec4 vtxColor;\n"
611 		"layout(location = 0) out highp vec4 fragColor;\n"
612 		"void main (void)\n"
613 		"{\n"
614 		"	fragColor = vtxColor;\n"
615 		"}\n";
616 
617 	sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
618 	sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
619 }
620 
initSampleShadingPrograms(SourceCollections & sources,MultisampleTestParams params)621 void initSampleShadingPrograms (SourceCollections& sources, MultisampleTestParams params)
622 {
623 	{
624 		const std::string	pointSize		= params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string("	gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string("");
625 		std::ostringstream	vertexSource;
626 
627 		vertexSource <<
628 			"#version 440\n"
629 			"layout(location = 0) in vec4 position;\n"
630 			"layout(location = 1) in vec4 color;\n"
631 			"void main (void)\n"
632 			"{\n"
633 			"	gl_Position = position;\n"
634 			<< pointSize
635 			<< "}\n";
636 
637 		static const char* fragmentSource =
638 			"#version 440\n"
639 			"layout(location = 0) out highp vec4 fragColor;\n"
640 			"void main (void)\n"
641 			"{\n"
642 			"	fragColor = vec4(fract(gl_FragCoord.xy), 0.0, 1.0);\n"
643 			"}\n";
644 
645 		sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
646 		sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
647 	}
648 
649 	{
650 		static const char*  vertexSource =
651 			"#version 440\n"
652 			"void main (void)\n"
653 			"{\n"
654 			"	const vec4 positions[4] = vec4[4](\n"
655 			"		vec4(-1.0, -1.0, 0.0, 1.0),\n"
656 			"		vec4(-1.0,  1.0, 0.0, 1.0),\n"
657 			"		vec4( 1.0, -1.0, 0.0, 1.0),\n"
658 			"		vec4( 1.0,  1.0, 0.0, 1.0)\n"
659 			"	);\n"
660 			"	gl_Position = positions[gl_VertexIndex];\n"
661 			"}\n";
662 
663 		static const char* fragmentSource =
664 			"#version 440\n"
665 			"precision highp float;\n"
666 			"layout(location = 0) out highp vec4 fragColor;\n"
667 			"layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
668 			"layout(push_constant) uniform PushConstantsBlock\n"
669 			"{\n"
670 			"	int sampleId;\n"
671 			"} pushConstants;\n"
672 			"void main (void)\n"
673 			"{\n"
674 			"	fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n"
675 			"}\n";
676 
677 		sources.glslSources.add("quad_vert") << glu::VertexSource(vertexSource);
678 		sources.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource);
679 	}
680 }
681 
isSupportedSampleCount(const InstanceInterface & instanceInterface,VkPhysicalDevice physicalDevice,VkSampleCountFlagBits rasterizationSamples)682 bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples)
683 {
684 	VkPhysicalDeviceProperties deviceProperties;
685 
686 	instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties);
687 
688 	return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples);
689 }
690 
getDefaultColorBlendAttachmentState(void)691 VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void)
692 {
693 	const VkPipelineColorBlendAttachmentState colorBlendState =
694 	{
695 		false,														// VkBool32					blendEnable;
696 		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcColorBlendFactor;
697 		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstColorBlendFactor;
698 		VK_BLEND_OP_ADD,											// VkBlendOp				colorBlendOp;
699 		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcAlphaBlendFactor;
700 		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstAlphaBlendFactor;
701 		VK_BLEND_OP_ADD,											// VkBlendOp				alphaBlendOp;
702 		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
703 			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
704 	};
705 
706 	return colorBlendState;
707 }
708 
getUniqueColorsCount(const tcu::ConstPixelBufferAccess & image)709 deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image)
710 {
711 	DE_ASSERT(image.getFormat().getPixelSize() == 4);
712 
713 	std::map<deUint32, deUint32>	histogram; // map<pixel value, number of occurrences>
714 	const deUint32					pixelCount	= image.getWidth() * image.getHeight() * image.getDepth();
715 
716 	for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
717 	{
718 		const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx);
719 
720 		if (histogram.find(pixelValue) != histogram.end())
721 			histogram[pixelValue]++;
722 		else
723 			histogram[pixelValue] = 1;
724 	}
725 
726 	return (deUint32)histogram.size();
727 }
728 
getImageAspectFlags(const VkFormat format)729 VkImageAspectFlags getImageAspectFlags (const VkFormat format)
730 {
731 	const tcu::TextureFormat tcuFormat = mapVkFormat(format);
732 
733 	if      (tcuFormat.order == tcu::TextureFormat::DS)		return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
734 	else if (tcuFormat.order == tcu::TextureFormat::D)		return VK_IMAGE_ASPECT_DEPTH_BIT;
735 	else if (tcuFormat.order == tcu::TextureFormat::S)		return VK_IMAGE_ASPECT_STENCIL_BIT;
736 
737 	DE_ASSERT(false);
738 	return 0u;
739 }
740 
generateVertices(const GeometryType geometryType)741 std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType)
742 {
743 	std::vector<Vertex4RGBA> vertices;
744 
745 	switch (geometryType)
746 	{
747 		case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
748 		case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:
749 		{
750 			Vertex4RGBA vertexData[3] =
751 			{
752 				{
753 					tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
754 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
755 				},
756 				{
757 					tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
758 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
759 				},
760 				{
761 					tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
762 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
763 				}
764 			};
765 
766 			if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE)
767 			{
768 				for (int i = 0; i < 3; i++)
769 					vertexData[i].color = tcu::Vec4();
770 			}
771 
772 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3);
773 			break;
774 		}
775 
776 		case GEOMETRY_TYPE_OPAQUE_LINE:
777 		{
778 			const Vertex4RGBA vertexData[2] =
779 			{
780 				{
781 					tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f),
782 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
783 				},
784 				{
785 					tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f),
786 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
787 				}
788 			};
789 
790 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2);
791 			break;
792 		}
793 
794 		case GEOMETRY_TYPE_OPAQUE_POINT:
795 		{
796 			const Vertex4RGBA vertex =
797 			{
798 				tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
799 				tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
800 			};
801 
802 			vertices = std::vector<Vertex4RGBA>(1, vertex);
803 			break;
804 		}
805 
806 		case GEOMETRY_TYPE_OPAQUE_QUAD:
807 		case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
808 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
809 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
810 		case GEOMETRY_TYPE_GRADIENT_QUAD:
811 		{
812 			Vertex4RGBA vertexData[4] =
813 			{
814 				{
815 					tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
816 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
817 				},
818 				{
819 					tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),
820 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
821 				},
822 				{
823 					tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
824 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
825 				},
826 				{
827 					tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
828 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
829 				}
830 			};
831 
832 			if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD)
833 			{
834 				for (int i = 0; i < 4; i++)
835 					vertexData[i].color.w() = 0.25f;
836 			}
837 			else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD)
838 			{
839 				for (int i = 0; i < 4; i++)
840 					vertexData[i].color.w() = 0.0f;
841 			}
842 			else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD)
843 			{
844 				vertexData[0].color.w() = 0.0f;
845 				vertexData[2].color.w() = 0.0f;
846 			}
847 			else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)
848 			{
849 				for (int i = 0; i < 4; i++)
850 					vertexData[i].position.z() = 0.5f;
851 			}
852 
853 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 4);
854 			break;
855 		}
856 
857 		default:
858 			DE_ASSERT(false);
859 	}
860 	return vertices;
861 }
862 
getPrimitiveTopology(const GeometryType geometryType)863 VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType)
864 {
865 	switch (geometryType)
866 	{
867 		case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
868 		case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:			return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
869 
870 		case GEOMETRY_TYPE_OPAQUE_LINE:					return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
871 		case GEOMETRY_TYPE_OPAQUE_POINT:				return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
872 
873 		case GEOMETRY_TYPE_OPAQUE_QUAD:
874 		case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
875 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
876 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
877 		case GEOMETRY_TYPE_GRADIENT_QUAD:				return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
878 
879 		default:
880 			DE_ASSERT(false);
881 			return VK_PRIMITIVE_TOPOLOGY_LAST;
882 	}
883 }
884 
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)885 bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
886 {
887 	VkFormatProperties formatProps;
888 	vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
889 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
890 }
891 
findSupportedDepthStencilFormat(Context & context,const bool useDepth,const bool useStencil)892 VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil)
893 {
894 	if (useDepth && !useStencil)
895 		return VK_FORMAT_D16_UNORM;		// must be supported
896 
897 	const InstanceInterface&	vki			= context.getInstanceInterface();
898 	const VkPhysicalDevice		physDevice	= context.getPhysicalDevice();
899 
900 	// One of these formats must be supported.
901 
902 	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
903 		return VK_FORMAT_D24_UNORM_S8_UINT;
904 
905 	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT))
906 		return VK_FORMAT_D32_SFLOAT_S8_UINT;
907 
908 	return VK_FORMAT_UNDEFINED;
909 }
910 
911 
912 // MultisampleTest
913 
MultisampleTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,float pointSize,ImageBackingMode backingMode)914 MultisampleTest::MultisampleTest (tcu::TestContext&								testContext,
915 								  const std::string&							name,
916 								  const std::string&							description,
917 								  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
918 								  const VkPipelineColorBlendAttachmentState&	blendState,
919 								  GeometryType									geometryType,
920 								  float											pointSize,
921 								  ImageBackingMode								backingMode)
922 	: vkt::TestCase				(testContext, name, description)
923 	, m_multisampleStateParams	(multisampleStateParams)
924 	, m_colorBlendState			(blendState)
925 	, m_geometryType			(geometryType)
926 	, m_pointSize				(pointSize)
927 	, m_backingMode				(backingMode)
928 {
929 	if (m_multisampleStateParams.pSampleMask)
930 	{
931 		// Copy pSampleMask to avoid dependencies with other classes
932 
933 		const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32);
934 
935 		for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++)
936 			m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]);
937 
938 		m_multisampleStateParams.pSampleMask = m_sampleMask.data();
939 	}
940 }
941 
initPrograms(SourceCollections & programCollection) const942 void MultisampleTest::initPrograms (SourceCollections& programCollection) const
943 {
944 	MultisampleTestParams params = {m_geometryType, m_pointSize, m_backingMode};
945 	initMultisamplePrograms(programCollection, params);
946 }
947 
createInstance(Context & context) const948 TestInstance* MultisampleTest::createInstance (Context& context) const
949 {
950 	return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), m_pointSize, generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState);
951 }
952 
953 
954 // RasterizationSamplesTest
955 
RasterizationSamplesTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType,float pointSize,ImageBackingMode backingMode,TestModeFlags modeFlags)956 RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext&		testContext,
957 													const std::string&		name,
958 													const std::string&		description,
959 													VkSampleCountFlagBits	rasterizationSamples,
960 													GeometryType			geometryType,
961 													float					pointSize,
962 													ImageBackingMode		backingMode,
963 													TestModeFlags			modeFlags)
964 	: MultisampleTest	(testContext, name, description, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
965 	, m_backingMode		(backingMode)
966 	, m_modeFlags		(modeFlags)
967 {
968 }
969 
getRasterizationSamplesStateParams(VkSampleCountFlagBits rasterizationSamples)970 VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples)
971 {
972 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
973 	{
974 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
975 		DE_NULL,													// const void*								pNext;
976 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
977 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
978 		false,														// VkBool32									sampleShadingEnable;
979 		0.0f,														// float									minSampleShading;
980 		DE_NULL,													// const VkSampleMask*						pSampleMask;
981 		false,														// VkBool32									alphaToCoverageEnable;
982 		false														// VkBool32									alphaToOneEnable;
983 	};
984 
985 	return multisampleStateParams;
986 }
987 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const988 TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context&										context,
989 																	   VkPrimitiveTopology							topology,
990 																	   float										pointSize,
991 																	   const std::vector<Vertex4RGBA>&				vertices,
992 																	   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
993 																	   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
994 {
995 	return new RasterizationSamplesInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_modeFlags, m_backingMode);
996 }
997 
998 
999 // MinSampleShadingTest
1000 
MinSampleShadingTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,float minSampleShading,GeometryType geometryType,float pointSize,ImageBackingMode backingMode)1001 MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext&		testContext,
1002 											const std::string&		name,
1003 											const std::string&		description,
1004 											VkSampleCountFlagBits	rasterizationSamples,
1005 											float					minSampleShading,
1006 											GeometryType			geometryType,
1007 											float					pointSize,
1008 											ImageBackingMode		backingMode)
1009 	: MultisampleTest	(testContext, name, description, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
1010 	, m_pointSize		(pointSize)
1011 	, m_backingMode		(backingMode)
1012 {
1013 }
1014 
initPrograms(SourceCollections & programCollection) const1015 void MinSampleShadingTest::initPrograms (SourceCollections& programCollection) const
1016 {
1017 	MultisampleTestParams params = {m_geometryType, m_pointSize, m_backingMode};
1018 	initSampleShadingPrograms(programCollection, params);
1019 }
1020 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1021 TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context&										context,
1022 																   VkPrimitiveTopology							topology,
1023 																   float										pointSize,
1024 																   const std::vector<Vertex4RGBA>&				vertices,
1025 																   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1026 																   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
1027 {
1028 	return new MinSampleShadingInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
1029 }
1030 
getMinSampleShadingStateParams(VkSampleCountFlagBits rasterizationSamples,float minSampleShading)1031 VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading)
1032 {
1033 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1034 	{
1035 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1036 		DE_NULL,													// const void*								pNext;
1037 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1038 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1039 		true,														// VkBool32									sampleShadingEnable;
1040 		minSampleShading,											// float									minSampleShading;
1041 		DE_NULL,													// const VkSampleMask*						pSampleMask;
1042 		false,														//  VkBool32								alphaToCoverageEnable;
1043 		false														//  VkBool32								alphaToOneEnable;
1044 	};
1045 
1046 	return multisampleStateParams;
1047 }
1048 
1049 
1050 // SampleMaskTest
1051 
SampleMaskTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,const std::vector<VkSampleMask> & sampleMask,GeometryType geometryType,float pointSize,ImageBackingMode backingMode)1052 SampleMaskTest::SampleMaskTest (tcu::TestContext&					testContext,
1053 								const std::string&					name,
1054 								const std::string&					description,
1055 								VkSampleCountFlagBits				rasterizationSamples,
1056 								const std::vector<VkSampleMask>&	sampleMask,
1057 								GeometryType						geometryType,
1058 								float								pointSize,
1059 								ImageBackingMode					backingMode)
1060 	: MultisampleTest	(testContext, name, description, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
1061 	, m_backingMode		(backingMode)
1062 {
1063 }
1064 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1065 TestInstance* SampleMaskTest::createMultisampleTestInstance (Context&										context,
1066 															 VkPrimitiveTopology							topology,
1067 															 float											pointSize,
1068 															 const std::vector<Vertex4RGBA>&				vertices,
1069 															 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1070 															 const VkPipelineColorBlendAttachmentState&		colorBlendState) const
1071 {
1072 	DE_UNREF(pointSize);
1073 	return new SampleMaskInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
1074 }
1075 
getSampleMaskStateParams(VkSampleCountFlagBits rasterizationSamples,const std::vector<VkSampleMask> & sampleMask)1076 VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask)
1077 {
1078 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1079 	{
1080 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1081 		DE_NULL,													// const void*								pNext;
1082 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1083 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1084 		false,														// VkBool32									sampleShadingEnable;
1085 		0.0f,														// float									minSampleShading;
1086 		sampleMask.data(),											// const VkSampleMask*						pSampleMask;
1087 		false,														// VkBool32									alphaToCoverageEnable;
1088 		false														// VkBool32									alphaToOneEnable;
1089 	};
1090 
1091 	return multisampleStateParams;
1092 }
1093 
1094 
1095 // AlphaToOneTest
1096 
AlphaToOneTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,ImageBackingMode backingMode)1097 AlphaToOneTest::AlphaToOneTest (tcu::TestContext&		testContext,
1098 								const std::string&		name,
1099 								const std::string&		description,
1100 								VkSampleCountFlagBits	rasterizationSamples,
1101 								ImageBackingMode		backingMode)
1102 	: MultisampleTest	(testContext, name, description, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD, 1.0f, backingMode)
1103 	, m_backingMode(backingMode)
1104 {
1105 }
1106 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1107 TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context&										context,
1108 															 VkPrimitiveTopology							topology,
1109 															 float											pointSize,
1110 															 const std::vector<Vertex4RGBA>&				vertices,
1111 															 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1112 															 const VkPipelineColorBlendAttachmentState&		colorBlendState) const
1113 {
1114 	DE_UNREF(pointSize);
1115 	return new AlphaToOneInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_backingMode);
1116 }
1117 
getAlphaToOneStateParams(VkSampleCountFlagBits rasterizationSamples)1118 VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples)
1119 {
1120 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1121 	{
1122 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1123 		DE_NULL,													// const void*								pNext;
1124 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1125 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1126 		false,														// VkBool32									sampleShadingEnable;
1127 		0.0f,														// float									minSampleShading;
1128 		DE_NULL,													// const VkSampleMask*						pSampleMask;
1129 		false,														// VkBool32									alphaToCoverageEnable;
1130 		true														// VkBool32									alphaToOneEnable;
1131 	};
1132 
1133 	return multisampleStateParams;
1134 }
1135 
getAlphaToOneBlendState(void)1136 VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void)
1137 {
1138 	const VkPipelineColorBlendAttachmentState colorBlendState =
1139 	{
1140 		true,														// VkBool32					blendEnable;
1141 		VK_BLEND_FACTOR_SRC_ALPHA,									// VkBlendFactor			srcColorBlendFactor;
1142 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,						// VkBlendFactor			dstColorBlendFactor;
1143 		VK_BLEND_OP_ADD,											// VkBlendOp				colorBlendOp;
1144 		VK_BLEND_FACTOR_SRC_ALPHA,									// VkBlendFactor			srcAlphaBlendFactor;
1145 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,						// VkBlendFactor			dstAlphaBlendFactor;
1146 		VK_BLEND_OP_ADD,											// VkBlendOp				alphaBlendOp;
1147 		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
1148 			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
1149 	};
1150 
1151 	return colorBlendState;
1152 }
1153 
1154 
1155 // AlphaToCoverageTest
1156 
AlphaToCoverageTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType,ImageBackingMode backingMode)1157 AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext&			testContext,
1158 										  const std::string&		name,
1159 										  const std::string&		description,
1160 										  VkSampleCountFlagBits		rasterizationSamples,
1161 										  GeometryType				geometryType,
1162 										  ImageBackingMode			backingMode)
1163 	: MultisampleTest	(testContext, name, description, getAlphaToCoverageStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode)
1164 	, m_geometryType	(geometryType)
1165 	, m_backingMode		(backingMode)
1166 {
1167 }
1168 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1169 TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context&										context,
1170 																  VkPrimitiveTopology							topology,
1171 																  float											pointSize,
1172 																  const std::vector<Vertex4RGBA>&				vertices,
1173 																  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1174 																  const VkPipelineColorBlendAttachmentState&	colorBlendState) const
1175 {
1176 	DE_UNREF(pointSize);
1177 	return new AlphaToCoverageInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode);
1178 }
1179 
getAlphaToCoverageStateParams(VkSampleCountFlagBits rasterizationSamples)1180 VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples)
1181 {
1182 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1183 	{
1184 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1185 		DE_NULL,													// const void*								pNext;
1186 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1187 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1188 		false,														// VkBool32									sampleShadingEnable;
1189 		0.0f,														// float									minSampleShading;
1190 		DE_NULL,													// const VkSampleMask*						pSampleMask;
1191 		true,														// VkBool32									alphaToCoverageEnable;
1192 		false														// VkBool32									alphaToOneEnable;
1193 	};
1194 
1195 	return multisampleStateParams;
1196 }
1197 
1198 // SampleMaskWithDepthTestTest
1199 
SampleMaskWithDepthTestTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const VkSampleCountFlagBits rasterizationSamples,const bool enablePostDepthCoverage)1200 SampleMaskWithDepthTestTest::SampleMaskWithDepthTestTest (tcu::TestContext&					testContext,
1201 														  const std::string&				name,
1202 														  const std::string&				description,
1203 														  const VkSampleCountFlagBits		rasterizationSamples,
1204 														  const bool						enablePostDepthCoverage)
1205 	: vkt::TestCase				(testContext, name, description)
1206 	, m_rasterizationSamples	(rasterizationSamples)
1207 	, m_enablePostDepthCoverage	(enablePostDepthCoverage)
1208 {
1209 }
1210 
initPrograms(SourceCollections & programCollection) const1211 void SampleMaskWithDepthTestTest::initPrograms (SourceCollections& programCollection) const
1212 {
1213 	DE_ASSERT((int)m_rasterizationSamples <= 32);
1214 
1215 	static const char* vertexSource =
1216 		"#version 440\n"
1217 		"layout(location = 0) in vec4 position;\n"
1218 		"layout(location = 1) in vec4 color;\n"
1219 		"layout(location = 0) out vec4 vtxColor;\n"
1220 		"out gl_PerVertex\n"
1221 		"{\n"
1222 		"    vec4 gl_Position;\n"
1223 		"};\n"
1224 		"\n"
1225 		"void main (void)\n"
1226 		"{\n"
1227 		"    gl_Position = position;\n"
1228 		"    vtxColor = color;\n"
1229 		"}\n";
1230 
1231 	std::ostringstream fragmentSource;
1232 	fragmentSource <<
1233 		"#version 440\n"
1234 		<< (m_enablePostDepthCoverage ? "#extension GL_ARB_post_depth_coverage : require\n" : "") <<
1235 		"layout(early_fragment_tests) in;\n"
1236 		<< (m_enablePostDepthCoverage ? "layout(post_depth_coverage) in;\n" : "") <<
1237 		"layout(location = 0) in vec4 vtxColor;\n"
1238 		"layout(location = 0) out vec4 fragColor;\n"
1239 		"void main (void)\n"
1240 		"{\n"
1241 		"    const int coveredSamples = bitCount(gl_SampleMaskIn[0]);\n"
1242 		"    fragColor = vtxColor * (1.0 / " << (int)m_rasterizationSamples << " * coveredSamples);\n"
1243 		"}\n";
1244 
1245 	programCollection.glslSources.add("color_vert") << glu::VertexSource(vertexSource);
1246 	programCollection.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
1247 }
1248 
createInstance(Context & context) const1249 TestInstance* SampleMaskWithDepthTestTest::createInstance (Context& context) const
1250 {
1251 	return new SampleMaskWithDepthTestInstance(context, m_rasterizationSamples, m_enablePostDepthCoverage);
1252 }
1253 
1254 // RasterizationSamplesInstance
1255 
RasterizationSamplesInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,const TestModeFlags modeFlags,ImageBackingMode backingMode)1256 RasterizationSamplesInstance::RasterizationSamplesInstance (Context&										context,
1257 															VkPrimitiveTopology								topology,
1258 															float											pointSize,
1259 															const std::vector<Vertex4RGBA>&					vertices,
1260 															const VkPipelineMultisampleStateCreateInfo&		multisampleStateParams,
1261 															const VkPipelineColorBlendAttachmentState&		blendState,
1262 															const TestModeFlags								modeFlags,
1263 															ImageBackingMode								backingMode)
1264 	: vkt::TestInstance		(context)
1265 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
1266 	, m_renderSize			(32, 32)
1267 	, m_primitiveTopology	(topology)
1268 	, m_pointSize			(pointSize)
1269 	, m_vertices			(vertices)
1270 	, m_fullQuadVertices	(generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH))
1271 	, m_modeFlags			(modeFlags)
1272 {
1273 	checkLargePointsSupport(context, topology, pointSize);
1274 
1275 	if (m_modeFlags != 0)
1276 	{
1277 		const bool		useDepth			= (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0;
1278 		const bool		useStencil			= (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0;
1279 		const VkFormat	depthStencilFormat	= findSupportedDepthStencilFormat(context, useDepth, useStencil);
1280 
1281 		if (depthStencilFormat == VK_FORMAT_UNDEFINED)
1282 			TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported");
1283 
1284 		const VkPrimitiveTopology		pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };
1285 		const std::vector<Vertex4RGBA>	pVertices[2] = { m_vertices, m_fullQuadVertices };
1286 
1287 		m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
1288 			new MultisampleRenderer(
1289 				context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode));
1290 	}
1291 	else
1292 	{
1293 		m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
1294 			new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode));
1295 	}
1296 }
1297 
iterate(void)1298 tcu::TestStatus RasterizationSamplesInstance::iterate (void)
1299 {
1300 	de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render());
1301 	return verifyImage(level->getAccess());
1302 }
1303 
verifyImage(const tcu::ConstPixelBufferAccess & result)1304 tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
1305 {
1306 	// Verify range of unique pixels
1307 	{
1308 		const deUint32	numUniqueColors = getUniqueColorsCount(result);
1309 		const deUint32	minUniqueColors	= (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && m_pointSize == 1.0f) ? 2 : 3;
1310 
1311 		tcu::TestLog& log = m_context.getTestContext().getLog();
1312 
1313 		log << tcu::TestLog::Message
1314 			<< "\nMin. unique colors expected: " << minUniqueColors << "\n"
1315 			<< "Unique colors found: " << numUniqueColors << "\n"
1316 			<< tcu::TestLog::EndMessage;
1317 
1318 		if (numUniqueColors < minUniqueColors)
1319 			return tcu::TestStatus::fail("Unique colors out of expected bounds");
1320 	}
1321 
1322 	// Verify shape of the rendered primitive (fuzzy-compare)
1323 	{
1324 		const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
1325 		const tcu::TextureFormat	tcuDepthFormat	= tcu::TextureFormat();
1326 		const ColorVertexShader		vertexShader;
1327 		const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
1328 		const rr::Program			program			(&vertexShader, &fragmentShader);
1329 		ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
1330 		rr::RenderState				renderState		(refRenderer.getViewportState());
1331 
1332 		if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
1333 		{
1334 			VkPhysicalDeviceProperties deviceProperties;
1335 
1336 			m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
1337 
1338 			// gl_PointSize is clamped to pointSizeRange
1339 			renderState.point.pointSize = deFloatMin(m_pointSize, deviceProperties.limits.pointSizeRange[1]);
1340 		}
1341 
1342 		if (m_modeFlags == 0)
1343 		{
1344 			refRenderer.colorClear(tcu::Vec4(0.0f));
1345 			refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
1346 		}
1347 		else
1348 		{
1349 			// For depth/stencil case the primitive is invisible and the surroundings are filled red.
1350 			refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1351 			refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
1352 		}
1353 
1354 		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT))
1355 			return tcu::TestStatus::fail("Primitive has unexpected shape");
1356 	}
1357 
1358 	return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds");
1359 }
1360 
1361 
1362 // MinSampleShadingInstance
1363 
MinSampleShadingInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState,ImageBackingMode backingMode)1364 MinSampleShadingInstance::MinSampleShadingInstance (Context&									context,
1365 													VkPrimitiveTopology							topology,
1366 													float										pointSize,
1367 													const std::vector<Vertex4RGBA>&				vertices,
1368 													const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1369 													const VkPipelineColorBlendAttachmentState&	colorBlendState,
1370 													ImageBackingMode							backingMode)
1371 	: vkt::TestInstance			(context)
1372 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
1373 	, m_renderSize				(32, 32)
1374 	, m_primitiveTopology		(topology)
1375 	, m_vertices				(vertices)
1376 	, m_multisampleStateParams	(multisampleStateParams)
1377 	, m_colorBlendState			(colorBlendState)
1378 	, m_backingMode				(backingMode)
1379 {
1380 	checkLargePointsSupport(context, topology, pointSize);
1381 
1382 	VkPhysicalDeviceFeatures deviceFeatures;
1383 
1384 	m_context.getInstanceInterface().getPhysicalDeviceFeatures(m_context.getPhysicalDevice(), &deviceFeatures);
1385 
1386 	if (!deviceFeatures.sampleRateShading)
1387 		throw tcu::NotSupportedError("Sample shading is not supported");
1388 }
1389 
iterate(void)1390 tcu::TestStatus MinSampleShadingInstance::iterate (void)
1391 {
1392 	de::MovePtr<tcu::TextureLevel>	noSampleshadingImage;
1393 	std::vector<tcu::TextureLevel>	sampleShadedImages;
1394 
1395 	// Render and resolve without sample shading
1396 	{
1397 		VkPipelineMultisampleStateCreateInfo multisampleStateParms = m_multisampleStateParams;
1398 		multisampleStateParms.sampleShadingEnable	= VK_FALSE;
1399 		multisampleStateParms.minSampleShading		= 0.0;
1400 
1401 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleStateParms, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1402 		noSampleshadingImage  = renderer.render();
1403 	}
1404 
1405 	// Render with test minSampleShading and collect per-sample images
1406 	{
1407 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES, m_backingMode);
1408 		renderer.render();
1409 
1410 		sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples);
1411 		for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
1412 		{
1413 			sampleShadedImages[sampleId] = *renderer.getSingleSampledImage(sampleId);
1414 		}
1415 	}
1416 
1417 	// Log images
1418 	{
1419 		tcu::TestLog& testLog	= m_context.getTestContext().getLog();
1420 
1421 		testLog << tcu::TestLog::ImageSet("Images", "Images")
1422 				<< tcu::TestLog::Image("noSampleshadingImage", "Image rendered without sample shading", noSampleshadingImage->getAccess());
1423 
1424 		for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
1425 		{
1426 			testLog << tcu::TestLog::Image("sampleShadedImage", "One sample of sample shaded image", sampleShadedImages[sampleId].getAccess());
1427 		}
1428 		testLog << tcu::TestLog::EndImageSet;
1429 	}
1430 
1431 	return verifySampleShadedImage(sampleShadedImages, noSampleshadingImage->getAccess());
1432 }
1433 
verifySampleShadedImage(const std::vector<tcu::TextureLevel> & sampleShadedImages,const tcu::ConstPixelBufferAccess & noSampleshadingImage)1434 tcu::TestStatus MinSampleShadingInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& noSampleshadingImage)
1435 {
1436 	const deUint32	pixelCount	= noSampleshadingImage.getWidth() * noSampleshadingImage.getHeight() * noSampleshadingImage.getDepth();
1437 
1438 	bool anyPixelCovered		= false;
1439 
1440 	for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
1441 	{
1442 		const deUint32 noSampleShadingValue = *((const deUint32*)noSampleshadingImage.getDataPtr() + pixelNdx);
1443 
1444 		if (noSampleShadingValue == 0)
1445 		{
1446 			// non-covered pixel, continue
1447 			continue;
1448 		}
1449 		else
1450 		{
1451 			anyPixelCovered = true;
1452 		}
1453 
1454 		int numNotCoveredSamples = 0;
1455 
1456 		std::map<deUint32, deUint32>	histogram; // map<pixel value, number of occurrences>
1457 
1458 		// Collect histogram of occurrences or each pixel across all samples
1459 		for (size_t i = 0; i < sampleShadedImages.size(); ++i)
1460 		{
1461 			const deUint32 sampleShadedValue = *((const deUint32*)sampleShadedImages[i].getAccess().getDataPtr() + pixelNdx);
1462 
1463 			if (sampleShadedValue == 0)
1464 			{
1465 				numNotCoveredSamples++;
1466 				continue;
1467 			}
1468 
1469 			if (histogram.find(sampleShadedValue) != histogram.end())
1470 				histogram[sampleShadedValue]++;
1471 			else
1472 				histogram[sampleShadedValue] = 1;
1473 		}
1474 
1475 		if (numNotCoveredSamples == static_cast<int>(sampleShadedImages.size()))
1476 		{
1477 			return tcu::TestStatus::fail("Got uncovered pixel, where covered samples were expected");
1478 		}
1479 
1480 		const int uniqueColorsCount				= (int)histogram.size();
1481 		const int expectedUniqueSamplesCount	= static_cast<int>(m_multisampleStateParams.minSampleShading * static_cast<float>(sampleShadedImages.size()) + 0.5f);
1482 
1483 		if (uniqueColorsCount + numNotCoveredSamples < expectedUniqueSamplesCount)
1484 		{
1485 			return tcu::TestStatus::fail("Got less unique colors than requested through minSampleShading");
1486 		}
1487 	}
1488 
1489 	if (!anyPixelCovered)
1490 	{
1491 		return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShading");
1492 	}
1493 
1494 	return tcu::TestStatus::pass("Got proper count of unique colors");
1495 }
1496 
SampleMaskInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,ImageBackingMode backingMode)1497 SampleMaskInstance::SampleMaskInstance (Context&										context,
1498 										VkPrimitiveTopology								topology,
1499 										float											pointSize,
1500 										const std::vector<Vertex4RGBA>&					vertices,
1501 										const VkPipelineMultisampleStateCreateInfo&		multisampleStateParams,
1502 										const VkPipelineColorBlendAttachmentState&		blendState,
1503 										ImageBackingMode								backingMode)
1504 	: vkt::TestInstance			(context)
1505 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
1506 	, m_renderSize				(32, 32)
1507 	, m_primitiveTopology		(topology)
1508 	, m_vertices				(vertices)
1509 	, m_multisampleStateParams	(multisampleStateParams)
1510 	, m_colorBlendState			(blendState)
1511 	, m_backingMode				(backingMode)
1512 {
1513 	checkLargePointsSupport(context, topology, pointSize);
1514 }
1515 
iterate(void)1516 tcu::TestStatus SampleMaskInstance::iterate (void)
1517 {
1518 	de::MovePtr<tcu::TextureLevel>				testSampleMaskImage;
1519 	de::MovePtr<tcu::TextureLevel>				minSampleMaskImage;
1520 	de::MovePtr<tcu::TextureLevel>				maxSampleMaskImage;
1521 
1522 	// Render with test flags
1523 	{
1524 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1525 		testSampleMaskImage = renderer.render();
1526 	}
1527 
1528 	// Render with all flags off
1529 	{
1530 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
1531 		const std::vector<VkSampleMask>			sampleMask			(multisampleParams.rasterizationSamples / 32, (VkSampleMask)0);
1532 
1533 		multisampleParams.pSampleMask = sampleMask.data();
1534 
1535 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1536 		minSampleMaskImage = renderer.render();
1537 	}
1538 
1539 	// Render with all flags on
1540 	{
1541 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
1542 		const std::vector<VkSampleMask>			sampleMask			(multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0));
1543 
1544 		multisampleParams.pSampleMask = sampleMask.data();
1545 
1546 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1547 		maxSampleMaskImage = renderer.render();
1548 	}
1549 
1550 	return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess());
1551 }
1552 
verifyImage(const tcu::ConstPixelBufferAccess & testSampleMaskImage,const tcu::ConstPixelBufferAccess & minSampleMaskImage,const tcu::ConstPixelBufferAccess & maxSampleMaskImage)1553 tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage,
1554 												 const tcu::ConstPixelBufferAccess& minSampleMaskImage,
1555 												 const tcu::ConstPixelBufferAccess& maxSampleMaskImage)
1556 {
1557 	const deUint32	testColorCount	= getUniqueColorsCount(testSampleMaskImage);
1558 	const deUint32	minColorCount	= getUniqueColorsCount(minSampleMaskImage);
1559 	const deUint32	maxColorCount	= getUniqueColorsCount(maxSampleMaskImage);
1560 
1561 	tcu::TestLog& log = m_context.getTestContext().getLog();
1562 
1563 	log << tcu::TestLog::Message
1564 		<< "\nColors found: " << testColorCount << "\n"
1565 		<< "Min. colors expected: " << minColorCount << "\n"
1566 		<< "Max. colors expected: " << maxColorCount << "\n"
1567 		<< tcu::TestLog::EndMessage;
1568 
1569 	if (minColorCount > testColorCount || testColorCount > maxColorCount)
1570 		return tcu::TestStatus::fail("Unique colors out of expected bounds");
1571 	else
1572 		return tcu::TestStatus::pass("Unique colors within expected bounds");
1573 }
1574 
testRasterSamplesConsistency(Context & context,MultisampleTestParams params)1575 tcu::TestStatus testRasterSamplesConsistency (Context& context, MultisampleTestParams params)
1576 {
1577 	const VkSampleCountFlagBits samples[] =
1578 	{
1579 		VK_SAMPLE_COUNT_1_BIT,
1580 		VK_SAMPLE_COUNT_2_BIT,
1581 		VK_SAMPLE_COUNT_4_BIT,
1582 		VK_SAMPLE_COUNT_8_BIT,
1583 		VK_SAMPLE_COUNT_16_BIT,
1584 		VK_SAMPLE_COUNT_32_BIT,
1585 		VK_SAMPLE_COUNT_64_BIT
1586 	};
1587 
1588 	const Vertex4RGBA vertexData[3] =
1589 	{
1590 		{
1591 			tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
1592 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1593 		},
1594 		{
1595 			tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
1596 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1597 		},
1598 		{
1599 			tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
1600 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1601 		}
1602 	};
1603 
1604 	const std::vector<Vertex4RGBA>	vertices			(vertexData, vertexData + 3);
1605 	deUint32						prevUniqueColors	= 2;
1606 	int								renderCount			= 0;
1607 
1608 	// Do not render with 1 sample (start with samplesNdx = 1).
1609 	for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
1610 	{
1611 		if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx]))
1612 			continue;
1613 
1614 		const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1615 		{
1616 			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1617 			DE_NULL,													// const void*								pNext;
1618 			0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1619 			samples[samplesNdx],										// VkSampleCountFlagBits					rasterizationSamples;
1620 			false,														// VkBool32									sampleShadingEnable;
1621 			0.0f,														// float									minSampleShading;
1622 			DE_NULL,													// const VkSampleMask*						pSampleMask;
1623 			false,														// VkBool32									alphaToCoverageEnable;
1624 			false														// VkBool32									alphaToOneEnable;
1625 		};
1626 
1627 		MultisampleRenderer				renderer		(context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState(), RENDER_TYPE_RESOLVE, params.backingMode);
1628 		de::MovePtr<tcu::TextureLevel>	result			= renderer.render();
1629 		const deUint32					uniqueColors	= getUniqueColorsCount(result->getAccess());
1630 
1631 		renderCount++;
1632 
1633 		if (prevUniqueColors > uniqueColors)
1634 		{
1635 			std::ostringstream message;
1636 
1637 			message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx];
1638 			return tcu::TestStatus::fail(message.str());
1639 		}
1640 
1641 		prevUniqueColors = uniqueColors;
1642 	}
1643 
1644 	if (renderCount == 0)
1645 		throw tcu::NotSupportedError("Multisampling is unsupported");
1646 
1647 	return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases");
1648 }
1649 
1650 
1651 // AlphaToOneInstance
1652 
AlphaToOneInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,ImageBackingMode backingMode)1653 AlphaToOneInstance::AlphaToOneInstance (Context&									context,
1654 										VkPrimitiveTopology							topology,
1655 										const std::vector<Vertex4RGBA>&				vertices,
1656 										const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1657 										const VkPipelineColorBlendAttachmentState&	blendState,
1658 										ImageBackingMode							backingMode)
1659 	: vkt::TestInstance			(context)
1660 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
1661 	, m_renderSize				(32, 32)
1662 	, m_primitiveTopology		(topology)
1663 	, m_vertices				(vertices)
1664 	, m_multisampleStateParams	(multisampleStateParams)
1665 	, m_colorBlendState			(blendState)
1666 	, m_backingMode				(backingMode)
1667 {
1668 	VkPhysicalDeviceFeatures deviceFeatures;
1669 
1670 	context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &deviceFeatures);
1671 
1672 	if (!deviceFeatures.alphaToOne)
1673 		throw tcu::NotSupportedError("Alpha-to-one is not supported");
1674 }
1675 
iterate(void)1676 tcu::TestStatus AlphaToOneInstance::iterate	(void)
1677 {
1678 	DE_ASSERT(m_multisampleStateParams.alphaToOneEnable);
1679 	DE_ASSERT(m_colorBlendState.blendEnable);
1680 
1681 	de::MovePtr<tcu::TextureLevel>	alphaOneImage;
1682 	de::MovePtr<tcu::TextureLevel>	noAlphaOneImage;
1683 
1684 	// Render with blend enabled and alpha to one on
1685 	{
1686 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1687 		alphaOneImage = renderer.render();
1688 	}
1689 
1690 	// Render with blend enabled and alpha to one off
1691 	{
1692 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
1693 		multisampleParams.alphaToOneEnable = false;
1694 
1695 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1696 		noAlphaOneImage = renderer.render();
1697 	}
1698 
1699 	return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess());
1700 }
1701 
verifyImage(const tcu::ConstPixelBufferAccess & alphaOneImage,const tcu::ConstPixelBufferAccess & noAlphaOneImage)1702 tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess&	alphaOneImage,
1703 												 const tcu::ConstPixelBufferAccess&	noAlphaOneImage)
1704 {
1705 	for (int y = 0; y < m_renderSize.y(); y++)
1706 	{
1707 		for (int x = 0; x < m_renderSize.x(); x++)
1708 		{
1709 			if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y))))
1710 			{
1711 				std::ostringstream message;
1712 				message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y);
1713 				return tcu::TestStatus::fail(message.str());
1714 			}
1715 		}
1716 	}
1717 
1718 	return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one");
1719 }
1720 
1721 
1722 // AlphaToCoverageInstance
1723 
AlphaToCoverageInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,ImageBackingMode backingMode)1724 AlphaToCoverageInstance::AlphaToCoverageInstance (Context&										context,
1725 												  VkPrimitiveTopology							topology,
1726 												  const std::vector<Vertex4RGBA>&				vertices,
1727 												  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1728 												  const VkPipelineColorBlendAttachmentState&	blendState,
1729 												  GeometryType									geometryType,
1730 												  ImageBackingMode								backingMode)
1731 	: vkt::TestInstance			(context)
1732 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
1733 	, m_renderSize				(32, 32)
1734 	, m_primitiveTopology		(topology)
1735 	, m_vertices				(vertices)
1736 	, m_multisampleStateParams	(multisampleStateParams)
1737 	, m_colorBlendState			(blendState)
1738 	, m_geometryType			(geometryType)
1739 	, m_backingMode				(backingMode)
1740 {
1741 }
1742 
iterate(void)1743 tcu::TestStatus AlphaToCoverageInstance::iterate (void)
1744 {
1745 	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
1746 
1747 	de::MovePtr<tcu::TextureLevel>	result;
1748 	MultisampleRenderer				renderer	(m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1749 
1750 	result = renderer.render();
1751 
1752 	return verifyImage(result->getAccess());
1753 }
1754 
verifyImage(const tcu::ConstPixelBufferAccess & result)1755 tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
1756 {
1757 	float maxColorValue;
1758 
1759 	switch (m_geometryType)
1760 	{
1761 		case GEOMETRY_TYPE_OPAQUE_QUAD:
1762 			maxColorValue = 1.01f;
1763 			break;
1764 
1765 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
1766 			maxColorValue = 0.52f;
1767 			break;
1768 
1769 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
1770 			maxColorValue = 0.01f;
1771 			break;
1772 
1773 		default:
1774 			maxColorValue = 0.0f;
1775 			DE_ASSERT(false);
1776 	}
1777 
1778 	for (int y = 0; y < m_renderSize.y(); y++)
1779 	{
1780 		for (int x = 0; x < m_renderSize.x(); x++)
1781 		{
1782 			if (result.getPixel(x, y).x() > maxColorValue)
1783 			{
1784 				std::ostringstream message;
1785 				message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")";
1786 				return tcu::TestStatus::fail(message.str());
1787 			}
1788 		}
1789 	}
1790 
1791 	return tcu::TestStatus::pass("Image matches reference value");
1792 }
1793 
1794 // SampleMaskWithDepthTestInstance
1795 
SampleMaskWithDepthTestInstance(Context & context,const VkSampleCountFlagBits rasterizationSamples,const bool enablePostDepthCoverage)1796 SampleMaskWithDepthTestInstance::SampleMaskWithDepthTestInstance (Context&						context,
1797 																  const VkSampleCountFlagBits	rasterizationSamples,
1798 																  const bool					enablePostDepthCoverage)
1799 	: vkt::TestInstance			(context)
1800 	, m_rasterizationSamples	(rasterizationSamples)
1801 	, m_enablePostDepthCoverage	(enablePostDepthCoverage)
1802 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
1803 	, m_depthStencilFormat		(VK_FORMAT_D16_UNORM)
1804 	, m_renderSize				(tcu::IVec2(3, 3))
1805 	, m_useDepth				(true)
1806 	, m_useStencil				(false)
1807 	, m_topology				(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
1808 	, m_renderColor				(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f))
1809 	, m_vertices				(generateVertices())
1810 	, m_multisampleStateParams	(getMultisampleState(rasterizationSamples))
1811 	, m_blendState				(getDefaultColorBlendAttachmentState())
1812 	, m_renderType				(RENDER_TYPE_RESOLVE)
1813 	, m_imageBackingMode		(IMAGE_BACKING_MODE_REGULAR)
1814 	, m_depthClearValue			(0.667f)
1815 {
1816 	if (!m_context.getDeviceProperties().limits.standardSampleLocations)
1817 		TCU_THROW(NotSupportedError, "standardSampleLocations required");
1818 
1819 	std::vector<VkExtensionProperties> supportedExtensions = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
1820 
1821 	if (!isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_post_depth_coverage")))
1822 		TCU_THROW(NotSupportedError, "VK_EXT_post_depth_coverage not supported");
1823 
1824 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_2_BIT]	= SampleCoverage(1u, 1u);	// !< Sample coverage of the diagonally halved pixel,
1825 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_4_BIT]	= SampleCoverage(2u, 2u);	// !< with max possible subPixelPrecisionBits threshold
1826 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_8_BIT]	= SampleCoverage(2u, 6u);	// !<
1827 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_16_BIT]	= SampleCoverage(6u, 11u);	// !<
1828 }
1829 
iterate(void)1830 tcu::TestStatus SampleMaskWithDepthTestInstance::iterate (void)
1831 {
1832 	de::MovePtr<tcu::TextureLevel>	result;
1833 
1834 	MultisampleRenderer renderer (m_context, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, 1u, &m_topology,
1835 								  &m_vertices, m_multisampleStateParams, m_blendState, m_renderType, m_imageBackingMode, m_depthClearValue);
1836 	result = renderer.render();
1837 
1838 	return verifyImage(result->getAccess());
1839 }
1840 
getMultisampleState(const VkSampleCountFlagBits rasterizationSamples)1841 VkPipelineMultisampleStateCreateInfo SampleMaskWithDepthTestInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples)
1842 {
1843 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1844 	{
1845 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1846 		DE_NULL,													// const void*								pNext;
1847 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1848 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1849 		false,														// VkBool32									sampleShadingEnable;
1850 		0.0f,														// float									minSampleShading;
1851 		DE_NULL,													// const VkSampleMask*						pSampleMask;
1852 		false,														// VkBool32									alphaToCoverageEnable;
1853 		false														// VkBool32									alphaToOneEnable;
1854 	};
1855 
1856 	return multisampleStateParams;
1857 }
1858 
generateVertices(void)1859 std::vector<Vertex4RGBA> SampleMaskWithDepthTestInstance::generateVertices (void)
1860 {
1861 	std::vector<Vertex4RGBA> vertices;
1862 
1863 	{
1864 		const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor };
1865 		vertices.push_back(vertexInput);
1866 	}
1867 	{
1868 		const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor };
1869 		vertices.push_back(vertexInput);
1870 	}
1871 	{
1872 		const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f,  1.0f, 1.0f, 1.0f), m_renderColor };
1873 		vertices.push_back(vertexInput);
1874 	}
1875 
1876 	return vertices;
1877 }
1878 
verifyImage(const tcu::ConstPixelBufferAccess & result)1879 tcu::TestStatus SampleMaskWithDepthTestInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
1880 {
1881 	bool			pass	= true;
1882 	const int		width	= result.getWidth();
1883 	const int		height	= result.getHeight();
1884 	tcu::TestLog&	log		= m_context.getTestContext().getLog();
1885 
1886 	DE_ASSERT(width == 3);
1887 	DE_ASSERT(height == 3);
1888 
1889 	const tcu::Vec4 clearColor = tcu::Vec4(0.0f);
1890 
1891 	for (int x = 0; x < width; ++x)
1892 	for (int y = 0; y < height; ++y)
1893 	{
1894 		const tcu::Vec4 resultPixel = result.getPixel(x, y);
1895 
1896 		if (x + y == 0)
1897 		{
1898 			if (resultPixel != m_renderColor)
1899 			{
1900 				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
1901 					<< " Reference: " << m_renderColor << tcu::TestLog::EndMessage;
1902 				pass = false;
1903 			}
1904 		}
1905 		else if (x + y == 1)
1906 		{
1907 			// default: m_rasterizationSamples bits set in FS's gl_SampleMaskIn[0] (before depth test)
1908 			// post_depth_coverage: m_refCoverageAfterDepthTest[m_rasterizationSamples] bits set in FS's gl_SampleMaskIn[0] (after depth test)
1909 			const float		threshold	= 0.02f;
1910 			const float		minCoverage	= (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples : 1.0f)
1911 										* ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples);
1912 			const float		maxCoverage	= (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples : 1.0f)
1913 										* ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples);
1914 
1915 			bool			localPass	= true;
1916 			for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx)
1917 			{
1918 				if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= m_renderColor[componentNdx] * (minCoverage - threshold)
1919 															|| resultPixel[componentNdx] >= m_renderColor[componentNdx] * (maxCoverage + threshold)))
1920 					localPass = false;
1921 			}
1922 
1923 			if (!localPass)
1924 			{
1925 				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
1926 					<< " Reference range ( " << m_renderColor * (minCoverage - threshold) << " ; " << m_renderColor * (maxCoverage + threshold) << " )" << tcu::TestLog::EndMessage;
1927 				pass = false;
1928 			}
1929 		}
1930 		else
1931 		{
1932 			if (resultPixel != clearColor)
1933 			{
1934 				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
1935 					<< " Reference: " << clearColor << tcu::TestLog::EndMessage;
1936 				pass = false;
1937 			}
1938 		}
1939 	}
1940 
1941 	if (pass)
1942 		return tcu::TestStatus::pass("Passed");
1943 	else
1944 		return tcu::TestStatus::fail("Failed");
1945 }
1946 
1947 // MultisampleRenderer
1948 
MultisampleRenderer(Context & context,const VkFormat colorFormat,const tcu::IVec2 & renderSize,const VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,const RenderType renderType,const ImageBackingMode backingMode)1949 MultisampleRenderer::MultisampleRenderer (Context&										context,
1950 										  const VkFormat								colorFormat,
1951 										  const tcu::IVec2&								renderSize,
1952 										  const VkPrimitiveTopology						topology,
1953 										  const std::vector<Vertex4RGBA>&				vertices,
1954 										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1955 										  const VkPipelineColorBlendAttachmentState&	blendState,
1956 										  const RenderType								renderType,
1957 										  const ImageBackingMode						backingMode)
1958 	: m_context					(context)
1959 	, m_bindSemaphore			(createSemaphore(context.getDeviceInterface(), context.getDevice()))
1960 	, m_colorFormat				(colorFormat)
1961 	, m_depthStencilFormat		(VK_FORMAT_UNDEFINED)
1962 	, m_renderSize				(renderSize)
1963 	, m_useDepth				(false)
1964 	, m_useStencil				(false)
1965 	, m_multisampleStateParams	(multisampleStateParams)
1966 	, m_colorBlendState			(blendState)
1967 	, m_renderType				(renderType)
1968 	, m_backingMode				(backingMode)
1969 	, m_depthClearValue			(1.0f)
1970 {
1971 	initialize(context, 1u, &topology, &vertices);
1972 }
1973 
MultisampleRenderer(Context & context,const VkFormat colorFormat,const VkFormat depthStencilFormat,const tcu::IVec2 & renderSize,const bool useDepth,const bool useStencil,const deUint32 numTopologies,const VkPrimitiveTopology * pTopology,const std::vector<Vertex4RGBA> * pVertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,const RenderType renderType,const ImageBackingMode backingMode,const float depthClearValue)1974 MultisampleRenderer::MultisampleRenderer (Context&										context,
1975 										  const VkFormat								colorFormat,
1976 										  const VkFormat								depthStencilFormat,
1977 										  const tcu::IVec2&								renderSize,
1978 										  const bool									useDepth,
1979 										  const bool									useStencil,
1980 										  const deUint32								numTopologies,
1981 										  const VkPrimitiveTopology*					pTopology,
1982 										  const std::vector<Vertex4RGBA>*				pVertices,
1983 										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1984 										  const VkPipelineColorBlendAttachmentState&	blendState,
1985 										  const RenderType								renderType,
1986 										  const ImageBackingMode						backingMode,
1987 										  const float									depthClearValue)
1988 	: m_context					(context)
1989 	, m_bindSemaphore			(createSemaphore(context.getDeviceInterface(), context.getDevice()))
1990 	, m_colorFormat				(colorFormat)
1991 	, m_depthStencilFormat		(depthStencilFormat)
1992 	, m_renderSize				(renderSize)
1993 	, m_useDepth				(useDepth)
1994 	, m_useStencil				(useStencil)
1995 	, m_multisampleStateParams	(multisampleStateParams)
1996 	, m_colorBlendState			(blendState)
1997 	, m_renderType				(renderType)
1998 	, m_backingMode				(backingMode)
1999 	, m_depthClearValue			(depthClearValue)
2000 {
2001 	initialize(context, numTopologies, pTopology, pVertices);
2002 }
2003 
initialize(Context & context,const deUint32 numTopologies,const VkPrimitiveTopology * pTopology,const std::vector<Vertex4RGBA> * pVertices)2004 void MultisampleRenderer::initialize (Context&									context,
2005 									  const deUint32							numTopologies,
2006 									  const VkPrimitiveTopology*				pTopology,
2007 									  const std::vector<Vertex4RGBA>*			pVertices)
2008 {
2009 	if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples))
2010 		throw tcu::NotSupportedError("Unsupported number of rasterization samples");
2011 
2012 	const DeviceInterface&		vk						= context.getDeviceInterface();
2013 	const VkDevice				vkDevice				= context.getDevice();
2014 	const deUint32				queueFamilyIndices[]	= { context.getUniversalQueueFamilyIndex(), context.getSparseQueueFamilyIndex() };
2015 	const bool					sparse					= m_backingMode == IMAGE_BACKING_MODE_SPARSE;
2016 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
2017 	const VkImageCreateFlags	imageCreateFlags		= sparse ? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0u;
2018 	const VkSharingMode			sharingMode				= (sparse && context.getUniversalQueueFamilyIndex() != context.getSparseQueueFamilyIndex()) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
2019 	Allocator&					memAlloc				= m_context.getDefaultAllocator();
2020 
2021 	if (sparse && !context.getDeviceFeatures().sparseBinding)
2022 		throw tcu::NotSupportedError("No sparseBinding support");
2023 
2024 	// Create color image
2025 	{
2026 		const VkImageUsageFlags	imageUsageFlags		= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2027 			(m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u);
2028 
2029 		const VkImageCreateInfo colorImageParams	=
2030 		{
2031 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
2032 			DE_NULL,																	// const void*				pNext;
2033 			imageCreateFlags,															// VkImageCreateFlags		flags;
2034 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
2035 			m_colorFormat,																// VkFormat					format;
2036 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },				// VkExtent3D				extent;
2037 			1u,																			// deUint32					mipLevels;
2038 			1u,																			// deUint32					arrayLayers;
2039 			m_multisampleStateParams.rasterizationSamples,								// VkSampleCountFlagBits	samples;
2040 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
2041 			imageUsageFlags,															// VkImageUsageFlags		usage;
2042 			sharingMode,																// VkSharingMode			sharingMode;
2043 			sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u,						// deUint32					queueFamilyIndexCount;
2044 			queueFamilyIndices,															// const deUint32*			pQueueFamilyIndices;
2045 			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
2046 		};
2047 
2048 		if (sparse && !checkSparseImageFormatSupport(context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams))
2049 			TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");
2050 
2051 		m_colorImage = createImage(vk, vkDevice, &colorImageParams);
2052 
2053 		// Allocate and bind color image memory
2054 		if (sparse)
2055 		{
2056 			allocateAndBindSparseImage(vk, vkDevice, context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams, *m_bindSemaphore, context.getSparseQueue(), memAlloc, m_allocations, mapVkFormat(m_colorFormat), *m_colorImage);
2057 		}
2058 		else
2059 		{
2060 			m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
2061 			VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
2062 		}
2063 	}
2064 
2065 	// Create resolve image
2066 	if (m_renderType == RENDER_TYPE_RESOLVE)
2067 	{
2068 		const VkImageCreateInfo resolveImageParams =
2069 		{
2070 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
2071 			DE_NULL,																		// const void*				pNext;
2072 			0u,																				// VkImageCreateFlags		flags;
2073 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
2074 			m_colorFormat,																	// VkFormat					format;
2075 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
2076 			1u,																				// deUint32					mipLevels;
2077 			1u,																				// deUint32					arrayLayers;
2078 			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
2079 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
2080 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |			// VkImageUsageFlags		usage;
2081 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2082 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
2083 			1u,																				// deUint32					queueFamilyIndexCount;
2084 			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
2085 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
2086 		};
2087 
2088 		m_resolveImage = createImage(vk, vkDevice, &resolveImageParams);
2089 
2090 		// Allocate and bind resolve image memory
2091 		m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any);
2092 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset()));
2093 
2094 		// Create resolve attachment view
2095 		{
2096 			const VkImageViewCreateInfo resolveAttachmentViewParams =
2097 			{
2098 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
2099 				DE_NULL,										// const void*				pNext;
2100 				0u,												// VkImageViewCreateFlags	flags;
2101 				*m_resolveImage,								// VkImage					image;
2102 				VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
2103 				m_colorFormat,									// VkFormat					format;
2104 				componentMappingRGBA,							// VkComponentMapping		components;
2105 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2106 			};
2107 
2108 			m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
2109 		}
2110 	}
2111 
2112 	// Create per-sample output images
2113 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2114 	{
2115 		const VkImageCreateInfo perSampleImageParams =
2116 		{
2117 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
2118 			DE_NULL,																		// const void*				pNext;
2119 			0u,																				// VkImageCreateFlags		flags;
2120 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
2121 			m_colorFormat,																	// VkFormat					format;
2122 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
2123 			1u,																				// deUint32					mipLevels;
2124 			1u,																				// deUint32					arrayLayers;
2125 			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
2126 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
2127 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |			// VkImageUsageFlags		usage;
2128 			VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2129 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
2130 			1u,																				// deUint32					queueFamilyIndexCount;
2131 			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
2132 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
2133 		};
2134 
2135 		m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples));
2136 
2137 		for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2138 		{
2139 			m_perSampleImages[i]	= de::SharedPtr<PerSampleImage>(new PerSampleImage);
2140 			PerSampleImage& image	= *m_perSampleImages[i];
2141 
2142 			image.m_image			= createImage(vk, vkDevice, &perSampleImageParams);
2143 
2144 			// Allocate and bind image memory
2145 			image.m_imageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any);
2146 			VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset()));
2147 
2148 			// Create per-sample attachment view
2149 			{
2150 				const VkImageViewCreateInfo perSampleAttachmentViewParams =
2151 				{
2152 					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
2153 					DE_NULL,										// const void*				pNext;
2154 					0u,												// VkImageViewCreateFlags	flags;
2155 					*image.m_image,									// VkImage					image;
2156 					VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
2157 					m_colorFormat,									// VkFormat					format;
2158 					componentMappingRGBA,							// VkComponentMapping		components;
2159 					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2160 				};
2161 
2162 				image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams);
2163 			}
2164 		}
2165 	}
2166 
2167 	// Create a depth/stencil image
2168 	if (m_useDepth || m_useStencil)
2169 	{
2170 		const VkImageCreateInfo depthStencilImageParams =
2171 		{
2172 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
2173 			DE_NULL,																		// const void*				pNext;
2174 			0u,																				// VkImageCreateFlags		flags;
2175 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
2176 			m_depthStencilFormat,															// VkFormat					format;
2177 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
2178 			1u,																				// deUint32					mipLevels;
2179 			1u,																				// deUint32					arrayLayers;
2180 			m_multisampleStateParams.rasterizationSamples,									// VkSampleCountFlagBits	samples;
2181 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
2182 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,									// VkImageUsageFlags		usage;
2183 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
2184 			1u,																				// deUint32					queueFamilyIndexCount;
2185 			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
2186 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
2187 		};
2188 
2189 		m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams);
2190 
2191 		// Allocate and bind depth/stencil image memory
2192 		m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any);
2193 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset()));
2194 	}
2195 
2196 	// Create color attachment view
2197 	{
2198 		const VkImageViewCreateInfo colorAttachmentViewParams =
2199 		{
2200 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
2201 			DE_NULL,										// const void*				pNext;
2202 			0u,												// VkImageViewCreateFlags	flags;
2203 			*m_colorImage,									// VkImage					image;
2204 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
2205 			m_colorFormat,									// VkFormat					format;
2206 			componentMappingRGBA,							// VkComponentMapping		components;
2207 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2208 		};
2209 
2210 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
2211 	}
2212 
2213 	VkImageAspectFlags	depthStencilAttachmentAspect	= (VkImageAspectFlagBits)0;
2214 
2215 	// Create depth/stencil attachment view
2216 	if (m_useDepth || m_useStencil)
2217 	{
2218 		depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat);
2219 
2220 		const VkImageViewCreateInfo depthStencilAttachmentViewParams =
2221 		{
2222 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
2223 			DE_NULL,											// const void*				pNext;
2224 			0u,													// VkImageViewCreateFlags	flags;
2225 			*m_depthStencilImage,								// VkImage					image;
2226 			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
2227 			m_depthStencilFormat,								// VkFormat					format;
2228 			componentMappingRGBA,								// VkComponentMapping		components;
2229 			{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2230 		};
2231 
2232 		m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
2233 	}
2234 
2235 	// Create render pass
2236 	{
2237 		std::vector<VkAttachmentDescription> attachmentDescriptions;
2238 		{
2239 			const VkAttachmentDescription colorAttachmentDescription =
2240 			{
2241 				0u,													// VkAttachmentDescriptionFlags		flags;
2242 				m_colorFormat,										// VkFormat							format;
2243 				m_multisampleStateParams.rasterizationSamples,		// VkSampleCountFlagBits			samples;
2244 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
2245 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
2246 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
2247 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
2248 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
2249 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
2250 			};
2251 			attachmentDescriptions.push_back(colorAttachmentDescription);
2252 		}
2253 
2254 		deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED;
2255 
2256 		if (m_renderType == RENDER_TYPE_RESOLVE)
2257 		{
2258 			resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2259 
2260 			const VkAttachmentDescription resolveAttachmentDescription =
2261 			{
2262 				0u,													// VkAttachmentDescriptionFlags		flags;
2263 				m_colorFormat,										// VkFormat							format;
2264 				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
2265 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
2266 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
2267 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
2268 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
2269 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
2270 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
2271 			};
2272 			attachmentDescriptions.push_back(resolveAttachmentDescription);
2273 		}
2274 
2275 		deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED;
2276 
2277 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2278 		{
2279 			perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2280 
2281 			const VkAttachmentDescription perSampleAttachmentDescription =
2282 			{
2283 				0u,													// VkAttachmentDescriptionFlags		flags;
2284 				m_colorFormat,										// VkFormat							format;
2285 				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
2286 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
2287 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
2288 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
2289 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
2290 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
2291 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
2292 			};
2293 
2294 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2295 			{
2296 				attachmentDescriptions.push_back(perSampleAttachmentDescription);
2297 			}
2298 		}
2299 
2300 		deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
2301 
2302 		if (m_useDepth || m_useStencil)
2303 		{
2304 			depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2305 
2306 			const VkAttachmentDescription depthStencilAttachmentDescription =
2307 			{
2308 				0u,																					// VkAttachmentDescriptionFlags		flags;
2309 				m_depthStencilFormat,																// VkFormat							format;
2310 				m_multisampleStateParams.rasterizationSamples,										// VkSampleCountFlagBits			samples;
2311 				(m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentLoadOp				loadOp;
2312 				(m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),		// VkAttachmentStoreOp				storeOp;
2313 				(m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentStoreOp				stencilLoadOp;
2314 				(m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),	// VkAttachmentStoreOp				stencilStoreOp;
2315 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,									// VkImageLayout					initialLayout;
2316 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL									// VkImageLayout					finalLayout;
2317 			};
2318 			attachmentDescriptions.push_back(depthStencilAttachmentDescription);
2319 		};
2320 
2321 		const VkAttachmentReference colorAttachmentReference =
2322 		{
2323 			0u,													// deUint32			attachment;
2324 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
2325 		};
2326 
2327 		const VkAttachmentReference inputAttachmentReference =
2328 		{
2329 			0u,													// deUint32			attachment;
2330 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL			// VkImageLayout	layout;
2331 		};
2332 
2333 		const VkAttachmentReference resolveAttachmentReference =
2334 		{
2335 			resolveAttachmentIndex,								// deUint32			attachment;
2336 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
2337 		};
2338 
2339 		std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size());
2340 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2341 		{
2342 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2343 			{
2344 				const VkAttachmentReference perSampleAttachmentReference =
2345 				{
2346 					perSampleAttachmentIndex + static_cast<deUint32>(i),	// deUint32			attachment;
2347 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL				// VkImageLayout	layout;
2348 				};
2349 				perSampleAttachmentReferences[i] = perSampleAttachmentReference;
2350 			}
2351 		}
2352 
2353 		const VkAttachmentReference depthStencilAttachmentReference =
2354 		{
2355 			depthStencilAttachmentIndex,						// deUint32			attachment;
2356 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
2357 		};
2358 
2359 		std::vector<VkSubpassDescription>	subpassDescriptions;
2360 		std::vector<VkSubpassDependency>	subpassDependencies;
2361 
2362 		{
2363 			const VkSubpassDescription renderSubpassDescription =
2364 			{
2365 				0u,																				// VkSubpassDescriptionFlags	flags;
2366 				VK_PIPELINE_BIND_POINT_GRAPHICS,												// VkPipelineBindPoint			pipelineBindPoint;
2367 				0u,																				// deUint32						inputAttachmentCount;
2368 				DE_NULL,																		// const VkAttachmentReference*	pInputAttachments;
2369 				1u,																				// deUint32						colorAttachmentCount;
2370 				&colorAttachmentReference,														// const VkAttachmentReference*	pColorAttachments;
2371 				(m_renderType == RENDER_TYPE_RESOLVE) ? &resolveAttachmentReference : DE_NULL,	// const VkAttachmentReference*	pResolveAttachments;
2372 				(m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL),		// const VkAttachmentReference*	pDepthStencilAttachment;
2373 				0u,																				// deUint32						preserveAttachmentCount;
2374 				DE_NULL																			// const VkAttachmentReference*	pPreserveAttachments;
2375 			};
2376 			subpassDescriptions.push_back(renderSubpassDescription);
2377 		}
2378 
2379 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2380 		{
2381 
2382 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2383 			{
2384 				const VkSubpassDescription copySampleSubpassDescription =
2385 				{
2386 					0u,													// VkSubpassDescriptionFlags		flags;
2387 					VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
2388 					1u,													// deUint32							inputAttachmentCount;
2389 					&inputAttachmentReference,							// const VkAttachmentReference*		pInputAttachments;
2390 					1u,													// deUint32							colorAttachmentCount;
2391 					&perSampleAttachmentReferences[i],					// const VkAttachmentReference*		pColorAttachments;
2392 					DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
2393 					DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
2394 					0u,													// deUint32							preserveAttachmentCount;
2395 					DE_NULL												// const VkAttachmentReference*		pPreserveAttachments;
2396 				};
2397 				subpassDescriptions.push_back(copySampleSubpassDescription);
2398 
2399 				const VkSubpassDependency copySampleSubpassDependency =
2400 				{
2401 					0u,													// deUint32							srcSubpass
2402 					1u + static_cast<deUint32>(i),						// deUint32							dstSubpass
2403 					VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,		// VkPipelineStageFlags				srcStageMask
2404 					VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,				// VkPipelineStageFlags				dstStageMask
2405 					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags					srcAccessMask
2406 					VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,				// VkAccessFlags					dstAccessMask
2407 					0u,													// VkDependencyFlags				dependencyFlags
2408 				};
2409 				subpassDependencies.push_back(copySampleSubpassDependency);
2410 			}
2411 		}
2412 
2413 		const VkRenderPassCreateInfo renderPassParams =
2414 		{
2415 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,					// VkStructureType					sType;
2416 			DE_NULL,													// const void*						pNext;
2417 			0u,															// VkRenderPassCreateFlags			flags;
2418 			(deUint32)attachmentDescriptions.size(),					// deUint32							attachmentCount;
2419 			&attachmentDescriptions[0],									// const VkAttachmentDescription*	pAttachments;
2420 			(deUint32)subpassDescriptions.size(),						// deUint32							subpassCount;
2421 			&subpassDescriptions[0],									// const VkSubpassDescription*		pSubpasses;
2422 			(deUint32)subpassDependencies.size(),						// deUint32							dependencyCount;
2423 			subpassDependencies.size() != 0 ? &subpassDependencies[0] : DE_NULL
2424 		};
2425 
2426 		m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2427 	}
2428 
2429 	// Create framebuffer
2430 	{
2431 		std::vector<VkImageView> attachments;
2432 		attachments.push_back(*m_colorAttachmentView);
2433 		if (m_renderType == RENDER_TYPE_RESOLVE)
2434 		{
2435 			attachments.push_back(*m_resolveAttachmentView);
2436 		}
2437 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2438 		{
2439 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2440 			{
2441 				attachments.push_back(*m_perSampleImages[i]->m_attachmentView);
2442 			}
2443 		}
2444 
2445 		if (m_useDepth || m_useStencil)
2446 		{
2447 			attachments.push_back(*m_depthStencilAttachmentView);
2448 		}
2449 
2450 		const VkFramebufferCreateInfo framebufferParams =
2451 		{
2452 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType					sType;
2453 			DE_NULL,											// const void*						pNext;
2454 			0u,													// VkFramebufferCreateFlags			flags;
2455 			*m_renderPass,										// VkRenderPass						renderPass;
2456 			(deUint32)attachments.size(),						// deUint32							attachmentCount;
2457 			&attachments[0],									// const VkImageView*				pAttachments;
2458 			(deUint32)m_renderSize.x(),							// deUint32							width;
2459 			(deUint32)m_renderSize.y(),							// deUint32							height;
2460 			1u													// deUint32							layers;
2461 		};
2462 
2463 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2464 	}
2465 
2466 	// Create pipeline layout
2467 	{
2468 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2469 		{
2470 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
2471 			DE_NULL,											// const void*						pNext;
2472 			0u,													// VkPipelineLayoutCreateFlags		flags;
2473 			0u,													// deUint32							setLayoutCount;
2474 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
2475 			0u,													// deUint32							pushConstantRangeCount;
2476 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
2477 		};
2478 
2479 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2480 
2481 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2482 		{
2483 
2484 			// Create descriptor set layout
2485 			const VkDescriptorSetLayoutBinding		layoutBinding					=
2486 			{
2487 				0u,															// deUint32								binding;
2488 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,						// VkDescriptorType						descriptorType;
2489 				1u,															// deUint32								descriptorCount;
2490 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlags					stageFlags;
2491 				DE_NULL,													// const VkSampler*						pImmutableSamplers;
2492 			};
2493 
2494 			const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutParams		=
2495 			{
2496 				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType
2497 				DE_NULL,													// const void*							pNext
2498 				0u,															// VkDescriptorSetLayoutCreateFlags		flags
2499 				1u,															// deUint32								bindingCount
2500 				&layoutBinding												// const VkDescriptorSetLayoutBinding*	pBindings
2501 			};
2502 			m_copySampleDesciptorLayout	= createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
2503 
2504 			// Create pipeline layout
2505 
2506 			const VkPushConstantRange				pushConstantRange				=
2507 			{
2508 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlags					stageFlags;
2509 				0u,															// deUint32								offset;
2510 				sizeof(deInt32)												// deUint32								size;
2511 			};
2512 			const VkPipelineLayoutCreateInfo		copySamplePipelineLayoutParams	=
2513 			{
2514 				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// VkStructureType						sType;
2515 				DE_NULL,													// const void*							pNext;
2516 				0u,															// VkPipelineLayoutCreateFlags			flags;
2517 				1u,															// deUint32								setLayoutCount;
2518 				&m_copySampleDesciptorLayout.get(),							// const VkDescriptorSetLayout*			pSetLayouts;
2519 				1u,															// deUint32								pushConstantRangeCount;
2520 				&pushConstantRange											// const VkPushConstantRange*			pPushConstantRanges;
2521 			};
2522 			m_copySamplePipelineLayout		= createPipelineLayout(vk, vkDevice, &copySamplePipelineLayoutParams);
2523 		}
2524 	}
2525 
2526 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
2527 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
2528 
2529 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2530 	{
2531 		m_copySampleVertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("quad_vert"), 0);
2532 		m_copySampleFragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("copy_sample_frag"), 0);
2533 	}
2534 
2535 	// Create pipeline
2536 	{
2537 		const VkVertexInputBindingDescription	vertexInputBindingDescription =
2538 		{
2539 			0u,									// deUint32				binding;
2540 			sizeof(Vertex4RGBA),				// deUint32				stride;
2541 			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputRate	inputRate;
2542 		};
2543 
2544 		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
2545 		{
2546 			{
2547 				0u,									// deUint32	location;
2548 				0u,									// deUint32	binding;
2549 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
2550 				0u									// deUint32	offset;
2551 			},
2552 			{
2553 				1u,									// deUint32	location;
2554 				0u,									// deUint32	binding;
2555 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
2556 				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
2557 			}
2558 		};
2559 
2560 		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2561 		{
2562 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
2563 			DE_NULL,														// const void*								pNext;
2564 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
2565 			1u,																// deUint32									vertexBindingDescriptionCount;
2566 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
2567 			2u,																// deUint32									vertexAttributeDescriptionCount;
2568 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
2569 		};
2570 
2571 		const std::vector<VkViewport>	viewports	(1, makeViewport(m_renderSize));
2572 		const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_renderSize));
2573 
2574 		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2575 		{
2576 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
2577 			DE_NULL,													// const void*									pNext;
2578 			0u,															// VkPipelineColorBlendStateCreateFlags			flags;
2579 			false,														// VkBool32										logicOpEnable;
2580 			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
2581 			1u,															// deUint32										attachmentCount;
2582 			&m_colorBlendState,											// const VkPipelineColorBlendAttachmentState*	pAttachments;
2583 			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
2584 		};
2585 
2586 		const VkStencilOpState stencilOpState =
2587 		{
2588 			VK_STENCIL_OP_KEEP,						// VkStencilOp	failOp;
2589 			VK_STENCIL_OP_REPLACE,					// VkStencilOp	passOp;
2590 			VK_STENCIL_OP_KEEP,						// VkStencilOp	depthFailOp;
2591 			VK_COMPARE_OP_GREATER,					// VkCompareOp	compareOp;
2592 			1u,										// deUint32		compareMask;
2593 			1u,										// deUint32		writeMask;
2594 			1u,										// deUint32		reference;
2595 		};
2596 
2597 		const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
2598 		{
2599 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
2600 			DE_NULL,													// const void*								pNext;
2601 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
2602 			m_useDepth,													// VkBool32									depthTestEnable;
2603 			m_useDepth,													// VkBool32									depthWriteEnable;
2604 			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
2605 			false,														// VkBool32									depthBoundsTestEnable;
2606 			m_useStencil,												// VkBool32									stencilTestEnable;
2607 			stencilOpState,												// VkStencilOpState	front;
2608 			stencilOpState,												// VkStencilOpState	back;
2609 			0.0f,														// float			minDepthBounds;
2610 			1.0f,														// float			maxDepthBounds;
2611 		};
2612 
2613 		for (deUint32 i = 0u; i < numTopologies; ++i)
2614 		{
2615 			m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(vk,							// const DeviceInterface&                        vk
2616 																								   vkDevice,					// const VkDevice                                device
2617 																								   *m_pipelineLayout,			// const VkPipelineLayout                        pipelineLayout
2618 																								   *m_vertexShaderModule,		// const VkShaderModule                          vertexShaderModule
2619 																								   DE_NULL,						// const VkShaderModule                          tessellationControlModule
2620 																								   DE_NULL,						// const VkShaderModule                          tessellationEvalModule
2621 																								   DE_NULL,						// const VkShaderModule                          geometryShaderModule
2622 																								   *m_fragmentShaderModule,		// const VkShaderModule                          fragmentShaderModule
2623 																								   *m_renderPass,				// const VkRenderPass                            renderPass
2624 																								   viewports,					// const std::vector<VkViewport>&                viewports
2625 																								   scissors,					// const std::vector<VkRect2D>&                  scissors
2626 																								   pTopology[i],				// const VkPrimitiveTopology                     topology
2627 																								   0u,							// const deUint32                                subpass
2628 																								   0u,							// const deUint32                                patchControlPoints
2629 																								   &vertexInputStateParams,		// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
2630 																								   DE_NULL,						// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
2631 																								   &m_multisampleStateParams,	// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
2632 																								   &depthStencilStateParams,	// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
2633 																								   &colorBlendStateParams))));	// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
2634 		}
2635 	}
2636 
2637 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2638 	{
2639 		// Create pipelines for copying samples to single sampled images
2640 		{
2641 			const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2642 			{
2643 				VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
2644 				DE_NULL,														// const void*								pNext;
2645 				0u,																// VkPipelineVertexInputStateCreateFlags	flags;
2646 				0u,																// deUint32									vertexBindingDescriptionCount;
2647 				DE_NULL,														// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
2648 				0u,																// deUint32									vertexAttributeDescriptionCount;
2649 				DE_NULL															// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
2650 			};
2651 
2652 			const std::vector<VkViewport>	viewports	(1, makeViewport(m_renderSize));
2653 			const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_renderSize));
2654 
2655 			const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2656 			{
2657 				VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
2658 				DE_NULL,													// const void*									pNext;
2659 				0u,															// VkPipelineColorBlendStateCreateFlags			flags;
2660 				false,														// VkBool32										logicOpEnable;
2661 				VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
2662 				1u,															// deUint32										attachmentCount;
2663 				&m_colorBlendState,											// const VkPipelineColorBlendAttachmentState*	pAttachments;
2664 				{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
2665 			};
2666 
2667 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2668 			{
2669 				// Pipeline is to be used in subpasses subsequent to sample-shading subpass
2670 				m_copySamplePipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
2671 																										 vkDevice,								// const VkDevice                                device
2672 																										 *m_copySamplePipelineLayout,			// const VkPipelineLayout                        pipelineLayout
2673 																										 *m_copySampleVertexShaderModule,		// const VkShaderModule                          vertexShaderModule
2674 																										 DE_NULL,								// const VkShaderModule                          tessellationControlModule
2675 																										 DE_NULL,								// const VkShaderModule                          tessellationEvalModule
2676 																										 DE_NULL,								// const VkShaderModule                          geometryShaderModule
2677 																										 *m_copySampleFragmentShaderModule,		// const VkShaderModule                          fragmentShaderModule
2678 																										 *m_renderPass,							// const VkRenderPass                            renderPass
2679 																										 viewports,								// const std::vector<VkViewport>&                viewports
2680 																										 scissors,								// const std::vector<VkRect2D>&                  scissors
2681 																										 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// const VkPrimitiveTopology                     topology
2682 																										 1u + (deUint32)i,						// const deUint32                                subpass
2683 																										 0u,									// const deUint32                                patchControlPoints
2684 																										 &vertexInputStateParams,				// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
2685 																										 DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
2686 																										 DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
2687 																										 DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
2688 																										 &colorBlendStateParams))));			// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
2689 			}
2690 		}
2691 
2692 
2693 		const VkDescriptorPoolSize			descriptorPoolSize			=
2694 		{
2695 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,					// VkDescriptorType					type;
2696 			1u														// deUint32							descriptorCount;
2697 		};
2698 
2699 		const VkDescriptorPoolCreateInfo	descriptorPoolCreateInfo	=
2700 		{
2701 			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,			// VkStructureType					sType
2702 			DE_NULL,												// const void*						pNext
2703 			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,		// VkDescriptorPoolCreateFlags		flags
2704 			1u,													// deUint32							maxSets
2705 			1u,														// deUint32							poolSizeCount
2706 			&descriptorPoolSize										// const VkDescriptorPoolSize*		pPoolSizes
2707 		};
2708 
2709 		m_copySampleDesciptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
2710 
2711 		const VkDescriptorSetAllocateInfo	descriptorSetAllocateInfo	=
2712 		{
2713 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,			// VkStructureType					sType
2714 			DE_NULL,												// const void*						pNext
2715 			*m_copySampleDesciptorPool,								// VkDescriptorPool					descriptorPool
2716 			1u,														// deUint32							descriptorSetCount
2717 			&m_copySampleDesciptorLayout.get(),						// const VkDescriptorSetLayout*		pSetLayouts
2718 		};
2719 
2720 		m_copySampleDesciptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
2721 
2722 		const VkDescriptorImageInfo			imageInfo					=
2723 		{
2724 			DE_NULL,
2725 			*m_colorAttachmentView,
2726 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
2727 		};
2728 		const VkWriteDescriptorSet			descriptorWrite				=
2729 		{
2730 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// VkStructureType					sType;
2731 			DE_NULL,										// const void*						pNext;
2732 			*m_copySampleDesciptorSet,						// VkDescriptorSet					dstSet;
2733 			0u,												// deUint32							dstBinding;
2734 			0u,												// deUint32							dstArrayElement;
2735 			1u,												// deUint32							descriptorCount;
2736 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			// VkDescriptorType					descriptorType;
2737 			&imageInfo,										// const VkDescriptorImageInfo*		pImageInfo;
2738 			DE_NULL,										// const VkDescriptorBufferInfo*	pBufferInfo;
2739 			DE_NULL,										// const VkBufferView*				pTexelBufferView;
2740 		};
2741 		vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
2742 	}
2743 
2744 	// Create vertex buffer
2745 	{
2746 		const VkBufferCreateInfo vertexBufferParams =
2747 		{
2748 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2749 			DE_NULL,									// const void*			pNext;
2750 			0u,											// VkBufferCreateFlags	flags;
2751 			1024u,										// VkDeviceSize			size;
2752 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
2753 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2754 			1u,											// deUint32				queueFamilyIndexCount;
2755 			&queueFamilyIndices[0]						// const deUint32*		pQueueFamilyIndices;
2756 		};
2757 
2758 		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
2759 		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
2760 
2761 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
2762 
2763 		// Load vertices into vertex buffer
2764 		{
2765 			Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr());
2766 			for (deUint32 i = 0u; i < numTopologies; ++i)
2767 			{
2768 				deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA));
2769 				pDst += pVertices[i].size();
2770 			}
2771 		}
2772 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
2773 	}
2774 
2775 	// Create command pool
2776 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndices[0]);
2777 
2778 	// Create command buffer
2779 	{
2780 		VkClearValue colorClearValue;
2781 		colorClearValue.color.float32[0] = 0.0f;
2782 		colorClearValue.color.float32[1] = 0.0f;
2783 		colorClearValue.color.float32[2] = 0.0f;
2784 		colorClearValue.color.float32[3] = 0.0f;
2785 
2786 		VkClearValue depthStencilClearValue;
2787 		depthStencilClearValue.depthStencil.depth = m_depthClearValue;
2788 		depthStencilClearValue.depthStencil.stencil = 0u;
2789 
2790 		std::vector<VkClearValue> clearValues;
2791 		clearValues.push_back(colorClearValue);
2792 		if (m_renderType == RENDER_TYPE_RESOLVE)
2793 		{
2794 			clearValues.push_back(colorClearValue);
2795 		}
2796 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2797 		{
2798 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2799 			{
2800 				clearValues.push_back(colorClearValue);
2801 			}
2802 		}
2803 		if (m_useDepth || m_useStencil)
2804 		{
2805 			clearValues.push_back(depthStencilClearValue);
2806 		}
2807 
2808 		vk::VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
2809 		std::vector<VkImageMemoryBarrier> imageLayoutBarriers;
2810 
2811 		{
2812 			const VkImageMemoryBarrier colorImageBarrier =
2813 				// color attachment image
2814 			{
2815 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
2816 				DE_NULL,										// const void*				pNext;
2817 				0u,												// VkAccessFlags			srcAccessMask;
2818 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
2819 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
2820 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
2821 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
2822 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
2823 				*m_colorImage,									// VkImage					image;
2824 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
2825 			};
2826 			imageLayoutBarriers.push_back(colorImageBarrier);
2827 		}
2828 		if (m_renderType == RENDER_TYPE_RESOLVE)
2829 		{
2830 			const VkImageMemoryBarrier resolveImageBarrier =
2831 			// resolve attachment image
2832 			{
2833 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
2834 				DE_NULL,										// const void*				pNext;
2835 				0u,												// VkAccessFlags			srcAccessMask;
2836 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
2837 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
2838 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
2839 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
2840 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
2841 				*m_resolveImage,								// VkImage					image;
2842 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
2843 			};
2844 			imageLayoutBarriers.push_back(resolveImageBarrier);
2845 		}
2846 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2847 		{
2848 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2849 			{
2850 				const VkImageMemoryBarrier perSampleImageBarrier =
2851 				// resolve attachment image
2852 				{
2853 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
2854 					DE_NULL,										// const void*				pNext;
2855 					0u,												// VkAccessFlags			srcAccessMask;
2856 					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
2857 					VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
2858 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
2859 					VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
2860 					VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
2861 					*m_perSampleImages[i]->m_image,					// VkImage					image;
2862 					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
2863 				};
2864 				imageLayoutBarriers.push_back(perSampleImageBarrier);
2865 			}
2866 		}
2867 		if (m_useDepth || m_useStencil)
2868 		{
2869 			const VkImageMemoryBarrier depthStencilImageBarrier =
2870 			// depth/stencil attachment image
2871 			{
2872 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
2873 				DE_NULL,											// const void*				pNext;
2874 				0u,													// VkAccessFlags			srcAccessMask;
2875 				VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
2876 				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
2877 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
2878 				VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
2879 				VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
2880 				*m_depthStencilImage,								// VkImage					image;
2881 				{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
2882 			};
2883 			imageLayoutBarriers.push_back(depthStencilImageBarrier);
2884 			dstStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
2885 		};
2886 
2887 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2888 
2889 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
2890 
2891 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask, (VkDependencyFlags)0,
2892 			0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), &imageLayoutBarriers[0]);
2893 
2894 		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)clearValues.size(), &clearValues[0]);
2895 
2896 		VkDeviceSize vertexBufferOffset = 0u;
2897 
2898 		for (deUint32 i = 0u; i < numTopologies; ++i)
2899 		{
2900 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[i]);
2901 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
2902 			vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0);
2903 
2904 			vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA));
2905 		}
2906 
2907 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2908 		{
2909 			// Copy each sample id to single sampled image
2910 			for (deInt32 sampleId = 0; sampleId < (deInt32)m_perSampleImages.size(); ++sampleId)
2911 			{
2912 				vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
2913 				vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_copySamplePipelines[sampleId]);
2914 				vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_copySamplePipelineLayout, 0u, 1u, &m_copySampleDesciptorSet.get(), 0u, DE_NULL);
2915 				vk.cmdPushConstants(*m_cmdBuffer, *m_copySamplePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &sampleId);
2916 				vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
2917 			}
2918 		}
2919 
2920 		endRenderPass(vk, *m_cmdBuffer);
2921 
2922 		endCommandBuffer(vk, *m_cmdBuffer);
2923 	}
2924 }
2925 
~MultisampleRenderer(void)2926 MultisampleRenderer::~MultisampleRenderer (void)
2927 {
2928 }
2929 
render(void)2930 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void)
2931 {
2932 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
2933 	const VkDevice				vkDevice			= m_context.getDevice();
2934 	const VkQueue				queue				= m_context.getUniversalQueue();
2935 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
2936 
2937 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
2938 
2939 	if (m_renderType == RENDER_TYPE_RESOLVE)
2940 	{
2941 		return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
2942 	}
2943 	else
2944 	{
2945 		return de::MovePtr<tcu::TextureLevel>();
2946 	}
2947 }
2948 
getSingleSampledImage(deUint32 sampleId)2949 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::getSingleSampledImage (deUint32 sampleId)
2950 {
2951 	return readColorAttachment(m_context.getDeviceInterface(), m_context.getDevice(), m_context.getUniversalQueue(), m_context.getUniversalQueueFamilyIndex(), m_context.getDefaultAllocator(), *m_perSampleImages[sampleId]->m_image, m_colorFormat, m_renderSize.cast<deUint32>());
2952 }
2953 
2954 } // anonymous
2955 
createMultisampleTests(tcu::TestContext & testCtx)2956 tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx)
2957 {
2958 	const VkSampleCountFlagBits samples[] =
2959 	{
2960 		VK_SAMPLE_COUNT_2_BIT,
2961 		VK_SAMPLE_COUNT_4_BIT,
2962 		VK_SAMPLE_COUNT_8_BIT,
2963 		VK_SAMPLE_COUNT_16_BIT,
2964 		VK_SAMPLE_COUNT_32_BIT,
2965 		VK_SAMPLE_COUNT_64_BIT
2966 	};
2967 
2968 	de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, "multisample", ""));
2969 
2970 	// Rasterization samples tests
2971 	{
2972 		de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", ""));
2973 
2974 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2975 		{
2976 			std::ostringstream caseName;
2977 			caseName << "samples_" << samples[samplesNdx];
2978 
2979 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
2980 
2981 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
2982 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
2983 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
2984 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
2985 
2986 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT));
2987 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_STENCIL_BIT));
2988 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil", "",	samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT));
2989 
2990 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle_sparse", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
2991 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line_sparse", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
2992 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px_sparse", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
2993 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_sparse", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
2994 
2995 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_sparse", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT));
2996 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil_sparse", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_STENCIL_BIT));
2997 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil_sparse", "",	samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT));
2998 
2999 			rasterizationSamplesTests->addChild(samplesTests.release());
3000 		}
3001 
3002 		multisampleTests->addChild(rasterizationSamplesTests.release());
3003 	}
3004 
3005 	// Raster samples consistency check
3006 	{
3007 		de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests	(new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", ""));
3008 		MultisampleTestParams			paramsRegular					= {GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR};
3009 		MultisampleTestParams			paramsSparse					= {GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE};
3010 
3011 		addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
3012 									"unique_colors_check",
3013 									"",
3014 									initMultisamplePrograms,
3015 									testRasterSamplesConsistency,
3016 									paramsRegular);
3017 
3018 		addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
3019 									"unique_colors_check_sparse",
3020 									"",
3021 									initMultisamplePrograms,
3022 									testRasterSamplesConsistency,
3023 									paramsSparse);
3024 
3025 		multisampleTests->addChild(rasterSamplesConsistencyTests.release());
3026 	}
3027 
3028 	// minSampleShading tests
3029 	{
3030 		struct TestConfig
3031 		{
3032 			const char*	name;
3033 			float		minSampleShading;
3034 		};
3035 
3036 		const TestConfig testConfigs[] =
3037 		{
3038 			{ "min_0_0",	0.0f },
3039 			{ "min_0_25",	0.25f },
3040 			{ "min_0_5",	0.5f },
3041 			{ "min_0_75",	0.75f },
3042 			{ "min_1_0",	1.0f }
3043 		};
3044 
3045 		de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", ""));
3046 
3047 		for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
3048 		{
3049 			const TestConfig&				testConfig				= testConfigs[configNdx];
3050 			de::MovePtr<tcu::TestCaseGroup>	minShadingValueTests	(new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
3051 
3052 			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
3053 			{
3054 				std::ostringstream caseName;
3055 				caseName << "samples_" << samples[samplesNdx];
3056 
3057 				de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
3058 
3059 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
3060 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
3061 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
3062 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
3063 
3064 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
3065 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
3066 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
3067 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
3068 
3069 				minShadingValueTests->addChild(samplesTests.release());
3070 			}
3071 
3072 			minSampleShadingTests->addChild(minShadingValueTests.release());
3073 		}
3074 
3075 		multisampleTests->addChild(minSampleShadingTests.release());
3076 	}
3077 
3078 	// SampleMask tests
3079 	{
3080 		struct TestConfig
3081 		{
3082 			const char*		name;
3083 			const char*		description;
3084 			VkSampleMask	sampleMask;
3085 		};
3086 
3087 		const TestConfig testConfigs[] =
3088 		{
3089 			{ "mask_all_on",	"All mask bits are off",			0x0 },
3090 			{ "mask_all_off",	"All mask bits are on",				0xFFFFFFFF },
3091 			{ "mask_one",		"All mask elements are 0x1",		0x1},
3092 			{ "mask_random",	"All mask elements are 0xAAAAAAAA",	0xAAAAAAAA },
3093 		};
3094 
3095 		de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", ""));
3096 
3097 		for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
3098 		{
3099 			const TestConfig&				testConfig				= testConfigs[configNdx];
3100 			de::MovePtr<tcu::TestCaseGroup>	sampleMaskValueTests	(new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description));
3101 
3102 			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
3103 			{
3104 				std::ostringstream caseName;
3105 				caseName << "samples_" << samples[samplesNdx];
3106 
3107 				const deUint32					sampleMaskCount	= samples[samplesNdx] / 32;
3108 				de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
3109 
3110 				std::vector<VkSampleMask> mask;
3111 				for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++)
3112 					mask.push_back(testConfig.sampleMask);
3113 
3114 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
3115 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
3116 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
3117 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
3118 
3119 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
3120 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
3121 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
3122 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
3123 
3124 				sampleMaskValueTests->addChild(samplesTests.release());
3125 			}
3126 
3127 			sampleMaskTests->addChild(sampleMaskValueTests.release());
3128 		}
3129 
3130 		multisampleTests->addChild(sampleMaskTests.release());
3131 
3132 	}
3133 
3134 	// AlphaToOne tests
3135 	{
3136 		de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", ""));
3137 
3138 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
3139 		{
3140 			std::ostringstream caseName;
3141 			caseName << "samples_" << samples[samplesNdx];
3142 
3143 			alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx], IMAGE_BACKING_MODE_REGULAR));
3144 
3145 			caseName << "_sparse";
3146 			alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx], IMAGE_BACKING_MODE_SPARSE));
3147 		}
3148 
3149 		multisampleTests->addChild(alphaToOneTests.release());
3150 	}
3151 
3152 	// AlphaToCoverageEnable tests
3153 	{
3154 		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", ""));
3155 
3156 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
3157 		{
3158 			std::ostringstream caseName;
3159 			caseName << "samples_" << samples[samplesNdx];
3160 
3161 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
3162 
3163 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
3164 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_REGULAR));
3165 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR));
3166 
3167 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
3168 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_SPARSE));
3169 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE));
3170 
3171 			alphaToCoverageTests->addChild(samplesTests.release());
3172 		}
3173 		multisampleTests->addChild(alphaToCoverageTests.release());
3174 	}
3175 
3176 	// Sampling from a multisampled image texture (texelFetch)
3177 	{
3178 		multisampleTests->addChild(createMultisampleSampledImageTests(testCtx));
3179 	}
3180 
3181 	// Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.)
3182 	{
3183 		multisampleTests->addChild(createMultisampleStorageImageTests(testCtx));
3184 	}
3185 
3186 	// VK_EXT_sample_locations
3187 	{
3188 		multisampleTests->addChild(createMultisampleSampleLocationsExtTests(testCtx));
3189 	}
3190 
3191 	// Sample mask with and without vk_ext_post_depth_coverage
3192 	{
3193 		const vk::VkSampleCountFlagBits standardSamplesSet[] =
3194 		{
3195 			vk::VK_SAMPLE_COUNT_2_BIT,
3196 			vk::VK_SAMPLE_COUNT_4_BIT,
3197 			vk::VK_SAMPLE_COUNT_8_BIT,
3198 			vk::VK_SAMPLE_COUNT_16_BIT
3199 		};
3200 
3201 		de::MovePtr<tcu::TestCaseGroup> sampleMaskWithDepthTestGroup(new tcu::TestCaseGroup(testCtx, "sample_mask_with_depth_test", ""));
3202 
3203 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(standardSamplesSet); ++ndx)
3204 		{
3205 			std::ostringstream caseName;
3206 			caseName << "samples_" << standardSamplesSet[ndx];
3207 
3208 			sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", standardSamplesSet[ndx]));
3209 
3210 			caseName << "_post_depth_coverage";
3211 			sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", standardSamplesSet[ndx], true));
3212 
3213 		}
3214 		multisampleTests->addChild(sampleMaskWithDepthTestGroup.release());
3215 	}
3216 
3217 	return multisampleTests.release();
3218 }
3219 
3220 } // pipeline
3221 } // vkt
3222