/*-------------------------------------------------------------------------
 * 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 Shader discard statement tests.
 *//*--------------------------------------------------------------------*/

#include "es3fShaderDiscardTests.hpp"
#include "glsShaderRenderCase.hpp"
#include "tcuStringTemplate.hpp"
#include "gluTexture.hpp"

#include <map>
#include <sstream>
#include <string>

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

using tcu::StringTemplate;

using std::map;
using std::string;
using std::ostringstream;

using namespace glu;
using namespace deqp::gls;

namespace deqp
{
namespace gles3
{
namespace Functional
{

class ShaderDiscardCase : public ShaderRenderCase
{
public:
						ShaderDiscardCase			(Context& context, const char* name, const char* description, const char* shaderSource, ShaderEvalFunc evalFunc, bool usesTexture);
	virtual				~ShaderDiscardCase			(void);

	void				init						(void);
	void				deinit						(void);

	void				setupUniforms				(int programID, const tcu::Vec4& constCoords);

private:
	bool				m_usesTexture;
	glu::Texture2D*		m_brickTexture;
};

ShaderDiscardCase::ShaderDiscardCase (Context& context, const char* name, const char* description, const char* shaderSource, ShaderEvalFunc evalFunc, bool usesTexture)
	: ShaderRenderCase	(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, false, evalFunc)
	, m_usesTexture		(usesTexture)
	, m_brickTexture	(DE_NULL)
{
	m_fragShaderSource	= shaderSource;
	m_vertShaderSource	=
		"#version 300 es\n"
		"in  highp   vec4 a_position;\n"
		"in  highp   vec4 a_coords;\n"
		"out mediump vec4 v_color;\n"
		"out mediump vec4 v_coords;\n\n"
		"void main (void)\n"
		"{\n"
		"    gl_Position = a_position;\n"
		"    v_color = vec4(a_coords.xyz, 1.0);\n"
		"    v_coords = a_coords;\n"
		"}\n";
}

ShaderDiscardCase::~ShaderDiscardCase (void)
{
	delete m_brickTexture;
}

void ShaderDiscardCase::init (void)
{
	if (m_usesTexture)
	{
		m_brickTexture = glu::Texture2D::create(m_renderCtx, m_ctxInfo, m_testCtx.getArchive(), "data/brick.png");
		m_textures.push_back(TextureBinding(m_brickTexture, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
																		 tcu::Sampler::LINEAR, tcu::Sampler::LINEAR)));
	}
	gls::ShaderRenderCase::init();
}

void ShaderDiscardCase::deinit (void)
{
	gls::ShaderRenderCase::deinit();
	delete m_brickTexture;
	m_brickTexture = DE_NULL;
}

void ShaderDiscardCase::setupUniforms (int programID, const tcu::Vec4&)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();
	gl.uniform1i(gl.getUniformLocation(programID, "ut_brick"), 0);
}

ShaderDiscardTests::ShaderDiscardTests (Context& context)
	: TestCaseGroup(context, "discard", "Discard statement tests")
{
}

ShaderDiscardTests::~ShaderDiscardTests (void)
{
}

enum DiscardMode
{
	DISCARDMODE_ALWAYS = 0,
	DISCARDMODE_NEVER,
	DISCARDMODE_UNIFORM,
	DISCARDMODE_DYNAMIC,
	DISCARDMODE_TEXTURE,

	DISCARDMODE_LAST
};

enum DiscardTemplate
{
	DISCARDTEMPLATE_MAIN_BASIC = 0,
	DISCARDTEMPLATE_FUNCTION_BASIC,
	DISCARDTEMPLATE_MAIN_STATIC_LOOP,
	DISCARDTEMPLATE_MAIN_DYNAMIC_LOOP,
	DISCARDTEMPLATE_FUNCTION_STATIC_LOOP,

	DISCARDTEMPLATE_LAST
};

// Evaluation functions
inline void evalDiscardAlways	(ShaderEvalContext& c) { c.discard(); }
inline void evalDiscardNever	(ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); }
inline void evalDiscardDynamic	(ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); if (c.coords.x()+c.coords.y() > 0.0f) c.discard(); }

inline void evalDiscardTexture (ShaderEvalContext& c)
{
	c.color.xyz() = c.coords.swizzle(0,1,2);
	if (c.texture2D(0, c.coords.swizzle(0,1) * 0.25f + 0.5f).x() < 0.7f)
		c.discard();
}

static ShaderEvalFunc getEvalFunc (DiscardMode mode)
{
	switch (mode)
	{
		case DISCARDMODE_ALWAYS:	return evalDiscardAlways;
		case DISCARDMODE_NEVER:		return evalDiscardNever;
		case DISCARDMODE_UNIFORM:	return evalDiscardAlways;
		case DISCARDMODE_DYNAMIC:	return evalDiscardDynamic;
		case DISCARDMODE_TEXTURE:	return evalDiscardTexture;
		default:
			DE_ASSERT(DE_FALSE);
			return evalDiscardAlways;
	}
}

static const char* getTemplate (DiscardTemplate variant)
{
	switch (variant)
	{
		case DISCARDTEMPLATE_MAIN_BASIC:
			return "#version 300 es\n"
				   "in mediump vec4 v_color;\n"
				   "in mediump vec4 v_coords;\n"
				   "layout(location = 0) out mediump vec4 o_color;\n"
				   "uniform sampler2D    ut_brick;\n"
				   "uniform mediump int  ui_one;\n\n"
				   "void main (void)\n"
				   "{\n"
				   "    o_color = v_color;\n"
				   "    ${DISCARD};\n"
				   "}\n";

		case DISCARDTEMPLATE_FUNCTION_BASIC:
			return "#version 300 es\n"
				   "in mediump vec4 v_color;\n"
				   "in mediump vec4 v_coords;\n"
				   "layout(location = 0) out mediump vec4 o_color;\n"
				   "uniform sampler2D    ut_brick;\n"
				   "uniform mediump int  ui_one;\n\n"
				   "void myfunc (void)\n"
				   "{\n"
				   "    ${DISCARD};\n"
				   "}\n\n"
				   "void main (void)\n"
				   "{\n"
				   "    o_color = v_color;\n"
				   "    myfunc();\n"
				   "}\n";

		case DISCARDTEMPLATE_MAIN_STATIC_LOOP:
			return "#version 300 es\n"
				   "in mediump vec4 v_color;\n"
				   "in mediump vec4 v_coords;\n"
				   "layout(location = 0) out mediump vec4 o_color;\n"
				   "uniform sampler2D    ut_brick;\n"
				   "uniform mediump int  ui_one;\n\n"
				   "void main (void)\n"
				   "{\n"
				   "    o_color = v_color;\n"
				   "    for (int i = 0; i < 2; i++)\n"
				   "    {\n"
				   "        if (i > 0)\n"
				   "            ${DISCARD};\n"
				   "    }\n"
				   "}\n";

		case DISCARDTEMPLATE_MAIN_DYNAMIC_LOOP:
			return "#version 300 es\n"
				   "in mediump vec4 v_color;\n"
				   "in mediump vec4 v_coords;\n"
				   "layout(location = 0) out mediump vec4 o_color;\n"
				   "uniform sampler2D    ut_brick;\n"
				   "uniform mediump int  ui_one;\n"
				   "uniform mediump int  ui_two;\n\n"
				   "void main (void)\n"
				   "{\n"
				   "    o_color = v_color;\n"
				   "    for (int i = 0; i < ui_two; i++)\n"
				   "    {\n"
				   "        if (i > 0)\n"
				   "            ${DISCARD};\n"
				   "    }\n"
				   "}\n";

		case DISCARDTEMPLATE_FUNCTION_STATIC_LOOP:
			return "#version 300 es\n"
				   "in mediump vec4 v_color;\n"
				   "in mediump vec4 v_coords;\n"
				   "layout(location = 0) out mediump vec4 o_color;\n"
				   "uniform sampler2D    ut_brick;\n"
				   "uniform mediump int  ui_one;\n\n"
				   "void myfunc (void)\n"
				   "{\n"
				   "    for (int i = 0; i < 2; i++)\n"
				   "    {\n"
				   "        if (i > 0)\n"
				   "            ${DISCARD};\n"
				   "    }\n"
				   "}\n\n"
				   "void main (void)\n"
				   "{\n"
				   "    o_color = v_color;\n"
				   "    myfunc();\n"
				   "}\n";

		default:
			DE_ASSERT(DE_FALSE);
			return DE_NULL;
	}
}

static const char* getTemplateName (DiscardTemplate variant)
{
	switch (variant)
	{
		case DISCARDTEMPLATE_MAIN_BASIC:			return "basic";
		case DISCARDTEMPLATE_FUNCTION_BASIC:		return "function";
		case DISCARDTEMPLATE_MAIN_STATIC_LOOP:		return "static_loop";
		case DISCARDTEMPLATE_MAIN_DYNAMIC_LOOP:		return "dynamic_loop";
		case DISCARDTEMPLATE_FUNCTION_STATIC_LOOP:	return "function_static_loop";
		default:
			DE_ASSERT(DE_FALSE);
			return DE_NULL;
	}
}

static const char* getModeName (DiscardMode mode)
{
	switch (mode)
	{
		case DISCARDMODE_ALWAYS:	return "always";
		case DISCARDMODE_NEVER:		return "never";
		case DISCARDMODE_UNIFORM:	return "uniform";
		case DISCARDMODE_DYNAMIC:	return "dynamic";
		case DISCARDMODE_TEXTURE:	return "texture";
		default:
			DE_ASSERT(DE_FALSE);
			return DE_NULL;
	}
}

static const char* getTemplateDesc (DiscardTemplate variant)
{
	switch (variant)
	{
		case DISCARDTEMPLATE_MAIN_BASIC:			return "main";
		case DISCARDTEMPLATE_FUNCTION_BASIC:		return "function";
		case DISCARDTEMPLATE_MAIN_STATIC_LOOP:		return "static loop";
		case DISCARDTEMPLATE_MAIN_DYNAMIC_LOOP:		return "dynamic loop";
		case DISCARDTEMPLATE_FUNCTION_STATIC_LOOP:	return "static loop in function";
		default:
			DE_ASSERT(DE_FALSE);
			return DE_NULL;
	}
}

static const char* getModeDesc (DiscardMode mode)
{
	switch (mode)
	{
		case DISCARDMODE_ALWAYS:	return "Always discard";
		case DISCARDMODE_NEVER:		return "Never discard";
		case DISCARDMODE_UNIFORM:	return "Discard based on uniform value";
		case DISCARDMODE_DYNAMIC:	return "Discard based on varying values";
		case DISCARDMODE_TEXTURE:	return "Discard based on texture value";
		default:
			DE_ASSERT(DE_FALSE);
			return DE_NULL;
	}
}

ShaderDiscardCase* makeDiscardCase (Context& context, DiscardTemplate tmpl, DiscardMode mode)
{
	StringTemplate shaderTemplate(getTemplate(tmpl));

	map<string, string> params;

	switch (mode)
	{
		case DISCARDMODE_ALWAYS:	params["DISCARD"] = "discard";										break;
		case DISCARDMODE_NEVER:		params["DISCARD"] = "if (false) discard";							break;
		case DISCARDMODE_UNIFORM:	params["DISCARD"] = "if (ui_one > 0) discard";						break;
		case DISCARDMODE_DYNAMIC:	params["DISCARD"] = "if (v_coords.x+v_coords.y > 0.0) discard";		break;
		case DISCARDMODE_TEXTURE:	params["DISCARD"] = "if (texture(ut_brick, v_coords.xy*0.25+0.5).x < 0.7) discard";	break;
		default:
			DE_ASSERT(DE_FALSE);
			break;
	}

	string name			= string(getTemplateName(tmpl)) + "_" + getModeName(mode);
	string description	= string(getModeDesc(mode)) + " in " + getTemplateDesc(tmpl);

	return new ShaderDiscardCase(context, name.c_str(), description.c_str(), shaderTemplate.specialize(params).c_str(), getEvalFunc(mode), mode == DISCARDMODE_TEXTURE);
}

void ShaderDiscardTests::init (void)
{
	for (int tmpl = 0; tmpl < DISCARDTEMPLATE_LAST; tmpl++)
		for (int mode = 0; mode < DISCARDMODE_LAST; mode++)
			addChild(makeDiscardCase(m_context, (DiscardTemplate)tmpl, (DiscardMode)mode));
}

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