/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2017 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */ /*!
 * \file  InternalformatTests.cpp
 * \brief
 */ /*-------------------------------------------------------------------*/

#include "glcInternalformatTests.hpp"
#include "deMath.h"
#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "gluDrawUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderProgram.hpp"
#include "gluStrUtil.hpp"
#include "gluTexture.hpp"
#include "gluTextureUtil.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"

#include <algorithm>
#include <map>

using namespace glw;

namespace glcts
{

// all extension names required by the tests
static const char* EXT_texture_type_2_10_10_10_REV = "GL_EXT_texture_type_2_10_10_10_REV";
static const char* EXT_texture_shared_exponent	 = "GL_EXT_texture_shared_exponent";
static const char* EXT_texture_integer			   = "GL_EXT_texture_integer";
static const char* ARB_texture_rgb10_a2ui		   = "GL_ARB_texture_rgb10_a2ui";
static const char* ARB_depth_texture			   = "GL_ARB_depth_texture";
static const char* ARB_texture_float			   = "GL_ARB_texture_float";
static const char* OES_texture_float			   = "GL_OES_texture_float";
static const char* OES_texture_float_linear		   = "GL_OES_texture_float_linear";
static const char* OES_texture_half_float		   = "GL_OES_texture_half_float";
static const char* OES_texture_half_float_linear   = "GL_OES_texture_half_float_linear";
static const char* OES_rgb8_rgba8				   = "GL_OES_rgb8_rgba8";
static const char* OES_depth_texture			   = "GL_OES_depth_texture";
static const char* OES_depth24					   = "GL_OES_depth24";
static const char* OES_depth32					   = "GL_OES_depth32";
static const char* OES_packed_depth_stencil		   = "GL_OES_packed_depth_stencil";
static const char* OES_stencil1					   = "GL_OES_stencil1";
static const char* OES_stencil4					   = "GL_OES_stencil4";
static const char* OES_stencil8					   = "GL_OES_stencil8";
static const char* OES_required_internalformat	 = "GL_OES_required_internalformat";

struct TextureFormat
{
	GLenum		format;
	GLenum		type;
	GLint		internalFormat;
	const char* requiredExtension;
	const char* secondReqiredExtension;
	GLint		minFilter;
	GLint		magFilter;

	TextureFormat()
	{
	}

	TextureFormat(GLenum aFormat, GLenum aType, GLint aInternalFormat, const char* aRequiredExtension = DE_NULL,
				  const char* aSecondReqiredExtension = DE_NULL, GLint aMinFilter = GL_NEAREST,
				  GLint aMagFilter = GL_NEAREST)
		: format(aFormat)
		, type(aType)
		, internalFormat(aInternalFormat)
		, requiredExtension(aRequiredExtension)
		, secondReqiredExtension(aSecondReqiredExtension)
		, minFilter(aMinFilter)
		, magFilter(aMagFilter)
	{
	}
};

struct CopyTexImageFormat
{
	GLint		internalFormat;
	const char* requiredExtension;
	const char* secondReqiredExtension;
	GLint		minFilter;
	GLint		magFilter;

	CopyTexImageFormat(GLenum aInternalFormat, const char* aRequiredExtension = DE_NULL,
					   const char* aSecondReqiredExtension = DE_NULL, GLint aMinFilter = GL_NEAREST,
					   GLint aMagFilter = GL_NEAREST)
		: internalFormat(aInternalFormat)
		, requiredExtension(aRequiredExtension)
		, secondReqiredExtension(aSecondReqiredExtension)
		, minFilter(aMinFilter)
		, magFilter(aMagFilter)
	{
	}
};

enum RenderBufferType
{
	RENDERBUFFER_COLOR,
	RENDERBUFFER_STENCIL,
	RENDERBUFFER_DEPTH,
	RENDERBUFFER_DEPTH_STENCIL
};

struct RenderbufferFormat
{
	GLenum			 format;
	RenderBufferType type;
	const char*		 requiredExtension;
	const char*		 secondReqiredExtension;

	RenderbufferFormat(GLenum aFormat, RenderBufferType aType, const char* aRequiredExtension = DE_NULL,
					   const char* aSecondReqiredExtension = DE_NULL)
		: format(aFormat)
		, type(aType)
		, requiredExtension(aRequiredExtension)
		, secondReqiredExtension(aSecondReqiredExtension)
	{
	}
};

class InternalformatCaseBase : public deqp::TestCase
{
public:
	InternalformatCaseBase(deqp::Context& context, const std::string& name);
	virtual ~InternalformatCaseBase()
	{
	}

protected:
	bool requiredExtensionsSupported(const char* extension1, const char* extension2);
	GLuint createTexture(GLint internalFormat, GLenum format, GLenum type, GLint minFilter, GLint magFilter,
						 bool generateData = true) const;
	glu::ProgramSources prepareTexturingProgramSources(GLint internalFormat, GLenum format, GLenum type) const;
	void renderTexturedQuad(GLuint programId) const;
	GLenum getUnsizedFormatFromInternalFormat(GLint internalFormat) const;
	GLenum getTypeFromInternalFormat(GLint internalFormat) const;

private:
	void generateTextureData(GLuint width, GLuint height, GLenum type, unsigned int pixelSize, unsigned int components,
							 std::vector<unsigned char>& result) const;

	// color converting methods
	static void convertByte(tcu::Vec4 inColor, unsigned char* dst, int components);
	static void convertUByte(tcu::Vec4 inColor, unsigned char* dst, int components);
	static void convertHFloat(tcu::Vec4 inColor, unsigned char* dst, int components);
	static void convertFloat(tcu::Vec4 inColor, unsigned char* dst, int components);
	static void convertShort(tcu::Vec4 inColor, unsigned char* dst, int components);
	static void convertUShort(tcu::Vec4 inColor, unsigned char* dst, int components);
	static void convertInt(tcu::Vec4 inColor, unsigned char* dst, int components);
	static void convertUInt(tcu::Vec4 inColor, unsigned char* dst, int components);
	static void convertUInt_24_8(tcu::Vec4 inColor, unsigned char* dst, int components);
	static void convertUShort_4_4_4_4(tcu::Vec4 inColor, unsigned char* dst, int);
	static void convertUShort_5_5_5_1(tcu::Vec4 inColor, unsigned char* dst, int);
	static void convertUShort_5_6_5(tcu::Vec4 inColor, unsigned char* dst, int);
	static void convertUInt_2_10_10_10_rev(tcu::Vec4 inColor, unsigned char* dst, int);

	static GLhalf floatToHalf(float f);

protected:
	GLsizei m_renderWidth;
	GLsizei m_renderHeight;
};

InternalformatCaseBase::InternalformatCaseBase(deqp::Context& context, const std::string& name)
	: deqp::TestCase(context, name.c_str(), ""), m_renderWidth(64), m_renderHeight(64)
{
}

bool InternalformatCaseBase::requiredExtensionsSupported(const char* extension1, const char* extension2)
{
	const glu::ContextInfo& contextInfo = m_context.getContextInfo();
	if (extension1)
	{
		if (extension2)
		{
			if (!contextInfo.isExtensionSupported(extension1) || !contextInfo.isExtensionSupported(extension2))
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "One of required extensions is not supported");
				return false;
			}
		}
		else if (!contextInfo.isExtensionSupported(extension1))
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Required extension is not supported");
			return false;
		}
	}
	return true;
}

GLuint InternalformatCaseBase::createTexture(GLint internalFormat, GLenum format, GLenum type, GLint minFilter,
											 GLint magFilter, bool generateData) const
{
	const Functions&		   gl = m_context.getRenderContext().getFunctions();
	GLuint					   textureName;
	std::vector<unsigned char> textureData;
	GLvoid*					   textureDataPtr = DE_NULL;

	if (generateData)
	{
		tcu::TextureFormat tcuTextureFormat = glu::mapGLTransferFormat(format, type);
		unsigned int	   components		= tcu::getNumUsedChannels(tcuTextureFormat.order);
		unsigned int	   pixelSize		= 4;

		// note: getPixelSize hits assertion for GL_UNSIGNED_INT_2_10_10_10_REV when format is RGB
		if (type != GL_UNSIGNED_INT_2_10_10_10_REV)
			pixelSize = tcu::getPixelSize(tcuTextureFormat);

		generateTextureData(m_renderWidth, m_renderHeight, type, pixelSize, components, textureData);
		textureDataPtr = &textureData[0];
	}

	gl.genTextures(1, &textureName);
	gl.bindTexture(GL_TEXTURE_2D, textureName);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");

	gl.texImage2D(GL_TEXTURE_2D, 0, internalFormat, m_renderWidth, m_renderHeight, 0, format, type, textureDataPtr);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D");

	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");

	return textureName;
}

glu::ProgramSources InternalformatCaseBase::prepareTexturingProgramSources(GLint internalFormat, GLenum format,
																		   GLenum type) const
{
	glu::RenderContext& renderContext = m_context.getRenderContext();
	glu::ContextType	contextType   = renderContext.getType();
	glu::GLSLVersion	glslVersion   = glu::getContextTypeGLSLVersion(contextType);

	std::string vs;
	std::string fs;

	std::map<std::string, std::string> specializationMap;
	specializationMap["VERSION"] = glu::getGLSLVersionDeclaration(glslVersion);

	if (glu::contextSupports(contextType, glu::ApiType::es(3, 0)) || glu::isContextTypeGLCore(contextType))
	{
		vs = "${VERSION}\n"
			 "precision highp float;\n"
			 "in vec2 position;\n"
			 "in vec2 inTexcoord;\n"
			 "out vec2 texcoord;\n"
			 "void main()\n"
			 "{\n"
			 "  texcoord = inTexcoord;\n"
			 "  gl_Position = vec4(position, 0.0, 1.0);\n"
			 "}\n";
		fs = "${VERSION}\n"
			 "precision highp float;\n"
			 "uniform ${SAMPLER} sampler;\n"
			 "in vec2 texcoord;\n"
			 "out highp vec4 color;\n"
			 "void main()\n"
			 "{\n"
			 "  ${SAMPLED_TYPE} v = texture(sampler, texcoord);\n"
			 "  color = ${CALCULATE_COLOR};\n"
			 "  ${PROCESS_COLOR}\n"
			 "}\n";

		specializationMap["PROCESS_COLOR"] = "";
		if ((format == GL_RGB_INTEGER) || (format == GL_RGBA_INTEGER))
		{
			specializationMap["SAMPLED_TYPE"] = "uvec4";
			specializationMap["SAMPLER"]	  = "usampler2D";
			if (type == GL_BYTE)
			{
				specializationMap["SAMPLED_TYPE"]	= "ivec4";
				specializationMap["SAMPLER"]		 = "isampler2D";
				specializationMap["CALCULATE_COLOR"] = "vec4(v) / 127.0";
			}
			else if (type == GL_UNSIGNED_BYTE)
			{
				specializationMap["CALCULATE_COLOR"] = "vec4(v) / 255.0";
			}
			else if (type == GL_SHORT)
			{
				specializationMap["SAMPLED_TYPE"]	= "ivec4";
				specializationMap["SAMPLER"]		 = "isampler2D";
				specializationMap["CALCULATE_COLOR"] = "vec4(v / 128) / 256.0";
			}
			else if (type == GL_UNSIGNED_SHORT)
			{
				specializationMap["CALCULATE_COLOR"] = "vec4(v / 256) / 256.0";
			}
			else if (type == GL_INT)
			{
				specializationMap["SAMPLED_TYPE"]	= "ivec4";
				specializationMap["SAMPLER"]		 = "isampler2D";
				specializationMap["CALCULATE_COLOR"] = "vec4(v / 2097152u) / 1024.0";
			}
			else // GL_UNSIGNED_INT
			{
				if (internalFormat == GL_RGB10_A2UI)
					specializationMap["CALCULATE_COLOR"] = "vec4(vec3(v.rgb) / 1023.0, float(v.a) / 3.0)";
				else
					specializationMap["CALCULATE_COLOR"] = "vec4(v / 4194304u) / 1024.0";
			}

			if (format == GL_RGB_INTEGER)
				specializationMap["PROCESS_COLOR"] = "color.a = 1.0;\n";
		}
		else
		{
			specializationMap["SAMPLED_TYPE"]	= "vec4";
			specializationMap["SAMPLER"]		 = "sampler2D";
			if (format == GL_DEPTH_STENCIL)
				specializationMap["CALCULATE_COLOR"] = "vec4(v.r, 0.0, 0.0, 1.0)";
			else
				specializationMap["CALCULATE_COLOR"] = "v";
		}
	}
	else
	{
		vs = "${VERSION}\n"
			 "attribute highp vec2 position;\n"
			 "attribute highp vec2 inTexcoord;\n"
			 "varying highp vec2 texcoord;\n"
			 "void main()\n"
			 "{\n"
			 "  texcoord = inTexcoord;\n"
			 "  gl_Position = vec4(position, 0.0, 1.0);\n"
			 "}\n";
		fs = "${VERSION}\n"
			 "uniform highp sampler2D sampler;\n"
			 "varying highp vec2 texcoord;\n"
			 "void main()\n"
			 "{\n"
			 "  highp vec4 color = texture2D(sampler, texcoord);\n"
			 "  gl_FragColor = ${CALCULATE_COLOR};\n"
			 "}\n";

		if ((internalFormat == GL_DEPTH_COMPONENT) || (internalFormat == GL_DEPTH_STENCIL))
			specializationMap["CALCULATE_COLOR"] = "vec4(color.r, 0.0, 0.0, 1.0)";
		else
			specializationMap["CALCULATE_COLOR"] = "color";
	}

	vs = tcu::StringTemplate(vs).specialize(specializationMap);
	fs = tcu::StringTemplate(fs).specialize(specializationMap);
	return glu::makeVtxFragSources(vs.c_str(), fs.c_str());
}

void InternalformatCaseBase::renderTexturedQuad(GLuint programId) const
{
	// Prepare data for rendering
	static const deUint16				 quadIndices[]  = { 0, 1, 2, 2, 1, 3 };
	static const float					 position[]		= { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f };
	static const float					 texCoord[]		= { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	static const glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 2, 4, 0, position),
															glu::va::Float("inTexcoord", 2, 4, 0, texCoord) };

	glu::draw(m_context.getRenderContext(), programId, DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
			  glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
}

GLenum InternalformatCaseBase::getUnsizedFormatFromInternalFormat(GLint internalFormat) const
{
	switch (internalFormat)
	{
	case GL_RGBA:
	case GL_RGBA4:
	case GL_RGB5_A1:
	case GL_RGBA8:
	case GL_RGB10_A2:
		return GL_RGBA;
	case GL_RGB10_A2UI:
	case GL_RGBA8UI: //remove this
		return GL_RGBA_INTEGER;
	case GL_RGB:
	case GL_RGB565:
	case GL_RGB8:
	case GL_RGB10:
	case GL_RGB9_E5:
		return GL_RGB;
	case GL_LUMINANCE_ALPHA:
	case GL_LUMINANCE4_ALPHA4_OES:
	case GL_LUMINANCE8_ALPHA8_OES:
		return GL_LUMINANCE_ALPHA;
	case GL_LUMINANCE:
	case GL_LUMINANCE8_OES:
		return GL_LUMINANCE;
	case GL_ALPHA:
	case GL_ALPHA8_OES:
		return GL_ALPHA;
	case GL_DEPTH_COMPONENT16:
	case GL_DEPTH_COMPONENT24:
	case GL_DEPTH_COMPONENT32:
		return GL_DEPTH_COMPONENT;
	case GL_DEPTH24_STENCIL8:
		return GL_DEPTH_STENCIL;
	case GL_STENCIL_INDEX8:
		return GL_STENCIL_INDEX;
	default:
		TCU_FAIL("Unrecognized internal format");
	}
	return GL_NONE;
}

GLenum InternalformatCaseBase::getTypeFromInternalFormat(GLint internalFormat) const
{
	switch (internalFormat)
	{
	case GL_RGB10:
	case GL_RGB10_A2:
	case GL_RGB10_A2UI:
		return GL_UNSIGNED_INT_2_10_10_10_REV;
	case GL_DEPTH_COMPONENT16:
	case GL_DEPTH_COMPONENT24:
		return GL_UNSIGNED_SHORT;
	case GL_DEPTH_COMPONENT32:
		return GL_UNSIGNED_INT;
	}

	return GL_UNSIGNED_BYTE;
}

void InternalformatCaseBase::generateTextureData(GLuint width, GLuint height, GLenum type, unsigned int pixelSize,
												 unsigned int components, std::vector<unsigned char>& result) const
{
	// colors are the 4 corner colors specified ( lower left, lower right, upper left, upper right )
	static tcu::Vec4 colors[4] = { tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
								   tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f) };

	typedef void (*ColorConversionFunc)(tcu::Vec4, unsigned char*, int);
	typedef std::map<GLenum, ColorConversionFunc> ColorConversionMap;
	static ColorConversionMap colorConversionMap;
	if (colorConversionMap.empty())
	{
		colorConversionMap[GL_BYTE]						   = &convertByte;
		colorConversionMap[GL_UNSIGNED_BYTE]			   = &convertUByte;
		colorConversionMap[GL_HALF_FLOAT]				   = &convertHFloat;
		colorConversionMap[GL_FLOAT]					   = &convertFloat;
		colorConversionMap[GL_SHORT]					   = &convertShort;
		colorConversionMap[GL_UNSIGNED_SHORT]			   = &convertUShort;
		colorConversionMap[GL_INT]						   = &convertInt;
		colorConversionMap[GL_UNSIGNED_INT]				   = &convertUInt;
		colorConversionMap[GL_UNSIGNED_INT_24_8]		   = &convertUInt_24_8;
		colorConversionMap[GL_UNSIGNED_SHORT_4_4_4_4]	  = &convertUShort_4_4_4_4;
		colorConversionMap[GL_UNSIGNED_SHORT_5_5_5_1]	  = &convertUShort_5_5_5_1;
		colorConversionMap[GL_UNSIGNED_SHORT_5_6_5]		   = &convertUShort_5_6_5;
		colorConversionMap[GL_UNSIGNED_INT_2_10_10_10_REV] = &convertUInt_2_10_10_10_rev;
	}

	ColorConversionFunc convertColor = colorConversionMap.at(type);

	float lwidth  = static_cast<float>(width - 1);
	float lheight = static_cast<float>(height - 1);

	result.resize(width * height * pixelSize);
	unsigned char* dataPtr = &result[0];

	for (GLuint y = 0; y < height; ++y)
	{
		for (GLuint x = 0; x < width; ++x)
		{
			float	 posX  = (lwidth - static_cast<float>(x)) / lwidth;
			float	 posY  = (lheight - static_cast<float>(y)) / lheight;
			float	 rposX = 1.f - posX;
			float	 rposY = 1.f - posY;
			tcu::Vec4 c		= colors[0] * (posX * posY) + colors[1] * (rposX * posY) + colors[2] * (posX * rposY);

			// Hard-code the alpha as small floating point instability results in large differences for some formats
			c[3] = 1.f;
			convertColor(c, dataPtr, static_cast<int>(components));
			dataPtr += pixelSize;
		}
	}
}

void InternalformatCaseBase::convertByte(tcu::Vec4 inColor, unsigned char* dst, int components)
{
	char* dstChar = reinterpret_cast<char*>(dst);
	for (int i	 = 0; i < components; ++i)
		dstChar[i] = static_cast<char>(inColor[i] * 127.0f);
}

void InternalformatCaseBase::convertUByte(tcu::Vec4 inColor, unsigned char* dst, int components)
{
	for (int i = 0; i < components; ++i)
		dst[i] = static_cast<unsigned char>(inColor[i] * 255.f);
}

void InternalformatCaseBase::convertHFloat(tcu::Vec4 inColor, unsigned char* dst, int components)
{
	GLhalf* dstHalf = reinterpret_cast<GLhalf*>(dst);
	for (int i	 = 0; i < components; ++i)
		dstHalf[i] = floatToHalf(inColor[i]);
}

void InternalformatCaseBase::convertFloat(tcu::Vec4 inColor, unsigned char* dst, int components)
{
	float* dstFloat = reinterpret_cast<float*>(dst);
	for (int i		= 0; i < components; ++i)
		dstFloat[i] = inColor[i];
}

void InternalformatCaseBase::convertShort(tcu::Vec4 inColor, unsigned char* dst, int components)
{
	short* dstUShort = reinterpret_cast<short*>(dst);
	for (int i = 0; i < components; ++i)
	{
		double c	 = static_cast<double>(inColor[i]);
		dstUShort[i] = static_cast<short>(c * 32768 - 1);
	}
}

void InternalformatCaseBase::convertUShort(tcu::Vec4 inColor, unsigned char* dst, int components)
{
	unsigned short* dstUShort = reinterpret_cast<unsigned short*>(dst);
	for (int i = 0; i < components; ++i)
	{
		double c	 = static_cast<double>(inColor[i]);
		dstUShort[i] = static_cast<unsigned short>(c * 65535u);
	}
}

void InternalformatCaseBase::convertInt(tcu::Vec4 inColor, unsigned char* dst, int components)
{
	int* dstUInt = reinterpret_cast<int*>(dst);
	for (int i	 = 0; i < components; ++i)
		dstUInt[i] = static_cast<int>(inColor[i] * 2147483648u - 1);
}

void InternalformatCaseBase::convertUInt(tcu::Vec4 inColor, unsigned char* dst, int components)
{
	unsigned int* dstUInt = reinterpret_cast<unsigned int*>(dst);
	for (int i = 0; i < components; ++i)
	{
		double c   = static_cast<double>(inColor[i]);
		dstUInt[i] = static_cast<unsigned int>(c * 4294967295u);
	}
}

void InternalformatCaseBase::convertUInt_24_8(tcu::Vec4 inColor, unsigned char* dst, int)
{
	unsigned int* dstUint = reinterpret_cast<unsigned int*>(dst);

	unsigned int d = static_cast<unsigned int>(inColor[0] * 16777215u) << 8;
	unsigned int s = static_cast<unsigned int>(inColor[1] * 255u);

	dstUint[0] = (d & 0xFFFFFF00) | (s & 0xFF);
}

void InternalformatCaseBase::convertUShort_4_4_4_4(tcu::Vec4 inColor, unsigned char* dst, int)
{
	unsigned short* dstUShort = reinterpret_cast<unsigned short*>(dst);

	unsigned int r = static_cast<unsigned int>(inColor[0] * 15) << 12;
	unsigned int g = static_cast<unsigned int>(inColor[1] * 15) << 8;
	unsigned int b = static_cast<unsigned int>(inColor[2] * 15) << 4;
	unsigned int a = static_cast<unsigned int>(inColor[3] * 15) << 0;

	dstUShort[0] = (r & 0xF000) | (g & 0x0F00) | (b & 0x00F0) | (a & 0x000F);
}

void InternalformatCaseBase::convertUShort_5_5_5_1(tcu::Vec4 inColor, unsigned char* dst, int)
{
	unsigned short* dstUShort = reinterpret_cast<unsigned short*>(dst);

	unsigned int r = static_cast<unsigned int>(inColor[0] * 31) << 11;
	unsigned int g = static_cast<unsigned int>(inColor[1] * 31) << 6;
	unsigned int b = static_cast<unsigned int>(inColor[2] * 31) << 1;
	unsigned int a = static_cast<unsigned int>(inColor[3] * 1) << 0;

	dstUShort[0] = (r & 0xF800) | (g & 0x07c0) | (b & 0x003e) | (a & 0x0001);
}

void InternalformatCaseBase::convertUShort_5_6_5(tcu::Vec4 inColor, unsigned char* dst, int)
{
	unsigned short* dstUShort = reinterpret_cast<unsigned short*>(dst);

	unsigned int r = static_cast<unsigned int>(inColor[0] * 31) << 11;
	unsigned int g = static_cast<unsigned int>(inColor[1] * 63) << 5;
	unsigned int b = static_cast<unsigned int>(inColor[2] * 31) << 0;

	dstUShort[0] = (r & 0xF800) | (g & 0x07e0) | (b & 0x001f);
}

void InternalformatCaseBase::convertUInt_2_10_10_10_rev(tcu::Vec4 inColor, unsigned char* dst, int)
{
	unsigned int* dstUint = reinterpret_cast<unsigned int*>(dst);

	// Alpha value is rounded to eliminate small precision errors that
	// may result in big errors after converting value to just 4 bits
	unsigned int a = static_cast<unsigned int>(deFloatRound(inColor[3] * 3)) << 30;
	unsigned int b = static_cast<unsigned int>(inColor[2] * 1023) << 20;
	unsigned int g = static_cast<unsigned int>(inColor[1] * 1023) << 10;
	unsigned int r = static_cast<unsigned int>(inColor[0] * 1023) << 0;

	dstUint[0] = (a & 0xC0000000) | (b & 0x3FF00000) | (g & 0x000FFC00) | (r & 0x000003FF);
}

GLhalf InternalformatCaseBase::floatToHalf(float f)
{
	const unsigned int HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP = 0x38000000;
	// Max exponent value in single precision that will be converted
	// to Inf or Nan when stored as a half-float
	const unsigned int HALF_FLOAT_MAX_BIASED_EXP_AS_SINGLE_FP_EXP = 0x47800000;
	// 255 is the max exponent biased value
	const unsigned int FLOAT_MAX_BIASED_EXP		 = (0xFF << 23);
	const unsigned int HALF_FLOAT_MAX_BIASED_EXP = (0x1F << 10);

	char*		 c	= reinterpret_cast<char*>(&f);
	unsigned int x	= *reinterpret_cast<unsigned int*>(c);
	unsigned int sign = static_cast<GLhalf>(x >> 31);

	// Get mantissa
	unsigned int mantissa = x & ((1 << 23) - 1);
	// Get exponent bits
	unsigned int exp = x & FLOAT_MAX_BIASED_EXP;

	if (exp >= HALF_FLOAT_MAX_BIASED_EXP_AS_SINGLE_FP_EXP)
	{
		// Check if the original single precision float number is a NaN
		if (mantissa && (exp == FLOAT_MAX_BIASED_EXP))
		{
			// We have a single precision NaN
			mantissa = (1 << 23) - 1;
		}
		else
		{
			// 16-bit half-float representation stores number as Inf
			mantissa = 0;
		}
		return (GLhalf)((((GLhalf)sign) << 15) | (GLhalf)(HALF_FLOAT_MAX_BIASED_EXP) | (GLhalf)(mantissa >> 13));
	}
	// Check if exponent is <= -15
	else if (exp <= HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP)
	{
		// Store a denorm half-float value or zero
		exp = (HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP - exp) >> 23;
		mantissa |= (1 << 23);
		mantissa >>= (14 + exp);
		return (GLhalf)((((GLhalf)sign) << 15) | (GLhalf)(mantissa));
	}

	return (GLhalf)((((GLhalf)sign) << 15) | (GLhalf)((exp - HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP) >> 13) |
					(GLhalf)(mantissa >> 13));
}

class Texture2DCase : public InternalformatCaseBase
{
public:
	Texture2DCase(deqp::Context& context, const std::string& name, const TextureFormat& textureFormat);
	virtual ~Texture2DCase()
	{
	}

	virtual tcu::TestNode::IterateResult iterate(void);

private:
	TextureFormat m_testFormat;
};

Texture2DCase::Texture2DCase(deqp::Context& context, const std::string& name, const TextureFormat& testFormat)
	: InternalformatCaseBase(context, name.c_str()), m_testFormat(testFormat)
{
}

tcu::TestNode::IterateResult Texture2DCase::iterate(void)
{
	if (!requiredExtensionsSupported(m_testFormat.requiredExtension, m_testFormat.secondReqiredExtension))
		return STOP;

	glu::RenderContext&  renderContext   = m_context.getRenderContext();
	const Functions&	 gl				 = renderContext.getFunctions();

	typedef std::map<GLenum, TextureFormat> ReferenceFormatMap;
	static ReferenceFormatMap formatMap;
	if (formatMap.empty())
	{
		formatMap[GL_RED]			  = TextureFormat(GL_RED, GL_UNSIGNED_BYTE, GL_RED);
		formatMap[GL_RG]			  = TextureFormat(GL_RG, GL_UNSIGNED_BYTE, GL_RG);
		formatMap[GL_RGB]			  = TextureFormat(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB);
		formatMap[GL_RGBA]			  = TextureFormat(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB);
		formatMap[GL_RGBA_INTEGER]	= TextureFormat(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB);
		formatMap[GL_RGB_INTEGER]	 = TextureFormat(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB);
		formatMap[GL_ALPHA]			  = TextureFormat(GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA);
		formatMap[GL_LUMINANCE]		  = TextureFormat(GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE);
		formatMap[GL_LUMINANCE_ALPHA] = TextureFormat(GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE_ALPHA);
		formatMap[GL_DEPTH_COMPONENT] = TextureFormat(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT);
		formatMap[GL_DEPTH_STENCIL] = TextureFormat(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL);

		if (glu::IsES3Compatible(gl))
		{
			formatMap[GL_DEPTH_STENCIL] = TextureFormat(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8_OES);
		}
	}

	ReferenceFormatMap::iterator formatIterator = formatMap.find(m_testFormat.format);
	if (formatIterator == formatMap.end())
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Error: Unknown 2D texture format "
						   << glu::getTextureFormatStr(m_testFormat.format).toString() << tcu::TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		return STOP;
	}

	const TextureFormat& referenceFormat = formatIterator->second;

	if (m_renderWidth > m_context.getRenderTarget().getWidth())
		m_renderWidth = m_context.getRenderTarget().getWidth();
	if (m_renderHeight > m_context.getRenderTarget().getHeight())
		m_renderHeight = m_context.getRenderTarget().getHeight();

	// Setup viewport
	gl.viewport(0, 0, m_renderWidth, m_renderHeight);
	gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);

	// Create test and reference texture
	GLuint testTextureName = createTexture(m_testFormat.internalFormat, m_testFormat.format, m_testFormat.type,
										   m_testFormat.minFilter, m_testFormat.magFilter);
	GLuint referenceTextureName = createTexture(referenceFormat.internalFormat, referenceFormat.format,
												referenceFormat.type, m_testFormat.minFilter, m_testFormat.magFilter);

	// Create program that will render tested texture to screen
	glu::ShaderProgram testProgram(
		renderContext,
		prepareTexturingProgramSources(m_testFormat.internalFormat, m_testFormat.format, m_testFormat.type));
	if (!testProgram.isOk())
	{
		m_testCtx.getLog() << testProgram;
		TCU_FAIL("Compile failed");
	}
	gl.useProgram(testProgram.getProgram());
	gl.uniform1i(gl.getUniformLocation(testProgram.getProgram(), "sampler"), 0);

	// Render textured quad with tested texture
	gl.bindTexture(GL_TEXTURE_2D, testTextureName);
	renderTexturedQuad(testProgram.getProgram());
	tcu::Surface testSurface(m_renderWidth, m_renderHeight);
	glu::readPixels(renderContext, 0, 0, testSurface.getAccess());

	// Create program that will render reference texture to screen
	glu::ProgramSources referenceSources =
		prepareTexturingProgramSources(referenceFormat.internalFormat, referenceFormat.format, referenceFormat.type);
	glu::ShaderProgram referenceProgram(renderContext, referenceSources);
	if (!referenceProgram.isOk())
	{
		m_testCtx.getLog() << referenceProgram;
		TCU_FAIL("Compile failed");
	}
	gl.useProgram(referenceProgram.getProgram());
	gl.uniform1i(gl.getUniformLocation(referenceProgram.getProgram(), "sampler"), 0);

	// Render textured quad with reference texture
	gl.bindTexture(GL_TEXTURE_2D, referenceTextureName);
	renderTexturedQuad(referenceProgram.getProgram());
	tcu::Surface referenceSurface(m_renderWidth, m_renderHeight);
	glu::readPixels(renderContext, 0, 0, referenceSurface.getAccess());

	// Compare surfaces
	if (tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", referenceSurface, testSurface, 0.05f,
						  tcu::COMPARE_LOG_RESULT))
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	gl.deleteTextures(1, &testTextureName);
	gl.deleteTextures(1, &referenceTextureName);

	return STOP;
}

class CopyTexImageCase : public InternalformatCaseBase
{
public:
	CopyTexImageCase(deqp::Context& context, const std::string& name, const CopyTexImageFormat& copyTexImageFormat);
	virtual ~CopyTexImageCase()
	{
	}

	virtual tcu::TestNode::IterateResult iterate(void);

private:
	CopyTexImageFormat m_testFormat;
};

CopyTexImageCase::CopyTexImageCase(deqp::Context& context, const std::string& name,
								   const CopyTexImageFormat& copyTexImageFormat)
	: InternalformatCaseBase(context, name.c_str()), m_testFormat(copyTexImageFormat)
{
}

tcu::TestNode::IterateResult CopyTexImageCase::iterate(void)
{
	if (!requiredExtensionsSupported(m_testFormat.requiredExtension, m_testFormat.secondReqiredExtension))
		return STOP;

	glu::RenderContext& renderContext = m_context.getRenderContext();
	const Functions&	gl			  = renderContext.getFunctions();

	// Determine texture format and type
	GLint  textureInternalFormat = m_testFormat.internalFormat;
	GLuint textureType			 = getTypeFromInternalFormat(textureInternalFormat);
	GLuint textureFormat		 = getUnsizedFormatFromInternalFormat(textureInternalFormat);

	// Create program that will render texture to screen
	glu::ShaderProgram program(renderContext,
							   prepareTexturingProgramSources(textureInternalFormat, textureFormat, textureType));
	if (!program.isOk())
	{
		m_testCtx.getLog() << program;
		TCU_FAIL("Compile failed");
	}
	gl.useProgram(program.getProgram());
	gl.uniform1i(gl.getUniformLocation(program.getProgram(), "sampler"), 0);
	gl.viewport(0, 0, m_renderWidth, m_renderHeight);

	// Create required textures
	GLuint referenceTextureId = createTexture(textureInternalFormat, textureFormat, textureType, m_testFormat.minFilter,
											  m_testFormat.magFilter);
	GLuint copiedTextureId = createTexture(textureInternalFormat, textureFormat, textureType, m_testFormat.minFilter,
										   m_testFormat.magFilter, false);

	// Create main RGBA framebuffer - this is needed because some default framebuffer may be RGB
	GLuint mainFboId = 0;
	gl.genFramebuffers(1, &mainFboId);
	gl.bindFramebuffer(GL_FRAMEBUFFER, mainFboId);
	GLuint mainFboColorTextureId = createTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, false);
	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mainFboColorTextureId, 0);

	// Render reference texture to main FBO and grab it
	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	gl.bindTexture(GL_TEXTURE_2D, referenceTextureId);
	renderTexturedQuad(program.getProgram());
	tcu::Surface referenceSurface(m_renderWidth, m_renderHeight);
	glu::readPixels(renderContext, 0, 0, referenceSurface.getAccess());

	GLuint copyFboId				  = 0;
	GLuint copyFboColorTextureId	  = 0;

	// When possible use separate FBO for copy operation; create copy FBO and
	// attach reference texture to color or depth attachment
	gl.genFramebuffers(1, &copyFboId);
	gl.bindFramebuffer(GL_FRAMEBUFFER, copyFboId);

	if (textureFormat == GL_DEPTH_COMPONENT)
	{
		copyFboColorTextureId = createTexture(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, GL_NEAREST, GL_NEAREST, false);
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, copyFboColorTextureId, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D");
		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, referenceTextureId, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D");
	}
	else
	{
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, referenceTextureId, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D");
	}

	// If FBO is complete, then go back to use default FBO
	GLenum bufferStatus = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
	if (bufferStatus != GL_FRAMEBUFFER_COMPLETE)
	{
		// Bind back to main FBO
		gl.bindFramebuffer(GL_FRAMEBUFFER, mainFboId);
		gl.deleteFramebuffers(1, &copyFboId);
		if (copyFboColorTextureId)
			gl.deleteTextures(1, &copyFboColorTextureId);
		// Check the bits of each channel first, because according the GLES3.2 spec, the component sizes of internalformat
		// must exactly match the corresponding component sizes of the source buffer's effective internal format.
		if (glu::isContextTypeES(renderContext.getType()) && getTypeFromInternalFormat(textureInternalFormat) != GL_UNSIGNED_BYTE)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Not supported: The component sizes of internalformat do not exactly "
			<< "match the corresponding component sizes of the source buffer's effective internal format." << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "The test format isn't renderable, and the component sizes of "
			"internalformat do not exactly match the corresponding component sizes of the source buffer's effective internal format.");
			gl.deleteFramebuffers(1, &mainFboId);
			gl.deleteTextures(1, &mainFboColorTextureId);
			gl.deleteTextures(1, &copiedTextureId);
			gl.deleteTextures(1, &referenceTextureId);
			return STOP;
		}
	}

	// Copy attachment from copy FBO to tested texture (if copy FBO couldn't be created
	// then copying will be done from main FBO color attachment)
	gl.bindTexture(GL_TEXTURE_2D, copiedTextureId);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
	gl.copyTexImage2D(GL_TEXTURE_2D, 0, textureInternalFormat, 0, 0, m_renderWidth, m_renderHeight, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyTexImage2D");

	// Make sure that main FBO is bound
	gl.bindFramebuffer(GL_FRAMEBUFFER, mainFboId);

	// Render and grab tested texture
	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	gl.bindTexture(GL_TEXTURE_2D, copiedTextureId);
	renderTexturedQuad(program.getProgram());
	tcu::Surface resultSurface(m_renderWidth, m_renderHeight);
	glu::readPixels(renderContext, 0, 0, resultSurface.getAccess());

	// Compare surfaces
	if (tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", referenceSurface, resultSurface,
						  0.05f, tcu::COMPARE_LOG_RESULT))
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	// Cleanup
	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
	gl.deleteFramebuffers(1, &mainFboId);
	gl.deleteTextures(1, &mainFboColorTextureId);
	gl.deleteTextures(1, &copiedTextureId);
	gl.deleteTextures(1, &referenceTextureId);

	return STOP;
}

class RenderbufferCase : public InternalformatCaseBase
{
public:
	RenderbufferCase(deqp::Context& context, const std::string& name, const RenderbufferFormat& renderbufferFormat);
	virtual ~RenderbufferCase();

	virtual tcu::TestNode::IterateResult iterate(void);

private:
	void constructOrthoProjMatrix(GLfloat* mat4, GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n,
								  GLfloat f) const;
	bool   createFramebuffer();
	void   deleteFramebuffer();
	GLuint createAndAttachRenderBuffer(GLenum rbFormat, GLenum fbAttachment);
	void renderColoredQuad(GLuint programId, const float* positions) const;
	glu::ProgramSources prepareColoringProgramSources(GLenum format, GLenum type) const;
	void convertUInt(const tcu::PixelBufferAccess &src, const tcu::PixelBufferAccess &dst);
	void convertUInt_2_10_10_10_rev(const tcu::PixelBufferAccess &src, const tcu::PixelBufferAccess &dst);

private:
	GLuint			   m_fbo;
	GLuint			   m_rbColor;
	GLuint			   m_rbDepth;
	GLuint			   m_rbStencil;
	RenderbufferFormat m_testFormat;
};

RenderbufferCase::RenderbufferCase(deqp::Context& context, const std::string& name,
								   const RenderbufferFormat& renderbufferFormat)
	: InternalformatCaseBase(context, name.c_str())
	, m_fbo(0)
	, m_rbColor(0)
	, m_rbDepth(0)
	, m_rbStencil(0)
	, m_testFormat(renderbufferFormat)
{
}

RenderbufferCase::~RenderbufferCase()
{
}

tcu::TestNode::IterateResult RenderbufferCase::iterate(void)
{
	if (!requiredExtensionsSupported(m_testFormat.requiredExtension, m_testFormat.secondReqiredExtension))
		return STOP;

	glu::RenderContext& renderContext = m_context.getRenderContext();
	const Functions&	gl			  = renderContext.getFunctions();

	int maxRenderbufferSize;
	gl.getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &maxRenderbufferSize);
	int windowWidth  = m_context.getRenderTarget().getWidth();
	int windowHeight = m_context.getRenderTarget().getHeight();
	m_renderWidth	= (windowWidth > maxRenderbufferSize) ? maxRenderbufferSize : windowWidth;
	m_renderHeight   = (windowHeight > maxRenderbufferSize) ? maxRenderbufferSize : windowHeight;

	float			   w					   = static_cast<float>(m_renderWidth);
	float			   h					   = static_cast<float>(m_renderHeight);
	static const float bigQuadPositionsSet[]   = { 0, 0, 0, w, 0, 0, 0, h, 0, w, h, 0 };
	static const float smallQuadPositionsSet[] = { 5.0f, 5.0f,  0.5f, w / 2, 5.0f,  0.5f,
												   5.0f, h / 2, 0.5f, w / 2, h / 2, 0.5f };

	bool stencilRenderbufferAvailable =
		(m_testFormat.type == RENDERBUFFER_STENCIL) || (m_testFormat.type == RENDERBUFFER_DEPTH_STENCIL);

	GLenum	testFormat = getUnsizedFormatFromInternalFormat(m_testFormat.format);
	GLenum	testType = getTypeFromInternalFormat(m_testFormat.format);

	// We need surfaces for depth testing and stencil testing, and also for
	// storing the reference and the values for the format under testing
	tcu::Surface testSurface[2][2];
	for (GLuint loop1 = 0; loop1 < 2; loop1++)
	for (GLuint loop2 = 0; loop2 < 2; loop2++)
		testSurface[loop1][loop2].setSize(m_renderWidth, m_renderHeight);

	GLint defaultFramebufferDepthBits   = 0;
	GLint defaultFramebufferStencilBits = 0;
	if (glu::isContextTypeES(m_context.getRenderContext().getType()))
	{
		gl.getIntegerv(GL_DEPTH_BITS, &defaultFramebufferDepthBits);
		gl.getIntegerv(GL_STENCIL_BITS, &defaultFramebufferStencilBits);
	}
	else
	{
		GLint hasDepthBuffer	= 0;
		GLint hasStencilBuffer	= 0;

		gl.getNamedFramebufferAttachmentParameteriv(0, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
													&hasDepthBuffer);
		gl.getNamedFramebufferAttachmentParameteriv(0, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
													&hasStencilBuffer);

		if (hasDepthBuffer != GL_NONE)
			gl.getNamedFramebufferAttachmentParameteriv(0, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
														&defaultFramebufferDepthBits);

		if (hasStencilBuffer != GL_NONE)
			gl.getNamedFramebufferAttachmentParameteriv(0, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
														&defaultFramebufferStencilBits);
	}

	// Create two programs for rendering, one for rendering into default FB, and
	// a second one to render in our created FB

	glu::ShaderProgram program0(renderContext, prepareColoringProgramSources(GL_RGBA, GL_UNSIGNED_BYTE));
	glu::ShaderProgram program1(renderContext, prepareColoringProgramSources(testFormat, testType));

	std::vector<glu::ShaderProgram*> programs;
	programs.push_back(&program0);
	programs.push_back(&program1);

	bool testNonStencil = (m_testFormat.type != RENDERBUFFER_STENCIL);
	bool testStencil = defaultFramebufferStencilBits && stencilRenderbufferAvailable;

	for (GLuint loop = 0; loop < 2; loop++)
	{
		if (!programs[loop]->isOk())
		{
			m_testCtx.getLog() << *programs[loop];
			TCU_FAIL("Compile failed");
		}

		gl.useProgram(programs[loop]->getProgram());
		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");

		float mvpMatrix[16];
		constructOrthoProjMatrix(mvpMatrix, 0.0, m_renderWidth, 0.0f, m_renderHeight, 1.0f, -1.0f);
		GLint mvpUniformLocation = gl.getUniformLocation(programs[loop]->getProgram(), "mvpMatrix");
		gl.uniformMatrix4fv(mvpUniformLocation, 1, 0, mvpMatrix);

		gl.bindTexture(GL_TEXTURE_2D, 0);
		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
		gl.viewport(0, 0, m_renderWidth, m_renderHeight);

		if (testNonStencil)
		{
			if (loop && !createFramebuffer())
				return STOP;

			if (defaultFramebufferDepthBits)
			{
				gl.enable(GL_DEPTH_TEST);
				gl.depthFunc(GL_LESS);
			}

			gl.bindFramebuffer(GL_FRAMEBUFFER, loop ? m_fbo : m_context.getRenderContext().getDefaultFramebuffer());
			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

			if (defaultFramebufferDepthBits)
			{
				// Draw a small quad just in the z buffer
				gl.colorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
				renderColoredQuad(programs[loop]->getProgram(), smallQuadPositionsSet);

				// Large quad should be drawn on top small one to verify that the depth test is working
				gl.colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
			}

			// Draws large quad
			renderColoredQuad(programs[loop]->getProgram(), bigQuadPositionsSet);

			if (loop && testFormat == GL_RGBA_INTEGER)
			{
				de::ArrayBuffer<deUint32> pixels;
				pixels.setStorage(4 * m_renderWidth * m_renderHeight);
				tcu::PixelBufferAccess pixelBuffer(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32),
												   m_renderWidth, m_renderHeight, 1, pixels.getPtr());
				glu::readPixels(renderContext, 0, 0, pixelBuffer);
				if (testType == GL_UNSIGNED_INT_2_10_10_10_REV)
					convertUInt_2_10_10_10_rev(pixelBuffer, testSurface[0][loop].getAccess());
				else
					convertUInt(pixelBuffer, testSurface[0][loop].getAccess());
			}
			else
			{
				glu::readPixels(renderContext, 0, 0, testSurface[0][loop].getAccess());
			}
		}

		if (loop)
			deleteFramebuffer();

		if (defaultFramebufferStencilBits && stencilRenderbufferAvailable)
		{
			gl.disable(GL_DEPTH_TEST);
			gl.enable(GL_STENCIL_TEST);

			if (loop && !createFramebuffer())
				return STOP;

			gl.bindFramebuffer(GL_FRAMEBUFFER, loop ? m_fbo : m_context.getRenderContext().getDefaultFramebuffer());
			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

			// Draw a rect scissored to half the screen height, incrementing the stencil buffer.
			gl.enable(GL_SCISSOR_TEST);
			gl.scissor(0, 0, m_renderWidth, m_renderHeight / 2);
			gl.stencilFunc(GL_ALWAYS, 0x0, 0xFF);
			gl.stencilOp(GL_ZERO, GL_INCR, GL_INCR);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilOp");
			renderColoredQuad(programs[loop]->getProgram(), bigQuadPositionsSet);
			gl.disable(GL_SCISSOR_TEST);

			// Only draw where stencil is equal to 1
			gl.stencilFunc(GL_EQUAL, 0x01, 0xFF);
			gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
			gl.clear(GL_COLOR_BUFFER_BIT);
			renderColoredQuad(programs[loop]->getProgram(), bigQuadPositionsSet);

			glu::readPixels(renderContext, 0, 0, testSurface[1][loop].getAccess());

			gl.disable(GL_STENCIL_TEST);

			if (loop)
				deleteFramebuffer();
		}
	}

	// Compare surfaces for non-stencil
	if (testNonStencil && !tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result",
											 testSurface[0][0], testSurface[0][1],
											 0.05f, tcu::COMPARE_LOG_RESULT))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Depth subtest failed");
		return STOP;
	}

	// Compare surfaces for stencil
	if (testStencil && !tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result",
										  testSurface[1][0], testSurface[1][1],
										  0.05f, tcu::COMPARE_LOG_RESULT))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Stencil subtest failed");
		return STOP;
	}

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

void RenderbufferCase::constructOrthoProjMatrix(GLfloat* mat4, GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n,
												GLfloat f) const
{
	GLfloat inv_width  = 1.0f / (r - l);
	GLfloat inv_height = 1.0f / (t - b);
	GLfloat inv_depth  = 1.0f / (f - n);

	memset(mat4, 0, sizeof(GLfloat) * 16);
	/*
        0    4    8    12
        1    5    9    13
        2    6    10    14
        3    7    11    15
    */

	mat4[0]  = 2.0f * inv_width;
	mat4[5]  = 2.0f * inv_height;
	mat4[10] = 2.0f * inv_depth;

	mat4[12] = -(r + l) * inv_width;
	mat4[13] = -(t + b) * inv_height;
	mat4[14] = -(f + n) * inv_depth;
	mat4[15] = 1.0f;
}

bool RenderbufferCase::createFramebuffer()
{
	glu::RenderContext& renderContext = m_context.getRenderContext();
	const Functions&	gl			  = renderContext.getFunctions();

	gl.genFramebuffers(1, &m_fbo);
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);

	if (m_testFormat.type == RENDERBUFFER_COLOR)
	{
		m_rbColor = createAndAttachRenderBuffer(m_testFormat.format, GL_COLOR_ATTACHMENT0);
		m_rbDepth = createAndAttachRenderBuffer(GL_DEPTH_COMPONENT16, GL_DEPTH_ATTACHMENT);
	}
	else
	{
		m_rbColor = createAndAttachRenderBuffer(GL_RGBA8, GL_COLOR_ATTACHMENT0);
		if (m_testFormat.type == RENDERBUFFER_DEPTH)
			m_rbDepth = createAndAttachRenderBuffer(m_testFormat.format, GL_DEPTH_ATTACHMENT);
		else if (m_testFormat.type == RENDERBUFFER_STENCIL)
			m_rbStencil = createAndAttachRenderBuffer(m_testFormat.format, GL_STENCIL_ATTACHMENT);
		else if (m_testFormat.type == RENDERBUFFER_DEPTH_STENCIL)
		{
			if (glu::contextSupports(renderContext.getType(), glu::ApiType::es(2, 0)))
			{
				m_rbDepth = createAndAttachRenderBuffer(m_testFormat.format, GL_DEPTH_ATTACHMENT);
				gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbDepth);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer");
			}
			else
				m_rbDepth = createAndAttachRenderBuffer(m_testFormat.format, GL_DEPTH_STENCIL_ATTACHMENT);
		}
	}

	GLenum bufferStatus = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
	if (bufferStatus == GL_FRAMEBUFFER_UNSUPPORTED)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Unsuported framebuffer");
		return false;
	}
	else if (bufferStatus != GL_FRAMEBUFFER_COMPLETE)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Framebuffer not complete");
		return false;
	}

	return true;
}

void RenderbufferCase::deleteFramebuffer()
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
	if (m_fbo)
		gl.deleteFramebuffers(1, &m_fbo);
	if (m_rbColor)
		gl.deleteRenderbuffers(1, &m_rbColor);
	if (m_rbDepth)
		gl.deleteRenderbuffers(1, &m_rbDepth);
	if (m_rbStencil)
		gl.deleteRenderbuffers(1, &m_rbStencil);
}

GLuint RenderbufferCase::createAndAttachRenderBuffer(GLenum rbFormat, GLenum fbAttachment)
{
	const Functions& gl = m_context.getRenderContext().getFunctions();

	GLuint rbName;

	gl.genRenderbuffers(1, &rbName);
	gl.bindRenderbuffer(GL_RENDERBUFFER, rbName);
	gl.renderbufferStorage(GL_RENDERBUFFER, rbFormat, m_renderWidth, m_renderHeight);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage");
	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, fbAttachment, GL_RENDERBUFFER, rbName);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer");

	return rbName;
}

void RenderbufferCase::renderColoredQuad(GLuint programId, const float* positions) const
{
	// Prepare data for rendering
	static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
	static const float	colors[]		= {
		1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
	};
	const glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 3, 4, 0, positions),
													 glu::va::Float("color", 4, 4, 0, colors) };

	glu::draw(m_context.getRenderContext(), programId, DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
			  glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
}

glu::ProgramSources RenderbufferCase::prepareColoringProgramSources(GLenum format, GLenum type) const
{
	glu::RenderContext& renderContext	  = m_context.getRenderContext();
	glu::ContextType	contextType		   = renderContext.getType();
	glu::GLSLVersion	glslVersion		   = glu::getContextTypeGLSLVersion(contextType);
	std::string			versionDeclaration = glu::getGLSLVersionDeclaration(glslVersion);

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

	versionDeclaration += "\n";
	std::string vs = versionDeclaration;
	std::string fs = versionDeclaration;
	if (glu::contextSupports(contextType, glu::ApiType::es(3, 0)) || glu::isContextTypeGLCore(contextType))
	{
		vs += "in highp vec3 position;\n"
			  "in highp vec4 color;\n"
			  "out highp vec4 fColor;\n"
			  "uniform mat4 mvpMatrix;\n"
			  "void main()\n"
			  "{\n"
			  "  fColor = color;\n"
			  "  gl_Position = mvpMatrix * vec4(position, 1.0);\n"
			  "}\n";
		fs += "in highp vec4 fColor;\n"
			  "out ${COLOR_DATA} color;\n"
			  "void main()\n"
			  "{\n"
			  "  color = ${COMPUTE_COLOR};\n"
			  "}\n";
	}
	else
	{
		vs += "attribute highp vec3 position;\n"
			  "attribute highp vec4 color;\n"
			  "varying highp vec4 fColor;\n"
			  "uniform mat4 mvpMatrix;\n"
			  "void main()\n"
			  "{\n"
			  "  fColor = color;\n"
			  "  gl_Position = mvpMatrix * vec4(position, 1.0);\n"
			  "}\n";
		fs += "varying highp vec4 fColor;\n"
			  "void main()\n"
			  "{\n"
			  "  gl_FragColor = fColor;\n"
			  "}\n";
	}

	if (format == GL_RGBA_INTEGER)
	{
		std::string compute_color = "${COLOR_DATA}("
			"${MAX_RED} * fColor.r, "
			"${MAX_GREEN} * fColor.g, "
			"${MAX_BLUE} * fColor.b, "
			"${MAX_ALPHA} * fColor.a)";

		if (type == GL_UNSIGNED_INT_2_10_10_10_REV)
		{
			specializationMap["MAX_RED"] = "1023";
			specializationMap["MAX_GREEN"] = "1023";
			specializationMap["MAX_BLUE"] = "1023";
			specializationMap["MAX_ALPHA"] = "3";
		}
		else
		{
			specializationMap["MAX_RED"] = "255";
			specializationMap["MAX_GREEN"] = "255";
			specializationMap["MAX_BLUE"] = "255";
			specializationMap["MAX_ALPHA"] = "255";
		}
		specializationMap["COLOR_DATA"] = "uvec4";
		specializationMap["COMPUTE_COLOR"] = tcu::StringTemplate(compute_color).specialize(specializationMap);
	}
	else
	{
		specializationMap["COLOR_DATA"] = "highp vec4";
		specializationMap["COMPUTE_COLOR"] = "fColor";
	}

	vs = tcu::StringTemplate(vs).specialize(specializationMap);
	fs = tcu::StringTemplate(fs).specialize(specializationMap);
	return glu::makeVtxFragSources(vs.c_str(), fs.c_str());
}

typedef TextureFormat	  TF;
typedef CopyTexImageFormat CF;
typedef RenderbufferFormat RF;

struct TestData
{
	std::vector<TextureFormat>		texture2DFormats;
	std::vector<CopyTexImageFormat> copyTexImageFormats;
	std::vector<RenderbufferFormat> renderbufferFormats;
};

/** Constructor.
 *
 *  @param context Rendering context.
 */
InternalformatTests::InternalformatTests(deqp::Context& context)
	: TestCaseGroup(context, "internalformat", "Texture internalformat tests")
{
}

template <typename Data, unsigned int Size>
void InternalformatTests::append(std::vector<Data>& dataVector, const Data (&dataArray)[Size])
{
	dataVector.insert(dataVector.end(), dataArray, dataArray + Size);
}

void InternalformatTests::getESTestData(TestData& testData, glu::ContextType& contextType)
{
	TextureFormat commonTexture2DFormats[] = {
		TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA),
		TF(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB),
		TF(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA),
		TF(GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE_ALPHA),
		TF(GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE),
		TF(GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA),
		TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGBA, EXT_texture_type_2_10_10_10_REV),
		TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2, EXT_texture_type_2_10_10_10_REV),
		TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB5_A1, EXT_texture_type_2_10_10_10_REV),
		TF(GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB, EXT_texture_type_2_10_10_10_REV),
		TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT, OES_depth_texture),
		TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT, OES_depth_texture),
		TF(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL, OES_packed_depth_stencil, OES_depth_texture),
		TF(GL_RGB, GL_HALF_FLOAT, GL_RGB16F, OES_texture_half_float),
		TF(GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F, OES_texture_half_float),
		TF(GL_RGB, GL_HALF_FLOAT, GL_RGB16F, OES_texture_half_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
		TF(GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F, OES_texture_half_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
		TF(GL_RGB, GL_FLOAT, GL_RGB32F, OES_texture_float),
		TF(GL_RGBA, GL_FLOAT, GL_RGBA32F, OES_texture_float),
		TF(GL_RGB, GL_FLOAT, GL_RGB32F, OES_texture_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
		TF(GL_RGBA, GL_FLOAT, GL_RGBA32F, OES_texture_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
	};

	CopyTexImageFormat commonCopyTexImageFormats[] = {
		CF(GL_RGB),
		CF(GL_RGBA),
		CF(GL_ALPHA),
		CF(GL_LUMINANCE),
		CF(GL_LUMINANCE_ALPHA),
	};

	RenderbufferFormat commonRenderbufferFormats[] = {
		RF(GL_RGBA8, RENDERBUFFER_COLOR, OES_rgb8_rgba8),
		RF(GL_RGB8, RENDERBUFFER_COLOR, OES_rgb8_rgba8),
	};

	append(testData.texture2DFormats, commonTexture2DFormats);
	append(testData.copyTexImageFormats, commonCopyTexImageFormats);
	append(testData.renderbufferFormats, commonRenderbufferFormats);

	if (glu::contextSupports(contextType, glu::ApiType::es(3, 0)))
	{
		TextureFormat es3Texture2DFormats[] = {
			TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA4),
			TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGB5_A1),
			TF(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB565),
			TF(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4),
			TF(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGBA),
			TF(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1),
			TF(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB),
			TF(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565),
			TF(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8),
			TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8),
			TF(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8),
		};

		CopyTexImageFormat es3CopyTexImageFormats[] = {
			CF(GL_RGBA4),
			CF(GL_RGB5_A1),
			CF(GL_RGB565),
			CF(GL_RGBA8),
			CF(GL_RGB8),
		};

		RenderbufferFormat es3RenderbufferFormats[] = {
			RF(GL_RGB5_A1, RENDERBUFFER_COLOR),
		};

		append(testData.texture2DFormats, es3Texture2DFormats);
		append(testData.copyTexImageFormats, es3CopyTexImageFormats);
		append(testData.renderbufferFormats, es3RenderbufferFormats);
	}
	else if (glu::contextSupports(contextType, glu::ApiType::es(2, 0)))
	{
		TextureFormat es2Texture2DFormats[] = {
			TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGB5_A1, OES_required_internalformat),
			TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA4, OES_required_internalformat),
			TF(GL_RGB, GL_UNSIGNED_BYTE, GL_RGB565, OES_required_internalformat),
			TF(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, OES_required_internalformat),
			TF(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGBA, OES_required_internalformat),
			TF(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, OES_required_internalformat),
			TF(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB, OES_required_internalformat),
			TF(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565, OES_required_internalformat),
			TF(GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_OES, OES_required_internalformat),
			TF(GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE4_ALPHA4_OES, OES_required_internalformat),
			TF(GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_OES, OES_required_internalformat),
			TF(GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_OES, OES_required_internalformat),
			TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT16, OES_required_internalformat,
			   OES_depth_texture),
			TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16, OES_required_internalformat,
			   OES_depth_texture),
			TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT24, OES_required_internalformat, OES_depth24),
			TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32, OES_required_internalformat, OES_depth32),
		};

		CopyTexImageFormat es2CopyTexImageFormats[] = {
			CF(GL_RGB5_A1, OES_required_internalformat),
			CF(GL_RGB565, OES_required_internalformat),
			CF(GL_RGBA4, OES_required_internalformat),
			CF(GL_LUMINANCE4_ALPHA4_OES, OES_required_internalformat),
			CF(GL_LUMINANCE8_ALPHA8_OES, OES_required_internalformat),
			CF(GL_LUMINANCE8_OES, OES_required_internalformat),
			CF(GL_ALPHA8_OES, OES_required_internalformat),
			CF(GL_RGB10_A2, EXT_texture_type_2_10_10_10_REV, OES_required_internalformat),
			CF(GL_RGB10, EXT_texture_type_2_10_10_10_REV, OES_required_internalformat)
		};

		RenderbufferFormat es2RenderbufferFormats[] = {
			RF(GL_STENCIL_INDEX1, RENDERBUFFER_STENCIL, OES_stencil1),
			RF(GL_STENCIL_INDEX4, RENDERBUFFER_STENCIL, OES_stencil4),
			RF(GL_STENCIL_INDEX8, RENDERBUFFER_STENCIL, OES_stencil8),
			RF(GL_DEPTH_COMPONENT16, RENDERBUFFER_DEPTH, OES_depth_texture),
			RF(GL_DEPTH_COMPONENT24, RENDERBUFFER_DEPTH, OES_depth24),
			RF(GL_DEPTH_COMPONENT32, RENDERBUFFER_DEPTH, OES_depth32),
			RF(GL_DEPTH24_STENCIL8, RENDERBUFFER_DEPTH_STENCIL, OES_packed_depth_stencil),
			RF(GL_RGB5_A1, RENDERBUFFER_COLOR, OES_required_internalformat),
		};

		append(testData.texture2DFormats, es2Texture2DFormats);
		append(testData.copyTexImageFormats, es2CopyTexImageFormats);
		append(testData.renderbufferFormats, es2RenderbufferFormats);
	}
}

void InternalformatTests::getGLTestData(TestData& testData, glu::ContextType&)
{
	TextureFormat commonTexture2DFormats[] = {
		TF(GL_RED, GL_BYTE, GL_R8_SNORM),
		TF(GL_RED, GL_SHORT, GL_R16_SNORM),
		TF(GL_RG, GL_BYTE, GL_RG8_SNORM),
		TF(GL_RG, GL_SHORT, GL_RG16_SNORM),
		TF(GL_RGB, GL_BYTE, GL_RGB8_SNORM),
		TF(GL_RGB, GL_SHORT, GL_RGB16_SNORM),
		TF(GL_RGBA, GL_BYTE, GL_RGBA8_SNORM),
		TF(GL_RGBA, GL_SHORT, GL_RGBA16_SNORM),
		TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGBA),
		TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2),
		TF(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB5_A1),
		TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT, ARB_depth_texture),
		TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16, ARB_depth_texture),
		TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT, ARB_depth_texture),
		TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT24, ARB_depth_texture),
		TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32, ARB_depth_texture),
		TF(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT16, ARB_depth_texture),
		TF(GL_RGBA, GL_UNSIGNED_BYTE, GL_RGB9_E5, EXT_texture_shared_exponent),
		TF(GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI, ARB_texture_rgb10_a2ui),
		TF(GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI, EXT_texture_integer),
		TF(GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI, EXT_texture_integer),
		TF(GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI, EXT_texture_integer),
		TF(GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI, EXT_texture_integer),
		TF(GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI, EXT_texture_integer),
		TF(GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI, EXT_texture_integer),
		TF(GL_RGBA_INTEGER, GL_INT, GL_RGBA32I, EXT_texture_integer),
		TF(GL_RGB_INTEGER, GL_INT, GL_RGB32I, EXT_texture_integer),
		TF(GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I, EXT_texture_integer),
		TF(GL_RGB_INTEGER, GL_SHORT, GL_RGB16I, EXT_texture_integer),
		TF(GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I, EXT_texture_integer),
		TF(GL_RGB_INTEGER, GL_BYTE, GL_RGB8I, EXT_texture_integer),
		TF(GL_RED, GL_HALF_FLOAT, GL_R16F, ARB_texture_float),
		TF(GL_RG, GL_HALF_FLOAT, GL_RG16F, ARB_texture_float),
		TF(GL_RGB, GL_HALF_FLOAT, GL_RGB16F, ARB_texture_float),
		TF(GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F, ARB_texture_float),
		TF(GL_RED, GL_FLOAT, GL_R32F, ARB_texture_float),
		TF(GL_RG, GL_FLOAT, GL_RG32F, ARB_texture_float),
		TF(GL_RGB, GL_FLOAT, GL_RGB32F, ARB_texture_float),
		TF(GL_RGBA, GL_FLOAT, GL_RGBA32F, ARB_texture_float),
	};

	CopyTexImageFormat commonCopyTexImageFormats[] = {
		CF(GL_DEPTH_COMPONENT16, ARB_depth_texture),
		CF(GL_DEPTH_COMPONENT24, ARB_depth_texture),
		CF(GL_DEPTH_COMPONENT32, ARB_depth_texture),
		CF(GL_RGB9_E5, EXT_texture_shared_exponent),
		CF(GL_RGB10_A2UI, ARB_texture_rgb10_a2ui),
		CF(GL_RGB10_A2),
	};

	RenderbufferFormat commonRenderbufferFormats[] = {
		RF(GL_RGBA8, RENDERBUFFER_COLOR),
		RF(GL_RGB9_E5, RENDERBUFFER_COLOR, EXT_texture_shared_exponent),
		RF(GL_RGB10_A2UI, RENDERBUFFER_COLOR, ARB_texture_rgb10_a2ui),
		RF(GL_DEPTH24_STENCIL8, RENDERBUFFER_DEPTH_STENCIL),
		RF(GL_DEPTH_COMPONENT16, RENDERBUFFER_DEPTH, ARB_depth_texture),
		RF(GL_DEPTH_COMPONENT24, RENDERBUFFER_DEPTH, ARB_depth_texture),
		RF(GL_DEPTH_COMPONENT32, RENDERBUFFER_DEPTH, ARB_depth_texture),
	};

	append(testData.texture2DFormats, commonTexture2DFormats);
	append(testData.copyTexImageFormats, commonCopyTexImageFormats);
	append(testData.renderbufferFormats, commonRenderbufferFormats);
}

std::string formatToString(GLenum format)
{
	// this function extends glu::getTextureFormatStr by formats used in thise tests

	typedef std::map<GLenum, std::string> FormatMap;
	static FormatMap formatMap;
	if (formatMap.empty())
	{
		// store in map formats that are not supported by glu::getTextureFormatStr
		formatMap[GL_LUMINANCE8_ALPHA8_OES] = "luminance8_alpha8_oes";
		formatMap[GL_LUMINANCE4_ALPHA4_OES] = "luminance4_alpha4_oes";
		formatMap[GL_STENCIL_INDEX1_OES]	= "stencil_index1_oes";
		formatMap[GL_STENCIL_INDEX4_OES]	= "stencil_index4_oes";
		formatMap[GL_LUMINANCE8_OES]		= "luminance8_oes";
		formatMap[GL_ALPHA8_OES]			= "alpha8_oes";
	}

	FormatMap::iterator it = formatMap.find(format);
	if (it == formatMap.end())
	{
		// if format is not in map try glu function
		std::string formatString = glu::getTextureFormatStr(format).toString();

		// cut out "GL_" from string
		formatString = formatString.substr(3, formatString.length());

		// make lower case
		std::transform(formatString.begin(), formatString.end(), formatString.begin(), tolower);

		return formatString;
	}
	return it->second;
}

/** Initializes the test group contents. */
void InternalformatTests::init()
{
	// Determine which data sets should be used for tests
	TestData		 testData;
	glu::ContextType contextType = m_context.getRenderContext().getType();
	if (glu::isContextTypeGLCore(contextType))
		getGLTestData(testData, contextType);
	else
		getESTestData(testData, contextType);

	// Construct texture2d tests
	TestCaseGroup* texture2DGroup = new deqp::TestCaseGroup(m_context, "texture2d", "");
	for (unsigned int i = 0; i < testData.texture2DFormats.size(); i++)
	{
		const TextureFormat& tf				= testData.texture2DFormats[i];
		std::string			 format			= formatToString(tf.format);
		std::string			 type			= glu::getTypeStr(tf.type).toString();
		std::string			 internalFormat = formatToString(tf.internalFormat);

		// cut out "GL_" from type and make it lowercase
		type = type.substr(3, type.length());
		std::transform(type.begin(), type.end(), type.begin(), tolower);

		std::string name = format + "_" + type + "_" + internalFormat;
		if (tf.minFilter == GL_LINEAR)
			name += "_linear";

		texture2DGroup->addChild(new Texture2DCase(m_context, name, tf));
	}
	addChild(texture2DGroup);

	// Construct copy_text_image tests
	TestCaseGroup* copyTexImageGroup = new deqp::TestCaseGroup(m_context, "copy_tex_image", "");
	for (unsigned int i = 0; i < testData.copyTexImageFormats.size(); i++)
	{
		const CopyTexImageFormat& ctif = testData.copyTexImageFormats[i];
		std::string				  name = formatToString(ctif.internalFormat);
		copyTexImageGroup->addChild(new CopyTexImageCase(m_context, name, ctif));
	}
	addChild(copyTexImageGroup);

	// Construct renderbuffer tests
	TestCaseGroup* renderbufferGroup = new deqp::TestCaseGroup(m_context, "renderbuffer", "");
	for (unsigned int i = 0; i < testData.renderbufferFormats.size(); i++)
	{
		const RenderbufferFormat& rbf  = testData.renderbufferFormats[i];
		std::string				  name = formatToString(rbf.format);
		renderbufferGroup->addChild(new RenderbufferCase(m_context, name, rbf));
	}
	addChild(renderbufferGroup);
}

void RenderbufferCase::convertUInt(const tcu::PixelBufferAccess &src, const tcu::PixelBufferAccess &dst)
{
	for (int z = 0; z < dst.getDepth(); ++z)
	for (int y = 0; y < dst.getHeight(); ++y)
	for (int x = 0; x < dst.getWidth(); ++x)
	{
		tcu::UVec4 srcPixel = src.getPixelUint(x, y, z);
		tcu::Vec4 dstPixel(srcPixel.x() / 255.0f, srcPixel.y() / 255.0f, srcPixel.z() / 255.0f, srcPixel.w() / 255.0f);
		dst.setPixel(dstPixel, x, y, z);
	}
}

void RenderbufferCase::convertUInt_2_10_10_10_rev(const tcu::PixelBufferAccess &src, const tcu::PixelBufferAccess &dst)
{
	for (int z = 0; z < dst.getDepth(); ++z)
	for (int y = 0; y < dst.getHeight(); ++y)
	for (int x = 0; x < dst.getWidth(); ++x)
	{
		tcu::UVec4 srcPixel = src.getPixelUint(x, y, z);
		tcu::Vec4 dstPixel(srcPixel.x() / 1023.0f, srcPixel.y() / 1023.0f, srcPixel.z() / 1023.0f, srcPixel.w() / 3.0f);
		dst.setPixel(dstPixel, x, y, z);
	}
}
} /* glcts namespace */
