/*-------------------------------------------------------------------------
 * 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
 * \brief
 */ /*-------------------------------------------------------------------*/

/**
 */ /*!
 * \file  glcTextureFilterAnisotropicTests.cpp
 * \brief Conformance tests for the GL_EXT_texture_filter_anisotropic functionality.
 */ /*-------------------------------------------------------------------*/

#include "deMath.h"

#include "glcTextureFilterAnisotropicTests.hpp"
#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "gluShaderProgram.hpp"
#include "gluStrUtil.hpp"
#include "gluTextureUtil.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuRGBA.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuTestLog.hpp"
#include "tcuTexture.hpp"

using namespace glw;
using namespace glu;

namespace glcts
{

namespace TextureFilterAnisotropicUtils
{

/** Replace all occurrence of <token> with <text> in <str>
 *
 * @param token           Token string
 * @param text            String that will be used as replacement for <token>
 * @param string          String to work on
 **/
void replaceToken(const GLchar* token, const GLchar* text, std::string& str)
{
	const size_t text_length  = strlen(text);
	const size_t token_length = strlen(token);

	size_t token_position;
	while ((token_position = str.find(token, 0)) != std::string::npos)
	{
		str.replace(token_position, token_length, text, text_length);
	}
}

/** Allocate storage for texture
 *
 * @param target           Texture target
 * @param refTexCoordType  GLSL texture coord type
 * @param refSamplerType   GLSL texture sampler type
 **/
void generateTokens(GLenum target, std::string& refTexCoordType, std::string& refSamplerType)
{
	switch (target)
	{
	case GL_TEXTURE_2D:
		refTexCoordType = "vec2";
		refSamplerType  = "sampler2D";
		break;
	case GL_TEXTURE_2D_ARRAY:
		refTexCoordType = "vec3";
		refSamplerType  = "sampler2DArray";
		break;
	default:
		refTexCoordType = "vec2";
		refSamplerType  = "sampler2D";
		break;
	}
}

/** Set contents of texture
 *
 * @param gl              GL functions
 * @param target          Texture target
 * @param level           Mipmap level
 * @param internal_format Format of data
 * @param width           Width of texture
 * @param height          Height of texture
 * @param depth           Depth of texture
 * @param format          Format of data
 * @param type            Type of data
 * @param data            Buffer with image data
 **/
void texImage(const Functions& gl, GLenum target, GLint level, GLenum internal_format, GLuint width, GLuint height,
			  GLuint depth, GLenum format, GLenum type, const GLvoid* data)
{
	switch (target)
	{
	case GL_TEXTURE_2D:
		gl.texImage2D(target, level, internal_format, width, height, 0 /* border */, format, type, data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "texImage");
		break;
	case GL_TEXTURE_2D_ARRAY:
		gl.texImage3D(target, level, internal_format, width, height, depth, 0 /* border */, format, type, data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "texImage");
		break;
	default:
		TCU_FAIL("Invalid enum");
	}
}

/** Set contents of texture
 *
 * @param gl              GL functions
 * @param target          Texture target
 * @param level           Mipmap level
 * @param x               X offset
 * @param y               Y offset
 * @param z               Z offset
 * @param width           Width of texture
 * @param height          Height of texture
 * @param depth           Depth of texture
 * @param format          Format of data
 * @param type            Type of data
 * @param pixels          Buffer with image data
 **/
void subImage(const Functions& gl, GLenum target, GLint level, GLint x, GLint y, GLint z, GLsizei width, GLsizei height,
			  GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
{
	switch (target)
	{
	case GL_TEXTURE_2D:
		gl.texSubImage2D(target, level, x, y, width, height, format, type, pixels);
		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
		break;
	case GL_TEXTURE_2D_ARRAY:
		gl.texSubImage3D(target, level, x, y, z, width, height, depth, format, type, pixels);
		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage3D");
		break;
	default:
		TCU_FAIL("Invalid enum");
	}
}

} // TextureFilterAnisotropicUtils namespace

/** Constructor.
 *
 *  @param context     Rendering context
 */
TextureFilterAnisotropicQueriesTestCase::TextureFilterAnisotropicQueriesTestCase(deqp::Context& context)
	: TestCase(context, "queries", "Verifies if queries for GL_EXT_texture_filter_anisotropic tokens works as expected")
{
	/* Left blank intentionally */
}

/** Stub deinit method. */
void TextureFilterAnisotropicQueriesTestCase::deinit()
{
}

/** Stub init method */
void TextureFilterAnisotropicQueriesTestCase::init()
{
	glu::ContextType contextType = m_context.getRenderContext().getType();
	if (!glu::contextSupports(contextType, glu::ApiType::core(4, 6)) &&
		!m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_filter_anisotropic") &&
		!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_filter_anisotropic"))
	{
		TCU_THROW(NotSupportedError, "texture filter anisotropic functionality not supported");
	}
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult TextureFilterAnisotropicQueriesTestCase::iterate()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	GLuint texture;
	gl.genTextures(1, &texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
	gl.bindTexture(GL_TEXTURE_2D, texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
	TextureFilterAnisotropicUtils::texImage(gl, GL_TEXTURE_2D, 0, GL_RGBA8, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

	if (verifyTexParameters(gl) && verifyGet(gl))
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	gl.deleteTextures(1, &texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");

	return STOP;
}

/** Verify if texParameter*, getTexParameter* queries for GL_TEXTURE_MAX_ANISOTROPY_EXT pname works as expected.
 *
 *  @param gl   OpenGL functions wrapper
 *
 *  @return Returns true if queries test passed, false otherwise.
 */
bool TextureFilterAnisotropicQueriesTestCase::verifyTexParameters(const glw::Functions& gl)
{
	GLint iValue;
	gl.getTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv");

	// Verify initial integer value which should be equal to 1
	if (iValue != 1)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "GetTexParameteriv failed. Expected value: 1, Queried value: " << iValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	GLfloat fValue;
	gl.getTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameterfv");

	// Verify initial float value which should be equal to 1.0f
	if (fValue != 1.0f)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "GetTexParameterfv failed. Expected value: 1.0, Queried value: " << iValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	// Set custom integer value and verify it
	iValue = 2;
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, iValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");

	gl.getTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv");

	if (iValue != 2)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "texParameteri failed. Expected value: 2, Queried value: " << iValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	// Set custom float value and verify it
	fValue = 1.5f;
	gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texParameterf");

	gl.getTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameterfv");

	if (fValue != 1.5f)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "texParameterf failed. Expected value: 1.5, Queried value: " << fValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	// Set custom integer value and verify it
	iValue = 1;
	gl.texParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteriv");

	gl.getTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv");

	if (iValue != 1)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "texParameteriv failed. Expected value: 1, Queried value: " << iValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	// Set custom float value and verify it
	fValue = 2.0f;
	gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texParameterfv");

	gl.getTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameterfv");

	if (fValue != 2.0f)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "texParameterfv failed. Expected value: 2.0, Queried value: " << fValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	// Set texture filter anisotropic to 0.9f and check if INVALID_VALUE error is generated
	fValue = 0.9f;
	gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue);
	GLint error = gl.getError();
	if (error != GL_INVALID_VALUE)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "texParameterfv failed for values less then 1.0f. Expected INVALID_VALUE error. Generated error: "
			<< glu::getErrorName(error) << tcu::TestLog::EndMessage;
		return false;
	}

	return true;
}

/** Verify if get* queries for GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT pname works as expected.
 *
 *  @param gl   OpenGL functions wrapper
 *
 *  @return Returns true if queries test passed, false otherwise.
 */
bool TextureFilterAnisotropicQueriesTestCase::verifyGet(const glw::Functions& gl)
{
	GLboolean bValue;
	GLint	 iValue;
	GLfloat   fValue;
	GLdouble  dValue;

	gl.getBooleanv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &bValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv");

	gl.getIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &iValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");

	gl.getFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getFloatv");

	if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
	{
		gl.getDoublev(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &dValue);
		GLU_EXPECT_NO_ERROR(gl.getError(), "getDoublev");
	}

	return true;
}

/** Constructor.
 *
 *  @param context     Rendering context
 */
TextureFilterAnisotropicDrawingTestCase::TextureFilterAnisotropicDrawingTestCase(deqp::Context& context)
	: TestCase(context, "drawing", "Verifies if drawing texture with anisotropic filtering is performed as expected")
	, m_vertex(DE_NULL)
	, m_fragment(DE_NULL)
	, m_texture(0)
{
	/* Left blank intentionally */
}

/** Stub deinit method. */
void TextureFilterAnisotropicDrawingTestCase::deinit()
{
	/* Left blank intentionally */
}

/** Stub init method */
void TextureFilterAnisotropicDrawingTestCase::init()
{
	glu::ContextType contextType = m_context.getRenderContext().getType();
	if (!glu::contextSupports(contextType, glu::ApiType::core(4, 6)) &&
		!m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_filter_anisotropic") &&
		!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_filter_anisotropic"))
	{
		TCU_THROW(NotSupportedError, "texture filter anisotropic functionality not supported");
	}

	const tcu::RenderTarget& rt = m_context.getRenderTarget();

	GLint width  = rt.getWidth();
	GLint height = rt.getHeight();

	if (width < 32 || height < 32)
		TCU_THROW(NotSupportedError, "Config not supported - render buffer size should be at least 32x32");

	m_vertex = "#version <VERSION>\n"
			   "\n"
			   "in highp vec3 vertex;\n"
			   "in highp <TEXCOORD_TYPE> inTexCoord;\n"
			   "out highp <TEXCOORD_TYPE> commonTexCoord;\n"
			   "\n"
			   "uniform highp mat4 projectionMatrix;\n"
			   "\n"
			   "void main()\n"
			   "{\n"
			   "    commonTexCoord = inTexCoord;\n"
			   "    gl_Position = vec4(vertex, 1.0) * projectionMatrix;\n"
			   "}\n";

	m_fragment = "#version <VERSION>\n"
				 "\n"
				 "in highp <TEXCOORD_TYPE> commonTexCoord;\n"
				 "out highp vec4 fragColor;\n"
				 "\n"
				 "uniform highp <SAMPLER_TYPE> tex;\n"
				 "\n"
				 "void main()\n"
				 "{\n"
				 "    fragColor = texture(tex, commonTexCoord);\n"
				 "}\n"
				 "\n";

	m_supportedTargets.clear();
	m_supportedTargets.push_back(GL_TEXTURE_2D);
	m_supportedTargets.push_back(GL_TEXTURE_2D_ARRAY);

	m_supportedInternalFormats.clear();
	m_supportedInternalFormats.push_back(GL_R8);
	m_supportedInternalFormats.push_back(GL_R8_SNORM);
	m_supportedInternalFormats.push_back(GL_RG8);
	m_supportedInternalFormats.push_back(GL_RG8_SNORM);
	m_supportedInternalFormats.push_back(GL_RGB8);
	m_supportedInternalFormats.push_back(GL_RGB8_SNORM);
	m_supportedInternalFormats.push_back(GL_RGB565);
	m_supportedInternalFormats.push_back(GL_RGBA4);
	m_supportedInternalFormats.push_back(GL_RGB5_A1);
	m_supportedInternalFormats.push_back(GL_RGBA8);
	m_supportedInternalFormats.push_back(GL_RGBA8_SNORM);
	m_supportedInternalFormats.push_back(GL_RGB10_A2);
	m_supportedInternalFormats.push_back(GL_SRGB8);
	m_supportedInternalFormats.push_back(GL_SRGB8_ALPHA8);
	m_supportedInternalFormats.push_back(GL_R16F);
	m_supportedInternalFormats.push_back(GL_RG16F);
	m_supportedInternalFormats.push_back(GL_RGB16F);
	m_supportedInternalFormats.push_back(GL_RGBA16F);
	m_supportedInternalFormats.push_back(GL_R11F_G11F_B10F);
	m_supportedInternalFormats.push_back(GL_RGB9_E5);
}

/** Executes test iteration.
 *
 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
 */
tcu::TestNode::IterateResult TextureFilterAnisotropicDrawingTestCase::iterate()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bool result = true;

	GLfloat maxAnisoDegree = 2.0;

	gl.getFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisoDegree);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getFloatv");

	std::vector<GLfloat> anisoVec;
	anisoVec.push_back(1.0f);
	anisoVec.push_back(2.0f);

	for (deUint32 iTarget = 0; iTarget < m_supportedTargets.size(); ++iTarget)
	{
		GLenum target = m_supportedTargets[iTarget];

		for (deUint32 iFormat = 0; iFormat < m_supportedInternalFormats.size(); ++iFormat)
		{
			GLenum format = m_supportedInternalFormats[iFormat];

			// Generate texture
			generateTexture(gl, target);

			// Fill texture with strips pattern
			fillTexture(gl, target, format);

			// Draw scene
			GLuint lastPoints = 0xFFFFFFFF;
			for (deUint32 i = 0; i < anisoVec.size(); ++i)
			{
				GLfloat aniso = anisoVec[i];

				if (result)
					result = result && drawTexture(gl, target, aniso);

				// Verify result
				if (result)
				{
					GLuint currentPoints = verifyScene(gl);

					if (lastPoints <= currentPoints)
					{
						m_testCtx.getLog()
							<< tcu::TestLog::Message
							<< "Anisotropy verification failed (lastPoints <= currentPoints) for "
							<< "anisotropy: " << aniso << ", "
							<< "target: " << glu::getTextureTargetName(target) << ", "
							<< "internalFormat: " << glu::getUncompressedTextureFormatName(format) << ", "
							<< "lastPoints: " << lastPoints << ", "
							<< "currentPoints: " << currentPoints << tcu::TestLog::EndMessage;

						result = false;
						break;
					}

					lastPoints = currentPoints;
				}
			}

			// Release texture
			releaseTexture(gl);

			if (!result)
			{
				// Stop loops
				iTarget = static_cast<deUint32>(m_supportedTargets.size());
				iFormat = static_cast<deUint32>(m_supportedInternalFormats.size());
			}
		}
	}

	if (result)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	return STOP;
}

/** Generate texture and set filtering parameters.
 *
 *  @param gl              OpenGL functions wrapper
 *  @param target          Texture target
 *  @param internalFormat  Texture internal format
 */
void TextureFilterAnisotropicDrawingTestCase::generateTexture(const glw::Functions& gl, GLenum target)
{
	gl.genTextures(1, &m_texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures");
	gl.bindTexture(target, m_texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");

	gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
}

/** Fill texture with strips pattern.
 *
 *  @param gl              OpenGL functions wrapper
 *  @param target          Texture target
 *  @param internalFormat  Texture internal format
 */
void TextureFilterAnisotropicDrawingTestCase::fillTexture(const glw::Functions& gl, GLenum target,
														  GLenum internalFormat)
{
	tcu::TextureFormat  texFormat   = glu::mapGLInternalFormat(internalFormat);
	glu::TransferFormat transFormat = glu::getTransferFormat(texFormat);

	for (int l = 0; l < 2; ++l)
	{
		GLuint texSize = 32 / (l + 1);

		std::vector<GLubyte> vecData;
		vecData.resize(texSize * texSize * texFormat.getPixelSize() * 2);

		tcu::PixelBufferAccess bufferAccess(texFormat, texSize, texSize, 1, vecData.data());

		for (GLuint x = 0; x < texSize; ++x)
		{
			for (GLuint y = 0; y < texSize; ++y)
			{
				int		  value = ((x * (l + 1)) % 8 < 4) ? 255 : 0;
				tcu::RGBA rgbaColor(value, value, value, 255);
				tcu::Vec4 color = rgbaColor.toVec();
				bufferAccess.setPixel(color, x, y);
			}
		}

		TextureFilterAnisotropicUtils::texImage(gl, target, l, internalFormat, texSize, texSize, 1, transFormat.format,
												transFormat.dataType, vecData.data());
	}
}

/** Render polygon with anisotropic filtering.
 *
 *  @param gl           OpenGL functions wrapper
 *  @param target       Texture target
 *  @param anisoDegree  Degree of anisotropy
 *
 *  @return Returns true if no error occured, false otherwise.
 */
bool TextureFilterAnisotropicDrawingTestCase::drawTexture(const glw::Functions& gl, GLenum target, GLfloat anisoDegree)
{
	const GLfloat vertices2[] = { -1.0f, 0.0f, -0.5f, 0.0f, 0.0f, -4.0f, 4.0f, -2.0f, 0.0f, 1.0f,
								  1.0f,  0.0f, -0.5f, 1.0f, 0.0f, -2.0f, 4.0f, -2.0f, 1.0f, 1.0f };
	const GLfloat vertices3[] = { -1.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, -4.0f, 4.0f, -2.0f, 0.0f, 1.0f, 0.0f,
								  1.0f,  0.0f, -0.5f, 1.0f, 0.0f, 0.0f, -2.0f, 4.0f, -2.0f, 1.0f, 1.0f, 0.0f };

	// Projection values.
	const GLfloat projectionMatrix[] = { 0.5f, 0.0f, 0.0f,		   0.0f,		 0.0f, 0.5f, 0.0f,  0.0f,
										 0.0f, 0.0f, -2.5f / 1.5f, -2.0f / 1.5f, 0.0f, 0.0f, -1.0f, 0.0f };

	gl.viewport(0, 0, 32, 32);

	std::string vertexShader   = m_vertex;
	std::string fragmentShader = m_fragment;

	std::string texCoordType;
	std::string samplerType;
	TextureFilterAnisotropicUtils::generateTokens(target, texCoordType, samplerType);

	TextureFilterAnisotropicUtils::replaceToken("<TEXCOORD_TYPE>", texCoordType.c_str(), vertexShader);
	TextureFilterAnisotropicUtils::replaceToken("<TEXCOORD_TYPE>", texCoordType.c_str(), fragmentShader);
	TextureFilterAnisotropicUtils::replaceToken("<SAMPLER_TYPE>", samplerType.c_str(), vertexShader);
	TextureFilterAnisotropicUtils::replaceToken("<SAMPLER_TYPE>", samplerType.c_str(), fragmentShader);

	if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
	{
		TextureFilterAnisotropicUtils::replaceToken("<VERSION>", "130", vertexShader);
		TextureFilterAnisotropicUtils::replaceToken("<VERSION>", "130", fragmentShader);
	}
	else
	{
		TextureFilterAnisotropicUtils::replaceToken("<VERSION>", "300 es", vertexShader);
		TextureFilterAnisotropicUtils::replaceToken("<VERSION>", "300 es", fragmentShader);
	}

	ProgramSources sources = makeVtxFragSources(vertexShader, fragmentShader);
	ShaderProgram  program(gl, sources);

	if (!program.isOk())
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
						   << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
						   << vertexShader << "\n"
						   << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
						   << fragmentShader << "\n"
						   << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
		return false;
	}

	GLuint vao;
	gl.genVertexArrays(1, &vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
	gl.bindVertexArray(vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");

	GLuint vbo;
	gl.genBuffers(1, &vbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
	gl.bindBuffer(GL_ARRAY_BUFFER, vbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");

	std::vector<GLfloat> vboData;
	vboData.resize(24);

	GLuint texCoordDim;
	if (texCoordType == "vec2")
	{
		texCoordDim = 2;
		deMemcpy((void*)vboData.data(), (void*)vertices2, sizeof(vertices2));
	}
	else
	{
		texCoordDim = 3;
		deMemcpy((void*)vboData.data(), (void*)vertices3, sizeof(vertices3));
	}

	gl.bufferData(GL_ARRAY_BUFFER, vboData.size() * sizeof(GLfloat), (GLvoid*)vboData.data(), GL_DYNAMIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");

	gl.useProgram(program.getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");

	GLuint matrixLocation = gl.getUniformLocation(program.getProgram(), "projectionMatrix");
	GLuint texLocation	= gl.getUniformLocation(program.getProgram(), "tex");

	gl.activeTexture(GL_TEXTURE0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
	gl.bindTexture(target, m_texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
	gl.uniformMatrix4fv(matrixLocation, 1, GL_FALSE, projectionMatrix);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformMatrix4fv");
	gl.uniform1i(texLocation, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");

	gl.texParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoDegree);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texParameterfv");

	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
	gl.clear(GL_COLOR_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");

	gl.enableVertexAttribArray(0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
	gl.enableVertexAttribArray(1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");

	GLint attrLocationVertex = gl.getAttribLocation(program.getProgram(), "vertex");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation");
	GLint attrLocationInTexCoord = gl.getAttribLocation(program.getProgram(), "inTexCoord");
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation");

	GLuint strideSize = (3 + texCoordDim) * sizeof(GLfloat);
	gl.vertexAttribPointer(attrLocationVertex, 3, GL_FLOAT, GL_FALSE, strideSize, DE_NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
	gl.vertexAttribPointer(attrLocationInTexCoord, texCoordDim, GL_FLOAT, GL_FALSE, strideSize,
						   (GLvoid*)(3 * sizeof(GLfloat)));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");

	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");

	gl.disableVertexAttribArray(0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
	gl.disableVertexAttribArray(1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");

	if (vbo)
	{
		gl.deleteBuffers(1, &vbo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
	}

	if (vao)
	{
		gl.deleteVertexArrays(1, &vao);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
	}

	return true;
}

/** Verify rendered polygon anisotropy.
 *
 *  @param gl  OpenGL functions wrapper
 *
 *  @return Returns points value. Less points means better anisotropy (smoother strips).
 */
GLuint TextureFilterAnisotropicDrawingTestCase::verifyScene(const glw::Functions& gl)
{
	std::vector<GLubyte> pixels;
	pixels.resize(32 * 8 * 4);

	gl.readPixels(0, 23, 32, 8, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");

	GLuint sum = 0;

	GLubyte last	= 0;
	GLubyte current = 0;
	for (int j = 0; j < 8; ++j)
	{
		for (int i = 0; i < 32; ++i)
		{
			current = pixels[(i + j * 32) * 4];

			if (i > 0)
				sum += deAbs32((int)current - (int)last);

			last = current;
		}
	}

	return sum;
}

/** Release texture.
 *
 *  @param gl  OpenGL functions wrapper
 */
void TextureFilterAnisotropicDrawingTestCase::releaseTexture(const glw::Functions& gl)
{
	if (m_texture)
		gl.deleteTextures(1, &m_texture);

	m_texture = 0;
}

/** Constructor.
 *
 *  @param context Rendering context.
 */
TextureFilterAnisotropicTests::TextureFilterAnisotropicTests(deqp::Context& context)
	: TestCaseGroup(context, "texture_filter_anisotropic",
					"Verify conformance of CTS_EXT_texture_filter_anisotropic implementation")
{
}

/** Initializes the test group contents. */
void TextureFilterAnisotropicTests::init()
{
	addChild(new TextureFilterAnisotropicQueriesTestCase(m_context));
	addChild(new TextureFilterAnisotropicDrawingTestCase(m_context));
}

} /* glcts namespace */
