/*-------------------------------------------------------------------------
 * 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) / (float)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
