Home | History | Annotate | Download | only in pipeline
      1 /*------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2015 The Khronos Group Inc.
      6  * Copyright (c) 2015 Imagination Technologies Ltd.
      7  *
      8  * Licensed under the Apache License, Version 2.0 (the "License");
      9  * you may not use this file except in compliance with the License.
     10  * You may obtain a copy of the License at
     11  *
     12  *      http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing, software
     15  * distributed under the License is distributed on an "AS IS" BASIS,
     16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17  * See the License for the specific language governing permissions and
     18  * limitations under the License.
     19  *
     20  *//*!
     21  * \file
     22  * \brief Multisample Tests
     23  *//*--------------------------------------------------------------------*/
     24 
     25 #include "vktPipelineMultisampleTests.hpp"
     26 #include "vktPipelineMultisampleImageTests.hpp"
     27 #include "vktPipelineClearUtil.hpp"
     28 #include "vktPipelineImageUtil.hpp"
     29 #include "vktPipelineVertexUtil.hpp"
     30 #include "vktPipelineReferenceRenderer.hpp"
     31 #include "vktTestCase.hpp"
     32 #include "vktTestCaseUtil.hpp"
     33 #include "vkImageUtil.hpp"
     34 #include "vkMemUtil.hpp"
     35 #include "vkPrograms.hpp"
     36 #include "vkQueryUtil.hpp"
     37 #include "vkRef.hpp"
     38 #include "vkRefUtil.hpp"
     39 #include "tcuImageCompare.hpp"
     40 #include "tcuTestLog.hpp"
     41 #include "deUniquePtr.hpp"
     42 #include "deSharedPtr.hpp"
     43 #include "deStringUtil.hpp"
     44 #include "deMemory.h"
     45 
     46 #include <sstream>
     47 #include <vector>
     48 #include <map>
     49 
     50 namespace vkt
     51 {
     52 namespace pipeline
     53 {
     54 
     55 using namespace vk;
     56 
     57 namespace
     58 {
     59 enum GeometryType
     60 {
     61 	GEOMETRY_TYPE_OPAQUE_TRIANGLE,
     62 	GEOMETRY_TYPE_OPAQUE_LINE,
     63 	GEOMETRY_TYPE_OPAQUE_POINT,
     64 	GEOMETRY_TYPE_OPAQUE_QUAD,
     65 	GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH,	//!< placed at z = 0.5
     66 	GEOMETRY_TYPE_TRANSLUCENT_QUAD,
     67 	GEOMETRY_TYPE_INVISIBLE_TRIANGLE,
     68 	GEOMETRY_TYPE_INVISIBLE_QUAD,
     69 	GEOMETRY_TYPE_GRADIENT_QUAD
     70 };
     71 
     72 enum TestModeBits
     73 {
     74 	TEST_MODE_DEPTH_BIT		= 1u,
     75 	TEST_MODE_STENCIL_BIT	= 2u,
     76 };
     77 typedef deUint32 TestModeFlags;
     78 
     79 enum RenderType
     80 {
     81 	// resolve multisample rendering to single sampled image
     82 	RENDER_TYPE_RESOLVE		= 0u,
     83 
     84 	// copy samples to an array of single sampled images
     85 	RENDER_TYPE_COPY_SAMPLES
     86 };
     87 
     88 void									initMultisamplePrograms				(SourceCollections& sources, GeometryType geometryType);
     89 bool									isSupportedSampleCount				(const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples);
     90 bool									isSupportedDepthStencilFormat		(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format);
     91 VkPipelineColorBlendAttachmentState		getDefaultColorBlendAttachmentState	(void);
     92 deUint32								getUniqueColorsCount				(const tcu::ConstPixelBufferAccess& image);
     93 VkImageAspectFlags						getImageAspectFlags					(const VkFormat format);
     94 VkPrimitiveTopology						getPrimitiveTopology				(const GeometryType geometryType);
     95 std::vector<Vertex4RGBA>				generateVertices					(const GeometryType geometryType);
     96 VkFormat								findSupportedDepthStencilFormat		(Context& context, const bool useDepth, const bool useStencil);
     97 
     98 class MultisampleTest : public vkt::TestCase
     99 {
    100 public:
    101 
    102 												MultisampleTest						(tcu::TestContext&								testContext,
    103 																					 const std::string&								name,
    104 																					 const std::string&								description,
    105 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    106 																					 const VkPipelineColorBlendAttachmentState&		blendState,
    107 																					 GeometryType									geometryType);
    108 	virtual										~MultisampleTest					(void) {}
    109 
    110 	virtual void								initPrograms						(SourceCollections& programCollection) const;
    111 	virtual TestInstance*						createInstance						(Context& context) const;
    112 
    113 protected:
    114 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
    115 																					 VkPrimitiveTopology							topology,
    116 																					 const std::vector<Vertex4RGBA>&				vertices,
    117 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    118 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const = 0;
    119 	VkPipelineMultisampleStateCreateInfo		m_multisampleStateParams;
    120 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
    121 	const GeometryType							m_geometryType;
    122 	std::vector<VkSampleMask>					m_sampleMask;
    123 };
    124 
    125 class RasterizationSamplesTest : public MultisampleTest
    126 {
    127 public:
    128 												RasterizationSamplesTest			(tcu::TestContext&		testContext,
    129 																					 const std::string&		name,
    130 																					 const std::string&		description,
    131 																					 VkSampleCountFlagBits	rasterizationSamples,
    132 																					 GeometryType			geometryType,
    133 																					 TestModeFlags			modeFlags				= 0u);
    134 	virtual										~RasterizationSamplesTest			(void) {}
    135 
    136 protected:
    137 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
    138 																					 VkPrimitiveTopology							topology,
    139 																					 const std::vector<Vertex4RGBA>&				vertices,
    140 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    141 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
    142 
    143 	static VkPipelineMultisampleStateCreateInfo	getRasterizationSamplesStateParams	(VkSampleCountFlagBits rasterizationSamples);
    144 
    145 	const TestModeFlags							m_modeFlags;
    146 };
    147 
    148 class MinSampleShadingTest : public MultisampleTest
    149 {
    150 public:
    151 												MinSampleShadingTest				(tcu::TestContext&		testContext,
    152 																					 const std::string&		name,
    153 																					 const std::string&		description,
    154 																					 VkSampleCountFlagBits	rasterizationSamples,
    155 																					 float					minSampleShading,
    156 																					 GeometryType			geometryType);
    157 	virtual										~MinSampleShadingTest				(void) {}
    158 
    159 protected:
    160 	virtual void								initPrograms						(SourceCollections& programCollection) const;
    161 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
    162 																					 VkPrimitiveTopology							topology,
    163 																					 const std::vector<Vertex4RGBA>&				vertices,
    164 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    165 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
    166 
    167 	static VkPipelineMultisampleStateCreateInfo	getMinSampleShadingStateParams		(VkSampleCountFlagBits rasterizationSamples, float minSampleShading);
    168 };
    169 
    170 class SampleMaskTest : public MultisampleTest
    171 {
    172 public:
    173 												SampleMaskTest						(tcu::TestContext&					testContext,
    174 																					 const std::string&					name,
    175 																					 const std::string&					description,
    176 																					 VkSampleCountFlagBits				rasterizationSamples,
    177 																					 const std::vector<VkSampleMask>&	sampleMask,
    178 																					 GeometryType						geometryType);
    179 
    180 	virtual										~SampleMaskTest						(void) {}
    181 
    182 protected:
    183 	virtual TestInstance*						createMultisampleTestInstance		(Context&										context,
    184 																					 VkPrimitiveTopology							topology,
    185 																					 const std::vector<Vertex4RGBA>&				vertices,
    186 																					 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    187 																					 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
    188 
    189 	static VkPipelineMultisampleStateCreateInfo	getSampleMaskStateParams			(VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask);
    190 };
    191 
    192 class AlphaToOneTest : public MultisampleTest
    193 {
    194 public:
    195 												AlphaToOneTest					(tcu::TestContext&					testContext,
    196 																				 const std::string&					name,
    197 																				 const std::string&					description,
    198 																				 VkSampleCountFlagBits				rasterizationSamples);
    199 
    200 	virtual										~AlphaToOneTest					(void) {}
    201 
    202 protected:
    203 	virtual TestInstance*						createMultisampleTestInstance	(Context&										context,
    204 																				 VkPrimitiveTopology							topology,
    205 																				 const std::vector<Vertex4RGBA>&				vertices,
    206 																				 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    207 																				 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
    208 
    209 	static VkPipelineMultisampleStateCreateInfo	getAlphaToOneStateParams		(VkSampleCountFlagBits rasterizationSamples);
    210 	static VkPipelineColorBlendAttachmentState	getAlphaToOneBlendState			(void);
    211 };
    212 
    213 class AlphaToCoverageTest : public MultisampleTest
    214 {
    215 public:
    216 												AlphaToCoverageTest				(tcu::TestContext&		testContext,
    217 																				 const std::string&		name,
    218 																				 const std::string&		description,
    219 																				 VkSampleCountFlagBits	rasterizationSamples,
    220 																				 GeometryType			geometryType);
    221 
    222 	virtual										~AlphaToCoverageTest			(void) {}
    223 
    224 protected:
    225 	virtual TestInstance*						createMultisampleTestInstance	(Context&										context,
    226 																				 VkPrimitiveTopology							topology,
    227 																				 const std::vector<Vertex4RGBA>&				vertices,
    228 																				 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    229 																				 const VkPipelineColorBlendAttachmentState&		colorBlendState) const;
    230 
    231 	static VkPipelineMultisampleStateCreateInfo	getAlphaToCoverageStateParams	(VkSampleCountFlagBits rasterizationSamples);
    232 
    233 	GeometryType								m_geometryType;
    234 };
    235 
    236 typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp;
    237 
    238 class MultisampleRenderer
    239 {
    240 public:
    241 												MultisampleRenderer			(Context&										context,
    242 																			 const VkFormat									colorFormat,
    243 																			 const tcu::IVec2&								renderSize,
    244 																			 const VkPrimitiveTopology						topology,
    245 																			 const std::vector<Vertex4RGBA>&				vertices,
    246 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    247 																			 const VkPipelineColorBlendAttachmentState&		blendState,
    248 																			 const RenderType								renderType);
    249 
    250 												MultisampleRenderer			(Context&										context,
    251 																			 const VkFormat									colorFormat,
    252 																			 const VkFormat									depthStencilFormat,
    253 																			 const tcu::IVec2&								renderSize,
    254 																			 const bool										useDepth,
    255 																			 const bool										useStencil,
    256 																			 const deUint32									numTopologies,
    257 																			 const VkPrimitiveTopology*						pTopology,
    258 																			 const std::vector<Vertex4RGBA>*				pVertices,
    259 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    260 																			 const VkPipelineColorBlendAttachmentState&		blendState,
    261 																		     const RenderType								renderType);
    262 
    263 	virtual										~MultisampleRenderer		(void);
    264 
    265 	de::MovePtr<tcu::TextureLevel>				render						(void);
    266 	de::MovePtr<tcu::TextureLevel>				getSingleSampledImage		(deUint32 sampleId);
    267 
    268 protected:
    269 	void										initialize					(Context&										context,
    270 																			 const deUint32									numTopologies,
    271 																			 const VkPrimitiveTopology*						pTopology,
    272 																			 const std::vector<Vertex4RGBA>*				pVertices);
    273 
    274 	Context&									m_context;
    275 
    276 	const VkFormat								m_colorFormat;
    277 	const VkFormat								m_depthStencilFormat;
    278 	tcu::IVec2									m_renderSize;
    279 	const bool									m_useDepth;
    280 	const bool									m_useStencil;
    281 
    282 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
    283 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
    284 
    285 	const RenderType							m_renderType;
    286 
    287 	Move<VkImage>								m_colorImage;
    288 	de::MovePtr<Allocation>						m_colorImageAlloc;
    289 	Move<VkImageView>							m_colorAttachmentView;
    290 
    291 	Move<VkImage>								m_resolveImage;
    292 	de::MovePtr<Allocation>						m_resolveImageAlloc;
    293 	Move<VkImageView>							m_resolveAttachmentView;
    294 
    295 	struct PerSampleImage
    296 	{
    297 		Move<VkImage>								m_image;
    298 		de::MovePtr<Allocation>						m_imageAlloc;
    299 		Move<VkImageView>							m_attachmentView;
    300 	};
    301 	std::vector<de::SharedPtr<PerSampleImage> >	m_perSampleImages;
    302 
    303 	Move<VkImage>								m_depthStencilImage;
    304 	de::MovePtr<Allocation>						m_depthStencilImageAlloc;
    305 	Move<VkImageView>							m_depthStencilAttachmentView;
    306 
    307 	Move<VkRenderPass>							m_renderPass;
    308 	Move<VkFramebuffer>							m_framebuffer;
    309 
    310 	Move<VkShaderModule>						m_vertexShaderModule;
    311 	Move<VkShaderModule>						m_fragmentShaderModule;
    312 
    313 	Move<VkShaderModule>						m_copySampleVertexShaderModule;
    314 	Move<VkShaderModule>						m_copySampleFragmentShaderModule;
    315 
    316 	Move<VkBuffer>								m_vertexBuffer;
    317 	de::MovePtr<Allocation>						m_vertexBufferAlloc;
    318 
    319 	Move<VkPipelineLayout>						m_pipelineLayout;
    320 	std::vector<VkPipelineSp>					m_graphicsPipelines;
    321 
    322 	Move<VkDescriptorSetLayout>					m_copySampleDesciptorLayout;
    323 	Move<VkDescriptorPool>						m_copySampleDesciptorPool;
    324 	Move<VkDescriptorSet>						m_copySampleDesciptorSet;
    325 
    326 	Move<VkPipelineLayout>						m_copySamplePipelineLayout;
    327 	std::vector<VkPipelineSp>					m_copySamplePipelines;
    328 
    329 	Move<VkCommandPool>							m_cmdPool;
    330 	Move<VkCommandBuffer>						m_cmdBuffer;
    331 
    332 	Move<VkFence>								m_fence;
    333 };
    334 
    335 class RasterizationSamplesInstance : public vkt::TestInstance
    336 {
    337 public:
    338 										RasterizationSamplesInstance	(Context&										context,
    339 																		 VkPrimitiveTopology							topology,
    340 																		 const std::vector<Vertex4RGBA>&				vertices,
    341 																		 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    342 																		 const VkPipelineColorBlendAttachmentState&		blendState,
    343 																		 const TestModeFlags							modeFlags);
    344 	virtual								~RasterizationSamplesInstance	(void) {}
    345 
    346 	virtual tcu::TestStatus				iterate							(void);
    347 
    348 protected:
    349 	virtual tcu::TestStatus				verifyImage						(const tcu::ConstPixelBufferAccess& result);
    350 
    351 	const VkFormat						m_colorFormat;
    352 	const tcu::IVec2					m_renderSize;
    353 	const VkPrimitiveTopology			m_primitiveTopology;
    354 	const std::vector<Vertex4RGBA>		m_vertices;
    355 	const std::vector<Vertex4RGBA>		m_fullQuadVertices;			//!< used by depth/stencil case
    356 	const TestModeFlags					m_modeFlags;
    357 	de::MovePtr<MultisampleRenderer>	m_multisampleRenderer;
    358 };
    359 
    360 class MinSampleShadingInstance : public vkt::TestInstance
    361 {
    362 public:
    363 												MinSampleShadingInstance	(Context&										context,
    364 																			 VkPrimitiveTopology							topology,
    365 																			 const std::vector<Vertex4RGBA>&				vertices,
    366 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    367 																			 const VkPipelineColorBlendAttachmentState&		blendState);
    368 	virtual										~MinSampleShadingInstance	(void) {}
    369 
    370 	virtual tcu::TestStatus						iterate						(void);
    371 
    372 protected:
    373 	virtual tcu::TestStatus						verifySampleShadedImage		(const std::vector<tcu::TextureLevel>& testShadingImages,
    374 																			 const tcu::ConstPixelBufferAccess& noSampleshadingImage);
    375 
    376 	const VkFormat								m_colorFormat;
    377 	const tcu::IVec2							m_renderSize;
    378 	const VkPrimitiveTopology					m_primitiveTopology;
    379 	const std::vector<Vertex4RGBA>				m_vertices;
    380 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
    381 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
    382 };
    383 
    384 class SampleMaskInstance : public vkt::TestInstance
    385 {
    386 public:
    387 												SampleMaskInstance			(Context&										context,
    388 																			 VkPrimitiveTopology							topology,
    389 																			 const std::vector<Vertex4RGBA>&				vertices,
    390 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    391 																			 const VkPipelineColorBlendAttachmentState&		blendState);
    392 	virtual										~SampleMaskInstance			(void) {}
    393 
    394 	virtual tcu::TestStatus						iterate						(void);
    395 
    396 protected:
    397 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& testShadingImage,
    398 																			 const tcu::ConstPixelBufferAccess& minShadingImage,
    399 																			 const tcu::ConstPixelBufferAccess& maxShadingImage);
    400 	const VkFormat								m_colorFormat;
    401 	const tcu::IVec2							m_renderSize;
    402 	const VkPrimitiveTopology					m_primitiveTopology;
    403 	const std::vector<Vertex4RGBA>				m_vertices;
    404 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
    405 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
    406 };
    407 
    408 class AlphaToOneInstance : public vkt::TestInstance
    409 {
    410 public:
    411 												AlphaToOneInstance			(Context&										context,
    412 																			 VkPrimitiveTopology							topology,
    413 																			 const std::vector<Vertex4RGBA>&				vertices,
    414 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    415 																			 const VkPipelineColorBlendAttachmentState&		blendState);
    416 	virtual										~AlphaToOneInstance			(void) {}
    417 
    418 	virtual tcu::TestStatus						iterate						(void);
    419 
    420 protected:
    421 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& alphaOneImage,
    422 																			 const tcu::ConstPixelBufferAccess& noAlphaOneImage);
    423 	const VkFormat								m_colorFormat;
    424 	const tcu::IVec2							m_renderSize;
    425 	const VkPrimitiveTopology					m_primitiveTopology;
    426 	const std::vector<Vertex4RGBA>				m_vertices;
    427 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
    428 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
    429 };
    430 
    431 class AlphaToCoverageInstance : public vkt::TestInstance
    432 {
    433 public:
    434 												AlphaToCoverageInstance		(Context&										context,
    435 																			 VkPrimitiveTopology							topology,
    436 																			 const std::vector<Vertex4RGBA>&				vertices,
    437 																			 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    438 																			 const VkPipelineColorBlendAttachmentState&		blendState,
    439 																			 GeometryType									geometryType);
    440 	virtual										~AlphaToCoverageInstance	(void) {}
    441 
    442 	virtual tcu::TestStatus						iterate						(void);
    443 
    444 protected:
    445 	virtual tcu::TestStatus						verifyImage					(const tcu::ConstPixelBufferAccess& result);
    446 	const VkFormat								m_colorFormat;
    447 	const tcu::IVec2							m_renderSize;
    448 	const VkPrimitiveTopology					m_primitiveTopology;
    449 	const std::vector<Vertex4RGBA>				m_vertices;
    450 	const VkPipelineMultisampleStateCreateInfo	m_multisampleStateParams;
    451 	const VkPipelineColorBlendAttachmentState	m_colorBlendState;
    452 	const GeometryType							m_geometryType;
    453 };
    454 
    455 
    456 // Helper functions
    457 
    458 void initMultisamplePrograms (SourceCollections& sources, GeometryType geometryType)
    459 {
    460 	std::ostringstream vertexSource;
    461 
    462 	vertexSource <<
    463 		"#version 310 es\n"
    464 		"layout(location = 0) in vec4 position;\n"
    465 		"layout(location = 1) in vec4 color;\n"
    466 		"layout(location = 0) out highp vec4 vtxColor;\n"
    467 		"void main (void)\n"
    468 		"{\n"
    469 		"	gl_Position = position;\n"
    470 		"	vtxColor = color;\n"
    471 		<< (geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? "	gl_PointSize = 3.0f;\n"
    472 			: "")
    473 		<< "}\n";
    474 
    475 	static const char* fragmentSource =
    476 		"#version 310 es\n"
    477 		"layout(location = 0) in highp vec4 vtxColor;\n"
    478 		"layout(location = 0) out highp vec4 fragColor;\n"
    479 		"void main (void)\n"
    480 		"{\n"
    481 		"	fragColor = vtxColor;\n"
    482 		"}\n";
    483 
    484 	sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
    485 	sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
    486 }
    487 
    488 void initSampleShadingPrograms (SourceCollections& sources, GeometryType geometryType)
    489 {
    490 	{
    491 		std::ostringstream vertexSource;
    492 
    493 		vertexSource <<
    494 			"#version 440\n"
    495 			"layout(location = 0) in vec4 position;\n"
    496 			"layout(location = 1) in vec4 color;\n"
    497 			"void main (void)\n"
    498 			"{\n"
    499 			"	gl_Position = position;\n"
    500 			<< (geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? "	gl_PointSize = 3.0f;\n"
    501 				: "")
    502 			<< "}\n";
    503 
    504 		static const char* fragmentSource =
    505 			"#version 440\n"
    506 			"layout(location = 0) out highp vec4 fragColor;\n"
    507 			"void main (void)\n"
    508 			"{\n"
    509 			"	fragColor = vec4(fract(gl_FragCoord.xy), 0.0, 1.0);\n"
    510 			"}\n";
    511 
    512 		sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
    513 		sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
    514 	}
    515 
    516 	{
    517 		static const char*  vertexSource =
    518 			"#version 440\n"
    519 			"void main (void)\n"
    520 			"{\n"
    521 			"	const vec4 positions[4] = vec4[4](\n"
    522 			"		vec4(-1.0, -1.0, 0.0, 1.0),\n"
    523 			"		vec4(-1.0,  1.0, 0.0, 1.0),\n"
    524 			"		vec4( 1.0, -1.0, 0.0, 1.0),\n"
    525 			"		vec4( 1.0,  1.0, 0.0, 1.0)\n"
    526 			"	);\n"
    527 			"	gl_Position = positions[gl_VertexIndex];\n"
    528 			"}\n";
    529 
    530 		static const char* fragmentSource =
    531 			"#version 440\n"
    532 			"precision highp float;\n"
    533 			"layout(location = 0) out highp vec4 fragColor;\n"
    534 			"layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
    535 			"layout(push_constant) uniform PushConstantsBlock\n"
    536 			"{\n"
    537 			"	int sampleId;\n"
    538 			"} pushConstants;\n"
    539 			"void main (void)\n"
    540 			"{\n"
    541 			"	fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n"
    542 			"}\n";
    543 
    544 		sources.glslSources.add("quad_vert") << glu::VertexSource(vertexSource);
    545 		sources.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource);
    546 	}
    547 }
    548 
    549 bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples)
    550 {
    551 	VkPhysicalDeviceProperties deviceProperties;
    552 
    553 	instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties);
    554 
    555 	return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples);
    556 }
    557 
    558 VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void)
    559 {
    560 	const VkPipelineColorBlendAttachmentState colorBlendState =
    561 	{
    562 		false,														// VkBool32					blendEnable;
    563 		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcColorBlendFactor;
    564 		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstColorBlendFactor;
    565 		VK_BLEND_OP_ADD,											// VkBlendOp				colorBlendOp;
    566 		VK_BLEND_FACTOR_ONE,										// VkBlendFactor			srcAlphaBlendFactor;
    567 		VK_BLEND_FACTOR_ZERO,										// VkBlendFactor			dstAlphaBlendFactor;
    568 		VK_BLEND_OP_ADD,											// VkBlendOp				alphaBlendOp;
    569 		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
    570 			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
    571 	};
    572 
    573 	return colorBlendState;
    574 }
    575 
    576 deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image)
    577 {
    578 	DE_ASSERT(image.getFormat().getPixelSize() == 4);
    579 
    580 	std::map<deUint32, deUint32>	histogram; // map<pixel value, number of occurrences>
    581 	const deUint32					pixelCount	= image.getWidth() * image.getHeight() * image.getDepth();
    582 
    583 	for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
    584 	{
    585 		const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx);
    586 
    587 		if (histogram.find(pixelValue) != histogram.end())
    588 			histogram[pixelValue]++;
    589 		else
    590 			histogram[pixelValue] = 1;
    591 	}
    592 
    593 	return (deUint32)histogram.size();
    594 }
    595 
    596 VkImageAspectFlags getImageAspectFlags (const VkFormat format)
    597 {
    598 	const tcu::TextureFormat tcuFormat = mapVkFormat(format);
    599 
    600 	if      (tcuFormat.order == tcu::TextureFormat::DS)		return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
    601 	else if (tcuFormat.order == tcu::TextureFormat::D)		return VK_IMAGE_ASPECT_DEPTH_BIT;
    602 	else if (tcuFormat.order == tcu::TextureFormat::S)		return VK_IMAGE_ASPECT_STENCIL_BIT;
    603 
    604 	DE_ASSERT(false);
    605 	return 0u;
    606 }
    607 
    608 std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType)
    609 {
    610 	std::vector<Vertex4RGBA> vertices;
    611 
    612 	switch (geometryType)
    613 	{
    614 		case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
    615 		case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:
    616 		{
    617 			Vertex4RGBA vertexData[3] =
    618 			{
    619 				{
    620 					tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
    621 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
    622 				},
    623 				{
    624 					tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
    625 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
    626 				},
    627 				{
    628 					tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
    629 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
    630 				}
    631 			};
    632 
    633 			if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE)
    634 			{
    635 				for (int i = 0; i < 3; i++)
    636 					vertexData[i].color = tcu::Vec4();
    637 			}
    638 
    639 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3);
    640 			break;
    641 		}
    642 
    643 		case GEOMETRY_TYPE_OPAQUE_LINE:
    644 		{
    645 			const Vertex4RGBA vertexData[2] =
    646 			{
    647 				{
    648 					tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f),
    649 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
    650 				},
    651 				{
    652 					tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f),
    653 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
    654 				}
    655 			};
    656 
    657 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2);
    658 			break;
    659 		}
    660 
    661 		case GEOMETRY_TYPE_OPAQUE_POINT:
    662 		{
    663 			const Vertex4RGBA vertex =
    664 			{
    665 				tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
    666 				tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
    667 			};
    668 
    669 			vertices = std::vector<Vertex4RGBA>(1, vertex);
    670 			break;
    671 		}
    672 
    673 		case GEOMETRY_TYPE_OPAQUE_QUAD:
    674 		case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
    675 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
    676 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
    677 		case GEOMETRY_TYPE_GRADIENT_QUAD:
    678 		{
    679 			Vertex4RGBA vertexData[4] =
    680 			{
    681 				{
    682 					tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
    683 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
    684 				},
    685 				{
    686 					tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),
    687 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
    688 				},
    689 				{
    690 					tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
    691 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
    692 				},
    693 				{
    694 					tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
    695 					tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
    696 				}
    697 			};
    698 
    699 			if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD)
    700 			{
    701 				for (int i = 0; i < 4; i++)
    702 					vertexData[i].color.w() = 0.25f;
    703 			}
    704 			else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD)
    705 			{
    706 				for (int i = 0; i < 4; i++)
    707 					vertexData[i].color.w() = 0.0f;
    708 			}
    709 			else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD)
    710 			{
    711 				vertexData[0].color.w() = 0.0f;
    712 				vertexData[2].color.w() = 0.0f;
    713 			}
    714 			else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)
    715 			{
    716 				for (int i = 0; i < 4; i++)
    717 					vertexData[i].position.z() = 0.5f;
    718 			}
    719 
    720 			vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 4);
    721 			break;
    722 		}
    723 
    724 		default:
    725 			DE_ASSERT(false);
    726 	}
    727 	return vertices;
    728 }
    729 
    730 VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType)
    731 {
    732 	switch (geometryType)
    733 	{
    734 		case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
    735 		case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:			return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
    736 
    737 		case GEOMETRY_TYPE_OPAQUE_LINE:					return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
    738 		case GEOMETRY_TYPE_OPAQUE_POINT:				return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
    739 
    740 		case GEOMETRY_TYPE_OPAQUE_QUAD:
    741 		case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
    742 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
    743 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
    744 		case GEOMETRY_TYPE_GRADIENT_QUAD:				return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
    745 
    746 		default:
    747 			DE_ASSERT(false);
    748 			return VK_PRIMITIVE_TOPOLOGY_LAST;
    749 	}
    750 }
    751 
    752 bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
    753 {
    754 	VkFormatProperties formatProps;
    755 	vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
    756 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
    757 }
    758 
    759 VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil)
    760 {
    761 	if (useDepth && !useStencil)
    762 		return VK_FORMAT_D16_UNORM;		// must be supported
    763 
    764 	const InstanceInterface&	vki			= context.getInstanceInterface();
    765 	const VkPhysicalDevice		physDevice	= context.getPhysicalDevice();
    766 
    767 	// One of these formats must be supported.
    768 
    769 	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
    770 		return VK_FORMAT_D24_UNORM_S8_UINT;
    771 
    772 	if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT))
    773 		return VK_FORMAT_D32_SFLOAT_S8_UINT;
    774 
    775 	return VK_FORMAT_UNDEFINED;
    776 }
    777 
    778 
    779 // MultisampleTest
    780 
    781 MultisampleTest::MultisampleTest (tcu::TestContext&								testContext,
    782 								  const std::string&							name,
    783 								  const std::string&							description,
    784 								  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    785 								  const VkPipelineColorBlendAttachmentState&	blendState,
    786 								  GeometryType									geometryType)
    787 	: vkt::TestCase				(testContext, name, description)
    788 	, m_multisampleStateParams	(multisampleStateParams)
    789 	, m_colorBlendState			(blendState)
    790 	, m_geometryType			(geometryType)
    791 {
    792 	if (m_multisampleStateParams.pSampleMask)
    793 	{
    794 		// Copy pSampleMask to avoid dependencies with other classes
    795 
    796 		const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32);
    797 
    798 		for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++)
    799 			m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]);
    800 
    801 		m_multisampleStateParams.pSampleMask = m_sampleMask.data();
    802 	}
    803 }
    804 
    805 void MultisampleTest::initPrograms (SourceCollections& programCollection) const
    806 {
    807 	initMultisamplePrograms(programCollection, m_geometryType);
    808 }
    809 
    810 TestInstance* MultisampleTest::createInstance (Context& context) const
    811 {
    812 	return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState);
    813 }
    814 
    815 
    816 // RasterizationSamplesTest
    817 
    818 RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext&		testContext,
    819 													const std::string&		name,
    820 													const std::string&		description,
    821 													VkSampleCountFlagBits	rasterizationSamples,
    822 													GeometryType			geometryType,
    823 													TestModeFlags			modeFlags)
    824 	: MultisampleTest	(testContext, name, description, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType)
    825 	, m_modeFlags		(modeFlags)
    826 {
    827 }
    828 
    829 VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples)
    830 {
    831 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
    832 	{
    833 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
    834 		DE_NULL,													// const void*								pNext;
    835 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
    836 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
    837 		false,														// VkBool32									sampleShadingEnable;
    838 		0.0f,														// float									minSampleShading;
    839 		DE_NULL,													// const VkSampleMask*						pSampleMask;
    840 		false,														// VkBool32									alphaToCoverageEnable;
    841 		false														// VkBool32									alphaToOneEnable;
    842 	};
    843 
    844 	return multisampleStateParams;
    845 }
    846 
    847 TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context&										context,
    848 																	   VkPrimitiveTopology							topology,
    849 																	   const std::vector<Vertex4RGBA>&				vertices,
    850 																	   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    851 																	   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
    852 {
    853 	return new RasterizationSamplesInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_modeFlags);
    854 }
    855 
    856 
    857 // MinSampleShadingTest
    858 
    859 MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext&		testContext,
    860 											const std::string&		name,
    861 											const std::string&		description,
    862 											VkSampleCountFlagBits	rasterizationSamples,
    863 											float					minSampleShading,
    864 											GeometryType			geometryType)
    865 	: MultisampleTest	(testContext, name, description, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading), getDefaultColorBlendAttachmentState(), geometryType)
    866 {
    867 }
    868 
    869 void MinSampleShadingTest::initPrograms (SourceCollections& programCollection) const
    870 {
    871 	initSampleShadingPrograms(programCollection, m_geometryType);
    872 }
    873 
    874 TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context&										context,
    875 																   VkPrimitiveTopology							topology,
    876 																   const std::vector<Vertex4RGBA>&				vertices,
    877 																   const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    878 																   const VkPipelineColorBlendAttachmentState&	colorBlendState) const
    879 {
    880 	return new MinSampleShadingInstance(context, topology, vertices, multisampleStateParams, colorBlendState);
    881 }
    882 
    883 VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading)
    884 {
    885 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
    886 	{
    887 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
    888 		DE_NULL,													// const void*								pNext;
    889 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
    890 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
    891 		true,														// VkBool32									sampleShadingEnable;
    892 		minSampleShading,											// float									minSampleShading;
    893 		DE_NULL,													// const VkSampleMask*						pSampleMask;
    894 		false,														//  VkBool32								alphaToCoverageEnable;
    895 		false														//  VkBool32								alphaToOneEnable;
    896 	};
    897 
    898 	return multisampleStateParams;
    899 }
    900 
    901 
    902 // SampleMaskTest
    903 
    904 SampleMaskTest::SampleMaskTest (tcu::TestContext&					testContext,
    905 								const std::string&					name,
    906 								const std::string&					description,
    907 								VkSampleCountFlagBits				rasterizationSamples,
    908 								const std::vector<VkSampleMask>&	sampleMask,
    909 								GeometryType						geometryType)
    910 	: MultisampleTest	(testContext, name, description, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType)
    911 {
    912 }
    913 
    914 TestInstance* SampleMaskTest::createMultisampleTestInstance (Context&										context,
    915 															 VkPrimitiveTopology							topology,
    916 															 const std::vector<Vertex4RGBA>&				vertices,
    917 															 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    918 															 const VkPipelineColorBlendAttachmentState&		colorBlendState) const
    919 {
    920 	return new SampleMaskInstance(context, topology,vertices, multisampleStateParams, colorBlendState);
    921 }
    922 
    923 VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask)
    924 {
    925 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
    926 	{
    927 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
    928 		DE_NULL,													// const void*								pNext;
    929 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
    930 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
    931 		false,														// VkBool32									sampleShadingEnable;
    932 		0.0f,														// float									minSampleShading;
    933 		sampleMask.data(),											// const VkSampleMask*						pSampleMask;
    934 		false,														// VkBool32									alphaToCoverageEnable;
    935 		false														// VkBool32									alphaToOneEnable;
    936 	};
    937 
    938 	return multisampleStateParams;
    939 }
    940 
    941 
    942 // AlphaToOneTest
    943 
    944 AlphaToOneTest::AlphaToOneTest (tcu::TestContext&		testContext,
    945 								const std::string&		name,
    946 								const std::string&		description,
    947 								VkSampleCountFlagBits	rasterizationSamples)
    948 	: MultisampleTest	(testContext, name, description, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD)
    949 {
    950 }
    951 
    952 TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context&										context,
    953 															 VkPrimitiveTopology							topology,
    954 															 const std::vector<Vertex4RGBA>&				vertices,
    955 															 const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
    956 															 const VkPipelineColorBlendAttachmentState&		colorBlendState) const
    957 {
    958 	return new AlphaToOneInstance(context, topology, vertices, multisampleStateParams, colorBlendState);
    959 }
    960 
    961 VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples)
    962 {
    963 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
    964 	{
    965 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
    966 		DE_NULL,													// const void*								pNext;
    967 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
    968 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
    969 		false,														// VkBool32									sampleShadingEnable;
    970 		0.0f,														// float									minSampleShading;
    971 		DE_NULL,													// const VkSampleMask*						pSampleMask;
    972 		false,														// VkBool32									alphaToCoverageEnable;
    973 		true														// VkBool32									alphaToOneEnable;
    974 	};
    975 
    976 	return multisampleStateParams;
    977 }
    978 
    979 VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void)
    980 {
    981 	const VkPipelineColorBlendAttachmentState colorBlendState =
    982 	{
    983 		true,														// VkBool32					blendEnable;
    984 		VK_BLEND_FACTOR_SRC_ALPHA,									// VkBlendFactor			srcColorBlendFactor;
    985 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,						// VkBlendFactor			dstColorBlendFactor;
    986 		VK_BLEND_OP_ADD,											// VkBlendOp				colorBlendOp;
    987 		VK_BLEND_FACTOR_SRC_ALPHA,									// VkBlendFactor			srcAlphaBlendFactor;
    988 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,						// VkBlendFactor			dstAlphaBlendFactor;
    989 		VK_BLEND_OP_ADD,											// VkBlendOp				alphaBlendOp;
    990 		VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |		// VkColorComponentFlags	colorWriteMask;
    991 			VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
    992 	};
    993 
    994 	return colorBlendState;
    995 }
    996 
    997 
    998 // AlphaToCoverageTest
    999 
   1000 AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext&			testContext,
   1001 										  const std::string&		name,
   1002 										  const std::string&		description,
   1003 										  VkSampleCountFlagBits		rasterizationSamples,
   1004 										  GeometryType				geometryType)
   1005 	: MultisampleTest	(testContext, name, description, getAlphaToCoverageStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType)
   1006 	, m_geometryType	(geometryType)
   1007 {
   1008 }
   1009 
   1010 TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context&										context,
   1011 																  VkPrimitiveTopology							topology,
   1012 																  const std::vector<Vertex4RGBA>&				vertices,
   1013 																  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
   1014 																  const VkPipelineColorBlendAttachmentState&	colorBlendState) const
   1015 {
   1016 	return new AlphaToCoverageInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType);
   1017 }
   1018 
   1019 VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples)
   1020 {
   1021 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
   1022 	{
   1023 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
   1024 		DE_NULL,													// const void*								pNext;
   1025 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
   1026 		rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
   1027 		false,														// VkBool32									sampleShadingEnable;
   1028 		0.0f,														// float									minSampleShading;
   1029 		DE_NULL,													// const VkSampleMask*						pSampleMask;
   1030 		true,														// VkBool32									alphaToCoverageEnable;
   1031 		false														// VkBool32									alphaToOneEnable;
   1032 	};
   1033 
   1034 	return multisampleStateParams;
   1035 }
   1036 
   1037 // RasterizationSamplesInstance
   1038 
   1039 RasterizationSamplesInstance::RasterizationSamplesInstance (Context&										context,
   1040 															VkPrimitiveTopology								topology,
   1041 															const std::vector<Vertex4RGBA>&					vertices,
   1042 															const VkPipelineMultisampleStateCreateInfo&		multisampleStateParams,
   1043 															const VkPipelineColorBlendAttachmentState&		blendState,
   1044 															const TestModeFlags								modeFlags)
   1045 	: vkt::TestInstance		(context)
   1046 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
   1047 	, m_renderSize			(32, 32)
   1048 	, m_primitiveTopology	(topology)
   1049 	, m_vertices			(vertices)
   1050 	, m_fullQuadVertices	(generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH))
   1051 	, m_modeFlags			(modeFlags)
   1052 {
   1053 	if (m_modeFlags != 0)
   1054 	{
   1055 		const bool		useDepth			= (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0;
   1056 		const bool		useStencil			= (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0;
   1057 		const VkFormat	depthStencilFormat	= findSupportedDepthStencilFormat(context, useDepth, useStencil);
   1058 
   1059 		if (depthStencilFormat == VK_FORMAT_UNDEFINED)
   1060 			TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported");
   1061 
   1062 		const VkPrimitiveTopology		pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };
   1063 		const std::vector<Vertex4RGBA>	pVertices[2] = { m_vertices, m_fullQuadVertices };
   1064 
   1065 		m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
   1066 			new MultisampleRenderer(
   1067 				context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE));
   1068 	}
   1069 	else
   1070 	{
   1071 		m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
   1072 			new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE));
   1073 	}
   1074 }
   1075 
   1076 tcu::TestStatus RasterizationSamplesInstance::iterate (void)
   1077 {
   1078 	de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render());
   1079 	return verifyImage(level->getAccess());
   1080 }
   1081 
   1082 tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
   1083 {
   1084 	// Verify range of unique pixels
   1085 	{
   1086 		const deUint32	numUniqueColors = getUniqueColorsCount(result);
   1087 		const deUint32	minUniqueColors	= 3;
   1088 
   1089 		tcu::TestLog& log = m_context.getTestContext().getLog();
   1090 
   1091 		log << tcu::TestLog::Message
   1092 			<< "\nMin. unique colors expected: " << minUniqueColors << "\n"
   1093 			<< "Unique colors found: " << numUniqueColors << "\n"
   1094 			<< tcu::TestLog::EndMessage;
   1095 
   1096 		if (numUniqueColors < minUniqueColors)
   1097 			return tcu::TestStatus::fail("Unique colors out of expected bounds");
   1098 	}
   1099 
   1100 	// Verify shape of the rendered primitive (fuzzy-compare)
   1101 	{
   1102 		const tcu::TextureFormat	tcuColorFormat	= mapVkFormat(m_colorFormat);
   1103 		const tcu::TextureFormat	tcuDepthFormat	= tcu::TextureFormat();
   1104 		const ColorVertexShader		vertexShader;
   1105 		const ColorFragmentShader	fragmentShader	(tcuColorFormat, tcuDepthFormat);
   1106 		const rr::Program			program			(&vertexShader, &fragmentShader);
   1107 		ReferenceRenderer			refRenderer		(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
   1108 		rr::RenderState				renderState		(refRenderer.getViewportState());
   1109 
   1110 		if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
   1111 		{
   1112 			VkPhysicalDeviceProperties deviceProperties;
   1113 
   1114 			m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
   1115 
   1116 			// gl_PointSize is clamped to pointSizeRange
   1117 			renderState.point.pointSize = deFloatMin(3.0f, deviceProperties.limits.pointSizeRange[1]);
   1118 		}
   1119 
   1120 		if (m_modeFlags == 0)
   1121 		{
   1122 			refRenderer.colorClear(tcu::Vec4(0.0f));
   1123 			refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
   1124 		}
   1125 		else
   1126 		{
   1127 			// For depth/stencil case the primitive is invisible and the surroundings are filled red.
   1128 			refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
   1129 			refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
   1130 		}
   1131 
   1132 		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT))
   1133 			return tcu::TestStatus::fail("Primitive has unexpected shape");
   1134 	}
   1135 
   1136 	return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds");
   1137 }
   1138 
   1139 
   1140 // MinSampleShadingInstance
   1141 
   1142 MinSampleShadingInstance::MinSampleShadingInstance (Context&									context,
   1143 													VkPrimitiveTopology							topology,
   1144 													const std::vector<Vertex4RGBA>&				vertices,
   1145 													const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
   1146 													const VkPipelineColorBlendAttachmentState&	colorBlendState)
   1147 	: vkt::TestInstance			(context)
   1148 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
   1149 	, m_renderSize				(32, 32)
   1150 	, m_primitiveTopology		(topology)
   1151 	, m_vertices				(vertices)
   1152 	, m_multisampleStateParams	(multisampleStateParams)
   1153 	, m_colorBlendState			(colorBlendState)
   1154 {
   1155 	VkPhysicalDeviceFeatures deviceFeatures;
   1156 
   1157 	m_context.getInstanceInterface().getPhysicalDeviceFeatures(m_context.getPhysicalDevice(), &deviceFeatures);
   1158 
   1159 	if (!deviceFeatures.sampleRateShading)
   1160 		throw tcu::NotSupportedError("Sample shading is not supported");
   1161 }
   1162 
   1163 tcu::TestStatus MinSampleShadingInstance::iterate (void)
   1164 {
   1165 	de::MovePtr<tcu::TextureLevel>	noSampleshadingImage;
   1166 	std::vector<tcu::TextureLevel>	sampleShadedImages;
   1167 
   1168 	// Render and resolve without sample shading
   1169 	{
   1170 		VkPipelineMultisampleStateCreateInfo multisampleStateParms = m_multisampleStateParams;
   1171 		multisampleStateParms.sampleShadingEnable	= VK_FALSE;
   1172 		multisampleStateParms.minSampleShading		= 0.0;
   1173 
   1174 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleStateParms, m_colorBlendState, RENDER_TYPE_RESOLVE);
   1175 		noSampleshadingImage  = renderer.render();
   1176 	}
   1177 
   1178 	// Render with test minSampleShading and collect per-sample images
   1179 	{
   1180 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES);
   1181 		renderer.render();
   1182 
   1183 		sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples);
   1184 		for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
   1185 		{
   1186 			sampleShadedImages[sampleId] = *renderer.getSingleSampledImage(sampleId);
   1187 		}
   1188 	}
   1189 
   1190 	// Log images
   1191 	{
   1192 		tcu::TestLog& testLog	= m_context.getTestContext().getLog();
   1193 
   1194 		testLog << tcu::TestLog::ImageSet("Images", "Images")
   1195 				<< tcu::TestLog::Image("noSampleshadingImage", "Image rendered without sample shading", noSampleshadingImage->getAccess());
   1196 
   1197 		for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
   1198 		{
   1199 			testLog << tcu::TestLog::Image("sampleShadedImage", "One sample of sample shaded image", sampleShadedImages[sampleId].getAccess());
   1200 		}
   1201 		testLog << tcu::TestLog::EndImageSet;
   1202 	}
   1203 
   1204 	return verifySampleShadedImage(sampleShadedImages, noSampleshadingImage->getAccess());
   1205 }
   1206 
   1207 tcu::TestStatus MinSampleShadingInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& noSampleshadingImage)
   1208 {
   1209 	const deUint32	pixelCount	= noSampleshadingImage.getWidth() * noSampleshadingImage.getHeight() * noSampleshadingImage.getDepth();
   1210 
   1211 	bool anyPixelCovered		= false;
   1212 
   1213 	for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
   1214 	{
   1215 		const deUint32 noSampleShadingValue = *((const deUint32*)noSampleshadingImage.getDataPtr() + pixelNdx);
   1216 
   1217 		if (noSampleShadingValue == 0)
   1218 		{
   1219 			// non-covered pixel, continue
   1220 			continue;
   1221 		}
   1222 		else
   1223 		{
   1224 			anyPixelCovered = true;
   1225 		}
   1226 
   1227 		int numNotCoveredSamples = 0;
   1228 
   1229 		std::map<deUint32, deUint32>	histogram; // map<pixel value, number of occurrences>
   1230 
   1231 		// Collect histogram of occurrences or each pixel across all samples
   1232 		for (size_t i = 0; i < sampleShadedImages.size(); ++i)
   1233 		{
   1234 			const deUint32 sampleShadedValue = *((const deUint32*)sampleShadedImages[i].getAccess().getDataPtr() + pixelNdx);
   1235 
   1236 			if (sampleShadedValue == 0)
   1237 			{
   1238 				numNotCoveredSamples++;
   1239 				continue;
   1240 			}
   1241 
   1242 			if (histogram.find(sampleShadedValue) != histogram.end())
   1243 				histogram[sampleShadedValue]++;
   1244 			else
   1245 				histogram[sampleShadedValue] = 1;
   1246 		}
   1247 
   1248 		if (numNotCoveredSamples == static_cast<int>(sampleShadedImages.size()))
   1249 		{
   1250 			return tcu::TestStatus::fail("Got uncovered pixel, where covered samples were expected");
   1251 		}
   1252 
   1253 		const int uniqueColorsCount				= (int)histogram.size();
   1254 		const int expectedUniqueSamplesCount	= static_cast<int>(m_multisampleStateParams.minSampleShading * static_cast<float>(sampleShadedImages.size()) + 0.5f);
   1255 
   1256 		if (uniqueColorsCount + numNotCoveredSamples < expectedUniqueSamplesCount)
   1257 		{
   1258 			return tcu::TestStatus::fail("Got less unique colors than requested through minSampleShading");
   1259 		}
   1260 	}
   1261 
   1262 	if (!anyPixelCovered)
   1263 	{
   1264 		return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShading");
   1265 	}
   1266 
   1267 	return tcu::TestStatus::pass("Got proper count of unique colors");
   1268 }
   1269 
   1270 SampleMaskInstance::SampleMaskInstance (Context&										context,
   1271 										VkPrimitiveTopology								topology,
   1272 										const std::vector<Vertex4RGBA>&					vertices,
   1273 										const VkPipelineMultisampleStateCreateInfo&		multisampleStateParams,
   1274 										const VkPipelineColorBlendAttachmentState&		blendState)
   1275 	: vkt::TestInstance			(context)
   1276 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
   1277 	, m_renderSize				(32, 32)
   1278 	, m_primitiveTopology		(topology)
   1279 	, m_vertices				(vertices)
   1280 	, m_multisampleStateParams	(multisampleStateParams)
   1281 	, m_colorBlendState			(blendState)
   1282 {
   1283 }
   1284 
   1285 tcu::TestStatus SampleMaskInstance::iterate (void)
   1286 {
   1287 	de::MovePtr<tcu::TextureLevel>				testSampleMaskImage;
   1288 	de::MovePtr<tcu::TextureLevel>				minSampleMaskImage;
   1289 	de::MovePtr<tcu::TextureLevel>				maxSampleMaskImage;
   1290 
   1291 	// Render with test flags
   1292 	{
   1293 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE);
   1294 		testSampleMaskImage = renderer.render();
   1295 	}
   1296 
   1297 	// Render with all flags off
   1298 	{
   1299 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
   1300 		const std::vector<VkSampleMask>			sampleMask			(multisampleParams.rasterizationSamples / 32, (VkSampleMask)0);
   1301 
   1302 		multisampleParams.pSampleMask = sampleMask.data();
   1303 
   1304 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE);
   1305 		minSampleMaskImage = renderer.render();
   1306 	}
   1307 
   1308 	// Render with all flags on
   1309 	{
   1310 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
   1311 		const std::vector<VkSampleMask>			sampleMask			(multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0));
   1312 
   1313 		multisampleParams.pSampleMask = sampleMask.data();
   1314 
   1315 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE);
   1316 		maxSampleMaskImage = renderer.render();
   1317 	}
   1318 
   1319 	return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess());
   1320 }
   1321 
   1322 tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage,
   1323 												 const tcu::ConstPixelBufferAccess& minSampleMaskImage,
   1324 												 const tcu::ConstPixelBufferAccess& maxSampleMaskImage)
   1325 {
   1326 	const deUint32	testColorCount	= getUniqueColorsCount(testSampleMaskImage);
   1327 	const deUint32	minColorCount	= getUniqueColorsCount(minSampleMaskImage);
   1328 	const deUint32	maxColorCount	= getUniqueColorsCount(maxSampleMaskImage);
   1329 
   1330 	tcu::TestLog& log = m_context.getTestContext().getLog();
   1331 
   1332 	log << tcu::TestLog::Message
   1333 		<< "\nColors found: " << testColorCount << "\n"
   1334 		<< "Min. colors expected: " << minColorCount << "\n"
   1335 		<< "Max. colors expected: " << maxColorCount << "\n"
   1336 		<< tcu::TestLog::EndMessage;
   1337 
   1338 	if (minColorCount > testColorCount || testColorCount > maxColorCount)
   1339 		return tcu::TestStatus::fail("Unique colors out of expected bounds");
   1340 	else
   1341 		return tcu::TestStatus::pass("Unique colors within expected bounds");
   1342 }
   1343 
   1344 tcu::TestStatus testRasterSamplesConsistency (Context& context, GeometryType geometryType)
   1345 {
   1346 	// Use triangle only.
   1347 	DE_UNREF(geometryType);
   1348 
   1349 	const VkSampleCountFlagBits samples[] =
   1350 	{
   1351 		VK_SAMPLE_COUNT_1_BIT,
   1352 		VK_SAMPLE_COUNT_2_BIT,
   1353 		VK_SAMPLE_COUNT_4_BIT,
   1354 		VK_SAMPLE_COUNT_8_BIT,
   1355 		VK_SAMPLE_COUNT_16_BIT,
   1356 		VK_SAMPLE_COUNT_32_BIT,
   1357 		VK_SAMPLE_COUNT_64_BIT
   1358 	};
   1359 
   1360 	const Vertex4RGBA vertexData[3] =
   1361 	{
   1362 		{
   1363 			tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
   1364 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
   1365 		},
   1366 		{
   1367 			tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
   1368 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
   1369 		},
   1370 		{
   1371 			tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
   1372 			tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
   1373 		}
   1374 	};
   1375 
   1376 	const std::vector<Vertex4RGBA>	vertices			(vertexData, vertexData + 3);
   1377 	deUint32						prevUniqueColors	= 2;
   1378 	int								renderCount			= 0;
   1379 
   1380 	// Do not render with 1 sample (start with samplesNdx = 1).
   1381 	for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
   1382 	{
   1383 		if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx]))
   1384 			continue;
   1385 
   1386 		const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
   1387 		{
   1388 			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
   1389 			DE_NULL,													// const void*								pNext;
   1390 			0u,															// VkPipelineMultisampleStateCreateFlags	flags;
   1391 			samples[samplesNdx],										// VkSampleCountFlagBits					rasterizationSamples;
   1392 			false,														// VkBool32									sampleShadingEnable;
   1393 			0.0f,														// float									minSampleShading;
   1394 			DE_NULL,													// const VkSampleMask*						pSampleMask;
   1395 			false,														// VkBool32									alphaToCoverageEnable;
   1396 			false														// VkBool32									alphaToOneEnable;
   1397 		};
   1398 
   1399 		MultisampleRenderer				renderer		(context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState(), RENDER_TYPE_RESOLVE);
   1400 		de::MovePtr<tcu::TextureLevel>	result			= renderer.render();
   1401 		const deUint32					uniqueColors	= getUniqueColorsCount(result->getAccess());
   1402 
   1403 		renderCount++;
   1404 
   1405 		if (prevUniqueColors > uniqueColors)
   1406 		{
   1407 			std::ostringstream message;
   1408 
   1409 			message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx];
   1410 			return tcu::TestStatus::fail(message.str());
   1411 		}
   1412 
   1413 		prevUniqueColors = uniqueColors;
   1414 	}
   1415 
   1416 	if (renderCount == 0)
   1417 		throw tcu::NotSupportedError("Multisampling is unsupported");
   1418 
   1419 	return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases");
   1420 }
   1421 
   1422 
   1423 // AlphaToOneInstance
   1424 
   1425 AlphaToOneInstance::AlphaToOneInstance (Context&									context,
   1426 										VkPrimitiveTopology							topology,
   1427 										const std::vector<Vertex4RGBA>&				vertices,
   1428 										const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
   1429 										const VkPipelineColorBlendAttachmentState&	blendState)
   1430 	: vkt::TestInstance			(context)
   1431 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
   1432 	, m_renderSize				(32, 32)
   1433 	, m_primitiveTopology		(topology)
   1434 	, m_vertices				(vertices)
   1435 	, m_multisampleStateParams	(multisampleStateParams)
   1436 	, m_colorBlendState			(blendState)
   1437 {
   1438 	VkPhysicalDeviceFeatures deviceFeatures;
   1439 
   1440 	context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &deviceFeatures);
   1441 
   1442 	if (!deviceFeatures.alphaToOne)
   1443 		throw tcu::NotSupportedError("Alpha-to-one is not supported");
   1444 }
   1445 
   1446 tcu::TestStatus AlphaToOneInstance::iterate	(void)
   1447 {
   1448 	DE_ASSERT(m_multisampleStateParams.alphaToOneEnable);
   1449 	DE_ASSERT(m_colorBlendState.blendEnable);
   1450 
   1451 	de::MovePtr<tcu::TextureLevel>	alphaOneImage;
   1452 	de::MovePtr<tcu::TextureLevel>	noAlphaOneImage;
   1453 
   1454 	// Render with blend enabled and alpha to one on
   1455 	{
   1456 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE);
   1457 		alphaOneImage = renderer.render();
   1458 	}
   1459 
   1460 	// Render with blend enabled and alpha to one off
   1461 	{
   1462 		VkPipelineMultisampleStateCreateInfo	multisampleParams	= m_multisampleStateParams;
   1463 		multisampleParams.alphaToOneEnable = false;
   1464 
   1465 		MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE);
   1466 		noAlphaOneImage = renderer.render();
   1467 	}
   1468 
   1469 	return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess());
   1470 }
   1471 
   1472 tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess&	alphaOneImage,
   1473 												 const tcu::ConstPixelBufferAccess&	noAlphaOneImage)
   1474 {
   1475 	for (int y = 0; y < m_renderSize.y(); y++)
   1476 	{
   1477 		for (int x = 0; x < m_renderSize.x(); x++)
   1478 		{
   1479 			if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y))))
   1480 			{
   1481 				std::ostringstream message;
   1482 				message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y);
   1483 				return tcu::TestStatus::fail(message.str());
   1484 			}
   1485 		}
   1486 	}
   1487 
   1488 	return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one");
   1489 }
   1490 
   1491 
   1492 // AlphaToCoverageInstance
   1493 
   1494 AlphaToCoverageInstance::AlphaToCoverageInstance (Context&										context,
   1495 												  VkPrimitiveTopology							topology,
   1496 												  const std::vector<Vertex4RGBA>&				vertices,
   1497 												  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
   1498 												  const VkPipelineColorBlendAttachmentState&	blendState,
   1499 												  GeometryType									geometryType)
   1500 	: vkt::TestInstance			(context)
   1501 	, m_colorFormat				(VK_FORMAT_R8G8B8A8_UNORM)
   1502 	, m_renderSize				(32, 32)
   1503 	, m_primitiveTopology		(topology)
   1504 	, m_vertices				(vertices)
   1505 	, m_multisampleStateParams	(multisampleStateParams)
   1506 	, m_colorBlendState			(blendState)
   1507 	, m_geometryType			(geometryType)
   1508 {
   1509 }
   1510 
   1511 tcu::TestStatus AlphaToCoverageInstance::iterate (void)
   1512 {
   1513 	DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
   1514 
   1515 	de::MovePtr<tcu::TextureLevel>	result;
   1516 	MultisampleRenderer				renderer	(m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE);
   1517 
   1518 	result = renderer.render();
   1519 
   1520 	return verifyImage(result->getAccess());
   1521 }
   1522 
   1523 tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess&	result)
   1524 {
   1525 	float maxColorValue;
   1526 
   1527 	switch (m_geometryType)
   1528 	{
   1529 		case GEOMETRY_TYPE_OPAQUE_QUAD:
   1530 			maxColorValue = 1.01f;
   1531 			break;
   1532 
   1533 		case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
   1534 			maxColorValue = 0.52f;
   1535 			break;
   1536 
   1537 		case GEOMETRY_TYPE_INVISIBLE_QUAD:
   1538 			maxColorValue = 0.01f;
   1539 			break;
   1540 
   1541 		default:
   1542 			maxColorValue = 0.0f;
   1543 			DE_ASSERT(false);
   1544 	}
   1545 
   1546 	for (int y = 0; y < m_renderSize.y(); y++)
   1547 	{
   1548 		for (int x = 0; x < m_renderSize.x(); x++)
   1549 		{
   1550 			if (result.getPixel(x, y).x() > maxColorValue)
   1551 			{
   1552 				std::ostringstream message;
   1553 				message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")";
   1554 				return tcu::TestStatus::fail(message.str());
   1555 			}
   1556 		}
   1557 	}
   1558 
   1559 	return tcu::TestStatus::pass("Image matches reference value");
   1560 }
   1561 
   1562 
   1563 // MultisampleRenderer
   1564 
   1565 MultisampleRenderer::MultisampleRenderer (Context&										context,
   1566 										  const VkFormat								colorFormat,
   1567 										  const tcu::IVec2&								renderSize,
   1568 										  const VkPrimitiveTopology						topology,
   1569 										  const std::vector<Vertex4RGBA>&				vertices,
   1570 										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
   1571 										  const VkPipelineColorBlendAttachmentState&	blendState,
   1572 										  const RenderType								renderType)
   1573 	: m_context					(context)
   1574 	, m_colorFormat				(colorFormat)
   1575 	, m_depthStencilFormat		(VK_FORMAT_UNDEFINED)
   1576 	, m_renderSize				(renderSize)
   1577 	, m_useDepth				(false)
   1578 	, m_useStencil				(false)
   1579 	, m_multisampleStateParams	(multisampleStateParams)
   1580 	, m_colorBlendState			(blendState)
   1581 	, m_renderType				(renderType)
   1582 {
   1583 	initialize(context, 1u, &topology, &vertices);
   1584 }
   1585 
   1586 MultisampleRenderer::MultisampleRenderer (Context&										context,
   1587 										  const VkFormat								colorFormat,
   1588 										  const VkFormat								depthStencilFormat,
   1589 										  const tcu::IVec2&								renderSize,
   1590 										  const bool									useDepth,
   1591 										  const bool									useStencil,
   1592 										  const deUint32								numTopologies,
   1593 										  const VkPrimitiveTopology*					pTopology,
   1594 										  const std::vector<Vertex4RGBA>*				pVertices,
   1595 										  const VkPipelineMultisampleStateCreateInfo&	multisampleStateParams,
   1596 										  const VkPipelineColorBlendAttachmentState&	blendState,
   1597 										  const RenderType								renderType)
   1598 	: m_context					(context)
   1599 	, m_colorFormat				(colorFormat)
   1600 	, m_depthStencilFormat		(depthStencilFormat)
   1601 	, m_renderSize				(renderSize)
   1602 	, m_useDepth				(useDepth)
   1603 	, m_useStencil				(useStencil)
   1604 	, m_multisampleStateParams	(multisampleStateParams)
   1605 	, m_colorBlendState			(blendState)
   1606 	, m_renderType				(renderType)
   1607 {
   1608 	initialize(context, numTopologies, pTopology, pVertices);
   1609 }
   1610 
   1611 void MultisampleRenderer::initialize (Context&									context,
   1612 									  const deUint32							numTopologies,
   1613 									  const VkPrimitiveTopology*				pTopology,
   1614 									  const std::vector<Vertex4RGBA>*			pVertices)
   1615 {
   1616 	if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples))
   1617 		throw tcu::NotSupportedError("Unsupported number of rasterization samples");
   1618 
   1619 	const DeviceInterface&		vk						= context.getDeviceInterface();
   1620 	const VkDevice				vkDevice				= context.getDevice();
   1621 	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
   1622 	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
   1623 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
   1624 
   1625 	// Create color image
   1626 	{
   1627 
   1628 		const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
   1629 			(m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u);
   1630 
   1631 		const VkImageCreateInfo colorImageParams =
   1632 		{
   1633 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
   1634 			DE_NULL,																	// const void*				pNext;
   1635 			0u,																			// VkImageCreateFlags		flags;
   1636 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
   1637 			m_colorFormat,																// VkFormat					format;
   1638 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },				// VkExtent3D				extent;
   1639 			1u,																			// deUint32					mipLevels;
   1640 			1u,																			// deUint32					arrayLayers;
   1641 			m_multisampleStateParams.rasterizationSamples,								// VkSampleCountFlagBits	samples;
   1642 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
   1643 			imageUsageFlags,															// VkImageUsageFlags		usage;
   1644 			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
   1645 			1u,																			// deUint32					queueFamilyIndexCount;
   1646 			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
   1647 			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
   1648 		};
   1649 
   1650 		m_colorImage			= createImage(vk, vkDevice, &colorImageParams);
   1651 
   1652 		// Allocate and bind color image memory
   1653 		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
   1654 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
   1655 	}
   1656 
   1657 	// Create resolve image
   1658 	if (m_renderType == RENDER_TYPE_RESOLVE)
   1659 	{
   1660 		const VkImageCreateInfo resolveImageParams =
   1661 		{
   1662 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
   1663 			DE_NULL,																		// const void*				pNext;
   1664 			0u,																				// VkImageCreateFlags		flags;
   1665 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
   1666 			m_colorFormat,																	// VkFormat					format;
   1667 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
   1668 			1u,																				// deUint32					mipLevels;
   1669 			1u,																				// deUint32					arrayLayers;
   1670 			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
   1671 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
   1672 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |			// VkImageUsageFlags		usage;
   1673 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   1674 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
   1675 			1u,																				// deUint32					queueFamilyIndexCount;
   1676 			&queueFamilyIndex,																// const deUint32*			pQueueFamilyIndices;
   1677 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
   1678 		};
   1679 
   1680 		m_resolveImage = createImage(vk, vkDevice, &resolveImageParams);
   1681 
   1682 		// Allocate and bind resolve image memory
   1683 		m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any);
   1684 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset()));
   1685 
   1686 		// Create resolve attachment view
   1687 		{
   1688 			const VkImageViewCreateInfo resolveAttachmentViewParams =
   1689 			{
   1690 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
   1691 				DE_NULL,										// const void*				pNext;
   1692 				0u,												// VkImageViewCreateFlags	flags;
   1693 				*m_resolveImage,								// VkImage					image;
   1694 				VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
   1695 				m_colorFormat,									// VkFormat					format;
   1696 				componentMappingRGBA,							// VkComponentMapping		components;
   1697 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
   1698 			};
   1699 
   1700 			m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
   1701 		}
   1702 	}
   1703 
   1704 	// Create per-sample output images
   1705 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
   1706 	{
   1707 		const VkImageCreateInfo perSampleImageParams =
   1708 		{
   1709 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
   1710 			DE_NULL,																		// const void*				pNext;
   1711 			0u,																				// VkImageCreateFlags		flags;
   1712 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
   1713 			m_colorFormat,																	// VkFormat					format;
   1714 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
   1715 			1u,																				// deUint32					mipLevels;
   1716 			1u,																				// deUint32					arrayLayers;
   1717 			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
   1718 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
   1719 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |			// VkImageUsageFlags		usage;
   1720 			VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   1721 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
   1722 			1u,																				// deUint32					queueFamilyIndexCount;
   1723 			&queueFamilyIndex,																// const deUint32*			pQueueFamilyIndices;
   1724 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
   1725 		};
   1726 
   1727 		m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples));
   1728 
   1729 		for (size_t i = 0; i < m_perSampleImages.size(); ++i)
   1730 		{
   1731 			m_perSampleImages[i]	= de::SharedPtr<PerSampleImage>(new PerSampleImage);
   1732 			PerSampleImage& image	= *m_perSampleImages[i];
   1733 
   1734 			image.m_image			= createImage(vk, vkDevice, &perSampleImageParams);
   1735 
   1736 			// Allocate and bind image memory
   1737 			image.m_imageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any);
   1738 			VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset()));
   1739 
   1740 			// Create per-sample attachment view
   1741 			{
   1742 				const VkImageViewCreateInfo perSampleAttachmentViewParams =
   1743 				{
   1744 					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
   1745 					DE_NULL,										// const void*				pNext;
   1746 					0u,												// VkImageViewCreateFlags	flags;
   1747 					*image.m_image,									// VkImage					image;
   1748 					VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
   1749 					m_colorFormat,									// VkFormat					format;
   1750 					componentMappingRGBA,							// VkComponentMapping		components;
   1751 					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
   1752 				};
   1753 
   1754 				image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams);
   1755 			}
   1756 		}
   1757 	}
   1758 
   1759 	// Create a depth/stencil image
   1760 	if (m_useDepth || m_useStencil)
   1761 	{
   1762 		const VkImageCreateInfo depthStencilImageParams =
   1763 		{
   1764 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
   1765 			DE_NULL,																		// const void*				pNext;
   1766 			0u,																				// VkImageCreateFlags		flags;
   1767 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
   1768 			m_depthStencilFormat,															// VkFormat					format;
   1769 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },					// VkExtent3D				extent;
   1770 			1u,																				// deUint32					mipLevels;
   1771 			1u,																				// deUint32					arrayLayers;
   1772 			m_multisampleStateParams.rasterizationSamples,									// VkSampleCountFlagBits	samples;
   1773 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
   1774 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,									// VkImageUsageFlags		usage;
   1775 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
   1776 			1u,																				// deUint32					queueFamilyIndexCount;
   1777 			&queueFamilyIndex,																// const deUint32*			pQueueFamilyIndices;
   1778 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
   1779 		};
   1780 
   1781 		m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams);
   1782 
   1783 		// Allocate and bind depth/stencil image memory
   1784 		m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any);
   1785 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset()));
   1786 	}
   1787 
   1788 	// Create color attachment view
   1789 	{
   1790 		const VkImageViewCreateInfo colorAttachmentViewParams =
   1791 		{
   1792 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
   1793 			DE_NULL,										// const void*				pNext;
   1794 			0u,												// VkImageViewCreateFlags	flags;
   1795 			*m_colorImage,									// VkImage					image;
   1796 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
   1797 			m_colorFormat,									// VkFormat					format;
   1798 			componentMappingRGBA,							// VkComponentMapping		components;
   1799 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
   1800 		};
   1801 
   1802 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
   1803 	}
   1804 
   1805 	VkImageAspectFlags	depthStencilAttachmentAspect	= (VkImageAspectFlagBits)0;
   1806 
   1807 	// Create depth/stencil attachment view
   1808 	if (m_useDepth || m_useStencil)
   1809 	{
   1810 		depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat);
   1811 
   1812 		const VkImageViewCreateInfo depthStencilAttachmentViewParams =
   1813 		{
   1814 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
   1815 			DE_NULL,											// const void*				pNext;
   1816 			0u,													// VkImageViewCreateFlags	flags;
   1817 			*m_depthStencilImage,								// VkImage					image;
   1818 			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
   1819 			m_depthStencilFormat,								// VkFormat					format;
   1820 			componentMappingRGBA,								// VkComponentMapping		components;
   1821 			{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
   1822 		};
   1823 
   1824 		m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
   1825 	}
   1826 
   1827 	// Create render pass
   1828 	{
   1829 		std::vector<VkAttachmentDescription> attachmentDescriptions;
   1830 		{
   1831 			const VkAttachmentDescription colorAttachmentDescription =
   1832 			{
   1833 				0u,													// VkAttachmentDescriptionFlags		flags;
   1834 				m_colorFormat,										// VkFormat							format;
   1835 				m_multisampleStateParams.rasterizationSamples,		// VkSampleCountFlagBits			samples;
   1836 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
   1837 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
   1838 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
   1839 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
   1840 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
   1841 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
   1842 			};
   1843 			attachmentDescriptions.push_back(colorAttachmentDescription);
   1844 		}
   1845 
   1846 		deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED;
   1847 
   1848 		if (m_renderType == RENDER_TYPE_RESOLVE)
   1849 		{
   1850 			resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
   1851 
   1852 			const VkAttachmentDescription resolveAttachmentDescription =
   1853 			{
   1854 				0u,													// VkAttachmentDescriptionFlags		flags;
   1855 				m_colorFormat,										// VkFormat							format;
   1856 				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
   1857 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
   1858 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
   1859 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
   1860 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
   1861 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
   1862 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
   1863 			};
   1864 			attachmentDescriptions.push_back(resolveAttachmentDescription);
   1865 		}
   1866 
   1867 		deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED;
   1868 
   1869 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
   1870 		{
   1871 			perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
   1872 
   1873 			const VkAttachmentDescription perSampleAttachmentDescription =
   1874 			{
   1875 				0u,													// VkAttachmentDescriptionFlags		flags;
   1876 				m_colorFormat,										// VkFormat							format;
   1877 				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
   1878 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
   1879 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
   1880 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
   1881 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
   1882 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
   1883 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
   1884 			};
   1885 
   1886 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
   1887 			{
   1888 				attachmentDescriptions.push_back(perSampleAttachmentDescription);
   1889 			}
   1890 		}
   1891 
   1892 		deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
   1893 
   1894 		if (m_useDepth || m_useStencil)
   1895 		{
   1896 			depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
   1897 
   1898 			const VkAttachmentDescription depthStencilAttachmentDescription =
   1899 			{
   1900 				0u,																					// VkAttachmentDescriptionFlags		flags;
   1901 				m_depthStencilFormat,																// VkFormat							format;
   1902 				m_multisampleStateParams.rasterizationSamples,										// VkSampleCountFlagBits			samples;
   1903 				(m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentLoadOp				loadOp;
   1904 				(m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),		// VkAttachmentStoreOp				storeOp;
   1905 				(m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),		// VkAttachmentStoreOp				stencilLoadOp;
   1906 				(m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),	// VkAttachmentStoreOp				stencilStoreOp;
   1907 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,									// VkImageLayout					initialLayout;
   1908 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL									// VkImageLayout					finalLayout;
   1909 			};
   1910 			attachmentDescriptions.push_back(depthStencilAttachmentDescription);
   1911 		};
   1912 
   1913 		const VkAttachmentReference colorAttachmentReference =
   1914 		{
   1915 			0u,													// deUint32			attachment;
   1916 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
   1917 		};
   1918 
   1919 		const VkAttachmentReference inputAttachmentReference =
   1920 		{
   1921 			0u,													// deUint32			attachment;
   1922 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL			// VkImageLayout	layout;
   1923 		};
   1924 
   1925 		const VkAttachmentReference resolveAttachmentReference =
   1926 		{
   1927 			resolveAttachmentIndex,								// deUint32			attachment;
   1928 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
   1929 		};
   1930 
   1931 		std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size());
   1932 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
   1933 		{
   1934 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
   1935 			{
   1936 				const VkAttachmentReference perSampleAttachmentReference =
   1937 				{
   1938 					perSampleAttachmentIndex + static_cast<deUint32>(i),	// deUint32			attachment;
   1939 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL				// VkImageLayout	layout;
   1940 				};
   1941 				perSampleAttachmentReferences[i] = perSampleAttachmentReference;
   1942 			}
   1943 		}
   1944 
   1945 		const VkAttachmentReference depthStencilAttachmentReference =
   1946 		{
   1947 			depthStencilAttachmentIndex,						// deUint32			attachment;
   1948 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
   1949 		};
   1950 
   1951 		std::vector<VkSubpassDescription>	subpassDescriptions;
   1952 		std::vector<VkSubpassDependency>	subpassDependencies;
   1953 
   1954 		{
   1955 			const VkSubpassDescription renderSubpassDescription =
   1956 			{
   1957 				0u,																				// VkSubpassDescriptionFlags	flags;
   1958 				VK_PIPELINE_BIND_POINT_GRAPHICS,												// VkPipelineBindPoint			pipelineBindPoint;
   1959 				0u,																				// deUint32						inputAttachmentCount;
   1960 				DE_NULL,																		// const VkAttachmentReference*	pInputAttachments;
   1961 				1u,																				// deUint32						colorAttachmentCount;
   1962 				&colorAttachmentReference,														// const VkAttachmentReference*	pColorAttachments;
   1963 				(m_renderType == RENDER_TYPE_RESOLVE) ? &resolveAttachmentReference : DE_NULL,	// const VkAttachmentReference*	pResolveAttachments;
   1964 				(m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL),		// const VkAttachmentReference*	pDepthStencilAttachment;
   1965 				0u,																				// deUint32						preserveAttachmentCount;
   1966 				DE_NULL																			// const VkAttachmentReference*	pPreserveAttachments;
   1967 			};
   1968 			subpassDescriptions.push_back(renderSubpassDescription);
   1969 		}
   1970 
   1971 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
   1972 		{
   1973 
   1974 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
   1975 			{
   1976 				const VkSubpassDescription copySampleSubpassDescription =
   1977 				{
   1978 					0u,													// VkSubpassDescriptionFlags		flags;
   1979 					VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
   1980 					1u,													// deUint32							inputAttachmentCount;
   1981 					&inputAttachmentReference,							// const VkAttachmentReference*		pInputAttachments;
   1982 					1u,													// deUint32							colorAttachmentCount;
   1983 					&perSampleAttachmentReferences[i],					// const VkAttachmentReference*		pColorAttachments;
   1984 					DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
   1985 					DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
   1986 					0u,													// deUint32							preserveAttachmentCount;
   1987 					DE_NULL												// const VkAttachmentReference*		pPreserveAttachments;
   1988 				};
   1989 				subpassDescriptions.push_back(copySampleSubpassDescription);
   1990 
   1991 				const VkSubpassDependency copySampleSubpassDependency =
   1992 				{
   1993 					0u,													// deUint32							srcSubpass
   1994 					1u + static_cast<deUint32>(i),						// deUint32							dstSubpass
   1995 					VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,					// VkPipelineStageFlags				srcStageMask
   1996 					VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,				// VkPipelineStageFlags				dstStageMask
   1997 					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags					srcAccessMask
   1998 					VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,				// VkAccessFlags					dstAccessMask
   1999 					0u,													// VkDependencyFlags				dependencyFlags
   2000 				};
   2001 				subpassDependencies.push_back(copySampleSubpassDependency);
   2002 			}
   2003 		}
   2004 
   2005 		const VkRenderPassCreateInfo renderPassParams =
   2006 		{
   2007 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,					// VkStructureType					sType;
   2008 			DE_NULL,													// const void*						pNext;
   2009 			0u,															// VkRenderPassCreateFlags			flags;
   2010 			(deUint32)attachmentDescriptions.size(),					// deUint32							attachmentCount;
   2011 			&attachmentDescriptions[0],									// const VkAttachmentDescription*	pAttachments;
   2012 			(deUint32)subpassDescriptions.size(),						// deUint32							subpassCount;
   2013 			&subpassDescriptions[0],									// const VkSubpassDescription*		pSubpasses;
   2014 			(deUint32)subpassDependencies.size(),						// deUint32							dependencyCount;
   2015 			subpassDependencies.size() != 0 ? &subpassDependencies[0] : DE_NULL
   2016 		};
   2017 
   2018 		m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
   2019 	}
   2020 
   2021 	// Create framebuffer
   2022 	{
   2023 		std::vector<VkImageView> attachments;
   2024 		attachments.push_back(*m_colorAttachmentView);
   2025 		if (m_renderType == RENDER_TYPE_RESOLVE)
   2026 		{
   2027 			attachments.push_back(*m_resolveAttachmentView);
   2028 		}
   2029 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
   2030 		{
   2031 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
   2032 			{
   2033 				attachments.push_back(*m_perSampleImages[i]->m_attachmentView);
   2034 			}
   2035 		}
   2036 
   2037 		if (m_useDepth || m_useStencil)
   2038 		{
   2039 			attachments.push_back(*m_depthStencilAttachmentView);
   2040 		}
   2041 
   2042 		const VkFramebufferCreateInfo framebufferParams =
   2043 		{
   2044 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType					sType;
   2045 			DE_NULL,											// const void*						pNext;
   2046 			0u,													// VkFramebufferCreateFlags			flags;
   2047 			*m_renderPass,										// VkRenderPass						renderPass;
   2048 			(deUint32)attachments.size(),						// deUint32							attachmentCount;
   2049 			&attachments[0],									// const VkImageView*				pAttachments;
   2050 			(deUint32)m_renderSize.x(),							// deUint32							width;
   2051 			(deUint32)m_renderSize.y(),							// deUint32							height;
   2052 			1u													// deUint32							layers;
   2053 		};
   2054 
   2055 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
   2056 	}
   2057 
   2058 	// Create pipeline layout
   2059 	{
   2060 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
   2061 		{
   2062 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
   2063 			DE_NULL,											// const void*						pNext;
   2064 			0u,													// VkPipelineLayoutCreateFlags		flags;
   2065 			0u,													// deUint32							setLayoutCount;
   2066 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
   2067 			0u,													// deUint32							pushConstantRangeCount;
   2068 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
   2069 		};
   2070 
   2071 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
   2072 
   2073 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
   2074 		{
   2075 
   2076 			// Create descriptor set layout
   2077 			const VkDescriptorSetLayoutBinding		layoutBinding					=
   2078 			{
   2079 				0u,															// deUint32								binding;
   2080 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,						// VkDescriptorType						descriptorType;
   2081 				1u,															// deUint32								descriptorCount;
   2082 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlags					stageFlags;
   2083 				DE_NULL,													// const VkSampler*						pImmutableSamplers;
   2084 			};
   2085 
   2086 			const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutParams		=
   2087 			{
   2088 				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType
   2089 				DE_NULL,													// const void*							pNext
   2090 				0u,															// VkDescriptorSetLayoutCreateFlags		flags
   2091 				1u,															// deUint32								bindingCount
   2092 				&layoutBinding												// const VkDescriptorSetLayoutBinding*	pBindings
   2093 			};
   2094 			m_copySampleDesciptorLayout	= createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
   2095 
   2096 			// Create pipeline layout
   2097 
   2098 			const VkPushConstantRange				pushConstantRange				=
   2099 			{
   2100 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlags					stageFlags;
   2101 				0u,															// deUint32								offset;
   2102 				sizeof(deInt32)												// deUint32								size;
   2103 			};
   2104 			const VkPipelineLayoutCreateInfo		copySamplePipelineLayoutParams	=
   2105 			{
   2106 				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// VkStructureType						sType;
   2107 				DE_NULL,													// const void*							pNext;
   2108 				0u,															// VkPipelineLayoutCreateFlags			flags;
   2109 				1u,															// deUint32								setLayoutCount;
   2110 				&m_copySampleDesciptorLayout.get(),							// const VkDescriptorSetLayout*			pSetLayouts;
   2111 				1u,															// deUint32								pushConstantRangeCount;
   2112 				&pushConstantRange											// const VkPushConstantRange*			pPushConstantRanges;
   2113 			};
   2114 			m_copySamplePipelineLayout		= createPipelineLayout(vk, vkDevice, &copySamplePipelineLayoutParams);
   2115 		}
   2116 	}
   2117 
   2118 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
   2119 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
   2120 
   2121 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
   2122 	{
   2123 		m_copySampleVertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("quad_vert"), 0);
   2124 		m_copySampleFragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("copy_sample_frag"), 0);
   2125 	}
   2126 
   2127 	// Create pipeline
   2128 	{
   2129 		const VkPipelineShaderStageCreateInfo	shaderStageParams[2] =
   2130 		{
   2131 			{
   2132 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
   2133 				DE_NULL,													// const void*							pNext;
   2134 				0u,															// VkPipelineShaderStageCreateFlags		flags;
   2135 				VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits				stage;
   2136 				*m_vertexShaderModule,										// VkShaderModule						module;
   2137 				"main",														// const char*							pName;
   2138 				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
   2139 			},
   2140 			{
   2141 				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
   2142 				DE_NULL,													// const void*							pNext;
   2143 				0u,															// VkPipelineShaderStageCreateFlags		flags;
   2144 				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits				stage;
   2145 				*m_fragmentShaderModule,									// VkShaderModule						module;
   2146 				"main",														// const char*							pName;
   2147 				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
   2148 			}
   2149 		};
   2150 
   2151 		const VkVertexInputBindingDescription	vertexInputBindingDescription =
   2152 		{
   2153 			0u,									// deUint32				binding;
   2154 			sizeof(Vertex4RGBA),				// deUint32				stride;
   2155 			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputRate	inputRate;
   2156 		};
   2157 
   2158 		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
   2159 		{
   2160 			{
   2161 				0u,									// deUint32	location;
   2162 				0u,									// deUint32	binding;
   2163 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
   2164 				0u									// deUint32	offset;
   2165 			},
   2166 			{
   2167 				1u,									// deUint32	location;
   2168 				0u,									// deUint32	binding;
   2169 				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
   2170 				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offset;
   2171 			}
   2172 		};
   2173 
   2174 		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
   2175 		{
   2176 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
   2177 			DE_NULL,														// const void*								pNext;
   2178 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
   2179 			1u,																// deUint32									vertexBindingDescriptionCount;
   2180 			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
   2181 			2u,																// deUint32									vertexAttributeDescriptionCount;
   2182 			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
   2183 		};
   2184 
   2185 		// Topology is set before the pipeline creation.
   2186 		VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
   2187 		{
   2188 			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
   2189 			DE_NULL,														// const void*								pNext;
   2190 			0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
   2191 			VK_PRIMITIVE_TOPOLOGY_LAST,										// VkPrimitiveTopology						topology;
   2192 			false															// VkBool32									primitiveRestartEnable;
   2193 		};
   2194 
   2195 		const VkViewport viewport =
   2196 		{
   2197 			0.0f,						// float	x;
   2198 			0.0f,						// float	y;
   2199 			(float)m_renderSize.x(),	// float	width;
   2200 			(float)m_renderSize.y(),	// float	height;
   2201 			0.0f,						// float	minDepth;
   2202 			1.0f						// float	maxDepth;
   2203 		};
   2204 
   2205 		const VkRect2D scissor =
   2206 		{
   2207 			{ 0, 0 },													// VkOffset2D  offset;
   2208 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }	// VkExtent2D  extent;
   2209 		};
   2210 
   2211 		const VkPipelineViewportStateCreateInfo viewportStateParams =
   2212 		{
   2213 			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType						sType;
   2214 			DE_NULL,														// const void*							pNext;
   2215 			0u,																// VkPipelineViewportStateCreateFlags	flags;
   2216 			1u,																// deUint32								viewportCount;
   2217 			&viewport,														// const VkViewport*					pViewports;
   2218 			1u,																// deUint32								scissorCount;
   2219 			&scissor														// const VkRect2D*						pScissors;
   2220 		};
   2221 
   2222 		const VkPipelineRasterizationStateCreateInfo rasterStateParams =
   2223 		{
   2224 			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
   2225 			DE_NULL,														// const void*								pNext;
   2226 			0u,																// VkPipelineRasterizationStateCreateFlags	flags;
   2227 			false,															// VkBool32									depthClampEnable;
   2228 			false,															// VkBool32									rasterizerDiscardEnable;
   2229 			VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
   2230 			VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
   2231 			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
   2232 			VK_FALSE,														// VkBool32									depthBiasEnable;
   2233 			0.0f,															// float									depthBiasConstantFactor;
   2234 			0.0f,															// float									depthBiasClamp;
   2235 			0.0f,															// float									depthBiasSlopeFactor;
   2236 			1.0f															// float									lineWidth;
   2237 		};
   2238 
   2239 		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
   2240 		{
   2241 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
   2242 			DE_NULL,													// const void*									pNext;
   2243 			0u,															// VkPipelineColorBlendStateCreateFlags			flags;
   2244 			false,														// VkBool32										logicOpEnable;
   2245 			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
   2246 			1u,															// deUint32										attachmentCount;
   2247 			&m_colorBlendState,											// const VkPipelineColorBlendAttachmentState*	pAttachments;
   2248 			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
   2249 		};
   2250 
   2251 		const VkStencilOpState stencilOpState =
   2252 		{
   2253 			VK_STENCIL_OP_KEEP,						// VkStencilOp	failOp;
   2254 			VK_STENCIL_OP_REPLACE,					// VkStencilOp	passOp;
   2255 			VK_STENCIL_OP_KEEP,						// VkStencilOp	depthFailOp;
   2256 			VK_COMPARE_OP_GREATER,					// VkCompareOp	compareOp;
   2257 			1u,										// deUint32		compareMask;
   2258 			1u,										// deUint32		writeMask;
   2259 			1u,										// deUint32		reference;
   2260 		};
   2261 
   2262 		const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
   2263 		{
   2264 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
   2265 			DE_NULL,													// const void*								pNext;
   2266 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
   2267 			m_useDepth,													// VkBool32									depthTestEnable;
   2268 			m_useDepth,													// VkBool32									depthWriteEnable;
   2269 			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
   2270 			false,														// VkBool32									depthBoundsTestEnable;
   2271 			m_useStencil,												// VkBool32									stencilTestEnable;
   2272 			stencilOpState,												// VkStencilOpState	front;
   2273 			stencilOpState,												// VkStencilOpState	back;
   2274 			0.0f,														// float			minDepthBounds;
   2275 			1.0f,														// float			maxDepthBounds;
   2276 		};
   2277 
   2278 		const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
   2279 		{
   2280 			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
   2281 			DE_NULL,											// const void*										pNext;
   2282 			0u,													// VkPipelineCreateFlags							flags;
   2283 			2u,													// deUint32											stageCount;
   2284 			shaderStageParams,									// const VkPipelineShaderStageCreateInfo*			pStages;
   2285 			&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
   2286 			&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
   2287 			DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
   2288 			&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
   2289 			&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
   2290 			&m_multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
   2291 			&depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
   2292 			&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
   2293 			(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
   2294 			*m_pipelineLayout,									// VkPipelineLayout									layout;
   2295 			*m_renderPass,										// VkRenderPass										renderPass;
   2296 			0u,													// deUint32											subpass;
   2297 			0u,													// VkPipeline										basePipelineHandle;
   2298 			0u													// deInt32											basePipelineIndex;
   2299 		};
   2300 
   2301 		for (deUint32 i = 0u; i < numTopologies; ++i)
   2302 		{
   2303 			inputAssemblyStateParams.topology = pTopology[i];
   2304 			m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams))));
   2305 		}
   2306 	}
   2307 
   2308 	if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
   2309 	{
   2310 		// Create pipelines for copying samples to single sampled images
   2311 		{
   2312 			const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
   2313 			{
   2314 				{
   2315 					VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType							sType;
   2316 					DE_NULL,													// const void*								pNext;
   2317 					0u,															// VkPipelineShaderStageCreateFlags			flags;
   2318 					VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits					stage;
   2319 					*m_copySampleVertexShaderModule,							// VkShaderModule							module;
   2320 					"main",														// const char*								pName;
   2321 					DE_NULL														// const VkSpecializationInfo*				pSpecializationInfo;
   2322 				},
   2323 				{
   2324 					VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType							sType;
   2325 					DE_NULL,													// const void*								pNext;
   2326 					0u,															// VkPipelineShaderStageCreateFlags			flags;
   2327 					VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits					stage;
   2328 					*m_copySampleFragmentShaderModule,							// VkShaderModule							module;
   2329 					"main",														// const char*								pName;
   2330 					DE_NULL														// const VkSpecializationInfo*				pSpecializationInfo;
   2331 				}
   2332 			};
   2333 
   2334 			const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
   2335 			{
   2336 				VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
   2337 				DE_NULL,														// const void*								pNext;
   2338 				0u,																// VkPipelineVertexInputStateCreateFlags	flags;
   2339 				0u,																// deUint32									vertexBindingDescriptionCount;
   2340 				DE_NULL,														// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
   2341 				0u,																// deUint32									vertexAttributeDescriptionCount;
   2342 				DE_NULL															// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
   2343 			};
   2344 
   2345 			// Topology is set before the pipeline creation.
   2346 			VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
   2347 			{
   2348 				VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
   2349 				DE_NULL,														// const void*								pNext;
   2350 				0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
   2351 				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology						topology;
   2352 				false															// VkBool32									primitiveRestartEnable;
   2353 			};
   2354 
   2355 			const VkViewport viewport =
   2356 			{
   2357 				0.0f,						// float	x;
   2358 				0.0f,						// float	y;
   2359 				(float)m_renderSize.x(),	// float	width;
   2360 				(float)m_renderSize.y(),	// float	height;
   2361 				0.0f,						// float	minDepth;
   2362 				1.0f						// float	maxDepth;
   2363 			};
   2364 
   2365 			const VkRect2D scissor =
   2366 			{
   2367 				{ 0, 0 },													// VkOffset2D  offset;
   2368 				{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }	// VkExtent2D  extent;
   2369 			};
   2370 
   2371 			const VkPipelineViewportStateCreateInfo viewportStateParams =
   2372 			{
   2373 				VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType							sType;
   2374 				DE_NULL,														// const void*								pNext;
   2375 				0u,																// VkPipelineViewportStateCreateFlags		flags;
   2376 				1u,																// deUint32									viewportCount;
   2377 				&viewport,														// const VkViewport*						pViewports;
   2378 				1u,																// deUint32									scissorCount;
   2379 				&scissor														// const VkRect2D*							pScissors;
   2380 			};
   2381 
   2382 			const VkPipelineRasterizationStateCreateInfo rasterStateParams =
   2383 			{
   2384 				VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
   2385 				DE_NULL,														// const void*								pNext;
   2386 				0u,																// VkPipelineRasterizationStateCreateFlags	flags;
   2387 				false,															// VkBool32									depthClampEnable;
   2388 				false,															// VkBool32									rasterizerDiscardEnable;
   2389 				VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
   2390 				VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
   2391 				VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
   2392 				VK_FALSE,														// VkBool32									depthBiasEnable;
   2393 				0.0f,															// float									depthBiasConstantFactor;
   2394 				0.0f,															// float									depthBiasClamp;
   2395 				0.0f,															// float									depthBiasSlopeFactor;
   2396 				1.0f															// float									lineWidth;
   2397 			};
   2398 
   2399 			const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
   2400 			{
   2401 				VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
   2402 				DE_NULL,													// const void*									pNext;
   2403 				0u,															// VkPipelineColorBlendStateCreateFlags			flags;
   2404 				false,														// VkBool32										logicOpEnable;
   2405 				VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
   2406 				1u,															// deUint32										attachmentCount;
   2407 				&m_colorBlendState,											// const VkPipelineColorBlendAttachmentState*	pAttachments;
   2408 				{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
   2409 			};
   2410 
   2411 			const  VkPipelineMultisampleStateCreateInfo multisampleStateParams =
   2412 			{
   2413 				VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType
   2414 				DE_NULL,													// const void*								pNext
   2415 				0u,															// VkPipelineMultisampleStateCreateFlags	flags
   2416 				VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples
   2417 				VK_FALSE,													// VkBool32									sampleShadingEnable
   2418 				0.0f,														// float									minSampleShading
   2419 				DE_NULL,													// const VkSampleMask*						pSampleMask
   2420 				VK_FALSE,													// VkBool32									alphaToCoverageEnable
   2421 				VK_FALSE,													// VkBool32									alphaToOneEnable
   2422 			};
   2423 
   2424 			const VkGraphicsPipelineCreateInfo graphicsPipelineTemplate =
   2425 			{
   2426 				VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
   2427 				DE_NULL,											// const void*										pNext;
   2428 				0u,													// VkPipelineCreateFlags							flags;
   2429 				2u,													// deUint32											stageCount;
   2430 				shaderStageParams,									// const VkPipelineShaderStageCreateInfo*			pStages;
   2431 				&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
   2432 				&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
   2433 				DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
   2434 				&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
   2435 				&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
   2436 				&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
   2437 				DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
   2438 				&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
   2439 				(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
   2440 				*m_copySamplePipelineLayout,						// VkPipelineLayout									layout;
   2441 				*m_renderPass,										// VkRenderPass										renderPass;
   2442 				0u,													// deUint32											subpass;
   2443 				0u,													// VkPipeline										basePipelineHandle;
   2444 				0u													// deInt32											basePipelineIndex;
   2445 			};
   2446 
   2447 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
   2448 			{
   2449 				VkGraphicsPipelineCreateInfo graphicsPipelineParams = graphicsPipelineTemplate;
   2450 
   2451 				// Pipeline is to be used in subpasses subsequent to sample-shading subpass
   2452 				graphicsPipelineParams.subpass = 1u + (deUint32)i;
   2453 
   2454 				m_copySamplePipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams))));
   2455 			}
   2456 		}
   2457 
   2458 
   2459 		const VkDescriptorPoolSize			descriptorPoolSize			=
   2460 		{
   2461 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,					// VkDescriptorType					type;
   2462 			1u														// deUint32							descriptorCount;
   2463 		};
   2464 
   2465 		const VkDescriptorPoolCreateInfo	descriptorPoolCreateInfo	=
   2466 		{
   2467 			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,			// VkStructureType					sType
   2468 			DE_NULL,												// const void*						pNext
   2469 			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,		// VkDescriptorPoolCreateFlags		flags
   2470 			1u,													// deUint32							maxSets
   2471 			1u,														// deUint32							poolSizeCount
   2472 			&descriptorPoolSize										// const VkDescriptorPoolSize*		pPoolSizes
   2473 		};
   2474 
   2475 		m_copySampleDesciptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
   2476 
   2477 		const VkDescriptorSetAllocateInfo	descriptorSetAllocateInfo	=
   2478 		{
   2479 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,			// VkStructureType					sType
   2480 			DE_NULL,												// const void*						pNext
   2481 			*m_copySampleDesciptorPool,								// VkDescriptorPool					descriptorPool
   2482 			1u,														// deUint32							descriptorSetCount
   2483 			&m_copySampleDesciptorLayout.get(),						// const VkDescriptorSetLayout*		pSetLayouts
   2484 		};
   2485 
   2486 		m_copySampleDesciptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
   2487 
   2488 		const VkDescriptorImageInfo			imageInfo					=
   2489 		{
   2490 			DE_NULL,
   2491 			*m_colorAttachmentView,
   2492 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
   2493 		};
   2494 		const VkWriteDescriptorSet			descriptorWrite				=
   2495 		{
   2496 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,			// VkStructureType					sType;
   2497 			DE_NULL,										// const void*						pNext;
   2498 			*m_copySampleDesciptorSet,						// VkDescriptorSet					dstSet;
   2499 			0u,												// deUint32							dstBinding;
   2500 			0u,												// deUint32							dstArrayElement;
   2501 			1u,												// deUint32							descriptorCount;
   2502 			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			// VkDescriptorType					descriptorType;
   2503 			&imageInfo,										// const VkDescriptorImageInfo*		pImageInfo;
   2504 			DE_NULL,										// const VkDescriptorBufferInfo*	pBufferInfo;
   2505 			DE_NULL,										// const VkBufferView*				pTexelBufferView;
   2506 		};
   2507 		vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
   2508 	}
   2509 
   2510 	// Create vertex buffer
   2511 	{
   2512 		const VkBufferCreateInfo vertexBufferParams =
   2513 		{
   2514 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
   2515 			DE_NULL,									// const void*			pNext;
   2516 			0u,											// VkBufferCreateFlags	flags;
   2517 			1024u,										// VkDeviceSize			size;
   2518 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
   2519 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
   2520 			1u,											// deUint32				queueFamilyIndexCount;
   2521 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
   2522 		};
   2523 
   2524 		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
   2525 		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
   2526 
   2527 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
   2528 
   2529 		// Load vertices into vertex buffer
   2530 		{
   2531 			Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr());
   2532 			for (deUint32 i = 0u; i < numTopologies; ++i)
   2533 			{
   2534 				deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA));
   2535 				pDst += pVertices[i].size();
   2536 			}
   2537 		}
   2538 		flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
   2539 	}
   2540 
   2541 	// Create command pool
   2542 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
   2543 
   2544 	// Create command buffer
   2545 	{
   2546 		const VkCommandBufferBeginInfo cmdBufferBeginInfo =
   2547 		{
   2548 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
   2549 			DE_NULL,										// const void*						pNext;
   2550 			0u,												// VkCommandBufferUsageFlags		flags;
   2551 			(const VkCommandBufferInheritanceInfo*)DE_NULL,
   2552 		};
   2553 
   2554 		VkClearValue colorClearValue;
   2555 		colorClearValue.color.float32[0] = 0.0f;
   2556 		colorClearValue.color.float32[1] = 0.0f;
   2557 		colorClearValue.color.float32[2] = 0.0f;
   2558 		colorClearValue.color.float32[3] = 0.0f;
   2559 
   2560 		VkClearValue depthStencilClearValue;
   2561 		depthStencilClearValue.depthStencil.depth = 1.0f;
   2562 		depthStencilClearValue.depthStencil.stencil = 0u;
   2563 
   2564 		std::vector<VkClearValue> clearValues;
   2565 		clearValues.push_back(colorClearValue);
   2566 		if (m_renderType == RENDER_TYPE_RESOLVE)
   2567 		{
   2568 			clearValues.push_back(colorClearValue);
   2569 		}
   2570 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
   2571 		{
   2572 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
   2573 			{
   2574 				clearValues.push_back(colorClearValue);
   2575 			}
   2576 		}
   2577 		if (m_useDepth || m_useStencil)
   2578 		{
   2579 			clearValues.push_back(depthStencilClearValue);
   2580 		}
   2581 
   2582 		const VkRenderPassBeginInfo renderPassBeginInfo =
   2583 		{
   2584 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
   2585 			DE_NULL,												// const void*			pNext;
   2586 			*m_renderPass,											// VkRenderPass			renderPass;
   2587 			*m_framebuffer,											// VkFramebuffer		framebuffer;
   2588 			{
   2589 				{ 0, 0 },
   2590 				{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }
   2591 			},														// VkRect2D				renderArea;
   2592 			(deUint32)clearValues.size(),							// deUint32				clearValueCount;
   2593 			&clearValues[0]											// const VkClearValue*	pClearValues;
   2594 		};
   2595 
   2596 		std::vector<VkImageMemoryBarrier> imageLayoutBarriers;
   2597 
   2598 		{
   2599 			const VkImageMemoryBarrier colorImageBarrier =
   2600 				// color attachment image
   2601 			{
   2602 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
   2603 				DE_NULL,										// const void*				pNext;
   2604 				0u,												// VkAccessFlags			srcAccessMask;
   2605 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
   2606 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
   2607 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
   2608 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
   2609 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
   2610 				*m_colorImage,									// VkImage					image;
   2611 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
   2612 			};
   2613 			imageLayoutBarriers.push_back(colorImageBarrier);
   2614 		}
   2615 		if (m_renderType == RENDER_TYPE_RESOLVE)
   2616 		{
   2617 			const VkImageMemoryBarrier resolveImageBarrier =
   2618 			// resolve attachment image
   2619 			{
   2620 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
   2621 				DE_NULL,										// const void*				pNext;
   2622 				0u,												// VkAccessFlags			srcAccessMask;
   2623 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
   2624 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
   2625 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
   2626 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
   2627 				VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
   2628 				*m_resolveImage,								// VkImage					image;
   2629 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
   2630 			};
   2631 			imageLayoutBarriers.push_back(resolveImageBarrier);
   2632 		}
   2633 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
   2634 		{
   2635 			for (size_t i = 0; i < m_perSampleImages.size(); ++i)
   2636 			{
   2637 				const VkImageMemoryBarrier perSampleImageBarrier =
   2638 				// resolve attachment image
   2639 				{
   2640 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
   2641 					DE_NULL,										// const void*				pNext;
   2642 					0u,												// VkAccessFlags			srcAccessMask;
   2643 					VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
   2644 					VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
   2645 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout;
   2646 					VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
   2647 					VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
   2648 					*m_perSampleImages[i]->m_image,					// VkImage					image;
   2649 					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
   2650 				};
   2651 				imageLayoutBarriers.push_back(perSampleImageBarrier);
   2652 			}
   2653 		}
   2654 		if (m_useDepth || m_useStencil)
   2655 		{
   2656 			const VkImageMemoryBarrier depthStencilImageBarrier =
   2657 			// depth/stencil attachment image
   2658 			{
   2659 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
   2660 				DE_NULL,											// const void*				pNext;
   2661 				0u,													// VkAccessFlags			srcAccessMask;
   2662 				VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
   2663 				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
   2664 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
   2665 				VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
   2666 				VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
   2667 				*m_depthStencilImage,								// VkImage					image;
   2668 				{ depthStencilAttachmentAspect, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
   2669 			};
   2670 			imageLayoutBarriers.push_back(depthStencilImageBarrier);
   2671 		};
   2672 
   2673 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
   2674 
   2675 		VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
   2676 
   2677 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
   2678 			0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), &imageLayoutBarriers[0]);
   2679 
   2680 		vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
   2681 
   2682 		VkDeviceSize vertexBufferOffset = 0u;
   2683 
   2684 		for (deUint32 i = 0u; i < numTopologies; ++i)
   2685 		{
   2686 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[i]);
   2687 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
   2688 			vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0);
   2689 
   2690 			vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA));
   2691 		}
   2692 
   2693 		if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
   2694 		{
   2695 			// Copy each sample id to single sampled image
   2696 			for (deInt32 sampleId = 0; sampleId < (deInt32)m_perSampleImages.size(); ++sampleId)
   2697 			{
   2698 				vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
   2699 				vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_copySamplePipelines[sampleId]);
   2700 				vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_copySamplePipelineLayout, 0u, 1u, &m_copySampleDesciptorSet.get(), 0u, DE_NULL);
   2701 				vk.cmdPushConstants(*m_cmdBuffer, *m_copySamplePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &sampleId);
   2702 				vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
   2703 			}
   2704 		}
   2705 
   2706 		vk.cmdEndRenderPass(*m_cmdBuffer);
   2707 
   2708 		VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
   2709 	}
   2710 
   2711 	// Create fence
   2712 	m_fence = createFence(vk, vkDevice);
   2713 }
   2714 
   2715 MultisampleRenderer::~MultisampleRenderer (void)
   2716 {
   2717 }
   2718 
   2719 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void)
   2720 {
   2721 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
   2722 	const VkDevice				vkDevice			= m_context.getDevice();
   2723 	const VkQueue				queue				= m_context.getUniversalQueue();
   2724 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
   2725 	SimpleAllocator				allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
   2726 	const VkSubmitInfo			submitInfo	=
   2727 	{
   2728 		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
   2729 		DE_NULL,						// const void*				pNext;
   2730 		0u,								// deUint32					waitSemaphoreCount;
   2731 		DE_NULL,						// const VkSemaphore*		pWaitSemaphores;
   2732 		(const VkPipelineStageFlags*)DE_NULL,
   2733 		1u,								// deUint32					commandBufferCount;
   2734 		&m_cmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
   2735 		0u,								// deUint32					signalSemaphoreCount;
   2736 		DE_NULL							// const VkSemaphore*		pSignalSemaphores;
   2737 	};
   2738 
   2739 	VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
   2740 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
   2741 	VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
   2742 
   2743 	if (m_renderType == RENDER_TYPE_RESOLVE)
   2744 	{
   2745 		return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
   2746 	}
   2747 	else
   2748 	{
   2749 		return de::MovePtr<tcu::TextureLevel>();
   2750 	}
   2751 }
   2752 
   2753 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::getSingleSampledImage (deUint32 sampleId)
   2754 {
   2755 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
   2756 	const VkDevice				vkDevice			= m_context.getDevice();
   2757 	const VkQueue				queue				= m_context.getUniversalQueue();
   2758 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
   2759 	SimpleAllocator				allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
   2760 
   2761 	return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_perSampleImages[sampleId]->m_image, m_colorFormat, m_renderSize.cast<deUint32>());
   2762 }
   2763 
   2764 } // anonymous
   2765 
   2766 tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx)
   2767 {
   2768 	const VkSampleCountFlagBits samples[] =
   2769 	{
   2770 		VK_SAMPLE_COUNT_2_BIT,
   2771 		VK_SAMPLE_COUNT_4_BIT,
   2772 		VK_SAMPLE_COUNT_8_BIT,
   2773 		VK_SAMPLE_COUNT_16_BIT,
   2774 		VK_SAMPLE_COUNT_32_BIT,
   2775 		VK_SAMPLE_COUNT_64_BIT
   2776 	};
   2777 
   2778 	de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, "multisample", ""));
   2779 
   2780 	// Rasterization samples tests
   2781 	{
   2782 		de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", ""));
   2783 
   2784 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
   2785 		{
   2786 			std::ostringstream caseName;
   2787 			caseName << "samples_" << samples[samplesNdx];
   2788 
   2789 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
   2790 
   2791 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "",	samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE));
   2792 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE));
   2793 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "",		samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT));
   2794 
   2795 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_DEPTH_BIT));
   2796 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "",			samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_STENCIL_BIT));
   2797 			samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil", "",	samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT));
   2798 
   2799 			rasterizationSamplesTests->addChild(samplesTests.release());
   2800 		}
   2801 
   2802 		multisampleTests->addChild(rasterizationSamplesTests.release());
   2803 	}
   2804 
   2805 	// Raster samples consistency check
   2806 	{
   2807 		de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests(new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", ""));
   2808 
   2809 		addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
   2810 									"unique_colors_check",
   2811 									"",
   2812 									initMultisamplePrograms,
   2813 									testRasterSamplesConsistency,
   2814 									GEOMETRY_TYPE_OPAQUE_TRIANGLE);
   2815 
   2816 		multisampleTests->addChild(rasterSamplesConsistencyTests.release());
   2817 	}
   2818 
   2819 	// minSampleShading tests
   2820 	{
   2821 		struct TestConfig
   2822 		{
   2823 			const char*	name;
   2824 			float		minSampleShading;
   2825 		};
   2826 
   2827 		const TestConfig testConfigs[] =
   2828 		{
   2829 			{ "min_0_0",	0.0f },
   2830 			{ "min_0_25",	0.25f },
   2831 			{ "min_0_5",	0.5f },
   2832 			{ "min_0_75",	0.75f },
   2833 			{ "min_1_0",	1.0f }
   2834 		};
   2835 
   2836 		de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", ""));
   2837 
   2838 		for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
   2839 		{
   2840 			const TestConfig&				testConfig				= testConfigs[configNdx];
   2841 			de::MovePtr<tcu::TestCaseGroup>	minShadingValueTests	(new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
   2842 
   2843 			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
   2844 			{
   2845 				std::ostringstream caseName;
   2846 				caseName << "samples_" << samples[samplesNdx];
   2847 
   2848 				de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
   2849 
   2850 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE));
   2851 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE));
   2852 				samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT));
   2853 
   2854 				minShadingValueTests->addChild(samplesTests.release());
   2855 			}
   2856 
   2857 			minSampleShadingTests->addChild(minShadingValueTests.release());
   2858 		}
   2859 
   2860 		multisampleTests->addChild(minSampleShadingTests.release());
   2861 	}
   2862 
   2863 	// pSampleMask tests
   2864 	{
   2865 		struct TestConfig
   2866 		{
   2867 			const char*		name;
   2868 			const char*		description;
   2869 			VkSampleMask	sampleMask;
   2870 		};
   2871 
   2872 		const TestConfig testConfigs[] =
   2873 		{
   2874 			{ "mask_all_on",	"All mask bits are off",			0x0 },
   2875 			{ "mask_all_off",	"All mask bits are on",				0xFFFFFFFF },
   2876 			{ "mask_one",		"All mask elements are 0x1",		0x1},
   2877 			{ "mask_random",	"All mask elements are 0xAAAAAAAA",	0xAAAAAAAA },
   2878 		};
   2879 
   2880 		de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", ""));
   2881 
   2882 		for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
   2883 		{
   2884 			const TestConfig&				testConfig				= testConfigs[configNdx];
   2885 			de::MovePtr<tcu::TestCaseGroup>	sampleMaskValueTests	(new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description));
   2886 
   2887 			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
   2888 			{
   2889 				std::ostringstream caseName;
   2890 				caseName << "samples_" << samples[samplesNdx];
   2891 
   2892 				const deUint32					sampleMaskCount	= samples[samplesNdx] / 32;
   2893 				de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
   2894 
   2895 				std::vector<VkSampleMask> mask;
   2896 				for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++)
   2897 					mask.push_back(testConfig.sampleMask);
   2898 
   2899 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE));
   2900 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE));
   2901 				samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT));
   2902 
   2903 				sampleMaskValueTests->addChild(samplesTests.release());
   2904 			}
   2905 
   2906 			sampleMaskTests->addChild(sampleMaskValueTests.release());
   2907 		}
   2908 
   2909 		multisampleTests->addChild(sampleMaskTests.release());
   2910 
   2911 	}
   2912 
   2913 	// AlphaToOne tests
   2914 	{
   2915 		de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", ""));
   2916 
   2917 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
   2918 		{
   2919 			std::ostringstream caseName;
   2920 			caseName << "samples_" << samples[samplesNdx];
   2921 
   2922 			alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx]));
   2923 		}
   2924 
   2925 		multisampleTests->addChild(alphaToOneTests.release());
   2926 	}
   2927 
   2928 	// AlphaToCoverageEnable tests
   2929 	{
   2930 		de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", ""));
   2931 
   2932 		for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
   2933 		{
   2934 			std::ostringstream caseName;
   2935 			caseName << "samples_" << samples[samplesNdx];
   2936 
   2937 			de::MovePtr<tcu::TestCaseGroup> samplesTests	(new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
   2938 
   2939 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD));
   2940 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD));
   2941 			samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD));
   2942 
   2943 			alphaToCoverageTests->addChild(samplesTests.release());
   2944 		}
   2945 		multisampleTests->addChild(alphaToCoverageTests.release());
   2946 	}
   2947 
   2948 	// Sampling from a multisampled image texture (texelFetch)
   2949 	{
   2950 		multisampleTests->addChild(createMultisampleSampledImageTests(testCtx));
   2951 	}
   2952 
   2953 	// Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.)
   2954 	{
   2955 		multisampleTests->addChild(createMultisampleStorageImageTests(testCtx));
   2956 	}
   2957 
   2958 	return multisampleTests.release();
   2959 }
   2960 
   2961 } // pipeline
   2962 } // vkt
   2963