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