/*-------------------------------------------------------------------------
 * 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_HALF_FLOAT_OES]			   = &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_OES, GL_RGB, OES_texture_half_float),
		TF(GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA, OES_texture_half_float),
		TF(GL_RGB, GL_HALF_FLOAT_OES, GL_RGB, OES_texture_half_float_linear, DE_NULL, GL_LINEAR, GL_LINEAR),
		TF(GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA, 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_RGB, GL_HALF_FLOAT, GL_RGB16F),
			TF(GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F),
			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 */
