/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 Module
 * -------------------------------------------------
 *
 * 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 gl_FragDepth tests.
 *//*--------------------------------------------------------------------*/

#include "es3fFragDepthTests.hpp"
#include "tcuVector.hpp"
#include "tcuTestLog.hpp"
#include "tcuSurface.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderProgram.hpp"
#include "gluDrawUtil.hpp"
#include "deRandom.hpp"
#include "deMath.h"
#include "deString.h"

// For setupDefaultUniforms()
#include "glsShaderRenderCase.hpp"

#include "glwEnums.hpp"
#include "glwFunctions.hpp"

namespace deqp
{
namespace gles3
{
namespace Functional
{

using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::TestLog;
using std::string;
using std::vector;

typedef float (*EvalFragDepthFunc) (const Vec2& coord);

static const char* s_vertexShaderSrc =
	"#version 300 es\n"
	"in highp vec4 a_position;\n"
	"in highp vec2 a_coord;\n"
	"out highp vec2 v_coord;\n"
	"void main (void)\n"
	"{\n"
	"	gl_Position = a_position;\n"
	"	v_coord = a_coord;\n"
	"}\n";
static const char* s_defaultFragmentShaderSrc =
	"#version 300 es\n"
	"uniform highp vec4 u_color;\n"
	"layout(location = 0) out mediump vec4 o_color;\n"
	"void main (void)\n"
	"{\n"
	"	o_color = u_color;\n"
	"}\n";

template <typename T>
static inline bool compare (deUint32 func, T a, T b)
{
	switch (func)
	{
		case GL_NEVER:		return false;
		case GL_ALWAYS:		return true;
		case GL_LESS:		return a < b;
		case GL_LEQUAL:		return a <= b;
		case GL_EQUAL:		return a == b;
		case GL_NOTEQUAL:	return a != b;
		case GL_GEQUAL:		return a >= b;
		case GL_GREATER:	return a > b;
		default:
			DE_ASSERT(DE_FALSE);
			return false;
	}
}

class FragDepthCompareCase : public TestCase
{
public:
							FragDepthCompareCase	(Context& context, const char* name, const char* desc, const char* fragSrc, EvalFragDepthFunc evalFunc, deUint32 compareFunc);
							~FragDepthCompareCase	(void);

	IterateResult			iterate					(void);

private:
	string					m_fragSrc;
	EvalFragDepthFunc		m_evalFunc;
	deUint32				m_compareFunc;
};

FragDepthCompareCase::FragDepthCompareCase (Context& context, const char* name, const char* desc, const char* fragSrc, EvalFragDepthFunc evalFunc, deUint32 compareFunc)
	: TestCase			(context, name, desc)
	, m_fragSrc			(fragSrc)
	, m_evalFunc		(evalFunc)
	, m_compareFunc		(compareFunc)
{
}

FragDepthCompareCase::~FragDepthCompareCase (void)
{
}

FragDepthCompareCase::IterateResult FragDepthCompareCase::iterate (void)
{
	TestLog&					log				= m_testCtx.getLog();
	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
	de::Random					rnd				(deStringHash(getName()));
	const tcu::RenderTarget&	renderTarget	= m_context.getRenderContext().getRenderTarget();
	int							viewportW		= de::min(128, renderTarget.getWidth());
	int							viewportH		= de::min(128, renderTarget.getHeight());
	int							viewportX		= rnd.getInt(0, renderTarget.getWidth()-viewportW);
	int							viewportY		= rnd.getInt(0, renderTarget.getHeight()-viewportH);
	tcu::Surface				renderedFrame	(viewportW, viewportH);
	tcu::Surface				referenceFrame	(viewportW, viewportH);
	const float					constDepth		= 0.1f;

	if (renderTarget.getDepthBits() == 0)
		throw tcu::NotSupportedError("Depth buffer is required", "", __FILE__, __LINE__);

	gl.viewport(viewportX, viewportY, viewportW, viewportH);
	gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
	gl.enable(GL_DEPTH_TEST);

	static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };

	// Fill viewport with 2 quads - one with constant depth and another with d = [-1..1]
	{
		glu::ShaderProgram basicQuadProgram(m_context.getRenderContext(), glu::makeVtxFragSources(s_vertexShaderSrc, s_defaultFragmentShaderSrc));

		if (!basicQuadProgram.isOk())
		{
			log << basicQuadProgram;
			TCU_FAIL("Compile failed");
		}

		const float constDepthCoord[] =
		{
			-1.0f, -1.0f, constDepth, 1.0f,
			-1.0f, +1.0f, constDepth, 1.0f,
			 0.0f, -1.0f, constDepth, 1.0f,
			 0.0f, +1.0f, constDepth, 1.0f
		};
		const float varyingDepthCoord[] =
		{
			 0.0f, -1.0f, +1.0f, 1.0f,
			 0.0f, +1.0f,  0.0f, 1.0f,
			+1.0f, -1.0f,  0.0f, 1.0f,
			+1.0f, +1.0f, -1.0f, 1.0f
		};

		gl.useProgram(basicQuadProgram.getProgram());
		gl.uniform4f(gl.getUniformLocation(basicQuadProgram.getProgram(), "u_color"), 0.0f, 0.0f, 1.0f, 1.0f);
		gl.depthFunc(GL_ALWAYS);

		{
			glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 4, 4, 0, &constDepthCoord[0]);
			glu::draw(m_context.getRenderContext(), basicQuadProgram.getProgram(), 1, &posBinding,
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
		}

		{
			glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 4, 4, 0, &varyingDepthCoord[0]);
			glu::draw(m_context.getRenderContext(), basicQuadProgram.getProgram(), 1, &posBinding,
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw base quads");
	}

	// Render with depth test.
	{
		glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(s_vertexShaderSrc, m_fragSrc.c_str()));
		log << program;

		if (!program.isOk())
			TCU_FAIL("Compile failed");

		const float coord[] =
		{
			0.0f, 0.0f,
			0.0f, 1.0f,
			1.0f, 0.0f,
			1.0f, 1.0f
		};
		const float position[] =
		{
			-1.0f, -1.0f, +1.0f, 1.0f,
			-1.0f, +1.0f,  0.0f, 1.0f,
			+1.0f, -1.0f,  0.0f, 1.0f,
			+1.0f, +1.0f, -1.0f, 1.0f
		};

		gl.useProgram(program.getProgram());
		gl.depthFunc(m_compareFunc);
		gl.uniform4f(gl.getUniformLocation(program.getProgram(), "u_color"), 0.0f, 1.0f, 0.0f, 1.0f);

		// Setup default helper uniforms.
		gls::setupDefaultUniforms(m_context.getRenderContext(), program.getProgram());

		{
			glu::VertexArrayBinding vertexArrays[] =
			{
				glu::va::Float("a_position",	4, 4, 0, &position[0]),
				glu::va::Float("a_coord",		2, 4, 0, &coord[0])
			};
			glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw test quad");
	}

	glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedFrame.getAccess());

	// Render reference.
	for (int y = 0; y < referenceFrame.getHeight(); y++)
	{
		float	yf		= ((float)y + 0.5f) / referenceFrame.getHeight();
		int		half	= de::clamp((int)((float)referenceFrame.getWidth()*0.5f + 0.5f), 0, referenceFrame.getWidth());

		// Fill left half - comparison to constant 0.5
		for (int x = 0; x < half; x++)
		{
			float	xf		= ((float)x + 0.5f) / (float)referenceFrame.getWidth();
			float	d		= m_evalFunc(Vec2(xf, yf));
			bool	dpass	= compare(m_compareFunc, d, constDepth*0.5f + 0.5f);

			referenceFrame.setPixel(x, y, dpass ? tcu::RGBA::green : tcu::RGBA::blue);
		}

		// Fill right half - comparison to interpolated depth
		for (int x = half; x < referenceFrame.getWidth(); x++)
		{
			float	xf		= ((float)x + 0.5f) / (float)referenceFrame.getWidth();
			float	xh		= ((float)x - half + 0.5f) / (float)(referenceFrame.getWidth()-half);
			float	rd		= 1.0f - (xh + yf) * 0.5f;
			float	d		= m_evalFunc(Vec2(xf, yf));
			bool	dpass	= compare(m_compareFunc, d, rd);

			referenceFrame.setPixel(x, y, dpass ? tcu::RGBA::green : tcu::RGBA::blue);
		}
	}

	bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame, renderedFrame, 0.05f, tcu::COMPARE_LOG_RESULT);
	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
							isOk ? "Pass"				: "Fail");
	return STOP;
}

class FragDepthWriteCase : public TestCase
{
public:
							FragDepthWriteCase		(Context& context, const char* name, const char* desc, const char* fragSrc, EvalFragDepthFunc evalFunc);
							~FragDepthWriteCase		(void);

	IterateResult			iterate					(void);

private:
	string					m_fragSrc;
	EvalFragDepthFunc		m_evalFunc;
};

FragDepthWriteCase::FragDepthWriteCase (Context& context, const char* name, const char* desc, const char* fragSrc, EvalFragDepthFunc evalFunc)
	: TestCase			(context, name, desc)
	, m_fragSrc			(fragSrc)
	, m_evalFunc		(evalFunc)
{
}

FragDepthWriteCase::~FragDepthWriteCase (void)
{
}

FragDepthWriteCase::IterateResult FragDepthWriteCase::iterate (void)
{
	TestLog&					log				= m_testCtx.getLog();
	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
	de::Random					rnd				(deStringHash(getName()));
	const tcu::RenderTarget&	renderTarget	= m_context.getRenderContext().getRenderTarget();
	int							viewportW		= de::min(128, renderTarget.getWidth());
	int							viewportH		= de::min(128, renderTarget.getHeight());
	int							viewportX		= rnd.getInt(0, renderTarget.getWidth()-viewportW);
	int							viewportY		= rnd.getInt(0, renderTarget.getHeight()-viewportH);
	tcu::Surface				renderedFrame	(viewportW, viewportH);
	tcu::Surface				referenceFrame	(viewportW, viewportH);
	const int					numDepthSteps	= 16;
	const float					depthStep		= 1.0f/(float)(numDepthSteps-1);

	if (renderTarget.getDepthBits() == 0)
		throw tcu::NotSupportedError("Depth buffer is required", "", __FILE__, __LINE__);

	gl.viewport(viewportX, viewportY, viewportW, viewportH);
	gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
	gl.enable(GL_DEPTH_TEST);
	gl.depthFunc(GL_LESS);

	static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };

	// Render with given shader.
	{
		glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(s_vertexShaderSrc, m_fragSrc.c_str()));
		log << program;

		if (!program.isOk())
			TCU_FAIL("Compile failed");

		const float coord[] =
		{
			0.0f, 0.0f,
			0.0f, 1.0f,
			1.0f, 0.0f,
			1.0f, 1.0f
		};
		const float position[] =
		{
			-1.0f, -1.0f, +1.0f, 1.0f,
			-1.0f, +1.0f,  0.0f, 1.0f,
			+1.0f, -1.0f,  0.0f, 1.0f,
			+1.0f, +1.0f, -1.0f, 1.0f
		};

		gl.useProgram(program.getProgram());
		gl.uniform4f(gl.getUniformLocation(program.getProgram(), "u_color"), 0.0f, 1.0f, 0.0f, 1.0f);

		// Setup default helper uniforms.
		gls::setupDefaultUniforms(m_context.getRenderContext(), program.getProgram());

		{
			glu::VertexArrayBinding vertexArrays[] =
			{
				glu::va::Float("a_position",	4, 4, 0, &position[0]),
				glu::va::Float("a_coord",		2, 4, 0, &coord[0])
			};
			glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw test quad");
	}

	// Visualize by rendering full-screen quads with increasing depth and color.
	{
		glu::ShaderProgram program (m_context.getRenderContext(), glu::makeVtxFragSources(s_vertexShaderSrc, s_defaultFragmentShaderSrc));
		if (!program.isOk())
		{
			log << program;
			TCU_FAIL("Compile failed");
		}

		int posLoc		= gl.getAttribLocation(program.getProgram(), "a_position");
		int colorLoc	= gl.getUniformLocation(program.getProgram(), "u_color");

		gl.useProgram(program.getProgram());
		gl.depthMask(GL_FALSE);

		for (int stepNdx = 0; stepNdx < numDepthSteps; stepNdx++)
		{
			float	f		= (float)stepNdx*depthStep;
			float	depth	= f*2.0f - 1.0f;
			Vec4	color	= Vec4(f, f, f, 1.0f);

			const float position[] =
			{
				-1.0f, -1.0f, depth, 1.0f,
				-1.0f, +1.0f, depth, 1.0f,
				+1.0f, -1.0f, depth, 1.0f,
				+1.0f, +1.0f, depth, 1.0f
			};
			glu::VertexArrayBinding	posBinding = glu::va::Float(posLoc, 4, 4, 0, &position[0]);

			gl.uniform4fv(colorLoc, 1, color.getPtr());
			glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0]));
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Visualization draw");
	}

	glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedFrame.getAccess());

	// Render reference.
	for (int y = 0; y < referenceFrame.getHeight(); y++)
	{
		for (int x = 0; x < referenceFrame.getWidth(); x++)
		{
			float	xf		= ((float)x + 0.5f) / (float)referenceFrame.getWidth();
			float	yf		= ((float)y + 0.5f) / (float)referenceFrame.getHeight();
			float	d		= m_evalFunc(Vec2(xf, yf));
			int		step	= (int)deFloatFloor(d / depthStep);
			int		col		= de::clamp(deRoundFloatToInt32((float)step*depthStep*255.0f), 0, 255);

			referenceFrame.setPixel(x, y, tcu::RGBA(col, col, col, 0xff));
		}
	}

	bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame, renderedFrame, 0.05f, tcu::COMPARE_LOG_RESULT);
	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
							isOk ? "Pass"				: "Fail");
	return STOP;
}

FragDepthTests::FragDepthTests (Context& context)
	: TestCaseGroup(context, "fragdepth", "gl_FragDepth tests")
{
}

FragDepthTests::~FragDepthTests (void)
{
}

static float evalConstDepth		(const Vec2& coord)	{ DE_UNREF(coord); return 0.5f; }
static float evalDynamicDepth	(const Vec2& coord)	{ return (coord.x()+coord.y())*0.5f; }
static float evalNoWrite		(const Vec2& coord)	{ return 1.0f - (coord.x()+coord.y())*0.5f; }

static float evalDynamicConditionalDepth (const Vec2& coord)
{
	float d = (coord.x()+coord.y())*0.5f;
	if (coord.y() < 0.5f)
		return d;
	else
		return 1.0f - d;
}

void FragDepthTests::init (void)
{
	static const struct
	{
		const char*			name;
		const char*			desc;
		EvalFragDepthFunc	evalFunc;
		const char*			fragSrc;
	} cases[] =
	{
		{
			"no_write", "No gl_FragDepth write", evalNoWrite,
			"#version 300 es\n"
			"uniform highp vec4 u_color;\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
			"void main (void)\n"
			"{\n"
			"	o_color = u_color;\n"
			"}\n"
		},
		{
			"const", "Const depth write", evalConstDepth,
			"#version 300 es\n"
			"uniform highp vec4 u_color;\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
			"void main (void)\n"
			"{\n"
			"	o_color = u_color;\n"
			"	gl_FragDepth = 0.5;\n"
			"}\n"
		},
		{
			"uniform", "Uniform depth write", evalConstDepth,
			"#version 300 es\n"
			"uniform highp vec4 u_color;\n"
			"uniform highp float uf_half;\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
			"void main (void)\n"
			"{\n"
			"	o_color = u_color;\n"
			"	gl_FragDepth = uf_half;\n"
			"}\n"
		},
		{
			"dynamic", "Dynamic depth write", evalDynamicDepth,
			"#version 300 es\n"
			"uniform highp vec4 u_color;\n"
			"in highp vec2 v_coord;\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
			"void main (void)\n"
			"{\n"
			"	o_color = u_color;\n"
			"	gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n"
			"}\n"
		},
		{
			"fragcoord_z", "gl_FragDepth write from gl_FragCoord.z", evalNoWrite,
			"#version 300 es\n"
			"uniform highp vec4 u_color;\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
			"void main (void)\n"
			"{\n"
			"	o_color = u_color;\n"
			"	gl_FragDepth = gl_FragCoord.z;\n"
			"}\n"
		},
		{
			"uniform_conditional_write", "Uniform conditional write", evalDynamicDepth,
			"#version 300 es\n"
			"uniform highp vec4 u_color;\n"
			"uniform bool ub_true;\n"
			"in highp vec2 v_coord;\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
			"void main (void)\n"
			"{\n"
			"	o_color = u_color;\n"
			"	if (ub_true)\n"
			"		gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n"
			"}\n"
		},
		{
			"dynamic_conditional_write", "Uniform conditional write", evalDynamicConditionalDepth,
			"#version 300 es\n"
			"uniform highp vec4 u_color;\n"
			"uniform bool ub_true;\n"
			"in highp vec2 v_coord;\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
			"void main (void)\n"
			"{\n"
			"	o_color = u_color;\n"
			"	mediump float d = (v_coord.x+v_coord.y)*0.5f;\n"
			"	if (v_coord.y < 0.5)\n"
			"		gl_FragDepth = d;\n"
			"	else\n"
			"		gl_FragDepth = 1.0 - d;\n"
			"}\n"
		},
		{
			"uniform_loop_write", "Uniform loop write", evalConstDepth,
			"#version 300 es\n"
			"uniform highp vec4 u_color;\n"
			"uniform int ui_two;\n"
			"uniform highp float uf_fourth;\n"
			"in highp vec2 v_coord;\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
			"void main (void)\n"
			"{\n"
			"	o_color = u_color;\n"
			"	gl_FragDepth = 0.0;\n"
			"	for (int i = 0; i < ui_two; i++)\n"
			"		gl_FragDepth += uf_fourth;\n"
			"}\n"
		},
		{
			"write_in_function", "Uniform loop write", evalDynamicDepth,
			"#version 300 es\n"
			"uniform highp vec4 u_color;\n"
			"uniform highp float uf_half;\n"
			"in highp vec2 v_coord;\n"
			"layout(location = 0) out mediump vec4 o_color;\n"
			"void myfunc (highp vec2 coord)\n"
			"{\n"
			"	gl_FragDepth = (coord.x+coord.y)*0.5;\n"
			"}\n"
			"void main (void)\n"
			"{\n"
			"	o_color = u_color;\n"
			"	myfunc(v_coord);\n"
			"}\n"
		}
	};

	// .write
	tcu::TestCaseGroup* writeGroup = new tcu::TestCaseGroup(m_testCtx, "write", "gl_FragDepth write tests");
	addChild(writeGroup);
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
		writeGroup->addChild(new FragDepthWriteCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].fragSrc, cases[ndx].evalFunc));

	// .compare
	tcu::TestCaseGroup* compareGroup = new tcu::TestCaseGroup(m_testCtx, "compare", "gl_FragDepth used with depth comparison");
	addChild(compareGroup);
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
		compareGroup->addChild(new FragDepthCompareCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].fragSrc, cases[ndx].evalFunc, GL_LESS));
}

} // Functional
} // gles3
} // deqp
