/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.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 Rbo state query tests.
 *//*--------------------------------------------------------------------*/

#include "es2fShaderStateQueryTests.hpp"
#include "glsStateQueryUtil.hpp"
#include "es2fApiCase.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "deRandom.hpp"
#include "deMath.h"
#include "deString.h"

using namespace glw; // GLint and other GL types
using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;

namespace deqp
{
namespace gles2
{
namespace Functional
{
namespace
{

static const char* commonTestVertSource		=	"void main (void)\n"
												"{\n"
												"	gl_Position = vec4(0.0);\n"
												"}\n";
static const char* commonTestFragSource		=	"void main (void)\n"
												"{\n"
												"	gl_FragColor = vec4(0.0);\n"
												"}\n";

static const char* brokenShader				=	"broken, this should not compile!\n"
												"\n";

// rounds x.1 to x+1
template <typename T>
T roundGLfloatToNearestIntegerUp (GLfloat val)
{
	return (T)(ceil(val));
}

// rounds x.9 to x
template <typename T>
T roundGLfloatToNearestIntegerDown (GLfloat val)
{
	return (T)(floor(val));
}

bool checkIntEquals (tcu::TestContext& testCtx, GLint got, GLint expected)
{
	using tcu::TestLog;

	if (got != expected)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
		return false;
	}
	return true;
}

void checkPointerEquals (tcu::TestContext& testCtx, const void* got, const void* expected)
{
	using tcu::TestLog;

	if (got != expected)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
	}
}

void verifyShaderParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint shader, GLenum pname, GLenum reference)
{
	StateQueryMemoryWriteGuard<GLint> state;
	gl.glGetShaderiv(shader, pname, &state);

	if (state.verifyValidity(testCtx))
		checkIntEquals(testCtx, state, reference);
}

bool verifyProgramParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLenum pname, GLenum reference)
{
	StateQueryMemoryWriteGuard<GLint> state;
	gl.glGetProgramiv(program, pname, &state);

	if (state.verifyValidity(testCtx))
		return checkIntEquals(testCtx, state, reference);
	return false;
}

void verifyCurrentVertexAttribf (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat[4]> attribValue;
	gl.glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);

	attribValue.verifyValidity(testCtx);

	if (attribValue[0] != x || attribValue[1] != y || attribValue[2] != z || attribValue[3] != w)
	{
		testCtx.getLog() << TestLog::Message
			<< "// ERROR: Expected [" << x << "," << y << "," << z << "," << w << "];"
			<< "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]"
			<< TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value");
	}
}

void verifyCurrentVertexAttribConversion (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint[4]> attribValue;
	gl.glGetVertexAttribiv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);

	attribValue.verifyValidity(testCtx);

	const GLint referenceAsGLintMin[] =
	{
		roundGLfloatToNearestIntegerDown<GLint>(x),
		roundGLfloatToNearestIntegerDown<GLint>(y),
		roundGLfloatToNearestIntegerDown<GLint>(z),
		roundGLfloatToNearestIntegerDown<GLint>(w)
	};
	const GLint referenceAsGLintMax[] =
	{
		roundGLfloatToNearestIntegerUp<GLint>(x),
		roundGLfloatToNearestIntegerUp<GLint>(y),
		roundGLfloatToNearestIntegerUp<GLint>(z),
		roundGLfloatToNearestIntegerUp<GLint>(w)
	};

	if (attribValue[0] < referenceAsGLintMin[0] || attribValue[0] > referenceAsGLintMax[0] ||
		attribValue[1] < referenceAsGLintMin[1] || attribValue[1] > referenceAsGLintMax[1] ||
		attribValue[2] < referenceAsGLintMin[2] || attribValue[2] > referenceAsGLintMax[2] ||
		attribValue[3] < referenceAsGLintMin[3] || attribValue[3] > referenceAsGLintMax[3])
	{
		testCtx.getLog() << TestLog::Message
			<< "// ERROR: expected in range "
			<< "[" << referenceAsGLintMin[0] << " " << referenceAsGLintMax[0] << "], "
			<< "[" << referenceAsGLintMin[1] << " " << referenceAsGLintMax[1] << "], "
			<< "[" << referenceAsGLintMin[2] << " " << referenceAsGLintMax[2] << "], "
			<< "[" << referenceAsGLintMin[3] << " " << referenceAsGLintMax[3] << "]"
			<< "; got "
			<< attribValue[0] << ", "
			<< attribValue[1] << ", "
			<< attribValue[2] << ", "
			<< attribValue[3] << " "
			<< "; Input="
			<< x << "; "
			<< y << "; "
			<< z << "; "
			<< w << " " << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid attribute value");
	}
}

void verifyVertexAttrib (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLenum pname, GLenum reference)
{
	StateQueryMemoryWriteGuard<GLint> state;
	gl.glGetVertexAttribiv(index, pname, &state);

	if (state.verifyValidity(testCtx))
		checkIntEquals(testCtx, state, reference);
}

void verifyUniformValue1f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat[1]> state;
	gl.glGetUniformfv(program, location, state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state[0] != x)
	{
		testCtx.getLog() << TestLog::Message
		<< "// ERROR: expected ["
		<< x
		<< "]; got ["
		<< state[0]
		<< "]"
		<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
	}
}

void verifyUniformValue2f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat[2]> state;
	gl.glGetUniformfv(program, location, state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state[0] != x ||
		state[1] != y)
	{
		testCtx.getLog() << TestLog::Message
		<< "// ERROR: expected ["
		<< x << ", "
		<< y
		<< "]; got ["
		<< state[0] << ", "
		<< state[1]
		<< "]"
		<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
	}
}

void verifyUniformValue3f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y, float z)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat[3]> state;
	gl.glGetUniformfv(program, location, state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state[0] != x ||
		state[1] != y ||
		state[2] != z)
	{
		testCtx.getLog() << TestLog::Message
		<< "// ERROR: expected ["
		<< x << ", "
		<< y << ", "
		<< z
		<< "]; got ["
		<< state[0] << ", "
		<< state[1] << ", "
		<< state[2]
		<< "]"
		<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
	}
}

void verifyUniformValue4f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y, float z, float w)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat[4]> state;
	gl.glGetUniformfv(program, location, state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state[0] != x ||
		state[1] != y ||
		state[2] != z ||
		state[3] != w)
	{
		testCtx.getLog() << TestLog::Message
		<< "// ERROR: expected ["
		<< x << ", "
		<< y << ", "
		<< z << ", "
		<< w
		<< "]; got ["
		<< state[0] << ", "
		<< state[1] << ", "
		<< state[2] << ", "
		<< state[3]
		<< "]"
		<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
	}
}

void verifyUniformValue1i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint[1]> state;
	gl.glGetUniformiv(program, location, state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state[0] != x)
	{
		testCtx.getLog() << TestLog::Message
		<< "// ERROR: expected ["
		<< x
		<< "]; got ["
		<< state[0]
		<< "]"
		<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
	}
}

void verifyUniformValue2i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint[2]> state;
	gl.glGetUniformiv(program, location, state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state[0] != x ||
		state[1] != y)
	{
		testCtx.getLog() << TestLog::Message
		<< "// ERROR: expected ["
		<< x << ", "
		<< y
		<< "]; got ["
		<< state[0] << ", "
		<< state[1]
		<< "]"
		<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
	}
}

void verifyUniformValue3i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y, GLint z)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint[3]> state;
	gl.glGetUniformiv(program, location, state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state[0] != x ||
		state[1] != y ||
		state[2] != z)
	{
		testCtx.getLog() << TestLog::Message
		<< "// ERROR: expected ["
		<< x << ", "
		<< y << ", "
		<< z
		<< "]; got ["
		<< state[0] << ", "
		<< state[1] << ", "
		<< state[2]
		<< "]"
		<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
	}
}

void verifyUniformValue4i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint[4]> state;
	gl.glGetUniformiv(program, location, state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state[0] != x ||
		state[1] != y ||
		state[2] != z ||
		state[3] != w)
	{
		testCtx.getLog() << TestLog::Message
		<< "// ERROR: expected ["
		<< x << ", "
		<< y << ", "
		<< z << ", "
		<< w
		<< "]; got ["
		<< state[0] << ", "
		<< state[1] << ", "
		<< state[2] << ", "
		<< state[3]
		<< "]"
		<< TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
	}
}

template <int Count>
void verifyUniformValues (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, const GLfloat* values)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat[Count]> state;
	gl.glGetUniformfv(program, location, state);

	if (!state.verifyValidity(testCtx))
		return;

	for (int ndx = 0; ndx < Count; ++ndx)
	{
		if (values[ndx] != state[ndx])
		{
			testCtx.getLog() << TestLog::Message << "// ERROR: at index " << ndx << " expected " << values[ndx] << "; got " << state[ndx] << TestLog::EndMessage;

			if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
				testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
		}
	}
}

template <int N>
void verifyUniformMatrixValues (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, const GLfloat* values, bool transpose)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat[N*N]> state;
	gl.glGetUniformfv(program, location, state);

	if (!state.verifyValidity(testCtx))
		return;

	for (int y = 0; y < N; ++y)
		for (int x = 0; x < N; ++x)
		{
			const int refIndex = y*N + x;
			const int stateIndex = transpose ? (x*N + y) : (y*N + x);

			if (values[refIndex] != state[stateIndex])
			{
				testCtx.getLog() << TestLog::Message << "// ERROR: at index [" << y << "][" << x << "] expected " << values[refIndex] << "; got " << state[stateIndex] << TestLog::EndMessage;

				if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
			}
		}
}

void requireShaderCompiler (tcu::TestContext& testCtx, glu::CallLogWrapper& gl)
{
	StateQueryMemoryWriteGuard<GLboolean> state;
	gl.glGetBooleanv(GL_SHADER_COMPILER, &state);

	if (!state.verifyValidity(testCtx) || state != GL_TRUE)
		throw tcu::NotSupportedError("Test requires SHADER_COMPILER = TRUE");
}

class ShaderTypeCase : public ApiCase
{
public:
	ShaderTypeCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		const GLenum shaderTypes[] = {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER};
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ++ndx)
		{
			const GLuint shader = glCreateShader(shaderTypes[ndx]);
			verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_TYPE, shaderTypes[ndx]);
			glDeleteShader(shader);
		}
	}
};

class ShaderCompileStatusCase : public ApiCase
{
public:
	ShaderCompileStatusCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		requireShaderCompiler(m_testCtx, *this);

		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);

		verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_FALSE);
		verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_FALSE);

		glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
		glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);

		glCompileShader(shaderVert);
		glCompileShader(shaderFrag);
		expectError(GL_NO_ERROR);

		verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
		verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);

		glDeleteShader(shaderVert);
		glDeleteShader(shaderFrag);
		expectError(GL_NO_ERROR);
	}
};

class ShaderInfoLogCase : public ApiCase
{
public:
	ShaderInfoLogCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		requireShaderCompiler(m_testCtx, *this);

		using tcu::TestLog;

		// INFO_LOG_LENGTH is 0 by default and it includes null-terminator
		const GLuint shader = glCreateShader(GL_VERTEX_SHADER);
		verifyShaderParam(m_testCtx, *this, shader, GL_INFO_LOG_LENGTH, 0);

		glShaderSource(shader, 1, &brokenShader, DE_NULL);
		glCompileShader(shader);
		expectError(GL_NO_ERROR);

		// check the log length
		StateQueryMemoryWriteGuard<GLint> logLength;
		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
		if (!logLength.verifyValidity(m_testCtx))
		{
			glDeleteShader(shader);
			return;
		}
		if (logLength == 0)
		{
			glDeleteShader(shader);
			return;
		}

		// check normal case
		{
			char buffer[2048] = {'x'}; // non-zero initialization

			GLint written = 0; // written does not include null terminator
			glGetShaderInfoLog(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);

			// check lengths are consistent
			if (logLength <= DE_LENGTH_OF_ARRAY(buffer))
			{
				if (written != logLength-1)
				{
					m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << logLength-1 << "; got " << written << TestLog::EndMessage;
					if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
						m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
				}
			}

			// check null-terminator, either at end of buffer or at buffer[written]
			const char* terminator = &buffer[DE_LENGTH_OF_ARRAY(buffer) - 1];
			if (logLength < DE_LENGTH_OF_ARRAY(buffer))
				terminator = &buffer[written];

			if (*terminator != '\0')
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)*terminator << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator");
			}
		}

		// check with too small buffer
		{
			char buffer[2048] = {'x'}; // non-zero initialization

			// check string always ends with \0, even with small buffers
			GLint written = 0;
			glGetShaderInfoLog(shader, 1, &written, buffer);
			if (written != 0)
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length 0; got " << written << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
			}
			if (buffer[0] != '\0')
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)buffer[0] << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator");
			}
		}

		glDeleteShader(shader);
		expectError(GL_NO_ERROR);
	}
};

class ShaderSourceCase : public ApiCase
{
public:
	ShaderSourceCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		requireShaderCompiler(m_testCtx, *this);

		using tcu::TestLog;

		// SHADER_SOURCE_LENGTH does include 0-terminator
		const GLuint shader = glCreateShader(GL_VERTEX_SHADER);
		verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_SOURCE_LENGTH, 0);

		// check the SHADER_SOURCE_LENGTH
		{
			glShaderSource(shader, 1, &brokenShader, DE_NULL);
			expectError(GL_NO_ERROR);

			StateQueryMemoryWriteGuard<GLint> sourceLength;
			glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength);

			sourceLength.verifyValidity(m_testCtx);

			const GLint referenceLength = (GLint)std::string(brokenShader).length() + 1; // including the null terminator
			if (sourceLength != referenceLength)
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength	<< "; got " << sourceLength << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
			}
		}

		// check the concat source SHADER_SOURCE_LENGTH
		{
			const char* shaders[] = {brokenShader, brokenShader};
			glShaderSource(shader, 2, shaders, DE_NULL);
			expectError(GL_NO_ERROR);

			StateQueryMemoryWriteGuard<GLint> sourceLength;
			glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength);

			sourceLength.verifyValidity(m_testCtx);

			const GLint referenceLength = 2 * (GLint)std::string(brokenShader).length() + 1; // including the null terminator
			if (sourceLength != referenceLength)
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength << "; got " << sourceLength << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
			}
		}

		// check the string length
		{
			char buffer[2048] = {'x'};
			DE_ASSERT(DE_LENGTH_OF_ARRAY(buffer) > 2 * (int)std::string(brokenShader).length());

			GLint written = 0; // not inluding null-terminator
			glGetShaderSource(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);

			const GLint referenceLength = 2 * (GLint)std::string(brokenShader).length();
			if (written != referenceLength)
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length " << referenceLength << "; got " << written << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
			}
			// check null pointer at
			else
			{
				if (buffer[referenceLength] != '\0')
				{
					m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator at " << referenceLength << TestLog::EndMessage;
					if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
						m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "did not get a null terminator");
				}
			}
		}

		// check with small buffer
		{
			char buffer[2048] = {'x'};

			GLint written = 0;
			glGetShaderSource(shader, 1, &written, buffer);

			if (written != 0)
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
			}
			if (buffer[0] != '\0')
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator; got=" << int(buffer[0]) << ", char=" << buffer[0] << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid terminator");
			}
		}

		glDeleteShader(shader);
		expectError(GL_NO_ERROR);
	}
};

class DeleteStatusCase : public ApiCase
{
public:
	DeleteStatusCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);

		glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
		glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);

		glCompileShader(shaderVert);
		glCompileShader(shaderFrag);
		expectError(GL_NO_ERROR);

		verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
		verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);

		GLuint shaderProg = glCreateProgram();
		glAttachShader(shaderProg, shaderVert);
		glAttachShader(shaderProg, shaderFrag);
		glLinkProgram(shaderProg);
		expectError(GL_NO_ERROR);

		verifyProgramParam	(m_testCtx, *this, shaderProg, GL_LINK_STATUS, GL_TRUE);

		verifyShaderParam	(m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_FALSE);
		verifyShaderParam	(m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_FALSE);
		verifyProgramParam	(m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_FALSE);
		expectError(GL_NO_ERROR);

		glUseProgram(shaderProg);

		glDeleteShader(shaderVert);
		glDeleteShader(shaderFrag);
		glDeleteProgram(shaderProg);
		expectError(GL_NO_ERROR);

		verifyShaderParam	(m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_TRUE);
		verifyShaderParam	(m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_TRUE);
		verifyProgramParam	(m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_TRUE);
		expectError(GL_NO_ERROR);

		glUseProgram(0);
		expectError(GL_NO_ERROR);
	}
};

class CurrentVertexAttribInitialCase : public ApiCase
{
public:
	CurrentVertexAttribInitialCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		using tcu::TestLog;

		int attribute_count = 16;
		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);

		// initial

		for (int index = 0; index < attribute_count; ++index)
		{
			StateQueryMemoryWriteGuard<GLfloat[4]> attribValue;
			glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
			attribValue.verifyValidity(m_testCtx);

			if (attribValue[0] != 0.0f || attribValue[1] != 0.0f || attribValue[2] != 0.0f || attribValue[3] != 1.0f)
			{
				m_testCtx.getLog() << TestLog::Message
					<< "// ERROR: Expected [0, 0, 0, 1];"
					<< "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]"
					<< TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value");
			}
		}
	}
};

class CurrentVertexAttribFloatCase : public ApiCase
{
public:
	CurrentVertexAttribFloatCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		using tcu::TestLog;

		de::Random rnd(0xabcdef);

		int attribute_count = 16;
		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);

		// test write float/read float

		for (int index = 0; index < attribute_count; ++index)
		{
			const GLfloat x = rnd.getFloat(-64000, 64000);
			const GLfloat y = rnd.getFloat(-64000, 64000);
			const GLfloat z = rnd.getFloat(-64000, 64000);
			const GLfloat w = rnd.getFloat(-64000, 64000);

			glVertexAttrib4f(index, x, y, z, w);
			verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
		}
		for (int index = 0; index < attribute_count; ++index)
		{
			const GLfloat x = rnd.getFloat(-64000, 64000);
			const GLfloat y = rnd.getFloat(-64000, 64000);
			const GLfloat z = rnd.getFloat(-64000, 64000);
			const GLfloat w = 1.0f;

			glVertexAttrib3f(index, x, y, z);
			verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
		}
		for (int index = 0; index < attribute_count; ++index)
		{
			const GLfloat x = rnd.getFloat(-64000, 64000);
			const GLfloat y = rnd.getFloat(-64000, 64000);
			const GLfloat z = 0.0f;
			const GLfloat w = 1.0f;

			glVertexAttrib2f(index, x, y);
			verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
		}
		for (int index = 0; index < attribute_count; ++index)
		{
			const GLfloat x = rnd.getFloat(-64000, 64000);
			const GLfloat y = 0.0f;
			const GLfloat z = 0.0f;
			const GLfloat w = 1.0f;

			glVertexAttrib1f(index, x);
			verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
		}
	}
};

class CurrentVertexAttribConversionCase : public ApiCase
{
public:
	CurrentVertexAttribConversionCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		using tcu::TestLog;

		de::Random rnd(0xabcdef);

		int attribute_count = 16;
		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);

		// test write float/read float

		for (int index = 0; index < attribute_count; ++index)
		{
			const GLfloat x = rnd.getFloat(-64000, 64000);
			const GLfloat y = rnd.getFloat(-64000, 64000);
			const GLfloat z = rnd.getFloat(-64000, 64000);
			const GLfloat w = rnd.getFloat(-64000, 64000);

			glVertexAttrib4f(index, x, y, z, w);
			verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
		}
		for (int index = 0; index < attribute_count; ++index)
		{
			const GLfloat x = rnd.getFloat(-64000, 64000);
			const GLfloat y = rnd.getFloat(-64000, 64000);
			const GLfloat z = rnd.getFloat(-64000, 64000);
			const GLfloat w = 1.0f;

			glVertexAttrib3f(index, x, y, z);
			verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
		}
		for (int index = 0; index < attribute_count; ++index)
		{
			const GLfloat x = rnd.getFloat(-64000, 64000);
			const GLfloat y = rnd.getFloat(-64000, 64000);
			const GLfloat z = 0.0f;
			const GLfloat w = 1.0f;

			glVertexAttrib2f(index, x, y);
			verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
		}
		for (int index = 0; index < attribute_count; ++index)
		{
			const GLfloat x = rnd.getFloat(-64000, 64000);
			const GLfloat y = 0.0f;
			const GLfloat z = 0.0f;
			const GLfloat w = 1.0f;

			glVertexAttrib1f(index, x);
			verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
		}
	}
};

class ProgramInfoLogCase : public ApiCase
{
public:
	ProgramInfoLogCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		using tcu::TestLog;

		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);

		glShaderSource(shaderVert, 1, &brokenShader, DE_NULL);
		glShaderSource(shaderFrag, 1, &brokenShader, DE_NULL);

		glCompileShader(shaderVert);
		glCompileShader(shaderFrag);
		expectError(GL_NO_ERROR);

		GLuint program = glCreateProgram();
		glAttachShader(program, shaderVert);
		glAttachShader(program, shaderFrag);
		glLinkProgram(program);

		// check INFO_LOG_LENGTH == GetProgramInfoLog len
		{
			char buffer[2048] = {'x'};

			GLint written = 0;
			glGetProgramInfoLog(program, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);

			StateQueryMemoryWriteGuard<GLint> logLength;
			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
			logLength.verifyValidity(m_testCtx);

			if (logLength != 0 && written+1 != logLength) // INFO_LOG_LENGTH contains 0-terminator
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected INFO_LOG_LENGTH " << written+1 << "; got " << logLength << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
			}
		}

		// check GetProgramInfoLog works with too small buffer
		{
			char buffer[2048] = {'x'};

			GLint written = 0;
			glGetProgramInfoLog(program, 1, &written, buffer);

			if (written != 0)
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
			}
		}

		glDeleteShader(shaderVert);
		glDeleteShader(shaderFrag);
		glDeleteProgram(program);
		expectError(GL_NO_ERROR);
	}
};

class ProgramValidateStatusCase : public ApiCase
{
public:
	ProgramValidateStatusCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		// test validate ok
		{
			GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
			GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);

			glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
			glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);

			glCompileShader(shaderVert);
			glCompileShader(shaderFrag);
			expectError(GL_NO_ERROR);

			GLuint program = glCreateProgram();
			glAttachShader(program, shaderVert);
			glAttachShader(program, shaderFrag);
			glLinkProgram(program);
			expectError(GL_NO_ERROR);

			verifyShaderParam	(m_testCtx, *this, shaderVert,	GL_COMPILE_STATUS,	GL_TRUE);
			verifyShaderParam	(m_testCtx, *this, shaderFrag,	GL_COMPILE_STATUS,	GL_TRUE);
			verifyProgramParam	(m_testCtx, *this, program,		GL_LINK_STATUS,		GL_TRUE);

			glValidateProgram(program);
			verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_TRUE);

			glDeleteShader(shaderVert);
			glDeleteShader(shaderFrag);
			glDeleteProgram(program);
			expectError(GL_NO_ERROR);
		}

		// test with broken shader
		{
			GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
			GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);

			glShaderSource(shaderVert, 1, &commonTestVertSource,	DE_NULL);
			glShaderSource(shaderFrag, 1, &brokenShader,			DE_NULL);

			glCompileShader(shaderVert);
			glCompileShader(shaderFrag);
			expectError(GL_NO_ERROR);

			GLuint program = glCreateProgram();
			glAttachShader(program, shaderVert);
			glAttachShader(program, shaderFrag);
			glLinkProgram(program);
			expectError(GL_NO_ERROR);

			verifyShaderParam	(m_testCtx, *this, shaderVert,	GL_COMPILE_STATUS,	GL_TRUE);
			verifyShaderParam	(m_testCtx, *this, shaderFrag,	GL_COMPILE_STATUS,	GL_FALSE);
			verifyProgramParam	(m_testCtx, *this, program,		GL_LINK_STATUS,		GL_FALSE);

			glValidateProgram(program);
			verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_FALSE);

			glDeleteShader(shaderVert);
			glDeleteShader(shaderFrag);
			glDeleteProgram(program);
			expectError(GL_NO_ERROR);
		}
	}
};

class ProgramAttachedShadersCase : public ApiCase
{
public:
	ProgramAttachedShadersCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		using tcu::TestLog;

		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);

		glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
		glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);

		glCompileShader(shaderVert);
		glCompileShader(shaderFrag);
		expectError(GL_NO_ERROR);

		// check ATTACHED_SHADERS

		GLuint program = glCreateProgram();
		verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 0);
		expectError(GL_NO_ERROR);

		glAttachShader(program, shaderVert);
		verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 1);
		expectError(GL_NO_ERROR);

		glAttachShader(program, shaderFrag);
		verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 2);
		expectError(GL_NO_ERROR);

		// check GetAttachedShaders
		{
			GLuint shaders[2] = {0, 0};
			GLint count = 0;
			glGetAttachedShaders(program, DE_LENGTH_OF_ARRAY(shaders), &count, shaders);

			if (count != 2)
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 2; got " << count << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
			}
			// shaders are the attached shaders?
			if (!((shaders[0] == shaderVert && shaders[1] == shaderFrag) ||
				  (shaders[0] == shaderFrag && shaders[1] == shaderVert)))
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected {" << shaderVert << ", " << shaderFrag << "}; got {" << shaders[0] << ", " << shaders[1] << "}" << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
			}
		}

		// check GetAttachedShaders with too small buffer
		{
			GLuint shaders[2] = {0, 0};
			GLint count = 0;

			glGetAttachedShaders(program, 0, &count, shaders);
			if (count != 0)
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0; got " << count << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
			}

			count = 0;
			glGetAttachedShaders(program, 1, &count, shaders);
			if (count != 1)
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 1; got " << count << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
			}
		}

		glDeleteShader(shaderVert);
		glDeleteShader(shaderFrag);
		glDeleteProgram(program);
		expectError(GL_NO_ERROR);
	}
};

class ProgramActiveUniformNameCase : public ApiCase
{
public:
	ProgramActiveUniformNameCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		using tcu::TestLog;

		static const char* testVertSource =
			"uniform highp float uniformNameWithLength23;\n"
			"uniform highp vec2 uniformVec2;\n"
			"uniform highp mat4 uniformMat4;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = vec4(0.0) + vec4(uniformNameWithLength23) + vec4(uniformVec2.x) + vec4(uniformMat4[2][3]);\n"
			"}\n\0";
		static const char* testFragSource =

			"void main (void)\n"
			"{\n"
			"	gl_FragColor = vec4(0.0);\n"
			"}\n\0";

		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);

		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);

		glCompileShader(shaderVert);
		glCompileShader(shaderFrag);
		expectError(GL_NO_ERROR);

		GLuint program = glCreateProgram();
		glAttachShader(program, shaderVert);
		glAttachShader(program, shaderFrag);
		glLinkProgram(program);
		expectError(GL_NO_ERROR);

		verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORMS, 3);
		verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, (GLint)std::string("uniformNameWithLength23").length() + 1); // including a null terminator
		expectError(GL_NO_ERROR);

		const char* uniformNames[] =
		{
			"uniformNameWithLength23",
			"uniformVec2",
			"uniformMat4"
		};

		// check names
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformNames); ++ndx)
		{
			char  buffer[2048]	= {'x'};
			char* bufferEnd		= (buffer + 1);

			GLint written = 0; // null terminator not included
			GLint size = 0;
			GLenum type = 0;
			glGetActiveUniform(program, ndx, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer);

			if (written < DE_LENGTH_OF_ARRAY(buffer))
				bufferEnd = &buffer[written];

			// find matching uniform
			{
				const std::string uniformName(buffer, bufferEnd);
				bool found = false;

				for (int uniformNdx = 0; uniformNdx < DE_LENGTH_OF_ARRAY(uniformNames); ++uniformNdx)
				{
					if (uniformName == uniformNames[uniformNdx])
					{
						found = true;
						break;
					}
				}

				if (!found)
				{
					m_testCtx.getLog() << TestLog::Message << "// ERROR: Got unknown uniform name: " << uniformName << TestLog::EndMessage;
					if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
						m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name");
				}
			}

			// and with too small buffer
			written = 0;
			glGetActiveUniform(program, ndx, 1, &written, &size, &type, buffer);

			if (written != 0)
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0 got " << written << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length");
			}
		}


		glDeleteShader(shaderVert);
		glDeleteShader(shaderFrag);
		glDeleteProgram(program);
		expectError(GL_NO_ERROR);
	}
};

class ProgramUniformCase : public ApiCase
{
public:
	ProgramUniformCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		const struct UniformType
		{
			const char* declaration;
			const char* postDeclaration;
			const char* precision;
			const char* layout;
			const char* getter;
			GLenum		type;
			GLint		size;
			GLint		isRowMajor;
		} uniformTypes[] =
		{
			{ "float",					"",			"highp",	"",				"uniformValue",													GL_FLOAT,							1, GL_FALSE },
			{ "float",					"[2]",		"highp",	"",				"uniformValue[1]",												GL_FLOAT,							2, GL_FALSE },
			{ "vec2",					"",			"highp",	"",				"uniformValue.x",												GL_FLOAT_VEC2,						1, GL_FALSE },
			{ "vec3",					"",			"highp",	"",				"uniformValue.x",												GL_FLOAT_VEC3,						1, GL_FALSE },
			{ "vec4",					"",			"highp",	"",				"uniformValue.x",												GL_FLOAT_VEC4,						1, GL_FALSE },
			{ "int",					"",			"highp",	"",				"float(uniformValue)",											GL_INT,								1, GL_FALSE },
			{ "ivec2",					"",			"highp",	"",				"float(uniformValue.x)",										GL_INT_VEC2,						1, GL_FALSE },
			{ "ivec3",					"",			"highp",	"",				"float(uniformValue.x)",										GL_INT_VEC3,						1, GL_FALSE },
			{ "ivec4",					"",			"highp",	"",				"float(uniformValue.x)",										GL_INT_VEC4,						1, GL_FALSE },
			{ "bool",					"",			"",			"",				"float(uniformValue)",											GL_BOOL,							1, GL_FALSE },
			{ "bvec2",					"",			"",			"",				"float(uniformValue.x)",										GL_BOOL_VEC2,						1, GL_FALSE },
			{ "bvec3",					"",			"",			"",				"float(uniformValue.x)",										GL_BOOL_VEC3,						1, GL_FALSE },
			{ "bvec4",					"",			"",			"",				"float(uniformValue.x)",										GL_BOOL_VEC4,						1, GL_FALSE },
			{ "mat2",					"",			"highp",	"",				"float(uniformValue[0][0])",									GL_FLOAT_MAT2,						1, GL_FALSE },
			{ "mat3",					"",			"highp",	"",				"float(uniformValue[0][0])",									GL_FLOAT_MAT3,						1, GL_FALSE },
			{ "mat4",					"",			"highp",	"",				"float(uniformValue[0][0])",									GL_FLOAT_MAT4,						1, GL_FALSE },
			{ "sampler2D",				"",			"highp",	"",				"float(texture2D(uniformValue, vec2(0.0, 0.0)).r)",				GL_SAMPLER_2D,						1, GL_FALSE },
			{ "samplerCube",			"",			"highp",	"",				"float(textureCube(uniformValue, vec3(0.0, 0.0, 0.0)).r)",		GL_SAMPLER_CUBE,					1, GL_FALSE },
		};

		static const char* vertSource =
			"void main (void)\n"
			"{\n"
			"	gl_Position = vec4(0.0);\n"
			"}\n\0";

		GLuint shaderVert	= glCreateShader(GL_VERTEX_SHADER);
		GLuint shaderFrag	= glCreateShader(GL_FRAGMENT_SHADER);
		GLuint program		= glCreateProgram();

		glAttachShader(program, shaderVert);
		glAttachShader(program, shaderFrag);

		glShaderSource(shaderVert, 1, &vertSource, DE_NULL);
		glCompileShader(shaderVert);
		expectError(GL_NO_ERROR);

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformTypes); ++ndx)
		{
			tcu::ScopedLogSection(m_log, uniformTypes[ndx].declaration, std::string("Verify type of ") + uniformTypes[ndx].declaration + " variable" + uniformTypes[ndx].postDeclaration );

			// gen fragment shader

			std::ostringstream frag;
			frag << uniformTypes[ndx].layout << "uniform " << uniformTypes[ndx].precision << " " << uniformTypes[ndx].declaration << " uniformValue" << uniformTypes[ndx].postDeclaration << ";\n";
			frag << "void main (void)\n";
			frag << "{\n";
			frag << "	gl_FragColor = vec4(" << uniformTypes[ndx].getter << ");\n";
			frag << "}\n";

			{
				std::string fragmentSource = frag.str();
				const char* fragmentSourceCStr = fragmentSource.c_str();
				glShaderSource(shaderFrag, 1, &fragmentSourceCStr, DE_NULL);
			}

			// compile & link

			glCompileShader(shaderFrag);
			glLinkProgram(program);

			// test
			if (verifyProgramParam(m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE))
			{
				const GLint index = 0; // first and only active uniform

				char buffer[]	= "not written to"; // not written to
				GLint written	= 0;
				GLint size		= 0;
				GLenum type		= 0;
				glGetActiveUniform(program, index, 0, &written, &size, &type, buffer);

				checkIntEquals(m_testCtx, type, uniformTypes[ndx].type);
				checkIntEquals(m_testCtx, size, uniformTypes[ndx].size);
			}
		}

		glDeleteShader(shaderVert);
		glDeleteShader(shaderFrag);
		glDeleteProgram(program);
		expectError(GL_NO_ERROR);
	}
};

class ActiveAttributesCase : public ApiCase
{
public:
	ActiveAttributesCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		using tcu::TestLog;

		static const char* testVertSource =
			"attribute highp vec2 longInputAttributeName;\n"
			"attribute highp vec2 shortName;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = longInputAttributeName.yxxy + shortName.xyxy;\n"
			"}\n\0";
		static const char* testFragSource =
			"void main (void)\n"
			"{\n"
			"	gl_FragColor = vec4(0.0);\n"
			"}\n\0";

		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);

		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);

		glCompileShader(shaderVert);
		glCompileShader(shaderFrag);
		expectError(GL_NO_ERROR);

		GLuint program = glCreateProgram();
		glAttachShader(program, shaderVert);
		glAttachShader(program, shaderFrag);
		glLinkProgram(program);
		expectError(GL_NO_ERROR);

		verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTES, 2);
		verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, (GLint)std::string("longInputAttributeName").length() + 1); // does include null-terminator

		// check names
		for (int attributeNdx = 0; attributeNdx < 2; ++attributeNdx)
		{
			char buffer[2048] = {'x'};

			GLint written = 0;
			GLint size = 0;
			GLenum type = 0;
			glGetActiveAttrib(program, attributeNdx, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer);
			expectError(GL_NO_ERROR);

			if (deStringBeginsWith(buffer, "longInputAttributeName"))
			{
				checkIntEquals(m_testCtx, written, (GLint)std::string("longInputAttributeName").length()); // does NOT include null-terminator
			}
			else if (deStringBeginsWith(buffer, "shortName"))
			{
				checkIntEquals(m_testCtx, written, (GLint)std::string("shortName").length()); // does NOT include null-terminator
			}
			else
			{
				m_testCtx.getLog() << TestLog::Message << "// ERROR: Got unexpected attribute name." << TestLog::EndMessage;
				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected name");
			}
		}

		// and with too short buffer
		{
			char buffer[2048] = {'x'};

			GLint written = 0;
			GLint size = 0;
			GLenum type = 0;

			glGetActiveAttrib(program, 0, 1, &written, &size, &type, buffer);
			expectError(GL_NO_ERROR);
			checkIntEquals(m_testCtx, written, 0);
		}

		glDeleteShader(shaderVert);
		glDeleteShader(shaderFrag);
		glDeleteProgram(program);
		expectError(GL_NO_ERROR);
	}
};

struct PointerData
{
	GLint		size;
	GLenum		type;
	GLint		stride;
	GLboolean	normalized;
	void*		pointer;
};

class VertexAttributeSizeCase : public ApiCase
{
public:
	VertexAttributeSizeCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		GLfloat vertexData[4] = {0.0f}; // never accessed

		// test VertexAttribPointer
		const PointerData pointers[] =
		{
			// size test
			{ 4, GL_FLOAT,		0,	GL_FALSE, vertexData },
			{ 3, GL_FLOAT,		0,	GL_FALSE, vertexData },
			{ 2, GL_FLOAT,		0,	GL_FALSE, vertexData },
			{ 1, GL_FLOAT,		0,	GL_FALSE, vertexData },
			{ 4, GL_SHORT,		0,	GL_FALSE, vertexData },
			{ 3, GL_SHORT,		0,	GL_FALSE, vertexData },
			{ 2, GL_SHORT,		0,	GL_FALSE, vertexData },
			{ 1, GL_SHORT,		0,	GL_FALSE, vertexData },
		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
		{
			glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
			expectError(GL_NO_ERROR);

			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[ndx].size);
		}
	}
};

class VertexAttributeTypeCase : public ApiCase
{
public:
	VertexAttributeTypeCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		GLfloat vertexData[4] = {0.0f}; // never accessed

		const PointerData pointers[] =
		{
			{ 1, GL_BYTE,								0,	GL_FALSE, vertexData	},
			{ 1, GL_UNSIGNED_BYTE,						0,	GL_FALSE, vertexData	},
			{ 1, GL_SHORT,								0,	GL_FALSE, vertexData	},
			{ 1, GL_UNSIGNED_SHORT,						0,	GL_FALSE, vertexData	},
			{ 1, GL_FIXED,								0,	GL_FALSE, vertexData	},
			{ 1, GL_FLOAT,								0,	GL_FALSE, vertexData	},
		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
		{
			glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
			expectError(GL_NO_ERROR);

			verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type);
		}
	}
};

class VertexAttributeStrideCase : public ApiCase
{
public:
	VertexAttributeStrideCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		GLfloat vertexData[4] = {0.0f}; // never accessed

		struct StridePointerData
		{
			GLint		size;
			GLenum		type;
			GLint		stride;
			void*		pointer;
		};

		// test VertexAttribPointer
		{
			const StridePointerData pointers[] =
			{
				{ 1, GL_FLOAT,				0,	vertexData },
				{ 1, GL_FLOAT,				1,	vertexData },
				{ 1, GL_FLOAT,				4,	vertexData },
				{ 1, GL_SHORT,				0,	vertexData },
				{ 1, GL_SHORT,				1,	vertexData },
				{ 1, GL_SHORT,				4,	vertexData },
				{ 1, GL_FIXED,				0,	vertexData },
				{ 1, GL_FIXED,				1,	vertexData },
				{ 1, GL_FIXED,				4,	vertexData },
				{ 1, GL_BYTE,				0,	vertexData },
				{ 1, GL_UNSIGNED_SHORT,		1,	vertexData },
				{ 1, GL_UNSIGNED_SHORT,		4,	vertexData },
				{ 4, GL_UNSIGNED_BYTE,		0,	vertexData },
				{ 4, GL_UNSIGNED_BYTE,		1,	vertexData },
				{ 4, GL_UNSIGNED_BYTE,		4,	vertexData },
			};

			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
			{
				glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, GL_FALSE, pointers[ndx].stride, pointers[ndx].pointer);
				expectError(GL_NO_ERROR);

				verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride);
			}
		}
	}
};

class VertexAttributeNormalizedCase : public ApiCase
{
public:
	VertexAttributeNormalizedCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		GLfloat vertexData[4] = {0.0f}; // never accessed

		// test VertexAttribPointer
		{
			const PointerData pointers[] =
			{
				{ 1, GL_BYTE,								0,	GL_FALSE,	vertexData	},
				{ 1, GL_SHORT,								0,	GL_FALSE,	vertexData	},
				{ 1, GL_UNSIGNED_BYTE,						0,	GL_FALSE,	vertexData	},
				{ 1, GL_UNSIGNED_SHORT,						0,	GL_FALSE,	vertexData	},
				{ 1, GL_BYTE,								0,	GL_TRUE,	vertexData	},
				{ 1, GL_SHORT,								0,	GL_TRUE,	vertexData	},
				{ 1, GL_UNSIGNED_BYTE,						0,	GL_TRUE,	vertexData	},
				{ 1, GL_UNSIGNED_SHORT,						0,	GL_TRUE,	vertexData	},
			};

			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
			{
				glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
				expectError(GL_NO_ERROR);

				verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, pointers[ndx].normalized);
			}
		}
	}
};

class VertexAttributeEnabledCase : public ApiCase
{
public:
	VertexAttributeEnabledCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		// VERTEX_ATTRIB_ARRAY_ENABLED

		verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
		glEnableVertexAttribArray(0);
		verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE);
		glDisableVertexAttribArray(0);
		verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
	}
};

class VertexAttributeBufferBindingCase : public ApiCase
{
public:
	VertexAttributeBufferBindingCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		// initial
		verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 0);

		GLuint bufferID;
		glGenBuffers(1, &bufferID);
		glBindBuffer(GL_ARRAY_BUFFER, bufferID);
		expectError(GL_NO_ERROR);

		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
		expectError(GL_NO_ERROR);

		verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufferID);

		glDeleteBuffers(1, &bufferID);
		expectError(GL_NO_ERROR);
	}
};

class VertexAttributePointerCase : public ApiCase
{
public:
	VertexAttributePointerCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		StateQueryMemoryWriteGuard<GLvoid*> initialState;
		glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &initialState);
		initialState.verifyValidity(m_testCtx);
		checkPointerEquals(m_testCtx, initialState, 0);

		GLfloat vertexData[4] = {0.0f}; // never accessed
		const PointerData pointers[] =
		{
			{ 1, GL_BYTE,				0,	GL_FALSE, &vertexData[2] },
			{ 1, GL_SHORT,				0,	GL_FALSE, &vertexData[1] },
			{ 1, GL_FIXED,				0,	GL_FALSE, &vertexData[2] },
			{ 1, GL_FIXED,				0,	GL_FALSE, &vertexData[1] },
			{ 1, GL_FLOAT,				0,	GL_FALSE, &vertexData[0] },
			{ 1, GL_FLOAT,				0,	GL_FALSE, &vertexData[3] },
			{ 1, GL_FLOAT,				0,	GL_FALSE, &vertexData[2] },
			{ 1, GL_UNSIGNED_SHORT,		0,	GL_FALSE, &vertexData[0] },
			{ 4, GL_UNSIGNED_SHORT,		0,	GL_FALSE, &vertexData[1] },
			{ 4, GL_UNSIGNED_SHORT,		0,	GL_FALSE, &vertexData[2] },
		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
		{
			glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
			expectError(GL_NO_ERROR);

			StateQueryMemoryWriteGuard<GLvoid*> state;
			glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
			state.verifyValidity(m_testCtx);
			checkPointerEquals(m_testCtx, state, pointers[ndx].pointer);
		}
	}
};

class UniformValueFloatCase : public ApiCase
{
public:
	UniformValueFloatCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		static const char* testVertSource =
			"uniform highp float floatUniform;\n"
			"uniform highp vec2 float2Uniform;\n"
			"uniform highp vec3 float3Uniform;\n"
			"uniform highp vec4 float4Uniform;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = vec4(floatUniform + float2Uniform.x + float3Uniform.x + float4Uniform.x);\n"
			"}\n";
		static const char* testFragSource =

			"void main (void)\n"
			"{\n"
			"	gl_FragColor = vec4(0.0);\n"
			"}\n";

		glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
		if (!program.isOk())
		{
			m_log << program;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
			return;
		}

		glUseProgram(program.getProgram());
		expectError(GL_NO_ERROR);

		GLint location;

		location = glGetUniformLocation(program.getProgram(), "floatUniform");
		glUniform1f(location, 1.0f);
		verifyUniformValue1f(m_testCtx, *this, program.getProgram(), location, 1.0f);

		location = glGetUniformLocation(program.getProgram(), "float2Uniform");
		glUniform2f(location, 1.0f, 2.0f);
		verifyUniformValue2f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f);

		location = glGetUniformLocation(program.getProgram(), "float3Uniform");
		glUniform3f(location, 1.0f, 2.0f, 3.0f);
		verifyUniformValue3f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f, 3.0f);

		location = glGetUniformLocation(program.getProgram(), "float4Uniform");
		glUniform4f(location, 1.0f, 2.0f, 3.0f, 4.0f);
		verifyUniformValue4f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f, 3.0f, 4.0f);

		glUseProgram(0);
		expectError(GL_NO_ERROR);
	}
};

class UniformValueIntCase : public ApiCase
{
public:
	UniformValueIntCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		static const char* testVertSource =
			"uniform highp int intUniform;\n"
			"uniform highp ivec2 int2Uniform;\n"
			"uniform highp ivec3 int3Uniform;\n"
			"uniform highp ivec4 int4Uniform;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = vec4(float(intUniform + int2Uniform.x + int3Uniform.x + int4Uniform.x));\n"
			"}\n";
		static const char* testFragSource =
			"void main (void)\n"
			"{\n"
			"	gl_FragColor = vec4(0.0);\n"
			"}\n";

		glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
		if (!program.isOk())
		{
			m_log << program;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
			return;
		}

		glUseProgram(program.getProgram());
		expectError(GL_NO_ERROR);

		GLint location;

		location = glGetUniformLocation(program.getProgram(), "intUniform");
		glUniform1i(location, 1);
		verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);

		location = glGetUniformLocation(program.getProgram(), "int2Uniform");
		glUniform2i(location, 1, 2);
		verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 2);

		location = glGetUniformLocation(program.getProgram(), "int3Uniform");
		glUniform3i(location, 1, 2, 3);
		verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 1, 2, 3);

		location = glGetUniformLocation(program.getProgram(), "int4Uniform");
		glUniform4i(location, 1, 2, 3, 4);
		verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 2, 3, 4);

		glUseProgram(0);
		expectError(GL_NO_ERROR);
	}
};

class UniformValueBooleanCase : public ApiCase
{
public:
	UniformValueBooleanCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		static const char* testVertSource =
			"uniform bool boolUniform;\n"
			"uniform bvec2 bool2Uniform;\n"
			"uniform bvec3 bool3Uniform;\n"
			"uniform bvec4 bool4Uniform;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = vec4(float(boolUniform) + float(bool2Uniform.x) + float(bool3Uniform.x) + float(bool4Uniform.x));\n"
			"}\n";
		static const char* testFragSource =
			"void main (void)\n"
			"{\n"
			"	gl_FragColor = vec4(0.0);\n"
			"}\n";

		glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
		if (!program.isOk())
		{
			m_log << program;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
			return;
		}

		glUseProgram(program.getProgram());
		expectError(GL_NO_ERROR);

		GLint location;

		// int conversion

		location = glGetUniformLocation(program.getProgram(), "boolUniform");
		glUniform1i(location, 1);
		verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);

		location = glGetUniformLocation(program.getProgram(), "bool2Uniform");
		glUniform2i(location, 1, 2);
		verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 1);

		location = glGetUniformLocation(program.getProgram(), "bool3Uniform");
		glUniform3i(location, 0, 1, 2);
		verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 0, 1, 1);

		location = glGetUniformLocation(program.getProgram(), "bool4Uniform");
		glUniform4i(location, 1, 0, 1, -1);
		verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 0, 1, 1);

		// float conversion

		location = glGetUniformLocation(program.getProgram(), "boolUniform");
		glUniform1f(location, 1.0f);
		verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);

		location = glGetUniformLocation(program.getProgram(), "bool2Uniform");
		glUniform2f(location, 1.0f, 0.1f);
		verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 1);

		location = glGetUniformLocation(program.getProgram(), "bool3Uniform");
		glUniform3f(location, 0.0f, 0.1f, -0.1f);
		verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 0, 1, 1);

		location = glGetUniformLocation(program.getProgram(), "bool4Uniform");
		glUniform4f(location, 1.0f, 0.0f, 0.1f, -0.9f);
		verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 0, 1, 1);

		glUseProgram(0);
		expectError(GL_NO_ERROR);
	}
};

class UniformValueSamplerCase : public ApiCase
{
public:
	UniformValueSamplerCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		static const char* testVertSource =
			"void main (void)\n"
			"{\n"
			"	gl_Position = vec4(0.0);\n"
			"}\n";
		static const char* testFragSource =
			"uniform highp sampler2D uniformSampler;\n"

			"void main (void)\n"
			"{\n"
			"	gl_FragColor = vec4(texture2D(uniformSampler, vec2(0.0, 0.0)).x);\n"
			"}\n";

		glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
		if (!program.isOk())
		{
			m_log << program;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
			return;
		}

		glUseProgram(program.getProgram());
		expectError(GL_NO_ERROR);

		GLint location;

		location = glGetUniformLocation(program.getProgram(), "uniformSampler");
		glUniform1i(location, 1);
		verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);

		glUseProgram(0);
		expectError(GL_NO_ERROR);
	}
};

class UniformValueArrayCase : public ApiCase
{
public:
	UniformValueArrayCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		static const char* testVertSource =
			"uniform highp float arrayUniform[5];"
			"uniform highp vec2 array2Uniform[5];"
			"uniform highp vec3 array3Uniform[5];"
			"uniform highp vec4 array4Uniform[5];"
			"void main (void)\n"
			"{\n"
			"	gl_Position = \n"
			"		+ vec4(arrayUniform[0]		+ arrayUniform[1]		+ arrayUniform[2]		+ arrayUniform[3]		+ arrayUniform[4])\n"
			"		+ vec4(array2Uniform[0].x	+ array2Uniform[1].x	+ array2Uniform[2].x	+ array2Uniform[3].x	+ array2Uniform[4].x)\n"
			"		+ vec4(array3Uniform[0].x	+ array3Uniform[1].x	+ array3Uniform[2].x	+ array3Uniform[3].x	+ array3Uniform[4].x)\n"
			"		+ vec4(array4Uniform[0].x	+ array4Uniform[1].x	+ array4Uniform[2].x	+ array4Uniform[3].x	+ array4Uniform[4].x);\n"
			"}\n";
		static const char* testFragSource =

			"void main (void)\n"
			"{\n"
			"	gl_FragColor = vec4(0.0);\n"
			"}\n";

		glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
		if (!program.isOk())
		{
			m_log << program;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
			return;
		}

		glUseProgram(program.getProgram());
		expectError(GL_NO_ERROR);

		GLint location;

		float uniformValue[5 * 4] =
		{
			-1.0f,	0.1f,	4.0f,	800.0f,
			13.0f,	55.0f,	12.0f,	91.0f,
			-55.1f,	1.1f,	98.0f,	19.0f,
			41.0f,	65.0f,	4.0f,	12.2f,
			95.0f,	77.0f,	32.0f,	48.0f
		};

		location = glGetUniformLocation(program.getProgram(), "arrayUniform");
		glUniform1fv(location, 5, uniformValue);
		expectError(GL_NO_ERROR);

		verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[0]"), uniformValue[0]);
		verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[1]"), uniformValue[1]);
		verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[2]"), uniformValue[2]);
		verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[3]"), uniformValue[3]);
		verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[4]"), uniformValue[4]);
		expectError(GL_NO_ERROR);

		location = glGetUniformLocation(program.getProgram(),"array2Uniform");
		glUniform2fv(location, 5, uniformValue);
		expectError(GL_NO_ERROR);

		verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[0]"), uniformValue[2 * 0], uniformValue[(2 * 0) + 1]);
		verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[1]"), uniformValue[2 * 1], uniformValue[(2 * 1) + 1]);
		verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[2]"), uniformValue[2 * 2], uniformValue[(2 * 2) + 1]);
		verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[3]"), uniformValue[2 * 3], uniformValue[(2 * 3) + 1]);
		verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[4]"), uniformValue[2 * 4], uniformValue[(2 * 4) + 1]);
		expectError(GL_NO_ERROR);

		location = glGetUniformLocation(program.getProgram(),"array3Uniform");
		glUniform3fv(location, 5, uniformValue);
		expectError(GL_NO_ERROR);

		verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[0]"), uniformValue[3 * 0], uniformValue[(3 * 0) + 1], uniformValue[(3 * 0) + 2]);
		verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[1]"), uniformValue[3 * 1], uniformValue[(3 * 1) + 1], uniformValue[(3 * 1) + 2]);
		verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[2]"), uniformValue[3 * 2], uniformValue[(3 * 2) + 1], uniformValue[(3 * 2) + 2]);
		verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[3]"), uniformValue[3 * 3], uniformValue[(3 * 3) + 1], uniformValue[(3 * 3) + 2]);
		verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[4]"), uniformValue[3 * 4], uniformValue[(3 * 4) + 1], uniformValue[(3 * 4) + 2]);
		expectError(GL_NO_ERROR);

		location = glGetUniformLocation(program.getProgram(),"array4Uniform");
		glUniform4fv(location, 5, uniformValue);
		expectError(GL_NO_ERROR);

		verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[0]"), uniformValue[4 * 0], uniformValue[(4 * 0) + 1], uniformValue[(4 * 0) + 2], uniformValue[(4 * 0) + 3]);
		verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[1]"), uniformValue[4 * 1], uniformValue[(4 * 1) + 1], uniformValue[(4 * 1) + 2], uniformValue[(4 * 1) + 3]);
		verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[2]"), uniformValue[4 * 2], uniformValue[(4 * 2) + 1], uniformValue[(4 * 2) + 2], uniformValue[(4 * 2) + 3]);
		verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[3]"), uniformValue[4 * 3], uniformValue[(4 * 3) + 1], uniformValue[(4 * 3) + 2], uniformValue[(4 * 3) + 3]);
		verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[4]"), uniformValue[4 * 4], uniformValue[(4 * 4) + 1], uniformValue[(4 * 4) + 2], uniformValue[(4 * 4) + 3]);
		expectError(GL_NO_ERROR);

		glUseProgram(0);
		expectError(GL_NO_ERROR);
	}
};

class UniformValueMatrixCase : public ApiCase
{
public:
	UniformValueMatrixCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		static const char* testVertSource =
			"uniform highp mat2 mat2Uniform;"
			"uniform highp mat3 mat3Uniform;"
			"uniform highp mat4 mat4Uniform;"
			"void main (void)\n"
			"{\n"
			"	gl_Position = vec4(mat2Uniform[0][0] + mat3Uniform[0][0] + mat4Uniform[0][0]);\n"
			"}\n";
		static const char* testFragSource =

			"void main (void)\n"
			"{\n"
			"	gl_FragColor = vec4(0.0);\n"
			"}\n";

		glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
		if (!program.isOk())
		{
			m_log << program;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
			return;
		}

		glUseProgram(program.getProgram());
		expectError(GL_NO_ERROR);

		GLint location;

		float matrixValues[4 * 4] =
		{
			-1.0f,	0.1f,	4.0f,	800.0f,
			13.0f,	55.0f,	12.0f,	91.0f,
			-55.1f,	1.1f,	98.0f,	19.0f,
			41.0f,	65.0f,	4.0f,	12.2f,
		};

		// the values of the matrix are returned in column major order but they can be given in either order

		location = glGetUniformLocation(program.getProgram(), "mat2Uniform");
		glUniformMatrix2fv(location, 1, GL_FALSE, matrixValues);
		verifyUniformMatrixValues<2>(m_testCtx, *this, program.getProgram(), location, matrixValues, false);

		location = glGetUniformLocation(program.getProgram(), "mat3Uniform");
		glUniformMatrix3fv(location, 1, GL_FALSE, matrixValues);
		verifyUniformMatrixValues<3>(m_testCtx, *this, program.getProgram(), location, matrixValues, false);

		location = glGetUniformLocation(program.getProgram(), "mat4Uniform");
		glUniformMatrix4fv(location, 1, GL_FALSE, matrixValues);
		verifyUniformMatrixValues<4>(m_testCtx, *this, program.getProgram(), location, matrixValues, false);

		glUseProgram(0);
		expectError(GL_NO_ERROR);
	}
};

class PrecisionFormatCase : public ApiCase
{
public:
	struct RequiredFormat
	{
		int negativeRange;
		int positiveRange;
		int precision;
	};

	PrecisionFormatCase (Context& context, const char* name, const char* description, glw::GLenum shaderType, glw::GLenum precisionType)
		: ApiCase			(context, name, description)
		, m_shaderType		(shaderType)
		, m_precisionType	(precisionType)
	{
	}

private:
	void test (void)
	{
		const RequiredFormat											expected = getRequiredFormat();
		bool															error = false;
		gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean>	shaderCompiler;
		gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint[2]>	range;
		gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint>		precision;

		// requires SHADER_COMPILER = true
		glGetBooleanv(GL_SHADER_COMPILER, &shaderCompiler);
		expectError(GL_NO_ERROR);

		if (!shaderCompiler.verifyValidity(m_testCtx))
			return;
		if (shaderCompiler != GL_TRUE)
			throw tcu::NotSupportedError("SHADER_COMPILER = TRUE required");

		// query values
		glGetShaderPrecisionFormat(m_shaderType, m_precisionType, range, &precision);
		expectError(GL_NO_ERROR);

		if (!range.verifyValidity(m_testCtx))
			return;
		if (!precision.verifyValidity(m_testCtx))
			return;

		m_log
			<< tcu::TestLog::Message
			<< "range[0] = " << range[0] << "\n"
			<< "range[1] = " << range[1] << "\n"
			<< "precision = " << precision
			<< tcu::TestLog::EndMessage;

		// special case for highp and fragment shader

		if (m_shaderType == GL_FRAGMENT_SHADER && (m_precisionType == GL_HIGH_FLOAT || m_precisionType == GL_HIGH_INT))
		{
			// not supported is a valid return value
			if (range[0] == 0 && range[1] == 0 && precision == 0)
				return;
		}

		// verify the returned values

		if (range[0] < expected.negativeRange)
		{
			m_log << tcu::TestLog::Message << "// ERROR: Invalid range[0], expected greater or equal to " << expected.negativeRange << tcu::TestLog::EndMessage;
			error = true;
		}

		if (range[1] < expected.positiveRange)
		{
			m_log << tcu::TestLog::Message << "// ERROR: Invalid range[1], expected greater or equal to " << expected.positiveRange << tcu::TestLog::EndMessage;
			error = true;
		}

		if (precision < expected.precision)
		{
			m_log << tcu::TestLog::Message << "// ERROR: Invalid precision, expected greater or equal to " << expected.precision << tcu::TestLog::EndMessage;
			error = true;
		}

		if (error)
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid precision/range");
	}

	RequiredFormat getRequiredFormat (void) const
	{
		// Precisions for different types.
		// For example highp float: range: (-2^62, 2^62) => min = -2^62 + e, max = 2^62 - e
		const RequiredFormat requirements[] =
		{
			{  0,  0,  8 }, //!< lowp float
			{ 13, 13, 10 }, //!< mediump float
			{ 61, 61, 16 }, //!< highp float
			{ 7,   7,  0 }, //!< lowp int
			{ 9,   9,  0 }, //!< mediump int
			{ 15, 15,  0 }, //!< highp int
		};
		const int ndx = (int)m_precisionType - (int)GL_LOW_FLOAT;

		DE_ASSERT(ndx >= 0);
		DE_ASSERT(ndx < DE_LENGTH_OF_ARRAY(requirements));
		return requirements[ndx];
	}

	const glw::GLenum m_shaderType;
	const glw::GLenum m_precisionType;
};

} // anonymous


ShaderStateQueryTests::ShaderStateQueryTests (Context& context)
	: TestCaseGroup(context, "shader", "Shader State Query tests")
{
}

void ShaderStateQueryTests::init (void)
{
	// shader
	addChild(new ShaderTypeCase						(m_context, "shader_type",							"SHADER_TYPE"));
	addChild(new ShaderCompileStatusCase			(m_context, "shader_compile_status",				"COMPILE_STATUS"));
	addChild(new ShaderInfoLogCase					(m_context, "shader_info_log_length",				"INFO_LOG_LENGTH"));
	addChild(new ShaderSourceCase					(m_context, "shader_source_length",					"SHADER_SOURCE_LENGTH"));

	// shader and program
	addChild(new DeleteStatusCase					(m_context, "delete_status",						"DELETE_STATUS"));

	// vertex-attrib
	addChild(new CurrentVertexAttribInitialCase		(m_context, "current_vertex_attrib_initial",		"CURRENT_VERTEX_ATTRIB"));
	addChild(new CurrentVertexAttribFloatCase		(m_context, "current_vertex_attrib_float",			"CURRENT_VERTEX_ATTRIB"));
	addChild(new CurrentVertexAttribConversionCase	(m_context, "current_vertex_attrib_float_to_int",	"CURRENT_VERTEX_ATTRIB"));

	// program
	addChild(new ProgramInfoLogCase					(m_context, "program_info_log_length",				"INFO_LOG_LENGTH"));
	addChild(new ProgramValidateStatusCase			(m_context, "program_validate_status",				"VALIDATE_STATUS"));
	addChild(new ProgramAttachedShadersCase			(m_context, "program_attached_shaders",				"ATTACHED_SHADERS"));

	addChild(new ProgramActiveUniformNameCase		(m_context, "program_active_uniform_name",			"ACTIVE_UNIFORMS and ACTIVE_UNIFORM_MAX_LENGTH"));
	addChild(new ProgramUniformCase					(m_context, "program_active_uniform_types",			"UNIFORM_TYPE and UNIFORM_SIZE"));

	// attribute related
	addChild(new ActiveAttributesCase				(m_context, "active_attributes",					"ACTIVE_ATTRIBUTES and ACTIVE_ATTRIBUTE_MAX_LENGTH"));
	addChild(new VertexAttributeSizeCase			(m_context, "vertex_attrib_size",					"VERTEX_ATTRIB_ARRAY_SIZE"));
	addChild(new VertexAttributeTypeCase			(m_context, "vertex_attrib_type",					"VERTEX_ATTRIB_ARRAY_TYPE"));
	addChild(new VertexAttributeStrideCase			(m_context, "vertex_attrib_stride",					"VERTEX_ATTRIB_ARRAY_STRIDE"));
	addChild(new VertexAttributeNormalizedCase		(m_context, "vertex_attrib_normalized",				"VERTEX_ATTRIB_ARRAY_NORMALIZED"));
	addChild(new VertexAttributeEnabledCase			(m_context, "vertex_attrib_array_enabled",			"VERTEX_ATTRIB_ARRAY_ENABLED"));
	addChild(new VertexAttributeBufferBindingCase	(m_context, "vertex_attrib_array_buffer_binding",	"VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"));
	addChild(new VertexAttributePointerCase			(m_context, "vertex_attrib_pointerv",				"GetVertexAttribPointerv"));

	// uniform values
	addChild(new UniformValueFloatCase				(m_context, "uniform_value_float",					"GetUniform*"));
	addChild(new UniformValueIntCase				(m_context, "uniform_value_int",					"GetUniform*"));
	addChild(new UniformValueBooleanCase			(m_context, "uniform_value_boolean",				"GetUniform*"));
	addChild(new UniformValueSamplerCase			(m_context, "uniform_value_sampler",				"GetUniform*"));
	addChild(new UniformValueArrayCase				(m_context, "uniform_value_array",					"GetUniform*"));
	addChild(new UniformValueMatrixCase				(m_context, "uniform_value_matrix",					"GetUniform*"));

	// precision format query
	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_lowp_float",			"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_LOW_FLOAT));
	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_mediump_float",		"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_MEDIUM_FLOAT));
	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_highp_float",			"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_HIGH_FLOAT));
	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_lowp_int",			"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_LOW_INT));
	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_mediump_int",			"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_MEDIUM_INT));
	addChild(new PrecisionFormatCase				(m_context, "precision_vertex_highp_int",			"GetShaderPrecisionFormat",		GL_VERTEX_SHADER,	GL_HIGH_INT));
	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_lowp_float",		"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_LOW_FLOAT));
	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_mediump_float",		"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_MEDIUM_FLOAT));
	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_highp_float",		"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_HIGH_FLOAT));
	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_lowp_int",			"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_LOW_INT));
	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_mediump_int",		"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_MEDIUM_INT));
	addChild(new PrecisionFormatCase				(m_context, "precision_fragment_highp_int",			"GetShaderPrecisionFormat",		GL_FRAGMENT_SHADER,	GL_HIGH_INT));
}

} // Functional
} // gles2
} // deqp
