#ifndef _VKTPIPELINEREFERENCERENDERER_HPP
#define _VKTPIPELINEREFERENCERENDERER_HPP
/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 Imagination Technologies Ltd.
 *
 * 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 Reference renderer.
 *//*--------------------------------------------------------------------*/

#include "vkDefs.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "tcuVector.hpp"
#include "tcuVectorType.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "rrRenderState.hpp"
#include "rrRenderer.hpp"
#include <cstring>

namespace vkt
{

namespace pipeline
{

tcu::Vec4	swizzle		(const tcu::Vec4& color, const tcu::UVec4& swizzle);

class ColorVertexShader : public rr::VertexShader
{
public:
	ColorVertexShader (void) : rr::VertexShader(2, 2)
	{
		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;

		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
		m_outputs[1].type	= rr::GENERICVECTYPE_FLOAT;
	}

	virtual ~ColorVertexShader (void) {}

	virtual void shadeVertices (const rr::VertexAttrib*		inputs,
								rr::VertexPacket* const*	packets,
								const int					numPackets) const
	{
		tcu::Vec4 position;
		tcu::Vec4 color;

		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
		{
			rr::VertexPacket* const packet	= packets[packetNdx];

			readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);
			readVertexAttrib(color, inputs[1], packet->instanceNdx, packet->vertexNdx);

			packet->outputs[0]	= position;
			packet->outputs[1]	= color;
			packet->position	= position;
		}
	}
};

class ColorVertexShaderDualSource : public rr::VertexShader
{
public:
	ColorVertexShaderDualSource (void) : rr::VertexShader(3, 3)
	{
		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
		m_inputs[2].type	= rr::GENERICVECTYPE_FLOAT;

		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
		m_outputs[1].type	= rr::GENERICVECTYPE_FLOAT;
		m_outputs[2].type	= rr::GENERICVECTYPE_FLOAT;
	}

	virtual ~ColorVertexShaderDualSource (void) {}

	virtual void shadeVertices (const rr::VertexAttrib*		inputs,
								rr::VertexPacket* const*	packets,
								const int					numPackets) const
	{
		tcu::Vec4 position;
		tcu::Vec4 color0;
		tcu::Vec4 color1;

		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
		{
			rr::VertexPacket* const packet	= packets[packetNdx];

			readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);
			readVertexAttrib(color0, inputs[1], packet->instanceNdx, packet->vertexNdx);
			readVertexAttrib(color1, inputs[2], packet->instanceNdx, packet->vertexNdx);

			packet->outputs[0]	= position;
			packet->outputs[1]	= color0;
			packet->outputs[2]	= color1;
			packet->position	= position;
		}
	}
};

class TexCoordVertexShader : public rr::VertexShader
{
public:
	TexCoordVertexShader (void) : rr::VertexShader(2, 2)
	{
		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;

		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
		m_outputs[1].type	= rr::GENERICVECTYPE_FLOAT;
	}

	virtual ~TexCoordVertexShader (void) {}

	virtual void shadeVertices (const rr::VertexAttrib*		inputs,
								rr::VertexPacket* const*	packets,
								const int					numPackets) const
	{
		tcu::Vec4 position;
		tcu::Vec4 texCoord;

		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
		{
			rr::VertexPacket* const packet	= packets[packetNdx];

			readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);
			readVertexAttrib(texCoord, inputs[1], packet->instanceNdx, packet->vertexNdx);

			packet->outputs[0]	= position;
			packet->outputs[1]	= texCoord;
			packet->position	= position;
		}
	}
};

class ColorFragmentShader : public rr::FragmentShader
{
private:
	const tcu::TextureFormat		m_colorFormat;
	const tcu::TextureFormat		m_depthStencilFormat;

public:
	ColorFragmentShader (const tcu::TextureFormat& colorFormat,
						 const tcu::TextureFormat& depthStencilFormat)
		: rr::FragmentShader	(2, 1)
		, m_colorFormat			(colorFormat)
		, m_depthStencilFormat	(depthStencilFormat)
	{
		const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type);

		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
		m_outputs[0].type	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)? rr::GENERICVECTYPE_INT32 :
							  (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? rr::GENERICVECTYPE_UINT32
							  : rr::GENERICVECTYPE_FLOAT;
	}

	virtual ~ColorFragmentShader (void) {}

	virtual void shadeFragments (rr::FragmentPacket*				packets,
								 const int							numPackets,
								 const rr::FragmentShadingContext&	context) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
		{
			const rr::FragmentPacket& packet = packets[packetNdx];

			if (m_depthStencilFormat.order == tcu::TextureFormat::D || m_depthStencilFormat.order == tcu::TextureFormat::DS)
			{
				for (int fragNdx = 0; fragNdx < 4; fragNdx++)
				{
					const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
					rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
				}
			}

			for (int fragNdx = 0; fragNdx < 4; fragNdx++)
			{
				const tcu::Vec4 vtxColor = rr::readVarying<float>(packet, context, 1, fragNdx);
				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxColor);
			}
		}
	}
};

class ColorFragmentShaderDualSource : public rr::FragmentShader
{
private:
	const tcu::TextureFormat		m_colorFormat;
	const tcu::TextureFormat		m_depthStencilFormat;

public:
	ColorFragmentShaderDualSource (const tcu::TextureFormat& colorFormat,
								   const tcu::TextureFormat& depthStencilFormat)
		: rr::FragmentShader	(3, 1)
		, m_colorFormat			(colorFormat)
		, m_depthStencilFormat	(depthStencilFormat)
	{
		const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type);

		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
		m_inputs[2].type	= rr::GENERICVECTYPE_FLOAT;

		m_outputs[0].type	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)? rr::GENERICVECTYPE_INT32 :
							  (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? rr::GENERICVECTYPE_UINT32
							  : rr::GENERICVECTYPE_FLOAT;
	}

	virtual ~ColorFragmentShaderDualSource (void) {}

	virtual void shadeFragments (rr::FragmentPacket*				packets,
								 const int							numPackets,
								 const rr::FragmentShadingContext&	context) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
		{
			const rr::FragmentPacket& packet = packets[packetNdx];

			if (m_depthStencilFormat.order == tcu::TextureFormat::D || m_depthStencilFormat.order == tcu::TextureFormat::DS)
			{
				for (int fragNdx = 0; fragNdx < 4; fragNdx++)
				{
					const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
					rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
				}
			}

			for (int fragNdx = 0; fragNdx < 4; fragNdx++)
			{
				const tcu::Vec4 vtxColor0 = rr::readVarying<float>(packet, context, 1, fragNdx);
				const tcu::Vec4 vtxColor1 = rr::readVarying<float>(packet, context, 2, fragNdx);
				rr::writeFragmentOutputDualSource(context, packetNdx, fragNdx, 0, vtxColor0, vtxColor1);
			}
		}
	}
};

class CoordinateCaptureFragmentShader : public rr::FragmentShader
{
public:
	CoordinateCaptureFragmentShader (void)
		: rr::FragmentShader(2, 1)
	{
		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
	}

	virtual ~CoordinateCaptureFragmentShader (void)
	{
	}

	virtual void shadeFragments (rr::FragmentPacket*				packets,
								 const int							numPackets,
								 const rr::FragmentShadingContext&	context) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
		{
			const rr::FragmentPacket& packet = packets[packetNdx];

			for (int fragNdx = 0; fragNdx < 4; fragNdx++)
			{
				const tcu::Vec4	vtxTexCoord	= rr::readVarying<float>(packet, context, 1, fragNdx);
				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxTexCoord);
			}
		}
	}
};

class Program
{
public:
	virtual ~Program (void) { }

	virtual rr::Program getReferenceProgram (void) const = 0;
};

class CoordinateCaptureProgram : public Program
{
private:
	TexCoordVertexShader			m_vertexShader;
	CoordinateCaptureFragmentShader	m_fragmentShader;
public:
	CoordinateCaptureProgram (void)
	{
	}

	virtual ~CoordinateCaptureProgram (void) { }

	virtual rr::Program getReferenceProgram (void) const
	{
		return rr::Program(&m_vertexShader, &m_fragmentShader);
	}
};

class ReferenceRenderer
{
public:
								ReferenceRenderer		(int							surfaceWidth,
														 int							surfaceHeight,
														 int							numSamples,
														 const tcu::TextureFormat&		colorFormat,
														 const tcu::TextureFormat&		depthStencilFormat,
														 const rr::Program* const		program);

	virtual						~ReferenceRenderer		(void);

	void						colorClear				(const tcu::Vec4& color);

	void						draw					(const rr::RenderState&				renderState,
														 const rr::PrimitiveType			primitive,
														 const std::vector<Vertex4RGBA>&	vertexBuffer);

	void						draw					(const rr::RenderState&					renderState,
														 const rr::PrimitiveType				primitive,
														 const std::vector<Vertex4RGBARGBA>&	vertexBuffer);

	void						draw					(const rr::RenderState&				renderState,
														 const rr::PrimitiveType			primitive,
														 const std::vector<Vertex4Tex4>&	vertexBuffer);

	tcu::PixelBufferAccess		getAccess				(void);
	tcu::PixelBufferAccess		getDepthStencilAccess	(void);
	const rr::ViewportState		getViewportState		(void) const;

private:
	rr::Renderer				m_renderer;

	const int					m_surfaceWidth;
	const int					m_surfaceHeight;
	const int					m_numSamples;

	const tcu::TextureFormat	m_colorFormat;
	const tcu::TextureFormat	m_depthStencilFormat;

	tcu::TextureLevel			m_colorBuffer;
	tcu::TextureLevel			m_resolveColorBuffer;
	tcu::TextureLevel			m_depthStencilBuffer;
	tcu::TextureLevel			m_resolveDepthStencilBuffer;

	rr::RenderTarget*			m_renderTarget;
	const rr::Program*			m_program;
};

rr::TestFunc					mapVkCompareOp				(vk::VkCompareOp compareFunc);
rr::PrimitiveType				mapVkPrimitiveTopology		(vk::VkPrimitiveTopology primitiveTopology);
rr::BlendFunc					mapVkBlendFactor			(vk::VkBlendFactor blendFactor);
rr::BlendEquation				mapVkBlendOp				(vk::VkBlendOp blendOp);
tcu::BVec4						mapVkColorComponentFlags	(vk::VkColorComponentFlags flags);
rr::StencilOp					mapVkStencilOp				(vk::VkStencilOp stencilOp);

} // pipeline
} // vkt

#endif // _VKTPIPELINEREFERENCERENDERER_HPP
