/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 The Khronos Group Inc.
 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
 * Copyright (c) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Functional rasterization tests.
 *//*--------------------------------------------------------------------*/

#include "vktTestGroupUtil.hpp"
#include "vktAmberTestCase.hpp"
#include "vktRasterizationTests.hpp"
#include "vktRasterizationFragShaderSideEffectsTests.hpp"
#ifndef CTS_USES_VULKANSC
#include "vktRasterizationProvokingVertexTests.hpp"
#endif // CTS_USES_VULKANSC
#include "tcuRasterizationVerifier.hpp"
#include "tcuSurface.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuResultCollector.hpp"
#include "tcuFloatFormat.hpp"
#include "vkImageUtil.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"
#include "vktTestCase.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkPrograms.hpp"
#include "vkMemUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkImageWithMemory.hpp"
#include "vkBarrierUtil.hpp"

#include <vector>
#include <sstream>

using namespace vk;

namespace vkt
{
namespace rasterization
{
namespace
{

using tcu::RasterizationArguments;
using tcu::TriangleSceneSpec;
using tcu::PointSceneSpec;
using tcu::LineSceneSpec;
using tcu::LineInterpolationMethod;

static const char* const s_shaderVertexTemplate =	"#version 310 es\n"
													"layout(location = 0) in highp vec4 a_position;\n"
													"layout(location = 1) in highp vec4 a_color;\n"
													"layout(location = 0) ${INTERPOLATION}out highp vec4 v_color;\n"
													"layout (set=0, binding=0) uniform PointSize {\n"
													"	highp float u_pointSize;\n"
													"};\n"
													"void main ()\n"
													"{\n"
													"	gl_Position = a_position;\n"
													"	gl_PointSize = u_pointSize;\n"
													"	v_color = a_color;\n"
													"}\n";

static const char* const s_shaderFragmentTemplate =	"#version 310 es\n"
													"layout(location = 0) out highp vec4 fragColor;\n"
													"layout(location = 0) ${INTERPOLATION}in highp vec4 v_color;\n"
													"void main ()\n"
													"{\n"
													"	fragColor = v_color;\n"
													"}\n";

enum InterpolationCaseFlags
{
	INTERPOLATIONFLAGS_NONE = 0,
	INTERPOLATIONFLAGS_PROJECTED = (1 << 1),
	INTERPOLATIONFLAGS_FLATSHADE = (1 << 2),
};

enum ResolutionValues
{
	RESOLUTION_POT = 256,
	RESOLUTION_NPOT = 258
};

enum PrimitiveWideness
{
	PRIMITIVEWIDENESS_NARROW = 0,
	PRIMITIVEWIDENESS_WIDE,

	PRIMITIVEWIDENESS_LAST
};

enum LineStipple
{
	LINESTIPPLE_DISABLED = 0,
	LINESTIPPLE_STATIC,
	LINESTIPPLE_DYNAMIC,

	LINESTIPPLE_LAST
};

static const deUint32 lineStippleFactor = 2;
static const deUint32 lineStipplePattern = 0x0F0F;

enum class LineStippleFactorCase
{
	DEFAULT	= 0,
	ZERO,
	LARGE,
};

enum PrimitiveStrictness
{
	PRIMITIVESTRICTNESS_STRICT = 0,
	PRIMITIVESTRICTNESS_NONSTRICT,
	PRIMITIVESTRICTNESS_IGNORE,

	PRIMITIVESTRICTNESS_LAST
};


class BaseRenderingTestCase : public TestCase
{
public:
								BaseRenderingTestCase	(tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deBool flatshade = DE_FALSE);
	virtual						~BaseRenderingTestCase	(void);

	virtual void				initPrograms			(vk::SourceCollections& programCollection) const;

protected:
	const VkSampleCountFlagBits	m_sampleCount;
	const deBool				m_flatshade;
};

BaseRenderingTestCase::BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount, deBool flatshade)
	: TestCase(context, name, description)
	, m_sampleCount	(sampleCount)
	, m_flatshade	(flatshade)
{
}

void BaseRenderingTestCase::initPrograms (vk::SourceCollections& programCollection) const
{
	tcu::StringTemplate					vertexSource	(s_shaderVertexTemplate);
	tcu::StringTemplate					fragmentSource	(s_shaderFragmentTemplate);
	std::map<std::string, std::string>	params;

	params["INTERPOLATION"] = (m_flatshade) ? ("flat ") : ("");

	programCollection.glslSources.add("vertext_shader") << glu::VertexSource(vertexSource.specialize(params));
	programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fragmentSource.specialize(params));
}

BaseRenderingTestCase::~BaseRenderingTestCase (void)
{
}

class BaseRenderingTestInstance : public TestInstance
{
public:
													BaseRenderingTestInstance		(Context& context, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deUint32 renderSize = RESOLUTION_POT, VkFormat imageFormat = VK_FORMAT_R8G8B8A8_UNORM, deUint32 additionalRenderSize = 0);
													~BaseRenderingTestInstance		(void);

protected:
	void											addImageTransitionBarrier		(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const;
	virtual void									drawPrimitives					(tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology);
	void											drawPrimitives					(tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& coloDrata, VkPrimitiveTopology primitiveTopology);
	void											drawPrimitives					(tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology,
																						VkImage image, VkImage resolvedImage, VkFramebuffer frameBuffer, const deUint32 renderSize, VkBuffer resultBuffer, const Allocation& resultBufferMemory);
	virtual float									getLineWidth					(void) const;
	virtual float									getPointSize					(void) const;
	virtual bool									getLineStippleDynamic			(void) const { return false; }

	virtual
	const VkPipelineRasterizationStateCreateInfo*	getRasterizationStateCreateInfo	(void) const;

	virtual
	VkPipelineRasterizationLineStateCreateInfoEXT	initLineRasterizationStateCreateInfo	(void) const;

	virtual
	const VkPipelineRasterizationLineStateCreateInfoEXT*	getLineRasterizationStateCreateInfo	(void);

	virtual
	const VkPipelineColorBlendStateCreateInfo*		getColorBlendStateCreateInfo	(void) const;

	const tcu::TextureFormat&						getTextureFormat				(void) const;

	const deUint32									m_renderSize;
	const VkSampleCountFlagBits						m_sampleCount;
	deUint32										m_subpixelBits;
	const deBool									m_multisampling;

	const VkFormat									m_imageFormat;
	const tcu::TextureFormat						m_textureFormat;
	Move<VkCommandPool>								m_commandPool;

	Move<VkImage>									m_image;
	de::MovePtr<Allocation>							m_imageMemory;
	Move<VkImageView>								m_imageView;

	Move<VkImage>									m_resolvedImage;
	de::MovePtr<Allocation>							m_resolvedImageMemory;
	Move<VkImageView>								m_resolvedImageView;

	Move<VkRenderPass>								m_renderPass;
	Move<VkFramebuffer>								m_frameBuffer;

	Move<VkDescriptorPool>							m_descriptorPool;
	Move<VkDescriptorSet>							m_descriptorSet;
	Move<VkDescriptorSetLayout>						m_descriptorSetLayout;

	Move<VkBuffer>									m_uniformBuffer;
	de::MovePtr<Allocation>							m_uniformBufferMemory;
	const VkDeviceSize								m_uniformBufferSize;

	Move<VkPipelineLayout>							m_pipelineLayout;

	Move<VkShaderModule>							m_vertexShaderModule;
	Move<VkShaderModule>							m_fragmentShaderModule;

	Move<VkBuffer>									m_resultBuffer;
	de::MovePtr<Allocation>							m_resultBufferMemory;
	const VkDeviceSize								m_resultBufferSize;

	const deUint32									m_additionalRenderSize;
	const VkDeviceSize								m_additionalResultBufferSize;

	VkPipelineRasterizationLineStateCreateInfoEXT	m_lineRasterizationStateInfo;

private:
	virtual int										getIteration					(void) const { TCU_THROW(InternalError, "Iteration undefined in the base class"); }
};

BaseRenderingTestInstance::BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderSize, VkFormat imageFormat, deUint32 additionalRenderSize)
	: TestInstance			(context)
	, m_renderSize			(renderSize)
	, m_sampleCount			(sampleCount)
	, m_subpixelBits		(context.getDeviceProperties().limits.subPixelPrecisionBits)
	, m_multisampling		(m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
	, m_imageFormat			(imageFormat)
	, m_textureFormat		(vk::mapVkFormat(m_imageFormat))
	, m_uniformBufferSize	(sizeof(float))
	, m_resultBufferSize	(renderSize * renderSize * m_textureFormat.getPixelSize())
	, m_additionalRenderSize(additionalRenderSize)
	, m_additionalResultBufferSize(additionalRenderSize * additionalRenderSize * m_textureFormat.getPixelSize())
	, m_lineRasterizationStateInfo	()
{
	const DeviceInterface&						vkd						= m_context.getDeviceInterface();
	const VkDevice								vkDevice				= m_context.getDevice();
	const deUint32								queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	Allocator&									allocator				= m_context.getDefaultAllocator();
	DescriptorPoolBuilder						descriptorPoolBuilder;
	DescriptorSetLayoutBuilder					descriptorSetLayoutBuilder;

	// Command Pool
	m_commandPool = createCommandPool(vkd, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);

	// Image
	{
		const VkImageUsageFlags	imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
		VkImageFormatProperties	properties;

		if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
																					 m_imageFormat,
																					 VK_IMAGE_TYPE_2D,
																					 VK_IMAGE_TILING_OPTIMAL,
																					 imageUsage,
																					 0,
																					 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
		{
			TCU_THROW(NotSupportedError, "Format not supported");
		}

		if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
		{
			TCU_THROW(NotSupportedError, "Format not supported");
		}

		const VkImageCreateInfo					imageCreateInfo			=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			0u,											// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,							// VkImageType				imageType;
			m_imageFormat,								// VkFormat					format;
			{ m_renderSize,	m_renderSize, 1u },			// VkExtent3D				extent;
			1u,											// deUint32					mipLevels;
			1u,											// deUint32					arrayLayers;
			m_sampleCount,								// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
			imageUsage,									// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
			1u,											// deUint32					queueFamilyIndexCount;
			&queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED					// VkImageLayout			initialLayout;
		};

		m_image = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);

		m_imageMemory	= allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_image), MemoryRequirement::Any);
		VK_CHECK(vkd.bindImageMemory(vkDevice, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset()));
	}

	// Image View
	{
		const VkImageViewCreateInfo				imageViewCreateInfo		=
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType				sType;
			DE_NULL,									// const void*					pNext;
			0u,											// VkImageViewCreateFlags		flags;
			*m_image,									// VkImage						image;
			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType				viewType;
			m_imageFormat,								// VkFormat						format;
			makeComponentMappingRGBA(),					// VkComponentMapping			components;
			{
				VK_IMAGE_ASPECT_COLOR_BIT,					// VkImageAspectFlags			aspectMask;
				0u,											// deUint32						baseMipLevel;
				1u,											// deUint32						mipLevels;
				0u,											// deUint32						baseArrayLayer;
				1u,											// deUint32						arraySize;
			},											// VkImageSubresourceRange		subresourceRange;
		};

		m_imageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
	}

	if (m_multisampling)
	{
		{
			// Resolved Image
			const VkImageUsageFlags	imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
			VkImageFormatProperties	properties;

			if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
																						 m_imageFormat,
																						 VK_IMAGE_TYPE_2D,
																						 VK_IMAGE_TILING_OPTIMAL,
																						 imageUsage,
																						 0,
																						 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
			{
				TCU_THROW(NotSupportedError, "Format not supported");
			}

			const VkImageCreateInfo					imageCreateInfo			=
			{
				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
				DE_NULL,									// const void*				pNext;
				0u,											// VkImageCreateFlags		flags;
				VK_IMAGE_TYPE_2D,							// VkImageType				imageType;
				m_imageFormat,								// VkFormat					format;
				{ m_renderSize,	m_renderSize, 1u },			// VkExtent3D				extent;
				1u,											// deUint32					mipLevels;
				1u,											// deUint32					arrayLayers;
				VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits	samples;
				VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
				imageUsage,									// VkImageUsageFlags		usage;
				VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
				1u,											// deUint32					queueFamilyIndexCount;
				&queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
				VK_IMAGE_LAYOUT_UNDEFINED					// VkImageLayout			initialLayout;
			};

			m_resolvedImage			= vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
			m_resolvedImageMemory	= allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_resolvedImage), MemoryRequirement::Any);
			VK_CHECK(vkd.bindImageMemory(vkDevice, *m_resolvedImage, m_resolvedImageMemory->getMemory(), m_resolvedImageMemory->getOffset()));
		}

		// Resolved Image View
		{
			const VkImageViewCreateInfo				imageViewCreateInfo		=
			{
				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType				sType;
				DE_NULL,									// const void*					pNext;
				0u,											// VkImageViewCreateFlags		flags;
				*m_resolvedImage,							// VkImage						image;
				VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType				viewType;
				m_imageFormat,								// VkFormat						format;
				makeComponentMappingRGBA(),					// VkComponentMapping			components;
				{
					VK_IMAGE_ASPECT_COLOR_BIT,					// VkImageAspectFlags			aspectMask;
					0u,											// deUint32						baseMipLevel;
					1u,											// deUint32						mipLevels;
					0u,											// deUint32						baseArrayLayer;
					1u,											// deUint32						arraySize;
				},											// VkImageSubresourceRange		subresourceRange;
			};

			m_resolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
		}

	}

	// Render Pass
	{
		const VkImageLayout						imageLayout				= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
		const VkAttachmentDescription			attachmentDesc[]		=
		{
			{
				0u,													// VkAttachmentDescriptionFlags		flags;
				m_imageFormat,										// VkFormat							format;
				m_sampleCount,										// VkSampleCountFlagBits			samples;
				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
				imageLayout,										// VkImageLayout					initialLayout;
				imageLayout,										// VkImageLayout					finalLayout;
			},
			{
				0u,													// VkAttachmentDescriptionFlags		flags;
				m_imageFormat,										// VkFormat							format;
				VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				loadOp;
				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
				imageLayout,										// VkImageLayout					initialLayout;
				imageLayout,										// VkImageLayout					finalLayout;
			}
		};

		const VkAttachmentReference				attachmentRef			=
		{
			0u,													// deUint32							attachment;
			imageLayout,										// VkImageLayout					layout;
		};

		const VkAttachmentReference				resolveAttachmentRef	=
		{
			1u,													// deUint32							attachment;
			imageLayout,										// VkImageLayout					layout;
		};

		const VkSubpassDescription				subpassDesc				=
		{
			0u,													// VkSubpassDescriptionFlags		flags;
			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
			0u,													// deUint32							inputAttachmentCount;
			DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
			1u,													// deUint32							colorAttachmentCount;
			&attachmentRef,										// const VkAttachmentReference*		pColorAttachments;
			m_multisampling ? &resolveAttachmentRef : DE_NULL,	// const VkAttachmentReference*		pResolveAttachments;
			DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment;
			0u,													// deUint32							preserveAttachmentCount;
			DE_NULL,											// const VkAttachmentReference*		pPreserveAttachments;
		};

		const VkRenderPassCreateInfo			renderPassCreateInfo	=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
			DE_NULL,											// const void*						pNext;
			0u,													// VkRenderPassCreateFlags			flags;
			m_multisampling ? 2u : 1u,							// deUint32							attachmentCount;
			attachmentDesc,										// const VkAttachmentDescription*	pAttachments;
			1u,													// deUint32							subpassCount;
			&subpassDesc,										// const VkSubpassDescription*		pSubpasses;
			0u,													// deUint32							dependencyCount;
			DE_NULL,											// const VkSubpassDependency*		pDependencies;
		};

		m_renderPass =  createRenderPass(vkd, vkDevice, &renderPassCreateInfo, DE_NULL);
	}

	// FrameBuffer
	{
		const VkImageView						attachments[]			=
		{
			*m_imageView,
			*m_resolvedImageView
		};

		const VkFramebufferCreateInfo			framebufferCreateInfo	=
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
			DE_NULL,									// const void*				pNext;
			0u,											// VkFramebufferCreateFlags	flags;
			*m_renderPass,								// VkRenderPass				renderPass;
			m_multisampling ? 2u : 1u,					// deUint32					attachmentCount;
			attachments,								// const VkImageView*		pAttachments;
			m_renderSize,								// deUint32					width;
			m_renderSize,								// deUint32					height;
			1u,											// deUint32					layers;
		};

		m_frameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
	}

	// Uniform Buffer
	{
		const VkBufferCreateInfo				bufferCreateInfo		=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			m_uniformBufferSize,						// VkDeviceSize			size;
			VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
		};

		m_uniformBuffer			= createBuffer(vkd, vkDevice, &bufferCreateInfo);
		m_uniformBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset()));
	}

	// Descriptors
	{
		descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
		m_descriptorPool = descriptorPoolBuilder.build(vkd, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

		descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL);
		m_descriptorSetLayout = descriptorSetLayoutBuilder.build(vkd, vkDevice);

		const VkDescriptorSetAllocateInfo		descriptorSetParams		=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
			DE_NULL,
			*m_descriptorPool,
			1u,
			&m_descriptorSetLayout.get(),
		};

		m_descriptorSet = allocateDescriptorSet(vkd, vkDevice, &descriptorSetParams);

		const VkDescriptorBufferInfo			descriptorBufferInfo	=
		{
			*m_uniformBuffer,							// VkBuffer		buffer;
			0u,											// VkDeviceSize	offset;
			VK_WHOLE_SIZE								// VkDeviceSize	range;
		};

		const VkWriteDescriptorSet				writeDescritporSet		=
		{
			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,		// VkStructureType					sType;
			DE_NULL,									// const void*						pNext;
			*m_descriptorSet,							// VkDescriptorSet					destSet;
			0,											// deUint32							destBinding;
			0,											// deUint32							destArrayElement;
			1u,											// deUint32							count;
			VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,			// VkDescriptorType					descriptorType;
			DE_NULL,									// const VkDescriptorImageInfo*		pImageInfo;
			&descriptorBufferInfo,						// const VkDescriptorBufferInfo*	pBufferInfo;
			DE_NULL										// const VkBufferView*				pTexelBufferView;
		};

		vkd.updateDescriptorSets(vkDevice, 1u, &writeDescritporSet, 0u, DE_NULL);
	}

	// Pipeline Layout
	{
		const VkPipelineLayoutCreateInfo		pipelineLayoutCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
			DE_NULL,											// const void*					pNext;
			0u,													// VkPipelineLayoutCreateFlags	flags;
			1u,													// deUint32						descriptorSetCount;
			&m_descriptorSetLayout.get(),						// const VkDescriptorSetLayout*	pSetLayouts;
			0u,													// deUint32						pushConstantRangeCount;
			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
		};

		m_pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo);
	}

	// Shaders
	{
		m_vertexShaderModule	= createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_shader"), 0);
		m_fragmentShaderModule	= createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_shader"), 0);
	}

	// Result Buffer
	{
		const VkBufferCreateInfo				bufferCreateInfo		=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			m_resultBufferSize,							// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyIndexCount;
			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
		};

		m_resultBuffer			= createBuffer(vkd, vkDevice, &bufferCreateInfo);
		m_resultBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
	}

	m_context.getTestContext().getLog() << tcu::TestLog::Message << "Sample count = " << getSampleCountFlagsStr(m_sampleCount) << tcu::TestLog::EndMessage;
	m_context.getTestContext().getLog() << tcu::TestLog::Message << "SUBPIXEL_BITS = " << m_subpixelBits << tcu::TestLog::EndMessage;
}

BaseRenderingTestInstance::~BaseRenderingTestInstance (void)
{
}


void BaseRenderingTestInstance::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const
{

	const DeviceInterface&			vkd					= m_context.getDeviceInterface();

	const VkImageSubresourceRange	subResourcerange	=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
		0,								// deUint32				baseMipLevel;
		1,								// deUint32				levelCount;
		0,								// deUint32				baseArrayLayer;
		1								// deUint32				layerCount;
	};

	const VkImageMemoryBarrier		imageBarrier		=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		srcAccessMask,								// VkAccessFlags			srcAccessMask;
		dstAccessMask,								// VkAccessFlags			dstAccessMask;
		oldLayout,									// VkImageLayout			oldLayout;
		newLayout,									// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					destQueueFamilyIndex;
		image,										// VkImage					image;
		subResourcerange							// VkImageSubresourceRange	subresourceRange;
	};

	vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
}

void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
{
	// default to color white
	const std::vector<tcu::Vec4> colorData(vertexData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));

	drawPrimitives(result, vertexData, colorData, primitiveTopology);
}

void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology)
{
	drawPrimitives(result, positionData, colorData, primitiveTopology, *m_image, *m_resolvedImage, *m_frameBuffer, m_renderSize, *m_resultBuffer, *m_resultBufferMemory);
}
void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology,
					VkImage image, VkImage resolvedImage, VkFramebuffer frameBuffer, const deUint32 renderSize, VkBuffer resultBuffer, const Allocation& resultBufferMemory)
{
	const DeviceInterface&						vkd						= m_context.getDeviceInterface();
	const VkDevice								vkDevice				= m_context.getDevice();
	const VkQueue								queue					= m_context.getUniversalQueue();
	const deUint32								queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	Allocator&									allocator				= m_context.getDefaultAllocator();
	const size_t								attributeBatchSize		= positionData.size() * sizeof(tcu::Vec4);

	Move<VkCommandBuffer>						commandBuffer;
	Move<VkPipeline>							graphicsPipeline;
	Move<VkBuffer>								vertexBuffer;
	de::MovePtr<Allocation>						vertexBufferMemory;
	const VkPhysicalDeviceProperties			properties				= m_context.getDeviceProperties();

	if (attributeBatchSize > properties.limits.maxVertexInputAttributeOffset)
	{
		std::stringstream message;
		message << "Larger vertex input attribute offset is needed (" << attributeBatchSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
		TCU_THROW(NotSupportedError, message.str().c_str());
	}

	// Create Graphics Pipeline
	{
		const VkVertexInputBindingDescription	vertexInputBindingDescription =
		{
			0u,								// deUint32					binding;
			sizeof(tcu::Vec4),				// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputStepRate	stepRate;
		};

		const VkVertexInputAttributeDescription	vertexInputAttributeDescriptions[2] =
		{
			{
				0u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				0u									// deUint32	offsetInBytes;
			},
			{
				1u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				(deUint32)attributeBatchSize		// deUint32	offsetInBytes;
			}
		};

		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
			DE_NULL,														// const void*								pNext;
			0,																// VkPipelineVertexInputStateCreateFlags	flags;
			1u,																// deUint32									bindingCount;
			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
			2u,																// deUint32									attributeCount;
			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
		};

		const std::vector<VkViewport>	viewports	(1, makeViewport(tcu::UVec2(renderSize)));
		const std::vector<VkRect2D>		scissors	(1, makeRect2D(tcu::UVec2(renderSize)));

		const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
			DE_NULL,														// const void*								pNext;
			0u,																// VkPipelineMultisampleStateCreateFlags	flags;
			m_sampleCount,													// VkSampleCountFlagBits					rasterizationSamples;
			VK_FALSE,														// VkBool32									sampleShadingEnable;
			0.0f,															// float									minSampleShading;
			DE_NULL,														// const VkSampleMask*						pSampleMask;
			VK_FALSE,														// VkBool32									alphaToCoverageEnable;
			VK_FALSE														// VkBool32									alphaToOneEnable;
		};


		VkPipelineRasterizationStateCreateInfo rasterizationStateInfo = *getRasterizationStateCreateInfo();

		const VkPipelineRasterizationLineStateCreateInfoEXT* lineRasterizationStateInfo = getLineRasterizationStateCreateInfo();

		if (lineRasterizationStateInfo != DE_NULL && lineRasterizationStateInfo->sType != 0)
			appendStructurePtrToVulkanChain(&rasterizationStateInfo.pNext, lineRasterizationStateInfo);

		VkPipelineDynamicStateCreateInfo			dynamicStateCreateInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType                      sType
			DE_NULL,												// const void*                          pNext
			0u,														// VkPipelineDynamicStateCreateFlags    flags
			0u,														// deUint32                             dynamicStateCount
			DE_NULL													// const VkDynamicState*                pDynamicStates
		};

		VkDynamicState dynamicState = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
		if (getLineStippleDynamic())
		{
			dynamicStateCreateInfo.dynamicStateCount = 1;
			dynamicStateCreateInfo.pDynamicStates = &dynamicState;
		}

		graphicsPipeline = makeGraphicsPipeline(vkd,								// const DeviceInterface&                        vk
												vkDevice,							// const VkDevice                                device
												*m_pipelineLayout,					// const VkPipelineLayout                        pipelineLayout
												*m_vertexShaderModule,				// const VkShaderModule                          vertexShaderModule
												DE_NULL,							// const VkShaderModule                          tessellationControlShaderModule
												DE_NULL,							// const VkShaderModule                          tessellationEvalShaderModule
												DE_NULL,							// const VkShaderModule                          geometryShaderModule
												*m_fragmentShaderModule,			// const VkShaderModule                          fragmentShaderModule
												*m_renderPass,						// const VkRenderPass                            renderPass
												viewports,							// const std::vector<VkViewport>&                viewports
												scissors,							// const std::vector<VkRect2D>&                  scissors
												primitiveTopology,					// const VkPrimitiveTopology                     topology
												0u,									// const deUint32                                subpass
												0u,									// const deUint32                                patchControlPoints
												&vertexInputStateParams,			// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
												&rasterizationStateInfo,			// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
												&multisampleStateParams,			// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
												DE_NULL,							// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo,
												getColorBlendStateCreateInfo(),		// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo,
												&dynamicStateCreateInfo);			// const VkPipelineDynamicStateCreateInfo*       dynamicStateCreateInfo
	}

	// Create Vertex Buffer
	{
		const VkBufferCreateInfo			vertexBufferParams		=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			attributeBatchSize * 2,						// VkDeviceSize			size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			1u,											// deUint32				queueFamilyCount;
			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
		};

		vertexBuffer		= createBuffer(vkd, vkDevice, &vertexBufferParams);
		vertexBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));

		// Load vertices into vertex buffer
		deMemcpy(vertexBufferMemory->getHostPtr(), positionData.data(), attributeBatchSize);
		deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) +  attributeBatchSize, colorData.data(), attributeBatchSize);
		flushAlloc(vkd, vkDevice, *vertexBufferMemory);
	}

	// Create Command Buffer
	commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

	// Begin Command Buffer
	beginCommandBuffer(vkd, *commandBuffer);

	addImageTransitionBarrier(*commandBuffer, image,
							  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,				// VkPipelineStageFlags		srcStageMask
							  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,				// VkPipelineStageFlags		dstStageMask
							  0,												// VkAccessFlags			srcAccessMask
							  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags			dstAccessMask
							  VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
							  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);		// VkImageLayout			newLayout;

	if (m_multisampling) {
		addImageTransitionBarrier(*commandBuffer, resolvedImage,
								  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,				// VkPipelineStageFlags		srcStageMask
								  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,				// VkPipelineStageFlags		dstStageMask
								  0,												// VkAccessFlags			srcAccessMask
								  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags			dstAccessMask
								  VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
								  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);		// VkImageLayout			newLayout;
	}

	// Begin Render Pass
	beginRenderPass(vkd, *commandBuffer, *m_renderPass, frameBuffer, vk::makeRect2D(0, 0, renderSize, renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	const VkDeviceSize						vertexBufferOffset		= 0;

	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
	vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
	if (getLineStippleDynamic())
		vkd.cmdSetLineStippleEXT(*commandBuffer, lineStippleFactor, lineStipplePattern);
	vkd.cmdDraw(*commandBuffer, (deUint32)positionData.size(), 1, 0, 0);
	endRenderPass(vkd, *commandBuffer);

	// Copy Image
	copyImageToBuffer(vkd, *commandBuffer, m_multisampling ? resolvedImage : image, resultBuffer, tcu::IVec2(renderSize, renderSize));

	endCommandBuffer(vkd, *commandBuffer);

	// Set Point Size
	{
		float	pointSize	= getPointSize();
		deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
		flushAlloc(vkd, vkDevice, *m_uniformBufferMemory);
	}

	// Submit
	submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());

	invalidateAlloc(vkd, vkDevice, resultBufferMemory);
	tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(renderSize, renderSize, 1), resultBufferMemory.getHostPtr()));
}

float BaseRenderingTestInstance::getLineWidth (void) const
{
	return 1.0f;
}

float BaseRenderingTestInstance::getPointSize (void) const
{
	return 1.0f;
}

const VkPipelineRasterizationStateCreateInfo* BaseRenderingTestInstance::getRasterizationStateCreateInfo (void) const
{
	static VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		0,																// VkPipelineRasterizationStateCreateFlags	flags;
		false,															// VkBool32									depthClipEnable;
		false,															// VkBool32									rasterizerDiscardEnable;
		VK_POLYGON_MODE_FILL,											// VkFillMode								fillMode;
		VK_CULL_MODE_NONE,												// VkCullMode								cullMode;
		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
		VK_FALSE,														// VkBool32									depthBiasEnable;
		0.0f,															// float									depthBias;
		0.0f,															// float									depthBiasClamp;
		0.0f,															// float									slopeScaledDepthBias;
		getLineWidth(),													// float									lineWidth;
	};

	rasterizationStateCreateInfo.lineWidth = getLineWidth();
	return &rasterizationStateCreateInfo;
}

VkPipelineRasterizationLineStateCreateInfoEXT BaseRenderingTestInstance::initLineRasterizationStateCreateInfo (void) const
{
	VkPipelineRasterizationLineStateCreateInfoEXT lineRasterizationStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT,	// VkStructureType				sType;
		DE_NULL,																// const void*					pNext;
		VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT,									// VkLineRasterizationModeEXT	lineRasterizationMode;
		VK_FALSE,																// VkBool32						stippledLineEnable;
		1,																		// uint32_t						lineStippleFactor;
		0xFFFF,																	// uint16_t						lineStipplePattern;
	};

	return lineRasterizationStateInfo;
}

const VkPipelineRasterizationLineStateCreateInfoEXT* BaseRenderingTestInstance::getLineRasterizationStateCreateInfo (void)
{
	if (m_lineRasterizationStateInfo.sType != VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT)
		m_lineRasterizationStateInfo = initLineRasterizationStateCreateInfo();

	return &m_lineRasterizationStateInfo;
}

const VkPipelineColorBlendStateCreateInfo* BaseRenderingTestInstance::getColorBlendStateCreateInfo (void) const
{
	static const VkPipelineColorBlendAttachmentState	colorBlendAttachmentState	=
	{
		false,														// VkBool32			blendEnable;
		VK_BLEND_FACTOR_ONE,										// VkBlend			srcBlendColor;
		VK_BLEND_FACTOR_ZERO,										// VkBlend			destBlendColor;
		VK_BLEND_OP_ADD,											// VkBlendOp		blendOpColor;
		VK_BLEND_FACTOR_ONE,										// VkBlend			srcBlendAlpha;
		VK_BLEND_FACTOR_ZERO,										// VkBlend			destBlendAlpha;
		VK_BLEND_OP_ADD,											// VkBlendOp		blendOpAlpha;
		(VK_COLOR_COMPONENT_R_BIT |
		 VK_COLOR_COMPONENT_G_BIT |
		 VK_COLOR_COMPONENT_B_BIT |
		 VK_COLOR_COMPONENT_A_BIT)									// VkChannelFlags	channelWriteMask;
	};

	static const VkPipelineColorBlendStateCreateInfo	colorBlendStateParams		=
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
		DE_NULL,													// const void*									pNext;
		0,															// VkPipelineColorBlendStateCreateFlags			flags;
		false,														// VkBool32										logicOpEnable;
		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
		1u,															// deUint32										attachmentCount;
		&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
	};

	return &colorBlendStateParams;
}

const tcu::TextureFormat& BaseRenderingTestInstance::getTextureFormat (void) const
{
	return m_textureFormat;
}

class BaseTriangleTestInstance : public BaseRenderingTestInstance
{
public:
							BaseTriangleTestInstance	(Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount, deUint32 renderSize = RESOLUTION_POT);
	virtual tcu::TestStatus	iterate						(void);

protected:
	int						getIteration				(void) const	{ return m_iteration;		}
	int						getIterationCount			(void) const	{ return m_iterationCount;	}

private:
	virtual void			generateTriangles			(int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) = DE_NULL;
	virtual bool			compareAndVerify			(std::vector<TriangleSceneSpec::SceneTriangle>&	triangles,
														 tcu::Surface&									resultImage,
														 std::vector<tcu::Vec4>&						drawBuffer);

	int						m_iteration;
	const int				m_iterationCount;
	VkPrimitiveTopology		m_primitiveTopology;
	bool					m_allIterationsPassed;
};

BaseTriangleTestInstance::BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount, deUint32 renderSize)
	: BaseRenderingTestInstance		(context, sampleCount, renderSize)
	, m_iteration					(0)
	, m_iterationCount				(3)
	, m_primitiveTopology			(primitiveTopology)
	, m_allIterationsPassed			(true)
{
}

tcu::TestStatus BaseTriangleTestInstance::iterate (void)
{
	const std::string								iterationDescription	= "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
	const tcu::ScopedLogSection						section					(m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
	tcu::Surface									resultImage				(m_renderSize, m_renderSize);
	std::vector<tcu::Vec4>							drawBuffer;
	std::vector<TriangleSceneSpec::SceneTriangle>	triangles;

	generateTriangles(m_iteration, drawBuffer, triangles);

	// draw image
	drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);

	// compare
	{
		const bool compareOk = compareAndVerify(triangles, resultImage, drawBuffer);

		if (!compareOk)
			m_allIterationsPassed = false;
	}

	// result
	if (++m_iteration == m_iterationCount)
	{
		if (m_allIterationsPassed)
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Incorrect rasterization");
	}
	else
		return tcu::TestStatus::incomplete();
}

bool BaseTriangleTestInstance::compareAndVerify (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage, std::vector<tcu::Vec4>&)
{
	RasterizationArguments	args;
	TriangleSceneSpec		scene;

	tcu::IVec4				colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());

	args.numSamples		= m_multisampling ? 1 : 0;
	args.subpixelBits	= m_subpixelBits;
	args.redBits		= colorBits[0];
	args.greenBits		= colorBits[1];
	args.blueBits		= colorBits[2];

	scene.triangles.swap(triangles);

	return verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
}

class BaseLineTestInstance : public BaseRenderingTestInstance
{
public:
								BaseLineTestInstance	(Context&					context,
														 VkPrimitiveTopology		primitiveTopology,
														 PrimitiveWideness			wideness,
														 PrimitiveStrictness		strictness,
														 VkSampleCountFlagBits		sampleCount,
														 LineStipple				stipple,
														 VkLineRasterizationModeEXT	lineRasterizationMode,
														 LineStippleFactorCase		stippleFactor,
														 const deUint32				additionalRenderSize = 0,
														 const deUint32				renderSize = RESOLUTION_POT,
														 const float				narrowLineWidth = 1.0f);
	virtual tcu::TestStatus		iterate					(void);
	virtual float				getLineWidth			(void) const;
	bool						getLineStippleEnable	(void) const { return m_stipple != LINESTIPPLE_DISABLED; }
	virtual bool				getLineStippleDynamic	(void) const { return m_stipple == LINESTIPPLE_DYNAMIC; }

	virtual
	VkPipelineRasterizationLineStateCreateInfoEXT	initLineRasterizationStateCreateInfo	(void) const;

	virtual
	const VkPipelineRasterizationLineStateCreateInfoEXT*	getLineRasterizationStateCreateInfo	(void);

protected:
	int							getIteration			(void) const	{ return m_iteration;		}
	int							getIterationCount		(void) const	{ return m_iterationCount;	}

private:
	virtual void				generateLines			(int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) = DE_NULL;
	virtual bool				compareAndVerify		(std::vector<LineSceneSpec::SceneLine>&	lines,
														 tcu::Surface&							resultImage,
														 std::vector<tcu::Vec4>&				drawBuffer);

	bool						resultHasAlpha			(tcu::Surface& result);

	int							m_iteration;
	const int					m_iterationCount;
	VkPrimitiveTopology			m_primitiveTopology;
	const PrimitiveWideness		m_primitiveWideness;
	const PrimitiveStrictness	m_primitiveStrictness;
	bool						m_allIterationsPassed;
	bool						m_qualityWarning;
	float						m_maxLineWidth;
	std::vector<float>			m_lineWidths;
	LineStipple					m_stipple;
	VkLineRasterizationModeEXT	m_lineRasterizationMode;
	LineStippleFactorCase		m_stippleFactor;
	Move<VkImage>				m_additionalImage;
	de::MovePtr<Allocation>		m_additionalImageMemory;
	Move<VkImageView>			m_additionalImageView;
	Move<VkImage>				m_additionalResolvedImage;
	de::MovePtr<Allocation>		m_additionalResolvedImageMemory;
	Move<VkImageView>			m_additionalResolvedImageView;
	Move<VkFramebuffer>			m_additionalFrameBuffer;
	Move<VkBuffer>				m_additionalResultBuffer;
	de::MovePtr<Allocation>		m_additionalResultBufferMemory;
};

BaseLineTestInstance::BaseLineTestInstance (Context&					context,
											VkPrimitiveTopology			primitiveTopology,
											PrimitiveWideness			wideness,
											PrimitiveStrictness			strictness,
											VkSampleCountFlagBits		sampleCount,
											LineStipple					stipple,
											VkLineRasterizationModeEXT	lineRasterizationMode,
											LineStippleFactorCase		stippleFactor,
											const deUint32				additionalRenderSize,
											const deUint32				renderSize,
											const float					narrowLineWidth)
	: BaseRenderingTestInstance	(context, sampleCount, renderSize, VK_FORMAT_R8G8B8A8_UNORM, additionalRenderSize)
	, m_iteration				(0)
	, m_iterationCount			(3)
	, m_primitiveTopology		(primitiveTopology)
	, m_primitiveWideness		(wideness)
	, m_primitiveStrictness		(strictness)
	, m_allIterationsPassed		(true)
	, m_qualityWarning			(false)
	, m_maxLineWidth			(1.0f)
	, m_stipple					(stipple)
	, m_lineRasterizationMode	(lineRasterizationMode)
	, m_stippleFactor			(stippleFactor)
{
	DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);

	if (m_lineRasterizationMode != VK_LINE_RASTERIZATION_MODE_EXT_LAST)
	{
		if (context.isDeviceFunctionalitySupported("VK_EXT_line_rasterization"))
		{
			VkPhysicalDeviceLineRasterizationPropertiesEXT lineRasterizationProperties =
			{
				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT,	// VkStructureType	sType;
				DE_NULL,																// void*			pNext;
				0u,																		// deUint32			lineSubPixelPrecisionBits;
			};

			VkPhysicalDeviceProperties2 deviceProperties2;
			deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
			deviceProperties2.pNext = &lineRasterizationProperties;

			context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &deviceProperties2);

			m_subpixelBits = lineRasterizationProperties.lineSubPixelPrecisionBits;
		}
	}

	// create line widths
	if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
	{
		m_lineWidths.resize(m_iterationCount, narrowLineWidth);

		// Bump up m_maxLineWidth for conservative rasterization
		if (narrowLineWidth > m_maxLineWidth)
			m_maxLineWidth = narrowLineWidth;
	}
	else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
	{
		const float*	range = context.getDeviceProperties().limits.lineWidthRange;

		m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;

		DE_ASSERT(range[1] > 1.0f);

		// set hand picked sizes
		m_lineWidths.push_back(5.0f);
		m_lineWidths.push_back(10.0f);

		// Do not pick line width with 0.5 fractional value as rounding direction is not defined.
		if (deFloatFrac(range[1]) == 0.5f)
		{
			m_lineWidths.push_back(range[1] - context.getDeviceProperties().limits.lineWidthGranularity);
		}
		else
		{
			m_lineWidths.push_back(range[1]);
		}

		DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);

		m_maxLineWidth = range[1];
	}
	else
		DE_ASSERT(false);

	// Create image, image view and frame buffer for testing at an additional resolution if required.
	if (m_additionalRenderSize != 0)
	{
		const DeviceInterface&						vkd						= m_context.getDeviceInterface();
		const VkDevice								vkDevice				= m_context.getDevice();
		const deUint32								queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
		Allocator&									allocator				= m_context.getDefaultAllocator();
		DescriptorPoolBuilder						descriptorPoolBuilder;
		DescriptorSetLayoutBuilder					descriptorSetLayoutBuilder;
		{
			const VkImageUsageFlags	imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
			const VkImageCreateInfo					imageCreateInfo			=
			{
				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
				DE_NULL,									// const void*				pNext;
				0u,											// VkImageCreateFlags		flags;
				VK_IMAGE_TYPE_2D,							// VkImageType				imageType;
				m_imageFormat,								// VkFormat					format;
				{ m_additionalRenderSize, m_additionalRenderSize, 1u },			// VkExtent3D				extent;
				1u,											// deUint32					mipLevels;
				1u,											// deUint32					arrayLayers;
				m_sampleCount,								// VkSampleCountFlagBits	samples;
				VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
				imageUsage,									// VkImageUsageFlags		usage;
				VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
				1u,											// deUint32					queueFamilyIndexCount;
				&queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
				VK_IMAGE_LAYOUT_UNDEFINED					// VkImageLayout			initialLayout;
			};

			m_additionalImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);

			m_additionalImageMemory	= allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_additionalImage), MemoryRequirement::Any);
			VK_CHECK(vkd.bindImageMemory(vkDevice, *m_additionalImage, m_additionalImageMemory->getMemory(), m_additionalImageMemory->getOffset()));
		}

		// Image View
		{
			const VkImageViewCreateInfo				imageViewCreateInfo		=
			{
				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType				sType;
				DE_NULL,									// const void*					pNext;
				0u,											// VkImageViewCreateFlags		flags;
				*m_additionalImage,							// VkImage						image;
				VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType				viewType;
				m_imageFormat,								// VkFormat						format;
				makeComponentMappingRGBA(),					// VkComponentMapping			components;
				{
					VK_IMAGE_ASPECT_COLOR_BIT,					// VkImageAspectFlags			aspectMask;
					0u,											// deUint32						baseMipLevel;
					1u,											// deUint32						mipLevels;
					0u,											// deUint32						baseArrayLayer;
					1u,											// deUint32						arraySize;
				},											// VkImageSubresourceRange		subresourceRange;
			};

			m_additionalImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
		}

		if (m_multisampling)
		{
			{
				const VkImageUsageFlags	imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
				const VkImageCreateInfo					imageCreateInfo			=
				{
					VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
					DE_NULL,									// const void*				pNext;
					0u,											// VkImageCreateFlags		flags;
					VK_IMAGE_TYPE_2D,							// VkImageType				imageType;
					m_imageFormat,								// VkFormat					format;
					{ m_additionalRenderSize,	m_additionalRenderSize, 1u },			// VkExtent3D				extent;
					1u,											// deUint32					mipLevels;
					1u,											// deUint32					arrayLayers;
					VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits	samples;
					VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
					imageUsage,									// VkImageUsageFlags		usage;
					VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
					1u,											// deUint32					queueFamilyIndexCount;
					&queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
					VK_IMAGE_LAYOUT_UNDEFINED					// VkImageLayout			initialLayout;
				};

				m_additionalResolvedImage			= vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
				m_additionalResolvedImageMemory	= allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_additionalResolvedImage), MemoryRequirement::Any);
				VK_CHECK(vkd.bindImageMemory(vkDevice, *m_additionalResolvedImage, m_additionalResolvedImageMemory->getMemory(), m_additionalResolvedImageMemory->getOffset()));
			}

			// Image view
			{
				const VkImageViewCreateInfo				imageViewCreateInfo		=
				{
					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType				sType;
					DE_NULL,									// const void*					pNext;
					0u,											// VkImageViewCreateFlags		flags;
					*m_additionalResolvedImage,					// VkImage						image;
					VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType				viewType;
					m_imageFormat,								// VkFormat						format;
					makeComponentMappingRGBA(),					// VkComponentMapping			components;
					{
						VK_IMAGE_ASPECT_COLOR_BIT,					// VkImageAspectFlags			aspectMask;
						0u,											// deUint32						baseMipLevel;
						1u,											// deUint32						mipLevels;
						0u,											// deUint32						baseArrayLayer;
						1u,											// deUint32						arraySize;
					},											// VkImageSubresourceRange		subresourceRange;
				};
				m_additionalResolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
			}
		}

		{
			const VkImageView						attachments[]			=
			{
				*m_additionalImageView,
				*m_additionalResolvedImageView
			};

			const VkFramebufferCreateInfo			framebufferCreateInfo	=
			{
				VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
				DE_NULL,									// const void*				pNext;
				0u,											// VkFramebufferCreateFlags	flags;
				*m_renderPass,								// VkRenderPass				renderPass;
				m_multisampling ? 2u : 1u,					// deUint32					attachmentCount;
				attachments,								// const VkImageView*		pAttachments;
				m_additionalRenderSize,						// deUint32					width;
				m_additionalRenderSize,						// deUint32					height;
				1u,											// deUint32					layers;
			};
			m_additionalFrameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
		}

		// Framebuffer
		{
			const VkBufferCreateInfo				bufferCreateInfo		=
			{
				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
				DE_NULL,									// const void*			pNext;
				0u,											// VkBufferCreateFlags	flags;
				m_additionalResultBufferSize,							// VkDeviceSize			size;
				VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
				VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
				1u,											// deUint32				queueFamilyIndexCount;
				&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
			};

			m_additionalResultBuffer			= createBuffer(vkd, vkDevice, &bufferCreateInfo);
			m_additionalResultBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_additionalResultBuffer), MemoryRequirement::HostVisible);

			VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_additionalResultBuffer, m_additionalResultBufferMemory->getMemory(), m_additionalResultBufferMemory->getOffset()));
		}
	}
}

bool BaseLineTestInstance::resultHasAlpha(tcu::Surface& resultImage)
{
	bool hasAlpha = false;
	for (int y = 0; y < resultImage.getHeight() && !hasAlpha; ++y)
	for (int x = 0; x < resultImage.getWidth(); ++x)
	{
		const tcu::RGBA		color				= resultImage.getPixel(x, y);
		if (color.getAlpha() > 0 && color.getAlpha() < 0xFF)
		{
			hasAlpha = true;
			break;
		}
	}
	return hasAlpha;
}

tcu::TestStatus BaseLineTestInstance::iterate (void)
{
	const std::string						iterationDescription	= "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
	const tcu::ScopedLogSection				section					(m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
	const float								lineWidth				= getLineWidth();
	tcu::Surface							resultImage				(m_renderSize, m_renderSize);
	std::vector<tcu::Vec4>					drawBuffer;
	std::vector<LineSceneSpec::SceneLine>	lines;

	// supported?
	if (lineWidth <= m_maxLineWidth)
	{
		// gen data
		generateLines(m_iteration, drawBuffer, lines);

		// draw image
		drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);

		// compare
		{
			const bool compareOk = compareAndVerify(lines, resultImage, drawBuffer);

			if (!compareOk)
				m_allIterationsPassed = false;
		}
	}
	else
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;

	// result
	if (++m_iteration == m_iterationCount)
	{
		if (!m_allIterationsPassed)
			return tcu::TestStatus::fail("Incorrect rasterization");
		else if (m_qualityWarning)
			return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality line rasterization");
		else
			return tcu::TestStatus::pass("Pass");
	}
	else
		return tcu::TestStatus::incomplete();
}

bool BaseLineTestInstance::compareAndVerify (std::vector<LineSceneSpec::SceneLine>&	lines, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
{
	const float				lineWidth				= getLineWidth();
	bool					result					= true;
	tcu::Surface			additionalResultImage	(m_additionalRenderSize, m_additionalRenderSize);
	RasterizationArguments	args;
	LineSceneSpec			scene;
	tcu::IVec4				colorBits	= tcu::getTextureFormatBitDepth(getTextureFormat());
	bool					strict		= m_primitiveStrictness == PRIMITIVESTRICTNESS_STRICT;

	args.numSamples		= m_multisampling ? 1 : 0;
	args.subpixelBits	= m_subpixelBits;
	args.redBits		= colorBits[0];
	args.greenBits		= colorBits[1];
	args.blueBits		= colorBits[2];

	scene.lines.swap(lines);
	scene.lineWidth = lineWidth;
	scene.stippleEnable = getLineStippleEnable();
	scene.stippleFactor = getLineStippleEnable() ? lineStippleFactor : 1;
	scene.stipplePattern = getLineStippleEnable() ? lineStipplePattern : 0xFFFF;
	scene.isStrip = m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
	scene.isSmooth = m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
	scene.isRectangular = m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT ||
	                      m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;

	// Choose verification mode. Smooth lines assume mostly over-rasterization (bloated lines with a falloff).
	// Stippled lines lose some precision across segments in a strip, so need a weaker threshold than normal
	// lines. For simple cases, check for an exact match (STRICT).
	if (scene.isSmooth)
		scene.verificationMode = tcu::VERIFICATIONMODE_SMOOTH;
	else if (scene.stippleEnable)
		scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
	else
		scene.verificationMode = tcu::VERIFICATIONMODE_STRICT;

	if (m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT)
	{
		// bresenham is "no AA" in GL, so set numSamples to zero.
		args.numSamples = 0;
		if (!verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
			result = false;
	}
	else
	{
		if (scene.isSmooth)
		{
			// Smooth lines get the fractional coverage multiplied into the alpha component,
			// so do a sanity check to validate that there is at least one pixel in the image
			// with a fractional opacity.
			bool hasAlpha = resultHasAlpha(resultImage);
			if (!hasAlpha)
			{
				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Missing alpha transparency (failed)." << tcu::TestLog::EndMessage;
				result = false;
			}
		}

		if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling), strict))
		{
			// Retry with weaker verification. If it passes, consider it a quality warning.
			scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
			if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), false, strict))
				result = false;
			else
				m_qualityWarning = true;
		}

		if (m_additionalRenderSize != 0)
		{
			const std::vector<tcu::Vec4> colorData(drawBuffer.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));

			if (scene.isSmooth)
				scene.verificationMode = tcu::VERIFICATIONMODE_SMOOTH;
			else if (scene.stippleEnable)
				scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
			else
				scene.verificationMode = tcu::VERIFICATIONMODE_STRICT;

			drawPrimitives(additionalResultImage, drawBuffer, colorData, m_primitiveTopology, *m_additionalImage, *m_additionalResolvedImage, *m_additionalFrameBuffer, m_additionalRenderSize, *m_additionalResultBuffer, *m_additionalResultBufferMemory);

			// Compare
			if (!verifyRelaxedLineGroupRasterization(additionalResultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling), strict))
			{
				if (strict)
				{
					result = false;
				}
				else
				{
					// Retry with weaker verification. If it passes, consider it a quality warning.
					scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
					if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling), strict))
						result = false;
					else
						m_qualityWarning = true;
				}
			}
		}
	}

	return result;
}

float BaseLineTestInstance::getLineWidth (void) const
{
	return m_lineWidths[m_iteration];
}

VkPipelineRasterizationLineStateCreateInfoEXT BaseLineTestInstance::initLineRasterizationStateCreateInfo (void) const
{
	VkPipelineRasterizationLineStateCreateInfoEXT lineRasterizationStateInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT,	// VkStructureType				sType;
		DE_NULL,																// const void*					pNext;
		m_lineRasterizationMode,												// VkLineRasterizationModeEXT	lineRasterizationMode;
		getLineStippleEnable() ? VK_TRUE : VK_FALSE,							// VkBool32						stippledLineEnable;
		1,																		// uint32_t						lineStippleFactor;
		0xFFFF,																	// uint16_t						lineStipplePattern;
	};

	if (m_stipple == LINESTIPPLE_STATIC)
	{
		lineRasterizationStateInfo.lineStippleFactor = lineStippleFactor;
		lineRasterizationStateInfo.lineStipplePattern = lineStipplePattern;
	}
	else if (m_stipple == LINESTIPPLE_DISABLED)
	{
		if (m_stippleFactor == LineStippleFactorCase::ZERO)
			lineRasterizationStateInfo.lineStippleFactor = 0u;
		else if (m_stippleFactor == LineStippleFactorCase::LARGE)
			lineRasterizationStateInfo.lineStippleFactor = 0xFEDCBA98u;
	}

	return lineRasterizationStateInfo;
}

const VkPipelineRasterizationLineStateCreateInfoEXT* BaseLineTestInstance::getLineRasterizationStateCreateInfo (void)
{
	if (m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_EXT_LAST)
		return DE_NULL;

	if (m_lineRasterizationStateInfo.sType != VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT)
		m_lineRasterizationStateInfo = initLineRasterizationStateCreateInfo();

	return &m_lineRasterizationStateInfo;
}

class PointTestInstance : public BaseRenderingTestInstance
{
public:
							PointTestInstance		(Context&					context,
													 PrimitiveWideness			wideness,
													 PrimitiveStrictness		strictness,				// ignored
													 VkSampleCountFlagBits		sampleCount,
													 LineStipple				stipple,				// ignored
													 VkLineRasterizationModeEXT	lineRasterizationMode,	// ignored
													 LineStippleFactorCase		stippleFactor,			// ignored
													 deUint32					additionalRenderSize,	// ignored
													 deUint32					renderSize				= RESOLUTION_POT,
													 float						pointSizeNarrow			= 1.0f);
	virtual tcu::TestStatus	iterate					(void);
	virtual float			getPointSize			(void) const;

protected:
	int						getIteration				(void) const	{ return m_iteration;		}
	int						getIterationCount			(void) const	{ return m_iterationCount;	}

private:
	virtual void			generatePoints			(int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints);
	virtual bool			compareAndVerify		(std::vector<PointSceneSpec::ScenePoint>&	points,
													 tcu::Surface&								resultImage,
													 std::vector<tcu::Vec4>&					drawBuffer);

	int						m_iteration;
	const int				m_iterationCount;
	const PrimitiveWideness	m_primitiveWideness;
	bool					m_allIterationsPassed;
	float					m_maxPointSize;
	std::vector<float>		m_pointSizes;
};

PointTestInstance::PointTestInstance (Context&						context,
									  PrimitiveWideness				wideness,
									  PrimitiveStrictness			strictness,
									  VkSampleCountFlagBits			sampleCount,
									  LineStipple					stipple,
									  VkLineRasterizationModeEXT	lineRasterizationMode,
									  LineStippleFactorCase			stippleFactor,
									  deUint32						additionalRenderSize,
									  deUint32						renderSize,
									  float							pointSizeNarrow)
	: BaseRenderingTestInstance	(context, sampleCount, renderSize)
	, m_iteration				(0)
	, m_iterationCount			(3)
	, m_primitiveWideness		(wideness)
	, m_allIterationsPassed		(true)
	, m_maxPointSize			(pointSizeNarrow)
{
	DE_UNREF(strictness);
	DE_UNREF(stipple);
	DE_UNREF(lineRasterizationMode);
	DE_UNREF(stippleFactor);
	DE_UNREF(additionalRenderSize);

	// create point sizes
	if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
	{
		m_pointSizes.resize(m_iterationCount, pointSizeNarrow);
	}
	else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
	{
		const float*	range = context.getDeviceProperties().limits.pointSizeRange;

		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_ALIASED_POINT_SIZE_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;

		DE_ASSERT(range[1] > 1.0f);

		// set hand picked sizes
		m_pointSizes.push_back(10.0f);
		m_pointSizes.push_back(25.0f);
		m_pointSizes.push_back(range[1]);
		DE_ASSERT((int)m_pointSizes.size() == m_iterationCount);

		m_maxPointSize = range[1];
	}
	else
		DE_ASSERT(false);
}

tcu::TestStatus PointTestInstance::iterate (void)
{
	const std::string						iterationDescription	= "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
	const tcu::ScopedLogSection				section					(m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
	const float								pointSize				= getPointSize();
	tcu::Surface							resultImage				(m_renderSize, m_renderSize);
	std::vector<tcu::Vec4>					drawBuffer;
	std::vector<PointSceneSpec::ScenePoint>	points;

	// supported?
	if (pointSize <= m_maxPointSize)
	{
		// gen data
		generatePoints(m_iteration, drawBuffer, points);

		// draw image
		drawPrimitives(resultImage, drawBuffer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);

		// compare
		{
			const bool compareOk = compareAndVerify(points, resultImage, drawBuffer);

			if (!compareOk)
				m_allIterationsPassed = false;
		}
	}
	else
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point size " << pointSize << " not supported, skipping iteration." << tcu::TestLog::EndMessage;

	// result
	if (++m_iteration == m_iterationCount)
	{
		if (m_allIterationsPassed)
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Incorrect rasterization");
	}
	else
		return tcu::TestStatus::incomplete();
}

bool PointTestInstance::compareAndVerify (std::vector<PointSceneSpec::ScenePoint>&	points,
										  tcu::Surface&								resultImage,
										  std::vector<tcu::Vec4>&					drawBuffer)
{
	RasterizationArguments	args;
	PointSceneSpec			scene;

	tcu::IVec4				colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());

	args.numSamples		= m_multisampling ? 1 : 0;
	args.subpixelBits	= m_subpixelBits;
	args.redBits		= colorBits[0];
	args.greenBits		= colorBits[1];
	args.blueBits		= colorBits[2];

	scene.points.swap(points);

	DE_UNREF(drawBuffer);

	return verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
}

float PointTestInstance::getPointSize (void) const
{
	return m_pointSizes[m_iteration];
}

void PointTestInstance::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
{
	outData.resize(6);

	switch (iteration)
	{
		case 0:
			// \note: these values are chosen arbitrarily
			outData[0] = tcu::Vec4( 0.2f,  0.8f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4( 0.5f,  0.2f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4( 0.5f,  0.3f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4(-0.5f,  0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4(-0.2f, -0.4f, 0.0f, 1.0f);
			outData[5] = tcu::Vec4(-0.4f,  0.2f, 0.0f, 1.0f);
			break;

		case 1:
			outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4(-0.501f,  -0.3f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4(  0.11f,  -0.2f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4(  0.11f,   0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4(  0.88f,   0.9f, 0.0f, 1.0f);
			outData[5] = tcu::Vec4(   0.4f,   1.2f, 0.0f, 1.0f);
			break;

		case 2:
			outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4(  0.3f, -0.9f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4( -0.4f, -0.1f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4(-0.11f,  0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4( 0.88f,  0.7f, 0.0f, 1.0f);
			outData[5] = tcu::Vec4( -0.4f,  0.4f, 0.0f, 1.0f);
			break;
	}

	outPoints.resize(outData.size());
	for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
	{
		outPoints[pointNdx].position = outData[pointNdx];
		outPoints[pointNdx].pointSize = getPointSize();
	}

	// log
	m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outPoints.size() << " point(s): (point size = " << getPointSize() << ")" << tcu::TestLog::EndMessage;
	for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point " << (pointNdx+1) << ":\t" << outPoints[pointNdx].position << tcu::TestLog::EndMessage;
}

template <typename ConcreteTestInstance>
class PointSizeTestCase : public BaseRenderingTestCase
{
public:
							PointSizeTestCase	(tcu::TestContext&		context,
												 std::string&			name,
												 std::string&			description,
												 deUint32				renderSize,
												 float					pointSize,
												 VkSampleCountFlagBits	sampleCount = VK_SAMPLE_COUNT_1_BIT)
								: BaseRenderingTestCase (context, name, description, sampleCount)
								, m_pointSize	(pointSize)
								, m_renderSize	(renderSize)
							{}

	virtual TestInstance*	createInstance		(Context& context) const
							{
								VkPhysicalDeviceProperties	properties	(context.getDeviceProperties());

								if (m_renderSize > properties.limits.maxViewportDimensions[0] || m_renderSize > properties.limits.maxViewportDimensions[1])
									TCU_THROW(NotSupportedError , "Viewport dimensions not supported");

								if (m_renderSize > properties.limits.maxFramebufferWidth || m_renderSize > properties.limits.maxFramebufferHeight)
									TCU_THROW(NotSupportedError , "Framebuffer width/height not supported");

								return new ConcreteTestInstance(context, m_renderSize, m_pointSize);
							}

	virtual	void			checkSupport		(Context& context) const
							{
								context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
							}
protected:
	const float				m_pointSize;
	const deUint32			m_renderSize;
};

class PointSizeTestInstance : public BaseRenderingTestInstance
{
public:
							PointSizeTestInstance	(Context& context, deUint32 renderSize, float pointSize);
	virtual tcu::TestStatus	iterate					(void);
	virtual float			getPointSize			(void) const;

private:
	void					generatePointData		(PointSceneSpec::ScenePoint& outPoint);
	void					drawPoint				(tcu::PixelBufferAccess& result, tcu::PointSceneSpec::ScenePoint& point);
	bool					verifyPoint				(tcu::TestLog& log, tcu::PixelBufferAccess& access, float pointSize);
	bool					isPointSizeClamped		(float pointSize, float maxPointSizeLimit);

	const float				m_pointSize;
	const float				m_maxPointSize;
	const deUint32			m_renderSize;
	const VkFormat			m_format;
};

PointSizeTestInstance::PointSizeTestInstance (Context& context, deUint32 renderSize, float pointSize)
	: BaseRenderingTestInstance	(context, vk::VK_SAMPLE_COUNT_1_BIT, renderSize, VK_FORMAT_R8_UNORM)
	, m_pointSize				(pointSize)
	, m_maxPointSize			(context.getDeviceProperties().limits.pointSizeRange[1])
	, m_renderSize				(renderSize)
	, m_format					(VK_FORMAT_R8_UNORM) // Use single-channel format to minimize memory allocation when using large render targets
{
}

tcu::TestStatus PointSizeTestInstance::iterate (void)
{
	tcu::TextureLevel			resultBuffer	(mapVkFormat(m_format), m_renderSize, m_renderSize);
	tcu::PixelBufferAccess		access			(resultBuffer.getAccess());
	PointSceneSpec::ScenePoint	point;

	// Generate data
	generatePointData(point);

	// Draw
	drawPoint(access, point);

	// Compare
#ifdef CTS_USES_VULKANSC
	if (m_context.getTestContext().getCommandLine().isSubProcess())
#endif // CTS_USES_VULKANSC
	{
		// pointSize must either be specified pointSize or clamped to device limit pointSizeRange[1]
		const float	pointSize	(deFloatMin(m_pointSize, m_maxPointSize));
		const bool	compareOk	(verifyPoint(m_context.getTestContext().getLog(), access, pointSize));

		// Result
		if (compareOk)
			return isPointSizeClamped(pointSize, m_maxPointSize) ? tcu::TestStatus::pass("Pass, pointSize clamped to pointSizeRange[1]") : tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Incorrect rasterization");
	}
	return tcu::TestStatus::pass("Pass");
}

float PointSizeTestInstance::getPointSize (void) const
{
	return m_pointSize;
}

void PointSizeTestInstance::generatePointData (PointSceneSpec::ScenePoint& outPoint)
{
	const tcu::PointSceneSpec::ScenePoint point =
	{
		tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),	// position
		tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),	// color
		m_pointSize							// pointSize
	};

	outPoint = point;

	// log
	{
		tcu::TestLog& log = m_context.getTestContext().getLog();

		log << tcu::TestLog::Message << "Point position: "	<< de::toString(point.position)		<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "Point color: "		<< de::toString(point.color)		<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "Point size: "		<< de::toString(point.pointSize)	<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "Render size: "		<< de::toString(m_renderSize)		<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "Format: "			<< de::toString(m_format)			<< tcu::TestLog::EndMessage;
	}
}

void PointSizeTestInstance::drawPoint (tcu::PixelBufferAccess& result, PointSceneSpec::ScenePoint& point)
{
	const tcu::Vec4			positionData		(point.position);
	const tcu::Vec4			colorData			(point.color);

	const DeviceInterface&	vkd					(m_context.getDeviceInterface());
	const VkDevice			vkDevice			(m_context.getDevice());
	const VkQueue			queue				(m_context.getUniversalQueue());
	const deUint32			queueFamilyIndex	(m_context.getUniversalQueueFamilyIndex());
	const size_t			attributeBatchSize	(sizeof(tcu::Vec4));
	Allocator&				allocator			(m_context.getDefaultAllocator());

	Move<VkCommandBuffer>	commandBuffer;
	Move<VkPipeline>		graphicsPipeline;
	Move<VkBuffer>			vertexBuffer;
	de::MovePtr<Allocation>	vertexBufferMemory;

	// Create Graphics Pipeline
	{
		const std::vector<VkViewport>				viewports							(1, makeViewport(tcu::UVec2(m_renderSize)));
		const std::vector<VkRect2D>					scissors							(1, makeRect2D(tcu::UVec2(m_renderSize)));

		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
		{
			0u,									// deUint32					binding;
			(deUint32)(2 * sizeof(tcu::Vec4)),	// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputStepRate	stepRate;
		};

		const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[2]	=
		{
			{
				0u,								// deUint32	location;
				0u,								// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
				0u								// deUint32	offsetInBytes;
			},
			{
				1u,								// deUint32	location;
				0u,								// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
				(deUint32)sizeof(tcu::Vec4)		// deUint32	offsetInBytes;
			}
		};

		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
			DE_NULL,													// const void*								pNext;
			0,															// VkPipelineVertexInputStateCreateFlags	flags;
			1u,															// deUint32									bindingCount;
			&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
			2u,															// deUint32									attributeCount;
			vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
		};

		graphicsPipeline = makeGraphicsPipeline(vkd,								// const DeviceInterface&							 vk
												vkDevice,							// const VkDevice									 device
												*m_pipelineLayout,					// const VkPipelineLayout							 pipelineLayout
												*m_vertexShaderModule,				// const VkShaderModule								 vertexShaderModule
												DE_NULL,							// const VkShaderModule								 tessellationControlShaderModule
												DE_NULL,							// const VkShaderModule								 tessellationEvalShaderModule
												DE_NULL,							// const VkShaderModule								 geometryShaderModule
												*m_fragmentShaderModule,			// const VkShaderModule								 fragmentShaderModule
												*m_renderPass,						// const VkRenderPass								 renderPass
												viewports,							// const std::vector<VkViewport>&					 viewports
												scissors,							// const std::vector<VkRect2D>&						 scissors
												VK_PRIMITIVE_TOPOLOGY_POINT_LIST,	// const VkPrimitiveTopology						 topology
												0u,									// const deUint32									 subpass
												0u,									// const deUint32									 patchControlPoints
												&vertexInputStateParams,			// const VkPipelineVertexInputStateCreateInfo*		 vertexInputStateCreateInfo
												getRasterizationStateCreateInfo(),	// const VkPipelineRasterizationStateCreateInfo*	 rasterizationStateCreateInfo
												DE_NULL,							// const VkPipelineMultisampleStateCreateInfo*		 multisampleStateCreateInfo
												DE_NULL,							// const VkPipelineDepthStencilStateCreateInfo*		 depthStencilStateCreateInfo,
												getColorBlendStateCreateInfo());	// const VkPipelineColorBlendStateCreateInfo*		 colorBlendStateCreateInfo
	}

	// Create Vertex Buffer
	{
		const VkBufferCreateInfo	vertexBufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			0u,										// VkBufferCreateFlags	flags;
			attributeBatchSize * 2,					// VkDeviceSize			size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
		};

		vertexBuffer		= createBuffer(vkd, vkDevice, &vertexBufferParams);
		vertexBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));

		// Load vertices into vertex buffer
		deMemcpy(vertexBufferMemory->getHostPtr(), &positionData, attributeBatchSize);
		deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) +  attributeBatchSize, &colorData, attributeBatchSize);
		flushAlloc(vkd, vkDevice, *vertexBufferMemory);
	}

	// Create Command Buffer
	commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

	// Begin Command Buffer
	beginCommandBuffer(vkd, *commandBuffer);

	addImageTransitionBarrier(*commandBuffer, *m_image,
							  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,			// VkPipelineStageFlags		srcStageMask
							  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,			// VkPipelineStageFlags		dstStageMask
							  0,											// VkAccessFlags			srcAccessMask
							  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask
							  VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
							  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);	// VkImageLayout			newLayout;

	// Begin Render Pass
	beginRenderPass(vkd, *commandBuffer, *m_renderPass, *m_frameBuffer, vk::makeRect2D(0, 0, m_renderSize, m_renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	const VkDeviceSize vertexBufferOffset = 0;

	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
	vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
	vkd.cmdDraw(*commandBuffer, 1, 1, 0, 0);
	endRenderPass(vkd, *commandBuffer);

	// Copy Image
	copyImageToBuffer(vkd, *commandBuffer, *m_image, *m_resultBuffer, tcu::IVec2(m_renderSize, m_renderSize));

	endCommandBuffer(vkd, *commandBuffer);

	// Set Point Size
	{
		float pointSize = getPointSize();

		deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
		flushAlloc(vkd, vkDevice, *m_uniformBufferMemory);
	}

	// Submit
	submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());

	invalidateAlloc(vkd, vkDevice, *m_resultBufferMemory);
#ifdef CTS_USES_VULKANSC
	if (m_context.getTestContext().getCommandLine().isSubProcess())
#endif // CTS_USES_VULKANSC
	{
		tcu::copy(result, tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
	}
}

bool PointSizeTestInstance::verifyPoint (tcu::TestLog& log, tcu::PixelBufferAccess& image, float pointSize)
{
	const float	expectedPointColor				(1.0f);
	const float	expectedBackgroundColor			(0.0f);
	deUint32	pointWidth						(0u);
	deUint32	pointHeight						(0u);
	bool		incorrectlyColoredPixelsFound	(false);
	bool		isOk							(true);

	// Verify rasterized point width and color
	for (size_t x = 0; x < (deUint32)image.getWidth(); x++)
	{
		float pixelColor = image.getPixel((deUint32)x, image.getHeight() / 2).x();

		if (pixelColor == expectedPointColor)
			pointWidth++;

		if ((pixelColor != expectedPointColor) && (pixelColor != expectedBackgroundColor))
			incorrectlyColoredPixelsFound = true;
	}

	// Verify rasterized point height and color
	for (size_t y = 0; y < (deUint32)image.getHeight(); y++)
	{
		float pixelColor = image.getPixel((deUint32)y, image.getWidth() / 2).x();

		if (pixelColor == expectedPointColor)
			pointHeight++;

		if ((pixelColor != expectedPointColor) && (pixelColor != expectedBackgroundColor))
			incorrectlyColoredPixelsFound = true;
	}

	// Compare amount of rasterized point pixels to expected pointSize.
	if ((pointWidth != (deUint32)deRoundFloatToInt32(pointSize)) || (pointHeight != (deUint32)deRoundFloatToInt32(pointSize)))
	{
		log << tcu::TestLog::Message << "Incorrect point size. Expected pointSize: " << de::toString(pointSize)
			<< ". Rasterized point width: " << pointWidth << " pixels, height: "
			<< pointHeight << " pixels." << tcu::TestLog::EndMessage;

		isOk = false;
	}

	// Check incorrectly colored pixels
	if (incorrectlyColoredPixelsFound)
	{
		log << tcu::TestLog::Message << "Incorrectly colored pixels found." << tcu::TestLog::EndMessage;
		isOk = false;
	}

	return isOk;
}

bool PointSizeTestInstance::isPointSizeClamped (float pointSize, float maxPointSizeLimit)
{
	return (pointSize == maxPointSizeLimit);
}

template <typename ConcreteTestInstance>
class BaseTestCase : public BaseRenderingTestCase
{
public:
							BaseTestCase	(tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
								: BaseRenderingTestCase(context, name, description, sampleCount)
							{}

	virtual TestInstance*	createInstance	(Context& context) const
							{
								return new ConcreteTestInstance(context, m_sampleCount);
							}
};

class TrianglesTestInstance : public BaseTriangleTestInstance
{
public:
							TrianglesTestInstance	(Context& context, VkSampleCountFlagBits sampleCount)
								: BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, sampleCount)
							{}

	void					generateTriangles		(int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
};

void TrianglesTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
{
	outData.resize(6);

	switch (iteration)
	{
		case 0:
			// \note: these values are chosen arbitrarily
			outData[0] = tcu::Vec4( 0.2f,  0.8f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4( 0.5f,  0.2f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4( 0.5f,  0.3f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4(-0.5f,  0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
			outData[5] = tcu::Vec4(-0.4f,  0.2f, 0.0f, 1.0f);
			break;

		case 1:
			outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4(-0.501f,  -0.3f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4(  0.11f,  -0.2f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4(  0.11f,   0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4(  0.88f,   0.9f, 0.0f, 1.0f);
			outData[5] = tcu::Vec4(   0.4f,   1.2f, 0.0f, 1.0f);
			break;

		case 2:
			outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4(  1.1f, -0.9f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4( -1.1f, -0.1f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4(-0.11f,  0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4( 0.88f,  0.7f, 0.0f, 1.0f);
			outData[5] = tcu::Vec4( -0.4f,  0.4f, 0.0f, 1.0f);
			break;
	}

	outTriangles.resize(2);
	outTriangles[0].positions[0] = outData[0];	outTriangles[0].sharedEdge[0] = false;
	outTriangles[0].positions[1] = outData[1];	outTriangles[0].sharedEdge[1] = false;
	outTriangles[0].positions[2] = outData[2];	outTriangles[0].sharedEdge[2] = false;

	outTriangles[1].positions[0] = outData[3];	outTriangles[1].sharedEdge[0] = false;
	outTriangles[1].positions[1] = outData[4];	outTriangles[1].sharedEdge[1] = false;
	outTriangles[1].positions[2] = outData[5];	outTriangles[1].sharedEdge[2] = false;

	// log
	m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outTriangles.size() << " triangle(s):" << tcu::TestLog::EndMessage;
	for (int triangleNdx = 0; triangleNdx < (int)outTriangles.size(); ++triangleNdx)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Triangle " << (triangleNdx+1) << ":"
			<< "\n\t" << outTriangles[triangleNdx].positions[0]
			<< "\n\t" << outTriangles[triangleNdx].positions[1]
			<< "\n\t" << outTriangles[triangleNdx].positions[2]
			<< tcu::TestLog::EndMessage;
	}
}

class TriangleStripTestInstance : public BaseTriangleTestInstance
{
public:
				TriangleStripTestInstance		(Context& context, VkSampleCountFlagBits sampleCount)
					: BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, sampleCount)
				{}

	void		generateTriangles				(int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
};

void TriangleStripTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
{
	outData.resize(5);

	switch (iteration)
	{
		case 0:
			// \note: these values are chosen arbitrarily
			outData[0] = tcu::Vec4(-0.504f,  0.8f,   0.0f, 1.0f);
			outData[1] = tcu::Vec4(-0.2f,   -0.2f,   0.0f, 1.0f);
			outData[2] = tcu::Vec4(-0.2f,    0.199f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4( 0.5f,    0.201f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4( 1.5f,    0.4f,   0.0f, 1.0f);
			break;

		case 1:
			outData[0] = tcu::Vec4(-0.499f, 0.129f,  0.0f, 1.0f);
			outData[1] = tcu::Vec4(-0.501f,  -0.3f,  0.0f, 1.0f);
			outData[2] = tcu::Vec4(  0.11f,  -0.2f,  0.0f, 1.0f);
			outData[3] = tcu::Vec4(  0.11f,  -0.31f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4(  0.88f,   0.9f,  0.0f, 1.0f);
			break;

		case 2:
			outData[0] = tcu::Vec4( -0.9f, -0.3f,  0.0f, 1.0f);
			outData[1] = tcu::Vec4(  1.1f, -0.9f,  0.0f, 1.0f);
			outData[2] = tcu::Vec4(-0.87f, -0.1f,  0.0f, 1.0f);
			outData[3] = tcu::Vec4(-0.11f,  0.19f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4( 0.88f,  0.7f,  0.0f, 1.0f);
			break;
	}

	outTriangles.resize(3);
	outTriangles[0].positions[0] = outData[0];	outTriangles[0].sharedEdge[0] = false;
	outTriangles[0].positions[1] = outData[1];	outTriangles[0].sharedEdge[1] = true;
	outTriangles[0].positions[2] = outData[2];	outTriangles[0].sharedEdge[2] = false;

	outTriangles[1].positions[0] = outData[2];	outTriangles[1].sharedEdge[0] = true;
	outTriangles[1].positions[1] = outData[1];	outTriangles[1].sharedEdge[1] = false;
	outTriangles[1].positions[2] = outData[3];	outTriangles[1].sharedEdge[2] = true;

	outTriangles[2].positions[0] = outData[2];	outTriangles[2].sharedEdge[0] = true;
	outTriangles[2].positions[1] = outData[3];	outTriangles[2].sharedEdge[1] = false;
	outTriangles[2].positions[2] = outData[4];	outTriangles[2].sharedEdge[2] = false;

	// log
	m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle strip, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
	for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "\t" << outData[vtxNdx]
			<< tcu::TestLog::EndMessage;
	}
}

class TriangleFanTestInstance : public BaseTriangleTestInstance
{
public:
				TriangleFanTestInstance			(Context& context, VkSampleCountFlagBits sampleCount);


	void		generateTriangles				(int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
};

TriangleFanTestInstance::TriangleFanTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
	: BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, sampleCount)
{
#ifndef CTS_USES_VULKANSC
	if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
		!context.getPortabilitySubsetFeatures().triangleFans)
	{
		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
	}
#endif // CTS_USES_VULKANSC
}

void TriangleFanTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
{
	outData.resize(5);

	switch (iteration)
	{
		case 0:
			// \note: these values are chosen arbitrarily
			outData[0] = tcu::Vec4( 0.01f,  0.0f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4( 0.5f,   0.2f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4( 0.46f,  0.3f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4(-0.5f,   0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4(-1.5f,  -0.4f, 0.0f, 1.0f);
			break;

		case 1:
			outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4(-0.501f,  -0.3f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4(  0.11f,  -0.2f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4(  0.11f,   0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4(  0.88f,   0.9f, 0.0f, 1.0f);
			break;

		case 2:
			outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4(  1.1f, -0.9f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4(  0.7f, -0.1f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4( 0.11f,  0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4( 0.88f,  0.7f, 0.0f, 1.0f);
			break;
	}

	outTriangles.resize(3);
	outTriangles[0].positions[0] = outData[0];	outTriangles[0].sharedEdge[0] = false;
	outTriangles[0].positions[1] = outData[1];	outTriangles[0].sharedEdge[1] = false;
	outTriangles[0].positions[2] = outData[2];	outTriangles[0].sharedEdge[2] = true;

	outTriangles[1].positions[0] = outData[0];	outTriangles[1].sharedEdge[0] = true;
	outTriangles[1].positions[1] = outData[2];	outTriangles[1].sharedEdge[1] = false;
	outTriangles[1].positions[2] = outData[3];	outTriangles[1].sharedEdge[2] = true;

	outTriangles[2].positions[0] = outData[0];	outTriangles[2].sharedEdge[0] = true;
	outTriangles[2].positions[1] = outData[3];	outTriangles[2].sharedEdge[1] = false;
	outTriangles[2].positions[2] = outData[4];	outTriangles[2].sharedEdge[2] = false;

	// log
	m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle fan, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
	for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "\t" << outData[vtxNdx]
			<< tcu::TestLog::EndMessage;
	}
}

struct ConservativeTestConfig
{
	VkConservativeRasterizationModeEXT	conservativeRasterizationMode;
	float								extraOverestimationSize;
	VkPrimitiveTopology					primitiveTopology;
	bool								degeneratePrimitives;
	float								lineWidth;
	deUint32							resolution;
};

float getExtraOverestimationSize (const float overestimationSizeDesired, const VkPhysicalDeviceConservativeRasterizationPropertiesEXT& conservativeRasterizationProperties)
{
	const float extraOverestimationSize	= overestimationSizeDesired == TCU_INFINITY ? conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize
										: overestimationSizeDesired == -TCU_INFINITY ? conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity
										: overestimationSizeDesired;

	return extraOverestimationSize;
}

template <typename ConcreteTestInstance>
class ConservativeTestCase : public BaseRenderingTestCase
{
public:
									ConservativeTestCase		(tcu::TestContext&					context,
																 const std::string&					name,
																 const std::string&					description,
																 const ConservativeTestConfig&		conservativeTestConfig,
																 VkSampleCountFlagBits				sampleCount = VK_SAMPLE_COUNT_1_BIT)
										: BaseRenderingTestCase		(context, name, description, sampleCount)
										, m_conservativeTestConfig	(conservativeTestConfig)
									{}

	virtual void					checkSupport				(Context& context) const;

	virtual TestInstance*			createInstance				(Context& context) const
									{
										return new ConcreteTestInstance(context, m_conservativeTestConfig, m_sampleCount);
									}

protected:
	bool							isUseLineSubPixel			(Context& context) const;
	deUint32						getSubPixelResolution		(Context& context) const;

	const ConservativeTestConfig	m_conservativeTestConfig;
};

template <typename ConcreteTestInstance>
bool ConservativeTestCase<ConcreteTestInstance>::isUseLineSubPixel (Context& context) const
{
	return (isPrimitiveTopologyLine(m_conservativeTestConfig.primitiveTopology) && context.isDeviceFunctionalitySupported("VK_EXT_line_rasterization"));
}

template <typename ConcreteTestInstance>
deUint32 ConservativeTestCase<ConcreteTestInstance>::getSubPixelResolution (Context& context) const
{
	if (isUseLineSubPixel(context))
	{
		const VkPhysicalDeviceLineRasterizationPropertiesEXT	lineRasterizationPropertiesEXT	= context.getLineRasterizationPropertiesEXT();

		return lineRasterizationPropertiesEXT.lineSubPixelPrecisionBits;
	}
	else
	{
		return context.getDeviceProperties().limits.subPixelPrecisionBits;
	}
}

template <typename ConcreteTestInstance>
void ConservativeTestCase<ConcreteTestInstance>::checkSupport (Context& context) const
{
	context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");

	const VkPhysicalDeviceConservativeRasterizationPropertiesEXT	conservativeRasterizationProperties	= context.getConservativeRasterizationPropertiesEXT();
	const deUint32													subPixelPrecisionBits				= getSubPixelResolution(context);
	const deUint32													subPixelPrecision					= 1<<subPixelPrecisionBits;
	const bool														linesPrecision						= isUseLineSubPixel(context);
	const float														primitiveOverestimationSizeMult		= float(subPixelPrecision) * conservativeRasterizationProperties.primitiveOverestimationSize;
	const bool														topologyLineOrPoint					= isPrimitiveTopologyLine(m_conservativeTestConfig.primitiveTopology) || isPrimitiveTopologyPoint(m_conservativeTestConfig.primitiveTopology);

	DE_ASSERT(subPixelPrecisionBits < sizeof(deUint32) * 8);

	context.getTestContext().getLog()
		<< tcu::TestLog::Message
		<< "maxExtraPrimitiveOverestimationSize="			<< conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize << '\n'
		<< "extraPrimitiveOverestimationSizeGranularity="	<< conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity << '\n'
		<< "degenerateLinesRasterized="						<< conservativeRasterizationProperties.degenerateLinesRasterized << '\n'
		<< "degenerateTrianglesRasterized="					<< conservativeRasterizationProperties.degenerateTrianglesRasterized << '\n'
		<< "primitiveOverestimationSize="					<< conservativeRasterizationProperties.primitiveOverestimationSize << " (==" << primitiveOverestimationSizeMult << '/' << subPixelPrecision << ")\n"
		<< "subPixelPrecisionBits="							<< subPixelPrecisionBits << (linesPrecision ? " (using VK_EXT_line_rasterization)" : " (using limits)") << '\n'
		<< tcu::TestLog::EndMessage;

	if (conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity > conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize)
		TCU_FAIL("Granularity cannot be greater than maximum extra size");

	if (topologyLineOrPoint)
	{
		if (!conservativeRasterizationProperties.conservativePointAndLineRasterization)
			TCU_THROW(NotSupportedError, "Conservative line and point rasterization is not supported");
	}

	if (m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT)
	{
		if (conservativeRasterizationProperties.primitiveUnderestimation == DE_FALSE)
			TCU_THROW(NotSupportedError, "Underestimation is not supported");

		if (isPrimitiveTopologyLine(m_conservativeTestConfig.primitiveTopology))
		{
			const float	testLineWidth	= m_conservativeTestConfig.lineWidth;

			if (testLineWidth != 1.0f)
			{
				const VkPhysicalDeviceLimits&	limits					= context.getDeviceProperties().limits;
				const float						lineWidthRange[2]		= { limits.lineWidthRange[0], limits.lineWidthRange[1] };
				const float						lineWidthGranularity	= limits.lineWidthGranularity;

				context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);

				if (lineWidthGranularity == 0.0f)
					TCU_THROW(NotSupportedError, "Wide lines required for test, but are not supported");

				DE_ASSERT(lineWidthGranularity > 0.0f && lineWidthRange[0] > 0.0f && lineWidthRange[1] >= lineWidthRange[0]);

				if (!de::inBounds(testLineWidth, lineWidthRange[0], lineWidthRange[1]))
					TCU_THROW(NotSupportedError, "Tested line width is not supported");

				const float	n	= (testLineWidth - lineWidthRange[0]) / lineWidthGranularity;

				if (deFloatFrac(n) != 0.0f || n * lineWidthGranularity + lineWidthRange[0] != testLineWidth)
					TCU_THROW(NotSupportedError, "Exact match of line width is required for the test");
			}
		}
		else if (isPrimitiveTopologyPoint(m_conservativeTestConfig.primitiveTopology))
		{
			const float	testPointSize	= m_conservativeTestConfig.lineWidth;

			if (testPointSize != 1.0f)
			{
				const VkPhysicalDeviceLimits&	limits					= context.getDeviceProperties().limits;
				const float						pointSizeRange[2]		= { limits.pointSizeRange[0], limits.pointSizeRange[1] };
				const float						pointSizeGranularity	= limits.pointSizeGranularity;

				context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);

				if (pointSizeGranularity == 0.0f)
					TCU_THROW(NotSupportedError, "Large points required for test, but are not supported");

				DE_ASSERT(pointSizeGranularity > 0.0f && pointSizeRange[0] > 0.0f && pointSizeRange[1] >= pointSizeRange[0]);

				if (!de::inBounds(testPointSize, pointSizeRange[0], pointSizeRange[1]))
					TCU_THROW(NotSupportedError, "Tested point size is not supported");

				const float	n	= (testPointSize - pointSizeRange[0]) / pointSizeGranularity;

				if (deFloatFrac(n) != 0.0f || n * pointSizeGranularity + pointSizeRange[0] != testPointSize)
					TCU_THROW(NotSupportedError, "Exact match of point size is required for the test");
			}
		}
	}
	else if (m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT)
	{
		const float extraOverestimationSize	= getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, conservativeRasterizationProperties);

		if (extraOverestimationSize > conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize)
			TCU_THROW(NotSupportedError, "Specified overestimation size is not supported");

		if (topologyLineOrPoint)
		{
			if (!conservativeRasterizationProperties.conservativePointAndLineRasterization)
				TCU_THROW(NotSupportedError, "Conservative line and point rasterization is not supported");
		}

		if (isPrimitiveTopologyTriangle(m_conservativeTestConfig.primitiveTopology))
		{
			if (m_conservativeTestConfig.degeneratePrimitives)
			{
				// Enforce specification minimum required limit to avoid division by zero
				DE_ASSERT(subPixelPrecisionBits >= 4);

				// Make sure float precision of 22 bits is enough, i.e. resoultion in subpixel quarters less than float precision
				if (m_conservativeTestConfig.resolution * (1<<(subPixelPrecisionBits + 2)) > (1<<21))
					TCU_THROW(NotSupportedError, "Subpixel resolution is too high to generate degenerate primitives");
			}
		}
	}
	else
		TCU_THROW(InternalError, "Non-conservative mode tests are not supported by this class");
}

class ConservativeTraingleTestInstance : public BaseTriangleTestInstance
{
public:
																				ConservativeTraingleTestInstance				(Context&				context,
																																 ConservativeTestConfig	conservativeTestConfig,
																																 VkSampleCountFlagBits	sampleCount)
																					: BaseTriangleTestInstance						(context,
																																	 conservativeTestConfig.primitiveTopology,
																																	 sampleCount,
																																	 conservativeTestConfig.resolution)
																					, m_conservativeTestConfig						(conservativeTestConfig)
																					, m_conservativeRasterizationProperties			(context.getConservativeRasterizationPropertiesEXT())
																					, m_rasterizationConservativeStateCreateInfo	(initRasterizationConservativeStateCreateInfo())
																					, m_rasterizationStateCreateInfo				(initRasterizationStateCreateInfo())
																				{}

	void																		generateTriangles								(int											iteration,
																																 std::vector<tcu::Vec4>&						outData,
																																 std::vector<TriangleSceneSpec::SceneTriangle>&	outTriangles);
	const VkPipelineRasterizationStateCreateInfo*								getRasterizationStateCreateInfo					(void) const;

protected:
	virtual const VkPipelineRasterizationLineStateCreateInfoEXT*				getLineRasterizationStateCreateInfo				(void);

	virtual bool																compareAndVerify								(std::vector<TriangleSceneSpec::SceneTriangle>&	triangles,
																																 tcu::Surface&									resultImage,
																																 std::vector<tcu::Vec4>&						drawBuffer);
	virtual bool																compareAndVerifyOverestimatedNormal				(std::vector<TriangleSceneSpec::SceneTriangle>&	triangles,
																																 tcu::Surface&									resultImage);
	virtual bool																compareAndVerifyOverestimatedDegenerate			(std::vector<TriangleSceneSpec::SceneTriangle>&	triangles,
																																 tcu::Surface&									resultImage);
	virtual bool																compareAndVerifyUnderestimatedNormal			(std::vector<TriangleSceneSpec::SceneTriangle>&	triangles,
																																 tcu::Surface&									resultImage);
	virtual bool																compareAndVerifyUnderestimatedDegenerate		(std::vector<TriangleSceneSpec::SceneTriangle>&	triangles,
																																 tcu::Surface&									resultImage);
	void																		generateNormalTriangles							(int											iteration,
																																 std::vector<tcu::Vec4>&						outData,
																																 std::vector<TriangleSceneSpec::SceneTriangle>&	outTriangles);
	void																		generateDegenerateTriangles					(int											iteration,
																																 std::vector<tcu::Vec4>&						outData,
																																 std::vector<TriangleSceneSpec::SceneTriangle>&	outTriangles);
	void																		drawPrimitives									(tcu::Surface&									result,
																																 const std::vector<tcu::Vec4>&					vertexData,
																																 VkPrimitiveTopology							primitiveTopology);

private:
	const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT>	initRasterizationConservativeStateCreateInfo	(void);
	const std::vector<VkPipelineRasterizationStateCreateInfo>					initRasterizationStateCreateInfo				(void);

	const ConservativeTestConfig												m_conservativeTestConfig;
	const VkPhysicalDeviceConservativeRasterizationPropertiesEXT				m_conservativeRasterizationProperties;
	const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT>	m_rasterizationConservativeStateCreateInfo;
	const std::vector<VkPipelineRasterizationStateCreateInfo>					m_rasterizationStateCreateInfo;
};

void ConservativeTraingleTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
{
	if (m_conservativeTestConfig.degeneratePrimitives)
		generateDegenerateTriangles(iteration, outData, outTriangles);
	else
		generateNormalTriangles(iteration, outData, outTriangles);
}

void ConservativeTraingleTestInstance::generateNormalTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
{
	const float	halfPixel						= 1.0f / float(m_renderSize);
	const float extraOverestimationSize			= getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
	const float	overestimate					= 2.0f * halfPixel * (m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize);
	const float	overestimateMargin				= overestimate;
	const float	underestimateMargin				= 0.0f;
	const bool	isOverestimate					= m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
	const float	margin							= isOverestimate ? overestimateMargin : underestimateMargin;
	const char*	overestimateIterationComments[]	= { "Corner touch", "Any portion pixel coverage", "Edge touch" };

	outData.resize(6);

	switch (iteration)
	{
		case 0:
		{
			// Corner touch
			const float edge	= 2 * halfPixel + margin;
			const float left	= -1.0f + edge;
			const float right	= +1.0f - edge;
			const float up		= -1.0f + edge;
			const float down	= +1.0f - edge;

			outData[0] = tcu::Vec4( left, down, 0.0f, 1.0f);
			outData[1] = tcu::Vec4( left,   up, 0.0f, 1.0f);
			outData[2] = tcu::Vec4(right, down, 0.0f, 1.0f);

			outData[3] = tcu::Vec4( left,   up, 0.0f, 1.0f);
			outData[4] = tcu::Vec4(right, down, 0.0f, 1.0f);
			outData[5] = tcu::Vec4(right,   up, 0.0f, 1.0f);

			break;
		}

		case 1:
		{
			// Partial coverage
			const float eps		= halfPixel / 32.0f;
			const float edge	= 4.0f * halfPixel  + margin - eps;
			const float left	= -1.0f + edge;
			const float right	= +1.0f - edge;
			const float up		= -1.0f + edge;
			const float down	= +1.0f - edge;

			outData[0] = tcu::Vec4( left, down, 0.0f, 1.0f);
			outData[1] = tcu::Vec4( left,   up, 0.0f, 1.0f);
			outData[2] = tcu::Vec4(right, down, 0.0f, 1.0f);

			outData[3] = tcu::Vec4( left,   up, 0.0f, 1.0f);
			outData[4] = tcu::Vec4(right, down, 0.0f, 1.0f);
			outData[5] = tcu::Vec4(right,   up, 0.0f, 1.0f);

			break;
		}

		case 2:
		{
			// Edge touch
			const float edge	= 6.0f * halfPixel + margin;
			const float left	= -1.0f + edge;
			const float right	= +1.0f - edge;
			const float up		= -1.0f + edge;
			const float down	= +1.0f - edge;

			outData[0] = tcu::Vec4( left, down, 0.0f, 1.0f);
			outData[1] = tcu::Vec4( left,   up, 0.0f, 1.0f);
			outData[2] = tcu::Vec4(right, down, 0.0f, 1.0f);

			outData[3] = tcu::Vec4( left,   up, 0.0f, 1.0f);
			outData[4] = tcu::Vec4(right, down, 0.0f, 1.0f);
			outData[5] = tcu::Vec4(right,   up, 0.0f, 1.0f);

			break;
		}

		default:
			TCU_THROW(InternalError, "Unexpected iteration");
	}

	outTriangles.resize(outData.size() / 3);

	for (size_t ndx = 0; ndx < outTriangles.size(); ++ndx)
	{
		outTriangles[ndx].positions[0] = outData[3 * ndx + 0];	outTriangles[ndx].sharedEdge[0] = false;
		outTriangles[ndx].positions[1] = outData[3 * ndx + 1];	outTriangles[ndx].sharedEdge[1] = false;
		outTriangles[ndx].positions[2] = outData[3 * ndx + 2];	outTriangles[ndx].sharedEdge[2] = false;
	}

	// log
	if (isOverestimate)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Testing " << overestimateIterationComments[iteration] << " "
			<< "with rendering " << outTriangles.size() << " triangle(s):"
			<< tcu::TestLog::EndMessage;
	}
	else
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Rendering " << outTriangles.size() << " triangle(s):"
			<< tcu::TestLog::EndMessage;
	}

	for (size_t ndx = 0; ndx < outTriangles.size(); ++ndx)
	{
		const deUint32	 multiplier	= m_renderSize / 2;

		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Triangle " << (ndx + 1) << ":"
			<< "\n\t" << outTriangles[ndx].positions[0] << " == " << (float(multiplier) * outTriangles[ndx].positions[0]) << "/" << multiplier
			<< "\n\t" << outTriangles[ndx].positions[1] << " == " << (float(multiplier) * outTriangles[ndx].positions[1]) << "/" << multiplier
			<< "\n\t" << outTriangles[ndx].positions[2] << " == " << (float(multiplier) * outTriangles[ndx].positions[2]) << "/" << multiplier
			<< tcu::TestLog::EndMessage;
	}
}

void ConservativeTraingleTestInstance::generateDegenerateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
{
	tcu::TestLog&	log								= m_context.getTestContext().getLog();
	const float		pixelSize						= 2.0f / float(m_renderSize);
	const deUint32	subPixels						= 1u << m_context.getDeviceProperties().limits.subPixelPrecisionBits;
	const float		subPixelSize					= pixelSize / float(subPixels);
	const float		extraOverestimationSize			= getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
	const float		totalOverestimate				= m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize;
	const float		totalOverestimateInSubPixels	= deFloatCeil(totalOverestimate * float(subPixels));
	const float		overestimate					= subPixelSize * totalOverestimateInSubPixels;
	const float		overestimateSafetyMargin		= subPixelSize * 0.125f;
	const float		overestimateMargin				= overestimate + overestimateSafetyMargin;
	const float		underestimateMargin				= 0.0f;
	const bool		isOverestimate					= m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
	const float		margin							= isOverestimate ? overestimateMargin : underestimateMargin;
	const char*		overestimateIterationComments[]	= { "Backfacing", "Generate pixels", "Use provoking vertex" };

	if (pixelSize < 2 * overestimateMargin)
		TCU_THROW(NotSupportedError, "Could not generate degenerate triangle for such overestimate parameters");

	outData.clear();

	switch (iteration)
	{
		case 0:
		case 1:
		case 2:
		{
			for (int rowNdx = 0; rowNdx < 3; ++rowNdx)
			for (int colNdx = 0; colNdx < 4; ++colNdx)
			{
				const float	offsetX		= -1.0f + float(4 * (colNdx + 1)) * pixelSize;
				const float	offsetY		= -1.0f + float(4 * (rowNdx + 1)) * pixelSize;
				const float	left		= offsetX + margin;
				const float	right		= offsetX + margin + 0.25f * subPixelSize;
				const float	up			= offsetY + margin;
				const float	down		= offsetY + margin + 0.25f * subPixelSize;
				const bool	luPresent	= (rowNdx & 1) == 0;
				const bool	rdPresent	= (rowNdx & 2) == 0;
				const bool	luCW		= (colNdx & 1) == 0;
				const bool	rdCW		= (colNdx & 2) == 0;

				DE_ASSERT(left < right);
				DE_ASSERT(up < down);

				if (luPresent)
				{
					if (luCW)
					{
						// CW triangle left up
						outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
						outData.push_back(tcu::Vec4( left,   up, 0.0f, 1.0f));
						outData.push_back(tcu::Vec4(right,   up, 0.0f, 1.0f));
					}
					else
					{
						// CCW triangle left up
						outData.push_back(tcu::Vec4(right,   up, 0.0f, 1.0f));
						outData.push_back(tcu::Vec4( left,   up, 0.0f, 1.0f));
						outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
					}
				}

				if (rdPresent)
				{
					if (rdCW)
					{
						// CW triangle right down
						outData.push_back(tcu::Vec4(right,   up, 0.0f, 1.0f));
						outData.push_back(tcu::Vec4(right, down, 0.0f, 1.0f));
						outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
					}
					else
					{
						// CCW triangle right down
						outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
						outData.push_back(tcu::Vec4(right, down, 0.0f, 1.0f));
						outData.push_back(tcu::Vec4(right,   up, 0.0f, 1.0f));
					}
				}
			}

			break;
		}

		default:
			TCU_THROW(InternalError, "Unexpected iteration");
	}

	outTriangles.resize(outData.size() / 3);

	for (size_t ndx = 0; ndx < outTriangles.size(); ++ndx)
	{
		outTriangles[ndx].positions[0] = outData[3 * ndx + 0];	outTriangles[ndx].sharedEdge[0] = false;
		outTriangles[ndx].positions[1] = outData[3 * ndx + 1];	outTriangles[ndx].sharedEdge[1] = false;
		outTriangles[ndx].positions[2] = outData[3 * ndx + 2];	outTriangles[ndx].sharedEdge[2] = false;
	}

	// log
	if (isOverestimate)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Testing " << overestimateIterationComments[iteration] << " "
			<< "with rendering " << outTriangles.size() << " triangle(s):"
			<< tcu::TestLog::EndMessage;
	}
	else
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Rendering " << outTriangles.size() << " triangle(s):"
			<< tcu::TestLog::EndMessage;
	}

	for (int ndx = 0; ndx < (int)outTriangles.size(); ++ndx)
	{
		const deUint32	multiplierInt	= m_renderSize / 2;
		const deUint32	multiplierFrac	= subPixels;
		std::string		coordsString;

		for (size_t vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
		{
			const tcu::Vec4&	pos				= outTriangles[ndx].positions[vertexNdx];
			std::ostringstream	coordsFloat;
			std::ostringstream	coordsNatural;

			for (int coordNdx = 0; coordNdx < 2; ++coordNdx)
			{
				const char*	sep		= (coordNdx < 1) ? "," : "";
				const float	coord	= pos[coordNdx];
				const char	sign	= deSign(coord) < 0 ? '-' : '+';
				const float	m		= deFloatFloor(float(multiplierInt) * deFloatAbs(coord));
				const float	r		= deFloatFrac(float(multiplierInt) * deFloatAbs(coord)) * float(multiplierFrac);

				coordsFloat << std::fixed << std::setw(13) << std::setprecision(10) << coord << sep;
				coordsNatural << sign << '(' << m << '+' << r << '/' << multiplierFrac << ')' << sep;
			}

			coordsString += "\n\t[" + coordsFloat.str() + "] == [" + coordsNatural.str() + "] / " + de::toString(multiplierInt);
		}

		log << tcu::TestLog::Message
			<< "Triangle " << (ndx + 1) << ':'
			<< coordsString
			<< tcu::TestLog::EndMessage;
	}
}

void ConservativeTraingleTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
{
	if (m_conservativeTestConfig.degeneratePrimitives && getIteration() == 2)
	{
		// Set provoking vertex color to white
		tcu::Vec4				colorProvoking	(1.0f, 1.0f, 1.0f, 1.0f);
		tcu::Vec4				colorOther		(0.0f, 1.0f, 1.0f, 1.0f);
		std::vector<tcu::Vec4>	colorData;

		colorData.reserve(vertexData.size());

		for (size_t vertexNdx = 0; vertexNdx < vertexData.size(); ++vertexNdx)
			if (vertexNdx % 3 == 0)
				colorData.push_back(colorProvoking);
			else
				colorData.push_back(colorOther);

		BaseRenderingTestInstance::drawPrimitives(result, vertexData, colorData, primitiveTopology);
	}
	else
		BaseRenderingTestInstance::drawPrimitives(result, vertexData, primitiveTopology);
}

bool ConservativeTraingleTestInstance::compareAndVerify (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
{
	DE_UNREF(drawBuffer);

	switch (m_conservativeTestConfig.conservativeRasterizationMode)
	{
		case VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT:
		{
			if (m_conservativeTestConfig.degeneratePrimitives)
				return compareAndVerifyOverestimatedDegenerate(triangles, resultImage);
			else
				return compareAndVerifyOverestimatedNormal(triangles, resultImage);
		}

		case VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT:
		{
			if (m_conservativeTestConfig.degeneratePrimitives)
				return compareAndVerifyUnderestimatedDegenerate(triangles, resultImage);
			else
				return compareAndVerifyUnderestimatedNormal(triangles, resultImage);
		}

		default:
			TCU_THROW(InternalError, "Unknown conservative rasterization mode");
	}
}

bool ConservativeTraingleTestInstance::compareAndVerifyOverestimatedNormal (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
{
	DE_UNREF(triangles);

	const int			start					= getIteration() + 1;
	const int			end						= resultImage.getHeight() - start;
	const tcu::RGBA		backgroundColor			= tcu::RGBA(0, 0, 0, 255);
	const tcu::RGBA		foregroundColor			= tcu::RGBA(255, 255, 255, 255);
	const tcu::RGBA		unexpectedPixelColor	= tcu::RGBA(255, 0, 0, 255);
	tcu::TestLog&		log						= m_context.getTestContext().getLog();
	int					errX					= 0;
	int					errY					= 0;
	deUint32			errValue				= 0;
	bool				result					= true;

	DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());

	for (int y = start; result && y < end; ++y)
	for (int x = start; result && x < end; ++x)
	{
		if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
		{
			result		= false;
			errX		= x;
			errY		= y;
			errValue	= resultImage.getPixel(x,y).getPacked();

			break;
		}
	}

	if (!result)
	{
		tcu::Surface	errorMask		(resultImage.getWidth(), resultImage.getHeight());
		tcu::Surface	expectedImage	(resultImage.getWidth(), resultImage.getHeight());

		for (int y = 0; y < errorMask.getHeight(); ++y)
		for (int x = 0; x < errorMask.getWidth(); ++x)
		{
			errorMask.setPixel(x, y, backgroundColor);
			expectedImage.setPixel(x, y, backgroundColor);
		}

		for (int y = start; y < end; ++y)
		for (int x = start; x < end; ++x)
		{
			expectedImage.setPixel(x, y, foregroundColor);

			if (resultImage.getPixel(x, y).getPacked() != foregroundColor.getPacked())
				errorMask.setPixel(x, y, unexpectedPixelColor);
		}

		log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		resultImage)
			<< tcu::TestLog::Image("Expected",	"Expected",		expectedImage)
			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", resultImage)
			<< tcu::TestLog::EndImageSet;
	}

	return result;
}

bool ConservativeTraingleTestInstance::compareAndVerifyOverestimatedDegenerate (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
{
	DE_UNREF(triangles);

	const char*			iterationComments[]		= { "Cull back face triangles", "Cull front face triangles", "Cull none" };
	const tcu::RGBA		backgroundColor			= tcu::RGBA(0, 0, 0, 255);
	const tcu::RGBA		foregroundColor			= tcu::RGBA(255, 255, 255, 255);
	const tcu::RGBA		unexpectedPixelColor	= tcu::RGBA(255, 0, 0, 255);
	tcu::TestLog&		log						= m_context.getTestContext().getLog();
	bool				result					= true;
	tcu::Surface		referenceImage			(resultImage.getWidth(), resultImage.getHeight());

	for (int y = 0; y < resultImage.getHeight(); ++y)
	for (int x = 0; x < resultImage.getWidth(); ++x)
		referenceImage.setPixel(x, y, backgroundColor);

	if (m_conservativeRasterizationProperties.degenerateTrianglesRasterized)
	{
		if (getIteration() != 0)
		{
			log << tcu::TestLog::Message << "Triangles expected to be rasterized with at least one pixel of white color each" << tcu::TestLog::EndMessage;

			for (int rowNdx = 0; rowNdx < 3; ++rowNdx)
			for (int colNdx = 0; colNdx < 4; ++colNdx)
			{
				referenceImage.setPixel(4 * (colNdx + 1), 4 * (rowNdx + 1), foregroundColor);

				// Allow implementations that need to be extra conservative with degenerate triangles,
				// which may cause extra coverage.
				if (resultImage.getPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1) - 1) == foregroundColor)
					referenceImage.setPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1) - 1, foregroundColor);
				if (resultImage.getPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1)) == foregroundColor)
					referenceImage.setPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1), foregroundColor);
				if (resultImage.getPixel(4 * (colNdx + 1), 4 * (rowNdx + 1) - 1) == foregroundColor)
					referenceImage.setPixel(4 * (colNdx + 1), 4 * (rowNdx + 1) - 1, foregroundColor);
			}
		}
		else
			log << tcu::TestLog::Message << "Triangles expected to be culled due to backfacing culling and all degenerate triangles assumed to be backfacing" << tcu::TestLog::EndMessage;
	}
	else
		log << tcu::TestLog::Message << "Triangles expected to be culled due to degenerateTrianglesRasterized=false" << tcu::TestLog::EndMessage;

	for (int y = 0; result && y < resultImage.getHeight(); ++y)
	for (int x = 0; result && x < resultImage.getWidth(); ++x)
	{
		if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
		{
			result = false;

			break;
		}
	}

	if (!result)
	{
		tcu::Surface	errorMask	(resultImage.getWidth(), resultImage.getHeight());

		for (int y = 0; y < errorMask.getHeight(); ++y)
		for (int x = 0; x < errorMask.getWidth(); ++x)
		{
			if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
				errorMask.setPixel(x, y, unexpectedPixelColor);
			else
				errorMask.setPixel(x, y, backgroundColor);
		}

		log << tcu::TestLog::Message << "Invalid pixels found for mode '" << iterationComments[getIteration()] << "'"
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		resultImage)
			<< tcu::TestLog::Image("Reference",	"Reference",	referenceImage)
			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", resultImage)
			<< tcu::TestLog::EndImageSet;
	}

	return result;
}

bool ConservativeTraingleTestInstance::compareAndVerifyUnderestimatedNormal (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
{
	DE_UNREF(triangles);

	const tcu::RGBA		backgroundColor			= tcu::RGBA(0, 0, 0, 255);
	const tcu::RGBA		foregroundColor			= tcu::RGBA(255, 255, 255, 255);
	const tcu::RGBA		unexpectedPixelColor	= tcu::RGBA(255, 0, 0, 255);
	const tcu::IVec2	viewportSize			= tcu::IVec2(resultImage.getWidth(), resultImage.getHeight());
	tcu::TestLog&		log						= m_context.getTestContext().getLog();
	int					errX					= -1;
	int					errY					= -1;
	deUint32			errValue				= 0;
	tcu::Surface		referenceImage			(resultImage.getWidth(), resultImage.getHeight());
	bool				result					= true;

	DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());

	for (int y = 0; y < resultImage.getHeight(); ++y)
	for (int x = 0; x < resultImage.getWidth(); ++x)
		referenceImage.setPixel(x, y, backgroundColor);

	for (size_t triangleNdx = 0; triangleNdx < triangles.size(); ++triangleNdx)
	{
		const tcu::Vec4&	p0	= triangles[triangleNdx].positions[0];
		const tcu::Vec4&	p1	= triangles[triangleNdx].positions[1];
		const tcu::Vec4&	p2	= triangles[triangleNdx].positions[2];

		for (int y = 0; y < resultImage.getHeight(); ++y)
		for (int x = 0; x < resultImage.getWidth(); ++x)
		{
			if (calculateUnderestimateTriangleCoverage(p0, p1, p2, tcu::IVec2(x,y), m_subpixelBits, viewportSize) == tcu::COVERAGE_FULL)
				referenceImage.setPixel(x, y, foregroundColor);
		}
	}

	for (int y = 0; result && y < resultImage.getHeight(); ++y)
	for (int x = 0; result && x < resultImage.getWidth(); ++x)
		if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
		{
			result		= false;
			errX		= x;
			errY		= y;
			errValue	= resultImage.getPixel(x,y).getPacked();
		}

	if (!result)
	{
		tcu::Surface	errorMask	(resultImage.getWidth(), resultImage.getHeight());

		for (int y = 0; y < errorMask.getHeight(); ++y)
		for (int x = 0; x < errorMask.getWidth(); ++x)
		{
			if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
				errorMask.setPixel(x, y, unexpectedPixelColor);
			else
				errorMask.setPixel(x, y, backgroundColor);
		}

		log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		resultImage)
			<< tcu::TestLog::Image("Refernce",	"Refernce",		referenceImage)
			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", resultImage)
			<< tcu::TestLog::EndImageSet;
	}

	return result;
}

bool ConservativeTraingleTestInstance::compareAndVerifyUnderestimatedDegenerate (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
{
	DE_UNREF(triangles);

	const char*			iterationComments[]		= { "Cull back face triangles", "Cull front face triangles", "Cull none" };
	const tcu::RGBA		backgroundColor			= tcu::RGBA(0, 0, 0, 255);
	const tcu::RGBA		unexpectedPixelColor	= tcu::RGBA(255, 0, 0, 255);
	tcu::TestLog&		log						= m_context.getTestContext().getLog();
	int					errX					= 0;
	int					errY					= 0;
	deUint32			errValue				= 0;
	bool				result					= true;

	if (m_conservativeRasterizationProperties.degenerateTrianglesRasterized)
	{
		if (getIteration() != 0)
			log << tcu::TestLog::Message << "Triangles expected to be not rendered due to no one triangle can fully cover fragment" << tcu::TestLog::EndMessage;
		else
			log << tcu::TestLog::Message << "Triangles expected to be culled due to backfacing culling and all degenerate triangles assumed to be backfacing" << tcu::TestLog::EndMessage;
	}
	else
		log << tcu::TestLog::Message << "Triangles expected to be culled due to degenerateTrianglesRasterized=false" << tcu::TestLog::EndMessage;

	for (int y = 0; result && y < resultImage.getHeight(); ++y)
	for (int x = 0; result && x < resultImage.getWidth(); ++x)
	{
		if (resultImage.getPixel(x, y).getPacked() != backgroundColor.getPacked())
		{
			result		= false;
			errX		= x;
			errY		= y;
			errValue	= resultImage.getPixel(x,y).getPacked();

			break;
		}
	}

	if (!result)
	{
		tcu::Surface	referenceImage	(resultImage.getWidth(), resultImage.getHeight());
		tcu::Surface	errorMask		(resultImage.getWidth(), resultImage.getHeight());

		for (int y = 0; y < resultImage.getHeight(); ++y)
		for (int x = 0; x < resultImage.getWidth(); ++x)
			referenceImage.setPixel(x, y, backgroundColor);

		for (int y = 0; y < errorMask.getHeight(); ++y)
		for (int x = 0; x < errorMask.getWidth(); ++x)
		{
			if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
				errorMask.setPixel(x, y, unexpectedPixelColor);
			else
				errorMask.setPixel(x, y, backgroundColor);
		}

		log << tcu::TestLog::Message << "Invalid pixels found for mode '" << iterationComments[getIteration()] << "' starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
			<< tcu::TestLog::EndMessage;

		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		resultImage)
			<< tcu::TestLog::Image("Reference",	"Reference",	referenceImage)
			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", resultImage)
			<< tcu::TestLog::EndImageSet;
	}

	return result;
}

const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> ConservativeTraingleTestInstance::initRasterizationConservativeStateCreateInfo (void)
{
	const float															extraOverestimationSize	= getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
	std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT>	result;

	result.reserve(getIterationCount());

	for (int iteration = 0; iteration < getIterationCount(); ++iteration)
	{
		const VkPipelineRasterizationConservativeStateCreateInfoEXT	rasterizationConservativeStateCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT,	//  VkStructureType											sType;
			DE_NULL,																		//  const void*												pNext;
			(VkPipelineRasterizationConservativeStateCreateFlagsEXT)0,						//  VkPipelineRasterizationConservativeStateCreateFlagsEXT	flags;
			m_conservativeTestConfig.conservativeRasterizationMode,							//  VkConservativeRasterizationModeEXT						conservativeRasterizationMode;
			extraOverestimationSize															//  float													extraPrimitiveOverestimationSize;
		};

		result.push_back(rasterizationConservativeStateCreateInfo);
	}

	return result;
}

const std::vector<VkPipelineRasterizationStateCreateInfo> ConservativeTraingleTestInstance::initRasterizationStateCreateInfo (void)
{
	std::vector<VkPipelineRasterizationStateCreateInfo>	result;

	result.reserve(getIterationCount());

	for (int iteration = 0; iteration < getIterationCount(); ++iteration)
	{
		const VkCullModeFlags							cullModeFlags					= (!m_conservativeTestConfig.degeneratePrimitives) ? VK_CULL_MODE_NONE
																						: (iteration == 0) ? VK_CULL_MODE_BACK_BIT
																						: (iteration == 1) ? VK_CULL_MODE_FRONT_BIT
																						: VK_CULL_MODE_NONE;

		const VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		//  VkStructureType							sType;
			&m_rasterizationConservativeStateCreateInfo[iteration],			//  const void*								pNext;
			0,																//  VkPipelineRasterizationStateCreateFlags	flags;
			false,															//  VkBool32								depthClampEnable;
			false,															//  VkBool32								rasterizerDiscardEnable;
			VK_POLYGON_MODE_FILL,											//  VkPolygonMode							polygonMode;
			cullModeFlags,													//  VkCullModeFlags							cullMode;
			VK_FRONT_FACE_COUNTER_CLOCKWISE,								//  VkFrontFace								frontFace;
			VK_FALSE,														//  VkBool32								depthBiasEnable;
			0.0f,															//  float									depthBiasConstantFactor;
			0.0f,															//  float									depthBiasClamp;
			0.0f,															//  float									depthBiasSlopeFactor;
			getLineWidth(),													//  float									lineWidth;
		};

		result.push_back(rasterizationStateCreateInfo);
	}

	return result;
}

const VkPipelineRasterizationStateCreateInfo* ConservativeTraingleTestInstance::getRasterizationStateCreateInfo	(void) const
{
	return &m_rasterizationStateCreateInfo[getIteration()];
}

const VkPipelineRasterizationLineStateCreateInfoEXT* ConservativeTraingleTestInstance::getLineRasterizationStateCreateInfo	(void)
{
	return DE_NULL;
}


class ConservativeLineTestInstance : public BaseLineTestInstance
{
public:
																				ConservativeLineTestInstance					(Context&								context,
																																 ConservativeTestConfig					conservativeTestConfig,
																																 VkSampleCountFlagBits					sampleCount);

	void																		generateLines									(int									iteration,
																																 std::vector<tcu::Vec4>&				outData,
																																 std::vector<LineSceneSpec::SceneLine>&	outLines);
	const VkPipelineRasterizationStateCreateInfo*								getRasterizationStateCreateInfo					(void) const;

protected:
	virtual const VkPipelineRasterizationLineStateCreateInfoEXT*				getLineRasterizationStateCreateInfo				(void);

	virtual bool																compareAndVerify								(std::vector<LineSceneSpec::SceneLine>&	lines,
																																 tcu::Surface&							resultImage,
																																 std::vector<tcu::Vec4>&				drawBuffer);
	virtual bool																compareAndVerifyOverestimatedNormal				(std::vector<LineSceneSpec::SceneLine>&	lines,
																																 tcu::Surface&							resultImage);
	virtual bool																compareAndVerifyOverestimatedDegenerate			(std::vector<LineSceneSpec::SceneLine>&	lines,
																																 tcu::Surface&							resultImage);
	virtual bool																compareAndVerifyUnderestimatedNormal			(std::vector<LineSceneSpec::SceneLine>&	lines,
																																 tcu::Surface&							resultImage);
	virtual bool																compareAndVerifyUnderestimatedDegenerate		(std::vector<LineSceneSpec::SceneLine>&	lines,
																																 tcu::Surface&							resultImage);
	void																		generateNormalLines								(int									iteration,
																																 std::vector<tcu::Vec4>&				outData,
																																 std::vector<LineSceneSpec::SceneLine>&	outLines);
	void																		generateDegenerateLines							(int									iteration,
																																 std::vector<tcu::Vec4>&				outData,
																																 std::vector<LineSceneSpec::SceneLine>&	outLines);
	void																		drawPrimitives									(tcu::Surface&							result,
																																 const std::vector<tcu::Vec4>&			vertexData,
																																 VkPrimitiveTopology					primitiveTopology);

private:
	const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT>	initRasterizationConservativeStateCreateInfo	(void);
	const std::vector<VkPipelineRasterizationStateCreateInfo>					initRasterizationStateCreateInfo				(void);

	const ConservativeTestConfig												m_conservativeTestConfig;
	const VkPhysicalDeviceConservativeRasterizationPropertiesEXT				m_conservativeRasterizationProperties;
	const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT>	m_rasterizationConservativeStateCreateInfo;
	const std::vector<VkPipelineRasterizationStateCreateInfo>					m_rasterizationStateCreateInfo;
};

ConservativeLineTestInstance::ConservativeLineTestInstance (Context&				context,
															ConservativeTestConfig	conservativeTestConfig,
															VkSampleCountFlagBits	sampleCount)
	: BaseLineTestInstance							(
														context,
														conservativeTestConfig.primitiveTopology,
														PRIMITIVEWIDENESS_NARROW,
														PRIMITIVESTRICTNESS_IGNORE,
														sampleCount,
														LINESTIPPLE_DISABLED,
														VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT,
														LineStippleFactorCase::DEFAULT,
														0,
														conservativeTestConfig.resolution,
														conservativeTestConfig.lineWidth
													)
	, m_conservativeTestConfig						(conservativeTestConfig)
	, m_conservativeRasterizationProperties			(context.getConservativeRasterizationPropertiesEXT())
	, m_rasterizationConservativeStateCreateInfo	(initRasterizationConservativeStateCreateInfo())
	, m_rasterizationStateCreateInfo				(initRasterizationStateCreateInfo())
{
}

void ConservativeLineTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
{
	if (m_conservativeTestConfig.degeneratePrimitives)
		generateDegenerateLines(iteration, outData, outLines);
	else
		generateNormalLines(iteration, outData, outLines);
}

void ConservativeLineTestInstance::generateNormalLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
{
	const char*		iterationComment		= "";
	const float		halfPixel				= 1.0f / float(m_renderSize);
	const float		extraOverestimationSize	= getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
	const float		overestimate			= 2.0f * halfPixel * (m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize);
	const float		overestimateMargin		= overestimate;
	const float		underestimateMargin		= 0.0f;
	const bool		isOverestimate			= m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
	const float		margin					= isOverestimate ? overestimateMargin : underestimateMargin;
	const float		edge					= 4 * halfPixel + margin;
	const float		left					= -1.0f + edge;
	const float		right					= +1.0f - edge;
	const float		up						= -1.0f + edge;
	const float		down					= +1.0f - edge;

	outData.reserve(2);

	if (isOverestimate)
	{
		const char*		iterationComments[]		= { "Horizontal up line", "Vertical line", "Horizontal down line" };

		iterationComment = iterationComments[iteration];

		switch (iteration)
		{
			case 0:
			{
				outData.push_back(tcu::Vec4(              left,   up + halfPixel, 0.0f, 1.0f));
				outData.push_back(tcu::Vec4(             right,   up + halfPixel, 0.0f, 1.0f));

				break;
			}

			case 1:
			{
				outData.push_back(tcu::Vec4(  left + halfPixel,               up, 0.0f, 1.0f));
				outData.push_back(tcu::Vec4(  left + halfPixel,             down, 0.0f, 1.0f));

				break;
			}

			case 2:
			{
				outData.push_back(tcu::Vec4(              left, down - halfPixel, 0.0f, 1.0f));
				outData.push_back(tcu::Vec4(             right, down - halfPixel, 0.0f, 1.0f));

				break;
			}

			default:
				TCU_THROW(InternalError, "Unexpected iteration");
		}
	}
	else
	{
		const char*		iterationComments[]	= { "Horizontal lines", "Vertical lines", "Diagonal lines" };
		const deUint32	subPixels			= 1u << m_subpixelBits;
		const float		subPixelSize		= 2.0f * halfPixel / float(subPixels);
		const float		blockStep			= 16.0f * 2.0f * halfPixel;
		const float		lineWidth			= 2.0f * halfPixel * getLineWidth();
		const float		offsets[]			=
		{
			float(1) * blockStep,
			float(2) * blockStep + halfPixel,
			float(3) * blockStep + 0.5f * lineWidth + 2.0f * subPixelSize,
			float(4) * blockStep + 0.5f * lineWidth - 2.0f * subPixelSize,
		};

		iterationComment = iterationComments[iteration];

		outData.reserve(DE_LENGTH_OF_ARRAY(offsets));

		switch (iteration)
		{
			case 0:
			{
				for (size_t lineNdx = 0; lineNdx < DE_LENGTH_OF_ARRAY(offsets); ++lineNdx)
				{
					outData.push_back(tcu::Vec4( left + halfPixel, up + offsets[lineNdx], 0.0f, 1.0f));
					outData.push_back(tcu::Vec4(right - halfPixel, up + offsets[lineNdx], 0.0f, 1.0f));
				}

				break;
			}

			case 1:
			{
				for (size_t lineNdx = 0; lineNdx < DE_LENGTH_OF_ARRAY(offsets); ++lineNdx)
				{
					outData.push_back(tcu::Vec4(left + offsets[lineNdx],   up + halfPixel, 0.0f, 1.0f));
					outData.push_back(tcu::Vec4(left + offsets[lineNdx], down - halfPixel, 0.0f, 1.0f));
				}

				break;
			}

			case 2:
			{
				for (size_t lineNdx = 0; lineNdx < DE_LENGTH_OF_ARRAY(offsets); ++lineNdx)
				{
					outData.push_back(tcu::Vec4(left + offsets[lineNdx],          up + halfPixel, 0.0f, 1.0f));
					outData.push_back(tcu::Vec4(      right - halfPixel, down - offsets[lineNdx], 0.0f, 1.0f));
				}

				break;
			}

			default:
				TCU_THROW(InternalError, "Unexpected iteration");
		}
	}

	DE_ASSERT(outData.size() % 2 == 0);
	outLines.resize(outData.size() / 2);
	for(size_t lineNdx = 0; lineNdx < outLines.size(); ++lineNdx)
	{
		outLines[lineNdx].positions[0] = outData[2 * lineNdx + 0];
		outLines[lineNdx].positions[1] = outData[2 * lineNdx + 1];
	}

	// log
	m_context.getTestContext().getLog()
		<< tcu::TestLog::Message
		<< "Testing " << iterationComment << " "
		<< "with rendering " << outLines.size() << " line(s):"
		<< tcu::TestLog::EndMessage;

	for (int ndx = 0; ndx < (int)outLines.size(); ++ndx)
	{
		const deUint32	 multiplier	= m_renderSize / 2;

		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Line " << (ndx+1) << ":"
			<< "\n\t" << outLines[ndx].positions[0] << " == " << (float(multiplier) * outLines[ndx].positions[0]) << "/" << multiplier
			<< "\n\t" << outLines[ndx].positions[1] << " == " << (float(multiplier) * outLines[ndx].positions[1]) << "/" << multiplier
			<< tcu::TestLog::EndMessage;
	}
}

void ConservativeLineTestInstance::generateDegenerateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
{
	const bool		isOverestimate		= m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
	const float		pixelSize			= 2.0f / float(m_renderSize);
	const deUint32	subPixels			= 1u << m_context.getDeviceProperties().limits.subPixelPrecisionBits;
	const float		subPixelSize		= pixelSize / float(subPixels);
	const char*		iterationComments[]	= { "Horizontal line", "Vertical line", "Diagonal line" };

	outData.clear();

	if (isOverestimate)
	{
		const float		extraOverestimationSize			= getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
		const float		totalOverestimate				= m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize;
		const float		totalOverestimateInSubPixels	= deFloatCeil(totalOverestimate * float(subPixels));
		const float		overestimate					= subPixelSize * totalOverestimateInSubPixels;
		const float		overestimateSafetyMargin		= subPixelSize * 0.125f;
		const float		margin							= overestimate + overestimateSafetyMargin;
		const float		originOffset					= -1.0f + 1 * pixelSize;
		const float		originLeft						= originOffset + margin;
		const float		originRight						= originOffset + margin + 0.25f * subPixelSize;
		const float		originUp						= originOffset + margin;
		const float		originDown						= originOffset + margin + 0.25f * subPixelSize;

		switch (iteration)
		{
			case 0:
			{
				outData.push_back(tcu::Vec4( originLeft,   originUp, 0.0f, 1.0f));
				outData.push_back(tcu::Vec4(originRight,   originUp, 0.0f, 1.0f));

				break;
			}

			case 1:
			{
				outData.push_back(tcu::Vec4( originLeft,   originUp, 0.0f, 1.0f));
				outData.push_back(tcu::Vec4( originLeft, originDown, 0.0f, 1.0f));

				break;
			}

			case 2:
			{
				outData.push_back(tcu::Vec4( originLeft,   originUp, 0.0f, 1.0f));
				outData.push_back(tcu::Vec4(originRight, originDown, 0.0f, 1.0f));

				break;
			}

			default:
				TCU_THROW(InternalError, "Unexpected iteration");
		}
	}
	else
	{
		size_t rowStart	= 3 * getIteration();
		size_t rowEnd	= 3 * (getIteration() + 1);

		for (size_t rowNdx = rowStart; rowNdx < rowEnd; ++rowNdx)
		for (size_t colNdx = 0; colNdx < 3 * 3; ++colNdx)
		{
			const float		originOffsetY	= -1.0f + float(4 * (1 + rowNdx)) * pixelSize;
			const float		originOffsetX	= -1.0f + float(4 * (1 + colNdx)) * pixelSize;
			const float		x0				= float(rowNdx % 3);
			const float		y0				= float(rowNdx / 3);
			const float		x1				= float(colNdx % 3);
			const float		y1				= float(colNdx / 3);
			const tcu::Vec4	p0				= tcu::Vec4(originOffsetX + x0 * pixelSize / 2.0f, originOffsetY + y0 * pixelSize / 2.0f, 0.0f, 1.0f);
			const tcu::Vec4	p1				= tcu::Vec4(originOffsetX + x1 * pixelSize / 2.0f, originOffsetY + y1 * pixelSize / 2.0f, 0.0f, 1.0f);

			if (x0 == x1 && y0 == y1)
				continue;

			outData.push_back(p0);
			outData.push_back(p1);
		}
	}

	outLines.resize(outData.size() / 2);

	for (size_t ndx = 0; ndx < outLines.size(); ++ndx)
	{
		outLines[ndx].positions[0] = outData[2 * ndx + 0];
		outLines[ndx].positions[1] = outData[2 * ndx + 1];
	}

	// log
	m_context.getTestContext().getLog()
		<< tcu::TestLog::Message
		<< "Testing " << iterationComments[iteration] << " "
		<< "with rendering " << outLines.size() << " line(s):"
		<< tcu::TestLog::EndMessage;

	for (int ndx = 0; ndx < (int)outLines.size(); ++ndx)
	{
		const deUint32	multiplierInt	= m_renderSize / 2;
		const deUint32	multiplierFrac	= subPixels;
		std::string		coordsString;

		for (size_t vertexNdx = 0; vertexNdx < 2; ++vertexNdx)
		{
			const tcu::Vec4&	pos				= outLines[ndx].positions[vertexNdx];
			std::ostringstream	coordsFloat;
			std::ostringstream	coordsNatural;

			for (int coordNdx = 0; coordNdx < 2; ++coordNdx)
			{
				const char*	sep		= (coordNdx < 1) ? "," : "";
				const float	coord	= pos[coordNdx];
				const char	sign	= deSign(coord) < 0 ? '-' : '+';
				const float	m		= deFloatFloor(float(multiplierInt) * deFloatAbs(coord));
				const float	r		= deFloatFrac(float(multiplierInt) * deFloatAbs(coord)) * float(multiplierFrac);

				coordsFloat << std::fixed << std::setw(13) << std::setprecision(10) << coord << sep;
				coordsNatural << sign << '(' << m << '+' << r << '/' << multiplierFrac << ')' << sep;
			}

			coordsString += "\n\t[" + coordsFloat.str() + "] == [" + coordsNatural.str() + "] / " + de::toString(multiplierInt);
		}

		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Line " << (ndx + 1) << ':'
			<< coordsString
			<< tcu::TestLog::EndMessage;
	}
}

void ConservativeLineTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
{
	if (m_conservativeTestConfig.degeneratePrimitives)
	{
		// Set provoking vertex color to white
		tcu::Vec4				colorProvoking	(1.0f, 1.0f, 1.0f, 1.0f);
		tcu::Vec4				colorOther		(0.0f, 1.0f, 1.0f, 1.0f);
		std::vector<tcu::Vec4>	colorData;

		colorData.reserve(vertexData.size());

		for (size_t vertexNdx = 0; vertexNdx < vertexData.size(); ++vertexNdx)
			if (vertexNdx % 2 == 0)
				colorData.push_back(colorProvoking);
			else
				colorData.push_back(colorOther);

		BaseRenderingTestInstance::drawPrimitives(result, vertexData, colorData, primitiveTopology);
	}
	else
		BaseRenderingTestInstance::drawPrimitives(result, vertexData, primitiveTopology);
}

bool ConservativeLineTestInstance::compareAndVerify (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
{
	DE_UNREF(drawBuffer);

	switch (m_conservativeTestConfig.conservativeRasterizationMode)
	{
		case VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT:
		{
			if (m_conservativeTestConfig.degeneratePrimitives)
				return compareAndVerifyOverestimatedDegenerate(lines, resultImage);
			else
				return compareAndVerifyOverestimatedNormal(lines, resultImage);
		}
		case VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT:
		{
			if (m_conservativeTestConfig.degeneratePrimitives)
				return compareAndVerifyUnderestimatedDegenerate(lines, resultImage);
			else
				return compareAndVerifyUnderestimatedNormal(lines, resultImage);
		}

		default:
			TCU_THROW(InternalError, "Unknown conservative rasterization mode");
	}
}

bool ConservativeLineTestInstance::compareAndVerifyOverestimatedNormal (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
{
	DE_UNREF(lines);

	const int			b						= 3; // bar width
	const int			w						= resultImage.getWidth() - 1;
	const int			h						= resultImage.getHeight() - 1;
	const int			xStarts[]				= {     1,     1,     1 };
	const int			xEnds[]					= { w - 1,     b, w - 1 };
	const int			yStarts[]				= {     1,     1, h - b };
	const int			yEnds[]					= {     b, h - 1, h - 1 };
	const int			xStart					= xStarts[getIteration()];
	const int			xEnd					= xEnds[getIteration()];
	const int			yStart					= yStarts[getIteration()];
	const int			yEnd					= yEnds[getIteration()];
	const tcu::RGBA		backgroundColor			= tcu::RGBA(0, 0, 0, 255);
	const tcu::RGBA		foregroundColor			= tcu::RGBA(255, 255, 255, 255);
	const tcu::RGBA		unexpectedPixelColor	= tcu::RGBA(255, 0, 0, 255);
	tcu::TestLog&		log						= m_context.getTestContext().getLog();
	int					errX					= 0;
	int					errY					= 0;
	deUint32			errValue				= 0;
	bool				result					= true;

	DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());

	for (int y = yStart; result && y < yEnd; ++y)
	for (int x = xStart; result && x < xEnd; ++x)
	{
		if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
		{
			result		= false;
			errX		= x;
			errY		= y;
			errValue	= resultImage.getPixel(x,y).getPacked();

			break;
		}
	}

	if (!result)
	{
		tcu::Surface	errorMask	(resultImage.getWidth(), resultImage.getHeight());

		for (int y = 0; y < errorMask.getHeight(); ++y)
		for (int x = 0; x < errorMask.getWidth(); ++x)
			errorMask.setPixel(x, y, backgroundColor);

		for (int y = yStart; y < yEnd; ++y)
		for (int x = xStart; x < xEnd; ++x)
		{
			if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
				errorMask.setPixel(x,y, unexpectedPixelColor);
		}

		log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		resultImage)
			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", resultImage)
			<< tcu::TestLog::EndImageSet;
	}

	return result;
}

bool ConservativeLineTestInstance::compareAndVerifyOverestimatedDegenerate (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
{
	DE_UNREF(lines);

	const char*			iterationComments[]		= { "Horizontal line", "Vertical line", "Diagonal line" };
	const tcu::RGBA		backgroundColor			= tcu::RGBA(0, 0, 0, 255);
	const tcu::RGBA		foregroundColor			= tcu::RGBA(255, 255, 255, 255);
	const tcu::RGBA		unexpectedPixelColor	= tcu::RGBA(255, 0, 0, 255);
	tcu::TestLog&		log						= m_context.getTestContext().getLog();
	bool				result					= true;
	tcu::Surface		referenceImage			(resultImage.getWidth(), resultImage.getHeight());

	for (int y = 0; y < resultImage.getHeight(); ++y)
	for (int x = 0; x < resultImage.getWidth(); ++x)
		referenceImage.setPixel(x, y, backgroundColor);

	if (m_conservativeRasterizationProperties.degenerateLinesRasterized)
	{
		log << tcu::TestLog::Message << "Lines expected to be rasterized with white color" << tcu::TestLog::EndMessage;

		// This pixel will alway be covered due to the placement of the line.
		referenceImage.setPixel(1, 1, foregroundColor);

		// Additional pixels will be covered based on the extra bloat added to the primitive.
		const float extraOverestimation = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
		const int xExtent = 1 + int((extraOverestimation * 2.0f) + 0.5f);
		const int yExtent = xExtent;

		for (int y = 0; y <= yExtent; ++y)
		for (int x = 0; x <= xExtent; ++x)
			referenceImage.setPixel(x, y, foregroundColor);
	}
	else
		log << tcu::TestLog::Message << "Lines expected to be culled" << tcu::TestLog::EndMessage;

	for (int y = 0; result && y < resultImage.getHeight(); ++y)
	for (int x = 0; result && x < resultImage.getWidth(); ++x)
	{
		if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
		{
			result = false;

			break;
		}
	}

	if (!result)
	{
		tcu::Surface	errorMask	(resultImage.getWidth(), resultImage.getHeight());

		for (int y = 0; y < errorMask.getHeight(); ++y)
		for (int x = 0; x < errorMask.getWidth(); ++x)
		{
			if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
				errorMask.setPixel(x, y, unexpectedPixelColor);
			else
				errorMask.setPixel(x, y, backgroundColor);
		}

		log << tcu::TestLog::Message << "Invalid pixels found for mode " << iterationComments[getIteration()]
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		resultImage)
			<< tcu::TestLog::Image("Reference",	"Reference",	referenceImage)
			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", resultImage)
			<< tcu::TestLog::EndImageSet;
	}

	return result;
}

bool ConservativeLineTestInstance::compareAndVerifyUnderestimatedNormal (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
{
	DE_UNREF(lines);

	const tcu::RGBA		backgroundColor			= tcu::RGBA(0, 0, 0, 255);
	const tcu::RGBA		foregroundColor			= tcu::RGBA(255, 255, 255, 255);
	const tcu::RGBA		unexpectedPixelColor	= tcu::RGBA(255, 0, 0, 255);
	tcu::TestLog&		log						= m_context.getTestContext().getLog();
	int					errX					= -1;
	int					errY					= -1;
	tcu::RGBA			errValue;
	bool				result					= true;
	tcu::Surface		referenceImage			(resultImage.getWidth(), resultImage.getHeight());

	DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());

	for (int y = 0; y < referenceImage.getHeight(); ++y)
	for (int x = 0; x < referenceImage.getWidth(); ++x)
		referenceImage.setPixel(x, y, backgroundColor);

	if (getLineWidth() > 1.0f)
	{
		const tcu::IVec2	viewportSize(resultImage.getWidth(), resultImage.getHeight());

		for (size_t lineNdx = 0; lineNdx < lines.size(); ++lineNdx)
		for (int y = 0; y < resultImage.getHeight(); ++y)
		for (int x = 0; x < resultImage.getWidth(); ++x)
		{
			if (calculateUnderestimateLineCoverage(lines[lineNdx].positions[0], lines[lineNdx].positions[1], getLineWidth(), tcu::IVec2(x,y), viewportSize) == tcu::COVERAGE_FULL)
				referenceImage.setPixel(x, y, foregroundColor);
		}
	}

	for (int y = 0; result && y < resultImage.getHeight(); ++y)
	for (int x = 0; result && x < resultImage.getWidth(); ++x)
	{
		if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
		{
			result		= false;
			errX		= x;
			errY		= y;
			errValue	= resultImage.getPixel(x,y);

			break;
		}
	}

	if (!result)
	{
		tcu::Surface	errorMask	(resultImage.getWidth(), resultImage.getHeight());

		for (int y = 0; y < errorMask.getHeight(); ++y)
		for (int x = 0; x < errorMask.getWidth(); ++x)
			errorMask.setPixel(x, y, backgroundColor);

		for (int y = 0; y < errorMask.getHeight(); ++y)
		for (int x = 0; x < errorMask.getWidth();  ++x)
		{
			if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
				errorMask.setPixel(x, y, unexpectedPixelColor);
		}

		log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " errValue=" << errValue
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		resultImage)
			<< tcu::TestLog::Image("Reference",	"Reference",	referenceImage)
			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", resultImage)
			<< tcu::TestLog::EndImageSet;
	}

	return result;
}

bool ConservativeLineTestInstance::compareAndVerifyUnderestimatedDegenerate (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
{
	DE_UNREF(lines);

	const tcu::RGBA		backgroundColor			= tcu::RGBA(0, 0, 0, 255);
	const tcu::RGBA		unexpectedPixelColor	= tcu::RGBA(255, 0, 0, 255);
	tcu::TestLog&		log						= m_context.getTestContext().getLog();
	bool				result					= true;
	tcu::Surface		referenceImage			(resultImage.getWidth(), resultImage.getHeight());

	for (int y = 0; y < resultImage.getHeight(); ++y)
	for (int x = 0; x < resultImage.getWidth(); ++x)
		referenceImage.setPixel(x, y, backgroundColor);

	log << tcu::TestLog::Message << "No lines expected to be rasterized" << tcu::TestLog::EndMessage;

	for (int y = 0; result && y < resultImage.getHeight(); ++y)
	for (int x = 0; result && x < resultImage.getWidth(); ++x)
	{
		if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
		{
			result = false;

			break;
		}
	}

	if (!result)
	{
		tcu::Surface	errorMask	(resultImage.getWidth(), resultImage.getHeight());

		for (int y = 0; y < errorMask.getHeight(); ++y)
		for (int x = 0; x < errorMask.getWidth(); ++x)
		{
			if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
				errorMask.setPixel(x, y, unexpectedPixelColor);
			else
				errorMask.setPixel(x, y, backgroundColor);
		}

		log << tcu::TestLog::Message << "Invalid pixels found" << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		resultImage)
			<< tcu::TestLog::Image("Reference",	"Reference",	referenceImage)
			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", resultImage)
			<< tcu::TestLog::EndImageSet;
	}

	return result;
}

const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> ConservativeLineTestInstance::initRasterizationConservativeStateCreateInfo (void)
{
	const float															extraOverestimationSize	= getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
	std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT>	result;

	result.reserve(getIterationCount());

	for (int iteration = 0; iteration < getIterationCount(); ++iteration)
	{
		const VkPipelineRasterizationConservativeStateCreateInfoEXT	rasterizationConservativeStateCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT,	//  VkStructureType											sType;
			DE_NULL,																		//  const void*												pNext;
			(VkPipelineRasterizationConservativeStateCreateFlagsEXT)0,						//  VkPipelineRasterizationConservativeStateCreateFlagsEXT	flags;
			m_conservativeTestConfig.conservativeRasterizationMode,							//  VkConservativeRasterizationModeEXT						conservativeRasterizationMode;
			extraOverestimationSize															//  float													extraPrimitiveOverestimationSize;
		};

		result.push_back(rasterizationConservativeStateCreateInfo);
	}

	return result;
}

const std::vector<VkPipelineRasterizationStateCreateInfo> ConservativeLineTestInstance::initRasterizationStateCreateInfo (void)
{
	std::vector<VkPipelineRasterizationStateCreateInfo>	result;

	result.reserve(getIterationCount());

	for (int iteration = 0; iteration < getIterationCount(); ++iteration)
	{
		const VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		//  VkStructureType							sType;
			&m_rasterizationConservativeStateCreateInfo[iteration],			//  const void*								pNext;
			0,																//  VkPipelineRasterizationStateCreateFlags	flags;
			false,															//  VkBool32								depthClampEnable;
			false,															//  VkBool32								rasterizerDiscardEnable;
			VK_POLYGON_MODE_FILL,											//  VkPolygonMode							polygonMode;
			VK_CULL_MODE_NONE,												//  VkCullModeFlags							cullMode;
			VK_FRONT_FACE_COUNTER_CLOCKWISE,								//  VkFrontFace								frontFace;
			VK_FALSE,														//  VkBool32								depthBiasEnable;
			0.0f,															//  float									depthBiasConstantFactor;
			0.0f,															//  float									depthBiasClamp;
			0.0f,															//  float									depthBiasSlopeFactor;
			getLineWidth(),													//  float									lineWidth;
		};

		result.push_back(rasterizationStateCreateInfo);
	}

	return result;
}

const VkPipelineRasterizationStateCreateInfo* ConservativeLineTestInstance::getRasterizationStateCreateInfo	(void) const
{
	return &m_rasterizationStateCreateInfo[getIteration()];
}

const VkPipelineRasterizationLineStateCreateInfoEXT* ConservativeLineTestInstance::getLineRasterizationStateCreateInfo	(void)
{
	return DE_NULL;
}


class ConservativePointTestInstance : public PointTestInstance
{
public:
																				ConservativePointTestInstance					(Context&				context,
																																 ConservativeTestConfig	conservativeTestConfig,
																																 VkSampleCountFlagBits	sampleCount)
																					: PointTestInstance								(
																																		context,
																																		PRIMITIVEWIDENESS_NARROW,
																																		PRIMITIVESTRICTNESS_IGNORE,
																																		sampleCount,
																																		LINESTIPPLE_DISABLED,
																																		VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT,
																																		LineStippleFactorCase::DEFAULT,
																																		0,
																																		conservativeTestConfig.resolution,
																																		conservativeTestConfig.lineWidth
																																	)
																					, m_conservativeTestConfig						(conservativeTestConfig)
																					, m_conservativeRasterizationProperties			(context.getConservativeRasterizationPropertiesEXT())
																					, m_rasterizationConservativeStateCreateInfo	(initRasterizationConservativeStateCreateInfo())
																					, m_rasterizationStateCreateInfo				(initRasterizationStateCreateInfo())
																					, m_renderStart									()
																					, m_renderEnd									()
																				{}

	void																		generatePoints									(int										iteration,
																																 std::vector<tcu::Vec4>&					outData,
																																 std::vector<PointSceneSpec::ScenePoint>&	outPoints);
	const VkPipelineRasterizationStateCreateInfo*								getRasterizationStateCreateInfo					(void) const;

protected:
	virtual const VkPipelineRasterizationLineStateCreateInfoEXT*				getLineRasterizationStateCreateInfo				(void);

	virtual bool																compareAndVerify								(std::vector<PointSceneSpec::ScenePoint>&	points,
																																 tcu::Surface&								resultImage,
																																 std::vector<tcu::Vec4>&					drawBuffer);
	virtual bool																compareAndVerifyOverestimated					(std::vector<PointSceneSpec::ScenePoint>&	points,
																																 tcu::Surface&								resultImage);
	virtual bool																compareAndVerifyUnderestimated					(std::vector<PointSceneSpec::ScenePoint>&	points,
																																 tcu::Surface&								resultImage);

private:
	const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT>	initRasterizationConservativeStateCreateInfo	(void);
	const std::vector<VkPipelineRasterizationStateCreateInfo>					initRasterizationStateCreateInfo				(void);

	const ConservativeTestConfig												m_conservativeTestConfig;
	const VkPhysicalDeviceConservativeRasterizationPropertiesEXT				m_conservativeRasterizationProperties;
	const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT>	m_rasterizationConservativeStateCreateInfo;
	const std::vector<VkPipelineRasterizationStateCreateInfo>					m_rasterizationStateCreateInfo;
	std::vector<int>															m_renderStart;
	std::vector<int>															m_renderEnd;
};

void ConservativePointTestInstance::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
{
	const float	pixelSize		= 2.0f / float(m_renderSize);
	const bool	isOverestimate	= m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;

	m_renderStart.clear();
	m_renderEnd.clear();

	if (isOverestimate)
	{
		const float	extraOverestimationSize	= getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
		const float	overestimate			= m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize;
		const float	halfRenderAreaSize		= overestimate + 0.5f;
		const float	pointCenterOffset		= 2.0f + 0.5f * float(iteration) + halfRenderAreaSize;
		const float	pointEdgeStart			= pointCenterOffset - halfRenderAreaSize;
		const float	pointEdgeEnd			= pointEdgeStart + 2 * halfRenderAreaSize;
		const int	renderStart				= int(deFloatFloor(pointEdgeStart)) + int((deFloatFrac(pointEdgeStart) > 0.0f) ? 0 : -1);
		const int	renderEnd				= int(deFloatCeil(pointEdgeEnd)) + int((deFloatFrac(pointEdgeEnd) > 0.0f) ? 0 : 1);

		outData.push_back(tcu::Vec4(-1.0f + pixelSize * pointCenterOffset, -1.0f + pixelSize * pointCenterOffset, 0.0f, 1.0f));

		m_renderStart.push_back(renderStart);
		m_renderEnd.push_back(renderEnd);
	}
	else
	{
		const float	pointSize			= m_conservativeTestConfig.lineWidth;
		const float	halfRenderAreaSize	= pointSize / 2.0f;

		switch (iteration)
		{
			case 0:
			{
				const float	pointCenterOffset	= (pointSize + 1.0f + deFloatFrac(pointSize)) / 2.0f;
				const float	pointEdgeStart		= pointCenterOffset - halfRenderAreaSize;
				const float	pointEdgeEnd		= pointEdgeStart + 2.0f * halfRenderAreaSize;
				const int	renderStart			= (m_renderSize / 2) + int(deFloatCeil(pointEdgeStart));
				const int	renderEnd			= (m_renderSize / 2) + int(deFloatFloor(pointEdgeEnd));

				outData.push_back(tcu::Vec4(pixelSize * pointCenterOffset, pixelSize * pointCenterOffset, 0.0f, 1.0f));

				m_renderStart.push_back(renderStart);
				m_renderEnd.push_back(renderEnd);

				break;
			}

			case 1:
			{
				const float subPixelSize		= 1.0f / float(1u<<(m_subpixelBits - 1));
				const float	pointBottomLeft		= 1.0f - subPixelSize;
				const float	pointCenterOffset	= pointBottomLeft + pointSize / 2.0f;
				const float	pointEdgeStart		= pointCenterOffset - halfRenderAreaSize;
				const float	pointEdgeEnd		= pointEdgeStart + 2.0f * halfRenderAreaSize;
				const int	renderStart			= (m_renderSize / 2) + int(deFloatCeil(pointEdgeStart));
				const int	renderEnd			= (m_renderSize / 2) + int(deFloatFloor(pointEdgeEnd));

				outData.push_back(tcu::Vec4(pixelSize * pointCenterOffset, pixelSize * pointCenterOffset, 0.0f, 1.0f));

				m_renderStart.push_back(renderStart);
				m_renderEnd.push_back(renderEnd);

				break;
			}

			case 2:
			{
				// Edges of a point are considered not covered. Top-left coverage rule is not applicable for underestimate rasterization.
				const float	pointCenterOffset	= (pointSize + deFloatFrac(pointSize)) / 2.0f;
				const float	pointEdgeStart		= pointCenterOffset - halfRenderAreaSize;
				const float	pointEdgeEnd		= pointEdgeStart + 2.0f * halfRenderAreaSize;
				const int	renderStart			= (m_renderSize / 2) + int(deFloatCeil(pointEdgeStart)) + 1;
				const int	renderEnd			= (m_renderSize / 2) + int(deFloatFloor(pointEdgeEnd)) - 1;

				outData.push_back(tcu::Vec4(pixelSize * pointCenterOffset, pixelSize * pointCenterOffset, 0.0f, 1.0f));

				m_renderStart.push_back(renderStart);
				m_renderEnd.push_back(renderEnd);

				break;
			}

			default:
				TCU_THROW(InternalError, "Unexpected iteration");
		}
	}

	outPoints.resize(outData.size());
	for (size_t ndx = 0; ndx < outPoints.size(); ++ndx)
	{
		outPoints[ndx].position = outData[ndx];
		outPoints[ndx].pointSize = getPointSize();
	}

	// log
	m_context.getTestContext().getLog()
		<< tcu::TestLog::Message
		<< "Testing conservative point rendering "
		<< "with rendering " << outPoints.size() << " points(s):"
		<< tcu::TestLog::EndMessage;
	for (int ndx = 0; ndx < (int)outPoints.size(); ++ndx)
	{
		const deUint32	 multiplier	= m_renderSize / 2;

		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Point " << (ndx+1) << ":"
			<< "\n\t" << outPoints[ndx].position << " == " << (float(multiplier) * outPoints[ndx].position) << "/" << multiplier
			<< tcu::TestLog::EndMessage;
	}
}

bool ConservativePointTestInstance::compareAndVerify (std::vector<PointSceneSpec::ScenePoint>& points, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
{
	DE_UNREF(drawBuffer);

	switch (m_conservativeTestConfig.conservativeRasterizationMode)
	{
		case VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT:
		{
			return compareAndVerifyOverestimated(points, resultImage);
		}
		case VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT:
		{
			return compareAndVerifyUnderestimated(points, resultImage);
		}

		default:
			TCU_THROW(InternalError, "Unknown conservative rasterization mode");
	}
}

bool ConservativePointTestInstance::compareAndVerifyOverestimated (std::vector<PointSceneSpec::ScenePoint>& points, tcu::Surface& resultImage)
{
	DE_UNREF(points);

	const char*			iterationComments[]		= { "Edges and corners", "Partial coverage", "Edges and corners" };
	const tcu::RGBA		backgroundColor			= tcu::RGBA(0, 0, 0, 255);
	const tcu::RGBA		foregroundColor			= tcu::RGBA(255, 255, 255, 255);
	const tcu::RGBA		unexpectedPixelColor	= tcu::RGBA(255, 0, 0, 255);
	tcu::TestLog&		log						= m_context.getTestContext().getLog();
	int					errX					= 0;
	int					errY					= 0;
	deUint32			errValue				= 0;
	bool				result					= true;

	log << tcu::TestLog::Message << "Points expected to be rasterized with white color" << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "Testing " << iterationComments[getIteration()] << tcu::TestLog::EndMessage;

	for (size_t renderAreaNdx = 0; result && renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
	{
		const int renderStart	= m_renderStart[renderAreaNdx];
		const int renderEnd		= m_renderEnd[renderAreaNdx];

		for (int y = renderStart; result && y < renderEnd; ++y)
		for (int x = renderStart; result && x < renderEnd; ++x)
		{
			if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
			{
				result		= false;
				errX		= x;
				errY		= y;
				errValue	= resultImage.getPixel(x, y).getPacked();

				break;
			}
		}
	}

	if (!result)
	{
		tcu::Surface		referenceImage	(resultImage.getWidth(), resultImage.getHeight());
		tcu::Surface		errorMask		(resultImage.getWidth(), resultImage.getHeight());
		std::ostringstream	css;

		for (int y = 0; y < resultImage.getHeight(); ++y)
		for (int x = 0; x < resultImage.getWidth(); ++x)
			referenceImage.setPixel(x, y, backgroundColor);

		for (size_t renderAreaNdx = 0; renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
		{
			const int renderStart	= m_renderStart[renderAreaNdx];
			const int renderEnd		= m_renderEnd[renderAreaNdx];

			for (int y = renderStart; y < renderEnd; ++y)
			for (int x = renderStart; x < renderEnd; ++x)
				referenceImage.setPixel(x, y, foregroundColor);
		}

		for (int y = 0; y < errorMask.getHeight(); ++y)
		for (int x = 0; x < errorMask.getWidth(); ++x)
		{
			if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
				errorMask.setPixel(x, y, unexpectedPixelColor);
			else
				errorMask.setPixel(x, y, backgroundColor);
		}

		css << std::endl;
		for (size_t renderAreaNdx = 0; renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
		{
			const int renderStart	= m_renderStart[renderAreaNdx];
			const int renderEnd		= m_renderEnd[renderAreaNdx];

			css << "[" << renderStart << "," << renderEnd << ") x [" << renderStart << "," << renderEnd << ")" << std::endl;
		}

		log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "Expected area(s) to be filled:" << css.str()
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		resultImage)
			<< tcu::TestLog::Image("Reference",	"Reference",	referenceImage)
			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", resultImage)
			<< tcu::TestLog::EndImageSet;
	}

	return result;
}

bool ConservativePointTestInstance::compareAndVerifyUnderestimated (std::vector<PointSceneSpec::ScenePoint>& points, tcu::Surface& resultImage)
{
	DE_UNREF(points);

	const char*			iterationComments[]		= { "Full coverage", "Full coverage with subpixel", "Exact coverage" };
	const tcu::RGBA		backgroundColor			= tcu::RGBA(0, 0, 0, 255);
	const tcu::RGBA		foregroundColor			= tcu::RGBA(255, 255, 255, 255);
	const tcu::RGBA		unexpectedPixelColor	= tcu::RGBA(255, 0, 0, 255);
	tcu::TestLog&		log						= m_context.getTestContext().getLog();
	int					errX					= 0;
	int					errY					= 0;
	deUint32			errValue				= 0;
	bool				result					= true;
	tcu::Surface		referenceImage			(resultImage.getWidth(), resultImage.getHeight());

	log << tcu::TestLog::Message << "Points expected to be rasterized with white color" << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "Testing " << iterationComments[getIteration()] << tcu::TestLog::EndMessage;

	for (int y = 0; y < resultImage.getHeight(); ++y)
	for (int x = 0; x < resultImage.getWidth(); ++x)
		referenceImage.setPixel(x, y, backgroundColor);

	for (size_t renderAreaNdx = 0; result && renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
	{
		const int renderStart	= m_renderStart[renderAreaNdx];
		const int renderEnd		= m_renderEnd[renderAreaNdx];

		for (int y = renderStart; y < renderEnd; ++y)
		for (int x = renderStart; x < renderEnd; ++x)
			referenceImage.setPixel(x, y, foregroundColor);
	}

	for (int y = 0; result && y < resultImage.getHeight(); ++y)
	for (int x = 0; result && x < resultImage.getWidth(); ++x)
	{
		if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
		{
			result		= false;
			errX		= x;
			errY		= y;
			errValue	= resultImage.getPixel(x, y).getPacked();

			break;
		}
	}

	if (!result)
	{
		tcu::Surface		errorMask	(resultImage.getWidth(), resultImage.getHeight());
		std::ostringstream	css;

		for (int y = 0; y < errorMask.getHeight(); ++y)
		for (int x = 0; x < errorMask.getWidth(); ++x)
		{
			if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
				errorMask.setPixel(x, y, unexpectedPixelColor);
			else
				errorMask.setPixel(x, y, backgroundColor);
		}

		css << std::endl;
		for (size_t renderAreaNdx = 0; renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
		{
			const int renderStart	= m_renderStart[renderAreaNdx];
			const int renderEnd		= m_renderEnd[renderAreaNdx];

			css << "[" << renderStart << "," << renderEnd << ") x [" << renderStart << "," << renderEnd << ")" << std::endl;
		}

		log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "Expected area(s) to be filled:" << css.str()
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result",	"Result",		resultImage)
			<< tcu::TestLog::Image("Reference",	"Reference",	referenceImage)
			<< tcu::TestLog::Image("ErrorMask", "ErrorMask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
		log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
			<< tcu::TestLog::Image("Result", "Result", resultImage)
			<< tcu::TestLog::EndImageSet;
	}

	return result;
}

const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> ConservativePointTestInstance::initRasterizationConservativeStateCreateInfo (void)
{
	const float															extraOverestimationSize	= getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
	std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT>	result;

	result.reserve(getIterationCount());

	for (int iteration = 0; iteration < getIterationCount(); ++iteration)
	{
		const VkPipelineRasterizationConservativeStateCreateInfoEXT	rasterizationConservativeStateCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT,	//  VkStructureType											sType;
			DE_NULL,																		//  const void*												pNext;
			(VkPipelineRasterizationConservativeStateCreateFlagsEXT)0,						//  VkPipelineRasterizationConservativeStateCreateFlagsEXT	flags;
			m_conservativeTestConfig.conservativeRasterizationMode,							//  VkConservativeRasterizationModeEXT						conservativeRasterizationMode;
			extraOverestimationSize															//  float													extraPrimitiveOverestimationSize;
		};

		result.push_back(rasterizationConservativeStateCreateInfo);
	}

	return result;
}

const std::vector<VkPipelineRasterizationStateCreateInfo> ConservativePointTestInstance::initRasterizationStateCreateInfo (void)
{
	std::vector<VkPipelineRasterizationStateCreateInfo>	result;

	result.reserve(getIterationCount());

	for (int iteration = 0; iteration < getIterationCount(); ++iteration)
	{
		const VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		//  VkStructureType							sType;
			&m_rasterizationConservativeStateCreateInfo[iteration],			//  const void*								pNext;
			0,																//  VkPipelineRasterizationStateCreateFlags	flags;
			false,															//  VkBool32								depthClampEnable;
			false,															//  VkBool32								rasterizerDiscardEnable;
			VK_POLYGON_MODE_FILL,											//  VkPolygonMode							polygonMode;
			VK_CULL_MODE_NONE,												//  VkCullModeFlags							cullMode;
			VK_FRONT_FACE_COUNTER_CLOCKWISE,								//  VkFrontFace								frontFace;
			VK_FALSE,														//  VkBool32								depthBiasEnable;
			0.0f,															//  float									depthBiasConstantFactor;
			0.0f,															//  float									depthBiasClamp;
			0.0f,															//  float									depthBiasSlopeFactor;
			0.0f,															//  float									lineWidth;
		};

		result.push_back(rasterizationStateCreateInfo);
	}

	return result;
}

const VkPipelineRasterizationStateCreateInfo* ConservativePointTestInstance::getRasterizationStateCreateInfo	(void) const
{
	return &m_rasterizationStateCreateInfo[getIteration()];
}

const VkPipelineRasterizationLineStateCreateInfoEXT* ConservativePointTestInstance::getLineRasterizationStateCreateInfo	(void)
{
	return DE_NULL;
}


template <typename ConcreteTestInstance>
class WidenessTestCase : public BaseRenderingTestCase
{
public:
								WidenessTestCase	(tcu::TestContext&			context,
													 const std::string&			name,
													 const std::string&			description,
													 PrimitiveWideness			wideness,
													 PrimitiveStrictness		strictness,
													 bool						isLineTest,
													 VkSampleCountFlagBits		sampleCount,
													 LineStipple				stipple,
													 VkLineRasterizationModeEXT	lineRasterizationMode,
													 LineStippleFactorCase		stippleFactor = LineStippleFactorCase::DEFAULT,
													 deUint32					additionalRenderSize	= 0)
									: BaseRenderingTestCase		(context, name, description, sampleCount)
									, m_wideness				(wideness)
									, m_strictness				(strictness)
									, m_isLineTest				(isLineTest)
									, m_stipple					(stipple)
									, m_lineRasterizationMode	(lineRasterizationMode)
									, m_stippleFactor			(stippleFactor)
									, m_additionalRenderSize	(additionalRenderSize)
								{}

	virtual TestInstance*		createInstance		(Context& context) const
								{
									return new ConcreteTestInstance(context, m_wideness, m_strictness, m_sampleCount, m_stipple, m_lineRasterizationMode, m_stippleFactor, m_additionalRenderSize);
								}

	virtual	void				checkSupport		(Context& context) const
								{
									if (m_isLineTest)
									{
										if (m_wideness == PRIMITIVEWIDENESS_WIDE)
											context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);

										switch (m_lineRasterizationMode)
										{
											default:
												TCU_THROW(InternalError, "Unknown line rasterization mode");

											case VK_LINE_RASTERIZATION_MODE_EXT_LAST:
											{
												if (m_strictness == PRIMITIVESTRICTNESS_STRICT)
													if (!context.getDeviceProperties().limits.strictLines)
														TCU_THROW(NotSupportedError, "Strict rasterization is not supported");

												if (m_strictness == PRIMITIVESTRICTNESS_NONSTRICT)
													if (context.getDeviceProperties().limits.strictLines)
														TCU_THROW(NotSupportedError, "Nonstrict rasterization is not supported");

												break;
											}

											case VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT:
											{
												if (!context.getDeviceProperties().limits.strictLines)
													TCU_THROW(NotSupportedError, "Strict rasterization is not supported");

												if (getLineStippleEnable() &&
													!context.getLineRasterizationFeaturesEXT().stippledRectangularLines)
													TCU_THROW(NotSupportedError, "Stippled rectangular lines not supported");
												break;
											}

											case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT:
											{
												if (!context.getLineRasterizationFeaturesEXT().rectangularLines)
													TCU_THROW(NotSupportedError, "Rectangular lines not supported");

												if (getLineStippleEnable() &&
													!context.getLineRasterizationFeaturesEXT().stippledRectangularLines)
													TCU_THROW(NotSupportedError, "Stippled rectangular lines not supported");
												break;
											}

											case VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT:
											{
												if (!context.getLineRasterizationFeaturesEXT().bresenhamLines)
													TCU_THROW(NotSupportedError, "Bresenham lines not supported");

												if (getLineStippleEnable() &&
													!context.getLineRasterizationFeaturesEXT().stippledBresenhamLines)
													TCU_THROW(NotSupportedError, "Stippled Bresenham lines not supported");
												break;
											}

											case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT:
											{
												if (!context.getLineRasterizationFeaturesEXT().smoothLines)
													TCU_THROW(NotSupportedError, "Smooth lines not supported");

												if (getLineStippleEnable() &&
													!context.getLineRasterizationFeaturesEXT().stippledSmoothLines)
													TCU_THROW(NotSupportedError, "Stippled smooth lines not supported");
												break;
											}
										}
									}
									else
									{
										if (m_wideness == PRIMITIVEWIDENESS_WIDE)
											context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
									}
								}

	bool					getLineStippleEnable	(void) const { return m_stipple != LINESTIPPLE_DISABLED; }
	virtual bool			getLineStippleDynamic	(void) const { return m_stipple == LINESTIPPLE_DYNAMIC; }

protected:
	const PrimitiveWideness				m_wideness;
	const PrimitiveStrictness			m_strictness;
	const bool							m_isLineTest;
	const LineStipple					m_stipple;
	const VkLineRasterizationModeEXT	m_lineRasterizationMode;
	const LineStippleFactorCase			m_stippleFactor;
	const deUint32						m_additionalRenderSize;
};

class LinesTestInstance : public BaseLineTestInstance
{
public:
								LinesTestInstance	(Context& context, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode, LineStippleFactorCase stippleFactor, deUint32 additionalRenderSize = 0)
									: BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, wideness, strictness, sampleCount, stipple, lineRasterizationMode, stippleFactor, additionalRenderSize)
								{}

	virtual void				generateLines		(int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
};

void LinesTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
{
	outData.resize(8);

	switch (iteration)
	{
		case 0:
			// \note: these values are chosen arbitrarily
			outData[0] = tcu::Vec4( 0.01f,  0.0f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4(  0.5f,  0.2f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4( 0.46f,  0.3f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4( -0.3f,  0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4( -1.5f, -0.4f, 0.0f, 1.0f);
			outData[5] = tcu::Vec4(  0.1f,  0.5f, 0.0f, 1.0f);
			outData[6] = tcu::Vec4( 0.75f, -0.4f, 0.0f, 1.0f);
			outData[7] = tcu::Vec4(  0.3f,  0.8f, 0.0f, 1.0f);
			break;

		case 1:
			outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4(-0.501f,  -0.3f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4(  0.11f,  -0.2f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4(  0.11f,   0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4(  0.88f,   0.9f, 0.0f, 1.0f);
			outData[5] = tcu::Vec4(  0.18f,  -0.2f, 0.0f, 1.0f);
			outData[6] = tcu::Vec4(   0.0f,   1.0f, 0.0f, 1.0f);
			outData[7] = tcu::Vec4(   0.0f,  -1.0f, 0.0f, 1.0f);
			break;

		case 2:
			outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4(  1.1f, -0.9f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4(  0.7f, -0.1f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4( 0.11f,  0.2f, 0.0f, 1.0f);
			outData[4] = tcu::Vec4( 0.88f,  0.7f, 0.0f, 1.0f);
			outData[5] = tcu::Vec4(  0.8f, -0.7f, 0.0f, 1.0f);
			outData[6] = tcu::Vec4(  0.9f,  0.7f, 0.0f, 1.0f);
			outData[7] = tcu::Vec4( -0.9f,  0.7f, 0.0f, 1.0f);
			break;
	}

	outLines.resize(4);
	outLines[0].positions[0] = outData[0];
	outLines[0].positions[1] = outData[1];
	outLines[1].positions[0] = outData[2];
	outLines[1].positions[1] = outData[3];
	outLines[2].positions[0] = outData[4];
	outLines[2].positions[1] = outData[5];
	outLines[3].positions[0] = outData[6];
	outLines[3].positions[1] = outData[7];

	// log
	m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outLines.size() << " lines(s): (width = " << getLineWidth() << ")" << tcu::TestLog::EndMessage;
	for (int lineNdx = 0; lineNdx < (int)outLines.size(); ++lineNdx)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "Line " << (lineNdx+1) << ":"
			<< "\n\t" << outLines[lineNdx].positions[0]
			<< "\n\t" << outLines[lineNdx].positions[1]
			<< tcu::TestLog::EndMessage;
	}
}

class LineStripTestInstance : public BaseLineTestInstance
{
public:
					LineStripTestInstance	(Context& context, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode, LineStippleFactorCase stippleFactor, deUint32)
						: BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, wideness, strictness, sampleCount, stipple, lineRasterizationMode, stippleFactor)
					{}

	virtual void	generateLines			(int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
};

void LineStripTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
{
	outData.resize(4);

	switch (iteration)
	{
		case 0:
			// \note: these values are chosen arbitrarily
			outData[0] = tcu::Vec4( 0.01f,  0.0f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4( 0.5f,   0.2f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4( 0.46f,  0.3f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4(-0.5f,   0.2f, 0.0f, 1.0f);
			break;

		case 1:
			outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4(-0.501f,  -0.3f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4(  0.11f,  -0.2f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4(  0.11f,   0.2f, 0.0f, 1.0f);
			break;

		case 2:
			outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
			outData[1] = tcu::Vec4(  0.9f, -0.9f, 0.0f, 1.0f);
			outData[2] = tcu::Vec4(  0.7f, -0.1f, 0.0f, 1.0f);
			outData[3] = tcu::Vec4( 0.11f,  0.2f, 0.0f, 1.0f);
			break;
	}

	outLines.resize(3);
	outLines[0].positions[0] = outData[0];
	outLines[0].positions[1] = outData[1];
	outLines[1].positions[0] = outData[1];
	outLines[1].positions[1] = outData[2];
	outLines[2].positions[0] = outData[2];
	outLines[2].positions[1] = outData[3];

	// log
	m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering line strip, width = " << getLineWidth() << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
	for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message
			<< "\t" << outData[vtxNdx]
			<< tcu::TestLog::EndMessage;
	}
}

class FillRuleTestInstance : public BaseRenderingTestInstance
{
public:
	enum FillRuleCaseType
	{
		FILLRULECASE_BASIC = 0,
		FILLRULECASE_REVERSED,
		FILLRULECASE_CLIPPED_FULL,
		FILLRULECASE_CLIPPED_PARTIAL,
		FILLRULECASE_PROJECTED,

		FILLRULECASE_LAST
	};
														FillRuleTestInstance			(Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount);
	virtual tcu::TestStatus								iterate							(void);

private:

	virtual const VkPipelineColorBlendStateCreateInfo*	getColorBlendStateCreateInfo	(void) const;
	int													getRenderSize					(FillRuleCaseType type) const;
	int													getNumIterations				(FillRuleCaseType type) const;
	void												generateTriangles				(int iteration, std::vector<tcu::Vec4>& outData) const;

	const FillRuleCaseType								m_caseType;
	int													m_iteration;
	const int											m_iterationCount;
	bool												m_allIterationsPassed;

};

FillRuleTestInstance::FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount)
	: BaseRenderingTestInstance		(context, sampleCount, getRenderSize(type))
	, m_caseType					(type)
	, m_iteration					(0)
	, m_iterationCount				(getNumIterations(type))
	, m_allIterationsPassed			(true)
{
	DE_ASSERT(type < FILLRULECASE_LAST);
}

tcu::TestStatus FillRuleTestInstance::iterate (void)
{
	const std::string						iterationDescription	= "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
	const tcu::ScopedLogSection				section					(m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
	tcu::IVec4								colorBits				= tcu::getTextureFormatBitDepth(getTextureFormat());
	const int								thresholdRed			= 1 << (8 - colorBits[0]);
	const int								thresholdGreen			= 1 << (8 - colorBits[1]);
	const int								thresholdBlue			= 1 << (8 - colorBits[2]);
	tcu::Surface							resultImage				(m_renderSize, m_renderSize);
	std::vector<tcu::Vec4>					drawBuffer;

	generateTriangles(m_iteration, drawBuffer);

	// draw image
	{
		const std::vector<tcu::Vec4>	colorBuffer		(drawBuffer.size(), tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));

		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing gray triangles with shared edges.\nEnabling additive blending to detect overlapping fragments." << tcu::TestLog::EndMessage;

		drawPrimitives(resultImage, drawBuffer, colorBuffer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
	}

	// verify no overdraw
	{
		const tcu::RGBA	triangleColor	= tcu::RGBA(127, 127, 127, 255);
		bool			overdraw		= false;

		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Verifying result." << tcu::TestLog::EndMessage;

		for (int y = 0; y < resultImage.getHeight(); ++y)
		for (int x = 0; x < resultImage.getWidth();  ++x)
		{
			const tcu::RGBA color = resultImage.getPixel(x, y);

			// color values are greater than triangle color? Allow lower values for multisampled edges and background.
			if ((color.getRed()   - triangleColor.getRed())   > thresholdRed   ||
				(color.getGreen() - triangleColor.getGreen()) > thresholdGreen ||
				(color.getBlue()  - triangleColor.getBlue())  > thresholdBlue)
				overdraw = true;
		}

		// results
		if (!overdraw)
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "No overlapping fragments detected." << tcu::TestLog::EndMessage;
		else
		{
			m_context.getTestContext().getLog()	<< tcu::TestLog::Message << "Overlapping fragments detected, image is not valid." << tcu::TestLog::EndMessage;
			m_allIterationsPassed = false;
		}
	}

	// verify no missing fragments in the full viewport case
	if (m_caseType == FILLRULECASE_CLIPPED_FULL)
	{
		bool missingFragments = false;

		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Searching missing fragments." << tcu::TestLog::EndMessage;

		for (int y = 0; y < resultImage.getHeight(); ++y)
		for (int x = 0; x < resultImage.getWidth();  ++x)
		{
			const tcu::RGBA color = resultImage.getPixel(x, y);

			// black? (background)
			if (color.getRed()   <= thresholdRed   ||
				color.getGreen() <= thresholdGreen ||
				color.getBlue()  <= thresholdBlue)
				missingFragments = true;
		}

		// results
		if (!missingFragments)
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "No missing fragments detected." << tcu::TestLog::EndMessage;
		else
		{
			m_context.getTestContext().getLog()	<< tcu::TestLog::Message << "Missing fragments detected, image is not valid." << tcu::TestLog::EndMessage;

			m_allIterationsPassed = false;
		}
	}

	m_context.getTestContext().getLog()	<< tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
										<< tcu::TestLog::Image("Result", "Result", resultImage)
										<< tcu::TestLog::EndImageSet;

	// result
	if (++m_iteration == m_iterationCount)
	{
		if (m_allIterationsPassed)
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Found invalid pixels");
	}
	else
		return tcu::TestStatus::incomplete();
}

int FillRuleTestInstance::getRenderSize (FillRuleCaseType type) const
{
	if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
		return RESOLUTION_POT / 4;
	else
		return RESOLUTION_POT;
}

int FillRuleTestInstance::getNumIterations (FillRuleCaseType type) const
{
	if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
		return 15;
	else
		return 2;
}

void FillRuleTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const
{
	switch (m_caseType)
	{
		case FILLRULECASE_BASIC:
		case FILLRULECASE_REVERSED:
		case FILLRULECASE_PROJECTED:
		{
			const int	numRows		= 4;
			const int	numColumns	= 4;
			const float	quadSide	= 0.15f;
			de::Random	rnd			(0xabcd);

			outData.resize(6 * numRows * numColumns);

			for (int col = 0; col < numColumns; ++col)
			for (int row = 0; row < numRows;    ++row)
			{
				const tcu::Vec2 center		= tcu::Vec2(((float)row + 0.5f) / (float)numRows * 2.0f - 1.0f, ((float)col + 0.5f) / (float)numColumns * 2.0f - 1.0f);
				const float		rotation	= (float)(iteration * numColumns * numRows + col * numRows + row) / (float)(m_iterationCount * numColumns * numRows) * DE_PI / 2.0f;
				const tcu::Vec2 sideH		= quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
				const tcu::Vec2 sideV		= tcu::Vec2(sideH.y(), -sideH.x());
				const tcu::Vec2 quad[4]		=
				{
					center + sideH + sideV,
					center + sideH - sideV,
					center - sideH - sideV,
					center - sideH + sideV,
				};

				if (m_caseType == FILLRULECASE_BASIC)
				{
					outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
					outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
					outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
					outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
					outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
					outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
				}
				else if (m_caseType == FILLRULECASE_REVERSED)
				{
					outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
					outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
					outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
					outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
					outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
					outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
				}
				else if (m_caseType == FILLRULECASE_PROJECTED)
				{
					const float w0 = rnd.getFloat(0.1f, 4.0f);
					const float w1 = rnd.getFloat(0.1f, 4.0f);
					const float w2 = rnd.getFloat(0.1f, 4.0f);
					const float w3 = rnd.getFloat(0.1f, 4.0f);

					outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
					outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x() * w1, quad[1].y() * w1, 0.0f, w1);
					outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
					outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
					outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
					outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x() * w3, quad[3].y() * w3, 0.0f, w3);
				}
				else
					DE_ASSERT(DE_FALSE);
			}

			break;
		}

		case FILLRULECASE_CLIPPED_PARTIAL:
		case FILLRULECASE_CLIPPED_FULL:
		{
			const float		quadSide	= (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (1.0f) : (2.0f);
			const tcu::Vec2 center		= (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (tcu::Vec2(0.5f, 0.5f)) : (tcu::Vec2(0.0f, 0.0f));
			const float		rotation	= (float)(iteration) / (float)(m_iterationCount - 1) * DE_PI / 2.0f;
			const tcu::Vec2 sideH		= quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
			const tcu::Vec2 sideV		= tcu::Vec2(sideH.y(), -sideH.x());
			const tcu::Vec2 quad[4]		=
			{
				center + sideH + sideV,
				center + sideH - sideV,
				center - sideH - sideV,
				center - sideH + sideV,
			};

			outData.resize(6);
			outData[0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
			outData[1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
			outData[2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
			outData[3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
			outData[4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
			outData[5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
			break;
		}

		default:
			DE_ASSERT(DE_FALSE);
	}
}

const VkPipelineColorBlendStateCreateInfo* FillRuleTestInstance::getColorBlendStateCreateInfo (void) const
{
	static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
	{
		true,														// VkBool32			blendEnable;
		VK_BLEND_FACTOR_ONE,										// VkBlend			srcBlendColor;
		VK_BLEND_FACTOR_ONE,										// VkBlend			destBlendColor;
		VK_BLEND_OP_ADD,											// VkBlendOp		blendOpColor;
		VK_BLEND_FACTOR_ONE,										// VkBlend			srcBlendAlpha;
		VK_BLEND_FACTOR_ONE,										// VkBlend			destBlendAlpha;
		VK_BLEND_OP_ADD,											// VkBlendOp		blendOpAlpha;
		(VK_COLOR_COMPONENT_R_BIT |
		 VK_COLOR_COMPONENT_G_BIT |
		 VK_COLOR_COMPONENT_B_BIT |
		 VK_COLOR_COMPONENT_A_BIT)									// VkChannelFlags	channelWriteMask;
	};

	static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
		DE_NULL,													// const void*									pNext;
		0,															// VkPipelineColorBlendStateCreateFlags			flags;
		false,														// VkBool32										logicOpEnable;
		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
		1u,															// deUint32										attachmentCount;
		&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
	};

	return &colorBlendStateParams;
}


class FillRuleTestCase : public BaseRenderingTestCase
{
public:
								FillRuleTestCase	(tcu::TestContext& context, const std::string& name, const std::string& description, FillRuleTestInstance::FillRuleCaseType type, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
									: BaseRenderingTestCase	(context, name, description, sampleCount)
									, m_type				(type)
								{}

	virtual TestInstance*		createInstance		(Context& context) const
								{
									return new FillRuleTestInstance(context, m_type, m_sampleCount);
								}
protected:
	const FillRuleTestInstance::FillRuleCaseType m_type;
};

class CullingTestInstance : public BaseRenderingTestInstance
{
public:
													CullingTestInstance				(Context& context, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode)
														: BaseRenderingTestInstance		(context, VK_SAMPLE_COUNT_1_BIT, RESOLUTION_POT)
														, m_cullMode					(cullMode)
														, m_primitiveTopology			(primitiveTopology)
														, m_frontFace					(frontFace)
														, m_polygonMode					(polygonMode)
														, m_multisampling				(true)
													{}
	virtual
	const VkPipelineRasterizationStateCreateInfo*	getRasterizationStateCreateInfo (void) const;

	tcu::TestStatus									iterate							(void);

private:
	void											generateVertices				(std::vector<tcu::Vec4>& outData) const;
	void											extractTriangles				(std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
	void											extractLines					(std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<LineSceneSpec::SceneLine>& outLines) const;
	void											extractPoints					(std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<PointSceneSpec::ScenePoint>& outPoints) const;
	bool											triangleOrder					(const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const;

	const VkCullModeFlags							m_cullMode;
	const VkPrimitiveTopology						m_primitiveTopology;
	const VkFrontFace								m_frontFace;
	const VkPolygonMode								m_polygonMode;
	const bool										m_multisampling;
};


tcu::TestStatus CullingTestInstance::iterate (void)
{
	DE_ASSERT(m_polygonMode <= VK_POLYGON_MODE_POINT);

	tcu::Surface									resultImage						(m_renderSize, m_renderSize);
	std::vector<tcu::Vec4>							drawBuffer;
	std::vector<TriangleSceneSpec::SceneTriangle>	triangles;
	std::vector<PointSceneSpec::ScenePoint>			points;
	std::vector<LineSceneSpec::SceneLine>			lines;

	const InstanceInterface&						vk				= m_context.getInstanceInterface();
	const VkPhysicalDevice							physicalDevice	= m_context.getPhysicalDevice();
	const VkPhysicalDeviceFeatures					deviceFeatures	= getPhysicalDeviceFeatures(vk, physicalDevice);

	if (!(deviceFeatures.fillModeNonSolid) && (m_polygonMode == VK_POLYGON_MODE_LINE || m_polygonMode == VK_POLYGON_MODE_POINT))
		TCU_THROW(NotSupportedError, "Wireframe fill modes are not supported");

	// generate scene
	generateVertices(drawBuffer);
	extractTriangles(triangles, drawBuffer);

	if (m_polygonMode == VK_POLYGON_MODE_LINE)
		extractLines(triangles ,lines);
	else if (m_polygonMode == VK_POLYGON_MODE_POINT)
		extractPoints(triangles, points);

	// draw image
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting front face to " << m_frontFace << tcu::TestLog::EndMessage;
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting cull face to " << m_cullMode << tcu::TestLog::EndMessage;
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing test pattern (" << m_primitiveTopology << ")" << tcu::TestLog::EndMessage;

		drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
	}

	// compare
	{
		RasterizationArguments	args;
		tcu::IVec4				colorBits	= tcu::getTextureFormatBitDepth(getTextureFormat());
		bool					isCompareOk	= false;

		args.numSamples		= m_multisampling ? 1 : 0;
		args.subpixelBits	= m_subpixelBits;
		args.redBits		= colorBits[0];
		args.greenBits		= colorBits[1];
		args.blueBits		= colorBits[2];

		switch (m_polygonMode)
		{
			case VK_POLYGON_MODE_LINE:
			{
				LineSceneSpec scene;
				scene.lineWidth = 0;
				scene.lines.swap(lines);
				isCompareOk = verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
				break;
			}
			case VK_POLYGON_MODE_POINT:
			{
				PointSceneSpec scene;
				scene.points.swap(points);
				isCompareOk = verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
				break;
			}
			default:
			{
				TriangleSceneSpec scene;
				scene.triangles.swap(triangles);
				isCompareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), tcu::VERIFICATIONMODE_WEAK);
				break;
			}
		}

		if (isCompareOk)
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Incorrect rendering");
	}
}

void CullingTestInstance::generateVertices (std::vector<tcu::Vec4>& outData) const
{
	de::Random rnd(543210);

	outData.resize(6);
	for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
	{
		outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
		outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
		outData[vtxNdx].z() = 0.0f;
		outData[vtxNdx].w() = 1.0f;
	}
}

void CullingTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
{
	const bool cullDirection = (m_cullMode == VK_CULL_MODE_FRONT_BIT) ^ (m_frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);

	// No triangles
	if (m_cullMode == VK_CULL_MODE_FRONT_AND_BACK)
		return;

	switch (m_primitiveTopology)
	{
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
		{
			for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
			{
				const tcu::Vec4& v0 = vertices[vtxNdx + 0];
				const tcu::Vec4& v1 = vertices[vtxNdx + 1];
				const tcu::Vec4& v2 = vertices[vtxNdx + 2];

				if (triangleOrder(v0, v1, v2) != cullDirection)
				{
					TriangleSceneSpec::SceneTriangle tri;
					tri.positions[0] = v0;	tri.sharedEdge[0] = false;
					tri.positions[1] = v1;	tri.sharedEdge[1] = false;
					tri.positions[2] = v2;	tri.sharedEdge[2] = false;

					outTriangles.push_back(tri);
				}
			}
			break;
		}

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
		{
			for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
			{
				const tcu::Vec4& v0 = vertices[vtxNdx + 0];
				const tcu::Vec4& v1 = vertices[vtxNdx + 1];
				const tcu::Vec4& v2 = vertices[vtxNdx + 2];

				if (triangleOrder(v0, v1, v2) != (cullDirection ^ (vtxNdx % 2 != 0)))
				{
					TriangleSceneSpec::SceneTriangle tri;
					tri.positions[0] = v0;	tri.sharedEdge[0] = false;
					tri.positions[1] = v1;	tri.sharedEdge[1] = false;
					tri.positions[2] = v2;	tri.sharedEdge[2] = false;

					outTriangles.push_back(tri);
				}
			}
			break;
		}

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
		{
			for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
			{
				const tcu::Vec4& v0 = vertices[0];
				const tcu::Vec4& v1 = vertices[vtxNdx + 0];
				const tcu::Vec4& v2 = vertices[vtxNdx + 1];

				if (triangleOrder(v0, v1, v2) != cullDirection)
				{
					TriangleSceneSpec::SceneTriangle tri;
					tri.positions[0] = v0;	tri.sharedEdge[0] = false;
					tri.positions[1] = v1;	tri.sharedEdge[1] = false;
					tri.positions[2] = v2;	tri.sharedEdge[2] = false;

					outTriangles.push_back(tri);
				}
			}
			break;
		}

		default:
			DE_ASSERT(false);
	}
}

void CullingTestInstance::extractLines (std::vector<TriangleSceneSpec::SceneTriangle>&	outTriangles,
										std::vector<LineSceneSpec::SceneLine>&			outLines) const
{
	for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
	{
		for (int vrtxNdx = 0; vrtxNdx < 2; ++vrtxNdx)
		{
			LineSceneSpec::SceneLine line;
			line.positions[0] = outTriangles.at(triNdx).positions[vrtxNdx];
			line.positions[1] = outTriangles.at(triNdx).positions[vrtxNdx + 1];

			outLines.push_back(line);
		}
		LineSceneSpec::SceneLine line;
		line.positions[0] = outTriangles.at(triNdx).positions[2];
		line.positions[1] = outTriangles.at(triNdx).positions[0];
		outLines.push_back(line);
	}
}

void CullingTestInstance::extractPoints (std::vector<TriangleSceneSpec::SceneTriangle>	&outTriangles,
										std::vector<PointSceneSpec::ScenePoint>			&outPoints) const
{
	for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
	{
		for (int vrtxNdx = 0; vrtxNdx < 3; ++vrtxNdx)
		{
			PointSceneSpec::ScenePoint point;
			point.position = outTriangles.at(triNdx).positions[vrtxNdx];
			point.pointSize = 1.0f;

			outPoints.push_back(point);
		}
	}
}

bool CullingTestInstance::triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const
{
	const tcu::Vec2 s0 = v0.swizzle(0, 1) / v0.w();
	const tcu::Vec2 s1 = v1.swizzle(0, 1) / v1.w();
	const tcu::Vec2 s2 = v2.swizzle(0, 1) / v2.w();

	// cross
	return ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) > 0;
}


const VkPipelineRasterizationStateCreateInfo* CullingTestInstance::getRasterizationStateCreateInfo (void) const
{
	static VkPipelineRasterizationStateCreateInfo	rasterizationStateCreateInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
		DE_NULL,														// const void*								pNext;
		0,																// VkPipelineRasterizationStateCreateFlags	flags;
		false,															// VkBool32									depthClipEnable;
		false,															// VkBool32									rasterizerDiscardEnable;
		VK_POLYGON_MODE_FILL,											// VkFillMode								fillMode;
		VK_CULL_MODE_NONE,												// VkCullMode								cullMode;
		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
		VK_FALSE,														// VkBool32									depthBiasEnable;
		0.0f,															// float									depthBias;
		0.0f,															// float									depthBiasClamp;
		0.0f,															// float									slopeScaledDepthBias;
		getLineWidth(),													// float									lineWidth;
	};

	rasterizationStateCreateInfo.lineWidth		= getLineWidth();
	rasterizationStateCreateInfo.cullMode		= m_cullMode;
	rasterizationStateCreateInfo.frontFace		= m_frontFace;
	rasterizationStateCreateInfo.polygonMode	= m_polygonMode;

	return &rasterizationStateCreateInfo;
}

class CullingTestCase : public BaseRenderingTestCase
{
public:
								CullingTestCase		(tcu::TestContext& context, const std::string& name, const std::string& description, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
									: BaseRenderingTestCase	(context, name, description, sampleCount)
									, m_cullMode			(cullMode)
									, m_primitiveTopology	(primitiveTopology)
									, m_frontFace			(frontFace)
									, m_polygonMode			(polygonMode)
								{}

	virtual TestInstance*		createInstance		(Context& context) const
								{
									return new CullingTestInstance(context, m_cullMode, m_primitiveTopology, m_frontFace, m_polygonMode);
								}
	void						checkSupport		(Context& context) const;
protected:
	const VkCullModeFlags		m_cullMode;
	const VkPrimitiveTopology	m_primitiveTopology;
	const VkFrontFace			m_frontFace;
	const VkPolygonMode			m_polygonMode;
};

void CullingTestCase::checkSupport (Context& context) const
{
#ifndef CTS_USES_VULKANSC
	if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset"))
	{
		const VkPhysicalDevicePortabilitySubsetFeaturesKHR& subsetFeatures = context.getPortabilitySubsetFeatures();
		if (m_polygonMode == VK_POLYGON_MODE_POINT && !subsetFeatures.pointPolygons)
			TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Point polygons are not supported by this implementation");
		if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN && !subsetFeatures.triangleFans)
			TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
	}
#else
	DE_UNREF(context);
#endif // CTS_USES_VULKANSC
}

class DiscardTestInstance : public BaseRenderingTestInstance
{
public:
															DiscardTestInstance					(Context& context, VkPrimitiveTopology primitiveTopology, deBool queryFragmentShaderInvocations)
																: BaseRenderingTestInstance			(context, VK_SAMPLE_COUNT_1_BIT, RESOLUTION_POT)
																, m_primitiveTopology				(primitiveTopology)
																, m_queryFragmentShaderInvocations	(queryFragmentShaderInvocations)
															{}

	virtual const VkPipelineRasterizationStateCreateInfo*	getRasterizationStateCreateInfo		(void) const;
	tcu::TestStatus											iterate								(void);

private:
	void													generateVertices					(std::vector<tcu::Vec4>& outData) const;
	void													extractTriangles					(std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
	void													extractLines						(std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices) const;
	void													extractPoints						(std::vector<PointSceneSpec::ScenePoint>& outPoints, const std::vector<tcu::Vec4>& vertices) const;
	void													drawPrimitivesDiscard				(tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, VkPrimitiveTopology primitiveTopology, Move<VkQueryPool>& queryPool);

	const VkPrimitiveTopology								m_primitiveTopology;
	const deBool											m_queryFragmentShaderInvocations;
};

tcu::TestStatus DiscardTestInstance::iterate (void)
{
	const DeviceInterface&							vkd			= m_context.getDeviceInterface();
	const VkDevice									vkDevice	= m_context.getDevice();
	deUint64										queryResult	= 0u;
	tcu::Surface									resultImage	(m_renderSize, m_renderSize);
	std::vector<tcu::Vec4>							drawBuffer;
	std::vector<PointSceneSpec::ScenePoint>			points;
	std::vector<LineSceneSpec::SceneLine>			lines;
	std::vector<TriangleSceneSpec::SceneTriangle>	triangles;

	generateVertices(drawBuffer);

	switch (m_primitiveTopology)
	{
		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
			extractPoints(points, drawBuffer);
			break;

		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
			extractLines(lines, drawBuffer);
			break;

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
			extractTriangles(triangles, drawBuffer);
			break;

		default:
			DE_ASSERT(false);
	}

	const VkQueryPoolCreateInfo queryPoolCreateInfo =
	{
		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,						// VkStructureType					sType
		DE_NULL,														// const void*						pNext
		(VkQueryPoolCreateFlags)0,										// VkQueryPoolCreateFlags			flags
		VK_QUERY_TYPE_PIPELINE_STATISTICS ,								// VkQueryType						queryType
		1u,																// deUint32							entryCount
		VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT,	// VkQueryPipelineStatisticFlags	pipelineStatistics
	};

	if (m_queryFragmentShaderInvocations)
	{
		Move<VkQueryPool> queryPool	= createQueryPool(vkd, vkDevice, &queryPoolCreateInfo);

		drawPrimitivesDiscard(resultImage, drawBuffer, m_primitiveTopology, queryPool);
		vkd.getQueryPoolResults(vkDevice, *queryPool, 0u, 1u, sizeof(deUint64), &queryResult, 0u, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
	}
	else
		BaseRenderingTestInstance::drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);

	// compare
	{
		tcu::IVec4						colorBits	= tcu::getTextureFormatBitDepth(getTextureFormat());

		const RasterizationArguments	args		=
		{
			0,							// int	numSamples;
			(int)m_subpixelBits,		// int	subpixelBits;
			colorBits[0],				// int	redBits;
			colorBits[1],				// int	greenBits;
			colorBits[2]				// int	blueBits;
		};

		// Empty scene to compare to, primitives should be discarded before rasterization
		TriangleSceneSpec				scene;

		const bool						isCompareOk	= verifyTriangleGroupRasterization(resultImage,
																					   scene,
																					   args,
																					   m_context.getTestContext().getLog(),
																					   tcu::VERIFICATIONMODE_STRICT);

		if (isCompareOk)
		{
			if (m_queryFragmentShaderInvocations && queryResult > 0u)
				return tcu::TestStatus::fail("Fragment shader invocations occured");
			else
				return tcu::TestStatus::pass("Pass");
		}
		else
			return tcu::TestStatus::fail("Incorrect rendering");
	}
}

void DiscardTestInstance::generateVertices (std::vector<tcu::Vec4>& outData) const
{
	de::Random rnd(12345);

	outData.resize(6);

	for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
	{
		outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
		outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
		outData[vtxNdx].z() = 0.0f;
		outData[vtxNdx].w() = 1.0f;
	}
}

void DiscardTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
{
	switch (m_primitiveTopology)
	{
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
		{
			for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
			{
				TriangleSceneSpec::SceneTriangle	tri;
				const tcu::Vec4&					v0	= vertices[vtxNdx + 0];
				const tcu::Vec4&					v1	= vertices[vtxNdx + 1];
				const tcu::Vec4&					v2	= vertices[vtxNdx + 2];

				tri.positions[0] = v0;
				tri.positions[1] = v1;
				tri.positions[2] = v2;

				outTriangles.push_back(tri);
			}

			break;
		}

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
		{
			for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
			{
				TriangleSceneSpec::SceneTriangle	tri;
				const tcu::Vec4&					v0	= vertices[vtxNdx + 0];
				const tcu::Vec4&					v1	= vertices[vtxNdx + 1];
				const tcu::Vec4&					v2	= vertices[vtxNdx + 2];

				tri.positions[0] = v0;
				tri.positions[1] = v1;
				tri.positions[2] = v2;

				outTriangles.push_back(tri);
			}

			break;
		}

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
		{
			for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
			{
				TriangleSceneSpec::SceneTriangle	tri;
				const tcu::Vec4&					v0	= vertices[0];
				const tcu::Vec4&					v1	= vertices[vtxNdx + 0];
				const tcu::Vec4&					v2	= vertices[vtxNdx + 1];

				tri.positions[0] = v0;
				tri.positions[1] = v1;
				tri.positions[2] = v2;

				outTriangles.push_back(tri);
			}

			break;
		}

		default:
			DE_ASSERT(false);
	}
}

void DiscardTestInstance::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices) const
{
	switch (m_primitiveTopology)
	{
		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
		{
			for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
			{
				LineSceneSpec::SceneLine line;

				line.positions[0] = vertices[vtxNdx + 0];
				line.positions[1] = vertices[vtxNdx + 1];

				outLines.push_back(line);
			}

			break;
		}

		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
		{
			for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
			{
				LineSceneSpec::SceneLine line;

				line.positions[0] = vertices[vtxNdx + 0];
				line.positions[1] = vertices[vtxNdx + 1];

				outLines.push_back(line);
			}

			break;
		}

		default:
			DE_ASSERT(false);
		}
}

void DiscardTestInstance::extractPoints (std::vector<PointSceneSpec::ScenePoint>& outPoints, const std::vector<tcu::Vec4>& vertices) const
{
	for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
	{
		for (int vrtxNdx = 0; vrtxNdx < 3; ++vrtxNdx)
		{
			PointSceneSpec::ScenePoint point;

			point.position	= vertices[vrtxNdx];
			point.pointSize	= 1.0f;

			outPoints.push_back(point);
		}
	}
}

const VkPipelineRasterizationStateCreateInfo* DiscardTestInstance::getRasterizationStateCreateInfo (void) const
{
	static const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType							sType;
		NULL,														// const void*								pNext;
		0,															// VkPipelineRasterizationStateCreateFlags	flags;
		VK_FALSE,													// VkBool32									depthClipEnable;
		VK_TRUE,													// VkBool32									rasterizerDiscardEnable;
		VK_POLYGON_MODE_FILL,										// VkFillMode								fillMode;
		VK_CULL_MODE_NONE,											// VkCullMode								cullMode;
		VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace								frontFace;
		VK_FALSE,													// VkBool32									depthBiasEnable;
		0.0f,														// float									depthBias;
		0.0f,														// float									depthBiasClamp;
		0.0f,														// float									slopeScaledDepthBias;
		getLineWidth(),												// float									lineWidth;
	};

	return &rasterizationStateCreateInfo;
}

void DiscardTestInstance::drawPrimitivesDiscard (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, VkPrimitiveTopology primitiveTopology, Move<VkQueryPool>& queryPool)
{
	const DeviceInterface&				vkd					= m_context.getDeviceInterface();
	const VkDevice						vkDevice			= m_context.getDevice();
	const VkPhysicalDeviceProperties	properties			= m_context.getDeviceProperties();
	const VkQueue						queue				= m_context.getUniversalQueue();
	const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	Allocator&							allocator			= m_context.getDefaultAllocator();

	const size_t						attributeBatchSize	= positionData.size() * sizeof(tcu::Vec4);
	const VkDeviceSize					vertexBufferOffset	= 0;
	de::MovePtr<Allocation>				vertexBufferMemory;
	Move<VkBuffer>						vertexBuffer;
	Move<VkCommandBuffer>				commandBuffer;
	Move<VkPipeline>					graphicsPipeline;

	if (attributeBatchSize > properties.limits.maxVertexInputAttributeOffset)
	{
		std::stringstream message;
		message << "Larger vertex input attribute offset is needed (" << attributeBatchSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
		TCU_THROW(NotSupportedError, message.str().c_str());
	}

	// Create Graphics Pipeline
	{
		const VkVertexInputBindingDescription		vertexInputBindingDescription		=
		{
			0u,										// deUint32					binding;
			sizeof(tcu::Vec4),						// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX				// VkVertexInputStepRate	stepRate;
		};

		const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[2]	=
		{
			{
				0u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				0u									// deUint32	offsetInBytes;
			},
			{
				1u,									// deUint32	location;
				0u,									// deUint32	binding;
				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
				(deUint32)attributeBatchSize		// deUint32	offsetInBytes;
			}
		};

		const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
			DE_NULL,													// const void*								pNext;
			0,															// VkPipelineVertexInputStateCreateFlags	flags;
			1u,															// deUint32									bindingCount;
			&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
			2u,															// deUint32									attributeCount;
			vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
		};

		const std::vector<VkViewport>				viewports							(1, makeViewport(tcu::UVec2(m_renderSize)));
		const std::vector<VkRect2D>					scissors							(1, makeRect2D(tcu::UVec2(m_renderSize)));

		const VkPipelineMultisampleStateCreateInfo	multisampleStateParams				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
			DE_NULL,													// const void*								pNext;
			0u,															// VkPipelineMultisampleStateCreateFlags	flags;
			m_sampleCount,												// VkSampleCountFlagBits					rasterizationSamples;
			VK_FALSE,													// VkBool32									sampleShadingEnable;
			0.0f,														// float									minSampleShading;
			DE_NULL,													// const VkSampleMask*						pSampleMask;
			VK_FALSE,													// VkBool32									alphaToCoverageEnable;
			VK_FALSE													// VkBool32									alphaToOneEnable;
		};

		graphicsPipeline = makeGraphicsPipeline(vkd,								// const DeviceInterface&							vk
												vkDevice,							// const VkDevice									device
												*m_pipelineLayout,					// const VkPipelineLayout							pipelineLayout
												*m_vertexShaderModule,				// const VkShaderModule								vertexShaderModule
												DE_NULL,							// const VkShaderModule								tessellationControlShaderModule
												DE_NULL,							// const VkShaderModule								tessellationEvalShaderModule
												DE_NULL,							// const VkShaderModule								geometryShaderModule
												*m_fragmentShaderModule,			// const VkShaderModule								fragmentShaderModule
												*m_renderPass,						// const VkRenderPass								renderPass
												viewports,							// const std::vector<VkViewport>&					viewports
												scissors,							// const std::vector<VkRect2D>&						scissors
												primitiveTopology,					// const VkPrimitiveTopology						topology
												0u,									// const deUint32									subpass
												0u,									// const deUint32									patchControlPoints
												&vertexInputStateParams,			// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
												getRasterizationStateCreateInfo(),	// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
												&multisampleStateParams,			// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
												DE_NULL,							// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo,
												getColorBlendStateCreateInfo());	// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
	}

	// Create Vertex Buffer
	{
		const VkBufferCreateInfo					vertexBufferParams		=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			0u,										// VkBufferCreateFlags	flags;
			attributeBatchSize * 2,					// VkDeviceSize			size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
			1u,										// deUint32				queueFamilyCount;
			&queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
		};

		const std::vector<tcu::Vec4>				colorData				(positionData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));

		vertexBuffer		= createBuffer(vkd, vkDevice, &vertexBufferParams);
		vertexBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));

		// Load vertices into vertex buffer
		deMemcpy(vertexBufferMemory->getHostPtr(), positionData.data(), attributeBatchSize);
		deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + attributeBatchSize, colorData.data(), attributeBatchSize);
		flushAlloc(vkd, vkDevice, *vertexBufferMemory);
	}

	// Create Command Buffer
	commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

	// Begin Command Buffer
	beginCommandBuffer(vkd, *commandBuffer);

	addImageTransitionBarrier(*commandBuffer,									// VkCommandBuffer			commandBuffer
							  *m_image,											// VkImage					image
							  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,				// VkPipelineStageFlags		srcStageMask
							  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,				// VkPipelineStageFlags		dstStageMask
							  0,												// VkAccessFlags			srcAccessMask
							  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,				// VkAccessFlags			dstAccessMask
							  VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
							  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);		// VkImageLayout			newLayout;

	if (m_multisampling)
	{
		addImageTransitionBarrier(*commandBuffer,								// VkCommandBuffer			commandBuffer
								  *m_resolvedImage,								// VkImage					image
								  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,			// VkPipelineStageFlags		srcStageMask
								  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,			// VkPipelineStageFlags		dstStageMask
								  0,											// VkAccessFlags			srcAccessMask
								  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask
								  VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
								  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);	// VkImageLayout			newLayout;
	}

	// Reset query pool
	vkd.cmdResetQueryPool(*commandBuffer, *queryPool, 0u, 1u);

	// Begin render pass and start query
	beginRenderPass(vkd, *commandBuffer, *m_renderPass, *m_frameBuffer, vk::makeRect2D(0, 0, m_renderSize, m_renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
	vkd.cmdBeginQuery(*commandBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
	vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
	vkd.cmdDraw(*commandBuffer, (deUint32)positionData.size(), 1, 0, 0);
	endRenderPass(vkd, *commandBuffer);
	vkd.cmdEndQuery(*commandBuffer, *queryPool, 0u);

	// Copy Image
	copyImageToBuffer(vkd, *commandBuffer, m_multisampling ? *m_resolvedImage : *m_image, *m_resultBuffer, tcu::IVec2(m_renderSize, m_renderSize));

	endCommandBuffer(vkd, *commandBuffer);

	// Set Point Size
	{
		float pointSize = getPointSize();

		deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
		flushAlloc(vkd, vkDevice, *m_uniformBufferMemory);
	}

	// Submit
	submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());

	invalidateAlloc(vkd, vkDevice, *m_resultBufferMemory);
	tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
}

class DiscardTestCase : public BaseRenderingTestCase
{
public:
								DiscardTestCase					(tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, deBool queryFragmentShaderInvocations, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
									: BaseRenderingTestCase				(context, name, description, sampleCount)
									, m_primitiveTopology				(primitiveTopology)
									, m_queryFragmentShaderInvocations	(queryFragmentShaderInvocations)
								{}

	virtual TestInstance*		createInstance		(Context& context) const
								{
									return new DiscardTestInstance (context, m_primitiveTopology, m_queryFragmentShaderInvocations);
								}

	virtual	void				checkSupport		(Context& context) const
								{
									if (m_queryFragmentShaderInvocations)
										context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY);

#ifndef CTS_USES_VULKANSC
									if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
											context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
											!context.getPortabilitySubsetFeatures().triangleFans)
										TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
#endif // CTS_USES_VULKANSC
								}

protected:
	const VkPrimitiveTopology	m_primitiveTopology;
	const deBool				m_queryFragmentShaderInvocations;
};

class TriangleInterpolationTestInstance : public BaseRenderingTestInstance
{
public:

								TriangleInterpolationTestInstance	(Context& context, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount)
									: BaseRenderingTestInstance	(context, sampleCount, RESOLUTION_POT)
									, m_primitiveTopology		(primitiveTopology)
									, m_projective				((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
									, m_iterationCount			(3)
									, m_iteration				(0)
									, m_allIterationsPassed		(true)
									, m_flatshade				((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
								{}

	tcu::TestStatus				iterate								(void);


private:
	void						generateVertices					(int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
	void						extractTriangles					(std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;


	VkPrimitiveTopology			m_primitiveTopology;
	const bool					m_projective;
	const int					m_iterationCount;
	int							m_iteration;
	bool						m_allIterationsPassed;
	const deBool				m_flatshade;
};

tcu::TestStatus TriangleInterpolationTestInstance::iterate (void)
{
	const std::string								iterationDescription	= "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
	const tcu::ScopedLogSection						section					(m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
	tcu::Surface									resultImage				(m_renderSize, m_renderSize);
	std::vector<tcu::Vec4>							drawBuffer;
	std::vector<tcu::Vec4>							colorBuffer;
	std::vector<TriangleSceneSpec::SceneTriangle>	triangles;

	// generate scene
	generateVertices(m_iteration, drawBuffer, colorBuffer);
	extractTriangles(triangles, drawBuffer, colorBuffer);

	// log
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
		for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
	}

	// draw image
	drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);

	// compare
	{
		RasterizationArguments	args;
		TriangleSceneSpec		scene;
		tcu::IVec4				colorBits	= tcu::getTextureFormatBitDepth(getTextureFormat());

		args.numSamples		= m_multisampling ? 1 : 0;
		args.subpixelBits	= m_subpixelBits;
		args.redBits		= colorBits[0];
		args.greenBits		= colorBits[1];
		args.blueBits		= colorBits[2];

		scene.triangles.swap(triangles);

		if (!verifyTriangleGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog()))
			m_allIterationsPassed = false;
	}

	// result
	if (++m_iteration == m_iterationCount)
	{
		if (m_allIterationsPassed)
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Found invalid pixel values");
	}
	else
		return tcu::TestStatus::incomplete();
}

void TriangleInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
{
	// use only red, green and blue
	const tcu::Vec4 colors[] =
	{
		tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
		tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
		tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
	};

	de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);

	outVertices.resize(6);
	outColors.resize(6);

	for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
	{
		outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
		outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
		outVertices[vtxNdx].z() = 0.0f;

		if (!m_projective)
			outVertices[vtxNdx].w() = 1.0f;
		else
		{
			const float w = rnd.getFloat(0.2f, 4.0f);

			outVertices[vtxNdx].x() *= w;
			outVertices[vtxNdx].y() *= w;
			outVertices[vtxNdx].z() *= w;
			outVertices[vtxNdx].w() = w;
		}

		outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
	}
}

void TriangleInterpolationTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
{
	switch (m_primitiveTopology)
	{
		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
		{
			for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
			{
				TriangleSceneSpec::SceneTriangle tri;
				tri.positions[0]	= vertices[vtxNdx + 0];
				tri.positions[1]	= vertices[vtxNdx + 1];
				tri.positions[2]	= vertices[vtxNdx + 2];
				tri.sharedEdge[0]	= false;
				tri.sharedEdge[1]	= false;
				tri.sharedEdge[2]	= false;

				if (m_flatshade)
				{
					tri.colors[0] = colors[vtxNdx];
					tri.colors[1] = colors[vtxNdx];
					tri.colors[2] = colors[vtxNdx];
				}
				else
				{
					tri.colors[0] = colors[vtxNdx + 0];
					tri.colors[1] = colors[vtxNdx + 1];
					tri.colors[2] = colors[vtxNdx + 2];
				}

				outTriangles.push_back(tri);
			}
			break;
		}

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
		{
			for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
			{
				TriangleSceneSpec::SceneTriangle tri;
				tri.positions[0]	= vertices[vtxNdx + 0];
				tri.positions[1]	= vertices[vtxNdx + 1];
				tri.positions[2]	= vertices[vtxNdx + 2];
				tri.sharedEdge[0]	= false;
				tri.sharedEdge[1]	= false;
				tri.sharedEdge[2]	= false;

				if (m_flatshade)
				{
					tri.colors[0] = colors[vtxNdx];
					tri.colors[1] = colors[vtxNdx];
					tri.colors[2] = colors[vtxNdx];
				}
				else
				{
					tri.colors[0] = colors[vtxNdx + 0];
					tri.colors[1] = colors[vtxNdx + 1];
					tri.colors[2] = colors[vtxNdx + 2];
				}

				outTriangles.push_back(tri);
			}
			break;
		}

		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
		{
			for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
			{
				TriangleSceneSpec::SceneTriangle tri;
				tri.positions[0]	= vertices[0];
				tri.positions[1]	= vertices[vtxNdx + 0];
				tri.positions[2]	= vertices[vtxNdx + 1];
				tri.sharedEdge[0]	= false;
				tri.sharedEdge[1]	= false;
				tri.sharedEdge[2]	= false;

				if (m_flatshade)
				{
					tri.colors[0] = colors[vtxNdx];
					tri.colors[1] = colors[vtxNdx];
					tri.colors[2] = colors[vtxNdx];
				}
				else
				{
					tri.colors[0] = colors[0];
					tri.colors[1] = colors[vtxNdx + 0];
					tri.colors[2] = colors[vtxNdx + 1];
				}

				outTriangles.push_back(tri);
			}
			break;
		}

		default:
			DE_ASSERT(false);
	}
}

class TriangleInterpolationTestCase : public BaseRenderingTestCase
{
public:
								TriangleInterpolationTestCase	(tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
									: BaseRenderingTestCase		(context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
									, m_primitiveTopology		(primitiveTopology)
									, m_flags					(flags)
								{}

	virtual TestInstance*		createInstance					(Context& context) const
								{
									return new TriangleInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_sampleCount);
								}

	virtual	void				checkSupport		(Context& context) const
								{
#ifndef CTS_USES_VULKANSC
									if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
										context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
										!context.getPortabilitySubsetFeatures().triangleFans)
									{
										TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
									}
#else
	DE_UNREF(context);
#endif // CTS_USES_VULKANSC
								}
protected:
	const VkPrimitiveTopology	m_primitiveTopology;
	const int					m_flags;
};

class LineInterpolationTestInstance : public BaseRenderingTestInstance
{
public:
							LineInterpolationTestInstance	(Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount);

	virtual tcu::TestStatus	iterate							(void);

private:
	void					generateVertices				(int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
	void					extractLines					(std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
	virtual float			getLineWidth					(void) const;

	VkPrimitiveTopology		m_primitiveTopology;
	const bool				m_projective;
	const int				m_iterationCount;
	const PrimitiveWideness	m_primitiveWideness;

	int						m_iteration;
	bool					m_allIterationsPassed;
	float					m_maxLineWidth;
	std::vector<float>		m_lineWidths;
	bool					m_flatshade;
	PrimitiveStrictness		m_strictness;
};

LineInterpolationTestInstance::LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount)
	: BaseRenderingTestInstance			(context, sampleCount)
	, m_primitiveTopology				(primitiveTopology)
	, m_projective						((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
	, m_iterationCount					(3)
	, m_primitiveWideness				(wideness)
	, m_iteration						(0)
	, m_allIterationsPassed				(true)
	, m_maxLineWidth					(1.0f)
	, m_flatshade						((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
	, m_strictness						(strictness)
{
	DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);

	// create line widths
	if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
	{
		m_lineWidths.resize(m_iterationCount, 1.0f);
	}
	else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
	{
		const float*	range = context.getDeviceProperties().limits.lineWidthRange;

		m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;

		DE_ASSERT(range[1] > 1.0f);

		// set hand picked sizes
		m_lineWidths.push_back(5.0f);
		m_lineWidths.push_back(10.0f);
		m_lineWidths.push_back(range[1]);
		DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);

		m_maxLineWidth = range[1];
	}
	else
		DE_ASSERT(false);
}

tcu::TestStatus LineInterpolationTestInstance::iterate (void)
{
	const std::string						iterationDescription	= "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
	const tcu::ScopedLogSection				section					(m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
	const float								lineWidth				= getLineWidth();
	tcu::Surface							resultImage				(m_renderSize, m_renderSize);
	std::vector<tcu::Vec4>					drawBuffer;
	std::vector<tcu::Vec4>					colorBuffer;
	std::vector<LineSceneSpec::SceneLine>	lines;

	// supported?
	if (lineWidth <= m_maxLineWidth)
	{
		// generate scene
		generateVertices(m_iteration, drawBuffer, colorBuffer);
		extractLines(lines, drawBuffer, colorBuffer);

		// log
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
			for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
				m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
		}

		// draw image
		drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);

		// compare
		{
			RasterizationArguments	args;
			LineSceneSpec			scene;

			tcu::IVec4				colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());

			args.numSamples		= m_multisampling ? 1 : 0;
			args.subpixelBits	= m_subpixelBits;
			args.redBits		= colorBits[0];
			args.greenBits		= colorBits[1];
			args.blueBits		= colorBits[2];

			scene.lines.swap(lines);
			scene.lineWidth = getLineWidth();

			switch (m_strictness)
			{
				case PRIMITIVESTRICTNESS_STRICT:
				{
					if (!verifyTriangulatedLineGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog(), true))
						m_allIterationsPassed = false;

					break;
				}

				case PRIMITIVESTRICTNESS_NONSTRICT:
				case PRIMITIVESTRICTNESS_IGNORE:
				{
					if (!verifyTriangulatedLineGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog(), false, true))
						m_allIterationsPassed = false;

					break;
				}

				default:
					TCU_THROW(InternalError, "Not implemented");
			}
		}
	}
	else
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;

	// result
	if (++m_iteration == m_iterationCount)
	{
		if (m_allIterationsPassed)
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Incorrect rasterization");
	}
	else
		return tcu::TestStatus::incomplete();
}

void LineInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
{
	// use only red, green and blue
	const tcu::Vec4 colors[] =
	{
		tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
		tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
		tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
	};

	de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);

	outVertices.resize(6);
	outColors.resize(6);

	for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
	{
		outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
		outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
		outVertices[vtxNdx].z() = 0.0f;

		if (!m_projective)
			outVertices[vtxNdx].w() = 1.0f;
		else
		{
			const float w = rnd.getFloat(0.2f, 4.0f);

			outVertices[vtxNdx].x() *= w;
			outVertices[vtxNdx].y() *= w;
			outVertices[vtxNdx].z() *= w;
			outVertices[vtxNdx].w() = w;
		}

		outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
	}
}

void LineInterpolationTestInstance::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
{
	switch (m_primitiveTopology)
	{
		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
		{
			for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
			{
				LineSceneSpec::SceneLine line;
				line.positions[0] = vertices[vtxNdx + 0];
				line.positions[1] = vertices[vtxNdx + 1];

				if (m_flatshade)
				{
					line.colors[0] = colors[vtxNdx];
					line.colors[1] = colors[vtxNdx];
				}
				else
				{
					line.colors[0] = colors[vtxNdx + 0];
					line.colors[1] = colors[vtxNdx + 1];
				}

				outLines.push_back(line);
			}
			break;
		}

		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
		{
			for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
			{
				LineSceneSpec::SceneLine line;
				line.positions[0] = vertices[vtxNdx + 0];
				line.positions[1] = vertices[vtxNdx + 1];

				if (m_flatshade)
				{
					line.colors[0] = colors[vtxNdx];
					line.colors[1] = colors[vtxNdx];
				}
				else
				{
					line.colors[0] = colors[vtxNdx + 0];
					line.colors[1] = colors[vtxNdx + 1];
				}

				outLines.push_back(line);
			}
			break;
		}

		default:
			DE_ASSERT(false);
	}
}

float LineInterpolationTestInstance::getLineWidth (void) const
{
	return m_lineWidths[m_iteration];
}

class LineInterpolationTestCase : public BaseRenderingTestCase
{
public:
								LineInterpolationTestCase		(tcu::TestContext&		context,
																 const std::string&		name,
																 const std::string&		description,
																 VkPrimitiveTopology	primitiveTopology,
																 int					flags,
																 PrimitiveWideness		wideness,
																 PrimitiveStrictness	strictness,
																 VkSampleCountFlagBits	sampleCount = VK_SAMPLE_COUNT_1_BIT)
									: BaseRenderingTestCase		(context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
									, m_primitiveTopology		(primitiveTopology)
									, m_flags					(flags)
									, m_wideness				(wideness)
									, m_strictness				(strictness)
								{}

	virtual TestInstance*		createInstance					(Context& context) const
								{
									return new LineInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_wideness, m_strictness, m_sampleCount);
								}

	virtual	void				checkSupport		(Context& context) const
								{
									if (m_strictness == PRIMITIVESTRICTNESS_STRICT &&
										!context.getDeviceProperties().limits.strictLines)
										TCU_THROW(NotSupportedError, "Strict rasterization is not supported");

									if (m_wideness == PRIMITIVEWIDENESS_WIDE)
										context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
								}
protected:
	const VkPrimitiveTopology	m_primitiveTopology;
	const int					m_flags;
	const PrimitiveWideness		m_wideness;
	const PrimitiveStrictness	m_strictness;
};

class StrideZeroCase : public vkt::TestCase
{
public:
	struct Params
	{
		std::vector<tcu::Vec2>	bufferData;
		deUint32				drawVertexCount;
	};

							StrideZeroCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const Params& params)
								: vkt::TestCase	(testCtx, name, description)
								, m_params		(params)
								{}

	virtual					~StrideZeroCase		(void) {}

	virtual void			initPrograms		(vk::SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance		(Context& context) const;
	virtual void			checkSupport		(Context& context) const;

	static constexpr vk::VkFormat				kColorFormat	= vk::VK_FORMAT_R8G8B8A8_UNORM;
	static constexpr vk::VkFormatFeatureFlags	kColorFeatures	= (vk::VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | vk::VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
	static constexpr vk::VkImageUsageFlags		kColorUsage		= (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);

	//	(-1,-1)
	//		+-----+-----+
	//		|     |     |
	//		|  a  |  b  |	a = (-0.5, -0.5)
	//		|     |     |	b = ( 0.5, -0.5)
	//		+-----------+	c = (-0.5,  0.5)
	//		|     |     |	d = ( 0.5,  0.5)
	//		|  c  |  d  |
	//		|     |     |
	//		+-----+-----+
	//					(1,1)
	static constexpr deUint32					kImageDim		= 2u;
	static const float							kCornerDelta;	// 0.5f;

	static const tcu::Vec4						kClearColor;
	static const tcu::Vec4						kDrawColor;

private:
	Params m_params;
};

const float		StrideZeroCase::kCornerDelta	= 0.5f;
const tcu::Vec4	StrideZeroCase::kClearColor		(0.0f, 0.0f, 0.0f, 1.0f);
const tcu::Vec4	StrideZeroCase::kDrawColor		(1.0f, 1.0f, 1.0f, 1.0f);

class StrideZeroInstance : public vkt::TestInstance
{
public:
								StrideZeroInstance	(Context& context, const StrideZeroCase::Params& params)
									: vkt::TestInstance	(context)
									, m_params			(params)
									{}

	virtual						~StrideZeroInstance	(void) {}

	virtual tcu::TestStatus		iterate				(void);

private:
	StrideZeroCase::Params m_params;
};

void StrideZeroCase::initPrograms (vk::SourceCollections& programCollection) const
{
	std::ostringstream vert;
	std::ostringstream frag;

	std::ostringstream drawColor;
	drawColor
		<< std::setprecision(2) << std::fixed
		<< "vec4(" << kDrawColor.x() << ", " << kDrawColor.y() << ", " << kDrawColor.z() << ", " << kDrawColor.w() << ")";

	vert
		<< "#version 450\n"
		<< "layout (location=0) in vec2 inPos;\n"
		<< "void main() {\n"
		<< "    gl_Position = vec4(inPos, 0.0, 1.0);\n"
		<< "    gl_PointSize = 1.0;\n"
		<< "}\n"
		;

	frag
		<< "#version 450\n"
		<< "layout (location=0) out vec4 outColor;\n"
		<< "void main() {\n"
		<< "    outColor = " << drawColor.str() << ";\n"
		<< "}\n"
		;

	programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
	programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
}

TestInstance* StrideZeroCase::createInstance (Context& context) const
{
	return new StrideZeroInstance(context, m_params);
}

void StrideZeroCase::checkSupport (Context& context) const
{
	const auto properties = vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), kColorFormat);
	if ((properties.optimalTilingFeatures & kColorFeatures) != kColorFeatures)
		TCU_THROW(NotSupportedError, "Required image format not supported");
}

// Creates a vertex buffer with the given data but uses zero as the binding stride.
// Then, tries to draw the requested number of points. Only the first point should ever be used.
tcu::TestStatus StrideZeroInstance::iterate (void)
{
	const auto&		vkd			= m_context.getDeviceInterface();
	const auto		device		= m_context.getDevice();
	auto&			alloc		= m_context.getDefaultAllocator();
	const auto		queue		= m_context.getUniversalQueue();
	const auto		queueIndex	= m_context.getUniversalQueueFamilyIndex();
	constexpr auto	kImageDim	= StrideZeroCase::kImageDim;
	const auto		colorExtent	= vk::makeExtent3D(kImageDim, kImageDim, 1u);

	// Prepare vertex buffer.
	const auto					vertexBufferSize	= static_cast<vk::VkDeviceSize>(m_params.bufferData.size() * sizeof(decltype(m_params.bufferData)::value_type));
	const auto					vertexBufferInfo	= vk::makeBufferCreateInfo(vertexBufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
	const vk::BufferWithMemory	vertexBuffer(		vkd, device, alloc, vertexBufferInfo, vk::MemoryRequirement::HostVisible);
	auto&						vertexBufferAlloc	= vertexBuffer.getAllocation();
	const vk::VkDeviceSize		vertexBufferOffset	= 0ull;
	deMemcpy(vertexBufferAlloc.getHostPtr(), m_params.bufferData.data(), static_cast<size_t>(vertexBufferSize));
	flushAlloc(vkd, device, vertexBufferAlloc);

	// Prepare render image.
	const vk::VkImageCreateInfo colorAttachmentInfo =
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
		nullptr,									//	const void*				pNext;
		0u,											//	VkImageCreateFlags		flags;
		vk::VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
		StrideZeroCase::kColorFormat,				//	VkFormat				format;
		colorExtent,								//	VkExtent3D				extent;
		1u,											//	deUint32				mipLevels;
		1u,											//	deUint32				arrayLayers;
		vk::VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
		vk::VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
		StrideZeroCase::kColorUsage,				//	VkImageUsageFlags		usage;
		vk::VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
		1u,											//	deUint32				queueFamilyIndexCount;
		&queueIndex,								//	const deUint32*			pQueueFamilyIndices;
		vk::VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
	};
	const vk::ImageWithMemory colorAttachment(vkd, device, alloc, colorAttachmentInfo, vk::MemoryRequirement::Any);

	const auto colorSubresourceRange	= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const auto colorAttachmentView		= vk::makeImageView(vkd, device, colorAttachment.get(), vk::VK_IMAGE_VIEW_TYPE_2D, StrideZeroCase::kColorFormat, colorSubresourceRange);

	const vk::VkVertexInputBindingDescription vertexBinding =
	{
		0u,									//	deUint32			binding;
		0u,									//	deUint32			stride;		[IMPORTANT]
		vk::VK_VERTEX_INPUT_RATE_VERTEX,	//	VkVertexInputRate	inputRate;
	};

	const vk::VkVertexInputAttributeDescription vertexAttribute =
	{
		0u,								//	deUint32	location;
		0u,								//	deUint32	binding;
		vk::VK_FORMAT_R32G32_SFLOAT,	//	VkFormat	format;
		0u,								//	deUint32	offset;
	};

	const vk::VkPipelineVertexInputStateCreateInfo vertexInput =
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	//	VkStructureType								sType;
		nullptr,														//	const void*									pNext;
		0u,																//	VkPipelineVertexInputStateCreateFlags		flags;
		1u,																//	deUint32									vertexBindingDescriptionCount;
		&vertexBinding,													//	const VkVertexInputBindingDescription*		pVertexBindingDescriptions;
		1u,																//	deUint32									vertexAttributeDescriptionCount;
		&vertexAttribute,												//	const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
	};

	const auto renderArea		= vk::makeRect2D(kImageDim, kImageDim);
	const auto viewports		= std::vector<vk::VkViewport>(1, vk::makeViewport(kImageDim, kImageDim));
	const auto scissors			= std::vector<vk::VkRect2D>(1, renderArea);
	const auto pipelineLayout	= vk::makePipelineLayout(vkd, device);
	const auto vertexShader		= vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
	const auto fragmentShader	= vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
	const auto renderPass		= vk::makeRenderPass(vkd, device, StrideZeroCase::kColorFormat);
	const auto graphicsPipeline	= vk::makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
		vertexShader.get(), DE_NULL, DE_NULL, DE_NULL, fragmentShader.get(),					// Shaders.
		renderPass.get(), viewports, scissors, vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0u, 0u,	// Render pass, viewports, scissors, topology.
		&vertexInput);																			// Vertex input state.
	const auto framebuffer		= vk::makeFramebuffer(vkd, device, renderPass.get(), colorAttachmentView.get(), kImageDim, kImageDim);

	const auto cmdPool		= vk::makeCommandPool(vkd, device, queueIndex);
	const auto cmdBufferPtr	= vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	const auto cmdBuffer	= cmdBufferPtr.get();

	// Buffer used to verify results.
	const auto					tcuFormat			= vk::mapVkFormat(StrideZeroCase::kColorFormat);
	const auto					colorBufferSize		= static_cast<vk::VkDeviceSize>(tcu::getPixelSize(tcuFormat)) * kImageDim * kImageDim;
	const auto					colorBufferInfo		= vk::makeBufferCreateInfo(colorBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	const vk::BufferWithMemory	colorBuffer			(vkd, device, alloc, colorBufferInfo, vk::MemoryRequirement::HostVisible);
	auto&						colorBufferAlloc	= colorBuffer.getAllocation();
	void*						colorBufferPtr		= colorBufferAlloc.getHostPtr();
	const auto					colorLayers			= vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
	const auto					copyRegion			= vk::makeBufferImageCopy(colorExtent, colorLayers);

	// Barriers from attachment to buffer and buffer to host.
	const auto colorAttachmentBarrier	= vk::makeImageMemoryBarrier	(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, colorAttachment.get(), colorSubresourceRange);
	const auto colorBufferBarrier		= vk::makeBufferMemoryBarrier	(vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, colorBuffer.get(), 0ull, colorBufferSize);

	vk::beginCommandBuffer(vkd, cmdBuffer);
	vk::beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), renderArea, StrideZeroCase::kClearColor);
	vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
	vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
	vkd.cmdDraw(cmdBuffer, m_params.drawVertexCount, 1u, 0u, 0u);
	vk::endRenderPass(vkd, cmdBuffer);
	vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &colorAttachmentBarrier);
	vkd.cmdCopyImageToBuffer(cmdBuffer, colorAttachment.get(), vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, colorBuffer.get(), 1u, &copyRegion);
	vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &colorBufferBarrier, 0u, nullptr);
	vk::endCommandBuffer(vkd, cmdBuffer);

	vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);

	// Invalidate color buffer alloc.
	vk::invalidateAlloc(vkd, device, colorBufferAlloc);

	// Check buffer.
	const int							imageDimI	= static_cast<int>(kImageDim);
	const tcu::ConstPixelBufferAccess	colorPixels	(tcuFormat, imageDimI, imageDimI, 1, colorBufferPtr);
	tcu::TestStatus						testStatus	= tcu::TestStatus::pass("Pass");
	auto&								log			= m_context.getTestContext().getLog();

	for (int x = 0; x < imageDimI; ++x)
	for (int y = 0; y < imageDimI; ++y)
	{
		// Only the top-left corner should have draw data.
		const auto expectedColor	= ((x == 0 && y == 0) ? StrideZeroCase::kDrawColor : StrideZeroCase::kClearColor);
		const auto imageColor		= colorPixels.getPixel(x, y);

		if (expectedColor != imageColor)
		{
			log
				<< tcu::TestLog::Message
				<< "Unexpected color found in pixel (" << x << ", " << y << "): "
				<< "expected (" << expectedColor.x() << ", " << expectedColor.y() << ", " << expectedColor.z() << ", " << expectedColor.w() << ") "
				<< "and found (" << imageColor.x() << ", " << imageColor.y() << ", " << imageColor.z() << ", " << imageColor.w() << ")"
				<< tcu::TestLog::EndMessage;

			testStatus = tcu::TestStatus::fail("Failed; Check log for details");
		}
	}

	return testStatus;
}

void createRasterizationTests (tcu::TestCaseGroup* rasterizationTests)
{
	tcu::TestContext&	testCtx		=	rasterizationTests->getTestContext();

	const struct
	{
		LineStippleFactorCase	stippleFactor;
		const std::string		nameSuffix;
		const std::string		descSuffix;
	} stippleFactorCases[] =
	{
		{ LineStippleFactorCase::DEFAULT,	"",					""														},
		{ LineStippleFactorCase::ZERO,		"_factor_0",		" and use zero as the line stipple factor"				},
		{ LineStippleFactorCase::LARGE,		"_factor_large",	" and use a large number as the line stipple factor"	},
	};

	// .primitives
	{
		tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, "primitives", "Primitive rasterization");

		rasterizationTests->addChild(primitives);

		tcu::TestCaseGroup* const nostippleTests = new tcu::TestCaseGroup(testCtx, "no_stipple", "No stipple");
		tcu::TestCaseGroup* const stippleStaticTests = new tcu::TestCaseGroup(testCtx, "static_stipple", "Line stipple static");
		tcu::TestCaseGroup* const stippleDynamicTests = new tcu::TestCaseGroup(testCtx, "dynamic_stipple", "Line stipple dynamic");
		tcu::TestCaseGroup* const strideZeroTests = new tcu::TestCaseGroup(testCtx, "stride_zero", "Test input assembly with stride zero");

		primitives->addChild(nostippleTests);
		primitives->addChild(stippleStaticTests);
		primitives->addChild(stippleDynamicTests);
		primitives->addChild(strideZeroTests);

		// .stride_zero
		{
			{
				StrideZeroCase::Params params;
				params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
				params.drawVertexCount = 1u;
				strideZeroTests->addChild(new StrideZeroCase(testCtx, "single_point", "Attempt to draw 1 point with stride 0", params));
			}
			{
				StrideZeroCase::Params params;
				params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
				params.bufferData.emplace_back( StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
				params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta,  StrideZeroCase::kCornerDelta);
				params.bufferData.emplace_back( StrideZeroCase::kCornerDelta,  StrideZeroCase::kCornerDelta);
				params.drawVertexCount = static_cast<deUint32>(params.bufferData.size());
				strideZeroTests->addChild(new StrideZeroCase(testCtx, "four_points", "Attempt to draw 4 points with stride 0 and 4 points in the buffer", params));
			}
			{
				StrideZeroCase::Params params;
				params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
				params.drawVertexCount = 100000u;
				strideZeroTests->addChild(new StrideZeroCase(testCtx, "many_points", "Attempt to draw many points with stride 0 with one point in the buffer", params));
			}
		}

		nostippleTests->addChild(new BaseTestCase<TrianglesTestInstance>		(testCtx, "triangles",			"Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result"));
		nostippleTests->addChild(new BaseTestCase<TriangleStripTestInstance>	(testCtx, "triangle_strip",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, verify rasterization result"));
		nostippleTests->addChild(new BaseTestCase<TriangleFanTestInstance>		(testCtx, "triangle_fan",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, verify rasterization result"));
		nostippleTests->addChild(new WidenessTestCase<PointTestInstance>		(testCtx, "points",				"Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result",					PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, false, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));

		nostippleTests->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "strict_lines",			"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in strict mode, verify rasterization result",						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_STRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
		nostippleTests->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "strict_line_strip",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP in strict mode, verify rasterization result",					PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_STRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
		nostippleTests->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "strict_lines_wide",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in strict mode with wide lines, verify rasterization result",		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_STRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
		nostippleTests->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "strict_line_strip_wide",	"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP in strict mode with wide lines, verify rasterization result",	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_STRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));

		nostippleTests->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "non_strict_lines",			"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in nonstrict mode, verify rasterization result",					PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_NONSTRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
		nostippleTests->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "non_strict_line_strip",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP in nonstrict mode, verify rasterization result",					PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_NONSTRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
		nostippleTests->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "non_strict_lines_wide",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in nonstrict mode with wide lines, verify rasterization result",	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_NONSTRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
		nostippleTests->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "non_strict_line_strip_wide",	"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP in nonstrict mode with wide lines, verify rasterization result",	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_NONSTRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));

		for (int i = 0; i < 3; ++i) {

			tcu::TestCaseGroup *g = i == 2 ? stippleDynamicTests : i == 1 ? stippleStaticTests : nostippleTests;

			LineStipple stipple = (LineStipple)i;

			for (const auto& sfCase : stippleFactorCases)
			{
				if (sfCase.stippleFactor != LineStippleFactorCase::DEFAULT && stipple != LINESTIPPLE_DISABLED)
					continue;

				const auto& factor		= sfCase.stippleFactor;
				const auto& suffix		= sfCase.nameSuffix;
				const auto& descSuffix	= sfCase.descSuffix;

				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "lines" + suffix,							"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result" + descSuffix,						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, factor, i == 0 ? RESOLUTION_NPOT : 0));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "line_strip" + suffix,					"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result" + descSuffix,						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, factor));
				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "lines_wide" + suffix,					"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result" + descSuffix,		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, factor));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "line_strip_wide" + suffix,				"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result" + descSuffix,		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, factor));

				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "rectangular_lines" + suffix,				"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result" + descSuffix,						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, factor));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "rectangular_line_strip" + suffix,		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result" + descSuffix,						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, factor));
				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "rectangular_lines_wide" + suffix,		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result" + descSuffix,		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, factor));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "rectangular_line_strip_wide" + suffix,	"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result" + descSuffix,		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, factor));

				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "bresenham_lines" + suffix,				"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result" + descSuffix,						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, factor));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "bresenham_line_strip" + suffix,			"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result" + descSuffix,						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, factor));
				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "bresenham_lines_wide" + suffix,			"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result" + descSuffix,		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, factor));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "bresenham_line_strip_wide" + suffix,		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result" + descSuffix,		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, factor));

				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "smooth_lines" + suffix,					"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result" + descSuffix,						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, factor));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "smooth_line_strip" + suffix,				"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result" + descSuffix,						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, factor));
				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "smooth_lines_wide" + suffix,				"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result" + descSuffix,		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, factor));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "smooth_line_strip_wide" + suffix,		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result" + descSuffix,		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, factor));
			}
		}
	}

	// .primitive_size
	{
		tcu::TestCaseGroup* const primitiveSize = new tcu::TestCaseGroup(testCtx, "primitive_size", "Primitive size");
		rasterizationTests->addChild(primitiveSize);

		// .points
		{
			tcu::TestCaseGroup* const points = new tcu::TestCaseGroup(testCtx, "points", "Point size");

			static const struct TestCombinations
			{
				const deUint32	renderSize;
				const float		pointSize;
			} testCombinations[] =
			{
				{ 1024,		128.0f		},
				{ 1024,		256.0f		},
				{ 1024,		512.0f		},
				{ 2048,		1024.0f		},
				{ 4096,		2048.0f		},
				{ 8192,		4096.0f		},
				{ 9216,		8192.0f		},
				{ 10240,	10000.0f	}
			};

			for (size_t testCombNdx = 0; testCombNdx < DE_LENGTH_OF_ARRAY(testCombinations); testCombNdx++)
			{
				std::string	testCaseName	= "point_size_" + de::toString(testCombinations[testCombNdx].pointSize);
				deUint32	renderSize		= testCombinations[testCombNdx].renderSize;
				float		pointSize		= testCombinations[testCombNdx].pointSize;

				points->addChild(new PointSizeTestCase<PointSizeTestInstance>	(testCtx, testCaseName,	testCaseName, renderSize, pointSize));
			}

			primitiveSize->addChild(points);
		}
	}

	// .fill_rules
	{
		tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, "fill_rules", "Primitive fill rules");

		rasterizationTests->addChild(fillRules);

		fillRules->addChild(new FillRuleTestCase(testCtx,	"basic_quad",			"Verify fill rules",	FillRuleTestInstance::FILLRULECASE_BASIC));
		fillRules->addChild(new FillRuleTestCase(testCtx,	"basic_quad_reverse",	"Verify fill rules",	FillRuleTestInstance::FILLRULECASE_REVERSED));
		fillRules->addChild(new FillRuleTestCase(testCtx,	"clipped_full",			"Verify fill rules",	FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL));
		fillRules->addChild(new FillRuleTestCase(testCtx,	"clipped_partly",		"Verify fill rules",	FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL));
		fillRules->addChild(new FillRuleTestCase(testCtx,	"projected",			"Verify fill rules",	FillRuleTestInstance::FILLRULECASE_PROJECTED));
	}

	// .culling
	{
		static const struct CullMode
		{
			VkCullModeFlags	mode;
			const char*		prefix;
		} cullModes[] =
		{
			{ VK_CULL_MODE_FRONT_BIT,				"front_"	},
			{ VK_CULL_MODE_BACK_BIT,				"back_"		},
			{ VK_CULL_MODE_FRONT_AND_BACK,			"both_"		},
		};
		static const struct PrimitiveType
		{
			VkPrimitiveTopology	type;
			const char*			name;
		} primitiveTypes[] =
		{
			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,			"triangles"			},
			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,			"triangle_strip"	},
			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,			"triangle_fan"		},
		};
		static const struct FrontFaceOrder
		{
			VkFrontFace	mode;
			const char*	postfix;
		} frontOrders[] =
		{
			{ VK_FRONT_FACE_COUNTER_CLOCKWISE,	""			},
			{ VK_FRONT_FACE_CLOCKWISE,			"_reverse"	},
		};

		static const struct PolygonMode
		{
			VkPolygonMode	mode;
			const char*		name;
		} polygonModes[] =
		{
			{ VK_POLYGON_MODE_FILL,		""		},
			{ VK_POLYGON_MODE_LINE,		"_line"		},
			{ VK_POLYGON_MODE_POINT,	"_point"	}
		};

		tcu::TestCaseGroup* const culling = new tcu::TestCaseGroup(testCtx, "culling", "Culling");

		rasterizationTests->addChild(culling);

		for (int cullModeNdx	= 0; cullModeNdx	< DE_LENGTH_OF_ARRAY(cullModes);		++cullModeNdx)
		for (int primitiveNdx	= 0; primitiveNdx	< DE_LENGTH_OF_ARRAY(primitiveTypes);	++primitiveNdx)
		for (int frontOrderNdx	= 0; frontOrderNdx	< DE_LENGTH_OF_ARRAY(frontOrders);		++frontOrderNdx)
		for (int polygonModeNdx = 0; polygonModeNdx	< DE_LENGTH_OF_ARRAY(polygonModes);		++polygonModeNdx)
		{
			if (!(cullModes[cullModeNdx].mode == VK_CULL_MODE_FRONT_AND_BACK && polygonModes[polygonModeNdx].mode != VK_POLYGON_MODE_FILL))
			{
				const std::string name = std::string(cullModes[cullModeNdx].prefix) + primitiveTypes[primitiveNdx].name + frontOrders[frontOrderNdx].postfix + polygonModes[polygonModeNdx].name;
				culling->addChild(new CullingTestCase(testCtx, name, "Test primitive culling.", cullModes[cullModeNdx].mode, primitiveTypes[primitiveNdx].type, frontOrders[frontOrderNdx].mode, polygonModes[polygonModeNdx].mode));
			}
		}
	}

	// .discard
	{
		static const struct PrimitiveType
		{
			VkPrimitiveTopology	type;
			const char*			name;
		} primitiveTypes[] =
		{
			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	"triangle_list"		},
			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	"triangle_strip"	},
			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,	"triangle_fan"		},
			{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		"line_list"			},
			{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		"line_strip"		},
			{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,		"point_list"		}
		};

		static const struct queryPipeline
		{
			deBool			useQuery;
			const char*		name;
		} queryPipeline[] =
		{
			{ DE_FALSE,	"query_pipeline_false"	},
			{ DE_TRUE,	"query_pipeline_true"	},
		};

		tcu::TestCaseGroup* const discard = new tcu::TestCaseGroup(testCtx, "discard", "Rasterizer discard");

		for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx)
		{
			tcu::TestCaseGroup* const primitive = new tcu::TestCaseGroup(testCtx, primitiveTypes[primitiveNdx].name, "Rasterizer discard");

			for (int useQueryNdx = 0; useQueryNdx < DE_LENGTH_OF_ARRAY(queryPipeline); useQueryNdx++)
			{
				const std::string name = std::string(queryPipeline[useQueryNdx].name);

				primitive->addChild(new DiscardTestCase(testCtx, name, "Test primitive discarding.", primitiveTypes[primitiveNdx].type, queryPipeline[useQueryNdx].useQuery));
			}

			discard->addChild(primitive);
		}

		rasterizationTests->addChild(discard);
	}

	// .conservative
	{
		typedef struct
		{
			float			size;
			const char*		name;
		} overestimateSizes;

		const overestimateSizes overestimateNormalSizes[]	=
		{
			{ 0.00f,			"0_00" },
			{ 0.25f,			"0_25" },
			{ 0.50f,			"0_50" },
			{ 0.75f,			"0_75" },
			{ 1.00f,			"1_00" },
			{ 2.00f,			"2_00" },
			{ 4.00f,			"4_00" },
			{ -TCU_INFINITY,	"min" },
			{ TCU_INFINITY,		"max" },
		};
		const overestimateSizes overestimateDegenerate[]	=
		{
			{ 0.00f,			"0_00" },
			{ 0.25f,			"0_25" },
			{ -TCU_INFINITY,	"min" },
			{ TCU_INFINITY,		"max" },
		};
		const overestimateSizes underestimateLineWidths[]	=
		{
			{ 0.50f,			"0_50" },
			{ 1.00f,			"1_00" },
			{ 1.50f,			"1_50" },
		};
		const overestimateSizes underestimatePointSizes[]	=
		{
			{ 1.00f,			"1_00" },
			{ 1.50f,			"1_50" },
			{ 2.00f,			"2_00" },
			{ 3.00f,			"3_00" },
			{ 4.00f,			"4_00" },
			{ 8.00f,			"8_00" },
		};
		const struct PrimitiveType
		{
			VkPrimitiveTopology	type;
			const char*			name;
		}
		primitiveTypes[] =
		{
			{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	"triangles"		},
			{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		"lines"			},
			{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,		"points"		}
		};
		const VkSampleCountFlagBits samples[] =
		{
			VK_SAMPLE_COUNT_1_BIT,
			VK_SAMPLE_COUNT_2_BIT,
			VK_SAMPLE_COUNT_4_BIT,
			VK_SAMPLE_COUNT_8_BIT,
			VK_SAMPLE_COUNT_16_BIT,
			VK_SAMPLE_COUNT_32_BIT,
			VK_SAMPLE_COUNT_64_BIT
		};

		tcu::TestCaseGroup* const conservative = new tcu::TestCaseGroup(testCtx, "conservative", "Conservative rasterization tests");

		rasterizationTests->addChild(conservative);

		{
			tcu::TestCaseGroup* const overestimate = new tcu::TestCaseGroup(testCtx, "overestimate", "Overestimate tests");

			conservative->addChild(overestimate);

			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); ++samplesNdx)
			{
				const std::string samplesGroupName = "samples_" + de::toString(samples[samplesNdx]);

				tcu::TestCaseGroup* const samplesGroup = new tcu::TestCaseGroup(testCtx, samplesGroupName.c_str(), "Samples tests");

				overestimate->addChild(samplesGroup);

				for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveTypeNdx)
				{
					tcu::TestCaseGroup* const primitiveGroup = new tcu::TestCaseGroup(testCtx, primitiveTypes[primitiveTypeNdx].name, "Primitive tests");

					samplesGroup->addChild(primitiveGroup);

					{
						tcu::TestCaseGroup* const normal = new tcu::TestCaseGroup(testCtx, "normal", "Normal conservative rasterization tests");

						primitiveGroup->addChild(normal);

						for (int overestimateSizesNdx = 0; overestimateSizesNdx < DE_LENGTH_OF_ARRAY(overestimateNormalSizes); ++overestimateSizesNdx)
						{
							const ConservativeTestConfig	config	=
							{
								VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT,	//  VkConservativeRasterizationModeEXT	conservativeRasterizationMode;
								overestimateNormalSizes[overestimateSizesNdx].size,		//  float								extraOverestimationSize;
								primitiveTypes[primitiveTypeNdx].type,					//  VkPrimitiveTopology					primitiveTopology;
								false,													//  bool								degeneratePrimitives;
								1.0f,													//  float								lineWidth;
								RESOLUTION_POT,											//  deUint32							resolution;
							};

							if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
								normal->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance>	(testCtx,
																											 overestimateNormalSizes[overestimateSizesNdx].name,
																											 "Overestimate test, verify rasterization result",
																											 config,
																											 samples[samplesNdx]));

							if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
								normal->addChild(new ConservativeTestCase<ConservativeLineTestInstance>		(testCtx,
																											 overestimateNormalSizes[overestimateSizesNdx].name,
																											 "Overestimate test, verify rasterization result",
																											 config,
																											 samples[samplesNdx]));

							if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
								normal->addChild(new ConservativeTestCase<ConservativePointTestInstance>	(testCtx,
																											 overestimateNormalSizes[overestimateSizesNdx].name,
																											 "Overestimate test, verify rasterization result",
																											 config,
																											 samples[samplesNdx]));
						}
					}

					{
						tcu::TestCaseGroup* const degenerate = new tcu::TestCaseGroup(testCtx, "degenerate", "Degenerate primitives conservative rasterization tests");

						primitiveGroup->addChild(degenerate);

						for (int overestimateSizesNdx = 0; overestimateSizesNdx < DE_LENGTH_OF_ARRAY(overestimateDegenerate); ++overestimateSizesNdx)
						{
							const ConservativeTestConfig	config	=
							{
								VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT,	//  VkConservativeRasterizationModeEXT	conservativeRasterizationMode;
								overestimateDegenerate[overestimateSizesNdx].size,		//  float								extraOverestimationSize;
								primitiveTypes[primitiveTypeNdx].type,					//  VkPrimitiveTopology					primitiveTopology;
								true,													//  bool								degeneratePrimitives;
								1.0f,													//  float								lineWidth;
								64u,													//  deUint32							resolution;
							};

							if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
								degenerate->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance>	(testCtx,
																												 overestimateDegenerate[overestimateSizesNdx].name,
																												 "Overestimate triangle test, verify rasterization result",
																												 config,
																												 samples[samplesNdx]));

							if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
								degenerate->addChild(new ConservativeTestCase<ConservativeLineTestInstance>		(testCtx,
																												 overestimateDegenerate[overestimateSizesNdx].name,
																												 "Overestimate line test, verify rasterization result",
																												 config,
																												 samples[samplesNdx]));
						}
					}
				}
			}
		}

		{
			tcu::TestCaseGroup* const underestimate = new tcu::TestCaseGroup(testCtx, "underestimate", "Underestimate tests");

			conservative->addChild(underestimate);

			for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); ++samplesNdx)
			{
				const std::string samplesGroupName = "samples_" + de::toString(samples[samplesNdx]);

				tcu::TestCaseGroup* const samplesGroup = new tcu::TestCaseGroup(testCtx, samplesGroupName.c_str(), "Samples tests");

				underestimate->addChild(samplesGroup);

				for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveTypeNdx)
				{
					tcu::TestCaseGroup* const primitiveGroup = new tcu::TestCaseGroup(testCtx, primitiveTypes[primitiveTypeNdx].name, "Primitive tests");

					samplesGroup->addChild(primitiveGroup);

					{
						tcu::TestCaseGroup* const normal = new tcu::TestCaseGroup(testCtx, "normal", "Normal conservative rasterization tests");

						primitiveGroup->addChild(normal);

						ConservativeTestConfig	config	=
						{
							VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT,	//  VkConservativeRasterizationModeEXT	conservativeRasterizationMode;
							0.0f,													//  float								extraOverestimationSize;
							primitiveTypes[primitiveTypeNdx].type,					//  VkPrimitiveTopology					primitiveTopology;
							false,													//  bool								degeneratePrimitives;
							1.0f,													//  float								lineWidth;
							64u,													//  deUint32							resolution;
						};

						if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
							normal->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance>	(testCtx,
																										 "test",
																										 "Underestimate test, verify rasterization result",
																										 config,
																										 samples[samplesNdx]));

						if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
						{
							for (int underestimateWidthNdx = 0; underestimateWidthNdx < DE_LENGTH_OF_ARRAY(underestimateLineWidths); ++underestimateWidthNdx)
							{
								config.lineWidth = underestimateLineWidths[underestimateWidthNdx].size;
								normal->addChild(new ConservativeTestCase<ConservativeLineTestInstance>		(testCtx,
																											 underestimateLineWidths[underestimateWidthNdx].name,
																											 "Underestimate test, verify rasterization result",
																											 config,
																											 samples[samplesNdx]));
							}
						}

						if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
						{
							for (int underestimatePointSizeNdx = 0; underestimatePointSizeNdx < DE_LENGTH_OF_ARRAY(underestimatePointSizes); ++underestimatePointSizeNdx)
							{
								config.lineWidth = underestimatePointSizes[underestimatePointSizeNdx].size;
								normal->addChild(new ConservativeTestCase<ConservativePointTestInstance>	(testCtx,
																											 underestimatePointSizes[underestimatePointSizeNdx].name,
																											 "Underestimate test, verify rasterization result",
																											 config,
																											 samples[samplesNdx]));
							}
						}
					}

					{
						tcu::TestCaseGroup* const degenerate = new tcu::TestCaseGroup(testCtx, "degenerate", "Degenerate primitives conservative rasterization tests");

						primitiveGroup->addChild(degenerate);

						ConservativeTestConfig	config	=
						{
							VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT,	//  VkConservativeRasterizationModeEXT	conservativeRasterizationMode;
							0.0f,													//  float								extraOverestimationSize;
							primitiveTypes[primitiveTypeNdx].type,					//  VkPrimitiveTopology					primitiveTopology;
							true,													//  bool								degeneratePrimitives;
							1.0f,													//  float								lineWidth;
							64u,													//  deUint32							resolution;
						};

						if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
							degenerate->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance>	(testCtx,
																											 "test",
																											 "Underestimate triangle test, verify rasterization result",
																											 config,
																											 samples[samplesNdx]));

						if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
						{
							for (int underestimateWidthNdx = 0; underestimateWidthNdx < DE_LENGTH_OF_ARRAY(underestimateLineWidths); ++underestimateWidthNdx)
							{
								config.lineWidth = underestimateLineWidths[underestimateWidthNdx].size;
								degenerate->addChild(new ConservativeTestCase<ConservativeLineTestInstance>		(testCtx,
																												 underestimateLineWidths[underestimateWidthNdx].name,
																												 "Underestimate line test, verify rasterization result",
																												 config,
																												 samples[samplesNdx]));
							}
						}
					}
				}
			}
		}
	}

	// .interpolation
	{
		tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, "interpolation", "Test interpolation");

		rasterizationTests->addChild(interpolation);

		// .basic
		{
			tcu::TestCaseGroup* const basic = new tcu::TestCaseGroup(testCtx, "basic", "Non-projective interpolation");

			interpolation->addChild(basic);

			basic->addChild(new TriangleInterpolationTestCase		(testCtx, "triangles",		"Verify triangle interpolation",		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	INTERPOLATIONFLAGS_NONE));
			basic->addChild(new TriangleInterpolationTestCase		(testCtx, "triangle_strip",	"Verify triangle strip interpolation",	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	INTERPOLATIONFLAGS_NONE));
			basic->addChild(new TriangleInterpolationTestCase		(testCtx, "triangle_fan",	"Verify triangle fan interpolation",	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,		INTERPOLATIONFLAGS_NONE));
			basic->addChild(new LineInterpolationTestCase			(testCtx, "lines",			"Verify line interpolation",			VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE));
			basic->addChild(new LineInterpolationTestCase			(testCtx, "line_strip",		"Verify line strip interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE));
			basic->addChild(new LineInterpolationTestCase			(testCtx, "lines_wide",		"Verify wide line interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE));
			basic->addChild(new LineInterpolationTestCase			(testCtx, "line_strip_wide","Verify wide line strip interpolation",	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE));

			basic->addChild(new LineInterpolationTestCase			(testCtx, "strict_lines",			"Verify strict line interpolation",				VK_PRIMITIVE_TOPOLOGY_LINE_LIST,	INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_STRICT));
			basic->addChild(new LineInterpolationTestCase			(testCtx, "strict_line_strip",		"Verify strict line strip interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,	INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_STRICT));
			basic->addChild(new LineInterpolationTestCase			(testCtx, "strict_lines_wide",		"Verify strict wide line interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_LIST,	INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_STRICT));
			basic->addChild(new LineInterpolationTestCase			(testCtx, "strict_line_strip_wide",	"Verify strict wide line strip interpolation",	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,	INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_STRICT));

			basic->addChild(new LineInterpolationTestCase			(testCtx, "non_strict_lines",			"Verify non-strict line interpolation",				VK_PRIMITIVE_TOPOLOGY_LINE_LIST,	INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_NONSTRICT));
			basic->addChild(new LineInterpolationTestCase			(testCtx, "non_strict_line_strip",		"Verify non-strict line strip interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,	INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_NONSTRICT));
			basic->addChild(new LineInterpolationTestCase			(testCtx, "non_strict_lines_wide",		"Verify non-strict wide line interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_LIST,	INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_NONSTRICT));
			basic->addChild(new LineInterpolationTestCase			(testCtx, "non_strict_line_strip_wide",	"Verify non-strict wide line strip interpolation",	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,	INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_NONSTRICT));
		}

		// .projected
		{
			tcu::TestCaseGroup* const projected = new tcu::TestCaseGroup(testCtx, "projected", "Projective interpolation");

			interpolation->addChild(projected);

			projected->addChild(new TriangleInterpolationTestCase	(testCtx, "triangles",		"Verify triangle interpolation",		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	INTERPOLATIONFLAGS_PROJECTED));
			projected->addChild(new TriangleInterpolationTestCase	(testCtx, "triangle_strip",	"Verify triangle strip interpolation",	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	INTERPOLATIONFLAGS_PROJECTED));
			projected->addChild(new TriangleInterpolationTestCase	(testCtx, "triangle_fan",	"Verify triangle fan interpolation",	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,		INTERPOLATIONFLAGS_PROJECTED));
			projected->addChild(new LineInterpolationTestCase		(testCtx, "lines",			"Verify line interpolation",			VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE));
			projected->addChild(new LineInterpolationTestCase		(testCtx, "line_strip",		"Verify line strip interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE));
			projected->addChild(new LineInterpolationTestCase		(testCtx, "lines_wide",		"Verify wide line interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE));
			projected->addChild(new LineInterpolationTestCase		(testCtx, "line_strip_wide","Verify wide line strip interpolation",	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE));

			projected->addChild(new LineInterpolationTestCase		(testCtx, "strict_lines",			"Verify strict line interpolation",				VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_STRICT));
			projected->addChild(new LineInterpolationTestCase		(testCtx, "strict_line_strip",		"Verify strict line strip interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_STRICT));
			projected->addChild(new LineInterpolationTestCase		(testCtx, "strict_lines_wide",		"Verify strict wide line interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_STRICT));
			projected->addChild(new LineInterpolationTestCase		(testCtx, "strict_line_strip_wide",	"Verify strict wide line strip interpolation",	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_STRICT));

			projected->addChild(new LineInterpolationTestCase		(testCtx, "non_strict_lines",			"Verify non-strict line interpolation",				VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_NONSTRICT));
			projected->addChild(new LineInterpolationTestCase		(testCtx, "non_strict_line_strip",		"Verify non-strict line strip interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_NONSTRICT));
			projected->addChild(new LineInterpolationTestCase		(testCtx, "non_strict_lines_wide",		"Verify non-strict wide line interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_NONSTRICT));
			projected->addChild(new LineInterpolationTestCase		(testCtx, "non_strict_line_strip_wide",	"Verify non-strict wide line strip interpolation",	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_PROJECTED,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_NONSTRICT));
		}
	}

	// .flatshading
	{
		tcu::TestCaseGroup* const flatshading = new tcu::TestCaseGroup(testCtx, "flatshading", "Test flatshading");

		rasterizationTests->addChild(flatshading);

		flatshading->addChild(new TriangleInterpolationTestCase		(testCtx, "triangles",		"Verify triangle flatshading",			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	INTERPOLATIONFLAGS_FLATSHADE));
		flatshading->addChild(new TriangleInterpolationTestCase		(testCtx, "triangle_strip",	"Verify triangle strip flatshading",	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	INTERPOLATIONFLAGS_FLATSHADE));
		flatshading->addChild(new TriangleInterpolationTestCase		(testCtx, "triangle_fan",	"Verify triangle fan flatshading",		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,		INTERPOLATIONFLAGS_FLATSHADE));
		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "lines",			"Verify line flatshading",				VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE));
		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "line_strip",		"Verify line strip flatshading",		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE));
		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "lines_wide",		"Verify wide line flatshading",			VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE));
		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "line_strip_wide","Verify wide line strip flatshading",	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE));

		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "strict_lines",			"Verify strict line flatshading",				VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_STRICT));
		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "strict_line_strip",		"Verify strict line strip flatshading",			VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_STRICT));
		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "strict_lines_wide",		"Verify strict wide line flatshading",			VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_STRICT));
		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "strict_line_strip_wide",	"Verify strict wide line strip flatshading",	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_STRICT));

		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "non_strict_lines",			"Verify non-strict line flatshading",				VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_NONSTRICT));
		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "non_strict_line_strip",		"Verify non-strict line strip flatshading",			VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_NONSTRICT));
		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "non_strict_lines_wide",		"Verify non-strict wide line flatshading",			VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_NONSTRICT));
		flatshading->addChild(new LineInterpolationTestCase			(testCtx, "non_strict_line_strip_wide",	"Verify non-strict wide line strip flatshading",	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,		INTERPOLATIONFLAGS_FLATSHADE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_NONSTRICT));
	}

	const VkSampleCountFlagBits samples[] =
	{
		VK_SAMPLE_COUNT_2_BIT,
		VK_SAMPLE_COUNT_4_BIT,
		VK_SAMPLE_COUNT_8_BIT,
		VK_SAMPLE_COUNT_16_BIT,
		VK_SAMPLE_COUNT_32_BIT,
		VK_SAMPLE_COUNT_64_BIT
	};

	for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
	{
		std::ostringstream caseName;

		caseName << "_multisample_" << (2 << samplesNdx) << "_bit";

		// .primitives
		{
			tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, ("primitives" + caseName.str()).c_str(), "Primitive rasterization");

			rasterizationTests->addChild(primitives);

			tcu::TestCaseGroup* const nostippleTests = new tcu::TestCaseGroup(testCtx, "no_stipple", "No stipple");
			tcu::TestCaseGroup* const stippleStaticTests = new tcu::TestCaseGroup(testCtx, "static_stipple", "Line stipple static");
			tcu::TestCaseGroup* const stippleDynamicTests = new tcu::TestCaseGroup(testCtx, "dynamic_stipple", "Line stipple dynamic");

			primitives->addChild(nostippleTests);
			primitives->addChild(stippleStaticTests);
			primitives->addChild(stippleDynamicTests);

			nostippleTests->addChild(new BaseTestCase<TrianglesTestInstance>		(testCtx, "triangles",			"Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result",					samples[samplesNdx]));
			nostippleTests->addChild(new WidenessTestCase<PointTestInstance>		(testCtx, "points",				"Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result",						PRIMITIVEWIDENESS_WIDE,	PRIMITIVESTRICTNESS_IGNORE,	false, samples[samplesNdx], LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));

			nostippleTests->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "strict_lines",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in strict mode, verify rasterization result",						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_STRICT,	true, samples[samplesNdx], LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
			nostippleTests->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "strict_lines_wide",	"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in strict mode with wide lines, verify rasterization result",		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_STRICT,	true, samples[samplesNdx], LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));

			nostippleTests->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "non_strict_lines",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in nonstrict mode, verify rasterization result",						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_NONSTRICT,	true, samples[samplesNdx], LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
			nostippleTests->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "non_strict_lines_wide",	"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in nonstrict mode with wide lines, verify rasterization result",		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_NONSTRICT,	true, samples[samplesNdx], LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));

			for (int i = 0; i < 3; ++i) {

				tcu::TestCaseGroup *g = i == 2 ? stippleDynamicTests : i == 1 ? stippleStaticTests : nostippleTests;

				LineStipple stipple = (LineStipple)i;

				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "lines",						"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result",						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, LineStippleFactorCase::DEFAULT, i == 0 ? RESOLUTION_NPOT : 0));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "line_strip",					"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result",						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "lines_wide",					"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result",		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "line_strip_wide",			"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result",		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));

				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "rectangular_lines",			"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result",						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "rectangular_line_strip",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result",						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));
				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "rectangular_lines_wide",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result",		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "rectangular_line_strip_wide","Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result",		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));

				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "bresenham_lines",			"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result",						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "bresenham_line_strip",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result",						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "bresenham_lines_wide",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result",		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "bresenham_line_strip_wide",	"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result",		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));

				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "smooth_lines",				"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result",						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "smooth_line_strip",			"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result",						PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
				g->addChild(new WidenessTestCase<LinesTestInstance>		(testCtx, "smooth_lines_wide",			"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result",		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
				g->addChild(new WidenessTestCase<LineStripTestInstance>	(testCtx, "smooth_line_strip_wide",		"Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result",		PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
			}
		}

		// .fill_rules
		{
			tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, ("fill_rules" + caseName.str()).c_str(), "Primitive fill rules");

			rasterizationTests->addChild(fillRules);

			fillRules->addChild(new FillRuleTestCase(testCtx,	"basic_quad",			"Verify fill rules",	FillRuleTestInstance::FILLRULECASE_BASIC,			samples[samplesNdx]));
			fillRules->addChild(new FillRuleTestCase(testCtx,	"basic_quad_reverse",	"Verify fill rules",	FillRuleTestInstance::FILLRULECASE_REVERSED,		samples[samplesNdx]));
			fillRules->addChild(new FillRuleTestCase(testCtx,	"clipped_full",			"Verify fill rules",	FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL,	samples[samplesNdx]));
			fillRules->addChild(new FillRuleTestCase(testCtx,	"clipped_partly",		"Verify fill rules",	FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL,	samples[samplesNdx]));
			fillRules->addChild(new FillRuleTestCase(testCtx,	"projected",			"Verify fill rules",	FillRuleTestInstance::FILLRULECASE_PROJECTED,		samples[samplesNdx]));
		}

		// .interpolation
		{
			tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, ("interpolation" + caseName.str()).c_str(), "Test interpolation");

			rasterizationTests->addChild(interpolation);

			interpolation->addChild(new TriangleInterpolationTestCase		(testCtx, "triangles",		"Verify triangle interpolation",		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	INTERPOLATIONFLAGS_NONE,															samples[samplesNdx]));
			interpolation->addChild(new LineInterpolationTestCase			(testCtx, "lines",			"Verify line interpolation",			VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_IGNORE,	samples[samplesNdx]));
			interpolation->addChild(new LineInterpolationTestCase			(testCtx, "lines_wide",		"Verify wide line interpolation",		VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_IGNORE,	samples[samplesNdx]));

			interpolation->addChild(new LineInterpolationTestCase			(testCtx, "strict_lines",			"Verify strict line interpolation",			VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_STRICT,	samples[samplesNdx]));
			interpolation->addChild(new LineInterpolationTestCase			(testCtx, "strict_lines_wide",		"Verify strict wide line interpolation",	VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_STRICT,	samples[samplesNdx]));

			interpolation->addChild(new LineInterpolationTestCase			(testCtx, "non_strict_lines",			"Verify non-strict line interpolation",			VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_NARROW,	PRIMITIVESTRICTNESS_NONSTRICT,	samples[samplesNdx]));
			interpolation->addChild(new LineInterpolationTestCase			(testCtx, "non_strict_lines_wide",		"Verify non-strict wide line interpolation",	VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		INTERPOLATIONFLAGS_NONE,	PRIMITIVEWIDENESS_WIDE,		PRIMITIVESTRICTNESS_NONSTRICT,	samples[samplesNdx]));
		}
	}

	// .provoking_vertex
#ifndef CTS_USES_VULKANSC
	{
		rasterizationTests->addChild(createProvokingVertexTests(testCtx));
	}
#endif

	// .line_continuity
#ifndef CTS_USES_VULKANSC
	{
		tcu::TestCaseGroup* const	lineContinuity	= new tcu::TestCaseGroup(testCtx, "line_continuity", "Test line continuity");
		static const char			dataDir[]		= "rasterization/line_continuity";

		struct Case
		{
			std::string	name;
			std::string	desc;
			bool		requireFillModeNonSolid;
		};

		static const Case cases[] =
		{
			{	"line-strip",			"Test line strip drawing produces continuous lines",	false	},
			{	"polygon-mode-lines",	"Test triangles drawn with lines are continuous",		true	}
		};

		rasterizationTests->addChild(lineContinuity);

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
		{
			const std::string			fileName	= cases[i].name + ".amber";
			cts_amber::AmberTestCase*	testCase	= cts_amber::createAmberTestCase(testCtx, cases[i].name.c_str(), cases[i].desc.c_str(), dataDir, fileName);

			if (cases[i].requireFillModeNonSolid)
			{
				testCase->addRequirement("Features.fillModeNonSolid");
			}

			lineContinuity->addChild(testCase);
		}
	}
#endif

	// .depth bias
#ifndef CTS_USES_VULKANSC
	{
		tcu::TestCaseGroup* const	depthBias	= new tcu::TestCaseGroup(testCtx, "depth_bias", "Test depth bias");
		static const char			dataDir[]	= "rasterization/depth_bias";

		static const struct
		{
			std::string name;
			vk::VkFormat format;
			std::string description;
		} cases [] =
		{
			{"d16_unorm",	vk::VK_FORMAT_D16_UNORM,			"Test depth bias with format D16_UNORM"},
			{"d32_sfloat",	vk::VK_FORMAT_D32_SFLOAT,			"Test depth bias with format D32_SFLOAT"},
			{"d24_unorm",	vk::VK_FORMAT_D24_UNORM_S8_UINT,	"Test depth bias with format D24_UNORM_S8_UINT"}
		};

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
		{
			const VkImageCreateInfo vkImageCreateInfo = {
				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// sType
				nullptr,										// pNext
				0,												// flags
				VK_IMAGE_TYPE_2D,								// imageType
				cases[i].format,								// format
				{250, 250, 1},									// extent
				1,												// mipLevels
				1,												// arrayLayers
				VK_SAMPLE_COUNT_1_BIT,							// samples
				VK_IMAGE_TILING_OPTIMAL,						// tiling
				VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,	// usage
				VK_SHARING_MODE_EXCLUSIVE,						// sharingMode
				0,												// queueFamilyIndexCount
				nullptr,										// pQueueFamilyIndices
				VK_IMAGE_LAYOUT_UNDEFINED,						// initialLayout
			};

			std::vector<std::string>		requirements = std::vector<std::string>(0);
			std::vector<VkImageCreateInfo>	imageRequirements;
			imageRequirements.push_back(vkImageCreateInfo);
			const std::string			fileName	= cases[i].name + ".amber";
			cts_amber::AmberTestCase*	testCase	= cts_amber::createAmberTestCase(testCtx, cases[i].name.c_str(), cases[i].description.c_str(), dataDir, fileName, requirements, imageRequirements);

			depthBias->addChild(testCase);
		}

		rasterizationTests->addChild(depthBias);
	}
#endif // CTS_USES_VULKANSC

	// Fragment shader side effects.
	{
		rasterizationTests->addChild(createFragSideEffectsTests(testCtx));
	}
}

} // anonymous

tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "rasterization", "Rasterization Tests", createRasterizationTests);
}

} // rasterization
} // vkt
