• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Imagination Technologies Ltd.
7  * 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 "vktPipelineMultisampleMixedAttachmentSamplesTests.hpp"
30 #include "vktPipelineMultisampleShaderFragmentMaskTests.hpp"
31 #include "vktPipelineClearUtil.hpp"
32 #include "vktPipelineImageUtil.hpp"
33 #include "vktPipelineVertexUtil.hpp"
34 #include "vktPipelineReferenceRenderer.hpp"
35 #include "vktTestCase.hpp"
36 #include "vktTestCaseUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkMemUtil.hpp"
39 #include "vkPrograms.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkRef.hpp"
42 #include "vkRefUtil.hpp"
43 #include "vkCmdUtil.hpp"
44 #include "vkTypeUtil.hpp"
45 #include "vkObjUtil.hpp"
46 #include "vkBufferWithMemory.hpp"
47 #include "vkImageWithMemory.hpp"
48 #include "vkBuilderUtil.hpp"
49 #include "vkBarrierUtil.hpp"
50 #include "tcuImageCompare.hpp"
51 #include "tcuTestLog.hpp"
52 #include "deUniquePtr.hpp"
53 #include "deSharedPtr.hpp"
54 #include "deStringUtil.hpp"
55 #include "deMemory.h"
56 
57 #include <sstream>
58 #include <vector>
59 #include <map>
60 #include <memory>
61 #include <algorithm>
62 #include <set>
63 #include <array>
64 
65 namespace vkt
66 {
67 namespace pipeline
68 {
69 
70 using namespace vk;
71 
72 namespace
73 {
74 enum GeometryType
75 {
76 	GEOMETRY_TYPE_OPAQUE_TRIANGLE,
77 	GEOMETRY_TYPE_OPAQUE_LINE,
78 	GEOMETRY_TYPE_OPAQUE_POINT,
79 	GEOMETRY_TYPE_OPAQUE_QUAD,
80 	GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH,	//!< placed at z = 0.5
81 	GEOMETRY_TYPE_TRANSLUCENT_QUAD,
82 	GEOMETRY_TYPE_INVISIBLE_TRIANGLE,
83 	GEOMETRY_TYPE_INVISIBLE_QUAD,
84 	GEOMETRY_TYPE_GRADIENT_QUAD
85 };
86 
87 enum TestModeBits
88 {
89 	TEST_MODE_DEPTH_BIT		= 1u,
90 	TEST_MODE_STENCIL_BIT	= 2u,
91 };
92 typedef deUint32 TestModeFlags;
93 
94 enum RenderType
95 {
96 	// resolve multisample rendering to single sampled image
97 	RENDER_TYPE_RESOLVE				= 0u,
98 
99 	// copy samples to an array of single sampled images
100 	RENDER_TYPE_COPY_SAMPLES		= 1u,
101 
102 	// render first with only depth/stencil and then with color + depth/stencil
103 	RENDER_TYPE_DEPTHSTENCIL_ONLY	= 2u,
104 
105 	// render using color attachment at location 1 and location 0 set as unused
106 	RENDER_TYPE_UNUSED_ATTACHMENT	= 3u
107 };
108 
109 enum ImageBackingMode
110 {
111 	IMAGE_BACKING_MODE_REGULAR	= 0u,
112 	IMAGE_BACKING_MODE_SPARSE
113 };
114 
115 struct MultisampleTestParams
116 {
117 	GeometryType		geometryType;
118 	float				pointSize;
119 	ImageBackingMode	backingMode;
120 };
121 
122 void									initMultisamplePrograms				(SourceCollections& sources, MultisampleTestParams params);
123 bool									isSupportedSampleCount				(const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples);
124 bool									isSupportedDepthStencilFormat		(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format);
125 VkPipelineColorBlendAttachmentState		getDefaultColorBlendAttachmentState	(void);
126 deUint32								getUniqueColorsCount				(const tcu::ConstPixelBufferAccess& image);
127 VkImageAspectFlags						getImageAspectFlags					(const VkFormat format);
128 VkPrimitiveTopology						getPrimitiveTopology				(const GeometryType geometryType);
129 std::vector<Vertex4RGBA>				generateVertices					(const GeometryType geometryType);
130 VkFormat								findSupportedDepthStencilFormat		(Context& context, const bool useDepth, const bool useStencil);
131 
132 class MultisampleTest : public vkt::TestCase
133 {
134 public:
135 
136 												MultisampleTest						(tcu::TestContext&								testContext,
137 																					 const std::string&								name,
138 																					 const std::string&								description,
139 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
140 																					 const VkPipelineColorBlendAttachmentState&		blendState,
141 																					 GeometryType									geometryType,
142 																					 float											pointSize,
143 																					 ImageBackingMode								backingMode);
~MultisampleTest(void)144 	virtual										~MultisampleTest					(void) {}
145 
146 	virtual void								initPrograms						(SourceCollections& programCollection) const;
147 	virtual TestInstance*						createInstance						(Context& context) const;
148 	virtual void								checkSupport						(Context& context) const;
149 
150 protected:
151 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
152 																					 VkPrimitiveTopology							topology,
153 																					 float											pointSize,
154 																					 const std::vector<Vertex4RGBA>&				vertices,
155 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
156 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const = 0;
157 	VkPipelineMultisampleStateCreateInfo		m_multisampleStateParams;
158 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
159 	const GeometryType							m_geometryType;
160 	const float									m_pointSize;
161 	const ImageBackingMode						m_backingMode;
162 	std::vector<VkSampleMask>					m_sampleMask;
163 };
164 
165 class RasterizationSamplesTest : public MultisampleTest
166 {
167 public:
168 												RasterizationSamplesTest			(tcu::TestContext&		testContext,
169 																					 const std::string&		name,
170 																					 const std::string&		description,
171 																					 VkSampleCountFlagBits	rasterizationSamples,
172 																					 GeometryType			geometryType,
173 																					 float					pointSize,
174 																					 ImageBackingMode		backingMode,
175 																					 TestModeFlags			modeFlags				= 0u);
~RasterizationSamplesTest(void)176 	virtual										~RasterizationSamplesTest			(void) {}
177 
178 protected:
179 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
180 																					 VkPrimitiveTopology							topology,
181 																					 float											pointSize,
182 																					 const std::vector<Vertex4RGBA>&				vertices,
183 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
184 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
185 
186 	static VkPipelineMultisampleStateCreateInfo	getRasterizationSamplesStateParams	(VkSampleCountFlagBits rasterizationSamples);
187 
188 	const ImageBackingMode						m_backingMode;
189 	const TestModeFlags							m_modeFlags;
190 };
191 
192 class MinSampleShadingTest : public MultisampleTest
193 {
194 public:
195 												MinSampleShadingTest				(tcu::TestContext&		testContext,
196 																					 const std::string&		name,
197 																					 const std::string&		description,
198 																					 VkSampleCountFlagBits	rasterizationSamples,
199 																					 float					minSampleShading,
200 																					 GeometryType			geometryType,
201 																					 float					pointSize,
202 																					 ImageBackingMode		backingMode,
203 																					 const bool				minSampleShadingEnabled = true);
~MinSampleShadingTest(void)204 	virtual										~MinSampleShadingTest				(void) {}
205 
206 protected:
207 	virtual void								initPrograms						(SourceCollections& programCollection) const;
208 	virtual void								checkSupport						(Context& context) const;
209 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
210 																					 VkPrimitiveTopology							topology,
211 																					 float											pointSize,
212 																					 const std::vector<Vertex4RGBA>&				vertices,
213 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
214 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
215 
216 	static VkPipelineMultisampleStateCreateInfo	getMinSampleShadingStateParams		(VkSampleCountFlagBits	rasterizationSamples,
217 																					 float					minSampleShading,
218 																					 bool					minSampleShadingEnabled);
219 
220 	const float									m_pointSize;
221 	const ImageBackingMode						m_backingMode;
222 	const bool									m_minSampleShadingEnabled;
223 };
224 
225 class SampleMaskTest : public MultisampleTest
226 {
227 public:
228 												SampleMaskTest						(tcu::TestContext&					testContext,
229 																					 const std::string&					name,
230 																					 const std::string&					description,
231 																					 VkSampleCountFlagBits				rasterizationSamples,
232 																					 const std::vector<VkSampleMask>&	sampleMask,
233 																					 GeometryType						geometryType,
234 																					 float								pointSize,
235 																					 ImageBackingMode					backingMode);
236 
~SampleMaskTest(void)237 	virtual										~SampleMaskTest						(void) {}
238 
239 protected:
240 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
241 																					 VkPrimitiveTopology							topology,
242 																					 float											pointSize,
243 																					 const std::vector<Vertex4RGBA>&				vertices,
244 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
245 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
246 
247 	static VkPipelineMultisampleStateCreateInfo	getSampleMaskStateParams			(VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask);
248 
249 	const ImageBackingMode						m_backingMode;
250 };
251 
252 class AlphaToOneTest : public MultisampleTest
253 {
254 public:
255 												AlphaToOneTest					(tcu::TestContext&					testContext,
256 																				 const std::string&					name,
257 																				 const std::string&					description,
258 																				 VkSampleCountFlagBits				rasterizationSamples,
259 																				 ImageBackingMode					backingMode);
260 
~AlphaToOneTest(void)261 	virtual										~AlphaToOneTest					(void) {}
262 
263 protected:
264 	virtual void								checkSupport					(Context& context) const;
265 	virtual TestInstance*						createMultisampleTestInstance	(Context&										context,
266 																				 VkPrimitiveTopology							topology,
267 																				 float											pointSize,
268 																				 const std::vector<Vertex4RGBA>&				vertices,
269 																				 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
270 																				 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
271 
272 	static VkPipelineMultisampleStateCreateInfo	getAlphaToOneStateParams		(VkSampleCountFlagBits rasterizationSamples);
273 	static VkPipelineColorBlendAttachmentState	getAlphaToOneBlendState			(void);
274 
275 	const ImageBackingMode						m_backingMode;
276 };
277 
278 class AlphaToCoverageTest : public MultisampleTest
279 {
280 public:
281 												AlphaToCoverageTest				(tcu::TestContext&		testContext,
282 																				 const std::string&		name,
283 																				 const std::string&		description,
284 																				 VkSampleCountFlagBits	rasterizationSamples,
285 																				 GeometryType			geometryType,
286 																				 ImageBackingMode		backingMode);
287 
~AlphaToCoverageTest(void)288 	virtual										~AlphaToCoverageTest			(void) {}
289 
290 protected:
291 	virtual TestInstance*						createMultisampleTestInstance	(Context&										context,
292 																				 VkPrimitiveTopology							topology,
293 																				 float											pointSize,
294 																				 const std::vector<Vertex4RGBA>&				vertices,
295 																				 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
296 																				 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
297 
298 	static VkPipelineMultisampleStateCreateInfo	getAlphaToCoverageStateParams	(VkSampleCountFlagBits rasterizationSamples);
299 
300 	GeometryType								m_geometryType;
301 	const ImageBackingMode						m_backingMode;
302 };
303 
304 class AlphaToCoverageNoColorAttachmentTest : public MultisampleTest
305 {
306 public:
307 												AlphaToCoverageNoColorAttachmentTest	(tcu::TestContext&		testContext,
308 																						 const std::string&		name,
309 																						 const std::string&		description,
310 																						 VkSampleCountFlagBits	rasterizationSamples,
311 																						 GeometryType			geometryType,
312 																						 ImageBackingMode		backingMode);
313 
~AlphaToCoverageNoColorAttachmentTest(void)314 	virtual										~AlphaToCoverageNoColorAttachmentTest	(void) {}
315 
316 protected:
317 	virtual TestInstance*						createMultisampleTestInstance			(Context&										context,
318 																						 VkPrimitiveTopology							topology,
319 																						 float											pointSize,
320 																						 const std::vector<Vertex4RGBA>&				vertices,
321 																						 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
322 																						 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
323 
324 	static VkPipelineMultisampleStateCreateInfo	getStateParams							(VkSampleCountFlagBits rasterizationSamples);
325 
326 	GeometryType								m_geometryType;
327 	const ImageBackingMode						m_backingMode;
328 };
329 
330 class AlphaToCoverageColorUnusedAttachmentTest : public MultisampleTest
331 {
332 public:
333 												AlphaToCoverageColorUnusedAttachmentTest	(tcu::TestContext&		testContext,
334 																							 const std::string&		name,
335 																							 const std::string&		description,
336 																							 VkSampleCountFlagBits	rasterizationSamples,
337 																							 GeometryType			geometryType,
338 																							 ImageBackingMode		backingMode);
339 
~AlphaToCoverageColorUnusedAttachmentTest(void)340 	virtual										~AlphaToCoverageColorUnusedAttachmentTest	(void) {}
341 
342 protected:
343 	virtual void								initPrograms								(SourceCollections& programCollection) const;
344 
345 	virtual TestInstance*						createMultisampleTestInstance				(Context&										context,
346 																							 VkPrimitiveTopology							topology,
347 																							 float											pointSize,
348 																							 const std::vector<Vertex4RGBA>&				vertices,
349 																							 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
350 																							 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
351 
352 	static VkPipelineMultisampleStateCreateInfo	getStateParams								(VkSampleCountFlagBits rasterizationSamples);
353 
354 	GeometryType								m_geometryType;
355 	const ImageBackingMode						m_backingMode;
356 };
357 
358 class SampleMaskWithDepthTestTest : public vkt::TestCase
359 {
360 public:
361 												SampleMaskWithDepthTestTest		(tcu::TestContext&				testContext,
362 																				 const std::string&				name,
363 																				 const std::string&				description,
364 																				 const VkSampleCountFlagBits	rasterizationSamples,
365 																				 const bool						enablePostDepthCoverage		= false);
366 
~SampleMaskWithDepthTestTest(void)367 												~SampleMaskWithDepthTestTest	(void) {}
368 
369 	void										initPrograms					(SourceCollections&		programCollection)	const;
370 	TestInstance*								createInstance					(Context&				context)			const;
371 	virtual void								checkSupport					(Context&				context)			const;
372 private:
373 	const VkSampleCountFlagBits					m_rasterizationSamples;
374 	const bool									m_enablePostDepthCoverage;
375 };
376 
377 typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp;
378 
379 class MultisampleRenderer
380 {
381 public:
382 												MultisampleRenderer			(Context&										context,
383 																			 const VkFormat									colorFormat,
384 																			 const tcu::IVec2&								renderSize,
385 																			 const VkPrimitiveTopology						topology,
386 																			 const std::vector<Vertex4RGBA>&				vertices,
387 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
388 																			 const VkPipelineColorBlendAttachmentState&		blendState,
389 																			 const RenderType								renderType,
390 																			 const ImageBackingMode							backingMode);
391 
392 												MultisampleRenderer			(Context&										context,
393 																			 const VkFormat									colorFormat,
394 																			 const VkFormat									depthStencilFormat,
395 																			 const tcu::IVec2&								renderSize,
396 																			 const bool										useDepth,
397 																			 const bool										useStencil,
398 																			 const deUint32									numTopologies,
399 																			 const VkPrimitiveTopology*						pTopology,
400 																			 const std::vector<Vertex4RGBA>*				pVertices,
401 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
402 																			 const VkPipelineColorBlendAttachmentState&		blendState,
403 																			 const RenderType								renderType,
404 																			 const ImageBackingMode							backingMode,
405 																			 const float									depthClearValue			= 1.0f);
406 
407 	virtual										~MultisampleRenderer		(void);
408 
409 	de::MovePtr<tcu::TextureLevel>				render						(void);
410 	de::MovePtr<tcu::TextureLevel>				getSingleSampledImage		(deUint32 sampleId);
411 
412 protected:
413 	void										initialize					(Context&										context,
414 																			 const deUint32									numTopologies,
415 																			 const VkPrimitiveTopology*						pTopology,
416 																			 const std::vector<Vertex4RGBA>*				pVertices);
417 
418 	Context&									m_context;
419 
420 	const Unique<VkSemaphore>					m_bindSemaphore;
421 
422 	const VkFormat								m_colorFormat;
423 	const VkFormat								m_depthStencilFormat;
424 	tcu::IVec2									m_renderSize;
425 	const bool									m_useDepth;
426 	const bool									m_useStencil;
427 
428 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
429 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
430 
431 	const RenderType							m_renderType;
432 
433 	Move<VkImage>								m_colorImage;
434 	de::MovePtr<Allocation>						m_colorImageAlloc;
435 	Move<VkImageView>							m_colorAttachmentView;
436 
437 	Move<VkImage>								m_resolveImage;
438 	de::MovePtr<Allocation>						m_resolveImageAlloc;
439 	Move<VkImageView>							m_resolveAttachmentView;
440 
441 	struct PerSampleImage
442 	{
443 		Move<VkImage>								m_image;
444 		de::MovePtr<Allocation>						m_imageAlloc;
445 		Move<VkImageView>							m_attachmentView;
446 	};
447 	std::vector<de::SharedPtr<PerSampleImage> >	m_perSampleImages;
448 
449 	Move<VkImage>								m_depthStencilImage;
450 	de::MovePtr<Allocation>						m_depthStencilImageAlloc;
451 	Move<VkImageView>							m_depthStencilAttachmentView;
452 
453 	Move<VkRenderPass>							m_renderPass;
454 	Move<VkFramebuffer>							m_framebuffer;
455 
456 	Move<VkShaderModule>						m_vertexShaderModule;
457 	Move<VkShaderModule>						m_fragmentShaderModule;
458 
459 	Move<VkShaderModule>						m_copySampleVertexShaderModule;
460 	Move<VkShaderModule>						m_copySampleFragmentShaderModule;
461 
462 	Move<VkBuffer>								m_vertexBuffer;
463 	de::MovePtr<Allocation>						m_vertexBufferAlloc;
464 
465 	Move<VkPipelineLayout>						m_pipelineLayout;
466 	std::vector<VkPipelineSp>					m_graphicsPipelines;
467 
468 	Move<VkDescriptorSetLayout>					m_copySampleDesciptorLayout;
469 	Move<VkDescriptorPool>						m_copySampleDesciptorPool;
470 	Move<VkDescriptorSet>						m_copySampleDesciptorSet;
471 
472 	Move<VkPipelineLayout>						m_copySamplePipelineLayout;
473 	std::vector<VkPipelineSp>					m_copySamplePipelines;
474 
475 	Move<VkCommandPool>							m_cmdPool;
476 	Move<VkCommandBuffer>						m_cmdBuffer;
477 
478 	std::vector<de::SharedPtr<Allocation> >		m_allocations;
479 
480 	ImageBackingMode							m_backingMode;
481 	const float									m_depthClearValue;
482 };
483 
484 class RasterizationSamplesInstance : public vkt::TestInstance
485 {
486 public:
487 										RasterizationSamplesInstance	(Context&										context,
488 																		 VkPrimitiveTopology							topology,
489 																		 float											pointSize,
490 																		 const std::vector<Vertex4RGBA>&				vertices,
491 																		 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
492 																		 const VkPipelineColorBlendAttachmentState&		blendState,
493 																		 const TestModeFlags							modeFlags,
494 																		 ImageBackingMode								backingMode);
~RasterizationSamplesInstance(void)495 	virtual								~RasterizationSamplesInstance	(void) {}
496 
497 	virtual tcu::TestStatus				iterate							(void);
498 
499 protected:
500 	virtual tcu::TestStatus				verifyImage						(const tcu::ConstPixelBufferAccess& result);
501 
502 	const VkFormat						m_colorFormat;
503 	const tcu::IVec2					m_renderSize;
504 	const VkPrimitiveTopology			m_primitiveTopology;
505 	const float							m_pointSize;
506 	const std::vector<Vertex4RGBA>		m_vertices;
507 	const std::vector<Vertex4RGBA>		m_fullQuadVertices;			//!< used by depth/stencil case
508 	const TestModeFlags					m_modeFlags;
509 	de::MovePtr<MultisampleRenderer>	m_multisampleRenderer;
510 };
511 
512 class MinSampleShadingInstance : public vkt::TestInstance
513 {
514 public:
515 												MinSampleShadingInstance	(Context&										context,
516 																			 VkPrimitiveTopology							topology,
517 																			 float											pointSize,
518 																			 const std::vector<Vertex4RGBA>&				vertices,
519 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
520 																			 const VkPipelineColorBlendAttachmentState&		blendState,
521 																			 ImageBackingMode								backingMode);
~MinSampleShadingInstance(void)522 	virtual										~MinSampleShadingInstance	(void) {}
523 
524 	virtual tcu::TestStatus						iterate						(void);
525 
526 protected:
527 	virtual tcu::TestStatus						verifySampleShadedImage		(const std::vector<tcu::TextureLevel>& testShadingImages,
528 																			 const tcu::ConstPixelBufferAccess& noSampleshadingImage);
529 
530 	const VkFormat								m_colorFormat;
531 	const tcu::IVec2							m_renderSize;
532 	const VkPrimitiveTopology					m_primitiveTopology;
533 	const std::vector<Vertex4RGBA>				m_vertices;
534 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
535 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
536 	const ImageBackingMode						m_backingMode;
537 };
538 
539 class MinSampleShadingDisabledInstance : public MinSampleShadingInstance
540 {
541 public:
542 												MinSampleShadingDisabledInstance	(Context&										context,
543 																					 VkPrimitiveTopology							topology,
544 																					 float											pointSize,
545 																					 const std::vector<Vertex4RGBA>&				vertices,
546 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
547 																					 const VkPipelineColorBlendAttachmentState&		blendState,
548 																					 ImageBackingMode								backingMode);
~MinSampleShadingDisabledInstance(void)549 	virtual										~MinSampleShadingDisabledInstance	(void) {}
550 
551 protected:
552 	virtual tcu::TestStatus						verifySampleShadedImage				(const std::vector<tcu::TextureLevel>&	sampleShadedImages,
553 																					 const tcu::ConstPixelBufferAccess&		noSampleshadingImage);
554 };
555 
556 class SampleMaskInstance : public vkt::TestInstance
557 {
558 public:
559 												SampleMaskInstance			(Context&										context,
560 																			 VkPrimitiveTopology							topology,
561 																			 float											pointSize,
562 																			 const std::vector<Vertex4RGBA>&				vertices,
563 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
564 																			 const VkPipelineColorBlendAttachmentState&		blendState,
565 																			 ImageBackingMode								backingMode);
~SampleMaskInstance(void)566 	virtual										~SampleMaskInstance			(void) {}
567 
568 	virtual tcu::TestStatus						iterate						(void);
569 
570 protected:
571 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& testShadingImage,
572 																			 const tcu::ConstPixelBufferAccess& minShadingImage,
573 																			 const tcu::ConstPixelBufferAccess& maxShadingImage);
574 	const VkFormat								m_colorFormat;
575 	const tcu::IVec2							m_renderSize;
576 	const VkPrimitiveTopology					m_primitiveTopology;
577 	const std::vector<Vertex4RGBA>				m_vertices;
578 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
579 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
580 	const ImageBackingMode						m_backingMode;
581 };
582 
583 class AlphaToOneInstance : public vkt::TestInstance
584 {
585 public:
586 												AlphaToOneInstance			(Context&										context,
587 																			 VkPrimitiveTopology							topology,
588 																			 const std::vector<Vertex4RGBA>&				vertices,
589 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
590 																			 const VkPipelineColorBlendAttachmentState&		blendState,
591 																			 ImageBackingMode								backingMode);
~AlphaToOneInstance(void)592 	virtual										~AlphaToOneInstance			(void) {}
593 
594 	virtual tcu::TestStatus						iterate						(void);
595 
596 protected:
597 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& alphaOneImage,
598 																			 const tcu::ConstPixelBufferAccess& noAlphaOneImage);
599 	const VkFormat								m_colorFormat;
600 	const tcu::IVec2							m_renderSize;
601 	const VkPrimitiveTopology					m_primitiveTopology;
602 	const std::vector<Vertex4RGBA>				m_vertices;
603 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
604 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
605 	const ImageBackingMode						m_backingMode;
606 };
607 
608 class AlphaToCoverageInstance : public vkt::TestInstance
609 {
610 public:
611 												AlphaToCoverageInstance		(Context&										context,
612 																			 VkPrimitiveTopology							topology,
613 																			 const std::vector<Vertex4RGBA>&				vertices,
614 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
615 																			 const VkPipelineColorBlendAttachmentState&		blendState,
616 																			 GeometryType									geometryType,
617 																			 ImageBackingMode								backingMode);
~AlphaToCoverageInstance(void)618 	virtual										~AlphaToCoverageInstance	(void) {}
619 
620 	virtual tcu::TestStatus						iterate						(void);
621 
622 protected:
623 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& result);
624 	const VkFormat								m_colorFormat;
625 	const tcu::IVec2							m_renderSize;
626 	const VkPrimitiveTopology					m_primitiveTopology;
627 	const std::vector<Vertex4RGBA>				m_vertices;
628 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
629 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
630 	const GeometryType							m_geometryType;
631 	const ImageBackingMode						m_backingMode;
632 };
633 
634 class AlphaToCoverageNoColorAttachmentInstance : public vkt::TestInstance
635 {
636 public:
637 												AlphaToCoverageNoColorAttachmentInstance	(Context&										context,
638 																							 VkPrimitiveTopology							topology,
639 																							 const std::vector<Vertex4RGBA>&				vertices,
640 																							 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
641 																							 const VkPipelineColorBlendAttachmentState&		blendState,
642 																							 GeometryType									geometryType,
643 																							 ImageBackingMode								backingMode);
~AlphaToCoverageNoColorAttachmentInstance(void)644 	virtual										~AlphaToCoverageNoColorAttachmentInstance	(void) {}
645 
646 	virtual tcu::TestStatus						iterate										(void);
647 
648 protected:
649 	virtual tcu::TestStatus						verifyImage									(const tcu::ConstPixelBufferAccess& result);
650 	const VkFormat								m_colorFormat;
651 	const VkFormat								m_depthStencilFormat;
652 	const tcu::IVec2							m_renderSize;
653 	const VkPrimitiveTopology					m_primitiveTopology;
654 	const std::vector<Vertex4RGBA>				m_vertices;
655 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
656 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
657 	const GeometryType							m_geometryType;
658 	const ImageBackingMode						m_backingMode;
659 };
660 
661 class AlphaToCoverageColorUnusedAttachmentInstance : public vkt::TestInstance
662 {
663 public:
664 												AlphaToCoverageColorUnusedAttachmentInstance	(Context&										context,
665 																								 VkPrimitiveTopology							topology,
666 																								 const std::vector<Vertex4RGBA>&				vertices,
667 																								 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
668 																								 const VkPipelineColorBlendAttachmentState&		blendState,
669 																								 GeometryType									geometryType,
670 																								 ImageBackingMode								backingMode);
~AlphaToCoverageColorUnusedAttachmentInstance(void)671 	virtual										~AlphaToCoverageColorUnusedAttachmentInstance	(void) {}
672 
673 	virtual tcu::TestStatus						iterate											(void);
674 
675 protected:
676 	virtual tcu::TestStatus						verifyImage										(const tcu::ConstPixelBufferAccess& result);
677 	const VkFormat								m_colorFormat;
678 	const tcu::IVec2							m_renderSize;
679 	const VkPrimitiveTopology					m_primitiveTopology;
680 	const std::vector<Vertex4RGBA>				m_vertices;
681 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
682 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
683 	const GeometryType							m_geometryType;
684 	const ImageBackingMode						m_backingMode;
685 };
686 
687 class SampleMaskWithDepthTestInstance : public vkt::TestInstance
688 {
689 public:
690 													SampleMaskWithDepthTestInstance		(Context&							context,
691 																						 const VkSampleCountFlagBits		rasterizationSamples,
692 																						 const bool							enablePostDepthCoverage);
~SampleMaskWithDepthTestInstance(void)693 													~SampleMaskWithDepthTestInstance	(void) {}
694 
695 	tcu::TestStatus									iterate								(void);
696 
697 protected:
698 	VkPipelineMultisampleStateCreateInfo			getMultisampleState					(const VkSampleCountFlagBits		rasterizationSamples);
699 	std::vector<Vertex4RGBA>						generateVertices					(void);
700 	tcu::TestStatus									verifyImage							(const tcu::ConstPixelBufferAccess&	result);
701 
702 	struct SampleCoverage
703 	{
SampleCoveragevkt::pipeline::__anon16de12d60111::SampleMaskWithDepthTestInstance::SampleCoverage704 		SampleCoverage() {};
SampleCoveragevkt::pipeline::__anon16de12d60111::SampleMaskWithDepthTestInstance::SampleCoverage705 		SampleCoverage(deUint32 min_, deUint32 max_)
706 			: min(min_), max(max_) {};
707 
708 		deUint32	min;
709 		deUint32	max;
710 	};
711 
712 	const VkSampleCountFlagBits						m_rasterizationSamples;
713 	const bool										m_enablePostDepthCoverage;
714 	const VkFormat									m_colorFormat;
715 	const VkFormat									m_depthStencilFormat;
716 	const tcu::IVec2								m_renderSize;
717 	const bool										m_useDepth;
718 	const bool										m_useStencil;
719 	const VkPrimitiveTopology						m_topology;
720 	const tcu::Vec4									m_renderColor;
721 	const std::vector<Vertex4RGBA>					m_vertices;
722 	const VkPipelineMultisampleStateCreateInfo		m_multisampleStateParams;
723 	const VkPipelineColorBlendAttachmentState		m_blendState;
724 	const RenderType								m_renderType;
725 	const ImageBackingMode							m_imageBackingMode;
726 	const float										m_depthClearValue;
727 	std::map<VkSampleCountFlagBits, SampleCoverage>	m_refCoverageAfterDepthTest;
728 };
729 
730 
731 // Helper functions
732 
initMultisamplePrograms(SourceCollections & sources,MultisampleTestParams params)733 void initMultisamplePrograms (SourceCollections& sources, MultisampleTestParams params)
734 {
735 	const std::string	pointSize		= params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string("	gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string("");
736 	std::ostringstream	vertexSource;
737 
738 	vertexSource <<
739 		"#version 310 es\n"
740 		"layout(location = 0) in vec4 position;\n"
741 		"layout(location = 1) in vec4 color;\n"
742 		"layout(location = 0) out highp vec4 vtxColor;\n"
743 		"void main (void)\n"
744 		"{\n"
745 		"	gl_Position = position;\n"
746 		"	vtxColor = color;\n"
747 		<< pointSize
748 		<< "}\n";
749 
750 	static const char* fragmentSource =
751 		"#version 310 es\n"
752 		"layout(location = 0) in highp vec4 vtxColor;\n"
753 		"layout(location = 0) out highp vec4 fragColor;\n"
754 		"void main (void)\n"
755 		"{\n"
756 		"	fragColor = vtxColor;\n"
757 		"}\n";
758 
759 	sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
760 	sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
761 }
762 
initSampleShadingPrograms(SourceCollections & sources,MultisampleTestParams params)763 void initSampleShadingPrograms (SourceCollections& sources, MultisampleTestParams params)
764 {
765 	{
766 		const std::string	pointSize		= params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string("	gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string("");
767 		std::ostringstream	vertexSource;
768 
769 		vertexSource <<
770 			"#version 440\n"
771 			"layout(location = 0) in vec4 position;\n"
772 			"layout(location = 1) in vec4 color;\n"
773 			"void main (void)\n"
774 			"{\n"
775 			"	gl_Position = position;\n"
776 			<< pointSize
777 			<< "}\n";
778 
779 		static const char* fragmentSource =
780 			"#version 440\n"
781 			"layout(location = 0) out highp vec4 fragColor;\n"
782 			"void main (void)\n"
783 			"{\n"
784 			"	fragColor = vec4(fract(gl_FragCoord.xy), 0.0, 1.0);\n"
785 			"}\n";
786 
787 		sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
788 		sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
789 	}
790 
791 	{
792 		static const char*  vertexSource =
793 			"#version 440\n"
794 			"void main (void)\n"
795 			"{\n"
796 			"	const vec4 positions[4] = vec4[4](\n"
797 			"		vec4(-1.0, -1.0, 0.0, 1.0),\n"
798 			"		vec4(-1.0,  1.0, 0.0, 1.0),\n"
799 			"		vec4( 1.0, -1.0, 0.0, 1.0),\n"
800 			"		vec4( 1.0,  1.0, 0.0, 1.0)\n"
801 			"	);\n"
802 			"	gl_Position = positions[gl_VertexIndex];\n"
803 			"}\n";
804 
805 		static const char* fragmentSource =
806 			"#version 440\n"
807 			"precision highp float;\n"
808 			"layout(location = 0) out highp vec4 fragColor;\n"
809 			"layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
810 			"layout(push_constant) uniform PushConstantsBlock\n"
811 			"{\n"
812 			"	int sampleId;\n"
813 			"} pushConstants;\n"
814 			"void main (void)\n"
815 			"{\n"
816 			"	fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n"
817 			"}\n";
818 
819 		sources.glslSources.add("quad_vert") << glu::VertexSource(vertexSource);
820 		sources.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource);
821 	}
822 }
823 
initAlphaToCoverageColorUnusedAttachmentPrograms(SourceCollections & sources)824 void initAlphaToCoverageColorUnusedAttachmentPrograms (SourceCollections& sources)
825 {
826 	std::ostringstream vertexSource;
827 
828 	vertexSource <<
829 		"#version 310 es\n"
830 		"layout(location = 0) in vec4 position;\n"
831 		"layout(location = 1) in vec4 color;\n"
832 		"layout(location = 0) out highp vec4 vtxColor;\n"
833 		"void main (void)\n"
834 		"{\n"
835 		"	gl_Position = position;\n"
836 		"	vtxColor = color;\n"
837 		"}\n";
838 
839 	// Location 0 is unused, but the alpha for coverage is written there. Location 1 has no alpha channel.
840 	static const char* fragmentSource =
841 		"#version 310 es\n"
842 		"layout(location = 0) in highp vec4 vtxColor;\n"
843 		"layout(location = 0) out highp vec4 fragColor0;\n"
844 		"layout(location = 1) out highp vec3 fragColor1;\n"
845 		"void main (void)\n"
846 		"{\n"
847 		"	fragColor0 = vtxColor;\n"
848 		"	fragColor1 = vtxColor.rgb;\n"
849 		"}\n";
850 
851 	sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
852 	sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
853 }
854 
isSupportedSampleCount(const InstanceInterface & instanceInterface,VkPhysicalDevice physicalDevice,VkSampleCountFlagBits rasterizationSamples)855 bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples)
856 {
857 	VkPhysicalDeviceProperties deviceProperties;
858 
859 	instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties);
860 
861 	return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples);
862 }
863 
getDefaultColorBlendAttachmentState(void)864 VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void)
865 {
866 	const VkPipelineColorBlendAttachmentState colorBlendState =
867 	{
868 		false,														// VkBool32					blendEnable;
869 		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcColorBlendFactor;
870 		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstColorBlendFactor;
871 		VK_BLEND_OP_ADD,											// VkBlendOp				colorBlendOp;
872 		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcAlphaBlendFactor;
873 		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstAlphaBlendFactor;
874 		VK_BLEND_OP_ADD,											// VkBlendOp				alphaBlendOp;
875 		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
876 			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
877 	};
878 
879 	return colorBlendState;
880 }
881 
getUniqueColorsCount(const tcu::ConstPixelBufferAccess & image)882 deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image)
883 {
884 	DE_ASSERT(image.getFormat().getPixelSize() == 4);
885 
886 	std::map<deUint32, deUint32>	histogram; // map<pixel value, number of occurrences>
887 	const deUint32					pixelCount	= image.getWidth() * image.getHeight() * image.getDepth();
888 
889 	for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
890 	{
891 		const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx);
892 
893 		if (histogram.find(pixelValue) != histogram.end())
894 			histogram[pixelValue]++;
895 		else
896 			histogram[pixelValue] = 1;
897 	}
898 
899 	return (deUint32)histogram.size();
900 }
901 
getImageAspectFlags(const VkFormat format)902 VkImageAspectFlags getImageAspectFlags (const VkFormat format)
903 {
904 	const tcu::TextureFormat tcuFormat = mapVkFormat(format);
905 
906 	if      (tcuFormat.order == tcu::TextureFormat::DS)		return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
907 	else if (tcuFormat.order == tcu::TextureFormat::D)		return VK_IMAGE_ASPECT_DEPTH_BIT;
908 	else if (tcuFormat.order == tcu::TextureFormat::S)		return VK_IMAGE_ASPECT_STENCIL_BIT;
909 
910 	DE_ASSERT(false);
911 	return 0u;
912 }
913 
generateVertices(const GeometryType geometryType)914 std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType)
915 {
916 	std::vector<Vertex4RGBA> vertices;
917 
918 	switch (geometryType)
919 	{
920 		case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
921 		case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:
922 		{
923 			Vertex4RGBA vertexData[3] =
924 			{
925 				{
926 					tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
927 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
928 				},
929 				{
930 					tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
931 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
932 				},
933 				{
934 					tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
935 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
936 				}
937 			};
938 
939 			if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE)
940 			{
941 				for (int i = 0; i < 3; i++)
942 					vertexData[i].color = tcu::Vec4();
943 			}
944 
945 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3);
946 			break;
947 		}
948 
949 		case GEOMETRY_TYPE_OPAQUE_LINE:
950 		{
951 			const Vertex4RGBA vertexData[2] =
952 			{
953 				{
954 					tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f),
955 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
956 				},
957 				{
958 					tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f),
959 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
960 				}
961 			};
962 
963 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2);
964 			break;
965 		}
966 
967 		case GEOMETRY_TYPE_OPAQUE_POINT:
968 		{
969 			const Vertex4RGBA vertex =
970 			{
971 				tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
972 				tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
973 			};
974 
975 			vertices = std::vector<Vertex4RGBA>(1, vertex);
976 			break;
977 		}
978 
979 		case GEOMETRY_TYPE_OPAQUE_QUAD:
980 		case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
981 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
982 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
983 		case GEOMETRY_TYPE_GRADIENT_QUAD:
984 		{
985 			Vertex4RGBA vertexData[4] =
986 			{
987 				{
988 					tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
989 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
990 				},
991 				{
992 					tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),
993 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
994 				},
995 				{
996 					tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
997 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
998 				},
999 				{
1000 					tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
1001 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1002 				}
1003 			};
1004 
1005 			if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD)
1006 			{
1007 				for (int i = 0; i < 4; i++)
1008 					vertexData[i].color.w() = 0.25f;
1009 			}
1010 			else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD)
1011 			{
1012 				for (int i = 0; i < 4; i++)
1013 					vertexData[i].color.w() = 0.0f;
1014 			}
1015 			else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD)
1016 			{
1017 				vertexData[0].color.w() = 0.0f;
1018 				vertexData[2].color.w() = 0.0f;
1019 			}
1020 			else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)
1021 			{
1022 				for (int i = 0; i < 4; i++)
1023 					vertexData[i].position.z() = 0.5f;
1024 			}
1025 
1026 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 4);
1027 			break;
1028 		}
1029 
1030 		default:
1031 			DE_ASSERT(false);
1032 	}
1033 	return vertices;
1034 }
1035 
getPrimitiveTopology(const GeometryType geometryType)1036 VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType)
1037 {
1038 	switch (geometryType)
1039 	{
1040 		case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
1041 		case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:			return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1042 
1043 		case GEOMETRY_TYPE_OPAQUE_LINE:					return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
1044 		case GEOMETRY_TYPE_OPAQUE_POINT:				return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
1045 
1046 		case GEOMETRY_TYPE_OPAQUE_QUAD:
1047 		case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
1048 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
1049 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
1050 		case GEOMETRY_TYPE_GRADIENT_QUAD:				return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
1051 
1052 		default:
1053 			DE_ASSERT(false);
1054 			return VK_PRIMITIVE_TOPOLOGY_LAST;
1055 	}
1056 }
1057 
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)1058 bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
1059 {
1060 	VkFormatProperties formatProps;
1061 	vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
1062 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
1063 }
1064 
findSupportedDepthStencilFormat(Context & context,const bool useDepth,const bool useStencil)1065 VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil)
1066 {
1067 	if (useDepth && !useStencil)
1068 		return VK_FORMAT_D16_UNORM;		// must be supported
1069 
1070 	const InstanceInterface&	vki			= context.getInstanceInterface();
1071 	const VkPhysicalDevice		physDevice	= context.getPhysicalDevice();
1072 
1073 	// One of these formats must be supported.
1074 
1075 	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
1076 		return VK_FORMAT_D24_UNORM_S8_UINT;
1077 
1078 	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT))
1079 		return VK_FORMAT_D32_SFLOAT_S8_UINT;
1080 
1081 	return VK_FORMAT_UNDEFINED;
1082 }
1083 
1084 
1085 // MultisampleTest
1086 
MultisampleTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,float pointSize,ImageBackingMode backingMode)1087 MultisampleTest::MultisampleTest (tcu::TestContext&								testContext,
1088 								  const std::string&							name,
1089 								  const std::string&							description,
1090 								  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1091 								  const VkPipelineColorBlendAttachmentState&	blendState,
1092 								  GeometryType									geometryType,
1093 								  float											pointSize,
1094 								  ImageBackingMode								backingMode)
1095 	: vkt::TestCase				(testContext, name, description)
1096 	, m_multisampleStateParams	(multisampleStateParams)
1097 	, m_colorBlendState			(blendState)
1098 	, m_geometryType			(geometryType)
1099 	, m_pointSize				(pointSize)
1100 	, m_backingMode				(backingMode)
1101 {
1102 	if (m_multisampleStateParams.pSampleMask)
1103 	{
1104 		// Copy pSampleMask to avoid dependencies with other classes
1105 
1106 		const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32);
1107 
1108 		for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++)
1109 			m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]);
1110 
1111 		m_multisampleStateParams.pSampleMask = m_sampleMask.data();
1112 	}
1113 }
1114 
initPrograms(SourceCollections & programCollection) const1115 void MultisampleTest::initPrograms (SourceCollections& programCollection) const
1116 {
1117 	MultisampleTestParams params = {m_geometryType, m_pointSize, m_backingMode};
1118 	initMultisamplePrograms(programCollection, params);
1119 }
1120 
createInstance(Context & context) const1121 TestInstance* MultisampleTest::createInstance (Context& context) const
1122 {
1123 	return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), m_pointSize, generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState);
1124 }
1125 
checkSupport(Context & context) const1126 void MultisampleTest::checkSupport (Context& context) const
1127 {
1128 	if (m_geometryType == GEOMETRY_TYPE_OPAQUE_POINT && m_pointSize > 1.0f)
1129 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
1130 }
1131 
1132 // RasterizationSamplesTest
1133 
RasterizationSamplesTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType,float pointSize,ImageBackingMode backingMode,TestModeFlags modeFlags)1134 RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext&		testContext,
1135 													const std::string&		name,
1136 													const std::string&		description,
1137 													VkSampleCountFlagBits	rasterizationSamples,
1138 													GeometryType			geometryType,
1139 													float					pointSize,
1140 													ImageBackingMode		backingMode,
1141 													TestModeFlags			modeFlags)
1142 	: MultisampleTest	(testContext, name, description, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
1143 	, m_backingMode		(backingMode)
1144 	, m_modeFlags		(modeFlags)
1145 {
1146 }
1147 
getRasterizationSamplesStateParams(VkSampleCountFlagBits rasterizationSamples)1148 VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples)
1149 {
1150 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1151 	{
1152 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1153 		DE_NULL,													// const void*								pNext;
1154 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1155 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1156 		false,														// VkBool32									sampleShadingEnable;
1157 		0.0f,														// float									minSampleShading;
1158 		DE_NULL,													// const VkSampleMask*						pSampleMask;
1159 		false,														// VkBool32									alphaToCoverageEnable;
1160 		false														// VkBool32									alphaToOneEnable;
1161 	};
1162 
1163 	return multisampleStateParams;
1164 }
1165 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1166 TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context&										context,
1167 																	   VkPrimitiveTopology							topology,
1168 																	   float										pointSize,
1169 																	   const std::vector<Vertex4RGBA>&				vertices,
1170 																	   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1171 																	   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
1172 {
1173 	return new RasterizationSamplesInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_modeFlags, m_backingMode);
1174 }
1175 
1176 
1177 // MinSampleShadingTest
1178 
MinSampleShadingTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,float minSampleShading,GeometryType geometryType,float pointSize,ImageBackingMode backingMode,const bool minSampleShadingEnabled)1179 MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext&		testContext,
1180 											const std::string&		name,
1181 											const std::string&		description,
1182 											VkSampleCountFlagBits	rasterizationSamples,
1183 											float					minSampleShading,
1184 											GeometryType			geometryType,
1185 											float					pointSize,
1186 											ImageBackingMode		backingMode,
1187 											const bool				minSampleShadingEnabled)
1188 	: MultisampleTest			(testContext, name, description, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading, minSampleShadingEnabled), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
1189 	, m_pointSize				(pointSize)
1190 	, m_backingMode				(backingMode)
1191 	, m_minSampleShadingEnabled	(minSampleShadingEnabled)
1192 {
1193 }
1194 
checkSupport(Context & context) const1195 void MinSampleShadingTest::checkSupport (Context& context) const
1196 {
1197 	MultisampleTest::checkSupport(context);
1198 
1199 	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING);
1200 }
1201 
initPrograms(SourceCollections & programCollection) const1202 void MinSampleShadingTest::initPrograms (SourceCollections& programCollection) const
1203 {
1204 	MultisampleTestParams params = {m_geometryType, m_pointSize, m_backingMode};
1205 	initSampleShadingPrograms(programCollection, params);
1206 }
1207 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1208 TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context&										context,
1209 																   VkPrimitiveTopology							topology,
1210 																   float										pointSize,
1211 																   const std::vector<Vertex4RGBA>&				vertices,
1212 																   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1213 																   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
1214 {
1215 	if (m_minSampleShadingEnabled)
1216 		return new MinSampleShadingInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
1217 	else
1218 		return new MinSampleShadingDisabledInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
1219 }
1220 
getMinSampleShadingStateParams(VkSampleCountFlagBits rasterizationSamples,float minSampleShading,bool minSampleShadingEnabled)1221 VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading, bool minSampleShadingEnabled)
1222 {
1223 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1224 	{
1225 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1226 		DE_NULL,													// const void*								pNext;
1227 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1228 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1229 		minSampleShadingEnabled ? VK_TRUE : VK_FALSE,				// VkBool32									sampleShadingEnable;
1230 		minSampleShading,											// float									minSampleShading;
1231 		DE_NULL,													// const VkSampleMask*						pSampleMask;
1232 		false,														//  VkBool32								alphaToCoverageEnable;
1233 		false														//  VkBool32								alphaToOneEnable;
1234 	};
1235 
1236 	return multisampleStateParams;
1237 }
1238 
1239 
1240 // SampleMaskTest
1241 
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)1242 SampleMaskTest::SampleMaskTest (tcu::TestContext&					testContext,
1243 								const std::string&					name,
1244 								const std::string&					description,
1245 								VkSampleCountFlagBits				rasterizationSamples,
1246 								const std::vector<VkSampleMask>&	sampleMask,
1247 								GeometryType						geometryType,
1248 								float								pointSize,
1249 								ImageBackingMode					backingMode)
1250 	: MultisampleTest	(testContext, name, description, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
1251 	, m_backingMode		(backingMode)
1252 {
1253 }
1254 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1255 TestInstance* SampleMaskTest::createMultisampleTestInstance (Context&										context,
1256 															 VkPrimitiveTopology							topology,
1257 															 float											pointSize,
1258 															 const std::vector<Vertex4RGBA>&				vertices,
1259 															 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1260 															 const VkPipelineColorBlendAttachmentState&		colorBlendState) const
1261 {
1262 	DE_UNREF(pointSize);
1263 	return new SampleMaskInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
1264 }
1265 
getSampleMaskStateParams(VkSampleCountFlagBits rasterizationSamples,const std::vector<VkSampleMask> & sampleMask)1266 VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask)
1267 {
1268 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1269 	{
1270 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1271 		DE_NULL,													// const void*								pNext;
1272 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1273 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1274 		false,														// VkBool32									sampleShadingEnable;
1275 		0.0f,														// float									minSampleShading;
1276 		sampleMask.data(),											// const VkSampleMask*						pSampleMask;
1277 		false,														// VkBool32									alphaToCoverageEnable;
1278 		false														// VkBool32									alphaToOneEnable;
1279 	};
1280 
1281 	return multisampleStateParams;
1282 }
1283 
1284 
1285 // AlphaToOneTest
1286 
AlphaToOneTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,ImageBackingMode backingMode)1287 AlphaToOneTest::AlphaToOneTest (tcu::TestContext&		testContext,
1288 								const std::string&		name,
1289 								const std::string&		description,
1290 								VkSampleCountFlagBits	rasterizationSamples,
1291 								ImageBackingMode		backingMode)
1292 	: MultisampleTest	(testContext, name, description, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD, 1.0f, backingMode)
1293 	, m_backingMode(backingMode)
1294 {
1295 }
1296 
checkSupport(Context & context) const1297 void AlphaToOneTest::checkSupport (Context& context) const
1298 {
1299 	MultisampleTest::checkSupport(context);
1300 
1301 	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_ALPHA_TO_ONE);
1302 }
1303 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1304 TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context&										context,
1305 															 VkPrimitiveTopology							topology,
1306 															 float											pointSize,
1307 															 const std::vector<Vertex4RGBA>&				vertices,
1308 															 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1309 															 const VkPipelineColorBlendAttachmentState&		colorBlendState) const
1310 {
1311 	DE_UNREF(pointSize);
1312 	return new AlphaToOneInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_backingMode);
1313 }
1314 
getAlphaToOneStateParams(VkSampleCountFlagBits rasterizationSamples)1315 VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples)
1316 {
1317 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1318 	{
1319 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1320 		DE_NULL,													// const void*								pNext;
1321 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1322 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1323 		false,														// VkBool32									sampleShadingEnable;
1324 		0.0f,														// float									minSampleShading;
1325 		DE_NULL,													// const VkSampleMask*						pSampleMask;
1326 		false,														// VkBool32									alphaToCoverageEnable;
1327 		true														// VkBool32									alphaToOneEnable;
1328 	};
1329 
1330 	return multisampleStateParams;
1331 }
1332 
getAlphaToOneBlendState(void)1333 VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void)
1334 {
1335 	const VkPipelineColorBlendAttachmentState colorBlendState =
1336 	{
1337 		true,														// VkBool32					blendEnable;
1338 		VK_BLEND_FACTOR_SRC_ALPHA,									// VkBlendFactor			srcColorBlendFactor;
1339 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,						// VkBlendFactor			dstColorBlendFactor;
1340 		VK_BLEND_OP_ADD,											// VkBlendOp				colorBlendOp;
1341 		VK_BLEND_FACTOR_SRC_ALPHA,									// VkBlendFactor			srcAlphaBlendFactor;
1342 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,						// VkBlendFactor			dstAlphaBlendFactor;
1343 		VK_BLEND_OP_ADD,											// VkBlendOp				alphaBlendOp;
1344 		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
1345 			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
1346 	};
1347 
1348 	return colorBlendState;
1349 }
1350 
1351 
1352 // AlphaToCoverageTest
1353 
AlphaToCoverageTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType,ImageBackingMode backingMode)1354 AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext&			testContext,
1355 										  const std::string&		name,
1356 										  const std::string&		description,
1357 										  VkSampleCountFlagBits		rasterizationSamples,
1358 										  GeometryType				geometryType,
1359 										  ImageBackingMode			backingMode)
1360 	: MultisampleTest	(testContext, name, description, getAlphaToCoverageStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode)
1361 	, m_geometryType	(geometryType)
1362 	, m_backingMode		(backingMode)
1363 {
1364 }
1365 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1366 TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context&										context,
1367 																  VkPrimitiveTopology							topology,
1368 																  float											pointSize,
1369 																  const std::vector<Vertex4RGBA>&				vertices,
1370 																  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1371 																  const VkPipelineColorBlendAttachmentState&	colorBlendState) const
1372 {
1373 	DE_UNREF(pointSize);
1374 	return new AlphaToCoverageInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode);
1375 }
1376 
getAlphaToCoverageStateParams(VkSampleCountFlagBits rasterizationSamples)1377 VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples)
1378 {
1379 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1380 	{
1381 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1382 		DE_NULL,													// const void*								pNext;
1383 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1384 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1385 		false,														// VkBool32									sampleShadingEnable;
1386 		0.0f,														// float									minSampleShading;
1387 		DE_NULL,													// const VkSampleMask*						pSampleMask;
1388 		true,														// VkBool32									alphaToCoverageEnable;
1389 		false														// VkBool32									alphaToOneEnable;
1390 	};
1391 
1392 	return multisampleStateParams;
1393 }
1394 
1395 // AlphaToCoverageNoColorAttachmentTest
1396 
AlphaToCoverageNoColorAttachmentTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType,ImageBackingMode backingMode)1397 AlphaToCoverageNoColorAttachmentTest::AlphaToCoverageNoColorAttachmentTest (tcu::TestContext&		testContext,
1398 																			const std::string&		name,
1399 																			const std::string&		description,
1400 																			VkSampleCountFlagBits	rasterizationSamples,
1401 																			GeometryType			geometryType,
1402 																			ImageBackingMode		backingMode)
1403 	: MultisampleTest	(testContext, name, description, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode)
1404 	, m_geometryType	(geometryType)
1405 	, m_backingMode		(backingMode)
1406 {
1407 }
1408 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1409 TestInstance* AlphaToCoverageNoColorAttachmentTest::createMultisampleTestInstance (Context&										context,
1410 																				   VkPrimitiveTopology							topology,
1411 																				   float										pointSize,
1412 																				   const std::vector<Vertex4RGBA>&				vertices,
1413 																				   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1414 																				   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
1415 {
1416 	DE_UNREF(pointSize);
1417 	return new AlphaToCoverageNoColorAttachmentInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode);
1418 }
1419 
getStateParams(VkSampleCountFlagBits rasterizationSamples)1420 VkPipelineMultisampleStateCreateInfo AlphaToCoverageNoColorAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples)
1421 {
1422 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1423 	{
1424 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1425 		DE_NULL,													// const void*								pNext;
1426 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1427 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1428 		false,														// VkBool32									sampleShadingEnable;
1429 		0.0f,														// float									minSampleShading;
1430 		DE_NULL,													// const VkSampleMask*						pSampleMask;
1431 		true,														// VkBool32									alphaToCoverageEnable;
1432 		false														// VkBool32									alphaToOneEnable;
1433 	};
1434 
1435 	return multisampleStateParams;
1436 }
1437 
1438 // AlphaToCoverageColorUnusedAttachmentTest
1439 
AlphaToCoverageColorUnusedAttachmentTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType,ImageBackingMode backingMode)1440 AlphaToCoverageColorUnusedAttachmentTest::AlphaToCoverageColorUnusedAttachmentTest (tcu::TestContext&		testContext,
1441 																					const std::string&		name,
1442 																					const std::string&		description,
1443 																					VkSampleCountFlagBits	rasterizationSamples,
1444 																					GeometryType			geometryType,
1445 																					ImageBackingMode		backingMode)
1446 	: MultisampleTest	(testContext, name, description, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode)
1447 	, m_geometryType	(geometryType)
1448 	, m_backingMode		(backingMode)
1449 {
1450 }
1451 
initPrograms(SourceCollections & programCollection) const1452 void AlphaToCoverageColorUnusedAttachmentTest::initPrograms (SourceCollections& programCollection) const
1453 {
1454 	initAlphaToCoverageColorUnusedAttachmentPrograms(programCollection);
1455 }
1456 
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1457 TestInstance* AlphaToCoverageColorUnusedAttachmentTest::createMultisampleTestInstance (Context&										context,
1458 																					   VkPrimitiveTopology							topology,
1459 																					   float										pointSize,
1460 																					   const std::vector<Vertex4RGBA>&				vertices,
1461 																					   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1462 																					   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
1463 {
1464 	DE_UNREF(pointSize);
1465 	return new AlphaToCoverageColorUnusedAttachmentInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode);
1466 }
1467 
getStateParams(VkSampleCountFlagBits rasterizationSamples)1468 VkPipelineMultisampleStateCreateInfo AlphaToCoverageColorUnusedAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples)
1469 {
1470 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1471 	{
1472 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1473 		DE_NULL,													// const void*								pNext;
1474 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1475 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
1476 		false,														// VkBool32									sampleShadingEnable;
1477 		0.0f,														// float									minSampleShading;
1478 		DE_NULL,													// const VkSampleMask*						pSampleMask;
1479 		true,														// VkBool32									alphaToCoverageEnable;
1480 		false														// VkBool32									alphaToOneEnable;
1481 	};
1482 
1483 	return multisampleStateParams;
1484 }
1485 
1486 // SampleMaskWithDepthTestTest
1487 
SampleMaskWithDepthTestTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const VkSampleCountFlagBits rasterizationSamples,const bool enablePostDepthCoverage)1488 SampleMaskWithDepthTestTest::SampleMaskWithDepthTestTest (tcu::TestContext&					testContext,
1489 														  const std::string&				name,
1490 														  const std::string&				description,
1491 														  const VkSampleCountFlagBits		rasterizationSamples,
1492 														  const bool						enablePostDepthCoverage)
1493 	: vkt::TestCase				(testContext, name, description)
1494 	, m_rasterizationSamples	(rasterizationSamples)
1495 	, m_enablePostDepthCoverage	(enablePostDepthCoverage)
1496 {
1497 }
1498 
checkSupport(Context & context) const1499 void SampleMaskWithDepthTestTest::checkSupport (Context& context) const
1500 {
1501 	if (!context.getDeviceProperties().limits.standardSampleLocations)
1502 		TCU_THROW(NotSupportedError, "standardSampleLocations required");
1503 
1504 	context.requireDeviceFunctionality("VK_EXT_post_depth_coverage");
1505 }
1506 
initPrograms(SourceCollections & programCollection) const1507 void SampleMaskWithDepthTestTest::initPrograms (SourceCollections& programCollection) const
1508 {
1509 	DE_ASSERT((int)m_rasterizationSamples <= 32);
1510 
1511 	static const char* vertexSource =
1512 		"#version 440\n"
1513 		"layout(location = 0) in vec4 position;\n"
1514 		"layout(location = 1) in vec4 color;\n"
1515 		"layout(location = 0) out vec4 vtxColor;\n"
1516 		"out gl_PerVertex\n"
1517 		"{\n"
1518 		"    vec4 gl_Position;\n"
1519 		"};\n"
1520 		"\n"
1521 		"void main (void)\n"
1522 		"{\n"
1523 		"    gl_Position = position;\n"
1524 		"    vtxColor = color;\n"
1525 		"}\n";
1526 
1527 	std::ostringstream fragmentSource;
1528 	fragmentSource <<
1529 		"#version 440\n"
1530 		<< (m_enablePostDepthCoverage ? "#extension GL_ARB_post_depth_coverage : require\n" : "") <<
1531 		"layout(early_fragment_tests) in;\n"
1532 		<< (m_enablePostDepthCoverage ? "layout(post_depth_coverage) in;\n" : "") <<
1533 		"layout(location = 0) in vec4 vtxColor;\n"
1534 		"layout(location = 0) out vec4 fragColor;\n"
1535 		"void main (void)\n"
1536 		"{\n"
1537 		"    const int coveredSamples = bitCount(gl_SampleMaskIn[0]);\n"
1538 		"    fragColor = vtxColor * (1.0 / " << (int)m_rasterizationSamples << " * coveredSamples);\n"
1539 		"}\n";
1540 
1541 	programCollection.glslSources.add("color_vert") << glu::VertexSource(vertexSource);
1542 	programCollection.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
1543 }
1544 
createInstance(Context & context) const1545 TestInstance* SampleMaskWithDepthTestTest::createInstance (Context& context) const
1546 {
1547 	return new SampleMaskWithDepthTestInstance(context, m_rasterizationSamples, m_enablePostDepthCoverage);
1548 }
1549 
1550 // RasterizationSamplesInstance
1551 
RasterizationSamplesInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,const TestModeFlags modeFlags,ImageBackingMode backingMode)1552 RasterizationSamplesInstance::RasterizationSamplesInstance (Context&										context,
1553 															VkPrimitiveTopology								topology,
1554 															float											pointSize,
1555 															const std::vector<Vertex4RGBA>&					vertices,
1556 															const VkPipelineMultisampleStateCreateInfo&		multisampleStateParams,
1557 															const VkPipelineColorBlendAttachmentState&		blendState,
1558 															const TestModeFlags								modeFlags,
1559 															ImageBackingMode								backingMode)
1560 	: vkt::TestInstance		(context)
1561 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
1562 	, m_renderSize			(32, 32)
1563 	, m_primitiveTopology	(topology)
1564 	, m_pointSize			(pointSize)
1565 	, m_vertices			(vertices)
1566 	, m_fullQuadVertices	(generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH))
1567 	, m_modeFlags			(modeFlags)
1568 {
1569 	if (m_modeFlags != 0)
1570 	{
1571 		const bool		useDepth			= (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0;
1572 		const bool		useStencil			= (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0;
1573 		const VkFormat	depthStencilFormat	= findSupportedDepthStencilFormat(context, useDepth, useStencil);
1574 
1575 		if (depthStencilFormat == VK_FORMAT_UNDEFINED)
1576 			TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported");
1577 
1578 		const VkPrimitiveTopology		pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };
1579 		const std::vector<Vertex4RGBA>	pVertices[2] = { m_vertices, m_fullQuadVertices };
1580 
1581 		m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
1582 			new MultisampleRenderer(
1583 				context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode));
1584 	}
1585 	else
1586 	{
1587 		m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
1588 			new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode));
1589 	}
1590 }
1591 
iterate(void)1592 tcu::TestStatus RasterizationSamplesInstance::iterate (void)
1593 {
1594 	de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render());
1595 	return verifyImage(level->getAccess());
1596 }
1597 
verifyImage(const tcu::ConstPixelBufferAccess & result)1598 tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
1599 {
1600 	// Verify range of unique pixels
1601 	{
1602 		const deUint32	numUniqueColors = getUniqueColorsCount(result);
1603 		const deUint32	minUniqueColors	= (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && m_pointSize == 1.0f) ? 2 : 3;
1604 
1605 		tcu::TestLog& log = m_context.getTestContext().getLog();
1606 
1607 		log << tcu::TestLog::Message
1608 			<< "\nMin. unique colors expected: " << minUniqueColors << "\n"
1609 			<< "Unique colors found: " << numUniqueColors << "\n"
1610 			<< tcu::TestLog::EndMessage;
1611 
1612 		if (numUniqueColors < minUniqueColors)
1613 			return tcu::TestStatus::fail("Unique colors out of expected bounds");
1614 	}
1615 
1616 	// Verify shape of the rendered primitive (fuzzy-compare)
1617 	{
1618 		const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
1619 		const tcu::TextureFormat	tcuDepthFormat	= tcu::TextureFormat();
1620 		const ColorVertexShader		vertexShader;
1621 		const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
1622 		const rr::Program			program			(&vertexShader, &fragmentShader);
1623 		ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
1624 		rr::RenderState				renderState		(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
1625 
1626 		if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
1627 		{
1628 			VkPhysicalDeviceProperties deviceProperties;
1629 
1630 			m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
1631 
1632 			// gl_PointSize is clamped to pointSizeRange
1633 			renderState.point.pointSize = deFloatMin(m_pointSize, deviceProperties.limits.pointSizeRange[1]);
1634 		}
1635 
1636 		if (m_modeFlags == 0)
1637 		{
1638 			refRenderer.colorClear(tcu::Vec4(0.0f));
1639 			refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
1640 		}
1641 		else
1642 		{
1643 			// For depth/stencil case the primitive is invisible and the surroundings are filled red.
1644 			refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1645 			refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
1646 		}
1647 
1648 		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT))
1649 			return tcu::TestStatus::fail("Primitive has unexpected shape");
1650 	}
1651 
1652 	return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds");
1653 }
1654 
1655 
1656 // MinSampleShadingInstance
1657 
MinSampleShadingInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState,ImageBackingMode backingMode)1658 MinSampleShadingInstance::MinSampleShadingInstance (Context&									context,
1659 													VkPrimitiveTopology							topology,
1660 													float										pointSize,
1661 													const std::vector<Vertex4RGBA>&				vertices,
1662 													const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1663 													const VkPipelineColorBlendAttachmentState&	colorBlendState,
1664 													ImageBackingMode							backingMode)
1665 	: vkt::TestInstance			(context)
1666 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
1667 	, m_renderSize				(32, 32)
1668 	, m_primitiveTopology		(topology)
1669 	, m_vertices				(vertices)
1670 	, m_multisampleStateParams	(multisampleStateParams)
1671 	, m_colorBlendState			(colorBlendState)
1672 	, m_backingMode				(backingMode)
1673 {
1674 	DE_UNREF(pointSize);
1675 }
1676 
iterate(void)1677 tcu::TestStatus MinSampleShadingInstance::iterate (void)
1678 {
1679 	de::MovePtr<tcu::TextureLevel>	noSampleshadingImage;
1680 	std::vector<tcu::TextureLevel>	sampleShadedImages;
1681 
1682 	// Render and resolve without sample shading
1683 	{
1684 		VkPipelineMultisampleStateCreateInfo multisampleStateParms = m_multisampleStateParams;
1685 		multisampleStateParms.sampleShadingEnable	= VK_FALSE;
1686 		multisampleStateParms.minSampleShading		= 0.0;
1687 
1688 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleStateParms, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1689 		noSampleshadingImage  = renderer.render();
1690 	}
1691 
1692 	// Render with test minSampleShading and collect per-sample images
1693 	{
1694 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES, m_backingMode);
1695 		renderer.render();
1696 
1697 		sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples);
1698 		for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
1699 		{
1700 			sampleShadedImages[sampleId] = *renderer.getSingleSampledImage(sampleId);
1701 		}
1702 	}
1703 
1704 	// Log images
1705 	{
1706 		tcu::TestLog& testLog	= m_context.getTestContext().getLog();
1707 
1708 		testLog << tcu::TestLog::ImageSet("Images", "Images")
1709 				<< tcu::TestLog::Image("noSampleshadingImage", "Image rendered without sample shading", noSampleshadingImage->getAccess());
1710 
1711 		for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
1712 		{
1713 			testLog << tcu::TestLog::Image("sampleShadedImage", "One sample of sample shaded image", sampleShadedImages[sampleId].getAccess());
1714 		}
1715 		testLog << tcu::TestLog::EndImageSet;
1716 	}
1717 
1718 	return verifySampleShadedImage(sampleShadedImages, noSampleshadingImage->getAccess());
1719 }
1720 
verifySampleShadedImage(const std::vector<tcu::TextureLevel> & sampleShadedImages,const tcu::ConstPixelBufferAccess & noSampleshadingImage)1721 tcu::TestStatus MinSampleShadingInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& noSampleshadingImage)
1722 {
1723 	const deUint32	pixelCount	= noSampleshadingImage.getWidth() * noSampleshadingImage.getHeight() * noSampleshadingImage.getDepth();
1724 
1725 	bool anyPixelCovered		= false;
1726 
1727 	for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
1728 	{
1729 		const deUint32 noSampleShadingValue = *((const deUint32*)noSampleshadingImage.getDataPtr() + pixelNdx);
1730 
1731 		if (noSampleShadingValue == 0)
1732 		{
1733 			// non-covered pixel, continue
1734 			continue;
1735 		}
1736 		else
1737 		{
1738 			anyPixelCovered = true;
1739 		}
1740 
1741 		int numNotCoveredSamples = 0;
1742 
1743 		std::map<deUint32, deUint32>	histogram; // map<pixel value, number of occurrences>
1744 
1745 		// Collect histogram of occurrences or each pixel across all samples
1746 		for (size_t i = 0; i < sampleShadedImages.size(); ++i)
1747 		{
1748 			const deUint32 sampleShadedValue = *((const deUint32*)sampleShadedImages[i].getAccess().getDataPtr() + pixelNdx);
1749 
1750 			if (sampleShadedValue == 0)
1751 			{
1752 				numNotCoveredSamples++;
1753 				continue;
1754 			}
1755 
1756 			if (histogram.find(sampleShadedValue) != histogram.end())
1757 				histogram[sampleShadedValue]++;
1758 			else
1759 				histogram[sampleShadedValue] = 1;
1760 		}
1761 
1762 		if (numNotCoveredSamples == static_cast<int>(sampleShadedImages.size()))
1763 		{
1764 			return tcu::TestStatus::fail("Got uncovered pixel, where covered samples were expected");
1765 		}
1766 
1767 		const int uniqueColorsCount				= (int)histogram.size();
1768 		const int expectedUniqueSamplesCount	= static_cast<int>(m_multisampleStateParams.minSampleShading * static_cast<float>(sampleShadedImages.size()) + 0.5f);
1769 
1770 		if (uniqueColorsCount + numNotCoveredSamples < expectedUniqueSamplesCount)
1771 		{
1772 			return tcu::TestStatus::fail("Got less unique colors than requested through minSampleShading");
1773 		}
1774 	}
1775 
1776 	if (!anyPixelCovered)
1777 	{
1778 		return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShading");
1779 	}
1780 
1781 	return tcu::TestStatus::pass("Got proper count of unique colors");
1782 }
1783 
MinSampleShadingDisabledInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,ImageBackingMode backingMode)1784 MinSampleShadingDisabledInstance::MinSampleShadingDisabledInstance	(Context&										context,
1785 																	 VkPrimitiveTopology							topology,
1786 																	 float											pointSize,
1787 																	 const std::vector<Vertex4RGBA>&				vertices,
1788 																	 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
1789 																	 const VkPipelineColorBlendAttachmentState&		blendState,
1790 																	 ImageBackingMode								backingMode)
1791 	: MinSampleShadingInstance	(context, topology, pointSize, vertices, multisampleStateParams, blendState, backingMode)
1792 {
1793 }
1794 
verifySampleShadedImage(const std::vector<tcu::TextureLevel> & sampleShadedImages,const tcu::ConstPixelBufferAccess & noSampleshadingImage)1795 tcu::TestStatus MinSampleShadingDisabledInstance::verifySampleShadedImage	(const std::vector<tcu::TextureLevel>&	sampleShadedImages,
1796 																			 const tcu::ConstPixelBufferAccess&		noSampleshadingImage)
1797 {
1798 	const deUint32		samplesCount		= (int)sampleShadedImages.size();
1799 	const deUint32		width				= noSampleshadingImage.getWidth();
1800 	const deUint32		height				= noSampleshadingImage.getHeight();
1801 	const deUint32		depth				= noSampleshadingImage.getDepth();
1802 	const tcu::UVec4	zeroPixel			= tcu::UVec4();
1803 	bool				anyPixelCovered		= false;
1804 
1805 	DE_ASSERT(depth == 1);
1806 	DE_UNREF(depth);
1807 
1808 	for (deUint32 y = 0; y < height; ++y)
1809 	for (deUint32 x = 0; x < width; ++x)
1810 	{
1811 		const tcu::UVec4	noSampleShadingValue	= noSampleshadingImage.getPixelUint(x, y);
1812 
1813 		if (noSampleShadingValue == zeroPixel)
1814 			continue;
1815 
1816 		anyPixelCovered = true;
1817 		tcu::UVec4	sampleShadingValue	= tcu::UVec4();
1818 
1819 		// Collect histogram of occurrences or each pixel across all samples
1820 		for (size_t i = 0; i < samplesCount; ++i)
1821 		{
1822 			const tcu::UVec4	sampleShadedValue	= sampleShadedImages[i].getAccess().getPixelUint(x, y);
1823 
1824 			sampleShadingValue += sampleShadedValue;
1825 		}
1826 
1827 		sampleShadingValue = sampleShadingValue / samplesCount;
1828 
1829 		if (sampleShadingValue.w() != 255)
1830 		{
1831 			return tcu::TestStatus::fail("Invalid Alpha channel value");
1832 		}
1833 
1834 		if (sampleShadingValue != noSampleShadingValue)
1835 		{
1836 			return tcu::TestStatus::fail("Invalid color");
1837 		}
1838 	}
1839 
1840 	if (!anyPixelCovered)
1841 	{
1842 		return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShadingDisabled");
1843 	}
1844 
1845 	return tcu::TestStatus::pass("Got proper count of unique colors");
1846 }
1847 
SampleMaskInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,ImageBackingMode backingMode)1848 SampleMaskInstance::SampleMaskInstance (Context&										context,
1849 										VkPrimitiveTopology								topology,
1850 										float											pointSize,
1851 										const std::vector<Vertex4RGBA>&					vertices,
1852 										const VkPipelineMultisampleStateCreateInfo&		multisampleStateParams,
1853 										const VkPipelineColorBlendAttachmentState&		blendState,
1854 										ImageBackingMode								backingMode)
1855 	: vkt::TestInstance			(context)
1856 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
1857 	, m_renderSize				(32, 32)
1858 	, m_primitiveTopology		(topology)
1859 	, m_vertices				(vertices)
1860 	, m_multisampleStateParams	(multisampleStateParams)
1861 	, m_colorBlendState			(blendState)
1862 	, m_backingMode				(backingMode)
1863 {
1864 	DE_UNREF(pointSize);
1865 }
1866 
iterate(void)1867 tcu::TestStatus SampleMaskInstance::iterate (void)
1868 {
1869 	de::MovePtr<tcu::TextureLevel>				testSampleMaskImage;
1870 	de::MovePtr<tcu::TextureLevel>				minSampleMaskImage;
1871 	de::MovePtr<tcu::TextureLevel>				maxSampleMaskImage;
1872 
1873 	// Render with test flags
1874 	{
1875 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1876 		testSampleMaskImage = renderer.render();
1877 	}
1878 
1879 	// Render with all flags off
1880 	{
1881 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
1882 		const std::vector<VkSampleMask>			sampleMask			(multisampleParams.rasterizationSamples / 32, (VkSampleMask)0);
1883 
1884 		multisampleParams.pSampleMask = sampleMask.data();
1885 
1886 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1887 		minSampleMaskImage = renderer.render();
1888 	}
1889 
1890 	// Render with all flags on
1891 	{
1892 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
1893 		const std::vector<VkSampleMask>			sampleMask			(multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0));
1894 
1895 		multisampleParams.pSampleMask = sampleMask.data();
1896 
1897 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1898 		maxSampleMaskImage = renderer.render();
1899 	}
1900 
1901 	return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess());
1902 }
1903 
verifyImage(const tcu::ConstPixelBufferAccess & testSampleMaskImage,const tcu::ConstPixelBufferAccess & minSampleMaskImage,const tcu::ConstPixelBufferAccess & maxSampleMaskImage)1904 tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage,
1905 												 const tcu::ConstPixelBufferAccess& minSampleMaskImage,
1906 												 const tcu::ConstPixelBufferAccess& maxSampleMaskImage)
1907 {
1908 	const deUint32	testColorCount	= getUniqueColorsCount(testSampleMaskImage);
1909 	const deUint32	minColorCount	= getUniqueColorsCount(minSampleMaskImage);
1910 	const deUint32	maxColorCount	= getUniqueColorsCount(maxSampleMaskImage);
1911 
1912 	tcu::TestLog& log = m_context.getTestContext().getLog();
1913 
1914 	log << tcu::TestLog::Message
1915 		<< "\nColors found: " << testColorCount << "\n"
1916 		<< "Min. colors expected: " << minColorCount << "\n"
1917 		<< "Max. colors expected: " << maxColorCount << "\n"
1918 		<< tcu::TestLog::EndMessage;
1919 
1920 	if (minColorCount > testColorCount || testColorCount > maxColorCount)
1921 		return tcu::TestStatus::fail("Unique colors out of expected bounds");
1922 	else
1923 		return tcu::TestStatus::pass("Unique colors within expected bounds");
1924 }
1925 
testRasterSamplesConsistency(Context & context,MultisampleTestParams params)1926 tcu::TestStatus testRasterSamplesConsistency (Context& context, MultisampleTestParams params)
1927 {
1928 	const VkSampleCountFlagBits samples[] =
1929 	{
1930 		VK_SAMPLE_COUNT_1_BIT,
1931 		VK_SAMPLE_COUNT_2_BIT,
1932 		VK_SAMPLE_COUNT_4_BIT,
1933 		VK_SAMPLE_COUNT_8_BIT,
1934 		VK_SAMPLE_COUNT_16_BIT,
1935 		VK_SAMPLE_COUNT_32_BIT,
1936 		VK_SAMPLE_COUNT_64_BIT
1937 	};
1938 
1939 	const Vertex4RGBA vertexData[3] =
1940 	{
1941 		{
1942 			tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
1943 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1944 		},
1945 		{
1946 			tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
1947 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1948 		},
1949 		{
1950 			tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
1951 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1952 		}
1953 	};
1954 
1955 	const std::vector<Vertex4RGBA>	vertices			(vertexData, vertexData + 3);
1956 	deUint32						prevUniqueColors	= 2;
1957 	int								renderCount			= 0;
1958 
1959 	// Do not render with 1 sample (start with samplesNdx = 1).
1960 	for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
1961 	{
1962 		if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx]))
1963 			continue;
1964 
1965 		const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1966 		{
1967 			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1968 			DE_NULL,													// const void*								pNext;
1969 			0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1970 			samples[samplesNdx],										// VkSampleCountFlagBits					rasterizationSamples;
1971 			false,														// VkBool32									sampleShadingEnable;
1972 			0.0f,														// float									minSampleShading;
1973 			DE_NULL,													// const VkSampleMask*						pSampleMask;
1974 			false,														// VkBool32									alphaToCoverageEnable;
1975 			false														// VkBool32									alphaToOneEnable;
1976 		};
1977 
1978 		MultisampleRenderer				renderer		(context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState(), RENDER_TYPE_RESOLVE, params.backingMode);
1979 		de::MovePtr<tcu::TextureLevel>	result			= renderer.render();
1980 		const deUint32					uniqueColors	= getUniqueColorsCount(result->getAccess());
1981 
1982 		renderCount++;
1983 
1984 		if (prevUniqueColors > uniqueColors)
1985 		{
1986 			std::ostringstream message;
1987 
1988 			message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx];
1989 			return tcu::TestStatus::fail(message.str());
1990 		}
1991 
1992 		prevUniqueColors = uniqueColors;
1993 	}
1994 
1995 	if (renderCount == 0)
1996 		throw tcu::NotSupportedError("Multisampling is unsupported");
1997 
1998 	return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases");
1999 }
2000 
2001 
2002 // AlphaToOneInstance
2003 
AlphaToOneInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,ImageBackingMode backingMode)2004 AlphaToOneInstance::AlphaToOneInstance (Context&									context,
2005 										VkPrimitiveTopology							topology,
2006 										const std::vector<Vertex4RGBA>&				vertices,
2007 										const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
2008 										const VkPipelineColorBlendAttachmentState&	blendState,
2009 										ImageBackingMode							backingMode)
2010 	: vkt::TestInstance			(context)
2011 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
2012 	, m_renderSize				(32, 32)
2013 	, m_primitiveTopology		(topology)
2014 	, m_vertices				(vertices)
2015 	, m_multisampleStateParams	(multisampleStateParams)
2016 	, m_colorBlendState			(blendState)
2017 	, m_backingMode				(backingMode)
2018 {
2019 }
2020 
iterate(void)2021 tcu::TestStatus AlphaToOneInstance::iterate	(void)
2022 {
2023 	DE_ASSERT(m_multisampleStateParams.alphaToOneEnable);
2024 	DE_ASSERT(m_colorBlendState.blendEnable);
2025 
2026 	de::MovePtr<tcu::TextureLevel>	alphaOneImage;
2027 	de::MovePtr<tcu::TextureLevel>	noAlphaOneImage;
2028 
2029 	// Render with blend enabled and alpha to one on
2030 	{
2031 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
2032 		alphaOneImage = renderer.render();
2033 	}
2034 
2035 	// Render with blend enabled and alpha to one off
2036 	{
2037 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
2038 		multisampleParams.alphaToOneEnable = false;
2039 
2040 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
2041 		noAlphaOneImage = renderer.render();
2042 	}
2043 
2044 	return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess());
2045 }
2046 
verifyImage(const tcu::ConstPixelBufferAccess & alphaOneImage,const tcu::ConstPixelBufferAccess & noAlphaOneImage)2047 tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess&	alphaOneImage,
2048 												 const tcu::ConstPixelBufferAccess&	noAlphaOneImage)
2049 {
2050 	for (int y = 0; y < m_renderSize.y(); y++)
2051 	{
2052 		for (int x = 0; x < m_renderSize.x(); x++)
2053 		{
2054 			if (alphaOneImage.getPixel(x, y).w() != 1.0)
2055 			{
2056 				std::ostringstream message;
2057 				message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " doesn't have alpha set to 1";
2058 				return tcu::TestStatus::fail(message.str());
2059 			}
2060 
2061 			if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y))))
2062 			{
2063 				std::ostringstream message;
2064 				message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y);
2065 				return tcu::TestStatus::fail(message.str());
2066 			}
2067 		}
2068 	}
2069 
2070 	return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one");
2071 }
2072 
2073 
2074 // AlphaToCoverageInstance
2075 
AlphaToCoverageInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,ImageBackingMode backingMode)2076 AlphaToCoverageInstance::AlphaToCoverageInstance (Context&										context,
2077 												  VkPrimitiveTopology							topology,
2078 												  const std::vector<Vertex4RGBA>&				vertices,
2079 												  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
2080 												  const VkPipelineColorBlendAttachmentState&	blendState,
2081 												  GeometryType									geometryType,
2082 												  ImageBackingMode								backingMode)
2083 	: vkt::TestInstance			(context)
2084 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
2085 	, m_renderSize				(32, 32)
2086 	, m_primitiveTopology		(topology)
2087 	, m_vertices				(vertices)
2088 	, m_multisampleStateParams	(multisampleStateParams)
2089 	, m_colorBlendState			(blendState)
2090 	, m_geometryType			(geometryType)
2091 	, m_backingMode				(backingMode)
2092 {
2093 }
2094 
iterate(void)2095 tcu::TestStatus AlphaToCoverageInstance::iterate (void)
2096 {
2097 	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2098 
2099 	de::MovePtr<tcu::TextureLevel>	result;
2100 	MultisampleRenderer				renderer	(m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
2101 
2102 	result = renderer.render();
2103 
2104 	return verifyImage(result->getAccess());
2105 }
2106 
verifyImage(const tcu::ConstPixelBufferAccess & result)2107 tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
2108 {
2109 	float maxColorValue;
2110 
2111 	switch (m_geometryType)
2112 	{
2113 		case GEOMETRY_TYPE_OPAQUE_QUAD:
2114 			maxColorValue = 1.01f;
2115 			break;
2116 
2117 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
2118 			maxColorValue = 0.52f;
2119 			break;
2120 
2121 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
2122 			maxColorValue = 0.01f;
2123 			break;
2124 
2125 		default:
2126 			maxColorValue = 0.0f;
2127 			DE_ASSERT(false);
2128 	}
2129 
2130 	for (int y = 0; y < m_renderSize.y(); y++)
2131 	{
2132 		for (int x = 0; x < m_renderSize.x(); x++)
2133 		{
2134 			if (result.getPixel(x, y).x() > maxColorValue)
2135 			{
2136 				std::ostringstream message;
2137 				message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")";
2138 				return tcu::TestStatus::fail(message.str());
2139 			}
2140 		}
2141 	}
2142 
2143 	return tcu::TestStatus::pass("Image matches reference value");
2144 }
2145 
2146 // AlphaToCoverageNoColorAttachmentInstance
2147 
AlphaToCoverageNoColorAttachmentInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,ImageBackingMode backingMode)2148 AlphaToCoverageNoColorAttachmentInstance::AlphaToCoverageNoColorAttachmentInstance (Context&									context,
2149 																					VkPrimitiveTopology							topology,
2150 																					const std::vector<Vertex4RGBA>&				vertices,
2151 																					const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
2152 																					const VkPipelineColorBlendAttachmentState&	blendState,
2153 																					GeometryType								geometryType,
2154 																					ImageBackingMode							backingMode)
2155 	: vkt::TestInstance			(context)
2156 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
2157 	, m_depthStencilFormat		(VK_FORMAT_D16_UNORM)
2158 	, m_renderSize				(32, 32)
2159 	, m_primitiveTopology		(topology)
2160 	, m_vertices				(vertices)
2161 	, m_multisampleStateParams	(multisampleStateParams)
2162 	, m_colorBlendState			(blendState)
2163 	, m_geometryType			(geometryType)
2164 	, m_backingMode				(backingMode)
2165 {
2166 }
2167 
iterate(void)2168 tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::iterate (void)
2169 {
2170 	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2171 
2172 	de::MovePtr<tcu::TextureLevel>	result;
2173 	MultisampleRenderer				renderer	(m_context, m_colorFormat, m_depthStencilFormat, m_renderSize, true, false, 1u, &m_primitiveTopology, &m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_DEPTHSTENCIL_ONLY, m_backingMode, 1.0f);
2174 
2175 	result = renderer.render();
2176 
2177 	return verifyImage(result->getAccess());
2178 }
2179 
verifyImage(const tcu::ConstPixelBufferAccess & result)2180 tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
2181 {
2182 	for (int y = 0; y < m_renderSize.y(); y++)
2183 	{
2184 		for (int x = 0; x < m_renderSize.x(); x++)
2185 		{
2186 			// Expect full red for each pixel. Fail if clear color is showing.
2187 			if (result.getPixel(x, y).x() < 1.0f)
2188 			{
2189 				// Log result image when failing.
2190 				m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;
2191 
2192 				return tcu::TestStatus::fail("Fail");
2193 			}
2194 		}
2195 	}
2196 
2197 	return tcu::TestStatus::pass("Pass");
2198 }
2199 
2200 // AlphaToCoverageColorUnusedAttachmentInstance
2201 
AlphaToCoverageColorUnusedAttachmentInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,ImageBackingMode backingMode)2202 AlphaToCoverageColorUnusedAttachmentInstance::AlphaToCoverageColorUnusedAttachmentInstance (Context&									context,
2203 																							VkPrimitiveTopology							topology,
2204 																							const std::vector<Vertex4RGBA>&				vertices,
2205 																							const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
2206 																							const VkPipelineColorBlendAttachmentState&	blendState,
2207 																							GeometryType								geometryType,
2208 																							ImageBackingMode							backingMode)
2209 	: vkt::TestInstance			(context)
2210 	, m_colorFormat				(VK_FORMAT_R5G6B5_UNORM_PACK16)
2211 	, m_renderSize				(32, 32)
2212 	, m_primitiveTopology		(topology)
2213 	, m_vertices				(vertices)
2214 	, m_multisampleStateParams	(multisampleStateParams)
2215 	, m_colorBlendState			(blendState)
2216 	, m_geometryType			(geometryType)
2217 	, m_backingMode				(backingMode)
2218 {
2219 }
2220 
iterate(void)2221 tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::iterate (void)
2222 {
2223 	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2224 
2225 	de::MovePtr<tcu::TextureLevel>	result;
2226 	MultisampleRenderer				renderer	(m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_UNUSED_ATTACHMENT, m_backingMode);
2227 
2228 	result = renderer.render();
2229 
2230 	return verifyImage(result->getAccess());
2231 }
2232 
verifyImage(const tcu::ConstPixelBufferAccess & result)2233 tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
2234 {
2235 	for (int y = 0; y < m_renderSize.y(); y++)
2236 	{
2237 		for (int x = 0; x < m_renderSize.x(); x++)
2238 		{
2239 			// Quad color gets written to color buffer at location 1, and the alpha value to location 0 which is unused.
2240 			// The coverage should still be affected by the alpha written to location 0.
2241 			if ((m_geometryType == GEOMETRY_TYPE_OPAQUE_QUAD && result.getPixel(x, y).x() < 1.0f)
2242 				|| (m_geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD && result.getPixel(x, y).x() > 0.0f))
2243 			{
2244 				// Log result image when failing.
2245 				m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;
2246 
2247 				return tcu::TestStatus::fail("Fail");
2248 			}
2249 		}
2250 	}
2251 
2252 	return tcu::TestStatus::pass("Pass");
2253 }
2254 
2255 // SampleMaskWithDepthTestInstance
2256 
SampleMaskWithDepthTestInstance(Context & context,const VkSampleCountFlagBits rasterizationSamples,const bool enablePostDepthCoverage)2257 SampleMaskWithDepthTestInstance::SampleMaskWithDepthTestInstance (Context&						context,
2258 																  const VkSampleCountFlagBits	rasterizationSamples,
2259 																  const bool					enablePostDepthCoverage)
2260 	: vkt::TestInstance			(context)
2261 	, m_rasterizationSamples	(rasterizationSamples)
2262 	, m_enablePostDepthCoverage	(enablePostDepthCoverage)
2263 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
2264 	, m_depthStencilFormat		(VK_FORMAT_D16_UNORM)
2265 	, m_renderSize				(tcu::IVec2(3, 3))
2266 	, m_useDepth				(true)
2267 	, m_useStencil				(false)
2268 	, m_topology				(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
2269 	, m_renderColor				(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f))
2270 	, m_vertices				(generateVertices())
2271 	, m_multisampleStateParams	(getMultisampleState(rasterizationSamples))
2272 	, m_blendState				(getDefaultColorBlendAttachmentState())
2273 	, m_renderType				(RENDER_TYPE_RESOLVE)
2274 	, m_imageBackingMode		(IMAGE_BACKING_MODE_REGULAR)
2275 	, m_depthClearValue			(0.667f)
2276 {
2277 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_2_BIT]	= SampleCoverage(1u, 1u);	// !< Sample coverage of the diagonally halved pixel,
2278 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_4_BIT]	= SampleCoverage(2u, 2u);	// !< with max possible subPixelPrecisionBits threshold
2279 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_8_BIT]	= SampleCoverage(2u, 6u);	// !<
2280 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_16_BIT]	= SampleCoverage(6u, 11u);	// !<
2281 }
2282 
iterate(void)2283 tcu::TestStatus SampleMaskWithDepthTestInstance::iterate (void)
2284 {
2285 	de::MovePtr<tcu::TextureLevel>	result;
2286 
2287 	MultisampleRenderer renderer (m_context, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, 1u, &m_topology,
2288 								  &m_vertices, m_multisampleStateParams, m_blendState, m_renderType, m_imageBackingMode, m_depthClearValue);
2289 	result = renderer.render();
2290 
2291 	return verifyImage(result->getAccess());
2292 }
2293 
getMultisampleState(const VkSampleCountFlagBits rasterizationSamples)2294 VkPipelineMultisampleStateCreateInfo SampleMaskWithDepthTestInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples)
2295 {
2296 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2297 	{
2298 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
2299 		DE_NULL,													// const void*								pNext;
2300 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
2301 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
2302 		false,														// VkBool32									sampleShadingEnable;
2303 		0.0f,														// float									minSampleShading;
2304 		DE_NULL,													// const VkSampleMask*						pSampleMask;
2305 		false,														// VkBool32									alphaToCoverageEnable;
2306 		false														// VkBool32									alphaToOneEnable;
2307 	};
2308 
2309 	return multisampleStateParams;
2310 }
2311 
generateVertices(void)2312 std::vector<Vertex4RGBA> SampleMaskWithDepthTestInstance::generateVertices (void)
2313 {
2314 	std::vector<Vertex4RGBA> vertices;
2315 
2316 	{
2317 		const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor };
2318 		vertices.push_back(vertexInput);
2319 	}
2320 	{
2321 		const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor };
2322 		vertices.push_back(vertexInput);
2323 	}
2324 	{
2325 		const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f,  1.0f, 1.0f, 1.0f), m_renderColor };
2326 		vertices.push_back(vertexInput);
2327 	}
2328 
2329 	return vertices;
2330 }
2331 
verifyImage(const tcu::ConstPixelBufferAccess & result)2332 tcu::TestStatus SampleMaskWithDepthTestInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
2333 {
2334 	bool			pass	= true;
2335 	const int		width	= result.getWidth();
2336 	const int		height	= result.getHeight();
2337 	tcu::TestLog&	log		= m_context.getTestContext().getLog();
2338 
2339 	DE_ASSERT(width == 3);
2340 	DE_ASSERT(height == 3);
2341 
2342 	const tcu::Vec4 clearColor = tcu::Vec4(0.0f);
2343 
2344 	for (int x = 0; x < width; ++x)
2345 	for (int y = 0; y < height; ++y)
2346 	{
2347 		const tcu::Vec4 resultPixel = result.getPixel(x, y);
2348 
2349 		if (x + y == 0)
2350 		{
2351 			if (resultPixel != m_renderColor)
2352 			{
2353 				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
2354 					<< " Reference: " << m_renderColor << tcu::TestLog::EndMessage;
2355 				pass = false;
2356 			}
2357 		}
2358 		else if (x + y == 1)
2359 		{
2360 			// default: m_rasterizationSamples bits set in FS's gl_SampleMaskIn[0] (before depth test)
2361 			// post_depth_coverage: m_refCoverageAfterDepthTest[m_rasterizationSamples] bits set in FS's gl_SampleMaskIn[0] (after depth test)
2362 			const float		threshold	= 0.02f;
2363 			const float		minCoverage	= (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples : 1.0f)
2364 										* ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples);
2365 			const float		maxCoverage	= (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples : 1.0f)
2366 										* ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples);
2367 
2368 			bool			localPass	= true;
2369 			for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx)
2370 			{
2371 				if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= m_renderColor[componentNdx] * (minCoverage - threshold)
2372 															|| resultPixel[componentNdx] >= m_renderColor[componentNdx] * (maxCoverage + threshold)))
2373 					localPass = false;
2374 			}
2375 
2376 			if (!localPass)
2377 			{
2378 				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
2379 					<< " Reference range ( " << m_renderColor * (minCoverage - threshold) << " ; " << m_renderColor * (maxCoverage + threshold) << " )" << tcu::TestLog::EndMessage;
2380 				pass = false;
2381 			}
2382 		}
2383 		else
2384 		{
2385 			if (resultPixel != clearColor)
2386 			{
2387 				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
2388 					<< " Reference: " << clearColor << tcu::TestLog::EndMessage;
2389 				pass = false;
2390 			}
2391 		}
2392 	}
2393 
2394 	if (pass)
2395 		return tcu::TestStatus::pass("Passed");
2396 	else
2397 		return tcu::TestStatus::fail("Failed");
2398 }
2399 
2400 // MultisampleRenderer
2401 
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)2402 MultisampleRenderer::MultisampleRenderer (Context&										context,
2403 										  const VkFormat								colorFormat,
2404 										  const tcu::IVec2&								renderSize,
2405 										  const VkPrimitiveTopology						topology,
2406 										  const std::vector<Vertex4RGBA>&				vertices,
2407 										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
2408 										  const VkPipelineColorBlendAttachmentState&	blendState,
2409 										  const RenderType								renderType,
2410 										  const ImageBackingMode						backingMode)
2411 	: m_context					(context)
2412 	, m_bindSemaphore			(createSemaphore(context.getDeviceInterface(), context.getDevice()))
2413 	, m_colorFormat				(colorFormat)
2414 	, m_depthStencilFormat		(VK_FORMAT_UNDEFINED)
2415 	, m_renderSize				(renderSize)
2416 	, m_useDepth				(false)
2417 	, m_useStencil				(false)
2418 	, m_multisampleStateParams	(multisampleStateParams)
2419 	, m_colorBlendState			(blendState)
2420 	, m_renderType				(renderType)
2421 	, m_backingMode				(backingMode)
2422 	, m_depthClearValue			(1.0f)
2423 {
2424 	initialize(context, 1u, &topology, &vertices);
2425 }
2426 
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)2427 MultisampleRenderer::MultisampleRenderer (Context&										context,
2428 										  const VkFormat								colorFormat,
2429 										  const VkFormat								depthStencilFormat,
2430 										  const tcu::IVec2&								renderSize,
2431 										  const bool									useDepth,
2432 										  const bool									useStencil,
2433 										  const deUint32								numTopologies,
2434 										  const VkPrimitiveTopology*					pTopology,
2435 										  const std::vector<Vertex4RGBA>*				pVertices,
2436 										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
2437 										  const VkPipelineColorBlendAttachmentState&	blendState,
2438 										  const RenderType								renderType,
2439 										  const ImageBackingMode						backingMode,
2440 										  const float									depthClearValue)
2441 	: m_context					(context)
2442 	, m_bindSemaphore			(createSemaphore(context.getDeviceInterface(), context.getDevice()))
2443 	, m_colorFormat				(colorFormat)
2444 	, m_depthStencilFormat		(depthStencilFormat)
2445 	, m_renderSize				(renderSize)
2446 	, m_useDepth				(useDepth)
2447 	, m_useStencil				(useStencil)
2448 	, m_multisampleStateParams	(multisampleStateParams)
2449 	, m_colorBlendState			(blendState)
2450 	, m_renderType				(renderType)
2451 	, m_backingMode				(backingMode)
2452 	, m_depthClearValue			(depthClearValue)
2453 {
2454 	initialize(context, numTopologies, pTopology, pVertices);
2455 }
2456 
initialize(Context & context,const deUint32 numTopologies,const VkPrimitiveTopology * pTopology,const std::vector<Vertex4RGBA> * pVertices)2457 void MultisampleRenderer::initialize (Context&									context,
2458 									  const deUint32							numTopologies,
2459 									  const VkPrimitiveTopology*				pTopology,
2460 									  const std::vector<Vertex4RGBA>*			pVertices)
2461 {
2462 	if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples))
2463 		throw tcu::NotSupportedError("Unsupported number of rasterization samples");
2464 
2465 	const DeviceInterface&			vk						= context.getDeviceInterface();
2466 	const VkDevice					vkDevice				= context.getDevice();
2467 	const VkPhysicalDeviceFeatures	features				= context.getDeviceFeatures();
2468 	const deUint32					queueFamilyIndices[]	= { context.getUniversalQueueFamilyIndex(), context.getSparseQueueFamilyIndex() };
2469 	const bool						sparse					= m_backingMode == IMAGE_BACKING_MODE_SPARSE;
2470 	const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
2471 	const VkImageCreateFlags		imageCreateFlags		= sparse ? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0u;
2472 	const VkSharingMode				sharingMode				= (sparse && context.getUniversalQueueFamilyIndex() != context.getSparseQueueFamilyIndex()) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
2473 	Allocator&						memAlloc				= m_context.getDefaultAllocator();
2474 	const bool						usesResolveImage		= m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT;
2475 
2476 	if (sparse)
2477 	{
2478 		bool sparseSamplesSupported = false;
2479 		switch(m_multisampleStateParams.rasterizationSamples)
2480 		{
2481 			case VK_SAMPLE_COUNT_2_BIT:
2482 				sparseSamplesSupported = features.sparseResidency2Samples;
2483 				break;
2484 			case VK_SAMPLE_COUNT_4_BIT:
2485 				sparseSamplesSupported = features.sparseResidency4Samples;
2486 				break;
2487 			case VK_SAMPLE_COUNT_8_BIT:
2488 				sparseSamplesSupported = features.sparseResidency8Samples;
2489 				break;
2490 			case VK_SAMPLE_COUNT_16_BIT:
2491 				sparseSamplesSupported = features.sparseResidency16Samples;
2492 				break;
2493 			default:
2494 				break;
2495 		}
2496 
2497 		if (!sparseSamplesSupported)
2498 			throw tcu::NotSupportedError("Unsupported number of rasterization samples for sparse residency");
2499 	}
2500 
2501 	if (sparse && !context.getDeviceFeatures().sparseBinding)
2502 		throw tcu::NotSupportedError("No sparseBinding support");
2503 
2504 	// Create color image
2505 	{
2506 		const VkImageUsageFlags	imageUsageFlags		= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2507 			(m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u);
2508 
2509 		const VkImageCreateInfo colorImageParams	=
2510 		{
2511 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
2512 			DE_NULL,																	// const void*				pNext;
2513 			imageCreateFlags,															// VkImageCreateFlags		flags;
2514 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
2515 			m_colorFormat,																// VkFormat					format;
2516 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },				// VkExtent3D				extent;
2517 			1u,																			// deUint32					mipLevels;
2518 			1u,																			// deUint32					arrayLayers;
2519 			m_multisampleStateParams.rasterizationSamples,								// VkSampleCountFlagBits	samples;
2520 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
2521 			imageUsageFlags,															// VkImageUsageFlags		usage;
2522 			sharingMode,																// VkSharingMode			sharingMode;
2523 			sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u,						// deUint32					queueFamilyIndexCount;
2524 			queueFamilyIndices,															// const deUint32*			pQueueFamilyIndices;
2525 			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
2526 		};
2527 
2528 		if (sparse && !checkSparseImageFormatSupport(context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams))
2529 			TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");
2530 
2531 		m_colorImage = createImage(vk, vkDevice, &colorImageParams);
2532 
2533 		// Allocate and bind color image memory
2534 		if (sparse)
2535 		{
2536 			allocateAndBindSparseImage(vk, vkDevice, context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams, *m_bindSemaphore, context.getSparseQueue(), memAlloc, m_allocations, mapVkFormat(m_colorFormat), *m_colorImage);
2537 		}
2538 		else
2539 		{
2540 			m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
2541 			VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
2542 		}
2543 	}
2544 
2545 	// Create resolve image
2546 	if (usesResolveImage)
2547 	{
2548 		const VkImageCreateInfo resolveImageParams =
2549 		{
2550 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
2551 			DE_NULL,																		// const void*				pNext;
2552 			0u,																				// VkImageCreateFlags		flags;
2553 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
2554 			m_colorFormat,																	// VkFormat					format;
2555 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
2556 			1u,																				// deUint32					mipLevels;
2557 			1u,																				// deUint32					arrayLayers;
2558 			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
2559 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
2560 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |			// VkImageUsageFlags		usage;
2561 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2562 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
2563 			1u,																				// deUint32					queueFamilyIndexCount;
2564 			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
2565 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
2566 		};
2567 
2568 		m_resolveImage = createImage(vk, vkDevice, &resolveImageParams);
2569 
2570 		// Allocate and bind resolve image memory
2571 		m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any);
2572 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset()));
2573 
2574 		// Create resolve attachment view
2575 		{
2576 			const VkImageViewCreateInfo resolveAttachmentViewParams =
2577 			{
2578 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
2579 				DE_NULL,										// const void*				pNext;
2580 				0u,												// VkImageViewCreateFlags	flags;
2581 				*m_resolveImage,								// VkImage					image;
2582 				VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
2583 				m_colorFormat,									// VkFormat					format;
2584 				componentMappingRGBA,							// VkComponentMapping		components;
2585 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2586 			};
2587 
2588 			m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
2589 		}
2590 	}
2591 
2592 	// Create per-sample output images
2593 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2594 	{
2595 		const VkImageCreateInfo perSampleImageParams =
2596 		{
2597 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
2598 			DE_NULL,																		// const void*				pNext;
2599 			0u,																				// VkImageCreateFlags		flags;
2600 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
2601 			m_colorFormat,																	// VkFormat					format;
2602 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
2603 			1u,																				// deUint32					mipLevels;
2604 			1u,																				// deUint32					arrayLayers;
2605 			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
2606 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
2607 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |			// VkImageUsageFlags		usage;
2608 			VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2609 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
2610 			1u,																				// deUint32					queueFamilyIndexCount;
2611 			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
2612 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
2613 		};
2614 
2615 		m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples));
2616 
2617 		for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2618 		{
2619 			m_perSampleImages[i]	= de::SharedPtr<PerSampleImage>(new PerSampleImage);
2620 			PerSampleImage& image	= *m_perSampleImages[i];
2621 
2622 			image.m_image			= createImage(vk, vkDevice, &perSampleImageParams);
2623 
2624 			// Allocate and bind image memory
2625 			image.m_imageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any);
2626 			VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset()));
2627 
2628 			// Create per-sample attachment view
2629 			{
2630 				const VkImageViewCreateInfo perSampleAttachmentViewParams =
2631 				{
2632 					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
2633 					DE_NULL,										// const void*				pNext;
2634 					0u,												// VkImageViewCreateFlags	flags;
2635 					*image.m_image,									// VkImage					image;
2636 					VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
2637 					m_colorFormat,									// VkFormat					format;
2638 					componentMappingRGBA,							// VkComponentMapping		components;
2639 					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2640 				};
2641 
2642 				image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams);
2643 			}
2644 		}
2645 	}
2646 
2647 	// Create a depth/stencil image
2648 	if (m_useDepth || m_useStencil)
2649 	{
2650 		const VkImageCreateInfo depthStencilImageParams =
2651 		{
2652 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
2653 			DE_NULL,																		// const void*				pNext;
2654 			0u,																				// VkImageCreateFlags		flags;
2655 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
2656 			m_depthStencilFormat,															// VkFormat					format;
2657 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
2658 			1u,																				// deUint32					mipLevels;
2659 			1u,																				// deUint32					arrayLayers;
2660 			m_multisampleStateParams.rasterizationSamples,									// VkSampleCountFlagBits	samples;
2661 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
2662 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,									// VkImageUsageFlags		usage;
2663 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
2664 			1u,																				// deUint32					queueFamilyIndexCount;
2665 			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
2666 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
2667 		};
2668 
2669 		m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams);
2670 
2671 		// Allocate and bind depth/stencil image memory
2672 		m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any);
2673 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset()));
2674 	}
2675 
2676 	// Create color attachment view
2677 	{
2678 		const VkImageViewCreateInfo colorAttachmentViewParams =
2679 		{
2680 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
2681 			DE_NULL,										// const void*				pNext;
2682 			0u,												// VkImageViewCreateFlags	flags;
2683 			*m_colorImage,									// VkImage					image;
2684 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
2685 			m_colorFormat,									// VkFormat					format;
2686 			componentMappingRGBA,							// VkComponentMapping		components;
2687 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2688 		};
2689 
2690 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
2691 	}
2692 
2693 	VkImageAspectFlags	depthStencilAttachmentAspect	= (VkImageAspectFlagBits)0;
2694 
2695 	// Create depth/stencil attachment view
2696 	if (m_useDepth || m_useStencil)
2697 	{
2698 		depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat);
2699 
2700 		const VkImageViewCreateInfo depthStencilAttachmentViewParams =
2701 		{
2702 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
2703 			DE_NULL,											// const void*				pNext;
2704 			0u,													// VkImageViewCreateFlags	flags;
2705 			*m_depthStencilImage,								// VkImage					image;
2706 			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
2707 			m_depthStencilFormat,								// VkFormat					format;
2708 			componentMappingRGBA,								// VkComponentMapping		components;
2709 			{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2710 		};
2711 
2712 		m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
2713 	}
2714 
2715 	// Create render pass
2716 	{
2717 		std::vector<VkAttachmentDescription> attachmentDescriptions;
2718 		{
2719 			const VkAttachmentDescription colorAttachmentDescription =
2720 			{
2721 				0u,													// VkAttachmentDescriptionFlags		flags;
2722 				m_colorFormat,										// VkFormat							format;
2723 				m_multisampleStateParams.rasterizationSamples,		// VkSampleCountFlagBits			samples;
2724 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
2725 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
2726 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
2727 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
2728 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
2729 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
2730 			};
2731 			attachmentDescriptions.push_back(colorAttachmentDescription);
2732 		}
2733 
2734 		deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED;
2735 
2736 		if (usesResolveImage)
2737 		{
2738 			resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2739 
2740 			const VkAttachmentDescription resolveAttachmentDescription =
2741 			{
2742 				0u,													// VkAttachmentDescriptionFlags		flags;
2743 				m_colorFormat,										// VkFormat							format;
2744 				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
2745 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
2746 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
2747 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
2748 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
2749 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
2750 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
2751 			};
2752 			attachmentDescriptions.push_back(resolveAttachmentDescription);
2753 		}
2754 
2755 		deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED;
2756 
2757 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2758 		{
2759 			perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2760 
2761 			const VkAttachmentDescription perSampleAttachmentDescription =
2762 			{
2763 				0u,													// VkAttachmentDescriptionFlags		flags;
2764 				m_colorFormat,										// VkFormat							format;
2765 				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
2766 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
2767 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
2768 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
2769 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
2770 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
2771 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
2772 			};
2773 
2774 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2775 			{
2776 				attachmentDescriptions.push_back(perSampleAttachmentDescription);
2777 			}
2778 		}
2779 
2780 		deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
2781 
2782 		if (m_useDepth || m_useStencil)
2783 		{
2784 			depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2785 
2786 			const VkAttachmentDescription depthStencilAttachmentDescription =
2787 			{
2788 				0u,																					// VkAttachmentDescriptionFlags		flags;
2789 				m_depthStencilFormat,																// VkFormat							format;
2790 				m_multisampleStateParams.rasterizationSamples,										// VkSampleCountFlagBits			samples;
2791 				(m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentLoadOp				loadOp;
2792 				(m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),		// VkAttachmentStoreOp				storeOp;
2793 				(m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentStoreOp				stencilLoadOp;
2794 				(m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),	// VkAttachmentStoreOp				stencilStoreOp;
2795 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,									// VkImageLayout					initialLayout;
2796 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL									// VkImageLayout					finalLayout;
2797 			};
2798 			attachmentDescriptions.push_back(depthStencilAttachmentDescription);
2799 		};
2800 
2801 		const VkAttachmentReference colorAttachmentReference =
2802 		{
2803 			0u,													// deUint32			attachment;
2804 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
2805 		};
2806 
2807 		const VkAttachmentReference inputAttachmentReference =
2808 		{
2809 			0u,													// deUint32			attachment;
2810 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL			// VkImageLayout	layout;
2811 		};
2812 
2813 		const VkAttachmentReference resolveAttachmentReference =
2814 		{
2815 			resolveAttachmentIndex,								// deUint32			attachment;
2816 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
2817 		};
2818 
2819 		const VkAttachmentReference colorAttachmentReferencesUnusedAttachment[] =
2820 		{
2821 			{
2822 				VK_ATTACHMENT_UNUSED,		// deUint32			attachment
2823 				VK_IMAGE_LAYOUT_UNDEFINED	// VkImageLayout	layout
2824 			},
2825 			{
2826 				0u,											// deUint32			attachment
2827 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
2828 			}
2829 		};
2830 
2831 		const VkAttachmentReference resolveAttachmentReferencesUnusedAttachment[] =
2832 		{
2833 			{
2834 				VK_ATTACHMENT_UNUSED,		// deUint32			attachment
2835 				VK_IMAGE_LAYOUT_UNDEFINED	// VkImageLayout	layout
2836 			},
2837 			{
2838 				resolveAttachmentIndex,						// deUint32			attachment
2839 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
2840 			}
2841 		};
2842 
2843 		std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size());
2844 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2845 		{
2846 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2847 			{
2848 				const VkAttachmentReference perSampleAttachmentReference =
2849 				{
2850 					perSampleAttachmentIndex + static_cast<deUint32>(i),	// deUint32			attachment;
2851 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL				// VkImageLayout	layout;
2852 				};
2853 				perSampleAttachmentReferences[i] = perSampleAttachmentReference;
2854 			}
2855 		}
2856 
2857 		const VkAttachmentReference depthStencilAttachmentReference =
2858 		{
2859 			depthStencilAttachmentIndex,						// deUint32			attachment;
2860 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
2861 		};
2862 
2863 		std::vector<VkSubpassDescription>	subpassDescriptions;
2864 		std::vector<VkSubpassDependency>	subpassDependencies;
2865 
2866 		if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
2867 		{
2868 				const VkSubpassDescription	subpassDescription0	=
2869 				{
2870 					0u,										// VkSubpassDescriptionFlags	flags
2871 					VK_PIPELINE_BIND_POINT_GRAPHICS,		// VkPipelineBindPoint			pipelineBindPoint
2872 					0u,										// deUint32						inputAttachmentCount
2873 					DE_NULL,								// const VkAttachmentReference*	pInputAttachments
2874 					0u,										// deUint32						colorAttachmentCount
2875 					DE_NULL,								// const VkAttachmentReference*	pColorAttachments
2876 					DE_NULL,								// const VkAttachmentReference*	pResolveAttachments
2877 					&depthStencilAttachmentReference,		// const VkAttachmentReference*	pDepthStencilAttachment
2878 					0u,										// deUint32						preserveAttachmentCount
2879 					DE_NULL									// const VkAttachmentReference*	pPreserveAttachments
2880 				};
2881 
2882 				const VkSubpassDescription	subpassDescription1	=
2883 				{
2884 					0u,									// VkSubpassDescriptionFlags	flags
2885 					VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint
2886 					0u,									// deUint32						inputAttachmentCount
2887 					DE_NULL,							// const VkAttachmentReference*	pInputAttachments
2888 					1u,									// deUint32						colorAttachmentCount
2889 					&colorAttachmentReference,			// const VkAttachmentReference*	pColorAttachments
2890 					&resolveAttachmentReference,		// const VkAttachmentReference*	pResolveAttachments
2891 					&depthStencilAttachmentReference,	// const VkAttachmentReference*	pDepthStencilAttachment
2892 					0u,									// deUint32						preserveAttachmentCount
2893 					DE_NULL								// const VkAttachmentReference*	pPreserveAttachments
2894 				};
2895 
2896 				const VkSubpassDependency	subpassDependency	=
2897 				{
2898 					0u,												// deUint32				srcSubpass
2899 					1u,												// deUint32				dstSubpass
2900 					VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,		// VkPipelineStageFlags	srcStageMask
2901 					VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,		// VkPipelineStageFlags	dstStageMask
2902 					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,	// VkAccessFlags		srcAccessMask
2903 					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,	// VkAccessFlags		dstAccessMask
2904 					0u												// VkDependencyFlags	dependencyFlags
2905 				};
2906 
2907 				subpassDescriptions.push_back(subpassDescription0);
2908 				subpassDescriptions.push_back(subpassDescription1);
2909 				subpassDependencies.push_back(subpassDependency);
2910 		}
2911 		else if (m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
2912 		{
2913 			const VkSubpassDescription renderSubpassDescription =
2914 			{
2915 				0u,												// VkSubpassDescriptionFlags	flags
2916 				VK_PIPELINE_BIND_POINT_GRAPHICS,				// VkPipelineBindPoint			pipelineBindPoint
2917 				0u,												// deUint32						inputAttachmentCount
2918 				DE_NULL,										// const VkAttachmentReference*	pInputAttachments
2919 				2u,												// deUint32						colorAttachmentCount
2920 				colorAttachmentReferencesUnusedAttachment,		// const VkAttachmentReference*	pColorAttachments
2921 				resolveAttachmentReferencesUnusedAttachment,	// const VkAttachmentReference*	pResolveAttachments
2922 				DE_NULL,										// const VkAttachmentReference*	pDepthStencilAttachment
2923 				0u,												// deUint32						preserveAttachmentCount
2924 				DE_NULL											// const VkAttachmentReference*	pPreserveAttachments
2925 			};
2926 
2927 			subpassDescriptions.push_back(renderSubpassDescription);
2928 		}
2929 		else
2930 		{
2931 			{
2932 				const VkSubpassDescription renderSubpassDescription =
2933 				{
2934 					0u,																				// VkSubpassDescriptionFlags	flags;
2935 					VK_PIPELINE_BIND_POINT_GRAPHICS,												// VkPipelineBindPoint			pipelineBindPoint;
2936 					0u,																				// deUint32						inputAttachmentCount;
2937 					DE_NULL,																		// const VkAttachmentReference*	pInputAttachments;
2938 					1u,																				// deUint32						colorAttachmentCount;
2939 					&colorAttachmentReference,														// const VkAttachmentReference*	pColorAttachments;
2940 					usesResolveImage ? &resolveAttachmentReference : DE_NULL,						// const VkAttachmentReference*	pResolveAttachments;
2941 					(m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL),		// const VkAttachmentReference*	pDepthStencilAttachment;
2942 					0u,																				// deUint32						preserveAttachmentCount;
2943 					DE_NULL																			// const VkAttachmentReference*	pPreserveAttachments;
2944 				};
2945 				subpassDescriptions.push_back(renderSubpassDescription);
2946 			}
2947 
2948 			if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2949 			{
2950 
2951 				for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2952 				{
2953 					const VkSubpassDescription copySampleSubpassDescription =
2954 					{
2955 						0u,													// VkSubpassDescriptionFlags		flags;
2956 						VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
2957 						1u,													// deUint32							inputAttachmentCount;
2958 						&inputAttachmentReference,							// const VkAttachmentReference*		pInputAttachments;
2959 						1u,													// deUint32							colorAttachmentCount;
2960 						&perSampleAttachmentReferences[i],					// const VkAttachmentReference*		pColorAttachments;
2961 						DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
2962 						DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
2963 						0u,													// deUint32							preserveAttachmentCount;
2964 						DE_NULL												// const VkAttachmentReference*		pPreserveAttachments;
2965 					};
2966 					subpassDescriptions.push_back(copySampleSubpassDescription);
2967 
2968 					const VkSubpassDependency copySampleSubpassDependency =
2969 					{
2970 						0u,													// deUint32							srcSubpass
2971 						1u + static_cast<deUint32>(i),						// deUint32							dstSubpass
2972 						VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,		// VkPipelineStageFlags				srcStageMask
2973 						VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,				// VkPipelineStageFlags				dstStageMask
2974 						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags					srcAccessMask
2975 						VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,				// VkAccessFlags					dstAccessMask
2976 						0u,													// VkDependencyFlags				dependencyFlags
2977 					};
2978 					subpassDependencies.push_back(copySampleSubpassDependency);
2979 				}
2980 				// the very last sample pass must synchronize with all prior subpasses
2981 				for (size_t i = 0; i < (m_perSampleImages.size() - 1); ++i)
2982 				{
2983 					const VkSubpassDependency storeSubpassDependency =
2984 					{
2985 						1u + static_cast<deUint32>(i),						// deUint32							srcSubpass
2986 						static_cast<deUint32>(m_perSampleImages.size()),    // deUint32							dstSubpass
2987 						VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,		// VkPipelineStageFlags				srcStageMask
2988 						VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,				// VkPipelineStageFlags				dstStageMask
2989 						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags					srcAccessMask
2990 						VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,				// VkAccessFlags					dstAccessMask
2991 						0u,													// VkDependencyFlags				dependencyFlags
2992 					};
2993 					subpassDependencies.push_back(storeSubpassDependency);
2994 				}
2995 			}
2996 		}
2997 
2998 		const VkRenderPassCreateInfo renderPassParams =
2999 		{
3000 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,					// VkStructureType					sType;
3001 			DE_NULL,													// const void*						pNext;
3002 			0u,															// VkRenderPassCreateFlags			flags;
3003 			(deUint32)attachmentDescriptions.size(),					// deUint32							attachmentCount;
3004 			&attachmentDescriptions[0],									// const VkAttachmentDescription*	pAttachments;
3005 			(deUint32)subpassDescriptions.size(),						// deUint32							subpassCount;
3006 			&subpassDescriptions[0],									// const VkSubpassDescription*		pSubpasses;
3007 			(deUint32)subpassDependencies.size(),						// deUint32							dependencyCount;
3008 			subpassDependencies.size() != 0 ? &subpassDependencies[0] : DE_NULL
3009 		};
3010 
3011 		m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
3012 	}
3013 
3014 	// Create framebuffer
3015 	{
3016 		std::vector<VkImageView> attachments;
3017 		attachments.push_back(*m_colorAttachmentView);
3018 		if (usesResolveImage)
3019 		{
3020 			attachments.push_back(*m_resolveAttachmentView);
3021 		}
3022 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3023 		{
3024 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3025 			{
3026 				attachments.push_back(*m_perSampleImages[i]->m_attachmentView);
3027 			}
3028 		}
3029 
3030 		if (m_useDepth || m_useStencil)
3031 		{
3032 			attachments.push_back(*m_depthStencilAttachmentView);
3033 		}
3034 
3035 		const VkFramebufferCreateInfo framebufferParams =
3036 		{
3037 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType					sType;
3038 			DE_NULL,											// const void*						pNext;
3039 			0u,													// VkFramebufferCreateFlags			flags;
3040 			*m_renderPass,										// VkRenderPass						renderPass;
3041 			(deUint32)attachments.size(),						// deUint32							attachmentCount;
3042 			&attachments[0],									// const VkImageView*				pAttachments;
3043 			(deUint32)m_renderSize.x(),							// deUint32							width;
3044 			(deUint32)m_renderSize.y(),							// deUint32							height;
3045 			1u													// deUint32							layers;
3046 		};
3047 
3048 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
3049 	}
3050 
3051 	// Create pipeline layout
3052 	{
3053 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
3054 		{
3055 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
3056 			DE_NULL,											// const void*						pNext;
3057 			0u,													// VkPipelineLayoutCreateFlags		flags;
3058 			0u,													// deUint32							setLayoutCount;
3059 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
3060 			0u,													// deUint32							pushConstantRangeCount;
3061 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
3062 		};
3063 
3064 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
3065 
3066 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3067 		{
3068 
3069 			// Create descriptor set layout
3070 			const VkDescriptorSetLayoutBinding		layoutBinding					=
3071 			{
3072 				0u,															// deUint32								binding;
3073 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,						// VkDescriptorType						descriptorType;
3074 				1u,															// deUint32								descriptorCount;
3075 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlags					stageFlags;
3076 				DE_NULL,													// const VkSampler*						pImmutableSamplers;
3077 			};
3078 
3079 			const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutParams		=
3080 			{
3081 				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType
3082 				DE_NULL,													// const void*							pNext
3083 				0u,															// VkDescriptorSetLayoutCreateFlags		flags
3084 				1u,															// deUint32								bindingCount
3085 				&layoutBinding												// const VkDescriptorSetLayoutBinding*	pBindings
3086 			};
3087 			m_copySampleDesciptorLayout	= createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
3088 
3089 			// Create pipeline layout
3090 
3091 			const VkPushConstantRange				pushConstantRange				=
3092 			{
3093 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlags					stageFlags;
3094 				0u,															// deUint32								offset;
3095 				sizeof(deInt32)												// deUint32								size;
3096 			};
3097 			const VkPipelineLayoutCreateInfo		copySamplePipelineLayoutParams	=
3098 			{
3099 				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// VkStructureType						sType;
3100 				DE_NULL,													// const void*							pNext;
3101 				0u,															// VkPipelineLayoutCreateFlags			flags;
3102 				1u,															// deUint32								setLayoutCount;
3103 				&m_copySampleDesciptorLayout.get(),							// const VkDescriptorSetLayout*			pSetLayouts;
3104 				1u,															// deUint32								pushConstantRangeCount;
3105 				&pushConstantRange											// const VkPushConstantRange*			pPushConstantRanges;
3106 			};
3107 			m_copySamplePipelineLayout		= createPipelineLayout(vk, vkDevice, &copySamplePipelineLayoutParams);
3108 		}
3109 	}
3110 
3111 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
3112 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
3113 
3114 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3115 	{
3116 		m_copySampleVertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("quad_vert"), 0);
3117 		m_copySampleFragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("copy_sample_frag"), 0);
3118 	}
3119 
3120 	// Create pipeline
3121 	{
3122 		const VkVertexInputBindingDescription	vertexInputBindingDescription =
3123 		{
3124 			0u,									// deUint32				binding;
3125 			sizeof(Vertex4RGBA),				// deUint32				stride;
3126 			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputRate	inputRate;
3127 		};
3128 
3129 		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
3130 		{
3131 			{
3132 				0u,									// deUint32	location;
3133 				0u,									// deUint32	binding;
3134 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
3135 				0u									// deUint32	offset;
3136 			},
3137 			{
3138 				1u,									// deUint32	location;
3139 				0u,									// deUint32	binding;
3140 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
3141 				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
3142 			}
3143 		};
3144 
3145 		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
3146 		{
3147 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
3148 			DE_NULL,														// const void*								pNext;
3149 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
3150 			1u,																// deUint32									vertexBindingDescriptionCount;
3151 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
3152 			2u,																// deUint32									vertexAttributeDescriptionCount;
3153 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
3154 		};
3155 
3156 		const std::vector<VkViewport>	viewports		(1, makeViewport(m_renderSize));
3157 		const std::vector<VkRect2D>		scissors		(1, makeRect2D(m_renderSize));
3158 
3159 		const deUint32					attachmentCount	= m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT ? 2u : 1u;
3160 
3161 		std::vector<VkPipelineColorBlendAttachmentState> attachments;
3162 
3163 		for (deUint32 attachmentIdx = 0; attachmentIdx < attachmentCount; attachmentIdx++)
3164 			attachments.push_back(m_colorBlendState);
3165 
3166 		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
3167 		{
3168 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
3169 			DE_NULL,													// const void*									pNext;
3170 			0u,															// VkPipelineColorBlendStateCreateFlags			flags;
3171 			false,														// VkBool32										logicOpEnable;
3172 			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
3173 			attachmentCount,											// deUint32										attachmentCount;
3174 			attachments.data(),											// const VkPipelineColorBlendAttachmentState*	pAttachments;
3175 			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
3176 		};
3177 
3178 		const VkStencilOpState stencilOpState =
3179 		{
3180 			VK_STENCIL_OP_KEEP,						// VkStencilOp	failOp;
3181 			VK_STENCIL_OP_REPLACE,					// VkStencilOp	passOp;
3182 			VK_STENCIL_OP_KEEP,						// VkStencilOp	depthFailOp;
3183 			VK_COMPARE_OP_GREATER,					// VkCompareOp	compareOp;
3184 			1u,										// deUint32		compareMask;
3185 			1u,										// deUint32		writeMask;
3186 			1u,										// deUint32		reference;
3187 		};
3188 
3189 		const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
3190 		{
3191 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
3192 			DE_NULL,													// const void*								pNext;
3193 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
3194 			m_useDepth,													// VkBool32									depthTestEnable;
3195 			m_useDepth,													// VkBool32									depthWriteEnable;
3196 			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
3197 			false,														// VkBool32									depthBoundsTestEnable;
3198 			m_useStencil,												// VkBool32									stencilTestEnable;
3199 			stencilOpState,												// VkStencilOpState							front;
3200 			stencilOpState,												// VkStencilOpState							back;
3201 			0.0f,														// float									minDepthBounds;
3202 			1.0f,														// float									maxDepthBounds;
3203 		};
3204 
3205 		const deUint32 numSubpasses = m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY ? 2u : 1u;
3206 
3207 		for (deUint32 subpassIdx = 0; subpassIdx < numSubpasses; subpassIdx++)
3208 			for (deUint32 i = 0u; i < numTopologies; ++i)
3209 			{
3210 				m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(vk,							// const DeviceInterface&                        vk
3211 																									   vkDevice,					// const VkDevice                                device
3212 																									   *m_pipelineLayout,			// const VkPipelineLayout                        pipelineLayout
3213 																									   *m_vertexShaderModule,		// const VkShaderModule                          vertexShaderModule
3214 																									   DE_NULL,						// const VkShaderModule                          tessellationControlModule
3215 																									   DE_NULL,						// const VkShaderModule                          tessellationEvalModule
3216 																									   DE_NULL,						// const VkShaderModule                          geometryShaderModule
3217 																									   *m_fragmentShaderModule,		// const VkShaderModule                          fragmentShaderModule
3218 																									   *m_renderPass,				// const VkRenderPass                            renderPass
3219 																									   viewports,					// const std::vector<VkViewport>&                viewports
3220 																									   scissors,					// const std::vector<VkRect2D>&                  scissors
3221 																									   pTopology[i],				// const VkPrimitiveTopology                     topology
3222 																									   subpassIdx,					// const deUint32                                subpass
3223 																									   0u,							// const deUint32                                patchControlPoints
3224 																									   &vertexInputStateParams,		// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
3225 																									   DE_NULL,						// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
3226 																									   &m_multisampleStateParams,	// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
3227 																									   &depthStencilStateParams,	// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
3228 																									   &colorBlendStateParams))));	// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
3229 			}
3230 	}
3231 
3232 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3233 	{
3234 		// Create pipelines for copying samples to single sampled images
3235 		{
3236 			const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
3237 			{
3238 				VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
3239 				DE_NULL,														// const void*								pNext;
3240 				0u,																// VkPipelineVertexInputStateCreateFlags	flags;
3241 				0u,																// deUint32									vertexBindingDescriptionCount;
3242 				DE_NULL,														// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
3243 				0u,																// deUint32									vertexAttributeDescriptionCount;
3244 				DE_NULL															// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
3245 			};
3246 
3247 			const std::vector<VkViewport>	viewports	(1, makeViewport(m_renderSize));
3248 			const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_renderSize));
3249 
3250 			const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
3251 			{
3252 				VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
3253 				DE_NULL,													// const void*									pNext;
3254 				0u,															// VkPipelineColorBlendStateCreateFlags			flags;
3255 				false,														// VkBool32										logicOpEnable;
3256 				VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
3257 				1u,															// deUint32										attachmentCount;
3258 				&m_colorBlendState,											// const VkPipelineColorBlendAttachmentState*	pAttachments;
3259 				{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
3260 			};
3261 
3262 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3263 			{
3264 				// Pipeline is to be used in subpasses subsequent to sample-shading subpass
3265 				m_copySamplePipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
3266 																										 vkDevice,								// const VkDevice                                device
3267 																										 *m_copySamplePipelineLayout,			// const VkPipelineLayout                        pipelineLayout
3268 																										 *m_copySampleVertexShaderModule,		// const VkShaderModule                          vertexShaderModule
3269 																										 DE_NULL,								// const VkShaderModule                          tessellationControlModule
3270 																										 DE_NULL,								// const VkShaderModule                          tessellationEvalModule
3271 																										 DE_NULL,								// const VkShaderModule                          geometryShaderModule
3272 																										 *m_copySampleFragmentShaderModule,		// const VkShaderModule                          fragmentShaderModule
3273 																										 *m_renderPass,							// const VkRenderPass                            renderPass
3274 																										 viewports,								// const std::vector<VkViewport>&                viewports
3275 																										 scissors,								// const std::vector<VkRect2D>&                  scissors
3276 																										 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// const VkPrimitiveTopology                     topology
3277 																										 1u + (deUint32)i,						// const deUint32                                subpass
3278 																										 0u,									// const deUint32                                patchControlPoints
3279 																										 &vertexInputStateParams,				// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
3280 																										 DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
3281 																										 DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
3282 																										 DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
3283 																										 &colorBlendStateParams))));			// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
3284 			}
3285 		}
3286 
3287 
3288 		const VkDescriptorPoolSize			descriptorPoolSize			=
3289 		{
3290 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,					// VkDescriptorType					type;
3291 			1u														// deUint32							descriptorCount;
3292 		};
3293 
3294 		const VkDescriptorPoolCreateInfo	descriptorPoolCreateInfo	=
3295 		{
3296 			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,			// VkStructureType					sType
3297 			DE_NULL,												// const void*						pNext
3298 			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,		// VkDescriptorPoolCreateFlags		flags
3299 			1u,													// deUint32							maxSets
3300 			1u,														// deUint32							poolSizeCount
3301 			&descriptorPoolSize										// const VkDescriptorPoolSize*		pPoolSizes
3302 		};
3303 
3304 		m_copySampleDesciptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
3305 
3306 		const VkDescriptorSetAllocateInfo	descriptorSetAllocateInfo	=
3307 		{
3308 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,			// VkStructureType					sType
3309 			DE_NULL,												// const void*						pNext
3310 			*m_copySampleDesciptorPool,								// VkDescriptorPool					descriptorPool
3311 			1u,														// deUint32							descriptorSetCount
3312 			&m_copySampleDesciptorLayout.get(),						// const VkDescriptorSetLayout*		pSetLayouts
3313 		};
3314 
3315 		m_copySampleDesciptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
3316 
3317 		const VkDescriptorImageInfo			imageInfo					=
3318 		{
3319 			DE_NULL,
3320 			*m_colorAttachmentView,
3321 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
3322 		};
3323 		const VkWriteDescriptorSet			descriptorWrite				=
3324 		{
3325 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// VkStructureType					sType;
3326 			DE_NULL,										// const void*						pNext;
3327 			*m_copySampleDesciptorSet,						// VkDescriptorSet					dstSet;
3328 			0u,												// deUint32							dstBinding;
3329 			0u,												// deUint32							dstArrayElement;
3330 			1u,												// deUint32							descriptorCount;
3331 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			// VkDescriptorType					descriptorType;
3332 			&imageInfo,										// const VkDescriptorImageInfo*		pImageInfo;
3333 			DE_NULL,										// const VkDescriptorBufferInfo*	pBufferInfo;
3334 			DE_NULL,										// const VkBufferView*				pTexelBufferView;
3335 		};
3336 		vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
3337 	}
3338 
3339 	// Create vertex buffer
3340 	{
3341 		const VkBufferCreateInfo vertexBufferParams =
3342 		{
3343 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
3344 			DE_NULL,									// const void*			pNext;
3345 			0u,											// VkBufferCreateFlags	flags;
3346 			1024u,										// VkDeviceSize			size;
3347 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
3348 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
3349 			1u,											// deUint32				queueFamilyIndexCount;
3350 			&queueFamilyIndices[0]						// const deUint32*		pQueueFamilyIndices;
3351 		};
3352 
3353 		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
3354 		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
3355 
3356 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
3357 
3358 		// Load vertices into vertex buffer
3359 		{
3360 			Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr());
3361 
3362 			if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
3363 			{
3364 				DE_ASSERT(numTopologies == 1);
3365 
3366 				std::vector<Vertex4RGBA> vertices = pVertices[0];
3367 
3368 				// Set alpha to zero for the first draw. This should prevent depth writes because of zero coverage.
3369 				for (size_t i = 0; i < vertices.size(); i++)
3370 					vertices[i].color.w() = 0.0f;
3371 
3372 				deMemcpy(pDst, &vertices[0], vertices.size() * sizeof(Vertex4RGBA));
3373 
3374 				pDst += vertices.size();
3375 
3376 				// The second draw uses original vertices which are pure red.
3377 				deMemcpy(pDst, &pVertices[0][0], pVertices[0].size() * sizeof(Vertex4RGBA));
3378 			}
3379 			else
3380 			{
3381 				for (deUint32 i = 0u; i < numTopologies; ++i)
3382 				{
3383 					deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA));
3384 					pDst += pVertices[i].size();
3385 				}
3386 			}
3387 		}
3388 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
3389 	}
3390 
3391 	// Create command pool
3392 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndices[0]);
3393 
3394 	// Create command buffer
3395 	{
3396 		VkClearValue colorClearValue;
3397 		if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
3398 		{
3399 			colorClearValue.color.float32[0] = 0.25;
3400 			colorClearValue.color.float32[1] = 0.25;
3401 			colorClearValue.color.float32[2] = 0.25;
3402 			colorClearValue.color.float32[3] = 1.0f;
3403 		}
3404 		else
3405 		{
3406 			colorClearValue.color.float32[0] = 0.0f;
3407 			colorClearValue.color.float32[1] = 0.0f;
3408 			colorClearValue.color.float32[2] = 0.0f;
3409 			colorClearValue.color.float32[3] = 0.0f;
3410 		}
3411 
3412 		VkClearValue depthStencilClearValue;
3413 		depthStencilClearValue.depthStencil.depth = m_depthClearValue;
3414 		depthStencilClearValue.depthStencil.stencil = 0u;
3415 
3416 		std::vector<VkClearValue> clearValues;
3417 		clearValues.push_back(colorClearValue);
3418 		if (usesResolveImage)
3419 		{
3420 			clearValues.push_back(colorClearValue);
3421 		}
3422 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3423 		{
3424 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3425 			{
3426 				clearValues.push_back(colorClearValue);
3427 			}
3428 		}
3429 		if (m_useDepth || m_useStencil)
3430 		{
3431 			clearValues.push_back(depthStencilClearValue);
3432 		}
3433 
3434 		vk::VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
3435 		std::vector<VkImageMemoryBarrier> imageLayoutBarriers;
3436 
3437 		{
3438 			const VkImageMemoryBarrier colorImageBarrier =
3439 			// color attachment image
3440 			{
3441 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
3442 				DE_NULL,										// const void*				pNext;
3443 				0u,												// VkAccessFlags			srcAccessMask;
3444 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
3445 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
3446 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
3447 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
3448 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
3449 				*m_colorImage,									// VkImage					image;
3450 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
3451 			};
3452 			imageLayoutBarriers.push_back(colorImageBarrier);
3453 		}
3454 		if (usesResolveImage)
3455 		{
3456 			const VkImageMemoryBarrier resolveImageBarrier =
3457 			// resolve attachment image
3458 			{
3459 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
3460 				DE_NULL,										// const void*				pNext;
3461 				0u,												// VkAccessFlags			srcAccessMask;
3462 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
3463 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
3464 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
3465 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
3466 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
3467 				*m_resolveImage,								// VkImage					image;
3468 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
3469 			};
3470 			imageLayoutBarriers.push_back(resolveImageBarrier);
3471 		}
3472 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3473 		{
3474 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3475 			{
3476 				const VkImageMemoryBarrier perSampleImageBarrier =
3477 				// resolve attachment image
3478 				{
3479 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
3480 					DE_NULL,										// const void*				pNext;
3481 					0u,												// VkAccessFlags			srcAccessMask;
3482 					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
3483 					VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
3484 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
3485 					VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
3486 					VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
3487 					*m_perSampleImages[i]->m_image,					// VkImage					image;
3488 					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
3489 				};
3490 				imageLayoutBarriers.push_back(perSampleImageBarrier);
3491 			}
3492 		}
3493 		if (m_useDepth || m_useStencil)
3494 		{
3495 			const VkImageMemoryBarrier depthStencilImageBarrier =
3496 			// depth/stencil attachment image
3497 			{
3498 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
3499 				DE_NULL,											// const void*				pNext;
3500 				0u,													// VkAccessFlags			srcAccessMask;
3501 				VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
3502 				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
3503 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
3504 				VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
3505 				VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
3506 				*m_depthStencilImage,								// VkImage					image;
3507 				{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
3508 			};
3509 			imageLayoutBarriers.push_back(depthStencilImageBarrier);
3510 			dstStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
3511 		};
3512 
3513 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3514 
3515 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
3516 
3517 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask, (VkDependencyFlags)0,
3518 			0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), &imageLayoutBarriers[0]);
3519 
3520 		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)clearValues.size(), &clearValues[0]);
3521 
3522 		VkDeviceSize vertexBufferOffset = 0u;
3523 
3524 		for (deUint32 i = 0u; i < numTopologies; ++i)
3525 		{
3526 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[i]);
3527 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
3528 			vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0);
3529 
3530 			vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA));
3531 		}
3532 
3533 		if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
3534 		{
3535 			// The first draw was without color buffer and zero coverage. The depth buffer is expected to still have the clear value.
3536 			vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
3537 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[1]);
3538 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
3539 			// The depth test should pass as the first draw didn't touch the depth buffer.
3540 			vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[0].size(), 1, 0, 0);
3541 		}
3542 		else if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3543 		{
3544 			// Copy each sample id to single sampled image
3545 			for (deInt32 sampleId = 0; sampleId < (deInt32)m_perSampleImages.size(); ++sampleId)
3546 			{
3547 				vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
3548 				vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_copySamplePipelines[sampleId]);
3549 				vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_copySamplePipelineLayout, 0u, 1u, &m_copySampleDesciptorSet.get(), 0u, DE_NULL);
3550 				vk.cmdPushConstants(*m_cmdBuffer, *m_copySamplePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &sampleId);
3551 				vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
3552 			}
3553 		}
3554 
3555 		endRenderPass(vk, *m_cmdBuffer);
3556 
3557 		endCommandBuffer(vk, *m_cmdBuffer);
3558 	}
3559 }
3560 
~MultisampleRenderer(void)3561 MultisampleRenderer::~MultisampleRenderer (void)
3562 {
3563 }
3564 
render(void)3565 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void)
3566 {
3567 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
3568 	const VkDevice				vkDevice			= m_context.getDevice();
3569 	const VkQueue				queue				= m_context.getUniversalQueue();
3570 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
3571 
3572 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
3573 
3574 	if (m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
3575 	{
3576 		return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
3577 	}
3578 	else
3579 	{
3580 		return de::MovePtr<tcu::TextureLevel>();
3581 	}
3582 }
3583 
getSingleSampledImage(deUint32 sampleId)3584 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::getSingleSampledImage (deUint32 sampleId)
3585 {
3586 	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>());
3587 }
3588 
3589 // Multisample tests with subpasses using no attachments.
3590 class VariableRateTestCase : public vkt::TestCase
3591 {
3592 public:
3593 	using SampleCounts = std::vector<vk::VkSampleCountFlagBits>;
3594 
3595 	struct PushConstants
3596 	{
3597 		int width;
3598 		int height;
3599 		int samples;
3600 	};
3601 
3602 	struct TestParams
3603 	{
3604 		bool						nonEmptyFramebuffer;	// Empty framebuffer or not.
3605 		vk::VkSampleCountFlagBits	fbCount;				// If not empty, framebuffer sample count.
3606 		bool						unusedAttachment;		// If not empty, create unused attachment or not.
3607 		SampleCounts				subpassCounts;			// Counts for the different subpasses.
3608 	};
3609 
3610 	static const deInt32 kWidth		= 256u;
3611 	static const deInt32 kHeight	= 256u;
3612 
3613 									VariableRateTestCase	(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params);
~VariableRateTestCase(void)3614 	virtual							~VariableRateTestCase	(void) {}
3615 
3616 	virtual void					initPrograms			(vk::SourceCollections& programCollection) const;
3617 	virtual TestInstance*			createInstance			(Context& context) const;
3618 	virtual void					checkSupport			(Context& context) const;
3619 
3620 	static constexpr vk::VkFormat	kColorFormat			= vk::VK_FORMAT_R8G8B8A8_UNORM;
3621 
3622 private:
3623 	TestParams m_params;
3624 };
3625 
3626 class VariableRateTestInstance : public vkt::TestInstance
3627 {
3628 public:
3629 	using TestParams = VariableRateTestCase::TestParams;
3630 
3631 								VariableRateTestInstance	(Context& context, const TestParams& counts);
~VariableRateTestInstance(void)3632 	virtual						~VariableRateTestInstance	(void) {}
3633 
3634 	virtual tcu::TestStatus		iterate						(void);
3635 
3636 private:
3637 	TestParams m_params;
3638 };
3639 
VariableRateTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams & params)3640 VariableRateTestCase::VariableRateTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
3641 	: vkt::TestCase	(testCtx, name, description)
3642 	, m_params		(params)
3643 {
3644 }
3645 
initPrograms(vk::SourceCollections & programCollection) const3646 void VariableRateTestCase::initPrograms (vk::SourceCollections& programCollection) const
3647 {
3648 	std::stringstream vertSrc;
3649 
3650 	vertSrc	<< "#version 450\n"
3651 			<< "\n"
3652 			<< "layout(location=0) in vec2 inPos;\n"
3653 			<< "\n"
3654 			<< "void main() {\n"
3655 			<< "    gl_Position = vec4(inPos, 0.0, 1.0);\n"
3656 			<< "}\n"
3657 			;
3658 
3659 	std::stringstream fragSrc;
3660 
3661 	fragSrc	<< "#version 450\n"
3662 			<< "\n"
3663 			<< "layout(set=0, binding=0, std430) buffer OutBuffer {\n"
3664 			<< "    int coverage[];\n"
3665 			<< "} out_buffer;\n"
3666 			<< "\n"
3667 			<< "layout(push_constant) uniform PushConstants {\n"
3668 			<< "    int width;\n"
3669 			<< "    int height;\n"
3670 			<< "    int samples;\n"
3671 			<< "} push_constants;\n"
3672 			<< "\n"
3673 			<< "void main() {\n"
3674 			<< "   ivec2 coord = ivec2(floor(gl_FragCoord.xy));\n"
3675 			<< "   int pos = ((coord.y * push_constants.width) + coord.x) * push_constants.samples + int(gl_SampleID);\n"
3676 			<< "   out_buffer.coverage[pos] = 1;\n"
3677 			<< "}\n"
3678 			;
3679 
3680 	programCollection.glslSources.add("vert") << glu::VertexSource(vertSrc.str());
3681 	programCollection.glslSources.add("frag") << glu::FragmentSource(fragSrc.str());
3682 }
3683 
createInstance(Context & context) const3684 TestInstance* VariableRateTestCase::createInstance (Context& context) const
3685 {
3686 	return new VariableRateTestInstance(context, m_params);
3687 }
3688 
checkSupport(Context & context) const3689 void VariableRateTestCase::checkSupport (Context& context) const
3690 {
3691 	const auto&	vki				= context.getInstanceInterface();
3692 	const auto	physicalDevice	= context.getPhysicalDevice();
3693 
3694 	// When using multiple subpasses, require variableMultisampleRate.
3695 	if (m_params.subpassCounts.size() > 1)
3696 	{
3697 		if (!vk::getPhysicalDeviceFeatures(vki, physicalDevice).variableMultisampleRate)
3698 			TCU_THROW(NotSupportedError, "Variable multisample rate not supported");
3699 	}
3700 
3701 	// Check if sampleRateShading is supported.
3702 	if(!vk::getPhysicalDeviceFeatures(vki, physicalDevice).sampleRateShading)
3703 		TCU_THROW(NotSupportedError, "Sample rate shading is not supported");
3704 
3705 	// Make sure all subpass sample counts are supported.
3706 	const auto	properties		= vk::getPhysicalDeviceProperties(vki, physicalDevice);
3707 	const auto&	supportedCounts	= properties.limits.framebufferNoAttachmentsSampleCounts;
3708 
3709 	for (const auto count : m_params.subpassCounts)
3710 	{
3711 		if ((supportedCounts & count) == 0u)
3712 			TCU_THROW(NotSupportedError, "Sample count combination not supported");
3713 	}
3714 
3715 	if (m_params.nonEmptyFramebuffer)
3716 	{
3717 		// Check the framebuffer sample count is supported.
3718 		const auto formatProperties = vk::getPhysicalDeviceImageFormatProperties(vki, physicalDevice, kColorFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0u);
3719 		if ((formatProperties.sampleCounts & m_params.fbCount) == 0u)
3720 			TCU_THROW(NotSupportedError, "Sample count of " + de::toString(m_params.fbCount) + " not supported for color attachment");
3721 	}
3722 }
3723 
zeroOutAndFlush(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::BufferWithMemory & buffer,vk::VkDeviceSize size)3724 void zeroOutAndFlush(const vk::DeviceInterface& vkd, vk::VkDevice device, vk::BufferWithMemory& buffer, vk::VkDeviceSize size)
3725 {
3726 	auto& alloc = buffer.getAllocation();
3727 	deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(size));
3728 	vk::flushAlloc(vkd, device, alloc);
3729 }
3730 
VariableRateTestInstance(Context & context,const TestParams & params)3731 VariableRateTestInstance::VariableRateTestInstance (Context& context, const TestParams& params)
3732 	: vkt::TestInstance	(context)
3733 	, m_params			(params)
3734 {
3735 }
3736 
iterate(void)3737 tcu::TestStatus VariableRateTestInstance::iterate (void)
3738 {
3739 	using PushConstants = VariableRateTestCase::PushConstants;
3740 
3741 	const auto&	vkd			= m_context.getDeviceInterface();
3742 	const auto	device		= m_context.getDevice();
3743 	auto&		allocator	= m_context.getDefaultAllocator();
3744 	const auto&	queue		= m_context.getUniversalQueue();
3745 	const auto	queueIndex	= m_context.getUniversalQueueFamilyIndex();
3746 
3747 	const vk::VkDeviceSize	kWidth			= static_cast<vk::VkDeviceSize>(VariableRateTestCase::kWidth);
3748 	const vk::VkDeviceSize	kHeight			= static_cast<vk::VkDeviceSize>(VariableRateTestCase::kHeight);
3749 	constexpr auto			kColorFormat	= VariableRateTestCase::kColorFormat;
3750 
3751 	const auto kWidth32		= static_cast<deUint32>(kWidth);
3752 	const auto kHeight32	= static_cast<deUint32>(kHeight);
3753 
3754 	std::vector<std::unique_ptr<vk::BufferWithMemory>>	referenceBuffers;
3755 	std::vector<std::unique_ptr<vk::BufferWithMemory>>	outputBuffers;
3756 	std::vector<size_t>									bufferNumElements;
3757 	std::vector<vk::VkDeviceSize>						bufferSizes;
3758 
3759 	// Create reference and output buffers.
3760 	for (const auto count : m_params.subpassCounts)
3761 	{
3762 		bufferNumElements.push_back(static_cast<size_t>(kWidth * kHeight * count));
3763 		bufferSizes.push_back(bufferNumElements.back() * sizeof(deInt32));
3764 		const auto bufferCreateInfo = vk::makeBufferCreateInfo(bufferSizes.back(), vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3765 
3766 		referenceBuffers.emplace_back	(new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible});
3767 		outputBuffers.emplace_back		(new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible});
3768 	}
3769 
3770 	// Descriptor set layout.
3771 	vk::DescriptorSetLayoutBuilder builder;
3772 	builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT);
3773 	const auto descriptorSetLayout = builder.build(vkd, device);
3774 
3775 	// Pipeline layout.
3776 	const vk::VkPushConstantRange pushConstantRange =
3777 	{
3778 		vk::VK_SHADER_STAGE_FRAGMENT_BIT,				//	VkShaderStageFlags	stageFlags;
3779 		0u,												//	deUint32			offset;
3780 		static_cast<deUint32>(sizeof(PushConstants)),	//	deUint32			size;
3781 	};
3782 
3783 	const vk::VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
3784 	{
3785 		vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	//	VkStructureType					sType;
3786 		nullptr,											//	const void*						pNext;
3787 		0u,													//	VkPipelineLayoutCreateFlags		flags;
3788 		1u,													//	deUint32						setLayoutCount;
3789 		&descriptorSetLayout.get(),							//	const VkDescriptorSetLayout*	pSetLayouts;
3790 		1u,													//	deUint32						pushConstantRangeCount;
3791 		&pushConstantRange,									//	const VkPushConstantRange*		pPushConstantRanges;
3792 	};
3793 	const auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
3794 
3795 	// Subpass with no attachments.
3796 	const vk::VkSubpassDescription emptySubpassDescription =
3797 	{
3798 		0u,										//	VkSubpassDescriptionFlags		flags;
3799 		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,	//	VkPipelineBindPoint				pipelineBindPoint;
3800 		0u,										//	deUint32						inputAttachmentCount;
3801 		nullptr,								//	const VkAttachmentReference*	pInputAttachments;
3802 		0u,										//	deUint32						colorAttachmentCount;
3803 		nullptr,								//	const VkAttachmentReference*	pColorAttachments;
3804 		nullptr,								//	const VkAttachmentReference*	pResolveAttachments;
3805 		nullptr,								//	const VkAttachmentReference*	pDepthStencilAttachment;
3806 		0u,										//	deUint32						preserveAttachmentCount;
3807 		nullptr,								//	const deUint32*					pPreserveAttachments;
3808 	};
3809 
3810 	// Unused attachment reference.
3811 	const vk::VkAttachmentReference unusedAttachmentReference =
3812 	{
3813 		VK_ATTACHMENT_UNUSED,							//	deUint32		attachment;
3814 		vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	//	VkImageLayout	layout;
3815 	};
3816 
3817 	// Subpass with unused attachment.
3818 	const vk::VkSubpassDescription unusedAttachmentSubpassDescription =
3819 	{
3820 		0u,										//	VkSubpassDescriptionFlags		flags;
3821 		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,	//	VkPipelineBindPoint				pipelineBindPoint;
3822 		0u,										//	deUint32						inputAttachmentCount;
3823 		nullptr,								//	const VkAttachmentReference*	pInputAttachments;
3824 		1u,										//	deUint32						colorAttachmentCount;
3825 		&unusedAttachmentReference,				//	const VkAttachmentReference*	pColorAttachments;
3826 		nullptr,								//	const VkAttachmentReference*	pResolveAttachments;
3827 		nullptr,								//	const VkAttachmentReference*	pDepthStencilAttachment;
3828 		0u,										//	deUint32						preserveAttachmentCount;
3829 		nullptr,								//	const deUint32*					pPreserveAttachments;
3830 	};
3831 
3832 	// Renderpass with multiple subpasses.
3833 	vk::VkRenderPassCreateInfo renderPassCreateInfo =
3834 	{
3835 		vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	//	VkStructureType					sType;
3836 		nullptr,										//	const void*						pNext;
3837 		0u,												//	VkRenderPassCreateFlags			flags;
3838 		0u,												//	deUint32						attachmentCount;
3839 		nullptr,										//	const VkAttachmentDescription*	pAttachments;
3840 		0u,												//	deUint32						subpassCount;
3841 		nullptr,										//	const VkSubpassDescription*		pSubpasses;
3842 		0u,												//	deUint32						dependencyCount;
3843 		nullptr,										//	const VkSubpassDependency*		pDependencies;
3844 	};
3845 
3846 	std::vector<vk::VkSubpassDescription> subpassesVector;
3847 
3848 	for (size_t i = 0; i < m_params.subpassCounts.size(); ++i)
3849 		subpassesVector.push_back(emptySubpassDescription);
3850 	renderPassCreateInfo.subpassCount	= static_cast<deUint32>(subpassesVector.size());
3851 	renderPassCreateInfo.pSubpasses		= subpassesVector.data();
3852 	const auto renderPassMultiplePasses = vk::createRenderPass(vkd, device, &renderPassCreateInfo);
3853 
3854 	// Render pass with single subpass.
3855 	const vk::VkAttachmentDescription colorAttachmentDescription =
3856 	{
3857 		0u,												//	VkAttachmentDescriptionFlags	flags;
3858 		kColorFormat,									//	VkFormat						format;
3859 		m_params.fbCount,								//	VkSampleCountFlagBits			samples;
3860 		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,			//	VkAttachmentLoadOp				loadOp;
3861 		vk::VK_ATTACHMENT_STORE_OP_STORE,				//	VkAttachmentStoreOp				storeOp;
3862 		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,			//	VkAttachmentLoadOp				stencilLoadOp;
3863 		vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,			//	VkAttachmentStoreOp				stencilStoreOp;
3864 		vk::VK_IMAGE_LAYOUT_UNDEFINED,					//	VkImageLayout					initialLayout;
3865 		vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	//	VkImageLayout					finalLayout;
3866 	};
3867 
3868 	if (m_params.nonEmptyFramebuffer)
3869 	{
3870 		renderPassCreateInfo.attachmentCount = 1u;
3871 		renderPassCreateInfo.pAttachments = &colorAttachmentDescription;
3872 	}
3873 	renderPassCreateInfo.subpassCount	= 1u;
3874 	renderPassCreateInfo.pSubpasses		= ((m_params.nonEmptyFramebuffer && m_params.unusedAttachment) ? &unusedAttachmentSubpassDescription : &emptySubpassDescription);
3875 	const auto renderPassSingleSubpass	= vk::createRenderPass(vkd, device, &renderPassCreateInfo);
3876 
3877 	// Framebuffers.
3878 	vk::VkFramebufferCreateInfo framebufferCreateInfo =
3879 	{
3880 		vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	//	VkStructureType				sType;
3881 		nullptr,										//	const void*					pNext;
3882 		0u,												//	VkFramebufferCreateFlags	flags;
3883 		DE_NULL,										//	VkRenderPass				renderPass;
3884 		0u,												//	deUint32					attachmentCount;
3885 		nullptr,										//	const VkImageView*			pAttachments;
3886 		kWidth32,										//	deUint32					width;
3887 		kHeight32,										//	deUint32					height;
3888 		1u,												//	deUint32					layers;
3889 	};
3890 
3891 	// Framebuffer for multiple-subpasses render pass.
3892 	framebufferCreateInfo.renderPass		= renderPassMultiplePasses.get();
3893 	const auto framebufferMultiplePasses	= vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3894 
3895 	// Framebuffer for single-subpass render pass.
3896 	std::unique_ptr<vk::ImageWithMemory>	imagePtr;
3897 	vk::Move<vk::VkImageView>				imageView;
3898 
3899 	if (m_params.nonEmptyFramebuffer)
3900 	{
3901 		const vk::VkImageCreateInfo imageCreateInfo =
3902 		{
3903 			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
3904 			nullptr,									//	const void*				pNext;
3905 			0u,											//	VkImageCreateFlags		flags;
3906 			vk::VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
3907 			kColorFormat,								//	VkFormat				format;
3908 			vk::makeExtent3D(kWidth32, kHeight32, 1u),	//	VkExtent3D				extent;
3909 			1u,											//	deUint32				mipLevels;
3910 			1u,											//	deUint32				arrayLayers;
3911 			m_params.fbCount,							//	VkSampleCountFlagBits	samples;
3912 			vk::VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
3913 			vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,	//	VkImageUsageFlags		usage;
3914 			vk::VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
3915 			0u,											//	deUint32				queueFamilyIndexCount;
3916 			nullptr,									//	const deUint32*			pQueueFamilyIndices;
3917 			vk::VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
3918 		};
3919 		imagePtr.reset(new vk::ImageWithMemory{vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any});
3920 
3921 		const auto subresourceRange	= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
3922 		imageView					= vk::makeImageView(vkd, device, imagePtr->get(), vk::VK_IMAGE_VIEW_TYPE_2D, kColorFormat, subresourceRange);
3923 
3924 		framebufferCreateInfo.attachmentCount	= 1u;
3925 		framebufferCreateInfo.pAttachments		= &imageView.get();
3926 	}
3927 	framebufferCreateInfo.renderPass	= renderPassSingleSubpass.get();
3928 	const auto framebufferSingleSubpass	= vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3929 
3930 	// Shader modules and stages.
3931 	const auto vertModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
3932 	const auto fragModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
3933 
3934 	std::vector<vk::VkPipelineShaderStageCreateInfo> shaderStages;
3935 
3936 	vk::VkPipelineShaderStageCreateInfo shaderStageCreateInfo =
3937 	{
3938 		vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	//	VkStructureType						sType;
3939 		nullptr,													//	const void*							pNext;
3940 		0u,															//	VkPipelineShaderStageCreateFlags	flags;
3941 		vk::VK_SHADER_STAGE_VERTEX_BIT,								//	VkShaderStageFlagBits				stage;
3942 		vertModule.get(),											//	VkShaderModule						module;
3943 		"main",														//	const char*							pName;
3944 		nullptr,													//	const VkSpecializationInfo*			pSpecializationInfo;
3945 	};
3946 
3947 	shaderStages.push_back(shaderStageCreateInfo);
3948 	shaderStageCreateInfo.stage		= vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3949 	shaderStageCreateInfo.module	= fragModule.get();
3950 	shaderStages.push_back(shaderStageCreateInfo);
3951 
3952 	// Vertices, input state and assembly.
3953 	const std::vector<tcu::Vec2> vertices =
3954 	{
3955 		{ -0.987f, -0.964f },
3956 		{  0.982f, -0.977f },
3957 		{  0.005f,  0.891f },
3958 	};
3959 
3960 	const auto vertexBinding	= vk::makeVertexInputBindingDescription(0u, static_cast<deUint32>(sizeof(decltype(vertices)::value_type)), vk::VK_VERTEX_INPUT_RATE_VERTEX);
3961 	const auto vertexAttribute	= vk::makeVertexInputAttributeDescription(0u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, 0u);
3962 
3963 	const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
3964 	{
3965 		vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	//	VkStructureType								sType;
3966 		nullptr,														//	const void*									pNext;
3967 		0u,																//	VkPipelineVertexInputStateCreateFlags		flags;
3968 		1u,																//	deUint32									vertexBindingDescriptionCount;
3969 		&vertexBinding,													//	const VkVertexInputBindingDescription*		pVertexBindingDescriptions;
3970 		1u,																//	deUint32									vertexAttributeDescriptionCount;
3971 		&vertexAttribute,												//	const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
3972 	};
3973 
3974 	const vk::VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
3975 	{
3976 		vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	//	VkStructureType							sType;
3977 		nullptr,															//	const void*								pNext;
3978 		0u,																	//	VkPipelineInputAssemblyStateCreateFlags	flags;
3979 		vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							//	VkPrimitiveTopology						topology;
3980 		VK_FALSE,															//	VkBool32								primitiveRestartEnable;
3981 	};
3982 
3983 	// Graphics pipelines to create output buffers.
3984 	const auto viewport	= vk::makeViewport(kWidth32, kHeight32);
3985 	const auto scissor	= vk::makeRect2D(kWidth32, kHeight32);
3986 
3987 	const vk::VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
3988 	{
3989 		vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	//	VkStructureType						sType;
3990 		nullptr,													//	const void*							pNext;
3991 		0u,															//	VkPipelineViewportStateCreateFlags	flags;
3992 		1u,															//	deUint32							viewportCount;
3993 		&viewport,													//	const VkViewport*					pViewports;
3994 		1u,															//	deUint32							scissorCount;
3995 		&scissor,													//	const VkRect2D*						pScissors;
3996 	};
3997 
3998 	const vk::VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
3999 	{
4000 		vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	//	VkStructureType							sType;
4001 		nullptr,														//	const void*								pNext;
4002 		0u,																//	VkPipelineRasterizationStateCreateFlags	flags;
4003 		VK_FALSE,														//	VkBool32								depthClampEnable;
4004 		VK_FALSE,														//	VkBool32								rasterizerDiscardEnable;
4005 		vk::VK_POLYGON_MODE_FILL,										//	VkPolygonMode							polygonMode;
4006 		vk::VK_CULL_MODE_NONE,											//	VkCullModeFlags							cullMode;
4007 		vk::VK_FRONT_FACE_CLOCKWISE,									//	VkFrontFace								frontFace;
4008 		VK_FALSE,														//	VkBool32								depthBiasEnable;
4009 		0.0f,															//	float									depthBiasConstantFactor;
4010 		0.0f,															//	float									depthBiasClamp;
4011 		0.0f,															//	float									depthBiasSlopeFactor;
4012 		1.0f,															//	float									lineWidth;
4013 	};
4014 
4015 	vk::VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
4016 	{
4017 		vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	//	VkStructureType							sType;
4018 		nullptr,														//	const void*								pNext;
4019 		0u,																//	VkPipelineMultisampleStateCreateFlags	flags;
4020 		vk::VK_SAMPLE_COUNT_1_BIT,										//	VkSampleCountFlagBits					rasterizationSamples;
4021 		VK_FALSE,														//	VkBool32								sampleShadingEnable;
4022 		0.0f,															//	float									minSampleShading;
4023 		nullptr,														//	const VkSampleMask*						pSampleMask;
4024 		VK_FALSE,														//	VkBool32								alphaToCoverageEnable;
4025 		VK_FALSE,														//	VkBool32								alphaToOneEnable;
4026 	};
4027 
4028 	std::vector<vk::Move<vk::VkPipeline>> outputPipelines;
4029 
4030 	for (const auto samples : m_params.subpassCounts)
4031 	{
4032 		multisampleStateCreateInfo.rasterizationSamples = samples;
4033 
4034 		const vk::VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
4035 		{
4036 			vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	//	VkStructureType									sType;
4037 			nullptr,												//	const void*										pNext;
4038 			0u,														//	VkPipelineCreateFlags							flags;
4039 			static_cast<deUint32>(shaderStages.size()),				//	deUint32										stageCount;
4040 			shaderStages.data(),									//	const VkPipelineShaderStageCreateInfo*			pStages;
4041 			&vertexInputStateCreateInfo,							//	const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
4042 			&inputAssemblyStateCreateInfo,							//	const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
4043 			nullptr,												//	const VkPipelineTessellationStateCreateInfo*	pTessellationState;
4044 			&viewportStateCreateInfo,								//	const VkPipelineViewportStateCreateInfo*		pViewportState;
4045 			&rasterizationStateCreateInfo,							//	const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
4046 			&multisampleStateCreateInfo,							//	const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
4047 			nullptr,												//	const VkPipelineDepthStencilStateCreateInfo*	pDepthStencilState;
4048 			nullptr,												//	const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
4049 			nullptr,												//	const VkPipelineDynamicStateCreateInfo*			pDynamicState;
4050 			pipelineLayout.get(),									//	VkPipelineLayout								layout;
4051 			renderPassSingleSubpass.get(),							//	VkRenderPass									renderPass;
4052 			0u,														//	deUint32										subpass;
4053 			DE_NULL,												//	VkPipeline										basePipelineHandle;
4054 			0,														//	deInt32											basePipelineIndex;
4055 		};
4056 
4057 		outputPipelines.push_back(vk::createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo));
4058 	}
4059 
4060 	// Graphics pipelines with variable rate but using several subpasses.
4061 	std::vector<vk::Move<vk::VkPipeline>> referencePipelines;
4062 
4063 	for (size_t i = 0; i < m_params.subpassCounts.size(); ++i)
4064 	{
4065 		multisampleStateCreateInfo.rasterizationSamples = m_params.subpassCounts[i];
4066 
4067 		const vk::VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
4068 		{
4069 			vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	//	VkStructureType									sType;
4070 			nullptr,												//	const void*										pNext;
4071 			0u,														//	VkPipelineCreateFlags							flags;
4072 			static_cast<deUint32>(shaderStages.size()),				//	deUint32										stageCount;
4073 			shaderStages.data(),									//	const VkPipelineShaderStageCreateInfo*			pStages;
4074 			&vertexInputStateCreateInfo,							//	const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
4075 			&inputAssemblyStateCreateInfo,							//	const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
4076 			nullptr,												//	const VkPipelineTessellationStateCreateInfo*	pTessellationState;
4077 			&viewportStateCreateInfo,								//	const VkPipelineViewportStateCreateInfo*		pViewportState;
4078 			&rasterizationStateCreateInfo,							//	const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
4079 			&multisampleStateCreateInfo,							//	const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
4080 			nullptr,												//	const VkPipelineDepthStencilStateCreateInfo*	pDepthStencilState;
4081 			nullptr,												//	const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
4082 			nullptr,												//	const VkPipelineDynamicStateCreateInfo*			pDynamicState;
4083 			pipelineLayout.get(),									//	VkPipelineLayout								layout;
4084 			renderPassMultiplePasses.get(),							//	VkRenderPass									renderPass;
4085 			static_cast<deUint32>(i),								//	deUint32										subpass;
4086 			DE_NULL,												//	VkPipeline										basePipelineHandle;
4087 			0,														//	deInt32											basePipelineIndex;
4088 		};
4089 
4090 		referencePipelines.push_back(vk::createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo));
4091 	}
4092 
4093 	// Prepare vertex, reference and output buffers.
4094 	const auto				vertexBufferSize		= vertices.size() * sizeof(decltype(vertices)::value_type);
4095 	const auto				vertexBufferCreateInfo	= vk::makeBufferCreateInfo(static_cast<VkDeviceSize>(vertexBufferSize), vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
4096 	vk::BufferWithMemory	vertexBuffer			{vkd, device, allocator, vertexBufferCreateInfo, MemoryRequirement::HostVisible};
4097 	auto&					vertexAlloc				= vertexBuffer.getAllocation();
4098 
4099 	deMemcpy(vertexAlloc.getHostPtr(), vertices.data(), vertexBufferSize);
4100 	vk::flushAlloc(vkd, device, vertexAlloc);
4101 
4102 	for (size_t i = 0; i < referenceBuffers.size(); ++i)
4103 	{
4104 		zeroOutAndFlush(vkd, device, *referenceBuffers[i], bufferSizes[i]);
4105 		zeroOutAndFlush(vkd, device, *outputBuffers[i], bufferSizes[i]);
4106 	}
4107 
4108 	// Prepare descriptor sets.
4109 	const deUint32				totalSets		= static_cast<deUint32>(referenceBuffers.size() * 2u);
4110 	vk::DescriptorPoolBuilder	poolBuilder;
4111 	poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, static_cast<deUint32>(referenceBuffers.size() * 2u));
4112 	const auto descriptorPool = poolBuilder.build(vkd, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, totalSets);
4113 
4114 	std::vector<vk::Move<vk::VkDescriptorSet>> referenceSets	(referenceBuffers.size());
4115 	std::vector<vk::Move<vk::VkDescriptorSet>> outputSets		(outputBuffers.size());
4116 
4117 	for (auto& set : referenceSets)
4118 		set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
4119 	for (auto& set : outputSets)
4120 		set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
4121 
4122 	vk::DescriptorSetUpdateBuilder updateBuilder;
4123 
4124 	for (size_t i = 0; i < referenceSets.size(); ++i)
4125 	{
4126 		const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(referenceBuffers[i]->get(), 0u, bufferSizes[i]);
4127 		updateBuilder.writeSingle(referenceSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
4128 	}
4129 	for (size_t i = 0; i < outputSets.size(); ++i)
4130 	{
4131 		const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(outputBuffers[i]->get(), 0u, bufferSizes[i]);
4132 		updateBuilder.writeSingle(outputSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
4133 	}
4134 
4135 	updateBuilder.update(vkd, device);
4136 
4137 	// Prepare command pool.
4138 	const auto cmdPool		= vk::makeCommandPool(vkd, device, queueIndex);
4139 	const auto cmdBufferPtr	= vk::allocateCommandBuffer(vkd , device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4140 	const auto cmdBuffer	= cmdBufferPtr.get();
4141 
4142 	vk::VkBufferMemoryBarrier storageBufferDevToHostBarrier =
4143 	{
4144 		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//	VkStructureType	sType;
4145 		nullptr,										//	const void*		pNext;
4146 		vk::VK_ACCESS_SHADER_WRITE_BIT,					//	VkAccessFlags	srcAccessMask;
4147 		vk::VK_ACCESS_HOST_READ_BIT,					//	VkAccessFlags	dstAccessMask;
4148 		VK_QUEUE_FAMILY_IGNORED,						//	deUint32		srcQueueFamilyIndex;
4149 		VK_QUEUE_FAMILY_IGNORED,						//	deUint32		dstQueueFamilyIndex;
4150 		DE_NULL,										//	VkBuffer		buffer;
4151 		0u,												//	VkDeviceSize	offset;
4152 		VK_WHOLE_SIZE,									//	VkDeviceSize	size;
4153 	};
4154 
4155 	// Record command buffer.
4156 	const vk::VkDeviceSize	vertexBufferOffset	= 0u;
4157 	const auto				renderArea			= vk::makeRect2D(kWidth32, kHeight32);
4158 	PushConstants			pushConstants		= { static_cast<int>(kWidth), static_cast<int>(kHeight), 0 };
4159 
4160 	vk::beginCommandBuffer(vkd, cmdBuffer);
4161 
4162 	// Render output buffers.
4163 	vk::beginRenderPass(vkd, cmdBuffer, renderPassSingleSubpass.get(), framebufferSingleSubpass.get(), renderArea);
4164 	for (size_t i = 0; i < outputBuffers.size(); ++i)
4165 	{
4166 		vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, outputPipelines[i].get());
4167 		vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &outputSets[i].get(), 0u, nullptr);
4168 		vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
4169 		pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]);
4170 		vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants);
4171 		vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u);
4172 	}
4173 	vk::endRenderPass(vkd, cmdBuffer);
4174 	for (size_t i = 0; i < outputBuffers.size(); ++i)
4175 	{
4176 		storageBufferDevToHostBarrier.buffer = outputBuffers[i]->get();
4177 		vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr);
4178 	}
4179 
4180 	// Render reference buffers.
4181 	vk::beginRenderPass(vkd, cmdBuffer, renderPassMultiplePasses.get(), framebufferMultiplePasses.get(), renderArea);
4182 	for (size_t i = 0; i < referenceBuffers.size(); ++i)
4183 	{
4184 		if (i > 0)
4185 			vkd.cmdNextSubpass(cmdBuffer, vk::VK_SUBPASS_CONTENTS_INLINE);
4186 		vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, referencePipelines[i].get());
4187 		vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &referenceSets[i].get(), 0u, nullptr);
4188 		vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
4189 		pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]);
4190 		vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants);
4191 		vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u);
4192 	}
4193 	vk::endRenderPass(vkd, cmdBuffer);
4194 	for (size_t i = 0; i < referenceBuffers.size(); ++i)
4195 	{
4196 		storageBufferDevToHostBarrier.buffer = referenceBuffers[i]->get();
4197 		vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr);
4198 	}
4199 
4200 	vk::endCommandBuffer(vkd, cmdBuffer);
4201 
4202 	// Run all pipelines.
4203 	vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
4204 
4205 	// Invalidate reference allocs.
4206 #undef LOG_BUFFER_CONTENTS
4207 #ifdef LOG_BUFFER_CONTENTS
4208 	auto& log = m_context.getTestContext().getLog();
4209 #endif
4210 	for (size_t i = 0; i < referenceBuffers.size(); ++i)
4211 	{
4212 		auto& buffer	= referenceBuffers[i];
4213 		auto& alloc		= buffer->getAllocation();
4214 		vk::invalidateAlloc(vkd, device, alloc);
4215 
4216 #ifdef LOG_BUFFER_CONTENTS
4217 		std::vector<deInt32> bufferValues(bufferNumElements[i]);
4218 		deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]);
4219 
4220 		std::ostringstream msg;
4221 		for (const auto value : bufferValues)
4222 			msg << " " << value;
4223 		log << tcu::TestLog::Message << "Reference buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage;
4224 #endif
4225 	}
4226 
4227 	for (size_t i = 0; i < outputBuffers.size(); ++i)
4228 	{
4229 		auto& buffer	= outputBuffers[i];
4230 		auto& alloc		= buffer->getAllocation();
4231 		vk::invalidateAlloc(vkd, device, alloc);
4232 
4233 #ifdef LOG_BUFFER_CONTENTS
4234 		std::vector<deInt32> bufferValues(bufferNumElements[i]);
4235 		deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]);
4236 
4237 		std::ostringstream msg;
4238 		for (const auto value : bufferValues)
4239 			msg << " " << value;
4240 		log << tcu::TestLog::Message << "Output buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage;
4241 #endif
4242 
4243 		if (deMemCmp(alloc.getHostPtr(), referenceBuffers[i]->getAllocation().getHostPtr(), static_cast<size_t>(bufferSizes[i])) != 0)
4244 			return tcu::TestStatus::fail("Buffer mismatch in output buffer " + de::toString(i));
4245 	}
4246 
4247 	return tcu::TestStatus::pass("Pass");
4248 }
4249 
4250 using ElementsVector	= std::vector<vk::VkSampleCountFlagBits>;
4251 using CombinationVector	= std::vector<ElementsVector>;
4252 
combinationsRecursive(const ElementsVector & elements,size_t requestedSize,CombinationVector & solutions,ElementsVector & partial)4253 void combinationsRecursive(const ElementsVector& elements, size_t requestedSize, CombinationVector& solutions, ElementsVector& partial)
4254 {
4255 	if (partial.size() == requestedSize)
4256 		solutions.push_back(partial);
4257 	else
4258 	{
4259 		for (const auto& elem : elements)
4260 		{
4261 			partial.push_back(elem);
4262 			combinationsRecursive(elements, requestedSize, solutions, partial);
4263 			partial.pop_back();
4264 		}
4265 	}
4266 }
4267 
combinations(const ElementsVector & elements,size_t requestedSize)4268 CombinationVector combinations(const ElementsVector& elements, size_t requestedSize)
4269 {
4270 	CombinationVector solutions;
4271 	ElementsVector partial;
4272 
4273 	combinationsRecursive(elements, requestedSize, solutions, partial);
4274 	return solutions;
4275 }
4276 
4277 } // anonymous
4278 
createMultisampleTests(tcu::TestContext & testCtx)4279 tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx)
4280 {
4281 	const VkSampleCountFlagBits samples[] =
4282 	{
4283 		VK_SAMPLE_COUNT_2_BIT,
4284 		VK_SAMPLE_COUNT_4_BIT,
4285 		VK_SAMPLE_COUNT_8_BIT,
4286 		VK_SAMPLE_COUNT_16_BIT,
4287 		VK_SAMPLE_COUNT_32_BIT,
4288 		VK_SAMPLE_COUNT_64_BIT
4289 	};
4290 
4291 	de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, "multisample", ""));
4292 
4293 	// Rasterization samples tests
4294 	{
4295 		de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", ""));
4296 
4297 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4298 		{
4299 			std::ostringstream caseName;
4300 			caseName << "samples_" << samples[samplesNdx];
4301 
4302 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4303 
4304 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4305 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4306 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4307 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
4308 
4309 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT));
4310 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_STENCIL_BIT));
4311 			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));
4312 
4313 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle_sparse", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4314 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line_sparse", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4315 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px_sparse", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4316 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_sparse", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
4317 
4318 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_sparse", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT));
4319 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil_sparse", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_STENCIL_BIT));
4320 			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));
4321 
4322 			rasterizationSamplesTests->addChild(samplesTests.release());
4323 		}
4324 
4325 		multisampleTests->addChild(rasterizationSamplesTests.release());
4326 	}
4327 
4328 	// Raster samples consistency check
4329 	{
4330 		de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests	(new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", ""));
4331 		MultisampleTestParams			paramsRegular					= {GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR};
4332 		MultisampleTestParams			paramsSparse					= {GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE};
4333 
4334 		addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
4335 									"unique_colors_check",
4336 									"",
4337 									initMultisamplePrograms,
4338 									testRasterSamplesConsistency,
4339 									paramsRegular);
4340 
4341 		addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
4342 									"unique_colors_check_sparse",
4343 									"",
4344 									initMultisamplePrograms,
4345 									testRasterSamplesConsistency,
4346 									paramsSparse);
4347 
4348 		multisampleTests->addChild(rasterSamplesConsistencyTests.release());
4349 	}
4350 
4351 	// minSampleShading tests
4352 	{
4353 		struct TestConfig
4354 		{
4355 			const char*	name;
4356 			float		minSampleShading;
4357 		};
4358 
4359 		const TestConfig testConfigs[] =
4360 		{
4361 			{ "min_0_0",	0.0f },
4362 			{ "min_0_25",	0.25f },
4363 			{ "min_0_5",	0.5f },
4364 			{ "min_0_75",	0.75f },
4365 			{ "min_1_0",	1.0f }
4366 		};
4367 
4368 		{
4369 			de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", ""));
4370 
4371 			for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4372 			{
4373 				const TestConfig&				testConfig				= testConfigs[configNdx];
4374 				de::MovePtr<tcu::TestCaseGroup>	minShadingValueTests	(new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
4375 
4376 				for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4377 				{
4378 					std::ostringstream caseName;
4379 					caseName << "samples_" << samples[samplesNdx];
4380 
4381 					de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4382 
4383 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4384 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line",		"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4385 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4386 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point",		"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
4387 
4388 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle_sparse",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4389 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line_sparse",		"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4390 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px_sparse",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4391 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_sparse",		"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
4392 
4393 					minShadingValueTests->addChild(samplesTests.release());
4394 				}
4395 
4396 				minSampleShadingTests->addChild(minShadingValueTests.release());
4397 			}
4398 
4399 			multisampleTests->addChild(minSampleShadingTests.release());
4400 		}
4401 
4402 		{
4403 			de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_enabled", ""));
4404 
4405 			for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4406 			{
4407 				const TestConfig&				testConfig				= testConfigs[configNdx];
4408 				de::MovePtr<tcu::TestCaseGroup>	minShadingValueTests	(new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
4409 
4410 				for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4411 				{
4412 					std::ostringstream caseName;
4413 					caseName << "samples_" << samples[samplesNdx];
4414 
4415 					de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4416 
4417 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, true));
4418 
4419 					minShadingValueTests->addChild(samplesTests.release());
4420 				}
4421 
4422 				minSampleShadingTests->addChild(minShadingValueTests.release());
4423 			}
4424 
4425 			multisampleTests->addChild(minSampleShadingTests.release());
4426 		}
4427 
4428 		{
4429 			de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_disabled", ""));
4430 
4431 			for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4432 			{
4433 				const TestConfig&				testConfig				= testConfigs[configNdx];
4434 				de::MovePtr<tcu::TestCaseGroup>	minShadingValueTests	(new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
4435 
4436 				for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4437 				{
4438 					std::ostringstream caseName;
4439 					caseName << "samples_" << samples[samplesNdx];
4440 
4441 					de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4442 
4443 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, false));
4444 
4445 					minShadingValueTests->addChild(samplesTests.release());
4446 				}
4447 
4448 				minSampleShadingTests->addChild(minShadingValueTests.release());
4449 			}
4450 
4451 			multisampleTests->addChild(minSampleShadingTests.release());
4452 		}
4453 	}
4454 
4455 	// SampleMask tests
4456 	{
4457 		struct TestConfig
4458 		{
4459 			const char*		name;
4460 			const char*		description;
4461 			VkSampleMask	sampleMask;
4462 		};
4463 
4464 		const TestConfig testConfigs[] =
4465 		{
4466 			{ "mask_all_on",	"All mask bits are off",			0x0 },
4467 			{ "mask_all_off",	"All mask bits are on",				0xFFFFFFFF },
4468 			{ "mask_one",		"All mask elements are 0x1",		0x1},
4469 			{ "mask_random",	"All mask elements are 0xAAAAAAAA",	0xAAAAAAAA },
4470 		};
4471 
4472 		de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", ""));
4473 
4474 		for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4475 		{
4476 			const TestConfig&				testConfig				= testConfigs[configNdx];
4477 			de::MovePtr<tcu::TestCaseGroup>	sampleMaskValueTests	(new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description));
4478 
4479 			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4480 			{
4481 				std::ostringstream caseName;
4482 				caseName << "samples_" << samples[samplesNdx];
4483 
4484 				const deUint32					sampleMaskCount	= samples[samplesNdx] / 32;
4485 				de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4486 
4487 				std::vector<VkSampleMask> mask;
4488 				for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++)
4489 					mask.push_back(testConfig.sampleMask);
4490 
4491 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4492 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4493 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4494 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
4495 
4496 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4497 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4498 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4499 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
4500 
4501 				sampleMaskValueTests->addChild(samplesTests.release());
4502 			}
4503 
4504 			sampleMaskTests->addChild(sampleMaskValueTests.release());
4505 		}
4506 
4507 		multisampleTests->addChild(sampleMaskTests.release());
4508 
4509 	}
4510 
4511 	// AlphaToOne tests
4512 	{
4513 		de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", ""));
4514 
4515 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4516 		{
4517 			std::ostringstream caseName;
4518 			caseName << "samples_" << samples[samplesNdx];
4519 
4520 			alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx], IMAGE_BACKING_MODE_REGULAR));
4521 
4522 			caseName << "_sparse";
4523 			alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx], IMAGE_BACKING_MODE_SPARSE));
4524 		}
4525 
4526 		multisampleTests->addChild(alphaToOneTests.release());
4527 	}
4528 
4529 	// AlphaToCoverageEnable tests
4530 	{
4531 		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", ""));
4532 
4533 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4534 		{
4535 			std::ostringstream caseName;
4536 			caseName << "samples_" << samples[samplesNdx];
4537 
4538 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4539 
4540 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4541 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_REGULAR));
4542 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4543 
4544 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4545 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_SPARSE));
4546 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4547 
4548 			alphaToCoverageTests->addChild(samplesTests.release());
4549 		}
4550 		multisampleTests->addChild(alphaToCoverageTests.release());
4551 	}
4552 
4553 	// AlphaToCoverageEnable without color buffer tests
4554 	{
4555 		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageNoColorAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_no_color_attachment", ""));
4556 
4557 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4558 		{
4559 			std::ostringstream caseName;
4560 			caseName << "samples_" << samples[samplesNdx];
4561 
4562 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4563 
4564 			samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4565 			samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4566 
4567 			alphaToCoverageNoColorAttachmentTests->addChild(samplesTests.release());
4568 		}
4569 		multisampleTests->addChild(alphaToCoverageNoColorAttachmentTests.release());
4570 	}
4571 
4572 	// AlphaToCoverageEnable with unused color attachment:
4573 	// Set color output at location 0 as unused, but use the alpha write to control coverage for rendering to color buffer at location 1.
4574 	{
4575 		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageColorUnusedAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_unused_attachment", ""));
4576 
4577 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4578 		{
4579 			std::ostringstream caseName;
4580 			caseName << "samples_" << samples[samplesNdx];
4581 
4582 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4583 
4584 			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4585 			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4586 			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4587 			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4588 
4589 			alphaToCoverageColorUnusedAttachmentTests->addChild(samplesTests.release());
4590 		}
4591 		multisampleTests->addChild(alphaToCoverageColorUnusedAttachmentTests.release());
4592 	}
4593 
4594 	// Sampling from a multisampled image texture (texelFetch)
4595 	{
4596 		multisampleTests->addChild(createMultisampleSampledImageTests(testCtx));
4597 	}
4598 
4599 	// Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.)
4600 	{
4601 		multisampleTests->addChild(createMultisampleStorageImageTests(testCtx));
4602 	}
4603 
4604 	// Sampling from a multisampled image texture (texelFetch), checking supersample positions
4605 	{
4606 		multisampleTests->addChild(createMultisampleStandardSamplePositionTests(testCtx));
4607 	}
4608 
4609 	// VK_EXT_sample_locations
4610 	{
4611 		multisampleTests->addChild(createMultisampleSampleLocationsExtTests(testCtx));
4612 	}
4613 
4614 	// VK_AMD_mixed_attachment samples and VK_AMD_shader_fragment_mask
4615 	{
4616 		multisampleTests->addChild(createMultisampleMixedAttachmentSamplesTests(testCtx));
4617 		multisampleTests->addChild(createMultisampleShaderFragmentMaskTests(testCtx));
4618 	}
4619 
4620 	// Sample mask with and without vk_ext_post_depth_coverage
4621 	{
4622 		const vk::VkSampleCountFlagBits standardSamplesSet[] =
4623 		{
4624 			vk::VK_SAMPLE_COUNT_2_BIT,
4625 			vk::VK_SAMPLE_COUNT_4_BIT,
4626 			vk::VK_SAMPLE_COUNT_8_BIT,
4627 			vk::VK_SAMPLE_COUNT_16_BIT
4628 		};
4629 
4630 		de::MovePtr<tcu::TestCaseGroup> sampleMaskWithDepthTestGroup(new tcu::TestCaseGroup(testCtx, "sample_mask_with_depth_test", ""));
4631 
4632 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(standardSamplesSet); ++ndx)
4633 		{
4634 			std::ostringstream caseName;
4635 			caseName << "samples_" << standardSamplesSet[ndx];
4636 
4637 			sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", standardSamplesSet[ndx]));
4638 
4639 			caseName << "_post_depth_coverage";
4640 			sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", standardSamplesSet[ndx], true));
4641 
4642 		}
4643 		multisampleTests->addChild(sampleMaskWithDepthTestGroup.release());
4644 	}
4645 
4646 	{
4647 		static const std::vector<vk::VkSampleCountFlagBits> kSampleCounts =
4648 		{
4649 			vk::VK_SAMPLE_COUNT_1_BIT,
4650 			vk::VK_SAMPLE_COUNT_2_BIT,
4651 			vk::VK_SAMPLE_COUNT_4_BIT,
4652 			vk::VK_SAMPLE_COUNT_8_BIT,
4653 			vk::VK_SAMPLE_COUNT_16_BIT,
4654 			vk::VK_SAMPLE_COUNT_32_BIT,
4655 			vk::VK_SAMPLE_COUNT_64_BIT,
4656 		};
4657 
4658 		static const std::array<bool, 2> unusedAttachmentFlag = {{ false, true }};
4659 
4660 		{
4661 			de::MovePtr<tcu::TestCaseGroup> variableRateGroup(new tcu::TestCaseGroup(testCtx, "variable_rate", "Tests for multisample variable rate in subpasses"));
4662 
4663 			// 2 and 3 subpasses should be good enough.
4664 			static const std::vector<size_t> combinationSizes = { 2, 3 };
4665 
4666 			// Basic cases.
4667 			for (const auto size : combinationSizes)
4668 			{
4669 				const auto combs = combinations(kSampleCounts, size);
4670 				for (const auto& comb : combs)
4671 				{
4672 					// Check sample counts actually vary between some of the subpasses.
4673 					std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb));
4674 					if (uniqueVals.size() < 2)
4675 						continue;
4676 
4677 					std::ostringstream name;
4678 					std::ostringstream desc;
4679 
4680 					bool first = true;
4681 					for (const auto& count : comb)
4682 					{
4683 						name << (first ? "" : "_") << count;
4684 						desc << (first ? "Subpasses with counts " : ", ") << count;
4685 						first = false;
4686 					}
4687 
4688 					const VariableRateTestCase::TestParams params =
4689 					{
4690 						false,						//	bool						nonEmptyFramebuffer;
4691 						vk::VK_SAMPLE_COUNT_1_BIT,	//	vk::VkSampleCountFlagBits	fbCount;
4692 						false,						//	bool						unusedAttachment;
4693 						comb,						//	SampleCounts				subpassCounts;
4694 					};
4695 					variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), desc.str(), params));
4696 				}
4697 			}
4698 
4699 			// Cases with non-empty framebuffers: only 2 subpasses to avoid a large number of combinations.
4700 			{
4701 				// Use one more sample count for the framebuffer attachment. It will be taken from the last item.
4702 				auto combs = combinations(kSampleCounts, 2 + 1);
4703 				for (auto& comb : combs)
4704 				{
4705 					// Framebuffer sample count.
4706 					const auto fbCount = comb.back();
4707 					comb.pop_back();
4708 
4709 					// Check sample counts actually vary between some of the subpasses.
4710 					std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb));
4711 					if (uniqueVals.size() < 2)
4712 						continue;
4713 
4714 					for (const auto flag : unusedAttachmentFlag)
4715 					{
4716 						std::ostringstream name;
4717 						std::ostringstream desc;
4718 
4719 						desc << "Framebuffer with sample count " << fbCount << " and subpasses with counts ";
4720 
4721 						bool first = true;
4722 						for (const auto& count : comb)
4723 						{
4724 							name << (first ? "" : "_") << count;
4725 							desc << (first ? "" : ", ") << count;
4726 							first = false;
4727 						}
4728 
4729 						name << "_fb_" << fbCount;
4730 
4731 						if (flag)
4732 						{
4733 							name << "_unused";
4734 							desc << " and unused attachments";
4735 						}
4736 
4737 						const VariableRateTestCase::TestParams params =
4738 						{
4739 							true,						//	bool						nonEmptyFramebuffer;
4740 							fbCount,					//	vk::VkSampleCountFlagBits	fbCount;
4741 							flag,						//	bool						unusedAttachment;
4742 							comb,						//	SampleCounts				subpassCounts;
4743 						};
4744 						variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), desc.str(), params));
4745 					}
4746 				}
4747 			}
4748 
4749 			multisampleTests->addChild(variableRateGroup.release());
4750 		}
4751 
4752 		{
4753 			de::MovePtr<tcu::TestCaseGroup> mixedCountGroup(new tcu::TestCaseGroup(testCtx, "mixed_count", "Tests for mixed sample count in empty subpass and framebuffer"));
4754 
4755 			const auto combs = combinations(kSampleCounts, 2);
4756 			for (const auto& comb : combs)
4757 			{
4758 				// Check different sample count.
4759 				DE_ASSERT(comb.size() == 2u);
4760 				const auto& fbCount		= comb[0];
4761 				const auto& emptyCount	= comb[1];
4762 
4763 				if (fbCount == emptyCount)
4764 					continue;
4765 
4766 				const std::string fbCountStr	= de::toString(fbCount);
4767 				const std::string emptyCountStr	= de::toString(emptyCount);
4768 
4769 				for (const auto flag : unusedAttachmentFlag)
4770 				{
4771 					const std::string nameSuffix	= (flag ? "unused" : "");
4772 					const std::string descSuffix	= (flag ? "one unused attachment reference" : "no attachment references");
4773 					const std::string name			= fbCountStr + "_" + emptyCountStr + (nameSuffix.empty() ? "" : "_") + nameSuffix;
4774 					const std::string desc			= "Framebuffer with " + fbCountStr + " samples, subpass with " + emptyCountStr + " samples and " + descSuffix;
4775 
4776 					const VariableRateTestCase::TestParams params =
4777 					{
4778 						true,												//	bool						nonEmptyFramebuffer;
4779 						fbCount,											//	vk::VkSampleCountFlagBits	fbCount;
4780 						flag,												//	bool						unusedAttachment;
4781 						VariableRateTestCase::SampleCounts(1u, emptyCount),	//	SampleCounts				subpassCounts;
4782 					};
4783 					mixedCountGroup->addChild(new VariableRateTestCase(testCtx, name, desc, params));
4784 				}
4785 			}
4786 
4787 			multisampleTests->addChild(mixedCountGroup.release());
4788 		}
4789 	}
4790 
4791 	return multisampleTests.release();
4792 }
4793 
4794 } // pipeline
4795 } // vkt
4796