#ifndef _RRSHADINGCONTEXT_HPP
#define _RRSHADINGCONTEXT_HPP
/*-------------------------------------------------------------------------
 * drawElements Quality Program Reference Renderer
 * -----------------------------------------------
 *
 * Copyright 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 Shading context
 *//*--------------------------------------------------------------------*/

#include "rrDefs.hpp"
#include "rrGenericVector.hpp"
#include "rrFragmentPacket.hpp"

namespace rr
{

/*--------------------------------------------------------------------*//*!
 * \brief Fragment shading context
 *
 * Contains per-primitive information used in fragment shading
 *//*--------------------------------------------------------------------*/
struct FragmentShadingContext
{
								FragmentShadingContext (const GenericVec4* varying0, const GenericVec4* varying1, const GenericVec4* varying2, GenericVec4* outputArray, float* fragmentDepths, int primitiveID, int numFragmentOutputs, int numSamples);

	const GenericVec4*			varyings[3];		//!< Vertex shader outputs. Pointer will be NULL if there is no such vertex.
	GenericVec4* const			outputArray;		//!< Fragment output array
	const int					primitiveID;		//!< Geometry shader output
	const int					numFragmentOutputs;	//!< Fragment output count
	const int					numSamples;			//!< Number of samples
	float*						fragmentDepths;		//!< Fragment packet depths. Pointer will be NULL if there is no depth buffer. Each sample has per-sample depth values
};

// Write output

template <typename T>
void writeFragmentOutput (const FragmentShadingContext& context, int packetNdx, int fragNdx, int outputNdx, const T& value)
{
	DE_ASSERT(packetNdx >= 0);
	DE_ASSERT(fragNdx >= 0 && fragNdx < 4);
	DE_ASSERT(outputNdx >= 0 && outputNdx < context.numFragmentOutputs);

	context.outputArray[outputNdx + context.numFragmentOutputs*(fragNdx + packetNdx*4)] = value;
}

// Read Varying

template <typename T>
tcu::Vector<T, 4> readPointVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
{
	DE_UNREF(fragNdx);
	DE_UNREF(packet);

	return context.varyings[0][varyingLoc].get<T>();
}

template <typename T>
tcu::Vector<T, 4> readLineVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
{
	return   packet.barycentric[0][fragNdx] * context.varyings[0][varyingLoc].get<T>()
		   + packet.barycentric[1][fragNdx] * context.varyings[1][varyingLoc].get<T>();
}

template <typename T>
tcu::Vector<T, 4> readTriangleVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
{
	return   packet.barycentric[0][fragNdx] * context.varyings[0][varyingLoc].get<T>()
		   + packet.barycentric[1][fragNdx] * context.varyings[1][varyingLoc].get<T>()
		   + packet.barycentric[2][fragNdx] * context.varyings[2][varyingLoc].get<T>();
}

template <typename T>
tcu::Vector<T, 4> readVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
{
	if (context.varyings[1] == DE_NULL)	return readPointVarying<T>		(packet, context, varyingLoc, fragNdx);
	if (context.varyings[2] == DE_NULL)	return readLineVarying<T>		(packet, context, varyingLoc, fragNdx);
										return readTriangleVarying<T>	(packet, context, varyingLoc, fragNdx);
}

// Derivative

template <typename T, int Size>
void dFdxLocal (tcu::Vector<T, Size> outFragmentdFdx[4], const tcu::Vector<T, Size> func[4])
{
	const tcu::Vector<T, Size> dFdx[2] =
	{
		func[1] - func[0],
		func[3] - func[2]
	};

	outFragmentdFdx[0] = dFdx[0];
	outFragmentdFdx[1] = dFdx[0];
	outFragmentdFdx[2] = dFdx[1];
	outFragmentdFdx[3] = dFdx[1];
}

template <typename T, int Size>
void dFdyLocal (tcu::Vector<T, Size> outFragmentdFdy[4], const tcu::Vector<T, Size> func[4])
{
	const tcu::Vector<T, Size> dFdy[2] =
	{
		func[2] - func[0],
		func[3] - func[1]
	};

	outFragmentdFdy[0] = dFdy[0];
	outFragmentdFdy[1] = dFdy[1];
	outFragmentdFdy[2] = dFdy[0];
	outFragmentdFdy[3] = dFdy[1];
}

template <typename T>
inline void dFdxVarying (tcu::Vector<T, 4> outFragmentdFdx[4], const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc)
{
	const tcu::Vector<T, 4> func[4] =
	{
		readVarying<T>(packet, context, varyingLoc, 0),
		readVarying<T>(packet, context, varyingLoc, 1),
		readVarying<T>(packet, context, varyingLoc, 2),
		readVarying<T>(packet, context, varyingLoc, 3),
	};

	dFdxLocal(outFragmentdFdx, func);
}

template <typename T>
inline void dFdyVarying (tcu::Vector<T, 4> outFragmentdFdy[4], const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc)
{
	const tcu::Vector<T, 4> func[4] =
	{
		readVarying<T>(packet, context, varyingLoc, 0),
		readVarying<T>(packet, context, varyingLoc, 1),
		readVarying<T>(packet, context, varyingLoc, 2),
		readVarying<T>(packet, context, varyingLoc, 3),
	};

	dFdyLocal(outFragmentdFdy, func);
}

// Fragent depth

inline float readFragmentDepth (const FragmentShadingContext& context, int packetNdx, int fragNdx, int sampleNdx)
{
	// Reading or writing to fragment depth values while there is no depth buffer is legal but not supported by rr
	DE_ASSERT(context.fragmentDepths);
	return context.fragmentDepths[(packetNdx * 4 + fragNdx) * context.numSamples + sampleNdx];
}

inline void writeFragmentDepth (const FragmentShadingContext& context, int packetNdx, int fragNdx, int sampleNdx, float depthValue)
{
	// Reading or writing to fragment depth values while there is no depth buffer is legal but not supported by rr
	DE_ASSERT(context.fragmentDepths);
	context.fragmentDepths[(packetNdx * 4 + fragNdx) * context.numSamples + sampleNdx] = depthValue;
}

} // rr

#endif // _RRSHADINGCONTEXT_HPP
