/*-------------------------------------------------------------------------
 * 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 Sampler object testcases.
 *//*--------------------------------------------------------------------*/

#include "glsSamplerObjectTest.hpp"

#include "tcuTexture.hpp"
#include "tcuSurface.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuTestLog.hpp"
#include "tcuRGBA.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"

#include "gluShaderProgram.hpp"
#include "gluPixelTransfer.hpp"
#include "gluDrawUtil.hpp"
#include "gluRenderContext.hpp"
#include "gluTextureUtil.hpp"

#include "glwFunctions.hpp"

#include "deRandom.hpp"
#include "deString.h"

#include "deString.h"

#include <map>

namespace deqp
{
namespace gls
{

namespace
{
const int VIEWPORT_WIDTH	= 128;
const int VIEWPORT_HEIGHT	= 128;

const int TEXTURE2D_WIDTH	= 32;
const int TEXTURE2D_HEIGHT	= 32;

const int TEXTURE3D_WIDTH	= 32;
const int TEXTURE3D_HEIGHT	= 32;
const int TEXTURE3D_DEPTH	= 32;

const int CUBEMAP_SIZE		= 32;

} // anonymous


TextureSamplerTest::TextureSamplerTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const TestSpec& spec)
	: tcu::TestCase		(testCtx, spec.name, spec.desc)
	, m_renderCtx		(renderCtx)
	, m_program			(NULL)
	, m_target			(spec.target)
	, m_textureState	(spec.textureState)
	, m_samplerState	(spec.samplerState)
	, m_random			(deStringHash(spec.name))
{
}

void TextureSamplerTest::setTextureState (const glw::Functions& gl, GLenum target, SamplingState state)
{
	gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter)");
	gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter)");
	gl.texParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS)");
	gl.texParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT)");
	gl.texParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR)");
	gl.texParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod)");
	gl.texParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod)");
}

void TextureSamplerTest::setSamplerState (const glw::Functions& gl, SamplingState state, GLuint sampler)
{
	gl.samplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter)");
	gl.samplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter)");
	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS)");
	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT)");
	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR)");
	gl.samplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod)");
	gl.samplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod)");
}

const char* TextureSamplerTest::selectVertexShader (GLenum target)
{
	switch (target)
	{
		case GL_TEXTURE_2D:
			return
			"${VTX_HDR}"
			"${VTX_IN} ${HIGHP} vec2 a_position;\n"
			"uniform ${HIGHP} float u_posScale;\n"
			"${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\tv_texCoord = a_position;\n"
			"\tgl_Position = vec4(u_posScale * a_position, 0.0, 1.0);\n"
			"}";

		case GL_TEXTURE_3D:
			return
			"${VTX_HDR}"
			"${VTX_IN} ${HIGHP} vec3 a_position;\n"
			"uniform ${HIGHP} float u_posScale;\n"
			"${VTX_OUT} ${MEDIUMP} vec3 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\tv_texCoord = a_position;\n"
			"\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
			"}";

		case GL_TEXTURE_CUBE_MAP:
			return
			"${VTX_HDR}"
			"${VTX_IN} ${HIGHP} vec4 a_position;\n"
			"uniform ${HIGHP} float u_posScale;\n"
			"${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\tv_texCoord = a_position.zw;\n"
			"\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
			"}";

		default:
			DE_ASSERT(false);
			return NULL;
	}
}

const char* TextureSamplerTest::selectFragmentShader (GLenum target)
{
	switch (target)
	{
		case GL_TEXTURE_2D:
			return
			"${FRAG_HDR}"
			"uniform ${LOWP} sampler2D u_sampler;\n"
			"${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\t${FRAG_COLOR} = texture(u_sampler, v_texCoord);\n"
			"}";

		case GL_TEXTURE_3D:
			return
			"${FRAG_HDR}"
			"uniform ${LOWP} sampler3D u_sampler;\n"
			"${FRAG_IN} ${MEDIUMP} vec3 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\t${FRAG_COLOR} = texture(u_sampler, v_texCoord);\n"
			"}";

		case GL_TEXTURE_CUBE_MAP:
			return
			"${FRAG_HDR}"
			"uniform ${LOWP} samplerCube u_sampler;\n"
			"${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\t${FRAG_COLOR} = texture(u_sampler, vec3(cos(3.14 * v_texCoord.y) * sin(3.14 * v_texCoord.x), sin(3.14 * v_texCoord.y), cos(3.14 * v_texCoord.y) * cos(3.14 * v_texCoord.x)));\n"
			"}";

		default:
			DE_ASSERT(false);
			return NULL;
	}
}

void TextureSamplerTest::init (void)
{
	const char* vertexShaderTemplate	= selectVertexShader(m_target);
	const char* fragmentShaderTemplate	= selectFragmentShader(m_target);

	std::map<std::string, std::string>	params;

	if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_300_ES))
	{
		params["VTX_HDR"]		= "#version 300 es\n";
		params["FRAG_HDR"]		= "#version 300 es\nlayout(location = 0) out mediump vec4 o_color;\n";
		params["VTX_IN"]		= "in";
		params["VTX_OUT"]		= "out";
		params["FRAG_IN"]		= "in";
		params["FRAG_COLOR"]	= "o_color";
		params["HIGHP"]			= "highp";
		params["LOWP"]			= "lowp";
		params["MEDIUMP"]		= "mediump";
	}
	else if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_330))
	{
		params["VTX_HDR"]		= "#version 330\n";
		params["FRAG_HDR"]		= "#version 330\nlayout(location = 0) out mediump vec4 o_color;\n";
		params["VTX_IN"]		= "in";
		params["VTX_OUT"]		= "out";
		params["FRAG_IN"]		= "in";
		params["FRAG_COLOR"]	= "o_color";
		params["HIGHP"]			= "highp";
		params["LOWP"]			= "lowp";
		params["MEDIUMP"]		= "mediump";
	}
	else
		DE_ASSERT(false);

	DE_ASSERT(!m_program);
	m_program = new glu::ShaderProgram(m_renderCtx,
									   glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderTemplate).specialize(params),
															   tcu::StringTemplate(fragmentShaderTemplate).specialize(params)));

	if (!m_program->isOk())
	{
		tcu::TestLog& log = m_testCtx.getLog();
		log << *m_program;
		TCU_FAIL("Failed to compile shaders");
	}
}

void TextureSamplerTest::deinit (void)
{
	delete m_program;
	m_program = NULL;
}

TextureSamplerTest::~TextureSamplerTest (void)
{
	deinit();
}

const float s_positions[] = {
	-1.0, -1.0,
	 1.0, -1.0,
	 1.0,  1.0,

	 1.0,  1.0,
	-1.0,  1.0,
	-1.0, -1.0
};

const float s_positions3D[] = {
	-1.0f, -1.0f, -1.0f,
	 1.0f, -1.0f,  1.0f,
	 1.0f,  1.0f, -1.0f,

	 1.0f,  1.0f, -1.0f,
	-1.0f,  1.0f,  1.0f,
	-1.0f, -1.0f, -1.0f
};

const float s_positionsCube[] = {
	-1.0f, -1.0f, -1.0f, -0.5f,
	 1.0f, -1.0f,  1.0f, -0.5f,
	 1.0f,  1.0f,  1.0f,  0.5f,

	 1.0f,  1.0f,  1.0f,  0.5f,
	-1.0f,  1.0f, -1.0f,  0.5f,
	-1.0f, -1.0f, -1.0f, -0.5f
};

void TextureSamplerTest::render (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	GLuint	samplerLoc	= (GLuint)-1;
	GLuint	scaleLoc	= (GLuint)-1;

	gl.useProgram(m_program->getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram(m_program->getProgram())");

	samplerLoc = gl.getUniformLocation(m_program->getProgram(), "u_sampler");
	TCU_CHECK(samplerLoc != (GLuint)-1);

	scaleLoc = gl.getUniformLocation(m_program->getProgram(), "u_posScale");
	TCU_CHECK(scaleLoc != (GLuint)-1);

	gl.clearColor(0.5f, 0.5f, 0.5f, 1.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor(0.5f, 0.5f, 0.5f, 1.0f)");

	gl.clear(GL_COLOR_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear(GL_COLOR_BUFFER_BIT)");

	gl.uniform1i(samplerLoc, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i(samplerLoc, 0)");

	gl.uniform1f(scaleLoc, 1.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 1.0f)");

	switch (m_target)
	{
		case GL_TEXTURE_2D:
		{
			glu::VertexArrayBinding vertexArrays[] =
			{
				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 2, 6, 0, s_positions))
			};

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			gl.uniform1f(scaleLoc, 0.25f);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			break;
		}

		case GL_TEXTURE_3D:
		{
			glu::VertexArrayBinding vertexArrays[] =
			{
				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 3, 6, 0, s_positions3D))
			};

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			gl.uniform1f(scaleLoc, 0.25f);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			break;
		}

		case GL_TEXTURE_CUBE_MAP:
		{
			glu::VertexArrayBinding vertexArrays[] =
			{
				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 4, 6, 0, s_positionsCube))
			};

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			gl.uniform1f(scaleLoc, 0.25f);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			break;
		}

		default:
			DE_ASSERT(false);
	}
}

GLuint TextureSamplerTest::createTexture2D (const glw::Functions& gl)
{
	GLuint			texture		= (GLuint)-1;
	tcu::Texture2D	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE2D_WIDTH, TEXTURE2D_HEIGHT);

	refTexture.allocLevel(0);
	tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));

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

	gl.bindTexture(GL_TEXTURE_2D, texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, texture)");

	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");

	gl.generateMipmap(GL_TEXTURE_2D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_2D)");

	gl.bindTexture(GL_TEXTURE_2D, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, texture)");

	return texture;
}

GLuint TextureSamplerTest::createTexture3D (const glw::Functions& gl)
{
	GLuint			texture		= (GLuint)-1;
	tcu::Texture3D	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE3D_WIDTH, TEXTURE3D_HEIGHT, TEXTURE3D_DEPTH);

	refTexture.allocLevel(0);
	tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));

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

	gl.bindTexture(GL_TEXTURE_3D, texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, texture)");

	gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");

	gl.generateMipmap(GL_TEXTURE_3D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_3D)");

	gl.bindTexture(GL_TEXTURE_3D, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, 0)");

	return texture;
}

GLuint TextureSamplerTest::createTextureCube (const glw::Functions& gl)
{
	GLuint				texture		= (GLuint)-1;
	tcu::TextureCube	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), CUBEMAP_SIZE);

	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_X, 0);
	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Y, 0);
	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Z, 0);
	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_X, 0);
	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Y, 0);
	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Z, 0);

	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));

	gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, texture)");

	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
	{
		const deUint32 target = glu::getGLCubeFace((tcu::CubeFace)face);
		gl.texImage2D(target, 0, GL_RGBA8, refTexture.getSize(), refTexture.getSize(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevelFace(0, (tcu::CubeFace)face).getDataPtr());
	}
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_CUBE_MAP_...) failed");

	gl.generateMipmap(GL_TEXTURE_CUBE_MAP);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_CUBE_MAP)");
	gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, texture)");

	return texture;
}

GLuint TextureSamplerTest::createTexture (const glw::Functions& gl, GLenum target)
{
	switch (target)
	{
		case GL_TEXTURE_2D:
			return createTexture2D(gl);

		case GL_TEXTURE_3D:
			return createTexture3D(gl);

		case GL_TEXTURE_CUBE_MAP:
			return createTextureCube(gl);

		default:
			DE_ASSERT(false);
			return (GLuint)-1;
	}
}

void TextureSamplerTest::renderReferences (tcu::Surface& textureRef, tcu::Surface& samplerRef, int x, int y)
{
	const glw::Functions&	gl		= m_renderCtx.getFunctions();
	GLuint					texture	= createTexture(gl, m_target);

	gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");

	gl.bindTexture(m_target, texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture)");

	setTextureState(gl, m_target, m_textureState);
	render();
	glu::readPixels(m_renderCtx, x, y, textureRef.getAccess());

	setTextureState(gl, m_target, m_samplerState);
	render();
	glu::readPixels(m_renderCtx, x, y, samplerRef.getAccess());

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

void TextureSamplerTest::renderResults (tcu::Surface& textureResult, tcu::Surface& samplerResult, int x, int y)
{
	const glw::Functions&	gl		= m_renderCtx.getFunctions();
	GLuint					texture	= createTexture(gl, m_target);
	GLuint					sampler	= -1;

	gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");

	gl.genSamplers(1, &sampler);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenSamplers(1, &sampler)");
	TCU_CHECK(sampler != (GLuint)-1);

	gl.bindSampler(0, sampler);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, sampler)");

	// First set sampler state
	setSamplerState(gl, m_samplerState, sampler);

	// Set texture state
	gl.bindTexture(m_target, texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture)");

	setTextureState(gl, m_target, m_textureState);

	// Render using sampler
	render();
	glu::readPixels(m_renderCtx, x, y, samplerResult.getAccess());

	// Render without sampler
	gl.bindSampler(0, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, 0)");

	render();
	glu::readPixels(m_renderCtx, x, y, textureResult.getAccess());

	gl.deleteSamplers(1, &sampler);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteSamplers(1, &sampler)");
	gl.deleteTextures(1, &texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures(1, &texture)");
}

tcu::TestCase::IterateResult TextureSamplerTest::iterate (void)
{
	tcu::TestLog&	log = m_testCtx.getLog();

	tcu::Surface	textureRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	tcu::Surface	samplerRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);

	tcu::Surface	textureResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	tcu::Surface	samplerResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);

	int				x = m_random.getInt(0, m_renderCtx.getRenderTarget().getWidth() - VIEWPORT_WIDTH);
	int				y = m_random.getInt(0, m_renderCtx.getRenderTarget().getHeight() - VIEWPORT_HEIGHT);

	renderReferences(textureRef, samplerRef, x, y);
	renderResults(textureResult, samplerResult, x, y);

	bool isOk = pixelThresholdCompare (log, "Sampler render result", "Result from rendering with sampler", samplerRef, samplerResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);

	if (!pixelThresholdCompare (log, "Texture render result", "Result from rendering with texture state", textureRef, textureResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT))
		isOk = false;

	if (!isOk)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		return STOP;
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}

MultiTextureSamplerTest::MultiTextureSamplerTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const TestSpec& spec)
	: TestCase			(testCtx, spec.name, spec.desc)
	, m_renderCtx		(renderCtx)
	, m_program			(NULL)
	, m_target			(spec.target)
	, m_textureState1	(spec.textureState1)
	, m_textureState2	(spec.textureState2)
	, m_samplerState	(spec.samplerState)
	, m_random			(deStringHash(spec.name))
{
}

void MultiTextureSamplerTest::setTextureState (const glw::Functions& gl, GLenum target, SamplingState state)
{
	gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter)");
	gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter)");
	gl.texParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS)");
	gl.texParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT)");
	gl.texParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR)");
	gl.texParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod)");
	gl.texParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod)");
}

void MultiTextureSamplerTest::setSamplerState (const glw::Functions& gl, SamplingState state, GLuint sampler)
{
	gl.samplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter)");
	gl.samplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter)");
	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS)");
	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT)");
	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR)");
	gl.samplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod)");
	gl.samplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod)");
}

const char* MultiTextureSamplerTest::selectVertexShader (GLenum target)
{
	switch (target)
	{
		case GL_TEXTURE_2D:
			return
			"${VTX_HDR}"
			"${VTX_IN} ${HIGHP} vec2 a_position;\n"
			"uniform ${HIGHP} float u_posScale;\n"
			"${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\tv_texCoord = a_position;\n"
			"\tgl_Position = vec4(u_posScale * a_position, 0.0, 1.0);\n"
			"}";

		case GL_TEXTURE_3D:
			return
			"${VTX_HDR}"
			"${VTX_IN} ${HIGHP} vec3 a_position;\n"
			"uniform ${HIGHP} float u_posScale;\n"
			"${VTX_OUT} ${MEDIUMP} vec3 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\tv_texCoord = a_position;\n"
			"\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
			"}";

		case GL_TEXTURE_CUBE_MAP:
			return
			"${VTX_HDR}"
			"${VTX_IN} ${HIGHP} vec4 a_position;\n"
			"uniform ${HIGHP} float u_posScale;\n"
			"${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\tv_texCoord = a_position.zw;\n"
			"\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
			"}";

		default:
			DE_ASSERT(false);
			return NULL;
	}

}

const char* MultiTextureSamplerTest::selectFragmentShader (GLenum target)
{
	switch (target)
	{
		case GL_TEXTURE_2D:
			return
			"${FRAG_HDR}"
			"uniform ${LOWP} sampler2D u_sampler1;\n"
			"uniform ${LOWP} sampler2D u_sampler2;\n"
			"${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\t${FRAG_COLOR} = vec4(0.75, 0.75, 0.75, 1.0) * (texture(u_sampler1, v_texCoord) + texture(u_sampler2, v_texCoord));\n"
			"}";

			break;

		case GL_TEXTURE_3D:
			return
			"${FRAG_HDR}"
			"uniform ${LOWP} sampler3D u_sampler1;\n"
			"uniform ${LOWP} sampler3D u_sampler2;\n"
			"${FRAG_IN} ${MEDIUMP} vec3 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\t${FRAG_COLOR} = vec4(0.75, 0.75, 0.75, 1.0) * (texture(u_sampler1, v_texCoord) + texture(u_sampler2, v_texCoord));\n"
			"}";

		case GL_TEXTURE_CUBE_MAP:
			return
			"${FRAG_HDR}"
			"uniform ${LOWP} samplerCube u_sampler1;\n"
			"uniform ${LOWP} samplerCube u_sampler2;\n"
			"${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\t${FRAG_COLOR} = vec4(0.5, 0.5, 0.5, 1.0) * (texture(u_sampler1, vec3(cos(3.14 * v_texCoord.y) * sin(3.14 * v_texCoord.x), sin(3.14 * v_texCoord.y), cos(3.14 * v_texCoord.y) * cos(3.14 * v_texCoord.x)))"
			"+ texture(u_sampler2, vec3(cos(3.14 * v_texCoord.y) * sin(3.14 * v_texCoord.x), sin(3.14 * v_texCoord.y), cos(3.14 * v_texCoord.y) * cos(3.14 * v_texCoord.x))));\n"
			"}";

		default:
			DE_ASSERT(false);
			return NULL;
	}

}

void MultiTextureSamplerTest::init (void)
{
	const char* vertexShaderTemplate	= selectVertexShader(m_target);
	const char* fragmentShaderTemplate	= selectFragmentShader(m_target);

	std::map<std::string, std::string>	params;

	if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_300_ES))
	{
		params["VTX_HDR"]		= "#version 300 es\n";
		params["FRAG_HDR"]		= "#version 300 es\nlayout(location = 0) out mediump vec4 o_color;\n";
		params["VTX_IN"]		= "in";
		params["VTX_OUT"]		= "out";
		params["FRAG_IN"]		= "in";
		params["FRAG_COLOR"]	= "o_color";
		params["HIGHP"]			= "highp";
		params["LOWP"]			= "lowp";
		params["MEDIUMP"]		= "mediump";
	}
	else if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_330))
	{
		params["VTX_HDR"]		= "#version 330\n";
		params["FRAG_HDR"]		= "#version 330\nlayout(location = 0) out mediump vec4 o_color;\n";
		params["VTX_IN"]		= "in";
		params["VTX_OUT"]		= "out";
		params["FRAG_IN"]		= "in";
		params["FRAG_COLOR"]	= "o_color";
		params["HIGHP"]			= "highp";
		params["LOWP"]			= "lowp";
		params["MEDIUMP"]		= "mediump";
	}
	else
		DE_ASSERT(false);

	DE_ASSERT(!m_program);
	m_program = new glu::ShaderProgram(m_renderCtx,
									   glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderTemplate).specialize(params),
															   tcu::StringTemplate(fragmentShaderTemplate).specialize(params)));
	if (!m_program->isOk())
	{
		tcu::TestLog& log = m_testCtx.getLog();

		log << *m_program;
		TCU_FAIL("Failed to compile shaders");
	}
}

void MultiTextureSamplerTest::deinit (void)
{
	delete m_program;
	m_program = NULL;
}

MultiTextureSamplerTest::~MultiTextureSamplerTest (void)
{
	deinit();
}

void MultiTextureSamplerTest::render (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	GLuint	samplerLoc1	= (GLuint)-1;
	GLuint	samplerLoc2	= (GLuint)-1;
	GLuint	scaleLoc	= (GLuint)-1;

	gl.useProgram(m_program->getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram(m_program->getProgram())");

	samplerLoc1 = glGetUniformLocation(m_program->getProgram(), "u_sampler1");
	TCU_CHECK(samplerLoc1 != (GLuint)-1);

	samplerLoc2 = glGetUniformLocation(m_program->getProgram(), "u_sampler2");
	TCU_CHECK(samplerLoc2 != (GLuint)-1);

	scaleLoc = glGetUniformLocation(m_program->getProgram(), "u_posScale");
	TCU_CHECK(scaleLoc != (GLuint)-1);

	gl.clearColor(0.5f, 0.5f, 0.5f, 1.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor(0.5f, 0.5f, 0.5f, 1.0f)");

	gl.clear(GL_COLOR_BUFFER_BIT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear(GL_COLOR_BUFFER_BIT)");

	gl.uniform1i(samplerLoc1, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i(samplerLoc1, 0)");

	gl.uniform1i(samplerLoc2, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i(samplerLoc2, 1)");

	gl.uniform1f(scaleLoc, 1.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 1.0f)");

	switch (m_target)
	{
		case GL_TEXTURE_2D:
		{
			glu::VertexArrayBinding vertexArrays[] =
			{
				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 2, 6, 0, s_positions))
			};

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			gl.uniform1f(scaleLoc, 0.25f);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			break;
		}

		case GL_TEXTURE_3D:
		{
			glu::VertexArrayBinding vertexArrays[] =
			{
				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 3, 6, 0, s_positions3D))
			};

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			gl.uniform1f(scaleLoc, 0.25f);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			break;
		}

		case GL_TEXTURE_CUBE_MAP:
		{
			glu::VertexArrayBinding vertexArrays[] =
			{
				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 4, 6, 0, s_positionsCube))
			};

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			gl.uniform1f(scaleLoc, 0.25f);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");

			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));

			break;
		}

		default:
			DE_ASSERT(false);
	}
}

GLuint MultiTextureSamplerTest::createTexture2D (const glw::Functions& gl, int id)
{
	GLuint			texture		= (GLuint)-1;
	tcu::Texture2D	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE2D_WIDTH, TEXTURE2D_HEIGHT);

	refTexture.allocLevel(0);

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

	switch (id)
	{
		case 0:
			tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.5f, 0.5f));
			break;

		case 1:
			tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f));
			break;

		default:
			DE_ASSERT(false);
	}

	gl.bindTexture(GL_TEXTURE_2D, texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, texture)");

	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");

	gl.generateMipmap(GL_TEXTURE_2D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_2D)");

	gl.bindTexture(GL_TEXTURE_2D, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, 0)");

	return texture;
}

GLuint MultiTextureSamplerTest::createTexture3D (const glw::Functions& gl, int id)
{
	GLuint			texture		= (GLuint)-1;
	tcu::Texture3D	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE3D_WIDTH, TEXTURE3D_HEIGHT, TEXTURE3D_DEPTH);

	refTexture.allocLevel(0);

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

	switch (id)
	{
		case 0:
			tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.5f, 0.5f));
			break;

		case 1:
			tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f));
			break;

		default:
			DE_ASSERT(false);
	}

	gl.bindTexture(GL_TEXTURE_3D, texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, texture)");

	gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");

	gl.generateMipmap(GL_TEXTURE_3D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_3D)");

	gl.bindTexture(GL_TEXTURE_3D, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, 0)");

	return texture;
}

GLuint MultiTextureSamplerTest::createTextureCube (const glw::Functions& gl, int id)
{
	GLuint				texture		= (GLuint)-1;
	tcu::TextureCube	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), CUBEMAP_SIZE);

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

	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_X, 0);
	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Y, 0);
	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Z, 0);
	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_X, 0);
	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Y, 0);
	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Z, 0);

	switch (id)
	{
		case 0:
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
			break;

		case 1:
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Y), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Z), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_X), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Y), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Z), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
			break;

		default:
			DE_ASSERT(false);
	}

	gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, texture)");

	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
	{
		const deUint32 target = glu::getGLCubeFace((tcu::CubeFace)face);
		gl.texImage2D(target, 0, GL_RGBA8, refTexture.getSize(), refTexture.getSize(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevelFace(0, (tcu::CubeFace)face).getDataPtr());
	}
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_CUBE_MAP_...) failed");

	gl.generateMipmap(GL_TEXTURE_CUBE_MAP);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_CUBE_MAP)");
	gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, 0)");

	return texture;
}

GLuint MultiTextureSamplerTest::createTexture (const glw::Functions& gl, GLenum target, int id)
{
	switch (target)
	{
		case GL_TEXTURE_2D:
			return createTexture2D(gl, id);

		case GL_TEXTURE_3D:
			return createTexture3D(gl, id);

		case GL_TEXTURE_CUBE_MAP:
			return createTextureCube(gl, id);

		default:
			DE_ASSERT(false);
			return (GLuint)-1;
	}
}

void MultiTextureSamplerTest::renderReferences (tcu::Surface& textureRef, tcu::Surface& samplerRef, int x, int y)
{
	const glw::Functions&	gl			= m_renderCtx.getFunctions();
	GLuint					texture1	= createTexture(gl, m_target, 0);
	GLuint					texture2	= createTexture(gl, m_target, 1);

	gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");

	// Generate texture rendering reference
	gl.activeTexture(GL_TEXTURE0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
	gl.bindTexture(m_target, texture1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");
	setTextureState(gl, m_target, m_textureState1);

	gl.activeTexture(GL_TEXTURE1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
	gl.bindTexture(m_target, texture2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");
	setTextureState(gl, m_target, m_textureState2);

	render();
	glu::readPixels(m_renderCtx, x, y, textureRef.getAccess());

	// Generate sampler rendering reference
	gl.activeTexture(GL_TEXTURE0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
	gl.bindTexture(m_target, texture1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");
	setTextureState(gl, m_target, m_samplerState);

	gl.activeTexture(GL_TEXTURE1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
	gl.bindTexture(m_target, texture2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");
	setTextureState(gl, m_target, m_samplerState);

	render();
	glu::readPixels(m_renderCtx, x, y, samplerRef.getAccess());
}

void MultiTextureSamplerTest::renderResults (tcu::Surface& textureResult, tcu::Surface& samplerResult, int x, int y)
{
	const glw::Functions&	gl			= m_renderCtx.getFunctions();
	GLuint					texture1	= createTexture(gl, m_target, 0);
	GLuint					texture2	= createTexture(gl, m_target, 1);
	GLuint					sampler		= -1;

	gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");

	gl.genSamplers(1, &sampler);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenSamplers(1, &sampler)");
	TCU_CHECK(sampler != (GLuint)-1);

	gl.bindSampler(0, sampler);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, sampler)");
	gl.bindSampler(1, sampler);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(1, sampler)");

	// First set sampler state
	setSamplerState(gl, m_samplerState, sampler);

	// Set texture state
	gl.bindTexture(m_target, texture1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");
	setTextureState(gl, m_target, m_textureState1);

	gl.bindTexture(m_target, texture2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");
	setTextureState(gl, m_target, m_textureState2);

	gl.activeTexture(GL_TEXTURE0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
	gl.bindTexture(m_target, texture1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");

	gl.activeTexture(GL_TEXTURE1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
	gl.bindTexture(m_target, texture2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");

	// Render using sampler
	render();
	glu::readPixels(m_renderCtx, x, y, samplerResult.getAccess());

	gl.bindSampler(0, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, 0)");
	gl.bindSampler(1, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(1, 0)");

	render();
	glu::readPixels(m_renderCtx, x, y, textureResult.getAccess());

	gl.activeTexture(GL_TEXTURE0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
	gl.bindTexture(m_target, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, 0)");

	gl.activeTexture(GL_TEXTURE1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
	gl.bindTexture(m_target, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, 0)");

	gl.deleteSamplers(1, &sampler);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteSamplers(1, &sampler)");
	gl.deleteTextures(1, &texture1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures(1, &texture1)");
	gl.deleteTextures(1, &texture2);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures(1, &texture2)");
}

tcu::TestCase::IterateResult MultiTextureSamplerTest::iterate (void)
{
	tcu::TestLog&	log = m_testCtx.getLog();

	tcu::Surface	textureRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	tcu::Surface	samplerRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);

	tcu::Surface	textureResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
	tcu::Surface	samplerResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);

	int				x = m_random.getInt(0, m_renderCtx.getRenderTarget().getWidth() - VIEWPORT_WIDTH);
	int				y = m_random.getInt(0, m_renderCtx.getRenderTarget().getHeight() - VIEWPORT_HEIGHT);

	renderReferences(textureRef, samplerRef, x, y);
	renderResults(textureResult, samplerResult, x, y);

	bool isOk = pixelThresholdCompare (log, "Sampler render result", "Result from rendering with sampler", samplerRef, samplerResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);

	if (!pixelThresholdCompare (log, "Texture render result", "Result from rendering with texture state", textureRef, textureResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT))
		isOk = false;

	if (!isOk)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		return STOP;
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}


} // gls
} // deqp
