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