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::__anon4ab445100111::SampleMaskWithDepthTestInstance::SampleCoverage704 		SampleCoverage() {};
SampleCoveragevkt::pipeline::__anon4ab445100111::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 (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y))))
2055 			{
2056 				std::ostringstream message;
2057 				message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y);
2058 				return tcu::TestStatus::fail(message.str());
2059 			}
2060 		}
2061 	}
2062 
2063 	return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one");
2064 }
2065 
2066 
2067 // AlphaToCoverageInstance
2068 
AlphaToCoverageInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,ImageBackingMode backingMode)2069 AlphaToCoverageInstance::AlphaToCoverageInstance (Context&										context,
2070 												  VkPrimitiveTopology							topology,
2071 												  const std::vector<Vertex4RGBA>&				vertices,
2072 												  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
2073 												  const VkPipelineColorBlendAttachmentState&	blendState,
2074 												  GeometryType									geometryType,
2075 												  ImageBackingMode								backingMode)
2076 	: vkt::TestInstance			(context)
2077 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
2078 	, m_renderSize				(32, 32)
2079 	, m_primitiveTopology		(topology)
2080 	, m_vertices				(vertices)
2081 	, m_multisampleStateParams	(multisampleStateParams)
2082 	, m_colorBlendState			(blendState)
2083 	, m_geometryType			(geometryType)
2084 	, m_backingMode				(backingMode)
2085 {
2086 }
2087 
iterate(void)2088 tcu::TestStatus AlphaToCoverageInstance::iterate (void)
2089 {
2090 	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2091 
2092 	de::MovePtr<tcu::TextureLevel>	result;
2093 	MultisampleRenderer				renderer	(m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
2094 
2095 	result = renderer.render();
2096 
2097 	return verifyImage(result->getAccess());
2098 }
2099 
verifyImage(const tcu::ConstPixelBufferAccess & result)2100 tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
2101 {
2102 	float maxColorValue;
2103 
2104 	switch (m_geometryType)
2105 	{
2106 		case GEOMETRY_TYPE_OPAQUE_QUAD:
2107 			maxColorValue = 1.01f;
2108 			break;
2109 
2110 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
2111 			maxColorValue = 0.52f;
2112 			break;
2113 
2114 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
2115 			maxColorValue = 0.01f;
2116 			break;
2117 
2118 		default:
2119 			maxColorValue = 0.0f;
2120 			DE_ASSERT(false);
2121 	}
2122 
2123 	for (int y = 0; y < m_renderSize.y(); y++)
2124 	{
2125 		for (int x = 0; x < m_renderSize.x(); x++)
2126 		{
2127 			if (result.getPixel(x, y).x() > maxColorValue)
2128 			{
2129 				std::ostringstream message;
2130 				message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")";
2131 				return tcu::TestStatus::fail(message.str());
2132 			}
2133 		}
2134 	}
2135 
2136 	return tcu::TestStatus::pass("Image matches reference value");
2137 }
2138 
2139 // AlphaToCoverageNoColorAttachmentInstance
2140 
AlphaToCoverageNoColorAttachmentInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,ImageBackingMode backingMode)2141 AlphaToCoverageNoColorAttachmentInstance::AlphaToCoverageNoColorAttachmentInstance (Context&									context,
2142 																					VkPrimitiveTopology							topology,
2143 																					const std::vector<Vertex4RGBA>&				vertices,
2144 																					const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
2145 																					const VkPipelineColorBlendAttachmentState&	blendState,
2146 																					GeometryType								geometryType,
2147 																					ImageBackingMode							backingMode)
2148 	: vkt::TestInstance			(context)
2149 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
2150 	, m_depthStencilFormat		(VK_FORMAT_D16_UNORM)
2151 	, m_renderSize				(32, 32)
2152 	, m_primitiveTopology		(topology)
2153 	, m_vertices				(vertices)
2154 	, m_multisampleStateParams	(multisampleStateParams)
2155 	, m_colorBlendState			(blendState)
2156 	, m_geometryType			(geometryType)
2157 	, m_backingMode				(backingMode)
2158 {
2159 }
2160 
iterate(void)2161 tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::iterate (void)
2162 {
2163 	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2164 
2165 	de::MovePtr<tcu::TextureLevel>	result;
2166 	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);
2167 
2168 	result = renderer.render();
2169 
2170 	return verifyImage(result->getAccess());
2171 }
2172 
verifyImage(const tcu::ConstPixelBufferAccess & result)2173 tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
2174 {
2175 	for (int y = 0; y < m_renderSize.y(); y++)
2176 	{
2177 		for (int x = 0; x < m_renderSize.x(); x++)
2178 		{
2179 			// Expect full red for each pixel. Fail if clear color is showing.
2180 			if (result.getPixel(x, y).x() < 1.0f)
2181 			{
2182 				// Log result image when failing.
2183 				m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;
2184 
2185 				return tcu::TestStatus::fail("Fail");
2186 			}
2187 		}
2188 	}
2189 
2190 	return tcu::TestStatus::pass("Pass");
2191 }
2192 
2193 // AlphaToCoverageColorUnusedAttachmentInstance
2194 
AlphaToCoverageColorUnusedAttachmentInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,ImageBackingMode backingMode)2195 AlphaToCoverageColorUnusedAttachmentInstance::AlphaToCoverageColorUnusedAttachmentInstance (Context&									context,
2196 																							VkPrimitiveTopology							topology,
2197 																							const std::vector<Vertex4RGBA>&				vertices,
2198 																							const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
2199 																							const VkPipelineColorBlendAttachmentState&	blendState,
2200 																							GeometryType								geometryType,
2201 																							ImageBackingMode							backingMode)
2202 	: vkt::TestInstance			(context)
2203 	, m_colorFormat				(VK_FORMAT_R5G6B5_UNORM_PACK16)
2204 	, m_renderSize				(32, 32)
2205 	, m_primitiveTopology		(topology)
2206 	, m_vertices				(vertices)
2207 	, m_multisampleStateParams	(multisampleStateParams)
2208 	, m_colorBlendState			(blendState)
2209 	, m_geometryType			(geometryType)
2210 	, m_backingMode				(backingMode)
2211 {
2212 }
2213 
iterate(void)2214 tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::iterate (void)
2215 {
2216 	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2217 
2218 	de::MovePtr<tcu::TextureLevel>	result;
2219 	MultisampleRenderer				renderer	(m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_UNUSED_ATTACHMENT, m_backingMode);
2220 
2221 	result = renderer.render();
2222 
2223 	return verifyImage(result->getAccess());
2224 }
2225 
verifyImage(const tcu::ConstPixelBufferAccess & result)2226 tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
2227 {
2228 	for (int y = 0; y < m_renderSize.y(); y++)
2229 	{
2230 		for (int x = 0; x < m_renderSize.x(); x++)
2231 		{
2232 			// Quad color gets written to color buffer at location 1, and the alpha value to location 0 which is unused.
2233 			// The coverage should still be affected by the alpha written to location 0.
2234 			if ((m_geometryType == GEOMETRY_TYPE_OPAQUE_QUAD && result.getPixel(x, y).x() < 1.0f)
2235 				|| (m_geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD && result.getPixel(x, y).x() > 0.0f))
2236 			{
2237 				// Log result image when failing.
2238 				m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;
2239 
2240 				return tcu::TestStatus::fail("Fail");
2241 			}
2242 		}
2243 	}
2244 
2245 	return tcu::TestStatus::pass("Pass");
2246 }
2247 
2248 // SampleMaskWithDepthTestInstance
2249 
SampleMaskWithDepthTestInstance(Context & context,const VkSampleCountFlagBits rasterizationSamples,const bool enablePostDepthCoverage)2250 SampleMaskWithDepthTestInstance::SampleMaskWithDepthTestInstance (Context&						context,
2251 																  const VkSampleCountFlagBits	rasterizationSamples,
2252 																  const bool					enablePostDepthCoverage)
2253 	: vkt::TestInstance			(context)
2254 	, m_rasterizationSamples	(rasterizationSamples)
2255 	, m_enablePostDepthCoverage	(enablePostDepthCoverage)
2256 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
2257 	, m_depthStencilFormat		(VK_FORMAT_D16_UNORM)
2258 	, m_renderSize				(tcu::IVec2(3, 3))
2259 	, m_useDepth				(true)
2260 	, m_useStencil				(false)
2261 	, m_topology				(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
2262 	, m_renderColor				(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f))
2263 	, m_vertices				(generateVertices())
2264 	, m_multisampleStateParams	(getMultisampleState(rasterizationSamples))
2265 	, m_blendState				(getDefaultColorBlendAttachmentState())
2266 	, m_renderType				(RENDER_TYPE_RESOLVE)
2267 	, m_imageBackingMode		(IMAGE_BACKING_MODE_REGULAR)
2268 	, m_depthClearValue			(0.667f)
2269 {
2270 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_2_BIT]	= SampleCoverage(1u, 1u);	// !< Sample coverage of the diagonally halved pixel,
2271 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_4_BIT]	= SampleCoverage(2u, 2u);	// !< with max possible subPixelPrecisionBits threshold
2272 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_8_BIT]	= SampleCoverage(2u, 6u);	// !<
2273 	m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_16_BIT]	= SampleCoverage(6u, 11u);	// !<
2274 }
2275 
iterate(void)2276 tcu::TestStatus SampleMaskWithDepthTestInstance::iterate (void)
2277 {
2278 	de::MovePtr<tcu::TextureLevel>	result;
2279 
2280 	MultisampleRenderer renderer (m_context, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, 1u, &m_topology,
2281 								  &m_vertices, m_multisampleStateParams, m_blendState, m_renderType, m_imageBackingMode, m_depthClearValue);
2282 	result = renderer.render();
2283 
2284 	return verifyImage(result->getAccess());
2285 }
2286 
getMultisampleState(const VkSampleCountFlagBits rasterizationSamples)2287 VkPipelineMultisampleStateCreateInfo SampleMaskWithDepthTestInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples)
2288 {
2289 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2290 	{
2291 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
2292 		DE_NULL,													// const void*								pNext;
2293 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
2294 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
2295 		false,														// VkBool32									sampleShadingEnable;
2296 		0.0f,														// float									minSampleShading;
2297 		DE_NULL,													// const VkSampleMask*						pSampleMask;
2298 		false,														// VkBool32									alphaToCoverageEnable;
2299 		false														// VkBool32									alphaToOneEnable;
2300 	};
2301 
2302 	return multisampleStateParams;
2303 }
2304 
generateVertices(void)2305 std::vector<Vertex4RGBA> SampleMaskWithDepthTestInstance::generateVertices (void)
2306 {
2307 	std::vector<Vertex4RGBA> vertices;
2308 
2309 	{
2310 		const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor };
2311 		vertices.push_back(vertexInput);
2312 	}
2313 	{
2314 		const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor };
2315 		vertices.push_back(vertexInput);
2316 	}
2317 	{
2318 		const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f,  1.0f, 1.0f, 1.0f), m_renderColor };
2319 		vertices.push_back(vertexInput);
2320 	}
2321 
2322 	return vertices;
2323 }
2324 
verifyImage(const tcu::ConstPixelBufferAccess & result)2325 tcu::TestStatus SampleMaskWithDepthTestInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
2326 {
2327 	bool			pass	= true;
2328 	const int		width	= result.getWidth();
2329 	const int		height	= result.getHeight();
2330 	tcu::TestLog&	log		= m_context.getTestContext().getLog();
2331 
2332 	DE_ASSERT(width == 3);
2333 	DE_ASSERT(height == 3);
2334 
2335 	const tcu::Vec4 clearColor = tcu::Vec4(0.0f);
2336 
2337 	for (int x = 0; x < width; ++x)
2338 	for (int y = 0; y < height; ++y)
2339 	{
2340 		const tcu::Vec4 resultPixel = result.getPixel(x, y);
2341 
2342 		if (x + y == 0)
2343 		{
2344 			if (resultPixel != m_renderColor)
2345 			{
2346 				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
2347 					<< " Reference: " << m_renderColor << tcu::TestLog::EndMessage;
2348 				pass = false;
2349 			}
2350 		}
2351 		else if (x + y == 1)
2352 		{
2353 			// default: m_rasterizationSamples bits set in FS's gl_SampleMaskIn[0] (before depth test)
2354 			// post_depth_coverage: m_refCoverageAfterDepthTest[m_rasterizationSamples] bits set in FS's gl_SampleMaskIn[0] (after depth test)
2355 			const float		threshold	= 0.02f;
2356 			const float		minCoverage	= (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples : 1.0f)
2357 										* ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples);
2358 			const float		maxCoverage	= (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples : 1.0f)
2359 										* ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples);
2360 
2361 			bool			localPass	= true;
2362 			for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx)
2363 			{
2364 				if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= m_renderColor[componentNdx] * (minCoverage - threshold)
2365 															|| resultPixel[componentNdx] >= m_renderColor[componentNdx] * (maxCoverage + threshold)))
2366 					localPass = false;
2367 			}
2368 
2369 			if (!localPass)
2370 			{
2371 				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
2372 					<< " Reference range ( " << m_renderColor * (minCoverage - threshold) << " ; " << m_renderColor * (maxCoverage + threshold) << " )" << tcu::TestLog::EndMessage;
2373 				pass = false;
2374 			}
2375 		}
2376 		else
2377 		{
2378 			if (resultPixel != clearColor)
2379 			{
2380 				log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
2381 					<< " Reference: " << clearColor << tcu::TestLog::EndMessage;
2382 				pass = false;
2383 			}
2384 		}
2385 	}
2386 
2387 	if (pass)
2388 		return tcu::TestStatus::pass("Passed");
2389 	else
2390 		return tcu::TestStatus::fail("Failed");
2391 }
2392 
2393 // MultisampleRenderer
2394 
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)2395 MultisampleRenderer::MultisampleRenderer (Context&										context,
2396 										  const VkFormat								colorFormat,
2397 										  const tcu::IVec2&								renderSize,
2398 										  const VkPrimitiveTopology						topology,
2399 										  const std::vector<Vertex4RGBA>&				vertices,
2400 										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
2401 										  const VkPipelineColorBlendAttachmentState&	blendState,
2402 										  const RenderType								renderType,
2403 										  const ImageBackingMode						backingMode)
2404 	: m_context					(context)
2405 	, m_bindSemaphore			(createSemaphore(context.getDeviceInterface(), context.getDevice()))
2406 	, m_colorFormat				(colorFormat)
2407 	, m_depthStencilFormat		(VK_FORMAT_UNDEFINED)
2408 	, m_renderSize				(renderSize)
2409 	, m_useDepth				(false)
2410 	, m_useStencil				(false)
2411 	, m_multisampleStateParams	(multisampleStateParams)
2412 	, m_colorBlendState			(blendState)
2413 	, m_renderType				(renderType)
2414 	, m_backingMode				(backingMode)
2415 	, m_depthClearValue			(1.0f)
2416 {
2417 	initialize(context, 1u, &topology, &vertices);
2418 }
2419 
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)2420 MultisampleRenderer::MultisampleRenderer (Context&										context,
2421 										  const VkFormat								colorFormat,
2422 										  const VkFormat								depthStencilFormat,
2423 										  const tcu::IVec2&								renderSize,
2424 										  const bool									useDepth,
2425 										  const bool									useStencil,
2426 										  const deUint32								numTopologies,
2427 										  const VkPrimitiveTopology*					pTopology,
2428 										  const std::vector<Vertex4RGBA>*				pVertices,
2429 										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
2430 										  const VkPipelineColorBlendAttachmentState&	blendState,
2431 										  const RenderType								renderType,
2432 										  const ImageBackingMode						backingMode,
2433 										  const float									depthClearValue)
2434 	: m_context					(context)
2435 	, m_bindSemaphore			(createSemaphore(context.getDeviceInterface(), context.getDevice()))
2436 	, m_colorFormat				(colorFormat)
2437 	, m_depthStencilFormat		(depthStencilFormat)
2438 	, m_renderSize				(renderSize)
2439 	, m_useDepth				(useDepth)
2440 	, m_useStencil				(useStencil)
2441 	, m_multisampleStateParams	(multisampleStateParams)
2442 	, m_colorBlendState			(blendState)
2443 	, m_renderType				(renderType)
2444 	, m_backingMode				(backingMode)
2445 	, m_depthClearValue			(depthClearValue)
2446 {
2447 	initialize(context, numTopologies, pTopology, pVertices);
2448 }
2449 
initialize(Context & context,const deUint32 numTopologies,const VkPrimitiveTopology * pTopology,const std::vector<Vertex4RGBA> * pVertices)2450 void MultisampleRenderer::initialize (Context&									context,
2451 									  const deUint32							numTopologies,
2452 									  const VkPrimitiveTopology*				pTopology,
2453 									  const std::vector<Vertex4RGBA>*			pVertices)
2454 {
2455 	if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples))
2456 		throw tcu::NotSupportedError("Unsupported number of rasterization samples");
2457 
2458 	const DeviceInterface&			vk						= context.getDeviceInterface();
2459 	const VkDevice					vkDevice				= context.getDevice();
2460 	const VkPhysicalDeviceFeatures	features				= context.getDeviceFeatures();
2461 	const deUint32					queueFamilyIndices[]	= { context.getUniversalQueueFamilyIndex(), context.getSparseQueueFamilyIndex() };
2462 	const bool						sparse					= m_backingMode == IMAGE_BACKING_MODE_SPARSE;
2463 	const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
2464 	const VkImageCreateFlags		imageCreateFlags		= sparse ? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0u;
2465 	const VkSharingMode				sharingMode				= (sparse && context.getUniversalQueueFamilyIndex() != context.getSparseQueueFamilyIndex()) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
2466 	Allocator&						memAlloc				= m_context.getDefaultAllocator();
2467 	const bool						usesResolveImage		= m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT;
2468 
2469 	if (sparse)
2470 	{
2471 		bool sparseSamplesSupported = false;
2472 		switch(m_multisampleStateParams.rasterizationSamples)
2473 		{
2474 			case VK_SAMPLE_COUNT_2_BIT:
2475 				sparseSamplesSupported = features.sparseResidency2Samples;
2476 				break;
2477 			case VK_SAMPLE_COUNT_4_BIT:
2478 				sparseSamplesSupported = features.sparseResidency4Samples;
2479 				break;
2480 			case VK_SAMPLE_COUNT_8_BIT:
2481 				sparseSamplesSupported = features.sparseResidency8Samples;
2482 				break;
2483 			case VK_SAMPLE_COUNT_16_BIT:
2484 				sparseSamplesSupported = features.sparseResidency16Samples;
2485 				break;
2486 			default:
2487 				break;
2488 		}
2489 
2490 		if (!sparseSamplesSupported)
2491 			throw tcu::NotSupportedError("Unsupported number of rasterization samples for sparse residency");
2492 	}
2493 
2494 	if (sparse && !context.getDeviceFeatures().sparseBinding)
2495 		throw tcu::NotSupportedError("No sparseBinding support");
2496 
2497 	// Create color image
2498 	{
2499 		const VkImageUsageFlags	imageUsageFlags		= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2500 			(m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u);
2501 
2502 		const VkImageCreateInfo colorImageParams	=
2503 		{
2504 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
2505 			DE_NULL,																	// const void*				pNext;
2506 			imageCreateFlags,															// VkImageCreateFlags		flags;
2507 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
2508 			m_colorFormat,																// VkFormat					format;
2509 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },				// VkExtent3D				extent;
2510 			1u,																			// deUint32					mipLevels;
2511 			1u,																			// deUint32					arrayLayers;
2512 			m_multisampleStateParams.rasterizationSamples,								// VkSampleCountFlagBits	samples;
2513 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
2514 			imageUsageFlags,															// VkImageUsageFlags		usage;
2515 			sharingMode,																// VkSharingMode			sharingMode;
2516 			sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u,						// deUint32					queueFamilyIndexCount;
2517 			queueFamilyIndices,															// const deUint32*			pQueueFamilyIndices;
2518 			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
2519 		};
2520 
2521 		if (sparse && !checkSparseImageFormatSupport(context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams))
2522 			TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");
2523 
2524 		m_colorImage = createImage(vk, vkDevice, &colorImageParams);
2525 
2526 		// Allocate and bind color image memory
2527 		if (sparse)
2528 		{
2529 			allocateAndBindSparseImage(vk, vkDevice, context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams, *m_bindSemaphore, context.getSparseQueue(), memAlloc, m_allocations, mapVkFormat(m_colorFormat), *m_colorImage);
2530 		}
2531 		else
2532 		{
2533 			m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
2534 			VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
2535 		}
2536 	}
2537 
2538 	// Create resolve image
2539 	if (usesResolveImage)
2540 	{
2541 		const VkImageCreateInfo resolveImageParams =
2542 		{
2543 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
2544 			DE_NULL,																		// const void*				pNext;
2545 			0u,																				// VkImageCreateFlags		flags;
2546 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
2547 			m_colorFormat,																	// VkFormat					format;
2548 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
2549 			1u,																				// deUint32					mipLevels;
2550 			1u,																				// deUint32					arrayLayers;
2551 			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
2552 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
2553 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |			// VkImageUsageFlags		usage;
2554 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2555 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
2556 			1u,																				// deUint32					queueFamilyIndexCount;
2557 			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
2558 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
2559 		};
2560 
2561 		m_resolveImage = createImage(vk, vkDevice, &resolveImageParams);
2562 
2563 		// Allocate and bind resolve image memory
2564 		m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any);
2565 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset()));
2566 
2567 		// Create resolve attachment view
2568 		{
2569 			const VkImageViewCreateInfo resolveAttachmentViewParams =
2570 			{
2571 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
2572 				DE_NULL,										// const void*				pNext;
2573 				0u,												// VkImageViewCreateFlags	flags;
2574 				*m_resolveImage,								// VkImage					image;
2575 				VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
2576 				m_colorFormat,									// VkFormat					format;
2577 				componentMappingRGBA,							// VkComponentMapping		components;
2578 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2579 			};
2580 
2581 			m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
2582 		}
2583 	}
2584 
2585 	// Create per-sample output images
2586 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2587 	{
2588 		const VkImageCreateInfo perSampleImageParams =
2589 		{
2590 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
2591 			DE_NULL,																		// const void*				pNext;
2592 			0u,																				// VkImageCreateFlags		flags;
2593 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
2594 			m_colorFormat,																	// VkFormat					format;
2595 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
2596 			1u,																				// deUint32					mipLevels;
2597 			1u,																				// deUint32					arrayLayers;
2598 			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
2599 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
2600 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |			// VkImageUsageFlags		usage;
2601 			VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2602 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
2603 			1u,																				// deUint32					queueFamilyIndexCount;
2604 			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
2605 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
2606 		};
2607 
2608 		m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples));
2609 
2610 		for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2611 		{
2612 			m_perSampleImages[i]	= de::SharedPtr<PerSampleImage>(new PerSampleImage);
2613 			PerSampleImage& image	= *m_perSampleImages[i];
2614 
2615 			image.m_image			= createImage(vk, vkDevice, &perSampleImageParams);
2616 
2617 			// Allocate and bind image memory
2618 			image.m_imageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any);
2619 			VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset()));
2620 
2621 			// Create per-sample attachment view
2622 			{
2623 				const VkImageViewCreateInfo perSampleAttachmentViewParams =
2624 				{
2625 					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
2626 					DE_NULL,										// const void*				pNext;
2627 					0u,												// VkImageViewCreateFlags	flags;
2628 					*image.m_image,									// VkImage					image;
2629 					VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
2630 					m_colorFormat,									// VkFormat					format;
2631 					componentMappingRGBA,							// VkComponentMapping		components;
2632 					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2633 				};
2634 
2635 				image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams);
2636 			}
2637 		}
2638 	}
2639 
2640 	// Create a depth/stencil image
2641 	if (m_useDepth || m_useStencil)
2642 	{
2643 		const VkImageCreateInfo depthStencilImageParams =
2644 		{
2645 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
2646 			DE_NULL,																		// const void*				pNext;
2647 			0u,																				// VkImageCreateFlags		flags;
2648 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
2649 			m_depthStencilFormat,															// VkFormat					format;
2650 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
2651 			1u,																				// deUint32					mipLevels;
2652 			1u,																				// deUint32					arrayLayers;
2653 			m_multisampleStateParams.rasterizationSamples,									// VkSampleCountFlagBits	samples;
2654 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
2655 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,									// VkImageUsageFlags		usage;
2656 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
2657 			1u,																				// deUint32					queueFamilyIndexCount;
2658 			queueFamilyIndices,																// const deUint32*			pQueueFamilyIndices;
2659 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
2660 		};
2661 
2662 		m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams);
2663 
2664 		// Allocate and bind depth/stencil image memory
2665 		m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any);
2666 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset()));
2667 	}
2668 
2669 	// Create color attachment view
2670 	{
2671 		const VkImageViewCreateInfo colorAttachmentViewParams =
2672 		{
2673 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
2674 			DE_NULL,										// const void*				pNext;
2675 			0u,												// VkImageViewCreateFlags	flags;
2676 			*m_colorImage,									// VkImage					image;
2677 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
2678 			m_colorFormat,									// VkFormat					format;
2679 			componentMappingRGBA,							// VkComponentMapping		components;
2680 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2681 		};
2682 
2683 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
2684 	}
2685 
2686 	VkImageAspectFlags	depthStencilAttachmentAspect	= (VkImageAspectFlagBits)0;
2687 
2688 	// Create depth/stencil attachment view
2689 	if (m_useDepth || m_useStencil)
2690 	{
2691 		depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat);
2692 
2693 		const VkImageViewCreateInfo depthStencilAttachmentViewParams =
2694 		{
2695 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
2696 			DE_NULL,											// const void*				pNext;
2697 			0u,													// VkImageViewCreateFlags	flags;
2698 			*m_depthStencilImage,								// VkImage					image;
2699 			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
2700 			m_depthStencilFormat,								// VkFormat					format;
2701 			componentMappingRGBA,								// VkComponentMapping		components;
2702 			{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2703 		};
2704 
2705 		m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
2706 	}
2707 
2708 	// Create render pass
2709 	{
2710 		std::vector<VkAttachmentDescription> attachmentDescriptions;
2711 		{
2712 			const VkAttachmentDescription colorAttachmentDescription =
2713 			{
2714 				0u,													// VkAttachmentDescriptionFlags		flags;
2715 				m_colorFormat,										// VkFormat							format;
2716 				m_multisampleStateParams.rasterizationSamples,		// VkSampleCountFlagBits			samples;
2717 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
2718 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
2719 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
2720 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
2721 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
2722 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
2723 			};
2724 			attachmentDescriptions.push_back(colorAttachmentDescription);
2725 		}
2726 
2727 		deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED;
2728 
2729 		if (usesResolveImage)
2730 		{
2731 			resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2732 
2733 			const VkAttachmentDescription resolveAttachmentDescription =
2734 			{
2735 				0u,													// VkAttachmentDescriptionFlags		flags;
2736 				m_colorFormat,										// VkFormat							format;
2737 				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
2738 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
2739 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
2740 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
2741 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
2742 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
2743 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
2744 			};
2745 			attachmentDescriptions.push_back(resolveAttachmentDescription);
2746 		}
2747 
2748 		deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED;
2749 
2750 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2751 		{
2752 			perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2753 
2754 			const VkAttachmentDescription perSampleAttachmentDescription =
2755 			{
2756 				0u,													// VkAttachmentDescriptionFlags		flags;
2757 				m_colorFormat,										// VkFormat							format;
2758 				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
2759 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
2760 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
2761 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
2762 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
2763 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
2764 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
2765 			};
2766 
2767 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2768 			{
2769 				attachmentDescriptions.push_back(perSampleAttachmentDescription);
2770 			}
2771 		}
2772 
2773 		deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
2774 
2775 		if (m_useDepth || m_useStencil)
2776 		{
2777 			depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2778 
2779 			const VkAttachmentDescription depthStencilAttachmentDescription =
2780 			{
2781 				0u,																					// VkAttachmentDescriptionFlags		flags;
2782 				m_depthStencilFormat,																// VkFormat							format;
2783 				m_multisampleStateParams.rasterizationSamples,										// VkSampleCountFlagBits			samples;
2784 				(m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentLoadOp				loadOp;
2785 				(m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),		// VkAttachmentStoreOp				storeOp;
2786 				(m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentStoreOp				stencilLoadOp;
2787 				(m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),	// VkAttachmentStoreOp				stencilStoreOp;
2788 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,									// VkImageLayout					initialLayout;
2789 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL									// VkImageLayout					finalLayout;
2790 			};
2791 			attachmentDescriptions.push_back(depthStencilAttachmentDescription);
2792 		};
2793 
2794 		const VkAttachmentReference colorAttachmentReference =
2795 		{
2796 			0u,													// deUint32			attachment;
2797 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
2798 		};
2799 
2800 		const VkAttachmentReference inputAttachmentReference =
2801 		{
2802 			0u,													// deUint32			attachment;
2803 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL			// VkImageLayout	layout;
2804 		};
2805 
2806 		const VkAttachmentReference resolveAttachmentReference =
2807 		{
2808 			resolveAttachmentIndex,								// deUint32			attachment;
2809 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
2810 		};
2811 
2812 		const VkAttachmentReference colorAttachmentReferencesUnusedAttachment[] =
2813 		{
2814 			{
2815 				VK_ATTACHMENT_UNUSED,		// deUint32			attachment
2816 				VK_IMAGE_LAYOUT_UNDEFINED	// VkImageLayout	layout
2817 			},
2818 			{
2819 				0u,											// deUint32			attachment
2820 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
2821 			}
2822 		};
2823 
2824 		const VkAttachmentReference resolveAttachmentReferencesUnusedAttachment[] =
2825 		{
2826 			{
2827 				VK_ATTACHMENT_UNUSED,		// deUint32			attachment
2828 				VK_IMAGE_LAYOUT_UNDEFINED	// VkImageLayout	layout
2829 			},
2830 			{
2831 				resolveAttachmentIndex,						// deUint32			attachment
2832 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
2833 			}
2834 		};
2835 
2836 		std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size());
2837 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2838 		{
2839 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2840 			{
2841 				const VkAttachmentReference perSampleAttachmentReference =
2842 				{
2843 					perSampleAttachmentIndex + static_cast<deUint32>(i),	// deUint32			attachment;
2844 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL				// VkImageLayout	layout;
2845 				};
2846 				perSampleAttachmentReferences[i] = perSampleAttachmentReference;
2847 			}
2848 		}
2849 
2850 		const VkAttachmentReference depthStencilAttachmentReference =
2851 		{
2852 			depthStencilAttachmentIndex,						// deUint32			attachment;
2853 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
2854 		};
2855 
2856 		std::vector<VkSubpassDescription>	subpassDescriptions;
2857 		std::vector<VkSubpassDependency>	subpassDependencies;
2858 
2859 		if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
2860 		{
2861 				const VkSubpassDescription	subpassDescription0	=
2862 				{
2863 					0u,										// VkSubpassDescriptionFlags	flags
2864 					VK_PIPELINE_BIND_POINT_GRAPHICS,		// VkPipelineBindPoint			pipelineBindPoint
2865 					0u,										// deUint32						inputAttachmentCount
2866 					DE_NULL,								// const VkAttachmentReference*	pInputAttachments
2867 					0u,										// deUint32						colorAttachmentCount
2868 					DE_NULL,								// const VkAttachmentReference*	pColorAttachments
2869 					DE_NULL,								// const VkAttachmentReference*	pResolveAttachments
2870 					&depthStencilAttachmentReference,		// const VkAttachmentReference*	pDepthStencilAttachment
2871 					0u,										// deUint32						preserveAttachmentCount
2872 					DE_NULL									// const VkAttachmentReference*	pPreserveAttachments
2873 				};
2874 
2875 				const VkSubpassDescription	subpassDescription1	=
2876 				{
2877 					0u,									// VkSubpassDescriptionFlags	flags
2878 					VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint
2879 					0u,									// deUint32						inputAttachmentCount
2880 					DE_NULL,							// const VkAttachmentReference*	pInputAttachments
2881 					1u,									// deUint32						colorAttachmentCount
2882 					&colorAttachmentReference,			// const VkAttachmentReference*	pColorAttachments
2883 					&resolveAttachmentReference,		// const VkAttachmentReference*	pResolveAttachments
2884 					&depthStencilAttachmentReference,	// const VkAttachmentReference*	pDepthStencilAttachment
2885 					0u,									// deUint32						preserveAttachmentCount
2886 					DE_NULL								// const VkAttachmentReference*	pPreserveAttachments
2887 				};
2888 
2889 				const VkSubpassDependency	subpassDependency	=
2890 				{
2891 					0u,												// deUint32				srcSubpass
2892 					1u,												// deUint32				dstSubpass
2893 					VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,		// VkPipelineStageFlags	srcStageMask
2894 					VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,		// VkPipelineStageFlags	dstStageMask
2895 					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,	// VkAccessFlags		srcAccessMask
2896 					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,	// VkAccessFlags		dstAccessMask
2897 					0u												// VkDependencyFlags	dependencyFlags
2898 				};
2899 
2900 				subpassDescriptions.push_back(subpassDescription0);
2901 				subpassDescriptions.push_back(subpassDescription1);
2902 				subpassDependencies.push_back(subpassDependency);
2903 		}
2904 		else if (m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
2905 		{
2906 			const VkSubpassDescription renderSubpassDescription =
2907 			{
2908 				0u,												// VkSubpassDescriptionFlags	flags
2909 				VK_PIPELINE_BIND_POINT_GRAPHICS,				// VkPipelineBindPoint			pipelineBindPoint
2910 				0u,												// deUint32						inputAttachmentCount
2911 				DE_NULL,										// const VkAttachmentReference*	pInputAttachments
2912 				2u,												// deUint32						colorAttachmentCount
2913 				colorAttachmentReferencesUnusedAttachment,		// const VkAttachmentReference*	pColorAttachments
2914 				resolveAttachmentReferencesUnusedAttachment,	// const VkAttachmentReference*	pResolveAttachments
2915 				DE_NULL,										// const VkAttachmentReference*	pDepthStencilAttachment
2916 				0u,												// deUint32						preserveAttachmentCount
2917 				DE_NULL											// const VkAttachmentReference*	pPreserveAttachments
2918 			};
2919 
2920 			subpassDescriptions.push_back(renderSubpassDescription);
2921 		}
2922 		else
2923 		{
2924 			{
2925 				const VkSubpassDescription renderSubpassDescription =
2926 				{
2927 					0u,																				// VkSubpassDescriptionFlags	flags;
2928 					VK_PIPELINE_BIND_POINT_GRAPHICS,												// VkPipelineBindPoint			pipelineBindPoint;
2929 					0u,																				// deUint32						inputAttachmentCount;
2930 					DE_NULL,																		// const VkAttachmentReference*	pInputAttachments;
2931 					1u,																				// deUint32						colorAttachmentCount;
2932 					&colorAttachmentReference,														// const VkAttachmentReference*	pColorAttachments;
2933 					usesResolveImage ? &resolveAttachmentReference : DE_NULL,						// const VkAttachmentReference*	pResolveAttachments;
2934 					(m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL),		// const VkAttachmentReference*	pDepthStencilAttachment;
2935 					0u,																				// deUint32						preserveAttachmentCount;
2936 					DE_NULL																			// const VkAttachmentReference*	pPreserveAttachments;
2937 				};
2938 				subpassDescriptions.push_back(renderSubpassDescription);
2939 			}
2940 
2941 			if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2942 			{
2943 
2944 				for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2945 				{
2946 					const VkSubpassDescription copySampleSubpassDescription =
2947 					{
2948 						0u,													// VkSubpassDescriptionFlags		flags;
2949 						VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
2950 						1u,													// deUint32							inputAttachmentCount;
2951 						&inputAttachmentReference,							// const VkAttachmentReference*		pInputAttachments;
2952 						1u,													// deUint32							colorAttachmentCount;
2953 						&perSampleAttachmentReferences[i],					// const VkAttachmentReference*		pColorAttachments;
2954 						DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
2955 						DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
2956 						0u,													// deUint32							preserveAttachmentCount;
2957 						DE_NULL												// const VkAttachmentReference*		pPreserveAttachments;
2958 					};
2959 					subpassDescriptions.push_back(copySampleSubpassDescription);
2960 
2961 					const VkSubpassDependency copySampleSubpassDependency =
2962 					{
2963 						0u,													// deUint32							srcSubpass
2964 						1u + static_cast<deUint32>(i),						// deUint32							dstSubpass
2965 						VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,		// VkPipelineStageFlags				srcStageMask
2966 						VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,				// VkPipelineStageFlags				dstStageMask
2967 						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags					srcAccessMask
2968 						VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,				// VkAccessFlags					dstAccessMask
2969 						0u,													// VkDependencyFlags				dependencyFlags
2970 					};
2971 					subpassDependencies.push_back(copySampleSubpassDependency);
2972 				}
2973 			}
2974 		}
2975 
2976 		const VkRenderPassCreateInfo renderPassParams =
2977 		{
2978 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,					// VkStructureType					sType;
2979 			DE_NULL,													// const void*						pNext;
2980 			0u,															// VkRenderPassCreateFlags			flags;
2981 			(deUint32)attachmentDescriptions.size(),					// deUint32							attachmentCount;
2982 			&attachmentDescriptions[0],									// const VkAttachmentDescription*	pAttachments;
2983 			(deUint32)subpassDescriptions.size(),						// deUint32							subpassCount;
2984 			&subpassDescriptions[0],									// const VkSubpassDescription*		pSubpasses;
2985 			(deUint32)subpassDependencies.size(),						// deUint32							dependencyCount;
2986 			subpassDependencies.size() != 0 ? &subpassDependencies[0] : DE_NULL
2987 		};
2988 
2989 		m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2990 	}
2991 
2992 	// Create framebuffer
2993 	{
2994 		std::vector<VkImageView> attachments;
2995 		attachments.push_back(*m_colorAttachmentView);
2996 		if (usesResolveImage)
2997 		{
2998 			attachments.push_back(*m_resolveAttachmentView);
2999 		}
3000 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3001 		{
3002 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3003 			{
3004 				attachments.push_back(*m_perSampleImages[i]->m_attachmentView);
3005 			}
3006 		}
3007 
3008 		if (m_useDepth || m_useStencil)
3009 		{
3010 			attachments.push_back(*m_depthStencilAttachmentView);
3011 		}
3012 
3013 		const VkFramebufferCreateInfo framebufferParams =
3014 		{
3015 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType					sType;
3016 			DE_NULL,											// const void*						pNext;
3017 			0u,													// VkFramebufferCreateFlags			flags;
3018 			*m_renderPass,										// VkRenderPass						renderPass;
3019 			(deUint32)attachments.size(),						// deUint32							attachmentCount;
3020 			&attachments[0],									// const VkImageView*				pAttachments;
3021 			(deUint32)m_renderSize.x(),							// deUint32							width;
3022 			(deUint32)m_renderSize.y(),							// deUint32							height;
3023 			1u													// deUint32							layers;
3024 		};
3025 
3026 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
3027 	}
3028 
3029 	// Create pipeline layout
3030 	{
3031 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
3032 		{
3033 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
3034 			DE_NULL,											// const void*						pNext;
3035 			0u,													// VkPipelineLayoutCreateFlags		flags;
3036 			0u,													// deUint32							setLayoutCount;
3037 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
3038 			0u,													// deUint32							pushConstantRangeCount;
3039 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
3040 		};
3041 
3042 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
3043 
3044 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3045 		{
3046 
3047 			// Create descriptor set layout
3048 			const VkDescriptorSetLayoutBinding		layoutBinding					=
3049 			{
3050 				0u,															// deUint32								binding;
3051 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,						// VkDescriptorType						descriptorType;
3052 				1u,															// deUint32								descriptorCount;
3053 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlags					stageFlags;
3054 				DE_NULL,													// const VkSampler*						pImmutableSamplers;
3055 			};
3056 
3057 			const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutParams		=
3058 			{
3059 				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType
3060 				DE_NULL,													// const void*							pNext
3061 				0u,															// VkDescriptorSetLayoutCreateFlags		flags
3062 				1u,															// deUint32								bindingCount
3063 				&layoutBinding												// const VkDescriptorSetLayoutBinding*	pBindings
3064 			};
3065 			m_copySampleDesciptorLayout	= createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
3066 
3067 			// Create pipeline layout
3068 
3069 			const VkPushConstantRange				pushConstantRange				=
3070 			{
3071 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlags					stageFlags;
3072 				0u,															// deUint32								offset;
3073 				sizeof(deInt32)												// deUint32								size;
3074 			};
3075 			const VkPipelineLayoutCreateInfo		copySamplePipelineLayoutParams	=
3076 			{
3077 				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// VkStructureType						sType;
3078 				DE_NULL,													// const void*							pNext;
3079 				0u,															// VkPipelineLayoutCreateFlags			flags;
3080 				1u,															// deUint32								setLayoutCount;
3081 				&m_copySampleDesciptorLayout.get(),							// const VkDescriptorSetLayout*			pSetLayouts;
3082 				1u,															// deUint32								pushConstantRangeCount;
3083 				&pushConstantRange											// const VkPushConstantRange*			pPushConstantRanges;
3084 			};
3085 			m_copySamplePipelineLayout		= createPipelineLayout(vk, vkDevice, &copySamplePipelineLayoutParams);
3086 		}
3087 	}
3088 
3089 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
3090 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
3091 
3092 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3093 	{
3094 		m_copySampleVertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("quad_vert"), 0);
3095 		m_copySampleFragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("copy_sample_frag"), 0);
3096 	}
3097 
3098 	// Create pipeline
3099 	{
3100 		const VkVertexInputBindingDescription	vertexInputBindingDescription =
3101 		{
3102 			0u,									// deUint32				binding;
3103 			sizeof(Vertex4RGBA),				// deUint32				stride;
3104 			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputRate	inputRate;
3105 		};
3106 
3107 		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
3108 		{
3109 			{
3110 				0u,									// deUint32	location;
3111 				0u,									// deUint32	binding;
3112 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
3113 				0u									// deUint32	offset;
3114 			},
3115 			{
3116 				1u,									// deUint32	location;
3117 				0u,									// deUint32	binding;
3118 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
3119 				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
3120 			}
3121 		};
3122 
3123 		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
3124 		{
3125 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
3126 			DE_NULL,														// const void*								pNext;
3127 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
3128 			1u,																// deUint32									vertexBindingDescriptionCount;
3129 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
3130 			2u,																// deUint32									vertexAttributeDescriptionCount;
3131 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
3132 		};
3133 
3134 		const std::vector<VkViewport>	viewports		(1, makeViewport(m_renderSize));
3135 		const std::vector<VkRect2D>		scissors		(1, makeRect2D(m_renderSize));
3136 
3137 		const deUint32					attachmentCount	= m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT ? 2u : 1u;
3138 
3139 		std::vector<VkPipelineColorBlendAttachmentState> attachments;
3140 
3141 		for (deUint32 attachmentIdx = 0; attachmentIdx < attachmentCount; attachmentIdx++)
3142 			attachments.push_back(m_colorBlendState);
3143 
3144 		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
3145 		{
3146 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
3147 			DE_NULL,													// const void*									pNext;
3148 			0u,															// VkPipelineColorBlendStateCreateFlags			flags;
3149 			false,														// VkBool32										logicOpEnable;
3150 			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
3151 			attachmentCount,											// deUint32										attachmentCount;
3152 			attachments.data(),											// const VkPipelineColorBlendAttachmentState*	pAttachments;
3153 			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
3154 		};
3155 
3156 		const VkStencilOpState stencilOpState =
3157 		{
3158 			VK_STENCIL_OP_KEEP,						// VkStencilOp	failOp;
3159 			VK_STENCIL_OP_REPLACE,					// VkStencilOp	passOp;
3160 			VK_STENCIL_OP_KEEP,						// VkStencilOp	depthFailOp;
3161 			VK_COMPARE_OP_GREATER,					// VkCompareOp	compareOp;
3162 			1u,										// deUint32		compareMask;
3163 			1u,										// deUint32		writeMask;
3164 			1u,										// deUint32		reference;
3165 		};
3166 
3167 		const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
3168 		{
3169 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
3170 			DE_NULL,													// const void*								pNext;
3171 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
3172 			m_useDepth,													// VkBool32									depthTestEnable;
3173 			m_useDepth,													// VkBool32									depthWriteEnable;
3174 			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
3175 			false,														// VkBool32									depthBoundsTestEnable;
3176 			m_useStencil,												// VkBool32									stencilTestEnable;
3177 			stencilOpState,												// VkStencilOpState							front;
3178 			stencilOpState,												// VkStencilOpState							back;
3179 			0.0f,														// float									minDepthBounds;
3180 			1.0f,														// float									maxDepthBounds;
3181 		};
3182 
3183 		const deUint32 numSubpasses = m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY ? 2u : 1u;
3184 
3185 		for (deUint32 subpassIdx = 0; subpassIdx < numSubpasses; subpassIdx++)
3186 			for (deUint32 i = 0u; i < numTopologies; ++i)
3187 			{
3188 				m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(vk,							// const DeviceInterface&                        vk
3189 																									   vkDevice,					// const VkDevice                                device
3190 																									   *m_pipelineLayout,			// const VkPipelineLayout                        pipelineLayout
3191 																									   *m_vertexShaderModule,		// const VkShaderModule                          vertexShaderModule
3192 																									   DE_NULL,						// const VkShaderModule                          tessellationControlModule
3193 																									   DE_NULL,						// const VkShaderModule                          tessellationEvalModule
3194 																									   DE_NULL,						// const VkShaderModule                          geometryShaderModule
3195 																									   *m_fragmentShaderModule,		// const VkShaderModule                          fragmentShaderModule
3196 																									   *m_renderPass,				// const VkRenderPass                            renderPass
3197 																									   viewports,					// const std::vector<VkViewport>&                viewports
3198 																									   scissors,					// const std::vector<VkRect2D>&                  scissors
3199 																									   pTopology[i],				// const VkPrimitiveTopology                     topology
3200 																									   subpassIdx,					// const deUint32                                subpass
3201 																									   0u,							// const deUint32                                patchControlPoints
3202 																									   &vertexInputStateParams,		// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
3203 																									   DE_NULL,						// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
3204 																									   &m_multisampleStateParams,	// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
3205 																									   &depthStencilStateParams,	// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
3206 																									   &colorBlendStateParams))));	// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
3207 			}
3208 	}
3209 
3210 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3211 	{
3212 		// Create pipelines for copying samples to single sampled images
3213 		{
3214 			const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
3215 			{
3216 				VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
3217 				DE_NULL,														// const void*								pNext;
3218 				0u,																// VkPipelineVertexInputStateCreateFlags	flags;
3219 				0u,																// deUint32									vertexBindingDescriptionCount;
3220 				DE_NULL,														// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
3221 				0u,																// deUint32									vertexAttributeDescriptionCount;
3222 				DE_NULL															// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
3223 			};
3224 
3225 			const std::vector<VkViewport>	viewports	(1, makeViewport(m_renderSize));
3226 			const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_renderSize));
3227 
3228 			const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
3229 			{
3230 				VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
3231 				DE_NULL,													// const void*									pNext;
3232 				0u,															// VkPipelineColorBlendStateCreateFlags			flags;
3233 				false,														// VkBool32										logicOpEnable;
3234 				VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
3235 				1u,															// deUint32										attachmentCount;
3236 				&m_colorBlendState,											// const VkPipelineColorBlendAttachmentState*	pAttachments;
3237 				{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
3238 			};
3239 
3240 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3241 			{
3242 				// Pipeline is to be used in subpasses subsequent to sample-shading subpass
3243 				m_copySamplePipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
3244 																										 vkDevice,								// const VkDevice                                device
3245 																										 *m_copySamplePipelineLayout,			// const VkPipelineLayout                        pipelineLayout
3246 																										 *m_copySampleVertexShaderModule,		// const VkShaderModule                          vertexShaderModule
3247 																										 DE_NULL,								// const VkShaderModule                          tessellationControlModule
3248 																										 DE_NULL,								// const VkShaderModule                          tessellationEvalModule
3249 																										 DE_NULL,								// const VkShaderModule                          geometryShaderModule
3250 																										 *m_copySampleFragmentShaderModule,		// const VkShaderModule                          fragmentShaderModule
3251 																										 *m_renderPass,							// const VkRenderPass                            renderPass
3252 																										 viewports,								// const std::vector<VkViewport>&                viewports
3253 																										 scissors,								// const std::vector<VkRect2D>&                  scissors
3254 																										 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// const VkPrimitiveTopology                     topology
3255 																										 1u + (deUint32)i,						// const deUint32                                subpass
3256 																										 0u,									// const deUint32                                patchControlPoints
3257 																										 &vertexInputStateParams,				// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
3258 																										 DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
3259 																										 DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
3260 																										 DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
3261 																										 &colorBlendStateParams))));			// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
3262 			}
3263 		}
3264 
3265 
3266 		const VkDescriptorPoolSize			descriptorPoolSize			=
3267 		{
3268 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,					// VkDescriptorType					type;
3269 			1u														// deUint32							descriptorCount;
3270 		};
3271 
3272 		const VkDescriptorPoolCreateInfo	descriptorPoolCreateInfo	=
3273 		{
3274 			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,			// VkStructureType					sType
3275 			DE_NULL,												// const void*						pNext
3276 			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,		// VkDescriptorPoolCreateFlags		flags
3277 			1u,													// deUint32							maxSets
3278 			1u,														// deUint32							poolSizeCount
3279 			&descriptorPoolSize										// const VkDescriptorPoolSize*		pPoolSizes
3280 		};
3281 
3282 		m_copySampleDesciptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
3283 
3284 		const VkDescriptorSetAllocateInfo	descriptorSetAllocateInfo	=
3285 		{
3286 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,			// VkStructureType					sType
3287 			DE_NULL,												// const void*						pNext
3288 			*m_copySampleDesciptorPool,								// VkDescriptorPool					descriptorPool
3289 			1u,														// deUint32							descriptorSetCount
3290 			&m_copySampleDesciptorLayout.get(),						// const VkDescriptorSetLayout*		pSetLayouts
3291 		};
3292 
3293 		m_copySampleDesciptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
3294 
3295 		const VkDescriptorImageInfo			imageInfo					=
3296 		{
3297 			DE_NULL,
3298 			*m_colorAttachmentView,
3299 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
3300 		};
3301 		const VkWriteDescriptorSet			descriptorWrite				=
3302 		{
3303 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// VkStructureType					sType;
3304 			DE_NULL,										// const void*						pNext;
3305 			*m_copySampleDesciptorSet,						// VkDescriptorSet					dstSet;
3306 			0u,												// deUint32							dstBinding;
3307 			0u,												// deUint32							dstArrayElement;
3308 			1u,												// deUint32							descriptorCount;
3309 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			// VkDescriptorType					descriptorType;
3310 			&imageInfo,										// const VkDescriptorImageInfo*		pImageInfo;
3311 			DE_NULL,										// const VkDescriptorBufferInfo*	pBufferInfo;
3312 			DE_NULL,										// const VkBufferView*				pTexelBufferView;
3313 		};
3314 		vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
3315 	}
3316 
3317 	// Create vertex buffer
3318 	{
3319 		const VkBufferCreateInfo vertexBufferParams =
3320 		{
3321 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
3322 			DE_NULL,									// const void*			pNext;
3323 			0u,											// VkBufferCreateFlags	flags;
3324 			1024u,										// VkDeviceSize			size;
3325 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
3326 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
3327 			1u,											// deUint32				queueFamilyIndexCount;
3328 			&queueFamilyIndices[0]						// const deUint32*		pQueueFamilyIndices;
3329 		};
3330 
3331 		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
3332 		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
3333 
3334 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
3335 
3336 		// Load vertices into vertex buffer
3337 		{
3338 			Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr());
3339 
3340 			if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
3341 			{
3342 				DE_ASSERT(numTopologies == 1);
3343 
3344 				std::vector<Vertex4RGBA> vertices = pVertices[0];
3345 
3346 				// Set alpha to zero for the first draw. This should prevent depth writes because of zero coverage.
3347 				for (size_t i = 0; i < vertices.size(); i++)
3348 					vertices[i].color.w() = 0.0f;
3349 
3350 				deMemcpy(pDst, &vertices[0], vertices.size() * sizeof(Vertex4RGBA));
3351 
3352 				pDst += vertices.size();
3353 
3354 				// The second draw uses original vertices which are pure red.
3355 				deMemcpy(pDst, &pVertices[0][0], pVertices[0].size() * sizeof(Vertex4RGBA));
3356 			}
3357 			else
3358 			{
3359 				for (deUint32 i = 0u; i < numTopologies; ++i)
3360 				{
3361 					deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA));
3362 					pDst += pVertices[i].size();
3363 				}
3364 			}
3365 		}
3366 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
3367 	}
3368 
3369 	// Create command pool
3370 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndices[0]);
3371 
3372 	// Create command buffer
3373 	{
3374 		VkClearValue colorClearValue;
3375 		if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
3376 		{
3377 			colorClearValue.color.float32[0] = 0.25;
3378 			colorClearValue.color.float32[1] = 0.25;
3379 			colorClearValue.color.float32[2] = 0.25;
3380 			colorClearValue.color.float32[3] = 1.0f;
3381 		}
3382 		else
3383 		{
3384 			colorClearValue.color.float32[0] = 0.0f;
3385 			colorClearValue.color.float32[1] = 0.0f;
3386 			colorClearValue.color.float32[2] = 0.0f;
3387 			colorClearValue.color.float32[3] = 0.0f;
3388 		}
3389 
3390 		VkClearValue depthStencilClearValue;
3391 		depthStencilClearValue.depthStencil.depth = m_depthClearValue;
3392 		depthStencilClearValue.depthStencil.stencil = 0u;
3393 
3394 		std::vector<VkClearValue> clearValues;
3395 		clearValues.push_back(colorClearValue);
3396 		if (usesResolveImage)
3397 		{
3398 			clearValues.push_back(colorClearValue);
3399 		}
3400 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3401 		{
3402 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3403 			{
3404 				clearValues.push_back(colorClearValue);
3405 			}
3406 		}
3407 		if (m_useDepth || m_useStencil)
3408 		{
3409 			clearValues.push_back(depthStencilClearValue);
3410 		}
3411 
3412 		vk::VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
3413 		std::vector<VkImageMemoryBarrier> imageLayoutBarriers;
3414 
3415 		{
3416 			const VkImageMemoryBarrier colorImageBarrier =
3417 			// color attachment image
3418 			{
3419 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
3420 				DE_NULL,										// const void*				pNext;
3421 				0u,												// VkAccessFlags			srcAccessMask;
3422 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
3423 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
3424 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
3425 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
3426 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
3427 				*m_colorImage,									// VkImage					image;
3428 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
3429 			};
3430 			imageLayoutBarriers.push_back(colorImageBarrier);
3431 		}
3432 		if (usesResolveImage)
3433 		{
3434 			const VkImageMemoryBarrier resolveImageBarrier =
3435 			// resolve attachment image
3436 			{
3437 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
3438 				DE_NULL,										// const void*				pNext;
3439 				0u,												// VkAccessFlags			srcAccessMask;
3440 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
3441 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
3442 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
3443 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
3444 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
3445 				*m_resolveImage,								// VkImage					image;
3446 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
3447 			};
3448 			imageLayoutBarriers.push_back(resolveImageBarrier);
3449 		}
3450 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3451 		{
3452 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3453 			{
3454 				const VkImageMemoryBarrier perSampleImageBarrier =
3455 				// resolve attachment image
3456 				{
3457 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
3458 					DE_NULL,										// const void*				pNext;
3459 					0u,												// VkAccessFlags			srcAccessMask;
3460 					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
3461 					VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
3462 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
3463 					VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
3464 					VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
3465 					*m_perSampleImages[i]->m_image,					// VkImage					image;
3466 					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
3467 				};
3468 				imageLayoutBarriers.push_back(perSampleImageBarrier);
3469 			}
3470 		}
3471 		if (m_useDepth || m_useStencil)
3472 		{
3473 			const VkImageMemoryBarrier depthStencilImageBarrier =
3474 			// depth/stencil attachment image
3475 			{
3476 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
3477 				DE_NULL,											// const void*				pNext;
3478 				0u,													// VkAccessFlags			srcAccessMask;
3479 				VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
3480 				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
3481 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
3482 				VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
3483 				VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
3484 				*m_depthStencilImage,								// VkImage					image;
3485 				{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
3486 			};
3487 			imageLayoutBarriers.push_back(depthStencilImageBarrier);
3488 			dstStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
3489 		};
3490 
3491 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3492 
3493 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
3494 
3495 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask, (VkDependencyFlags)0,
3496 			0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), &imageLayoutBarriers[0]);
3497 
3498 		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)clearValues.size(), &clearValues[0]);
3499 
3500 		VkDeviceSize vertexBufferOffset = 0u;
3501 
3502 		for (deUint32 i = 0u; i < numTopologies; ++i)
3503 		{
3504 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[i]);
3505 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
3506 			vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0);
3507 
3508 			vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA));
3509 		}
3510 
3511 		if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
3512 		{
3513 			// The first draw was without color buffer and zero coverage. The depth buffer is expected to still have the clear value.
3514 			vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
3515 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[1]);
3516 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
3517 			// The depth test should pass as the first draw didn't touch the depth buffer.
3518 			vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[0].size(), 1, 0, 0);
3519 		}
3520 		else if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3521 		{
3522 			// Copy each sample id to single sampled image
3523 			for (deInt32 sampleId = 0; sampleId < (deInt32)m_perSampleImages.size(); ++sampleId)
3524 			{
3525 				vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
3526 				vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_copySamplePipelines[sampleId]);
3527 				vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_copySamplePipelineLayout, 0u, 1u, &m_copySampleDesciptorSet.get(), 0u, DE_NULL);
3528 				vk.cmdPushConstants(*m_cmdBuffer, *m_copySamplePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &sampleId);
3529 				vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
3530 			}
3531 		}
3532 
3533 		endRenderPass(vk, *m_cmdBuffer);
3534 
3535 		endCommandBuffer(vk, *m_cmdBuffer);
3536 	}
3537 }
3538 
~MultisampleRenderer(void)3539 MultisampleRenderer::~MultisampleRenderer (void)
3540 {
3541 }
3542 
render(void)3543 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void)
3544 {
3545 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
3546 	const VkDevice				vkDevice			= m_context.getDevice();
3547 	const VkQueue				queue				= m_context.getUniversalQueue();
3548 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
3549 
3550 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
3551 
3552 	if (m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
3553 	{
3554 		return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
3555 	}
3556 	else
3557 	{
3558 		return de::MovePtr<tcu::TextureLevel>();
3559 	}
3560 }
3561 
getSingleSampledImage(deUint32 sampleId)3562 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::getSingleSampledImage (deUint32 sampleId)
3563 {
3564 	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>());
3565 }
3566 
3567 // Multisample tests with subpasses using no attachments.
3568 class VariableRateTestCase : public vkt::TestCase
3569 {
3570 public:
3571 	using SampleCounts = std::vector<vk::VkSampleCountFlagBits>;
3572 
3573 	struct PushConstants
3574 	{
3575 		int width;
3576 		int height;
3577 		int samples;
3578 	};
3579 
3580 	struct TestParams
3581 	{
3582 		bool						nonEmptyFramebuffer;	// Empty framebuffer or not.
3583 		vk::VkSampleCountFlagBits	fbCount;				// If not empty, framebuffer sample count.
3584 		bool						unusedAttachment;		// If not empty, create unused attachment or not.
3585 		SampleCounts				subpassCounts;			// Counts for the different subpasses.
3586 	};
3587 
3588 	static const deInt32 kWidth		= 256u;
3589 	static const deInt32 kHeight	= 256u;
3590 
3591 									VariableRateTestCase	(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params);
~VariableRateTestCase(void)3592 	virtual							~VariableRateTestCase	(void) {}
3593 
3594 	virtual void					initPrograms			(vk::SourceCollections& programCollection) const;
3595 	virtual TestInstance*			createInstance			(Context& context) const;
3596 	virtual void					checkSupport			(Context& context) const;
3597 
3598 	static constexpr vk::VkFormat	kColorFormat			= vk::VK_FORMAT_R8G8B8A8_UNORM;
3599 
3600 private:
3601 	TestParams m_params;
3602 };
3603 
3604 class VariableRateTestInstance : public vkt::TestInstance
3605 {
3606 public:
3607 	using TestParams = VariableRateTestCase::TestParams;
3608 
3609 								VariableRateTestInstance	(Context& context, const TestParams& counts);
~VariableRateTestInstance(void)3610 	virtual						~VariableRateTestInstance	(void) {}
3611 
3612 	virtual tcu::TestStatus		iterate						(void);
3613 
3614 private:
3615 	TestParams m_params;
3616 };
3617 
VariableRateTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams & params)3618 VariableRateTestCase::VariableRateTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
3619 	: vkt::TestCase	(testCtx, name, description)
3620 	, m_params		(params)
3621 {
3622 }
3623 
initPrograms(vk::SourceCollections & programCollection) const3624 void VariableRateTestCase::initPrograms (vk::SourceCollections& programCollection) const
3625 {
3626 	std::stringstream vertSrc;
3627 
3628 	vertSrc	<< "#version 450\n"
3629 			<< "\n"
3630 			<< "layout(location=0) in vec2 inPos;\n"
3631 			<< "\n"
3632 			<< "void main() {\n"
3633 			<< "    gl_Position = vec4(inPos, 0.0, 1.0);\n"
3634 			<< "}\n"
3635 			;
3636 
3637 	std::stringstream fragSrc;
3638 
3639 	fragSrc	<< "#version 450\n"
3640 			<< "\n"
3641 			<< "layout(set=0, binding=0, std430) buffer OutBuffer {\n"
3642 			<< "    int coverage[];\n"
3643 			<< "} out_buffer;\n"
3644 			<< "\n"
3645 			<< "layout(push_constant) uniform PushConstants {\n"
3646 			<< "    int width;\n"
3647 			<< "    int height;\n"
3648 			<< "    int samples;\n"
3649 			<< "} push_constants;\n"
3650 			<< "\n"
3651 			<< "void main() {\n"
3652 			<< "   ivec2 coord = ivec2(floor(gl_FragCoord.xy));\n"
3653 			<< "   int pos = ((coord.y * push_constants.width) + coord.x) * push_constants.samples + int(gl_SampleID);\n"
3654 			<< "   out_buffer.coverage[pos] = 1;\n"
3655 			<< "}\n"
3656 			;
3657 
3658 	programCollection.glslSources.add("vert") << glu::VertexSource(vertSrc.str());
3659 	programCollection.glslSources.add("frag") << glu::FragmentSource(fragSrc.str());
3660 }
3661 
createInstance(Context & context) const3662 TestInstance* VariableRateTestCase::createInstance (Context& context) const
3663 {
3664 	return new VariableRateTestInstance(context, m_params);
3665 }
3666 
checkSupport(Context & context) const3667 void VariableRateTestCase::checkSupport (Context& context) const
3668 {
3669 	const auto&	vki				= context.getInstanceInterface();
3670 	const auto	physicalDevice	= context.getPhysicalDevice();
3671 
3672 	// When using multiple subpasses, require variableMultisampleRate.
3673 	if (m_params.subpassCounts.size() > 1)
3674 	{
3675 		if (!vk::getPhysicalDeviceFeatures(vki, physicalDevice).variableMultisampleRate)
3676 			TCU_THROW(NotSupportedError, "Variable multisample rate not supported");
3677 	}
3678 
3679 	// Check if sampleRateShading is supported.
3680 	if(!vk::getPhysicalDeviceFeatures(vki, physicalDevice).sampleRateShading)
3681 		TCU_THROW(NotSupportedError, "Sample rate shading is not supported");
3682 
3683 	// Make sure all subpass sample counts are supported.
3684 	const auto	properties		= vk::getPhysicalDeviceProperties(vki, physicalDevice);
3685 	const auto&	supportedCounts	= properties.limits.framebufferNoAttachmentsSampleCounts;
3686 
3687 	for (const auto count : m_params.subpassCounts)
3688 	{
3689 		if ((supportedCounts & count) == 0u)
3690 			TCU_THROW(NotSupportedError, "Sample count combination not supported");
3691 	}
3692 
3693 	if (m_params.nonEmptyFramebuffer)
3694 	{
3695 		// Check the framebuffer sample count is supported.
3696 		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);
3697 		if ((formatProperties.sampleCounts & m_params.fbCount) == 0u)
3698 			TCU_THROW(NotSupportedError, "Sample count of " + de::toString(m_params.fbCount) + " not supported for color attachment");
3699 	}
3700 }
3701 
zeroOutAndFlush(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::BufferWithMemory & buffer,vk::VkDeviceSize size)3702 void zeroOutAndFlush(const vk::DeviceInterface& vkd, vk::VkDevice device, vk::BufferWithMemory& buffer, vk::VkDeviceSize size)
3703 {
3704 	auto& alloc = buffer.getAllocation();
3705 	deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(size));
3706 	vk::flushAlloc(vkd, device, alloc);
3707 }
3708 
VariableRateTestInstance(Context & context,const TestParams & params)3709 VariableRateTestInstance::VariableRateTestInstance (Context& context, const TestParams& params)
3710 	: vkt::TestInstance	(context)
3711 	, m_params			(params)
3712 {
3713 }
3714 
iterate(void)3715 tcu::TestStatus VariableRateTestInstance::iterate (void)
3716 {
3717 	using PushConstants = VariableRateTestCase::PushConstants;
3718 
3719 	const auto&	vkd			= m_context.getDeviceInterface();
3720 	const auto	device		= m_context.getDevice();
3721 	auto&		allocator	= m_context.getDefaultAllocator();
3722 	const auto&	queue		= m_context.getUniversalQueue();
3723 	const auto	queueIndex	= m_context.getUniversalQueueFamilyIndex();
3724 
3725 	const vk::VkDeviceSize	kWidth			= static_cast<vk::VkDeviceSize>(VariableRateTestCase::kWidth);
3726 	const vk::VkDeviceSize	kHeight			= static_cast<vk::VkDeviceSize>(VariableRateTestCase::kHeight);
3727 	constexpr auto			kColorFormat	= VariableRateTestCase::kColorFormat;
3728 
3729 	const auto kWidth32		= static_cast<deUint32>(kWidth);
3730 	const auto kHeight32	= static_cast<deUint32>(kHeight);
3731 
3732 	std::vector<std::unique_ptr<vk::BufferWithMemory>>	referenceBuffers;
3733 	std::vector<std::unique_ptr<vk::BufferWithMemory>>	outputBuffers;
3734 	std::vector<size_t>									bufferNumElements;
3735 	std::vector<vk::VkDeviceSize>						bufferSizes;
3736 
3737 	// Create reference and output buffers.
3738 	for (const auto count : m_params.subpassCounts)
3739 	{
3740 		bufferNumElements.push_back(static_cast<size_t>(kWidth * kHeight * count));
3741 		bufferSizes.push_back(bufferNumElements.back() * sizeof(deInt32));
3742 		const auto bufferCreateInfo = vk::makeBufferCreateInfo(bufferSizes.back(), vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3743 
3744 		referenceBuffers.emplace_back	(new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible});
3745 		outputBuffers.emplace_back		(new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible});
3746 	}
3747 
3748 	// Descriptor set layout.
3749 	vk::DescriptorSetLayoutBuilder builder;
3750 	builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT);
3751 	const auto descriptorSetLayout = builder.build(vkd, device);
3752 
3753 	// Pipeline layout.
3754 	const vk::VkPushConstantRange pushConstantRange =
3755 	{
3756 		vk::VK_SHADER_STAGE_FRAGMENT_BIT,				//	VkShaderStageFlags	stageFlags;
3757 		0u,												//	deUint32			offset;
3758 		static_cast<deUint32>(sizeof(PushConstants)),	//	deUint32			size;
3759 	};
3760 
3761 	const vk::VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
3762 	{
3763 		vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	//	VkStructureType					sType;
3764 		nullptr,											//	const void*						pNext;
3765 		0u,													//	VkPipelineLayoutCreateFlags		flags;
3766 		1u,													//	deUint32						setLayoutCount;
3767 		&descriptorSetLayout.get(),							//	const VkDescriptorSetLayout*	pSetLayouts;
3768 		1u,													//	deUint32						pushConstantRangeCount;
3769 		&pushConstantRange,									//	const VkPushConstantRange*		pPushConstantRanges;
3770 	};
3771 	const auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
3772 
3773 	// Subpass with no attachments.
3774 	const vk::VkSubpassDescription emptySubpassDescription =
3775 	{
3776 		0u,										//	VkSubpassDescriptionFlags		flags;
3777 		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,	//	VkPipelineBindPoint				pipelineBindPoint;
3778 		0u,										//	deUint32						inputAttachmentCount;
3779 		nullptr,								//	const VkAttachmentReference*	pInputAttachments;
3780 		0u,										//	deUint32						colorAttachmentCount;
3781 		nullptr,								//	const VkAttachmentReference*	pColorAttachments;
3782 		nullptr,								//	const VkAttachmentReference*	pResolveAttachments;
3783 		nullptr,								//	const VkAttachmentReference*	pDepthStencilAttachment;
3784 		0u,										//	deUint32						preserveAttachmentCount;
3785 		nullptr,								//	const deUint32*					pPreserveAttachments;
3786 	};
3787 
3788 	// Unused attachment reference.
3789 	const vk::VkAttachmentReference unusedAttachmentReference =
3790 	{
3791 		VK_ATTACHMENT_UNUSED,							//	deUint32		attachment;
3792 		vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	//	VkImageLayout	layout;
3793 	};
3794 
3795 	// Subpass with unused attachment.
3796 	const vk::VkSubpassDescription unusedAttachmentSubpassDescription =
3797 	{
3798 		0u,										//	VkSubpassDescriptionFlags		flags;
3799 		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,	//	VkPipelineBindPoint				pipelineBindPoint;
3800 		0u,										//	deUint32						inputAttachmentCount;
3801 		nullptr,								//	const VkAttachmentReference*	pInputAttachments;
3802 		1u,										//	deUint32						colorAttachmentCount;
3803 		&unusedAttachmentReference,				//	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 	// Renderpass with multiple subpasses.
3811 	vk::VkRenderPassCreateInfo renderPassCreateInfo =
3812 	{
3813 		vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	//	VkStructureType					sType;
3814 		nullptr,										//	const void*						pNext;
3815 		0u,												//	VkRenderPassCreateFlags			flags;
3816 		0u,												//	deUint32						attachmentCount;
3817 		nullptr,										//	const VkAttachmentDescription*	pAttachments;
3818 		0u,												//	deUint32						subpassCount;
3819 		nullptr,										//	const VkSubpassDescription*		pSubpasses;
3820 		0u,												//	deUint32						dependencyCount;
3821 		nullptr,										//	const VkSubpassDependency*		pDependencies;
3822 	};
3823 
3824 	std::vector<vk::VkSubpassDescription> subpassesVector;
3825 
3826 	for (size_t i = 0; i < m_params.subpassCounts.size(); ++i)
3827 		subpassesVector.push_back(emptySubpassDescription);
3828 	renderPassCreateInfo.subpassCount	= static_cast<deUint32>(subpassesVector.size());
3829 	renderPassCreateInfo.pSubpasses		= subpassesVector.data();
3830 	const auto renderPassMultiplePasses = vk::createRenderPass(vkd, device, &renderPassCreateInfo);
3831 
3832 	// Render pass with single subpass.
3833 	const vk::VkAttachmentDescription colorAttachmentDescription =
3834 	{
3835 		0u,												//	VkAttachmentDescriptionFlags	flags;
3836 		kColorFormat,									//	VkFormat						format;
3837 		m_params.fbCount,								//	VkSampleCountFlagBits			samples;
3838 		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,			//	VkAttachmentLoadOp				loadOp;
3839 		vk::VK_ATTACHMENT_STORE_OP_STORE,				//	VkAttachmentStoreOp				storeOp;
3840 		vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,			//	VkAttachmentLoadOp				stencilLoadOp;
3841 		vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,			//	VkAttachmentStoreOp				stencilStoreOp;
3842 		vk::VK_IMAGE_LAYOUT_UNDEFINED,					//	VkImageLayout					initialLayout;
3843 		vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	//	VkImageLayout					finalLayout;
3844 	};
3845 
3846 	if (m_params.nonEmptyFramebuffer)
3847 	{
3848 		renderPassCreateInfo.attachmentCount = 1u;
3849 		renderPassCreateInfo.pAttachments = &colorAttachmentDescription;
3850 	}
3851 	renderPassCreateInfo.subpassCount	= 1u;
3852 	renderPassCreateInfo.pSubpasses		= ((m_params.nonEmptyFramebuffer && m_params.unusedAttachment) ? &unusedAttachmentSubpassDescription : &emptySubpassDescription);
3853 	const auto renderPassSingleSubpass	= vk::createRenderPass(vkd, device, &renderPassCreateInfo);
3854 
3855 	// Framebuffers.
3856 	vk::VkFramebufferCreateInfo framebufferCreateInfo =
3857 	{
3858 		vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	//	VkStructureType				sType;
3859 		nullptr,										//	const void*					pNext;
3860 		0u,												//	VkFramebufferCreateFlags	flags;
3861 		DE_NULL,										//	VkRenderPass				renderPass;
3862 		0u,												//	deUint32					attachmentCount;
3863 		nullptr,										//	const VkImageView*			pAttachments;
3864 		kWidth32,										//	deUint32					width;
3865 		kHeight32,										//	deUint32					height;
3866 		1u,												//	deUint32					layers;
3867 	};
3868 
3869 	// Framebuffer for multiple-subpasses render pass.
3870 	framebufferCreateInfo.renderPass		= renderPassMultiplePasses.get();
3871 	const auto framebufferMultiplePasses	= vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3872 
3873 	// Framebuffer for single-subpass render pass.
3874 	std::unique_ptr<vk::ImageWithMemory>	imagePtr;
3875 	vk::Move<vk::VkImageView>				imageView;
3876 
3877 	if (m_params.nonEmptyFramebuffer)
3878 	{
3879 		const vk::VkImageCreateInfo imageCreateInfo =
3880 		{
3881 			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
3882 			nullptr,									//	const void*				pNext;
3883 			0u,											//	VkImageCreateFlags		flags;
3884 			vk::VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
3885 			kColorFormat,								//	VkFormat				format;
3886 			vk::makeExtent3D(kWidth32, kHeight32, 1u),	//	VkExtent3D				extent;
3887 			1u,											//	deUint32				mipLevels;
3888 			1u,											//	deUint32				arrayLayers;
3889 			m_params.fbCount,							//	VkSampleCountFlagBits	samples;
3890 			vk::VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
3891 			vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,	//	VkImageUsageFlags		usage;
3892 			vk::VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
3893 			0u,											//	deUint32				queueFamilyIndexCount;
3894 			nullptr,									//	const deUint32*			pQueueFamilyIndices;
3895 			vk::VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
3896 		};
3897 		imagePtr.reset(new vk::ImageWithMemory{vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any});
3898 
3899 		const auto subresourceRange	= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
3900 		imageView					= vk::makeImageView(vkd, device, imagePtr->get(), vk::VK_IMAGE_VIEW_TYPE_2D, kColorFormat, subresourceRange);
3901 
3902 		framebufferCreateInfo.attachmentCount	= 1u;
3903 		framebufferCreateInfo.pAttachments		= &imageView.get();
3904 	}
3905 	framebufferCreateInfo.renderPass	= renderPassSingleSubpass.get();
3906 	const auto framebufferSingleSubpass	= vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3907 
3908 	// Shader modules and stages.
3909 	const auto vertModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
3910 	const auto fragModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
3911 
3912 	std::vector<vk::VkPipelineShaderStageCreateInfo> shaderStages;
3913 
3914 	vk::VkPipelineShaderStageCreateInfo shaderStageCreateInfo =
3915 	{
3916 		vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	//	VkStructureType						sType;
3917 		nullptr,													//	const void*							pNext;
3918 		0u,															//	VkPipelineShaderStageCreateFlags	flags;
3919 		vk::VK_SHADER_STAGE_VERTEX_BIT,								//	VkShaderStageFlagBits				stage;
3920 		vertModule.get(),											//	VkShaderModule						module;
3921 		"main",														//	const char*							pName;
3922 		nullptr,													//	const VkSpecializationInfo*			pSpecializationInfo;
3923 	};
3924 
3925 	shaderStages.push_back(shaderStageCreateInfo);
3926 	shaderStageCreateInfo.stage		= vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3927 	shaderStageCreateInfo.module	= fragModule.get();
3928 	shaderStages.push_back(shaderStageCreateInfo);
3929 
3930 	// Vertices, input state and assembly.
3931 	const std::vector<tcu::Vec2> vertices =
3932 	{
3933 		{ -0.987f, -0.964f },
3934 		{  0.982f, -0.977f },
3935 		{  0.005f,  0.891f },
3936 	};
3937 
3938 	const auto vertexBinding	= vk::makeVertexInputBindingDescription(0u, static_cast<deUint32>(sizeof(decltype(vertices)::value_type)), vk::VK_VERTEX_INPUT_RATE_VERTEX);
3939 	const auto vertexAttribute	= vk::makeVertexInputAttributeDescription(0u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, 0u);
3940 
3941 	const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
3942 	{
3943 		vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	//	VkStructureType								sType;
3944 		nullptr,														//	const void*									pNext;
3945 		0u,																//	VkPipelineVertexInputStateCreateFlags		flags;
3946 		1u,																//	deUint32									vertexBindingDescriptionCount;
3947 		&vertexBinding,													//	const VkVertexInputBindingDescription*		pVertexBindingDescriptions;
3948 		1u,																//	deUint32									vertexAttributeDescriptionCount;
3949 		&vertexAttribute,												//	const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
3950 	};
3951 
3952 	const vk::VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
3953 	{
3954 		vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	//	VkStructureType							sType;
3955 		nullptr,															//	const void*								pNext;
3956 		0u,																	//	VkPipelineInputAssemblyStateCreateFlags	flags;
3957 		vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							//	VkPrimitiveTopology						topology;
3958 		VK_FALSE,															//	VkBool32								primitiveRestartEnable;
3959 	};
3960 
3961 	// Graphics pipelines to create output buffers.
3962 	const auto viewport	= vk::makeViewport(kWidth32, kHeight32);
3963 	const auto scissor	= vk::makeRect2D(kWidth32, kHeight32);
3964 
3965 	const vk::VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
3966 	{
3967 		vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	//	VkStructureType						sType;
3968 		nullptr,													//	const void*							pNext;
3969 		0u,															//	VkPipelineViewportStateCreateFlags	flags;
3970 		1u,															//	deUint32							viewportCount;
3971 		&viewport,													//	const VkViewport*					pViewports;
3972 		1u,															//	deUint32							scissorCount;
3973 		&scissor,													//	const VkRect2D*						pScissors;
3974 	};
3975 
3976 	const vk::VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
3977 	{
3978 		vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	//	VkStructureType							sType;
3979 		nullptr,														//	const void*								pNext;
3980 		0u,																//	VkPipelineRasterizationStateCreateFlags	flags;
3981 		VK_FALSE,														//	VkBool32								depthClampEnable;
3982 		VK_FALSE,														//	VkBool32								rasterizerDiscardEnable;
3983 		vk::VK_POLYGON_MODE_FILL,										//	VkPolygonMode							polygonMode;
3984 		vk::VK_CULL_MODE_NONE,											//	VkCullModeFlags							cullMode;
3985 		vk::VK_FRONT_FACE_CLOCKWISE,									//	VkFrontFace								frontFace;
3986 		VK_FALSE,														//	VkBool32								depthBiasEnable;
3987 		0.0f,															//	float									depthBiasConstantFactor;
3988 		0.0f,															//	float									depthBiasClamp;
3989 		0.0f,															//	float									depthBiasSlopeFactor;
3990 		1.0f,															//	float									lineWidth;
3991 	};
3992 
3993 	vk::VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
3994 	{
3995 		vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	//	VkStructureType							sType;
3996 		nullptr,														//	const void*								pNext;
3997 		0u,																//	VkPipelineMultisampleStateCreateFlags	flags;
3998 		vk::VK_SAMPLE_COUNT_1_BIT,										//	VkSampleCountFlagBits					rasterizationSamples;
3999 		VK_FALSE,														//	VkBool32								sampleShadingEnable;
4000 		0.0f,															//	float									minSampleShading;
4001 		nullptr,														//	const VkSampleMask*						pSampleMask;
4002 		VK_FALSE,														//	VkBool32								alphaToCoverageEnable;
4003 		VK_FALSE,														//	VkBool32								alphaToOneEnable;
4004 	};
4005 
4006 	std::vector<vk::Move<vk::VkPipeline>> outputPipelines;
4007 
4008 	for (const auto samples : m_params.subpassCounts)
4009 	{
4010 		multisampleStateCreateInfo.rasterizationSamples = samples;
4011 
4012 		const vk::VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
4013 		{
4014 			vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	//	VkStructureType									sType;
4015 			nullptr,												//	const void*										pNext;
4016 			0u,														//	VkPipelineCreateFlags							flags;
4017 			static_cast<deUint32>(shaderStages.size()),				//	deUint32										stageCount;
4018 			shaderStages.data(),									//	const VkPipelineShaderStageCreateInfo*			pStages;
4019 			&vertexInputStateCreateInfo,							//	const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
4020 			&inputAssemblyStateCreateInfo,							//	const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
4021 			nullptr,												//	const VkPipelineTessellationStateCreateInfo*	pTessellationState;
4022 			&viewportStateCreateInfo,								//	const VkPipelineViewportStateCreateInfo*		pViewportState;
4023 			&rasterizationStateCreateInfo,							//	const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
4024 			&multisampleStateCreateInfo,							//	const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
4025 			nullptr,												//	const VkPipelineDepthStencilStateCreateInfo*	pDepthStencilState;
4026 			nullptr,												//	const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
4027 			nullptr,												//	const VkPipelineDynamicStateCreateInfo*			pDynamicState;
4028 			pipelineLayout.get(),									//	VkPipelineLayout								layout;
4029 			renderPassSingleSubpass.get(),							//	VkRenderPass									renderPass;
4030 			0u,														//	deUint32										subpass;
4031 			DE_NULL,												//	VkPipeline										basePipelineHandle;
4032 			0,														//	deInt32											basePipelineIndex;
4033 		};
4034 
4035 		outputPipelines.push_back(vk::createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo));
4036 	}
4037 
4038 	// Graphics pipelines with variable rate but using several subpasses.
4039 	std::vector<vk::Move<vk::VkPipeline>> referencePipelines;
4040 
4041 	for (size_t i = 0; i < m_params.subpassCounts.size(); ++i)
4042 	{
4043 		multisampleStateCreateInfo.rasterizationSamples = m_params.subpassCounts[i];
4044 
4045 		const vk::VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
4046 		{
4047 			vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	//	VkStructureType									sType;
4048 			nullptr,												//	const void*										pNext;
4049 			0u,														//	VkPipelineCreateFlags							flags;
4050 			static_cast<deUint32>(shaderStages.size()),				//	deUint32										stageCount;
4051 			shaderStages.data(),									//	const VkPipelineShaderStageCreateInfo*			pStages;
4052 			&vertexInputStateCreateInfo,							//	const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
4053 			&inputAssemblyStateCreateInfo,							//	const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
4054 			nullptr,												//	const VkPipelineTessellationStateCreateInfo*	pTessellationState;
4055 			&viewportStateCreateInfo,								//	const VkPipelineViewportStateCreateInfo*		pViewportState;
4056 			&rasterizationStateCreateInfo,							//	const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
4057 			&multisampleStateCreateInfo,							//	const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
4058 			nullptr,												//	const VkPipelineDepthStencilStateCreateInfo*	pDepthStencilState;
4059 			nullptr,												//	const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
4060 			nullptr,												//	const VkPipelineDynamicStateCreateInfo*			pDynamicState;
4061 			pipelineLayout.get(),									//	VkPipelineLayout								layout;
4062 			renderPassMultiplePasses.get(),							//	VkRenderPass									renderPass;
4063 			static_cast<deUint32>(i),								//	deUint32										subpass;
4064 			DE_NULL,												//	VkPipeline										basePipelineHandle;
4065 			0,														//	deInt32											basePipelineIndex;
4066 		};
4067 
4068 		referencePipelines.push_back(vk::createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo));
4069 	}
4070 
4071 	// Prepare vertex, reference and output buffers.
4072 	const auto				vertexBufferSize		= vertices.size() * sizeof(decltype(vertices)::value_type);
4073 	const auto				vertexBufferCreateInfo	= vk::makeBufferCreateInfo(static_cast<VkDeviceSize>(vertexBufferSize), vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
4074 	vk::BufferWithMemory	vertexBuffer			{vkd, device, allocator, vertexBufferCreateInfo, MemoryRequirement::HostVisible};
4075 	auto&					vertexAlloc				= vertexBuffer.getAllocation();
4076 
4077 	deMemcpy(vertexAlloc.getHostPtr(), vertices.data(), vertexBufferSize);
4078 	vk::flushAlloc(vkd, device, vertexAlloc);
4079 
4080 	for (size_t i = 0; i < referenceBuffers.size(); ++i)
4081 	{
4082 		zeroOutAndFlush(vkd, device, *referenceBuffers[i], bufferSizes[i]);
4083 		zeroOutAndFlush(vkd, device, *outputBuffers[i], bufferSizes[i]);
4084 	}
4085 
4086 	// Prepare descriptor sets.
4087 	const deUint32				totalSets		= static_cast<deUint32>(referenceBuffers.size() * 2u);
4088 	vk::DescriptorPoolBuilder	poolBuilder;
4089 	poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, static_cast<deUint32>(referenceBuffers.size() * 2u));
4090 	const auto descriptorPool = poolBuilder.build(vkd, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, totalSets);
4091 
4092 	std::vector<vk::Move<vk::VkDescriptorSet>> referenceSets	(referenceBuffers.size());
4093 	std::vector<vk::Move<vk::VkDescriptorSet>> outputSets		(outputBuffers.size());
4094 
4095 	for (auto& set : referenceSets)
4096 		set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
4097 	for (auto& set : outputSets)
4098 		set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
4099 
4100 	vk::DescriptorSetUpdateBuilder updateBuilder;
4101 
4102 	for (size_t i = 0; i < referenceSets.size(); ++i)
4103 	{
4104 		const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(referenceBuffers[i]->get(), 0u, bufferSizes[i]);
4105 		updateBuilder.writeSingle(referenceSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
4106 	}
4107 	for (size_t i = 0; i < outputSets.size(); ++i)
4108 	{
4109 		const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(outputBuffers[i]->get(), 0u, bufferSizes[i]);
4110 		updateBuilder.writeSingle(outputSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
4111 	}
4112 
4113 	updateBuilder.update(vkd, device);
4114 
4115 	// Prepare command pool.
4116 	const auto cmdPool		= vk::makeCommandPool(vkd, device, queueIndex);
4117 	const auto cmdBufferPtr	= vk::allocateCommandBuffer(vkd , device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4118 	const auto cmdBuffer	= cmdBufferPtr.get();
4119 
4120 	vk::VkBufferMemoryBarrier storageBufferDevToHostBarrier =
4121 	{
4122 		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//	VkStructureType	sType;
4123 		nullptr,										//	const void*		pNext;
4124 		vk::VK_ACCESS_SHADER_WRITE_BIT,					//	VkAccessFlags	srcAccessMask;
4125 		vk::VK_ACCESS_HOST_READ_BIT,					//	VkAccessFlags	dstAccessMask;
4126 		VK_QUEUE_FAMILY_IGNORED,						//	deUint32		srcQueueFamilyIndex;
4127 		VK_QUEUE_FAMILY_IGNORED,						//	deUint32		dstQueueFamilyIndex;
4128 		DE_NULL,										//	VkBuffer		buffer;
4129 		0u,												//	VkDeviceSize	offset;
4130 		VK_WHOLE_SIZE,									//	VkDeviceSize	size;
4131 	};
4132 
4133 	// Record command buffer.
4134 	const vk::VkDeviceSize	vertexBufferOffset	= 0u;
4135 	const auto				renderArea			= vk::makeRect2D(kWidth32, kHeight32);
4136 	PushConstants			pushConstants		= { static_cast<int>(kWidth), static_cast<int>(kHeight), 0 };
4137 
4138 	vk::beginCommandBuffer(vkd, cmdBuffer);
4139 
4140 	// Render output buffers.
4141 	vk::beginRenderPass(vkd, cmdBuffer, renderPassSingleSubpass.get(), framebufferSingleSubpass.get(), renderArea);
4142 	for (size_t i = 0; i < outputBuffers.size(); ++i)
4143 	{
4144 		vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, outputPipelines[i].get());
4145 		vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &outputSets[i].get(), 0u, nullptr);
4146 		vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
4147 		pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]);
4148 		vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants);
4149 		vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u);
4150 	}
4151 	vk::endRenderPass(vkd, cmdBuffer);
4152 	for (size_t i = 0; i < outputBuffers.size(); ++i)
4153 	{
4154 		storageBufferDevToHostBarrier.buffer = outputBuffers[i]->get();
4155 		vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr);
4156 	}
4157 
4158 	// Render reference buffers.
4159 	vk::beginRenderPass(vkd, cmdBuffer, renderPassMultiplePasses.get(), framebufferMultiplePasses.get(), renderArea);
4160 	for (size_t i = 0; i < referenceBuffers.size(); ++i)
4161 	{
4162 		if (i > 0)
4163 			vkd.cmdNextSubpass(cmdBuffer, vk::VK_SUBPASS_CONTENTS_INLINE);
4164 		vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, referencePipelines[i].get());
4165 		vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &referenceSets[i].get(), 0u, nullptr);
4166 		vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
4167 		pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]);
4168 		vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants);
4169 		vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u);
4170 	}
4171 	vk::endRenderPass(vkd, cmdBuffer);
4172 	for (size_t i = 0; i < referenceBuffers.size(); ++i)
4173 	{
4174 		storageBufferDevToHostBarrier.buffer = referenceBuffers[i]->get();
4175 		vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr);
4176 	}
4177 
4178 	vk::endCommandBuffer(vkd, cmdBuffer);
4179 
4180 	// Run all pipelines.
4181 	vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
4182 
4183 	// Invalidate reference allocs.
4184 #undef LOG_BUFFER_CONTENTS
4185 #ifdef LOG_BUFFER_CONTENTS
4186 	auto& log = m_context.getTestContext().getLog();
4187 #endif
4188 	for (size_t i = 0; i < referenceBuffers.size(); ++i)
4189 	{
4190 		auto& buffer	= referenceBuffers[i];
4191 		auto& alloc		= buffer->getAllocation();
4192 		vk::invalidateAlloc(vkd, device, alloc);
4193 
4194 #ifdef LOG_BUFFER_CONTENTS
4195 		std::vector<deInt32> bufferValues(bufferNumElements[i]);
4196 		deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]);
4197 
4198 		std::ostringstream msg;
4199 		for (const auto value : bufferValues)
4200 			msg << " " << value;
4201 		log << tcu::TestLog::Message << "Reference buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage;
4202 #endif
4203 	}
4204 
4205 	for (size_t i = 0; i < outputBuffers.size(); ++i)
4206 	{
4207 		auto& buffer	= outputBuffers[i];
4208 		auto& alloc		= buffer->getAllocation();
4209 		vk::invalidateAlloc(vkd, device, alloc);
4210 
4211 #ifdef LOG_BUFFER_CONTENTS
4212 		std::vector<deInt32> bufferValues(bufferNumElements[i]);
4213 		deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]);
4214 
4215 		std::ostringstream msg;
4216 		for (const auto value : bufferValues)
4217 			msg << " " << value;
4218 		log << tcu::TestLog::Message << "Output buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage;
4219 #endif
4220 
4221 		if (deMemCmp(alloc.getHostPtr(), referenceBuffers[i]->getAllocation().getHostPtr(), static_cast<size_t>(bufferSizes[i])) != 0)
4222 			return tcu::TestStatus::fail("Buffer mismatch in output buffer " + de::toString(i));
4223 	}
4224 
4225 	return tcu::TestStatus::pass("Pass");
4226 }
4227 
4228 using ElementsVector	= std::vector<vk::VkSampleCountFlagBits>;
4229 using CombinationVector	= std::vector<ElementsVector>;
4230 
combinationsRecursive(const ElementsVector & elements,size_t requestedSize,CombinationVector & solutions,ElementsVector & partial)4231 void combinationsRecursive(const ElementsVector& elements, size_t requestedSize, CombinationVector& solutions, ElementsVector& partial)
4232 {
4233 	if (partial.size() == requestedSize)
4234 		solutions.push_back(partial);
4235 	else
4236 	{
4237 		for (const auto& elem : elements)
4238 		{
4239 			partial.push_back(elem);
4240 			combinationsRecursive(elements, requestedSize, solutions, partial);
4241 			partial.pop_back();
4242 		}
4243 	}
4244 }
4245 
combinations(const ElementsVector & elements,size_t requestedSize)4246 CombinationVector combinations(const ElementsVector& elements, size_t requestedSize)
4247 {
4248 	CombinationVector solutions;
4249 	ElementsVector partial;
4250 
4251 	combinationsRecursive(elements, requestedSize, solutions, partial);
4252 	return solutions;
4253 }
4254 
4255 } // anonymous
4256 
createMultisampleTests(tcu::TestContext & testCtx)4257 tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx)
4258 {
4259 	const VkSampleCountFlagBits samples[] =
4260 	{
4261 		VK_SAMPLE_COUNT_2_BIT,
4262 		VK_SAMPLE_COUNT_4_BIT,
4263 		VK_SAMPLE_COUNT_8_BIT,
4264 		VK_SAMPLE_COUNT_16_BIT,
4265 		VK_SAMPLE_COUNT_32_BIT,
4266 		VK_SAMPLE_COUNT_64_BIT
4267 	};
4268 
4269 	de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, "multisample", ""));
4270 
4271 	// Rasterization samples tests
4272 	{
4273 		de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", ""));
4274 
4275 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4276 		{
4277 			std::ostringstream caseName;
4278 			caseName << "samples_" << samples[samplesNdx];
4279 
4280 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4281 
4282 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4283 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4284 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4285 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
4286 
4287 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT));
4288 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_STENCIL_BIT));
4289 			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));
4290 
4291 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle_sparse", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4292 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line_sparse", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4293 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px_sparse", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4294 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_sparse", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
4295 
4296 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_sparse", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT));
4297 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil_sparse", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_STENCIL_BIT));
4298 			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));
4299 
4300 			rasterizationSamplesTests->addChild(samplesTests.release());
4301 		}
4302 
4303 		multisampleTests->addChild(rasterizationSamplesTests.release());
4304 	}
4305 
4306 	// Raster samples consistency check
4307 	{
4308 		de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests	(new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", ""));
4309 		MultisampleTestParams			paramsRegular					= {GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR};
4310 		MultisampleTestParams			paramsSparse					= {GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE};
4311 
4312 		addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
4313 									"unique_colors_check",
4314 									"",
4315 									initMultisamplePrograms,
4316 									testRasterSamplesConsistency,
4317 									paramsRegular);
4318 
4319 		addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
4320 									"unique_colors_check_sparse",
4321 									"",
4322 									initMultisamplePrograms,
4323 									testRasterSamplesConsistency,
4324 									paramsSparse);
4325 
4326 		multisampleTests->addChild(rasterSamplesConsistencyTests.release());
4327 	}
4328 
4329 	// minSampleShading tests
4330 	{
4331 		struct TestConfig
4332 		{
4333 			const char*	name;
4334 			float		minSampleShading;
4335 		};
4336 
4337 		const TestConfig testConfigs[] =
4338 		{
4339 			{ "min_0_0",	0.0f },
4340 			{ "min_0_25",	0.25f },
4341 			{ "min_0_5",	0.5f },
4342 			{ "min_0_75",	0.75f },
4343 			{ "min_1_0",	1.0f }
4344 		};
4345 
4346 		{
4347 			de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", ""));
4348 
4349 			for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4350 			{
4351 				const TestConfig&				testConfig				= testConfigs[configNdx];
4352 				de::MovePtr<tcu::TestCaseGroup>	minShadingValueTests	(new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
4353 
4354 				for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4355 				{
4356 					std::ostringstream caseName;
4357 					caseName << "samples_" << samples[samplesNdx];
4358 
4359 					de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4360 
4361 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4362 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line",		"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4363 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4364 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point",		"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
4365 
4366 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle_sparse",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4367 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line_sparse",		"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4368 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px_sparse",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4369 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_sparse",		"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
4370 
4371 					minShadingValueTests->addChild(samplesTests.release());
4372 				}
4373 
4374 				minSampleShadingTests->addChild(minShadingValueTests.release());
4375 			}
4376 
4377 			multisampleTests->addChild(minSampleShadingTests.release());
4378 		}
4379 
4380 		{
4381 			de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_enabled", ""));
4382 
4383 			for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4384 			{
4385 				const TestConfig&				testConfig				= testConfigs[configNdx];
4386 				de::MovePtr<tcu::TestCaseGroup>	minShadingValueTests	(new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
4387 
4388 				for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4389 				{
4390 					std::ostringstream caseName;
4391 					caseName << "samples_" << samples[samplesNdx];
4392 
4393 					de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4394 
4395 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, true));
4396 
4397 					minShadingValueTests->addChild(samplesTests.release());
4398 				}
4399 
4400 				minSampleShadingTests->addChild(minShadingValueTests.release());
4401 			}
4402 
4403 			multisampleTests->addChild(minSampleShadingTests.release());
4404 		}
4405 
4406 		{
4407 			de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_disabled", ""));
4408 
4409 			for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4410 			{
4411 				const TestConfig&				testConfig				= testConfigs[configNdx];
4412 				de::MovePtr<tcu::TestCaseGroup>	minShadingValueTests	(new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
4413 
4414 				for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4415 				{
4416 					std::ostringstream caseName;
4417 					caseName << "samples_" << samples[samplesNdx];
4418 
4419 					de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4420 
4421 					samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad",	"", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, false));
4422 
4423 					minShadingValueTests->addChild(samplesTests.release());
4424 				}
4425 
4426 				minSampleShadingTests->addChild(minShadingValueTests.release());
4427 			}
4428 
4429 			multisampleTests->addChild(minSampleShadingTests.release());
4430 		}
4431 	}
4432 
4433 	// SampleMask tests
4434 	{
4435 		struct TestConfig
4436 		{
4437 			const char*		name;
4438 			const char*		description;
4439 			VkSampleMask	sampleMask;
4440 		};
4441 
4442 		const TestConfig testConfigs[] =
4443 		{
4444 			{ "mask_all_on",	"All mask bits are off",			0x0 },
4445 			{ "mask_all_off",	"All mask bits are on",				0xFFFFFFFF },
4446 			{ "mask_one",		"All mask elements are 0x1",		0x1},
4447 			{ "mask_random",	"All mask elements are 0xAAAAAAAA",	0xAAAAAAAA },
4448 		};
4449 
4450 		de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", ""));
4451 
4452 		for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4453 		{
4454 			const TestConfig&				testConfig				= testConfigs[configNdx];
4455 			de::MovePtr<tcu::TestCaseGroup>	sampleMaskValueTests	(new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description));
4456 
4457 			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4458 			{
4459 				std::ostringstream caseName;
4460 				caseName << "samples_" << samples[samplesNdx];
4461 
4462 				const deUint32					sampleMaskCount	= samples[samplesNdx] / 32;
4463 				de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4464 
4465 				std::vector<VkSampleMask> mask;
4466 				for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++)
4467 					mask.push_back(testConfig.sampleMask);
4468 
4469 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4470 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4471 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4472 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
4473 
4474 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4475 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4476 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4477 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
4478 
4479 				sampleMaskValueTests->addChild(samplesTests.release());
4480 			}
4481 
4482 			sampleMaskTests->addChild(sampleMaskValueTests.release());
4483 		}
4484 
4485 		multisampleTests->addChild(sampleMaskTests.release());
4486 
4487 	}
4488 
4489 	// AlphaToOne tests
4490 	{
4491 		de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", ""));
4492 
4493 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4494 		{
4495 			std::ostringstream caseName;
4496 			caseName << "samples_" << samples[samplesNdx];
4497 
4498 			alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx], IMAGE_BACKING_MODE_REGULAR));
4499 
4500 			caseName << "_sparse";
4501 			alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx], IMAGE_BACKING_MODE_SPARSE));
4502 		}
4503 
4504 		multisampleTests->addChild(alphaToOneTests.release());
4505 	}
4506 
4507 	// AlphaToCoverageEnable tests
4508 	{
4509 		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", ""));
4510 
4511 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4512 		{
4513 			std::ostringstream caseName;
4514 			caseName << "samples_" << samples[samplesNdx];
4515 
4516 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4517 
4518 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4519 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_REGULAR));
4520 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4521 
4522 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4523 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_SPARSE));
4524 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4525 
4526 			alphaToCoverageTests->addChild(samplesTests.release());
4527 		}
4528 		multisampleTests->addChild(alphaToCoverageTests.release());
4529 	}
4530 
4531 	// AlphaToCoverageEnable without color buffer tests
4532 	{
4533 		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageNoColorAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_no_color_attachment", ""));
4534 
4535 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4536 		{
4537 			std::ostringstream caseName;
4538 			caseName << "samples_" << samples[samplesNdx];
4539 
4540 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4541 
4542 			samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4543 			samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4544 
4545 			alphaToCoverageNoColorAttachmentTests->addChild(samplesTests.release());
4546 		}
4547 		multisampleTests->addChild(alphaToCoverageNoColorAttachmentTests.release());
4548 	}
4549 
4550 	// AlphaToCoverageEnable with unused color attachment:
4551 	// Set color output at location 0 as unused, but use the alpha write to control coverage for rendering to color buffer at location 1.
4552 	{
4553 		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageColorUnusedAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_unused_attachment", ""));
4554 
4555 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4556 		{
4557 			std::ostringstream caseName;
4558 			caseName << "samples_" << samples[samplesNdx];
4559 
4560 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4561 
4562 			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4563 			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4564 			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4565 			samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4566 
4567 			alphaToCoverageColorUnusedAttachmentTests->addChild(samplesTests.release());
4568 		}
4569 		multisampleTests->addChild(alphaToCoverageColorUnusedAttachmentTests.release());
4570 	}
4571 
4572 	// Sampling from a multisampled image texture (texelFetch)
4573 	{
4574 		multisampleTests->addChild(createMultisampleSampledImageTests(testCtx));
4575 	}
4576 
4577 	// Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.)
4578 	{
4579 		multisampleTests->addChild(createMultisampleStorageImageTests(testCtx));
4580 	}
4581 
4582 	// VK_EXT_sample_locations
4583 	{
4584 		multisampleTests->addChild(createMultisampleSampleLocationsExtTests(testCtx));
4585 	}
4586 
4587 	// VK_AMD_mixed_attachment samples and VK_AMD_shader_fragment_mask
4588 	{
4589 		multisampleTests->addChild(createMultisampleMixedAttachmentSamplesTests(testCtx));
4590 		multisampleTests->addChild(createMultisampleShaderFragmentMaskTests(testCtx));
4591 	}
4592 
4593 	// Sample mask with and without vk_ext_post_depth_coverage
4594 	{
4595 		const vk::VkSampleCountFlagBits standardSamplesSet[] =
4596 		{
4597 			vk::VK_SAMPLE_COUNT_2_BIT,
4598 			vk::VK_SAMPLE_COUNT_4_BIT,
4599 			vk::VK_SAMPLE_COUNT_8_BIT,
4600 			vk::VK_SAMPLE_COUNT_16_BIT
4601 		};
4602 
4603 		de::MovePtr<tcu::TestCaseGroup> sampleMaskWithDepthTestGroup(new tcu::TestCaseGroup(testCtx, "sample_mask_with_depth_test", ""));
4604 
4605 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(standardSamplesSet); ++ndx)
4606 		{
4607 			std::ostringstream caseName;
4608 			caseName << "samples_" << standardSamplesSet[ndx];
4609 
4610 			sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", standardSamplesSet[ndx]));
4611 
4612 			caseName << "_post_depth_coverage";
4613 			sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", standardSamplesSet[ndx], true));
4614 
4615 		}
4616 		multisampleTests->addChild(sampleMaskWithDepthTestGroup.release());
4617 	}
4618 
4619 	{
4620 		static const std::vector<vk::VkSampleCountFlagBits> kSampleCounts =
4621 		{
4622 			vk::VK_SAMPLE_COUNT_1_BIT,
4623 			vk::VK_SAMPLE_COUNT_2_BIT,
4624 			vk::VK_SAMPLE_COUNT_4_BIT,
4625 			vk::VK_SAMPLE_COUNT_8_BIT,
4626 			vk::VK_SAMPLE_COUNT_16_BIT,
4627 			vk::VK_SAMPLE_COUNT_32_BIT,
4628 			vk::VK_SAMPLE_COUNT_64_BIT,
4629 		};
4630 
4631 		static const std::array<bool, 2> unusedAttachmentFlag = {{ false, true }};
4632 
4633 		{
4634 			de::MovePtr<tcu::TestCaseGroup> variableRateGroup(new tcu::TestCaseGroup(testCtx, "variable_rate", "Tests for multisample variable rate in subpasses"));
4635 
4636 			// 2 and 3 subpasses should be good enough.
4637 			static const std::vector<size_t> combinationSizes = { 2, 3 };
4638 
4639 			// Basic cases.
4640 			for (const auto size : combinationSizes)
4641 			{
4642 				const auto combs = combinations(kSampleCounts, size);
4643 				for (const auto& comb : combs)
4644 				{
4645 					// Check sample counts actually vary between some of the subpasses.
4646 					std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb));
4647 					if (uniqueVals.size() < 2)
4648 						continue;
4649 
4650 					std::ostringstream name;
4651 					std::ostringstream desc;
4652 
4653 					bool first = true;
4654 					for (const auto& count : comb)
4655 					{
4656 						name << (first ? "" : "_") << count;
4657 						desc << (first ? "Subpasses with counts " : ", ") << count;
4658 						first = false;
4659 					}
4660 
4661 					const VariableRateTestCase::TestParams params =
4662 					{
4663 						false,						//	bool						nonEmptyFramebuffer;
4664 						vk::VK_SAMPLE_COUNT_1_BIT,	//	vk::VkSampleCountFlagBits	fbCount;
4665 						false,						//	bool						unusedAttachment;
4666 						comb,						//	SampleCounts				subpassCounts;
4667 					};
4668 					variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), desc.str(), params));
4669 				}
4670 			}
4671 
4672 			// Cases with non-empty framebuffers: only 2 subpasses to avoid a large number of combinations.
4673 			{
4674 				// Use one more sample count for the framebuffer attachment. It will be taken from the last item.
4675 				auto combs = combinations(kSampleCounts, 2 + 1);
4676 				for (auto& comb : combs)
4677 				{
4678 					// Framebuffer sample count.
4679 					const auto fbCount = comb.back();
4680 					comb.pop_back();
4681 
4682 					// Check sample counts actually vary between some of the subpasses.
4683 					std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb));
4684 					if (uniqueVals.size() < 2)
4685 						continue;
4686 
4687 					for (const auto flag : unusedAttachmentFlag)
4688 					{
4689 						std::ostringstream name;
4690 						std::ostringstream desc;
4691 
4692 						desc << "Framebuffer with sample count " << fbCount << " and subpasses with counts ";
4693 
4694 						bool first = true;
4695 						for (const auto& count : comb)
4696 						{
4697 							name << (first ? "" : "_") << count;
4698 							desc << (first ? "" : ", ") << count;
4699 							first = false;
4700 						}
4701 
4702 						name << "_fb_" << fbCount;
4703 
4704 						if (flag)
4705 						{
4706 							name << "_unused";
4707 							desc << " and unused attachments";
4708 						}
4709 
4710 						const VariableRateTestCase::TestParams params =
4711 						{
4712 							true,						//	bool						nonEmptyFramebuffer;
4713 							fbCount,					//	vk::VkSampleCountFlagBits	fbCount;
4714 							flag,						//	bool						unusedAttachment;
4715 							comb,						//	SampleCounts				subpassCounts;
4716 						};
4717 						variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), desc.str(), params));
4718 					}
4719 				}
4720 			}
4721 
4722 			multisampleTests->addChild(variableRateGroup.release());
4723 		}
4724 
4725 		{
4726 			de::MovePtr<tcu::TestCaseGroup> mixedCountGroup(new tcu::TestCaseGroup(testCtx, "mixed_count", "Tests for mixed sample count in empty subpass and framebuffer"));
4727 
4728 			const auto combs = combinations(kSampleCounts, 2);
4729 			for (const auto& comb : combs)
4730 			{
4731 				// Check different sample count.
4732 				DE_ASSERT(comb.size() == 2u);
4733 				const auto& fbCount		= comb[0];
4734 				const auto& emptyCount	= comb[1];
4735 
4736 				if (fbCount == emptyCount)
4737 					continue;
4738 
4739 				const std::string fbCountStr	= de::toString(fbCount);
4740 				const std::string emptyCountStr	= de::toString(emptyCount);
4741 
4742 				for (const auto flag : unusedAttachmentFlag)
4743 				{
4744 					const std::string nameSuffix	= (flag ? "unused" : "");
4745 					const std::string descSuffix	= (flag ? "one unused attachment reference" : "no attachment references");
4746 					const std::string name			= fbCountStr + "_" + emptyCountStr + (nameSuffix.empty() ? "" : "_") + nameSuffix;
4747 					const std::string desc			= "Framebuffer with " + fbCountStr + " samples, subpass with " + emptyCountStr + " samples and " + descSuffix;
4748 
4749 					const VariableRateTestCase::TestParams params =
4750 					{
4751 						true,												//	bool						nonEmptyFramebuffer;
4752 						fbCount,											//	vk::VkSampleCountFlagBits	fbCount;
4753 						flag,												//	bool						unusedAttachment;
4754 						VariableRateTestCase::SampleCounts(1u, emptyCount),	//	SampleCounts				subpassCounts;
4755 					};
4756 					mixedCountGroup->addChild(new VariableRateTestCase(testCtx, name, desc, params));
4757 				}
4758 			}
4759 
4760 			multisampleTests->addChild(mixedCountGroup.release());
4761 		}
4762 	}
4763 
4764 	return multisampleTests.release();
4765 }
4766 
4767 } // pipeline
4768 } // vkt
4769