/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2019 Valve Corporation.
 * Copyright (c) 2019 The Khronos Group Inc.
 *
 * 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 EXT_discard_rectangles tests
 *//*--------------------------------------------------------------------*/

#include "vktDrawDiscardRectanglesTests.hpp"

#include "vkDefs.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCase.hpp"
#include "vktDrawBufferObjectUtil.hpp"

#include "tcuTestCase.hpp"
#include "tcuVector.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"

#include "deUniquePtr.hpp"
#include "deSharedPtr.hpp"

namespace vkt
{
namespace Draw
{

namespace
{
using namespace vk;
using de::UniquePtr;
using de::SharedPtr;
using de::MovePtr;
using tcu::Vec4;
using tcu::Vec2;
using tcu::UVec2;
using tcu::UVec4;

enum TestMode
{
	TEST_MODE_INCLUSIVE = 0,
	TEST_MODE_EXCLUSIVE,
	TEST_MODE_COUNT
};

enum TestScissorMode
{
	TEST_SCISSOR_MODE_NONE = 0,
	TEST_SCISSOR_MODE_STATIC,
	TEST_SCISSOR_MODE_DYNAMIC,
	TEST_SCISSOR_MODE_COUNT
};

#define NUM_RECT_TESTS 6
#define NUM_DYNAMIC_DISCARD_TYPE_TESTS 2

struct TestParams
{
	TestMode		testMode;
	deUint32		numRectangles;
	deBool			dynamicDiscardRectangles;
	TestScissorMode	scissorMode;
};

template<typename T>
inline VkDeviceSize sizeInBytes(const std::vector<T>& vec)
{
	return vec.size() * sizeof(vec[0]);
}

MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
{
	MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
	VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
	return alloc;
}

inline Move<VkImage> makeImage (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo)
{
	return createImage(vk, device, &createInfo);
}

VkImageCreateInfo makeImageCreateInfo (const VkFormat format, const UVec2& size, VkImageUsageFlags usage)
{
	const VkImageCreateInfo imageParams =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		(VkImageCreateFlags)0,							// VkImageCreateFlags		flags;
		VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
		format,											// VkFormat					format;
		makeExtent3D(size.x(), size.y(), 1),			// VkExtent3D				extent;
		1u,												// deUint32					mipLevels;
		1u,												// deUint32					arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
		usage,											// VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
		0u,												// deUint32					queueFamilyIndexCount;
		DE_NULL,										// const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
	};
	return imageParams;
}

VkPipelineDiscardRectangleStateCreateInfoEXT makeDiscardRectangleStateCreateInfo (const deBool						dynamicDiscardRectangle,
																				  const VkDiscardRectangleModeEXT	discardRectangleMode,
																				  const deUint32					discardRectangleCount,
																				  const VkRect2D					*pDiscardRectangles)
{
	const VkPipelineDiscardRectangleStateCreateInfoEXT discardRectanglesCreateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT,		// VkStructureType									sType;
		DE_NULL,																// const void*										pNext;
		0u,																		// VkPipelineDiscardRectangleStateCreateFlagsEXT	flags;
		discardRectangleMode,													// VkDiscardRectangleModeEXT						discardRectangleMode;
		discardRectangleCount,													// deUint32											discardRectangleCount;
		dynamicDiscardRectangle ? DE_NULL : pDiscardRectangles					// const VkRect2D*									pDiscardRectangles;
	};
	return discardRectanglesCreateInfo;
}

Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&			vk,
									   const VkDevice					device,
									   const VkPipelineLayout			pipelineLayout,
									   const VkRenderPass				renderPass,
									   const VkShaderModule				vertexModule,
									   const VkShaderModule				fragmentModule,
									   const UVec2						renderSize,
									   const deBool						dynamicDiscardRectangle,
									   const VkDiscardRectangleModeEXT	discardRectangleMode,
									   const deUint32					discardRectangleCount,
									   const VkRect2D*					pDiscardRectangles,
									   const TestScissorMode			scissorMode,
									   const VkRect2D					rectScissor)
{
	const VkVertexInputBindingDescription vertexInputBindingDescription =
	{
		0u,								// uint32_t				binding;
		sizeof(Vec4),					// uint32_t				stride;
		VK_VERTEX_INPUT_RATE_VERTEX,	// VkVertexInputRate	inputRate;
	};

	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
	{
		{
			0u,								// uint32_t			location;
			0u,								// uint32_t			binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat			format;
			0u,								// uint32_t			offset;
		},
	};

	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType								sType;
		DE_NULL,														// const void*									pNext;
		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags		flags;
		1u,																// uint32_t										vertexBindingDescriptionCount;
		&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*		pVertexBindingDescriptions;
		DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),			// uint32_t										vertexAttributeDescriptionCount;
		vertexInputAttributeDescriptions,								// const VkVertexInputAttributeDescription*		pVertexAttributeDescriptions;
	};

	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType								sType;
		DE_NULL,														// const void*									pNext;
		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags		flags;
		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology							topology;
		VK_FALSE,														// VkBool32										primitiveRestartEnable;
	};


	VkViewport		viewport				= makeViewport(0.0f, 0.0f, static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()), 0.0f, 1.0f);
	const VkRect2D	rectScissorRenderSize	= { { 0, 0 }, { renderSize.x(), renderSize.y() } };

	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,							// VkStructureType								sType;
		DE_NULL,																		// const void*									pNext;
		(VkPipelineViewportStateCreateFlags)0,											// VkPipelineViewportStateCreateFlags			flags;
		1u,																				// uint32_t										viewportCount;
		&viewport,																		// const VkViewport*							pViewports;
		1u,																				// uint32_t										scissorCount;
		scissorMode != TEST_SCISSOR_MODE_NONE ? &rectScissor : &rectScissorRenderSize,	// const VkRect2D*								pScissors;
	};

	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType								sType;
		DE_NULL,														// const void*									pNext;
		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags		flags;
		VK_FALSE,														// VkBool32										depthClampEnable;
		VK_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;
		1.0f,															// float										lineWidth;
	};

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

	const VkStencilOpState stencilOpState = makeStencilOpState(
		VK_STENCIL_OP_KEEP,				// stencil fail
		VK_STENCIL_OP_KEEP,				// depth & stencil pass
		VK_STENCIL_OP_KEEP,				// depth only fail
		VK_COMPARE_OP_ALWAYS,			// compare op
		0u,								// compare mask
		0u,								// write mask
		0u);							// reference

	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType								sType;
		DE_NULL,														// const void*									pNext;
		(VkPipelineDepthStencilStateCreateFlags)0,						// VkPipelineDepthStencilStateCreateFlags		flags;
		VK_FALSE,														// VkBool32										depthTestEnable;
		VK_FALSE,														// VkBool32										depthWriteEnable;
		VK_COMPARE_OP_LESS,												// VkCompareOp									depthCompareOp;
		VK_FALSE,														// VkBool32										depthBoundsTestEnable;
		VK_FALSE,														// VkBool32										stencilTestEnable;
		stencilOpState,													// VkStencilOpState								front;
		stencilOpState,													// VkStencilOpState								back;
		0.0f,															// float										minDepthBounds;
		1.0f,															// float										maxDepthBounds;
	};

	const VkColorComponentFlags					colorComponentsAll					= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
	const VkPipelineColorBlendAttachmentState	pipelineColorBlendAttachmentState	=
	{
		VK_FALSE,						// VkBool32					blendEnable;
		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcColorBlendFactor;
		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstColorBlendFactor;
		VK_BLEND_OP_ADD,				// VkBlendOp				colorBlendOp;
		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcAlphaBlendFactor;
		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstAlphaBlendFactor;
		VK_BLEND_OP_ADD,				// VkBlendOp				alphaBlendOp;
		colorComponentsAll,				// VkColorComponentFlags	colorWriteMask;
	};

	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType								sType;
		DE_NULL,														// const void*									pNext;
		(VkPipelineColorBlendStateCreateFlags)0,						// VkPipelineColorBlendStateCreateFlags			flags;
		VK_FALSE,														// VkBool32										logicOpEnable;
		VK_LOGIC_OP_COPY,												// VkLogicOp									logicOp;
		1u,																// deUint32										attachmentCount;
		&pipelineColorBlendAttachmentState,								// const VkPipelineColorBlendAttachmentState*	pAttachments;
		{ 0.0f, 0.0f, 0.0f, 0.0f },										// float										blendConstants[4];
	};

	const VkPipelineShaderStageCreateInfo pShaderStages[] =
	{
		{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType								sType;
			DE_NULL,													// const void*									pNext;
			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags				flags;
			VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits						stage;
			vertexModule,												// VkShaderModule								module;
			"main",														// const char*									pName;
			DE_NULL,													// const VkSpecializationInfo*					pSpecializationInfo;
		},
		{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType								sType;
			DE_NULL,													// const void*									pNext;
			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags				flags;
			VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits						stage;
			fragmentModule,												// VkShaderModule								module;
			"main",														// const char*									pName;
			DE_NULL,													// const VkSpecializationInfo*					pSpecializationInfo;
		},
	};

	const VkPipelineDiscardRectangleStateCreateInfoEXT discardRectangleStateCreateInfo = makeDiscardRectangleStateCreateInfo(dynamicDiscardRectangle, discardRectangleMode, discardRectangleCount, pDiscardRectangles);

	const VkDynamicState dynamicStateDiscardRectangles	= VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT;
	const VkDynamicState dynamicStateScissor			= VK_DYNAMIC_STATE_SCISSOR;
	std::vector<VkDynamicState> dynamicStates;

	if (dynamicDiscardRectangle)
		dynamicStates.push_back(dynamicStateDiscardRectangles);
	if (scissorMode == TEST_SCISSOR_MODE_DYNAMIC)
		dynamicStates.push_back(dynamicStateScissor);

	const VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,			// VkStructureType								sType;
		DE_NULL,														// const void*									pNext;
		0u,																// VkPipelineDynamicStateCreateFlags			flags;
	    (deUint32)dynamicStates.size(),									// deUint32										dynamicStateCount;
		dynamicStates.data()											// const VkDynamicState*						pDynamicStates;
	};

	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
	{
		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,				// VkStructureType									sType;
		&discardRectangleStateCreateInfo,								// const void*										pNext;
		(VkPipelineCreateFlags)0,										// VkPipelineCreateFlags							flags;
		2u,																// deUint32											stageCount;
		pShaderStages,													// const VkPipelineShaderStageCreateInfo*			pStages;
		&vertexInputStateInfo,											// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
		&pipelineInputAssemblyStateInfo,								// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
		DE_NULL,														// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
		&pipelineViewportStateInfo,										// const VkPipelineViewportStateCreateInfo*			pViewportState;
		&pipelineRasterizationStateInfo,								// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
		&pipelineMultisampleStateInfo,									// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
		&pipelineDepthStencilStateInfo,									// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
		&pipelineColorBlendStateInfo,									// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
		&pipelineDynamicStateCreateInfo,								// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
		pipelineLayout,													// VkPipelineLayout									layout;
		renderPass,														// VkRenderPass										renderPass;
		0u,																// deUint32											subpass;
		DE_NULL,														// VkPipeline										basePipelineHandle;
		0,																// deInt32											basePipelineIndex;
	};

	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
}

void generateDiscardRectangles(const UVec2& renderSize, deUint32 numRect, std::vector<VkRect2D>& rectangles)
{
	deUint32 cellHight = renderSize.y() - 10;
	deUint32 cellWidth = (renderSize.x() - 10) / (2 * numRect - 1);

	DE_ASSERT(rectangles.size() == 0);

	for (deUint32 i = 0; i < numRect; i++)
	{
		VkRect2D rect;
		rect.extent.height = cellHight;
		rect.extent.width = cellWidth;
		rect.offset.x = 5u + i * 2 * cellWidth;
		rect.offset.y = 5u;
		rectangles.push_back(rect);
	}
}

//! Renders a colorful grid of rectangles.
tcu::TextureLevel generateReferenceImage (const tcu::TextureFormat		format,
										  const UVec2&					renderSize,
										  const TestMode				testMode,
										  const Vec4&					color,
										  const deUint32				numRectangles,
										  const std::vector<VkRect2D>	rectangles,
										  const deBool					enableScissor,
										  const VkRect2D				scissor)
{
	tcu::TextureLevel	image(format, renderSize.x(), renderSize.y());
	const Vec4			rectColor	= testMode == TEST_MODE_INCLUSIVE ? Vec4(0.0f, 1.0f, 0.0f, 1.0f)	: color;
	const Vec4			clearColor	= testMode == TEST_MODE_INCLUSIVE ? color							: Vec4(0.0f, 1.0f, 0.0f, 1.0f);

	if (!enableScissor)
	{
		// Clear the image with clearColor
		tcu::clear(image.getAccess(), clearColor);

		// Now draw the discard rectangles taking into account the selected mode.
		for (deUint32 i = 0; i < numRectangles; i++)
		{
			tcu::clear(tcu::getSubregion(image.getAccess(), rectangles[i].offset.x, rectangles[i].offset.y,
										 rectangles[i].extent.width, rectangles[i].extent.height),
					   rectColor);
		}
	}
	else
	{
		// Clear the image with the original clear color
		tcu::clear(image.getAccess(), color);
		// Clear the scissor are with the clearColor which depends on the selected mode
		tcu::clear(tcu::getSubregion(image.getAccess(), scissor.offset.x, scissor.offset.y,
									 scissor.extent.width, scissor.extent.height),
				   clearColor);

		// Now draw the discard rectangles taking into account both the scissor area and
		// the selected mode.
		for (deUint32 rect = 0; rect < numRectangles; rect++)
		{
			for (deUint32 x = rectangles[rect].offset.x; x < (rectangles[rect].offset.x + rectangles[rect].extent.width); x++)
			{
				for(deUint32 y = rectangles[rect].offset.y; y < (rectangles[rect].offset.y + rectangles[rect].extent.height); y++)
				{
					if ((x >= (deUint32)scissor.offset.x) && (x < (scissor.offset.x + scissor.extent.width)) &&
						(y >= (deUint32)scissor.offset.y) && (y < (scissor.offset.y + scissor.extent.height)))
					{
						image.getAccess().setPixel(rectColor, x, y);
					}
				}
			}
		}
	}
	return image;
}

class DiscardRectanglesTestInstance : public TestInstance
{
public:
							DiscardRectanglesTestInstance		(Context& context,
																 TestParams params);
	virtual					~DiscardRectanglesTestInstance		(void) {};
	virtual tcu::TestStatus	iterate								(void);

private:
	const TestParams			m_params;
	const Vec4					m_clearColor;
	const UVec2					m_renderSize;
	std::vector<Vec4>			m_vertices;
	std::vector<VkRect2D>		m_rectangles;

	Move<VkImage>				m_colorImage;
	MovePtr<Allocation>			m_colorImageAlloc;
	Move<VkImageView>			m_colorAttachment;
	SharedPtr<Buffer>			m_colorBuffer;
	SharedPtr<Buffer>			m_vertexBuffer;
	Move<VkShaderModule>		m_vertexModule;
	Move<VkShaderModule>		m_fragmentModule;
	Move<VkRenderPass>			m_renderPass;
	Move<VkFramebuffer>			m_framebuffer;
	Move<VkPipelineLayout>		m_pipelineLayout;
	Move<VkPipeline>			m_pipeline;
	Move<VkCommandPool>			m_cmdPool;
	Move<VkCommandBuffer>		m_cmdBuffer;
};

DiscardRectanglesTestInstance::DiscardRectanglesTestInstance (Context& context,
															  TestParams params)
	: TestInstance	(context)
	, m_params		(params)
	, m_clearColor	(Vec4(1.0f, 0.0f, 0.0f, 1.0f))
	, m_renderSize	(UVec2(340, 100))
{
}

tcu::TestStatus DiscardRectanglesTestInstance::iterate	(void)
{
	const DeviceInterface&			vk						= m_context.getDeviceInterface();
	const InstanceInterface&		vki						= m_context.getInstanceInterface();
	const VkPhysicalDevice			physicalDevice			= m_context.getPhysicalDevice();
	const VkDevice					device					= m_context.getDevice();
	const VkQueue					queue					= m_context.getUniversalQueue();
	const deUint32					queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	Allocator&						allocator				= m_context.getDefaultAllocator();
	const VkDiscardRectangleModeEXT	discardRectangleMode	= m_params.testMode == TEST_MODE_EXCLUSIVE ? VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT : VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT;
	const VkRect2D					rectScissor				= { { 90, 25 }, { 160, 50} };
	const VkImageSubresourceRange	colorSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const VkFormat					colorFormat				= VK_FORMAT_R8G8B8A8_UNORM;
	const VkDeviceSize				colorBufferSize			= m_renderSize.x() * m_renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat));

	// Check for VK_EXT_discard_rectangles support and maximum number of active discard rectangles
	{
		VkPhysicalDeviceDiscardRectanglePropertiesEXT discardRectangleProperties;
		deMemset(&discardRectangleProperties, 0, sizeof(VkPhysicalDeviceDiscardRectanglePropertiesEXT));
		discardRectangleProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT;

		VkPhysicalDeviceProperties2 physicalDeviceProperties;
		physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
		physicalDeviceProperties.pNext = &discardRectangleProperties;

		vki.getPhysicalDeviceProperties2(physicalDevice, &physicalDeviceProperties);

		if (discardRectangleProperties.maxDiscardRectangles == 0)
		{
			throw tcu::NotSupportedError("Implementation doesn't support discard rectangles");
		}

		if (discardRectangleProperties.maxDiscardRectangles < 4)
		{
			std::ostringstream message;
			message << "Implementation doesn't support the minimum value for maxDiscardRectangles: " << discardRectangleProperties.maxDiscardRectangles << " < 4";
			return tcu::TestStatus::fail(message.str());
		}

		if (discardRectangleProperties.maxDiscardRectangles < m_params.numRectangles)
		{
			std::ostringstream message;
			message << "Implementation doesn't support the required number of discard rectangles: " << discardRectangleProperties.maxDiscardRectangles << " < " << m_params.numRectangles;
			throw tcu::NotSupportedError(message.str());
		}
	}

	// Color attachment
	{
		m_colorImage		= makeImage(vk, device, makeImageCreateInfo(colorFormat, m_renderSize, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT));
		m_colorImageAlloc	= bindImage(vk, device, allocator, *m_colorImage, MemoryRequirement::Any);
		m_colorBuffer		= Buffer::createAndAlloc(vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), allocator, MemoryRequirement::HostVisible);
		m_colorAttachment	= makeImageView(vk, device, *m_colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange);

		// Zero colorBuffer.
		const Allocation alloc = m_colorBuffer->getBoundMemory();
		deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
		flushAlloc(vk, device, alloc);
	}

	// Initialize the pipeline and other variables
	{
		// Draw a quad covering the whole framebuffer
		m_vertices.push_back(Vec4(-1.0f,  1.0f, 0.0f, 1.0f));
		m_vertices.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
		m_vertices.push_back(Vec4( 1.0f,  1.0f, 0.0f, 1.0f));
		m_vertices.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
		VkDeviceSize vertexBufferSize	= sizeInBytes(m_vertices);
		m_vertexBuffer					= Buffer::createAndAlloc	(vk, device, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), allocator, MemoryRequirement::HostVisible);


		deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), m_vertices.data(), static_cast<std::size_t>(vertexBufferSize));
		flushAlloc(vk, device, m_vertexBuffer->getBoundMemory());

		m_vertexModule				= createShaderModule	(vk, device, m_context.getBinaryCollection().get("vert"), 0u);
		m_fragmentModule			= createShaderModule	(vk, device, m_context.getBinaryCollection().get("frag"), 0u);
		m_renderPass				= makeRenderPass		(vk, device, colorFormat);
		m_framebuffer				= makeFramebuffer		(vk, device, *m_renderPass, m_colorAttachment.get(),
															 static_cast<deUint32>(m_renderSize.x()),
															 static_cast<deUint32>(m_renderSize.y()));
		m_pipelineLayout			= makePipelineLayout	(vk, device);

		generateDiscardRectangles(m_renderSize, m_params.numRectangles, m_rectangles);
		m_pipeline					= makeGraphicsPipeline	(vk, device, *m_pipelineLayout, *m_renderPass, *m_vertexModule, *m_fragmentModule, m_renderSize,
															 m_params.dynamicDiscardRectangles, discardRectangleMode, m_params.numRectangles,
															 m_rectangles.data(), m_params.scissorMode, rectScissor);
		m_cmdPool					= createCommandPool		(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
		m_cmdBuffer					= allocateCommandBuffer	(vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	}

	// Write command buffer and submit it
	{
		beginCommandBuffer(vk, *m_cmdBuffer);

		const VkClearValue			clearValue	= makeClearValueColor(m_clearColor);
		const VkRect2D				renderArea	=
		{
			makeOffset2D(0, 0),
			makeExtent2D(m_renderSize.x(), m_renderSize.y()),
		};
		const VkRenderPassBeginInfo renderPassBeginInfo =
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
			DE_NULL,										// const void*             pNext;
			*m_renderPass,									// VkRenderPass            renderPass;
			*m_framebuffer,									// VkFramebuffer           framebuffer;
			renderArea,										// VkRect2D                renderArea;
			1u,												// uint32_t                clearValueCount;
			&clearValue,									// const VkClearValue*     pClearValues;
		};
		vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);

		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
		{
			const VkBuffer vertexBuffer = m_vertexBuffer->object();
			const VkDeviceSize vertexBufferOffset = 0ull;
			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
		}
		if (m_params.dynamicDiscardRectangles)
		{
			vk.cmdSetDiscardRectangleEXT(*m_cmdBuffer, 0u, m_params.numRectangles, m_rectangles.data());
		}
		if (m_params.scissorMode == TEST_SCISSOR_MODE_DYNAMIC)
		{
			vk.cmdSetScissor(*m_cmdBuffer, 0u, 1u, &rectScissor);
		}
		vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_vertices.size()), 1u, 0u, 0u);	// two triangles
		vk.cmdEndRenderPass(*m_cmdBuffer);

		copyImageToBuffer(vk, *m_cmdBuffer, *m_colorImage, m_colorBuffer->object(), tcu::IVec2(m_renderSize.x(), m_renderSize.y()), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, colorSubresourceRange.layerCount);

		VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
		submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
	}

	// Verify results
	{
		const Allocation alloc = m_colorBuffer->getBoundMemory();
		invalidateMappedMemoryRange(vk, device, alloc.getMemory(), 0ull, colorBufferSize);

		const tcu::ConstPixelBufferAccess	resultImage		(mapVkFormat(colorFormat), m_renderSize.x(), m_renderSize.y(), 1u, alloc.getHostPtr());
		const tcu::TextureLevel				referenceImage	= generateReferenceImage(mapVkFormat(colorFormat), m_renderSize, m_params.testMode, m_clearColor,
																					 m_params.numRectangles, m_rectangles, m_params.scissorMode != TEST_SCISSOR_MODE_NONE, rectScissor);
		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceImage.getAccess(), resultImage, Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
			TCU_FAIL("Rendered image is not correct");
	}
	return tcu::TestStatus::pass("OK");
}

class DiscardRectanglesTestCase : public TestCase
{
public:
								DiscardRectanglesTestCase	(tcu::TestContext &context,
															 const char *name,
															 const char *description,
															 TestParams params);
	virtual						~DiscardRectanglesTestCase	(void) {};

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

private:
	const TestParams			m_params;
};

DiscardRectanglesTestCase::DiscardRectanglesTestCase	(tcu::TestContext &context,
														 const char *name,
														 const char *description,
														 TestParams params)
	: TestCase		(context, name, description)
	, m_params		(params)
{
}

void DiscardRectanglesTestCase::initPrograms(SourceCollections& programCollection) const
{
	// Vertex
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
			<< "\n"
			<< "layout(location = 0) in highp vec4 position;\n"
			<< "layout(location = 0) out highp vec4 vsColor;\n"
			<< "\n"
			<< "out gl_PerVertex {\n"
			<< "   vec4 gl_Position;\n"
			<< "};\n"
			<< "\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "    gl_Position = position;\n"
			<< "    vsColor     = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
			<< "}\n";
		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
	}

	// Fragment
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
			<< "\n"
			<< "layout(location = 0) in highp vec4 vsColor;\n"
			<< "layout(location = 0) out highp vec4 fsColor;\n"
			<< "\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "    fsColor     = vsColor;\n"
			<< "}\n";
		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
	}
}

void DiscardRectanglesTestCase::checkSupport (Context& context) const
{
	context.requireDeviceExtension("VK_EXT_discard_rectangles");
}

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

void createTests (tcu::TestCaseGroup* testGroup)
{
	tcu::TestContext&	testCtx											= testGroup->getTestContext();
	deUint32			numRect [NUM_RECT_TESTS]						= { 1, 2, 3, 4,  8, 16};
	std::string			modeName [TEST_MODE_COUNT]						= { "inclusive_", "exclusive_" };
	std::string			scissorName [TEST_SCISSOR_MODE_COUNT]			= { "", "scissor_", "dynamic_scissor_" };
	std::string			dynamicName [NUM_DYNAMIC_DISCARD_TYPE_TESTS]	= { "", "dynamic_discard_" };

	for (deUint32 dynamic = 0 ; dynamic < NUM_DYNAMIC_DISCARD_TYPE_TESTS; dynamic++)
	{
		for (deUint32 scissor = 0 ; scissor < TEST_SCISSOR_MODE_COUNT; scissor++)
		{
			for (deUint32 mode = 0; mode < TEST_MODE_COUNT; mode++)
			{
				for (deUint32 rect = 0; rect < NUM_RECT_TESTS; rect++)
				{
					std::ostringstream	name;
					TestParams			params;

					params.testMode						= (TestMode) mode;
					params.dynamicDiscardRectangles		= dynamic ? DE_TRUE : DE_FALSE;
					params.scissorMode					= (TestScissorMode) scissor;
					params.numRectangles				= numRect[rect];
					name << dynamicName[dynamic] << scissorName[scissor] << modeName[mode] << "rect_" << numRect[rect];

					testGroup->addChild(new DiscardRectanglesTestCase(testCtx, name.str().c_str(), "", params));
				}
			}
		}
	}
}
}	// Anonymous

tcu::TestCaseGroup* createDiscardRectanglesTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "discard_rectangles", "Discard Rectangles tests", createTests);
}

}	// Draw
}	//vkt
