/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 The Khronos Group Inc.
 * 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 Scissor tests
 *//*--------------------------------------------------------------------*/

#include "vktFragmentOperationsScissorTests.hpp"
#include "vktFragmentOperationsScissorMultiViewportTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktFragmentOperationsMakeUtil.hpp"

#include "vkDefs.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPrograms.hpp"
#include "vkImageUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

#include "tcuTestLog.hpp"
#include "tcuVector.hpp"
#include "tcuImageCompare.hpp"

#include "deUniquePtr.hpp"
#include "deRandom.hpp"

namespace vkt
{
namespace FragmentOperations
{
using namespace vk;
using de::UniquePtr;
using de::MovePtr;
using tcu::Vec4;
using tcu::Vec2;
using tcu::IVec2;
using tcu::IVec4;

namespace
{

//! What primitives will be drawn by the test case.
enum TestPrimitive
{
	TEST_PRIMITIVE_POINTS,			//!< Many points.
	TEST_PRIMITIVE_LINES,			//!< Many short lines.
	TEST_PRIMITIVE_TRIANGLES,		//!< Many small triangles.
	TEST_PRIMITIVE_BIG_LINE,		//!< One line crossing the whole render area.
	TEST_PRIMITIVE_BIG_TRIANGLE,	//!< One triangle covering the whole render area.
};

struct VertexData
{
	Vec4	position;
	Vec4	color;
};

//! Parameters used by the test case.
struct CaseDef
{
	Vec4			renderArea;		//!< (ox, oy, w, h), where origin (0,0) is the top-left corner of the viewport. Width and height are in range [0, 1].
	Vec4			scissorArea;	//!< scissored area (ox, oy, w, h)
	TestPrimitive	primitive;
};

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

VkImageCreateInfo makeImageCreateInfo (const VkFormat format, const IVec2& 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;
}

Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&		vk,
									   const VkDevice				device,
									   const VkPipelineLayout		pipelineLayout,
									   const VkRenderPass			renderPass,
									   const VkShaderModule			vertexModule,
									   const VkShaderModule			fragmentModule,
									   const IVec2					renderSize,
									   const IVec4					scissorArea,	//!< (ox, oy, w, h)
									   const VkPrimitiveTopology	topology)
{
	const VkVertexInputBindingDescription vertexInputBindingDescription =
	{
		0u,								// uint32_t				binding;
		sizeof(VertexData),				// 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;
		},
		{
			1u,								// uint32_t		location;
			0u,								// uint32_t		binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat		format;
			sizeof(Vec4),					// 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 VkRect2D			scissor		=
	{
		makeOffset2D(scissorArea.x(), scissorArea.y()),
		makeExtent2D(scissorArea.z(), scissorArea.w())
	};

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

	return vk::makeGraphicsPipeline(vk,						// const DeviceInterface&                        vk
									device,					// const VkDevice                                device
									pipelineLayout,			// const VkPipelineLayout                        pipelineLayout
									vertexModule,			// const VkShaderModule                          vertexShaderModule
									DE_NULL,				// const VkShaderModule                          tessellationControlModule
									DE_NULL,				// const VkShaderModule                          tessellationEvalModule
									DE_NULL,				// const VkShaderModule                          geometryShaderModule
									fragmentModule,			// const VkShaderModule                          fragmentShaderModule
									renderPass,				// const VkRenderPass                            renderPass
									viewports,				// const std::vector<VkViewport>&                viewports
									scissors,				// const std::vector<VkRect2D>&                  scissors
									topology,				// const VkPrimitiveTopology                     topology
									0u,						// const deUint32                                subpass
									0u,						// const deUint32                                patchControlPoints
									&vertexInputStateInfo);	// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
}

inline VertexData makeVertex (const float x, const float y, const Vec4& color)
{
	const VertexData data = { Vec4(x, y, 0.0f, 1.0f), color };
	return data;
}

std::vector<VertexData> genVertices (const TestPrimitive primitive, const Vec4& renderArea, const Vec4& primitiveColor)
{
	std::vector<VertexData> vertices;
	de::Random				rng			(1234);

	const float	x0		= 2.0f * renderArea.x() - 1.0f;
	const float y0		= 2.0f * renderArea.y() - 1.0f;
	const float	rx		= 2.0f * renderArea.z();
	const float	ry		= 2.0f * renderArea.w();
	const float	size	= 0.2f;

	switch (primitive)
	{
		case TEST_PRIMITIVE_POINTS:
			for (int i = 0; i < 50; ++i)
			{
				const float x = x0 + rng.getFloat(0.0f, rx);
				const float y = y0 + rng.getFloat(0.0f, ry);
				vertices.push_back(makeVertex(x, y, primitiveColor));
			}
			break;

		case TEST_PRIMITIVE_LINES:
			for (int i = 0; i < 30; ++i)
			{
				const float x = x0 + rng.getFloat(0.0f, rx - size);
				const float y = y0 + rng.getFloat(0.0f, ry - size);
				vertices.push_back(makeVertex(x,        y,        primitiveColor));
				vertices.push_back(makeVertex(x + size, y + size, primitiveColor));
			}
			break;

		case TEST_PRIMITIVE_TRIANGLES:
			for (int i = 0; i < 20; ++i)
			{
				const float x = x0 + rng.getFloat(0.0f, rx - size);
				const float y = y0 + rng.getFloat(0.0f, ry - size);
				vertices.push_back(makeVertex(x,             y,        primitiveColor));
				vertices.push_back(makeVertex(x + size/2.0f, y + size, primitiveColor));
				vertices.push_back(makeVertex(x + size,      y,        primitiveColor));
			}
			break;

		case TEST_PRIMITIVE_BIG_LINE:
			vertices.push_back(makeVertex(x0,      y0,      primitiveColor));
			vertices.push_back(makeVertex(x0 + rx, y0 + ry, primitiveColor));
			break;

		case TEST_PRIMITIVE_BIG_TRIANGLE:
			vertices.push_back(makeVertex(x0,           y0,      primitiveColor));
			vertices.push_back(makeVertex(x0 + rx/2.0f, y0 + ry, primitiveColor));
			vertices.push_back(makeVertex(x0 + rx,      y0,      primitiveColor));
			break;
	}

	return vertices;
}

VkPrimitiveTopology	getTopology (const TestPrimitive primitive)
{
	switch (primitive)
	{
		case TEST_PRIMITIVE_POINTS:			return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;

		case TEST_PRIMITIVE_LINES:
		case TEST_PRIMITIVE_BIG_LINE:		return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;

		case TEST_PRIMITIVE_TRIANGLES:
		case TEST_PRIMITIVE_BIG_TRIANGLE:	return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

		default:
			DE_ASSERT(0);
			return VK_PRIMITIVE_TOPOLOGY_LAST;
	}
}

//! Transform from normalized coords to framebuffer space.
inline IVec4 getAreaRect (const Vec4& area, const int width, const int height)
{
	return IVec4(static_cast<deInt32>(static_cast<float>(width)  * area.x()),
				 static_cast<deInt32>(static_cast<float>(height) * area.y()),
				 static_cast<deInt32>(static_cast<float>(width)  * area.z()),
				 static_cast<deInt32>(static_cast<float>(height) * area.w()));
}

void applyScissor (tcu::PixelBufferAccess imageAccess, const Vec4& floatScissorArea, const Vec4& clearColor)
{
	const IVec4	scissorRect	(getAreaRect(floatScissorArea, imageAccess.getWidth(), imageAccess.getHeight()));
	const int	sx0			= scissorRect.x();
	const int	sx1			= scissorRect.x() + scissorRect.z();
	const int	sy0			= scissorRect.y();
	const int	sy1			= scissorRect.y() + scissorRect.w();

	for (int y = 0; y < imageAccess.getHeight(); ++y)
	for (int x = 0; x < imageAccess.getWidth(); ++x)
	{
		// Fragments outside fail the scissor test.
		if (x < sx0 || x >= sx1 || y < sy0 || y >= sy1)
			imageAccess.setPixel(clearColor, x, y);
	}
}

void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
{
	DE_UNREF(caseDef);

	// Vertex shader
	{
		const bool usePointSize = (caseDef.primitive == TEST_PRIMITIVE_POINTS);

		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "\n"
			<< "layout(location = 0) in  vec4 in_position;\n"
			<< "layout(location = 1) in  vec4 in_color;\n"
			<< "layout(location = 0) out vec4 o_color;\n"
			<< "\n"
			<< "out gl_PerVertex {\n"
			<< "    vec4  gl_Position;\n"
			<< (usePointSize ? "    float gl_PointSize;\n" : "")
			<< "};\n"
			<< "\n"
			<< "void main(void)\n"
			<< "{\n"
			<< "    gl_Position  = in_position;\n"
			<< (usePointSize ? "    gl_PointSize = 1.0;\n" : "")
			<< "    o_color      = in_color;\n"
			<< "}\n";

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

	// Fragment shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "\n"
			<< "layout(location = 0) in  vec4 in_color;\n"
			<< "layout(location = 0) out vec4 o_color;\n"
			<< "\n"
			<< "void main(void)\n"
			<< "{\n"
			<< "    o_color = in_color;\n"
			<< "}\n";

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

class ScissorRenderer
{
public:
	ScissorRenderer (Context& context, const CaseDef caseDef, const IVec2& renderSize, const VkFormat colorFormat, const Vec4& primitiveColor, const Vec4& clearColor)
		: m_renderSize				(renderSize)
		, m_colorFormat				(colorFormat)
		, m_colorSubresourceRange	(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
		, m_primitiveColor			(primitiveColor)
		, m_clearColor				(clearColor)
		, m_vertices				(genVertices(caseDef.primitive, caseDef.renderArea, m_primitiveColor))
		, m_vertexBufferSize		(sizeInBytes(m_vertices))
		, m_topology				(getTopology(caseDef.primitive))
	{
		const DeviceInterface&		vk					= context.getDeviceInterface();
		const VkDevice				device				= context.getDevice();
		const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
		Allocator&					allocator			= context.getDefaultAllocator();

		m_colorImage			= makeImage(vk, device, makeImageCreateInfo(m_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_colorAttachment		= makeImageView(vk, device, *m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_colorFormat, m_colorSubresourceRange);

		m_vertexBuffer			= makeBuffer(vk, device, m_vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
		m_vertexBufferAlloc		= bindBuffer(vk, device, allocator, *m_vertexBuffer, MemoryRequirement::HostVisible);

		{
			deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], static_cast<std::size_t>(m_vertexBufferSize));
			flushAlloc(vk, device, *m_vertexBufferAlloc);
		}

		m_vertexModule				= createShaderModule	(vk, device, context.getBinaryCollection().get("vert"), 0u);
		m_fragmentModule			= createShaderModule	(vk, device, context.getBinaryCollection().get("frag"), 0u);
		m_renderPass				= makeRenderPass		(vk, device, m_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);
		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);

	}

	void draw (Context& context, const Vec4& scissorAreaFloat, const VkBuffer colorBuffer) const
	{
		const DeviceInterface&		vk			= context.getDeviceInterface();
		const VkDevice				device		= context.getDevice();
		const VkQueue				queue		= context.getUniversalQueue();

		// New pipeline, because we're modifying scissor (we don't use dynamic state).
		const Unique<VkPipeline>	pipeline	(makeGraphicsPipeline(vk, device, *m_pipelineLayout, *m_renderPass, *m_vertexModule, *m_fragmentModule,
												 m_renderSize, getAreaRect(scissorAreaFloat, m_renderSize.x(), m_renderSize.y()), m_topology));

		beginCommandBuffer(vk, *m_cmdBuffer);

		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), m_clearColor);

		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
		{
			const VkDeviceSize vertexBufferOffset = 0ull;
			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
		}

		vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_vertices.size()), 1u, 0u, 0u);
		endRenderPass(vk, *m_cmdBuffer);

		copyImageToBuffer(vk, *m_cmdBuffer, *m_colorImage, colorBuffer, m_renderSize);

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

private:
	const IVec2						m_renderSize;
	const VkFormat					m_colorFormat;
	const VkImageSubresourceRange	m_colorSubresourceRange;
	const Vec4						m_primitiveColor;
	const Vec4						m_clearColor;
	const std::vector<VertexData>	m_vertices;
	const VkDeviceSize				m_vertexBufferSize;
	const VkPrimitiveTopology		m_topology;

	Move<VkImage>					m_colorImage;
	MovePtr<Allocation>				m_colorImageAlloc;
	Move<VkImageView>				m_colorAttachment;
	Move<VkBuffer>					m_vertexBuffer;
	MovePtr<Allocation>				m_vertexBufferAlloc;
	Move<VkShaderModule>			m_vertexModule;
	Move<VkShaderModule>			m_fragmentModule;
	Move<VkRenderPass>				m_renderPass;
	Move<VkFramebuffer>				m_framebuffer;
	Move<VkPipelineLayout>			m_pipelineLayout;
	Move<VkCommandPool>				m_cmdPool;
	Move<VkCommandBuffer>			m_cmdBuffer;

	// "deleted"
						ScissorRenderer	(const ScissorRenderer&);
	ScissorRenderer&	operator=		(const ScissorRenderer&);
};

tcu::TestStatus test (Context& context, const CaseDef caseDef)
{
	const DeviceInterface&			vk							= context.getDeviceInterface();
	const VkDevice					device						= context.getDevice();
	Allocator&						allocator					= context.getDefaultAllocator();

	const IVec2						renderSize					(128, 128);
	const VkFormat					colorFormat					= VK_FORMAT_R8G8B8A8_UNORM;
	const Vec4						scissorFullArea				(0.0f, 0.0f, 1.0f, 1.0f);
	const Vec4						primitiveColor				(1.0f, 1.0f, 1.0f, 1.0f);
	const Vec4						clearColor					(0.5f, 0.5f, 1.0f, 1.0f);

	const VkDeviceSize				colorBufferSize				= renderSize.x() * renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
	const Unique<VkBuffer>			colorBufferFull				(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>		colorBufferFullAlloc		(bindBuffer(vk, device, allocator, *colorBufferFull, MemoryRequirement::HostVisible));

	const Unique<VkBuffer>			colorBufferScissored		(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>		colorBufferScissoredAlloc	(bindBuffer(vk, device, allocator, *colorBufferScissored, MemoryRequirement::HostVisible));

	zeroBuffer(vk, device, *colorBufferFullAlloc, colorBufferSize);
	zeroBuffer(vk, device, *colorBufferScissoredAlloc, colorBufferSize);

	// Draw
	{
		const ScissorRenderer renderer (context, caseDef, renderSize, colorFormat, primitiveColor, clearColor);

		renderer.draw(context, scissorFullArea, *colorBufferFull);
		renderer.draw(context, caseDef.scissorArea, *colorBufferScissored);
	}

	// Log image
	{
		invalidateAlloc(vk, device, *colorBufferFullAlloc);
		invalidateAlloc(vk, device, *colorBufferScissoredAlloc);

		const tcu::ConstPixelBufferAccess	resultImage		(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1u, colorBufferScissoredAlloc->getHostPtr());
		tcu::PixelBufferAccess				referenceImage	(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1u, colorBufferFullAlloc->getHostPtr());

		// Apply scissor to the full image, so we can compare it with the result image.
		applyScissor (referenceImage, caseDef.scissorArea, clearColor);

		// Images should now match.
		if (!tcu::floatThresholdCompare(context.getTestContext().getLog(), "color", "Image compare", referenceImage, resultImage, Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
			return tcu::TestStatus::fail("Rendered image is not correct");
	}

	return tcu::TestStatus::pass("OK");
}

//! \note The ES 2.0 scissoring tests included color/depth/stencil clear cases, but these operations are not affected by scissor test in Vulkan.
//!       Scissor is part of the pipeline state and pipeline only affects the drawing commands.
void createTestsInGroup (tcu::TestCaseGroup* scissorGroup)
{
	tcu::TestContext& testCtx = scissorGroup->getTestContext();

	struct TestSpec
	{
		const char*		name;
		const char*		description;
		CaseDef			caseDef;
	};

	const Vec4	areaFull			(0.0f, 0.0f, 1.0f, 1.0f);
	const Vec4	areaCropped			(0.2f, 0.2f, 0.6f, 0.6f);
	const Vec4	areaCroppedMore		(0.4f, 0.4f, 0.2f, 0.2f);
	const Vec4	areaLeftHalf		(0.0f, 0.0f, 0.5f, 1.0f);
	const Vec4	areaRightHalf		(0.5f, 0.0f, 0.5f, 1.0f);

	// Points
	{
		MovePtr<tcu::TestCaseGroup> primitiveGroup (new tcu::TestCaseGroup(testCtx, "points", ""));

		const TestSpec	cases[] =
		{
			{ "inside",				"Points fully inside the scissor area",		{ areaFull,		areaFull,		TEST_PRIMITIVE_POINTS } },
			{ "partially_inside",	"Points partially inside the scissor area",	{ areaFull,		areaCropped,	TEST_PRIMITIVE_POINTS } },
			{ "outside",			"Points fully outside the scissor area",	{ areaLeftHalf,	areaRightHalf,	TEST_PRIMITIVE_POINTS } },
		};

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
			addFunctionCaseWithPrograms(primitiveGroup.get(), cases[i].name, cases[i].description, initPrograms, test, cases[i].caseDef);

		scissorGroup->addChild(primitiveGroup.release());
	}

	// Lines
	{
		MovePtr<tcu::TestCaseGroup> primitiveGroup (new tcu::TestCaseGroup(testCtx, "lines", ""));

		const TestSpec	cases[] =
		{
			{ "inside",				"Lines fully inside the scissor area",		{ areaFull,		areaFull,			TEST_PRIMITIVE_LINES	} },
			{ "partially_inside",	"Lines partially inside the scissor area",	{ areaFull,		areaCropped,		TEST_PRIMITIVE_LINES	} },
			{ "outside",			"Lines fully outside the scissor area",		{ areaLeftHalf,	areaRightHalf,		TEST_PRIMITIVE_LINES	} },
			{ "crossing",			"A line crossing the scissor area",			{ areaFull,		areaCroppedMore,	TEST_PRIMITIVE_BIG_LINE	} },
		};

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
			addFunctionCaseWithPrograms(primitiveGroup.get(), cases[i].name, cases[i].description, initPrograms, test, cases[i].caseDef);

		scissorGroup->addChild(primitiveGroup.release());
	}

	// Triangles
	{
		MovePtr<tcu::TestCaseGroup> primitiveGroup (new tcu::TestCaseGroup(testCtx, "triangles", ""));

		const TestSpec	cases[] =
		{
			{ "inside",				"Triangles fully inside the scissor area",		{ areaFull,		areaFull,			TEST_PRIMITIVE_TRIANGLES	} },
			{ "partially_inside",	"Triangles partially inside the scissor area",	{ areaFull,		areaCropped,		TEST_PRIMITIVE_TRIANGLES	} },
			{ "outside",			"Triangles fully outside the scissor area",		{ areaLeftHalf,	areaRightHalf,		TEST_PRIMITIVE_TRIANGLES	} },
			{ "crossing",			"A triangle crossing the scissor area",			{ areaFull,		areaCroppedMore,	TEST_PRIMITIVE_BIG_TRIANGLE	} },
		};

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
			addFunctionCaseWithPrograms(primitiveGroup.get(), cases[i].name, cases[i].description, initPrograms, test, cases[i].caseDef);

		scissorGroup->addChild(primitiveGroup.release());
	}

	// Mulit-viewport scissor
	{
		scissorGroup->addChild(createScissorMultiViewportTests(testCtx));
	}
}

} // anonymous

tcu::TestCaseGroup* createScissorTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "scissor", "Scissor tests", createTestsInGroup);
}

} // FragmentOperations
} // vkt
