/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2017 The Khronos Group Inc.
 *
 * 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  glcAggressiveShaderOptimizationsTests.cpp
 * \brief Conformance tests that checks if shader optimizations are not
 *		  overly aggressive. This is done by compering result of complex
 *		  trigonometric functions aproximation to shader buil
 */ /*-------------------------------------------------------------------*/

#include "glcAggressiveShaderOptimizationsTests.hpp"
#include "deSharedPtr.hpp"
#include "glsShaderExecUtil.hpp"
#include "gluContextInfo.hpp"
#include "gluDrawUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderProgram.hpp"
#include "glwFunctions.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"

using namespace glw;

namespace glcts
{

enum ShaderType
{
	TEST_VERTEX_SHADER,
	TEST_FRAGMENT_SHADER
};

struct TrigonometryCaseData
{
	const char* testedFunction;
	const char* testedType;
	const char* colorComponents;
	ShaderType  shaderType;
};

class TrigonometryTestCase : public deqp::TestCase
{
public:
	TrigonometryTestCase(deqp::Context& context, const std::string& name, const TrigonometryCaseData& data);
	virtual ~TrigonometryTestCase();

	IterateResult iterate(void);

protected:
	glu::ProgramSources prepareSineSources(bool useBuiltin);
	glu::ProgramSources prepareCosineSources(bool useBuiltin);

	void renderAndGrabSurface(glu::ProgramSources sources, tcu::Surface& result) const;

private:
	ShaderType  m_shaderType;
	const char* m_testedFunction;
	std::map<std::string, std::string> m_specializationMap;
};

TrigonometryTestCase::TrigonometryTestCase(deqp::Context& context, const std::string& name,
										   const TrigonometryCaseData& data)
	: deqp::TestCase(context, name.c_str(), ""), m_shaderType(data.shaderType), m_testedFunction(data.testedFunction)
{
	glu::ContextType contextType = m_context.getRenderContext().getType();
	glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(contextType);

	m_specializationMap["VERSION"]			= glu::getGLSLVersionDeclaration(glslVersion);
	m_specializationMap["TYPE"]				= data.testedType;
	m_specializationMap["COLOR_COMPONENTS"] = data.colorComponents;

	if (glu::contextSupports(contextType, glu::ApiType::es(3, 0)) || glu::isContextTypeGLCore(contextType))
	{
		m_specializationMap["IN"]						= "in";
		m_specializationMap["OUT"]						= "out";
		m_specializationMap["ATTRIBUTE"]				= "in";
		m_specializationMap["FS_OUT_COLOR_NAME"]		= "fragColor";
		m_specializationMap["FS_OUT_COLOR_DECLARATION"] = "out vec4 fragColor;";
	}
	else
	{
		m_specializationMap["IN"]						= "varying";
		m_specializationMap["OUT"]						= "varying";
		m_specializationMap["ATTRIBUTE"]				= "attribute";
		m_specializationMap["FS_OUT_COLOR_NAME"]		= "gl_FragColor";
		m_specializationMap["FS_OUT_COLOR_DECLARATION"] = "";
	}
}

TrigonometryTestCase::~TrigonometryTestCase()
{
}

glu::ProgramSources TrigonometryTestCase::prepareSineSources(bool useBuiltinSin)
{
	const char* vsDefault = "${VERSION}\n"
							"${ATTRIBUTE} highp vec2 position;\n"
							"${ATTRIBUTE} highp vec3 baseColor;\n"
							"${OUT} vec4 color;\n"
							"void main (void) {\n"
							"  color = vec4(baseColor, 1.0);\n"
							"  gl_Position = vec4(position, 0.0, 1.0);\n"
							"}\n";

	const char* vsCalculateSin = "${VERSION}\n"
								 "${ATTRIBUTE} highp vec2 position;\n"
								 "${ATTRIBUTE} highp vec3 baseColor;\n"
								 "${OUT} vec4 color;\n"
								 "${SIN_FUNCTION_DEFINITION_VS}\n"
								 "void main (void) {\n"
								 "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
								 "  ${TYPE} c = baseColor.${COLOR_COMPONENTS} * M_2PI;\n"
								 "  ${TYPE} sin_c = ${SIN_FUNCTION_NAME}(c);\n"
								 "  \n"
								 "  color = vec4(0.0, 0.0, 0.0, 1.0);\n"
								 "  color.${COLOR_COMPONENTS} = sin_c * 0.5 + 0.5;\n"
								 "  gl_Position = vec4(position, 0.0, 1.0);\n"
								 "}\n";

	const char* fsDefault = "${VERSION}\n"
							"precision mediump float;\n"
							"${IN} vec4 color;\n"
							"${FS_OUT_COLOR_DECLARATION}\n"
							"void main (void) {\n"
							"  ${FS_OUT_COLOR_NAME} = color;\n"
							"}\n";

	const char* fsCalculateSin = "${VERSION}\n"
								 "precision mediump float;\n"
								 "${IN} vec4 color;\n"
								 "${FS_OUT_COLOR_DECLARATION}\n\n"
								 "${SIN_FUNCTION_DEFINITION_FS}\n"
								 "void main (void) {\n"
								 "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
								 "  ${TYPE} c = color.${COLOR_COMPONENTS};\n"
								 "  ${TYPE} sin_c = ${SIN_FUNCTION_NAME}(c * M_2PI);\n"
								 "  \n"
								 "  ${FS_OUT_COLOR_NAME} =vec4(0.0, 0.0, 0.0, 1.0);\n"
								 "  ${FS_OUT_COLOR_NAME}.${COLOR_COMPONENTS} = sin_c * 0.5 + 0.5;\n"
								 "}\n";

	std::string vsTemplate;
	std::string fsTemplate;

	if (m_shaderType == TEST_VERTEX_SHADER)
	{
		vsTemplate = vsCalculateSin;
		fsTemplate = fsDefault;
	}
	else
	{
		vsTemplate = vsDefault;
		fsTemplate = fsCalculateSin;
	}

	if (useBuiltinSin)
	{
		m_specializationMap["SIN_FUNCTION_NAME"]		  = "sin";
		m_specializationMap["SIN_FUNCTION_DEFINITION_VS"] = "";
		m_specializationMap["SIN_FUNCTION_DEFINITION_FS"] = "";
	}
	else
	{
		std::string sinFunctionDefinitionVS = "${TYPE} ${SIN_FUNCTION_NAME}(${TYPE} c) {\n"
											  "  ${TYPE} sin_c = ${TYPE}(0.0);\n"
											  "  float sign = 1.0;\n"
											  "  float fact;\n"
											  "  float fact_of;\n"
											  "  \n"
											  "  // Taylors series expansion for sin \n"
											  "  for(int i = 0; i < 12; i++) {\n"
											  "    fact = 1.0;\n"
											  "    for(int j = 2; j <= 23; j++)\n"
											  "      if (j <= 2 * i + 1)\n"
											  "        fact *= float(j);\n"
											  "    \n"
											  "    sin_c += sign * pow(c, ${TYPE}(2.0 * float(i) + 1.0)) / fact;\n"
											  "    sign *= -1.0;\n"
											  "  }\n"
											  "  return sin_c;\n"
											  "}";
		std::string sinFunctionDefinitionFS = "float lerpHelper(float a, float b, float weight) {\n"
											  "  return a + (b - a) * weight;\n"
											  "}\n"
											  "float sinLerpHelper(int index, float weight) {\n"
											  "  float sArray[17];\n"
											  "  sArray[0] = 0.0;\n"
											  "  sArray[1] = 0.382683;\n"
											  "  sArray[2] = 0.707107;\n"
											  "  sArray[3] = 0.92388;\n"
											  "  sArray[4] = 1.0;\n"
											  "  sArray[5] = 0.92388;\n"
											  "  sArray[6] = 0.707107;\n"
											  "  sArray[7] = 0.382683;\n"
											  "  sArray[8] = 0.0;\n"
											  "  sArray[9] = -0.382683;\n"
											  "  sArray[10] = -0.707107;\n"
											  "  sArray[11] = -0.92388;\n"
											  "  sArray[12] = -1.0;\n"
											  "  sArray[13] = -0.923879;\n"
											  "  sArray[14] = -0.707107;\n"
											  "  sArray[15] = -0.382683;\n"
											  "  sArray[16] = 0.0;\n"
											  "  \n"
											  "  if (index == 0)\n"
											  "    return lerpHelper(sArray[0], sArray[1], weight);\n"
											  "  if (index == 1)\n"
											  "    return lerpHelper(sArray[1], sArray[2], weight);\n"
											  "  if (index == 2)\n"
											  "    return lerpHelper(sArray[2], sArray[3], weight);\n"
											  "  if (index == 3)\n"
											  "    return lerpHelper(sArray[3], sArray[4], weight);\n"
											  "  if (index == 4)\n"
											  "    return lerpHelper(sArray[4], sArray[5], weight);\n"
											  "  if (index == 5)\n"
											  "    return lerpHelper(sArray[5], sArray[6], weight);\n"
											  "  if (index == 6)\n"
											  "    return lerpHelper(sArray[6], sArray[7], weight);\n"
											  "  if (index == 7)\n"
											  "    return lerpHelper(sArray[7], sArray[8], weight);\n"
											  "  if (index == 8)\n"
											  "    return lerpHelper(sArray[8], sArray[9], weight);\n"
											  "  if (index == 9)\n"
											  "    return lerpHelper(sArray[9], sArray[10], weight);\n"
											  "  if (index == 10)\n"
											  "    return lerpHelper(sArray[10], sArray[11], weight);\n"
											  "  if (index == 11)\n"
											  "    return lerpHelper(sArray[11], sArray[12], weight);\n"
											  "  if (index == 12)\n"
											  "    return lerpHelper(sArray[12], sArray[13], weight);\n"
											  "  if (index == 13)\n"
											  "    return lerpHelper(sArray[13], sArray[14], weight);\n"
											  "  if (index == 14)\n"
											  "    return lerpHelper(sArray[14], sArray[15], weight);\n"
											  "  if (index == 15)\n"
											  "    return lerpHelper(sArray[15], sArray[16], weight);\n"
											  "  return sArray[16];\n"
											  "}\n"
											  "${TYPE} ${SIN_FUNCTION_NAME}(${TYPE} c) {\n"
											  "  ${TYPE} arrVal = c * 2.546478971;\n"
											  "  ${TYPE} weight = arrVal - floor(arrVal);\n"
											  "  ${TYPE} sin_c = ${TYPE}(0.0);\n"
											  "  ${INTERPOLATE_SIN}"
											  "  return sin_c;\n"
											  "}";

		if (m_specializationMap["TYPE"] == "float")
		{
			m_specializationMap["INTERPOLATE_SIN"] = "\n"
													 "  int index = int(floor(arrVal));\n"
													 "  sin_c = sinLerpHelper(index, weight);\n";
		}
		else if (m_specializationMap["TYPE"] == "vec2")
		{
			m_specializationMap["INTERPOLATE_SIN"] = "\n"
													 "  int indexX = int(floor(arrVal.x));\n"
													 "  sin_c.x = sinLerpHelper(indexX, weight.x);\n"
													 "  int indexY = int(floor(arrVal.y));\n"
													 "  sin_c.y = sinLerpHelper(indexY, weight.y);\n";
		}
		else if (m_specializationMap["TYPE"] == "vec3")
		{
			m_specializationMap["INTERPOLATE_SIN"] = "\n"
													 "  int indexX = int(floor(arrVal.x));\n"
													 "  sin_c.x = sinLerpHelper(indexX, weight.x);\n"
													 "  int indexY = int(floor(arrVal.y));\n"
													 "  sin_c.y = sinLerpHelper(indexY, weight.y);\n"
													 "  int indexZ = int(floor(arrVal.z));\n"
													 "  sin_c.z = sinLerpHelper(indexZ, weight.z);\n";
		}

		m_specializationMap["SIN_FUNCTION_NAME"] = "calculateSin";
		m_specializationMap["SIN_FUNCTION_DEFINITION_VS"] =
			tcu::StringTemplate(sinFunctionDefinitionVS).specialize(m_specializationMap);
		m_specializationMap["SIN_FUNCTION_DEFINITION_FS"] =
			tcu::StringTemplate(sinFunctionDefinitionFS).specialize(m_specializationMap);
	}

	// Specialize shader templates
	vsTemplate = tcu::StringTemplate(vsTemplate).specialize(m_specializationMap);
	fsTemplate = tcu::StringTemplate(fsTemplate).specialize(m_specializationMap);
	return glu::makeVtxFragSources(vsTemplate.c_str(), fsTemplate.c_str());
}

glu::ProgramSources TrigonometryTestCase::prepareCosineSources(bool useBuiltinCos)
{
	const char* vsDefault = "${VERSION}\n"
							"${ATTRIBUTE} highp vec2 position;\n"
							"${ATTRIBUTE} highp vec3 baseColor;\n"
							"${OUT} vec4 color;\n"
							"void main (void) {\n"
							"  color = vec4(baseColor, 1.0);\n"
							"  gl_Position = vec4(position, 0.0, 1.0);\n"
							"}\n";

	const char* vsCalculateCos = "${VERSION}\n"
								 "${ATTRIBUTE} highp vec2 position;\n"
								 "${ATTRIBUTE} highp vec3 baseColor;\n"
								 "${OUT} vec4 color;\n"
								 "${COS_FUNCTION_DEFINITION_VS}\n"
								 "void main (void) {\n"
								 "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
								 "  ${TYPE} c = baseColor.${COLOR_COMPONENTS};\n"
								 "  ${TYPE} cos_c = ${COS_FUNCTION_NAME}(c * M_2PI);\n"
								 "  \n"
								 "  color = vec4(0.0, 0.0, 0.0, 1.0);\n"
								 "  color.${COLOR_COMPONENTS} = cos_c * 0.5 + 0.5;\n"
								 "  gl_Position = vec4(position, 0.0, 1.0);\n"
								 "}\n";

	const char* fsDefault = "${VERSION}\n"
							"precision mediump float;\n"
							"${IN} vec4 color;\n"
							"${FS_OUT_COLOR_DECLARATION}\n"
							"void main (void) {\n"
							"  ${FS_OUT_COLOR_NAME} = color;\n"
							"}\n";

	const char* fsCalculateCos = "${VERSION}\n"
								 "precision mediump float;\n"
								 "${IN} vec4 color;\n"
								 "${FS_OUT_COLOR_DECLARATION}\n\n"
								 "// function definitions \n"
								 "${COS_FUNCTION_DEFINITION_FS}\n"
								 "${TYPE} preprocessColor(${TYPE} c) {\n"
								 "  ${PREPROCESS_COLOR};\n"
								 "  return c;\n"
								 "}\n\n"
								 "void main (void) {\n"
								 "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
								 "  ${TYPE} c = preprocessColor(color.${COLOR_COMPONENTS});\n"
								 "  ${TYPE} cos_c = ${COS_FUNCTION_NAME}(c * M_2PI);\n"
								 "  \n"
								 "  ${FS_OUT_COLOR_NAME} = vec4(0.0, 0.0, 0.0, 1.0);\n"
								 "  ${FS_OUT_COLOR_NAME}.${COLOR_COMPONENTS} = cos_c * 0.5 + 0.5;\n"
								 "}\n";

	std::string vsTemplate;
	std::string fsTemplate;

	if (m_shaderType == TEST_VERTEX_SHADER)
	{
		vsTemplate = vsCalculateCos;
		fsTemplate = fsDefault;
	}
	else
	{
		vsTemplate = vsDefault;
		fsTemplate = fsCalculateCos;
	}

	if (useBuiltinCos)
	{
		m_specializationMap["PREPROCESS_COLOR"]			  = "";
		m_specializationMap["COS_FUNCTION_NAME"]		  = "cos";
		m_specializationMap["COS_FUNCTION_DEFINITION_VS"] = "";
		m_specializationMap["COS_FUNCTION_DEFINITION_FS"] = "";
	}
	else
	{
		std::string cosFunctionDefinitionVS = "${TYPE} ${COS_FUNCTION_NAME}(${TYPE} c) {\n"
											  "  ${TYPE} cos_c = ${TYPE}(1.0);\n"
											  "  float sign = -1.0;\n"
											  "  float fact =  1.0;\n"
											  "  \n"
											  "  for(int i = 2; i <= 20; i += 2) {\n"
											  "    fact  *= float(i)*float(i-1);\n"
											  "    cos_c += sign*pow(c, ${TYPE}(float(i)))/fact;\n"
											  "    sign = -sign;\n"
											  "  }\n"
											  "  return cos_c;\n"
											  "}";
		std::string cosFunctionDefinitionFS = "${TYPE} ${COS_FUNCTION_NAME}(${TYPE} c) {\n"
											  "  ${TYPE} cos_c = ${TYPE}(-1.0);\n"
											  "  float sign      = 1.0;\n"
											  "  float fact_even = 1.0;\n"
											  "  float fact_odd  = 1.0;\n"
											  "  ${TYPE} sum;\n"
											  "  ${TYPE} exp;\n"
											  "  \n"
											  "  for(int i = 2; i <= 10; i += 2) {\n"
											  "    fact_even *= float(i);\n"
											  "    fact_odd  *= float(i-1);\n"
											  "    exp = ${TYPE}(float(i/2));\n"
											  "    sum = sign * pow(abs(c), exp)/fact_even;\n"
											  "    cos_c += pow(abs(c), exp)*(sum/fact_odd);\n"
											  "    sign = -sign;\n"
											  "  }\n"
											  "  return cos_c;\n"
											  "}";

		m_specializationMap["PREPROCESS_COLOR"]  = "c = (fract(abs(c)) - 0.5)";
		m_specializationMap["COS_FUNCTION_NAME"] = "calculateCos";
		m_specializationMap["COS_FUNCTION_DEFINITION_VS"] =
			tcu::StringTemplate(cosFunctionDefinitionVS).specialize(m_specializationMap);
		m_specializationMap["COS_FUNCTION_DEFINITION_FS"] =
			tcu::StringTemplate(cosFunctionDefinitionFS).specialize(m_specializationMap);
	}

	// Specialize shader templates
	vsTemplate = tcu::StringTemplate(vsTemplate).specialize(m_specializationMap);
	fsTemplate = tcu::StringTemplate(fsTemplate).specialize(m_specializationMap);
	return glu::makeVtxFragSources(vsTemplate.c_str(), fsTemplate.c_str());
}

void TrigonometryTestCase::renderAndGrabSurface(glu::ProgramSources sources, tcu::Surface& result) const
{
	static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
	static const float	positions[]   = { -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0 };
	static const float	baseColors[]  = { 1.0, 0.0, 0.25, 0.75, 0.25, 1.0, 0.0, 1.0, 0.75, 0.25, 0.5, 0.0 };

	glu::RenderContext&   renderContext = m_context.getRenderContext();
	const glw::Functions& gl			= renderContext.getFunctions();
	glu::ShaderProgram	testProgram(renderContext, sources);
	if (!testProgram.isOk())
	{
		m_testCtx.getLog() << testProgram;
		TCU_FAIL("Test program compilation failed");
	}

	// Render
	gl.useProgram(testProgram.getProgram());
	const glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 2, 4, 0, positions),
													 glu::va::Float("baseColor", 3, 4, 0, baseColors) };
	glu::draw(renderContext, testProgram.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
			  glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));

	// Grab surface
	glu::readPixels(renderContext, 0, 0, result.getAccess());
}

tcu::TestNode::IterateResult TrigonometryTestCase::iterate(void)
{
	glu::RenderContext&   renderContext = m_context.getRenderContext();
	const glw::Functions& gl			= renderContext.getFunctions();

	int  renderWidth  = 64;
	int  renderHeight = 64;
	if (renderWidth > m_context.getRenderTarget().getWidth())
		renderWidth = m_context.getRenderTarget().getWidth();
	if (renderHeight > m_context.getRenderTarget().getHeight())
		renderHeight = m_context.getRenderTarget().getHeight();
	bool isSin		  = std::string(m_testedFunction) == "sin";

	gl.viewport(0, 0, renderWidth, renderHeight);

	// Use program that will call trigonometric function aproximation
	tcu::Surface testSurface(renderWidth, renderHeight);
	if (isSin)
		renderAndGrabSurface(prepareSineSources(false), testSurface);
	else
		renderAndGrabSurface(prepareCosineSources(false), testSurface);

	// Use reference program that will call builtin function
	tcu::Surface referenceSurface(renderWidth, renderHeight);
	if (isSin)
		renderAndGrabSurface(prepareSineSources(true), referenceSurface);
	else
		renderAndGrabSurface(prepareCosineSources(true), referenceSurface);

	// Compare surfaces
	qpTestResult testResult = QP_TEST_RESULT_FAIL;
	if (tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", referenceSurface, testSurface, 0.05f,
						  tcu::COMPARE_LOG_RESULT))
		testResult = QP_TEST_RESULT_PASS;

	m_testCtx.setTestResult(testResult, qpGetTestResultName(testResult));
	return STOP;
}

AggressiveShaderOptimizationsTests::AggressiveShaderOptimizationsTests(deqp::Context& context)
	: TestCaseGroup(context, "aggressive_optimizations", "checks if shader optimizations are not overly aggressive")
{
}

AggressiveShaderOptimizationsTests::~AggressiveShaderOptimizationsTests()
{
}

void AggressiveShaderOptimizationsTests::init(void)
{
	TrigonometryCaseData trigonometryCases[] = {
		{ "sin", "float", "r", TEST_VERTEX_SHADER },  { "sin", "float", "r", TEST_FRAGMENT_SHADER },
		{ "sin", "vec2", "rg", TEST_VERTEX_SHADER },  { "sin", "vec2", "rg", TEST_FRAGMENT_SHADER },
		{ "sin", "vec3", "rgb", TEST_VERTEX_SHADER }, { "sin", "vec3", "rgb", TEST_FRAGMENT_SHADER },
		{ "cos", "float", "r", TEST_VERTEX_SHADER },  { "cos", "float", "r", TEST_FRAGMENT_SHADER },
		{ "cos", "vec2", "rg", TEST_VERTEX_SHADER },  { "cos", "vec2", "rg", TEST_FRAGMENT_SHADER },
		{ "cos", "vec3", "rgb", TEST_VERTEX_SHADER }, { "cos", "vec3", "rgb", TEST_FRAGMENT_SHADER },
	};

	for (int i = 0; i < DE_LENGTH_OF_ARRAY(trigonometryCases); ++i)
	{
		const TrigonometryCaseData& tcd		   = trigonometryCases[i];
		std::string					shaderType = (tcd.shaderType == TEST_VERTEX_SHADER) ? "_vert" : "_frag";
		std::string					name	   = std::string(tcd.testedFunction) + "_" + tcd.testedType + shaderType;
		addChild(new TrigonometryTestCase(m_context, name, tcd));
	}
}

} // glcts namespace
