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

#include "vktGeometryInputGeometryShaderTests.hpp"
#include "vktGeometryBasicClass.hpp"
#include "vktGeometryTestsUtil.hpp"

#include "vkDefs.hpp"
#include "vktTestCase.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkPrograms.hpp"
#include "vkBuilderUtil.hpp"

#include "vkRefUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkMemUtil.hpp"

#include <string>

using namespace vk;

namespace vkt
{
namespace geometry
{
namespace
{
using tcu::Vec4;
using tcu::TestStatus;
using tcu::TestContext;
using tcu::TestCaseGroup;
using de::MovePtr;
using std::string;
using std::vector;

class GeometryInputTestInstance : public GeometryExpanderRenderTestInstance
{
public:
			GeometryInputTestInstance	(Context&					context,
										 const VkPrimitiveTopology	primitiveType,
										 const char*				name);

			GeometryInputTestInstance	(Context&					context,
										 const VkPrimitiveTopology	primitiveType,
										 const char*				name,
										 const int					numDrawVertices);

	void	genVertexAttribData			(void);
};

GeometryInputTestInstance::GeometryInputTestInstance	(Context&						context,
														 const VkPrimitiveTopology		primitiveType,
														 const char*					name)
	: GeometryExpanderRenderTestInstance	(context, primitiveType, name)
{
	genVertexAttribData();
}

GeometryInputTestInstance::GeometryInputTestInstance	(Context&					context,
														 const VkPrimitiveTopology	primitiveType,
														 const char*				name,
														 const int					numDrawVertices)
	: GeometryExpanderRenderTestInstance	(context, primitiveType, name)
{
	genVertexAttribData();
	m_numDrawVertices = numDrawVertices;
}

void GeometryInputTestInstance::genVertexAttribData (void)
{
	// Create 1 X 2 grid in triangle strip adjacent - order
	const float	scale	= 0.3f;
	const Vec4	offset	(-0.5f, -0.2f, 0.0f, 1.0f);
	m_numDrawVertices	= 12;

	m_vertexPosData.resize(m_numDrawVertices);
	m_vertexPosData[ 0] = Vec4( 0,  0, 0.0f, 0.0f) * scale + offset;
	m_vertexPosData[ 1] = Vec4(-1, -1, 0.0f, 0.0f) * scale + offset;
	m_vertexPosData[ 2] = Vec4( 0, -1, 0.0f, 0.0f) * scale + offset;
	m_vertexPosData[ 3] = Vec4( 1,  1, 0.0f, 0.0f) * scale + offset;
	m_vertexPosData[ 4] = Vec4( 1,  0, 0.0f, 0.0f) * scale + offset;
	m_vertexPosData[ 5] = Vec4( 0, -2, 0.0f, 0.0f) * scale + offset;
	m_vertexPosData[ 6] = Vec4( 1, -1, 0.0f, 0.0f) * scale + offset;
	m_vertexPosData[ 7] = Vec4( 2,  1, 0.0f, 0.0f) * scale + offset;
	m_vertexPosData[ 8] = Vec4( 2,  0, 0.0f, 0.0f) * scale + offset;
	m_vertexPosData[ 9] = Vec4( 1, -2, 0.0f, 0.0f) * scale + offset;
	m_vertexPosData[10] = Vec4( 2, -1, 0.0f, 0.0f) * scale + offset;
	m_vertexPosData[11] = Vec4( 3,  0, 0.0f, 0.0f) * scale + offset;

	// Red and white
	m_vertexAttrData.resize(m_numDrawVertices);
	for (int i = 0; i < m_numDrawVertices; ++i)
		m_vertexAttrData[i] = (i % 2 == 0) ? Vec4(1, 1, 1, 1) : Vec4(1, 0, 0, 1);
}

class GeometryExpanderRenderTest : public TestCase
{
public:
								GeometryExpanderRenderTest	(TestContext&				testCtx,
															 const PrimitiveTestSpec&	inputPrimitives);

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

protected:
	string						shaderGeometry				(bool						pointSize) const;
	const VkPrimitiveTopology	m_primitiveType;
	const VkPrimitiveTopology	m_outputType;
};

GeometryExpanderRenderTest::GeometryExpanderRenderTest (TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives)
	: TestCase			(testCtx, inputPrimitives.name, inputPrimitives.name)
	, m_primitiveType	(inputPrimitives.primitiveType)
	, m_outputType		(inputPrimitives.outputType)
{

}

void GeometryExpanderRenderTest::checkSupport (Context& context) const
{
	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);

	if (m_primitiveType == vk::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");
	}
}

void GeometryExpanderRenderTest::initPrograms (SourceCollections& sourceCollections) const
{
	{
		std::ostringstream src;
		src	<< "#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) out highp vec4 v_geom_FragColor;\n"
			<<"void main (void)\n"
			<<"{\n"
			<<"	gl_Position = a_position;\n"
			<<"	v_geom_FragColor = a_color;\n"
			<<"}\n";
		sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
	}

	{
		sourceCollections.glslSources.add("geometry") << glu::GeometrySource(shaderGeometry(false));
		if (m_outputType == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
			sourceCollections.glslSources.add("geometry_pointsize") << glu::GeometrySource(shaderGeometry(true));
	}

	{
		std::ostringstream src;
		src	<< "#version 310 es\n"
			<<"layout(location = 0) out highp vec4 fragColor;\n"
			<<"layout(location = 0) in highp vec4 v_frag_FragColor;\n"
			<<"void main (void)\n"
			<<"{\n"
			<<"	fragColor = v_frag_FragColor;\n"
			<<"}\n";
		sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
	}
}

TestInstance* GeometryExpanderRenderTest::createInstance (Context& context) const
{
	return new GeometryInputTestInstance(context, m_primitiveType, getName());
}

string GeometryExpanderRenderTest::shaderGeometry (bool pointSize) const
{
	std::ostringstream src;
	src	<< "#version 310 es\n"
		<< "#extension GL_EXT_geometry_shader : require\n";
	if (pointSize)
		src	<<"#extension GL_EXT_geometry_point_size : require\n";
	src	<< "layout(" << inputTypeToGLString(m_primitiveType) << ") in;\n"
		<< "layout(" << outputTypeToGLString(m_outputType) << ", max_vertices = " << calcOutputVertices(m_primitiveType) << ") out;\n"
		<< "layout(location = 0) in highp vec4 v_geom_FragColor[];\n"
		<< "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
		<< "\n"
		<< "void main (void)\n"
		<< "{\n"
		<< "	const highp vec4 offset0 = vec4(-0.07, -0.01, 0.0, 0.0);\n"
		<< "	const highp vec4 offset1 = vec4( 0.03, -0.03, 0.0, 0.0);\n"
		<< "	const highp vec4 offset2 = vec4(-0.01,  0.08, 0.0, 0.0);\n"
		<< "	highp vec4 yoffset = float(gl_PrimitiveIDIn) * vec4(0.02, 0.1, 0.0, 0.0);\n"
		<< "\n"
		<< "	for (highp int ndx = 0; ndx < gl_in.length(); ndx++)\n"
		<< "	{\n";
		if (pointSize)
			src	<< "		gl_PointSize = 1.0;\n";
	src	<< "		gl_Position = gl_in[ndx].gl_Position + offset0 + yoffset;\n"
		<< "		v_frag_FragColor = v_geom_FragColor[ndx];\n"
		<< "		EmitVertex();\n"
		<< "\n";
		if (pointSize)
			src	<< "		gl_PointSize = 1.0;\n";
	src	<< "		gl_Position = gl_in[ndx].gl_Position + offset1 + yoffset;\n"
		<< "		v_frag_FragColor = v_geom_FragColor[ndx];\n"
		<< "		EmitVertex();\n"
		<< "\n";
		if (pointSize)
			src	<< "		gl_PointSize = 1.0;\n";
	src	<< "		gl_Position = gl_in[ndx].gl_Position + offset2 + yoffset;\n"
		<< "		v_frag_FragColor = v_geom_FragColor[ndx];\n"
		<< "		EmitVertex();\n"
		<< "		EndPrimitive();\n"
		<< "	}\n"
		<< "}\n";
	return src.str();
}

class TriangleStripAdjacencyVertexCountTest : public GeometryExpanderRenderTest
{
public:
							TriangleStripAdjacencyVertexCountTest	(TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives, const int numInputVertices);
	virtual TestInstance*	createInstance							(Context& context) const;
private:
	const int	m_numInputVertices;
};

TriangleStripAdjacencyVertexCountTest::TriangleStripAdjacencyVertexCountTest (TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives, const int numInputVertices)
	: GeometryExpanderRenderTest	(testCtx, inputPrimitives)
	, m_numInputVertices			(numInputVertices)
{
}

TestInstance* TriangleStripAdjacencyVertexCountTest::createInstance (Context& context) const
{
	return new GeometryInputTestInstance(context, m_primitiveType, getName(), m_numInputVertices);
}

} // anonymous

TestCaseGroup* createInputGeometryShaderTests (TestContext& testCtx)
{
	MovePtr<TestCaseGroup> inputPrimitiveGroup		(new TestCaseGroup(testCtx, "input", "Different input primitives."));
	MovePtr<TestCaseGroup> basicPrimitiveGroup		(new TestCaseGroup(testCtx, "basic_primitive", "Basic Primitive geometry tests"));
	MovePtr<TestCaseGroup> triStripAdjacencyGroup	(new TestCaseGroup(testCtx, "triangle_strip_adjacency",	"Different triangle_strip_adjacency vertex counts."));
	MovePtr<TestCaseGroup> conversionPrimitiveGroup	(new TestCaseGroup(testCtx, "conversion", "Different input and output primitives."));

	const PrimitiveTestSpec inputPrimitives[] =
	{
		{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,						"points",					VK_PRIMITIVE_TOPOLOGY_POINT_LIST		},
		{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST,						"lines",					VK_PRIMITIVE_TOPOLOGY_LINE_STRIP		},
		{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,						"line_strip",				VK_PRIMITIVE_TOPOLOGY_LINE_STRIP		},
		{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,					"triangles",				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP	},
		{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,					"triangle_strip",			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP	},
		{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,					"triangle_fan",				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP	},
		{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,		"lines_adjacency",			VK_PRIMITIVE_TOPOLOGY_LINE_STRIP		},
		{ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,		"line_strip_adjacency",		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP		},
		{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,	"triangles_adjacency",		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP	}
	};

		// more basic types
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(inputPrimitives); ++ndx)
			basicPrimitiveGroup->addChild(new GeometryExpanderRenderTest(testCtx, inputPrimitives[ndx]));

		// triangle strip adjacency with different vertex counts
		for (int vertexCount = 0; vertexCount <= 12; ++vertexCount)
		{
			const string name = "vertex_count_" + de::toString(vertexCount);
			const PrimitiveTestSpec primitives = { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, name.c_str(), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };

			triStripAdjacencyGroup->addChild(new TriangleStripAdjacencyVertexCountTest(testCtx, primitives, vertexCount));
		}

		// different type conversions
		{
			static const PrimitiveTestSpec conversionPrimitives[] =
			{
				{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	"triangles_to_points",	VK_PRIMITIVE_TOPOLOGY_POINT_LIST	},
				{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		"lines_to_points",		VK_PRIMITIVE_TOPOLOGY_POINT_LIST	},
				{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,		"points_to_lines",		VK_PRIMITIVE_TOPOLOGY_LINE_STRIP	},
				{ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	"triangles_to_lines",	VK_PRIMITIVE_TOPOLOGY_LINE_STRIP	},
				{ VK_PRIMITIVE_TOPOLOGY_POINT_LIST,		"points_to_triangles",	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP},
				{ VK_PRIMITIVE_TOPOLOGY_LINE_LIST,		"lines_to_triangles",	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP}
			};

			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(conversionPrimitives); ++ndx)
				conversionPrimitiveGroup->addChild(new GeometryExpanderRenderTest(testCtx, conversionPrimitives[ndx]));
		}

	inputPrimitiveGroup->addChild(basicPrimitiveGroup.release());
	inputPrimitiveGroup->addChild(triStripAdjacencyGroup.release());
	inputPrimitiveGroup->addChild(conversionPrimitiveGroup.release());
	return inputPrimitiveGroup.release();
}

} // geometry
} // vkt
