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