/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief FBO colorbuffer tests.
 *//*--------------------------------------------------------------------*/

#include "es3fFboColorbufferTests.hpp"
#include "es3fFboTestCase.hpp"
#include "es3fFboTestUtil.hpp"
#include "gluTextureUtil.hpp"
#include "gluContextInfo.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRGBA.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "sglrContextUtil.hpp"
#include "deRandom.hpp"
#include "deString.h"
#include "glwEnums.hpp"

namespace deqp
{
namespace gles3
{
namespace Functional
{

using std::string;
using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::IVec2;
using tcu::IVec3;
using tcu::IVec4;
using tcu::UVec4;
using tcu::TestLog;
using namespace FboTestUtil;

const tcu::RGBA MIN_THRESHOLD(12, 12, 12, 12);

template <int Size>
static tcu::Vector<float, Size> randomVector (de::Random& rnd, const tcu::Vector<float, Size>& minVal = tcu::Vector<float, Size>(0.0f), const tcu::Vector<float, Size>& maxVal = tcu::Vector<float, Size>(1.0f))
{
	tcu::Vector<float, Size> res;
	for (int ndx = 0; ndx < Size; ndx++)
		res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
	return res;
}

static tcu::Vec4 generateRandomColor (de::Random& random)
{
	tcu::Vec4 retVal;

	for (int i = 0; i < 3; ++i)
		retVal[i] = random.getFloat();
	retVal[3] = 1.0f;

	return retVal;
}

class FboColorbufferCase : public FboTestCase
{
public:
	FboColorbufferCase (Context& context, const char* name, const char* desc, const deUint32 format)
		: FboTestCase			(context, name, desc)
		, m_format				(format)
	{
	}

	bool compare (const tcu::Surface& reference, const tcu::Surface& result)
	{
		const tcu::RGBA threshold (tcu::max(getFormatThreshold(m_format), MIN_THRESHOLD));

		m_testCtx.getLog() << TestLog::Message << "Comparing images, threshold: " << threshold << TestLog::EndMessage;

		return tcu::bilinearCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(), result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT);
	}

protected:
	const deUint32	m_format;
};

class FboColorClearCase : public FboColorbufferCase
{
public:
	FboColorClearCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height)
		: FboColorbufferCase	(context, name, desc, format)
		, m_width				(width)
		, m_height				(height)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_format);
	}

	void render (tcu::Surface& dst)
	{
		tcu::TextureFormat			fboFormat	= glu::mapGLInternalFormat(m_format);
		tcu::TextureChannelClass	fmtClass	= tcu::getTextureChannelClass(fboFormat.type);
		tcu::TextureFormatInfo		fmtInfo		= tcu::getTextureFormatInfo(fboFormat);
		de::Random					rnd			(17);
		const int					numClears	= 16;
		deUint32					fbo			= 0;
		deUint32					rbo			= 0;

		glGenFramebuffers(1, &fbo);
		glGenRenderbuffers(1, &rbo);

		glBindRenderbuffer(GL_RENDERBUFFER, rbo);
		glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_width, m_height);
		checkError();

		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
		checkError();
		checkFramebufferStatus(GL_FRAMEBUFFER);

		glViewport(0, 0, m_width, m_height);

		// Initialize to transparent black.
		switch (fmtClass)
		{
			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
				glClearBufferfv(GL_COLOR, 0, Vec4(0.0f).getPtr());
				break;

			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
				glClearBufferuiv(GL_COLOR, 0, UVec4(0).getPtr());
				break;

			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
				glClearBufferiv(GL_COLOR, 0, IVec4(0).getPtr());
				break;

			default:
				DE_ASSERT(DE_FALSE);
		}

		// Do random scissored clears.
		glEnable(GL_SCISSOR_TEST);
		for (int ndx = 0; ndx < numClears; ndx++)
		{
			int		x		= rnd.getInt(0, m_width		- 1);
			int		y		= rnd.getInt(0, m_height	- 1);
			int		w		= rnd.getInt(1, m_width		- x);
			int		h		= rnd.getInt(1, m_height	- y);
			Vec4	color	= randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax);

			glScissor(x, y, w, h);

			switch (fmtClass)
			{
				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
					glClearBufferfv(GL_COLOR, 0, color.getPtr());
					break;

				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
					glClearBufferuiv(GL_COLOR, 0, color.cast<deUint32>().getPtr());
					break;

				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
					glClearBufferiv(GL_COLOR, 0, color.cast<int>().getPtr());
					break;

				default:
					DE_ASSERT(DE_FALSE);
			}
		}

		// Read results from renderbuffer.
		readPixels(dst, 0, 0, m_width, m_height, fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias);
		checkError();
	}

private:
	const int			m_width;
	const int			m_height;
};

class FboColorMultiTex2DCase : public FboColorbufferCase
{
public:
	FboColorMultiTex2DCase (Context& context, const char* name, const char* description, deUint32 tex0Fmt, const IVec2& tex0Size, deUint32 tex1Fmt, const IVec2& tex1Size)
		: FboColorbufferCase	(context, name, description, tex0Fmt)
		, m_tex0Fmt				(tex0Fmt)
		, m_tex1Fmt				(tex1Fmt)
		, m_tex0Size			(tex0Size)
		, m_tex1Size			(tex1Size)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_tex0Fmt);
		checkFormatSupport(m_tex1Fmt);
	}

	void render (tcu::Surface& dst)
	{
		tcu::TextureFormat		texFmt0			= glu::mapGLInternalFormat(m_tex0Fmt);
		tcu::TextureFormat		texFmt1			= glu::mapGLInternalFormat(m_tex1Fmt);
		tcu::TextureFormatInfo	fmtInfo0		= tcu::getTextureFormatInfo(texFmt0);
		tcu::TextureFormatInfo	fmtInfo1		= tcu::getTextureFormatInfo(texFmt1);

		Texture2DShader			texToFbo0Shader	(DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt0), fmtInfo0.valueMax-fmtInfo0.valueMin, fmtInfo0.valueMin);
		Texture2DShader			texToFbo1Shader	(DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt1), fmtInfo1.valueMax-fmtInfo1.valueMin, fmtInfo1.valueMin);
		Texture2DShader			multiTexShader	(DataTypes() << glu::getSampler2DType(texFmt0) << glu::getSampler2DType(texFmt1), glu::TYPE_FLOAT_VEC4);

		deUint32				texToFbo0ShaderID = getCurrentContext()->createProgram(&texToFbo0Shader);
		deUint32				texToFbo1ShaderID = getCurrentContext()->createProgram(&texToFbo1Shader);
		deUint32				multiTexShaderID  = getCurrentContext()->createProgram(&multiTexShader);

		// Setup shaders
		multiTexShader.setTexScaleBias(0, fmtInfo0.lookupScale * 0.5f, fmtInfo0.lookupBias * 0.5f);
		multiTexShader.setTexScaleBias(1, fmtInfo1.lookupScale * 0.5f, fmtInfo1.lookupBias * 0.5f);
		texToFbo0Shader.setUniforms(*getCurrentContext(), texToFbo0ShaderID);
		texToFbo1Shader.setUniforms(*getCurrentContext(), texToFbo1ShaderID);
		multiTexShader.setUniforms (*getCurrentContext(), multiTexShaderID);

		// Framebuffers.
		deUint32				fbo0, fbo1;
		deUint32				tex0, tex1;

		for (int ndx = 0; ndx < 2; ndx++)
		{
			glu::TransferFormat		transferFmt		= glu::getTransferFormat(ndx ? texFmt1 : texFmt0);
			deUint32				format			= ndx ? m_tex1Fmt : m_tex0Fmt;
			bool					isFilterable	= glu::isGLInternalColorFormatFilterable(format);
			const IVec2&			size			= ndx ? m_tex1Size : m_tex0Size;
			deUint32&				fbo				= ndx ? fbo1 : fbo0;
			deUint32&				tex				= ndx ? tex1 : tex0;

			glGenFramebuffers(1, &fbo);
			glGenTextures(1, &tex);

			glBindTexture(GL_TEXTURE_2D, tex);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	isFilterable ? GL_LINEAR : GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	isFilterable ? GL_LINEAR : GL_NEAREST);
			glTexImage2D(GL_TEXTURE_2D, 0, format, size.x(), size.y(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);

			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
			checkError();
			checkFramebufferStatus(GL_FRAMEBUFFER);
		}

		// Render textures to both framebuffers.
		for (int ndx = 0; ndx < 2; ndx++)
		{
			const deUint32		format		= GL_RGBA;
			const deUint32		dataType	= GL_UNSIGNED_BYTE;
			const int			texW		= 128;
			const int			texH		= 128;
			deUint32			tmpTex		= 0;
			deUint32			fbo			= ndx ? fbo1 : fbo0;
			const IVec2&		viewport	= ndx ? m_tex1Size : m_tex0Size;
			tcu::TextureLevel	data		(glu::mapGLTransferFormat(format, dataType), texW, texH, 1);

			if (ndx == 0)
				tcu::fillWithComponentGradients(data.getAccess(), Vec4(0.0f), Vec4(1.0f));
			else
				tcu::fillWithGrid(data.getAccess(), 8, Vec4(0.2f, 0.7f, 0.1f, 1.0f), Vec4(0.7f, 0.1f, 0.5f, 0.8f));

			glGenTextures(1, &tmpTex);
			glBindTexture(GL_TEXTURE_2D, tmpTex);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());

			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
			glViewport(0, 0, viewport.x(), viewport.y());
			sglr::drawQuad(*getCurrentContext(), ndx ? texToFbo1ShaderID : texToFbo0ShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		}

		// Render to framebuffer.
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glViewport(0, 0, getWidth(), getHeight());
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, tex0);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, tex1);
		sglr::drawQuad(*getCurrentContext(), multiTexShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

		readPixels(dst, 0, 0, getWidth(), getHeight());
	}

private:
	deUint32		m_tex0Fmt;
	deUint32		m_tex1Fmt;
	IVec2			m_tex0Size;
	IVec2			m_tex1Size;
};

class FboColorTexCubeCase : public FboColorbufferCase
{
public:
	FboColorTexCubeCase			(Context& context, const char* name, const char* description, deUint32 texFmt, const IVec2& texSize)
		: FboColorbufferCase	(context, name, description, texFmt)
		, m_texSize				(texSize)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_format);
	}

	void render (tcu::Surface& dst)
	{
		static const deUint32 cubeGLFaces[] =
		{
			GL_TEXTURE_CUBE_MAP_POSITIVE_X,
			GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
			GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
			GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
			GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
			GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
		};

		static const tcu::CubeFace cubeTexFaces[] =
		{
			tcu::CUBEFACE_POSITIVE_X,
			tcu::CUBEFACE_POSITIVE_Y,
			tcu::CUBEFACE_POSITIVE_Z,
			tcu::CUBEFACE_NEGATIVE_X,
			tcu::CUBEFACE_NEGATIVE_Y,
			tcu::CUBEFACE_NEGATIVE_Z
		};

		de::Random				rnd					(deStringHash(getName()) ^ 0x9eef603d);
		tcu::TextureFormat		texFmt				= glu::mapGLInternalFormat(m_format);
		tcu::TextureFormatInfo	fmtInfo				= tcu::getTextureFormatInfo(texFmt);

		Texture2DShader			texToFboShader		(DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt), fmtInfo.valueMax-fmtInfo.valueMin, fmtInfo.valueMin);
		TextureCubeShader		cubeTexShader		(glu::getSamplerCubeType(texFmt), glu::TYPE_FLOAT_VEC4);

		deUint32				texToFboShaderID	= getCurrentContext()->createProgram(&texToFboShader);
		deUint32				cubeTexShaderID		= getCurrentContext()->createProgram(&cubeTexShader);

		// Setup shaders
		texToFboShader.setUniforms(*getCurrentContext(), texToFboShaderID);
		cubeTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias);

		// Framebuffers.
		std::vector<deUint32>	fbos;
		deUint32				tex;

		{
			glu::TransferFormat		transferFmt		= glu::getTransferFormat(texFmt);
			bool					isFilterable	= glu::isGLInternalColorFormatFilterable(m_format);
			const IVec2&			size			= m_texSize;


			glGenTextures(1, &tex);

			glBindTexture(GL_TEXTURE_CUBE_MAP,		tex);
			glTexParameteri(GL_TEXTURE_CUBE_MAP,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_CUBE_MAP,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_CUBE_MAP,	GL_TEXTURE_MIN_FILTER,	isFilterable ? GL_LINEAR : GL_NEAREST);
			glTexParameteri(GL_TEXTURE_CUBE_MAP,	GL_TEXTURE_MAG_FILTER,	isFilterable ? GL_LINEAR : GL_NEAREST);

			// Generate an image and FBO for each cube face
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cubeGLFaces); ndx++)
				glTexImage2D(cubeGLFaces[ndx], 0, m_format, size.x(), size.y(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
			checkError();

			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cubeGLFaces); ndx++)
			{
				deUint32			layerFbo;

				glGenFramebuffers(1, &layerFbo);
				glBindFramebuffer(GL_FRAMEBUFFER, layerFbo);
				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cubeGLFaces[ndx], tex, 0);
				checkError();
				checkFramebufferStatus(GL_FRAMEBUFFER);

				fbos.push_back(layerFbo);
			}
		}

		// Render test images to random cube faces
		std::vector<int> order;

		for (size_t n = 0; n < fbos.size(); n++)
			order.push_back((int)n);
		rnd.shuffle(order.begin(), order.end());

		DE_ASSERT(order.size() >= 4);
		for (int ndx = 0; ndx < 4; ndx++)
		{
			const int			face		= order[ndx];
			const deUint32		format		= GL_RGBA;
			const deUint32		dataType	= GL_UNSIGNED_BYTE;
			const int			texW		= 128;
			const int			texH		= 128;
			deUint32			tmpTex		= 0;
			const deUint32		fbo			= fbos[face];
			const IVec2&		viewport	= m_texSize;
			tcu::TextureLevel	data		(glu::mapGLTransferFormat(format, dataType), texW, texH, 1);

			tcu::fillWithGrid(data.getAccess(), 8, generateRandomColor(rnd), Vec4(0.0f));

			glGenTextures(1, &tmpTex);
			glBindTexture(GL_TEXTURE_2D, tmpTex);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());

			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
			glViewport(0, 0, viewport.x(), viewport.y());
			sglr::drawQuad(*getCurrentContext(), texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
			checkError();

			// Render to framebuffer
			{
				const Vec3		p0	= Vec3(float(ndx % 2) - 1.0f, float(ndx / 2) - 1.0f, 0.0f);
				const Vec3		p1	= p0 + Vec3(1.0f, 1.0f, 0.0f);

				glBindFramebuffer(GL_FRAMEBUFFER, 0);
				glViewport(0, 0, getWidth(), getHeight());

				glActiveTexture(GL_TEXTURE0);
				glBindTexture(GL_TEXTURE_CUBE_MAP, tex);

				cubeTexShader.setFace(cubeTexFaces[face]);
				cubeTexShader.setUniforms(*getCurrentContext(), cubeTexShaderID);

				sglr::drawQuad(*getCurrentContext(), cubeTexShaderID, p0, p1);
				checkError();
			}
		}

		readPixels(dst, 0, 0, getWidth(), getHeight());
	}

private:
	IVec2			m_texSize;
};

class FboColorTex2DArrayCase : public FboColorbufferCase
{
public:
	FboColorTex2DArrayCase (Context& context, const char* name, const char* description, deUint32 texFmt, const IVec3& texSize)
		: FboColorbufferCase	(context, name, description, texFmt)
		, m_texSize				(texSize)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_format);
	}

	void render (tcu::Surface& dst)
	{
		de::Random				rnd					(deStringHash(getName()) ^ 0xed607a89);
		tcu::TextureFormat		texFmt				= glu::mapGLInternalFormat(m_format);
		tcu::TextureFormatInfo	fmtInfo				= tcu::getTextureFormatInfo(texFmt);

		Texture2DShader			texToFboShader		(DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt), fmtInfo.valueMax-fmtInfo.valueMin, fmtInfo.valueMin);
		Texture2DArrayShader	arrayTexShader		(glu::getSampler2DArrayType(texFmt), glu::TYPE_FLOAT_VEC4);

		deUint32				texToFboShaderID	= getCurrentContext()->createProgram(&texToFboShader);
		deUint32				arrayTexShaderID	= getCurrentContext()->createProgram(&arrayTexShader);

		// Setup textures
		texToFboShader.setUniforms(*getCurrentContext(), texToFboShaderID);
		arrayTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias);

		// Framebuffers.
		std::vector<deUint32>	fbos;
		deUint32				tex;

		{
			glu::TransferFormat		transferFmt		= glu::getTransferFormat(texFmt);
			bool					isFilterable	= glu::isGLInternalColorFormatFilterable(m_format);
			const IVec3&			size			= m_texSize;


			glGenTextures(1, &tex);

			glBindTexture(GL_TEXTURE_2D_ARRAY,		tex);
			glTexParameteri(GL_TEXTURE_2D_ARRAY,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D_ARRAY,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D_ARRAY,	GL_TEXTURE_WRAP_R,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D_ARRAY,	GL_TEXTURE_MIN_FILTER,	isFilterable ? GL_LINEAR : GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D_ARRAY,	GL_TEXTURE_MAG_FILTER,	isFilterable ? GL_LINEAR : GL_NEAREST);
			glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, size.x(), size.y(), size.z(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);

			// Generate an FBO for each layer
			for (int ndx = 0; ndx < m_texSize.z(); ndx++)
			{
				deUint32			layerFbo;

				glGenFramebuffers(1, &layerFbo);
				glBindFramebuffer(GL_FRAMEBUFFER, layerFbo);
				glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, ndx);
				checkError();
				checkFramebufferStatus(GL_FRAMEBUFFER);

				fbos.push_back(layerFbo);
			}
		}

		// Render test images to random texture layers
		std::vector<int>		order;

		for (size_t n = 0; n < fbos.size(); n++)
			order.push_back((int)n);
		rnd.shuffle(order.begin(), order.end());

		for (size_t ndx = 0; ndx < order.size(); ndx++)
		{
			const int			layer		= order[ndx];
			const deUint32		format		= GL_RGBA;
			const deUint32		dataType	= GL_UNSIGNED_BYTE;
			const int			texW		= 128;
			const int			texH		= 128;
			deUint32			tmpTex		= 0;
			const deUint32		fbo			= fbos[layer];
			const IVec3&		viewport	= m_texSize;
			tcu::TextureLevel	data		(glu::mapGLTransferFormat(format, dataType), texW, texH, 1);

			tcu::fillWithGrid(data.getAccess(), 8, generateRandomColor(rnd), Vec4(0.0f));

			glGenTextures(1, &tmpTex);
			glBindTexture(GL_TEXTURE_2D, tmpTex);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());

			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
			glViewport(0, 0, viewport.x(), viewport.y());
			sglr::drawQuad(*getCurrentContext(), texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
			checkError();

			// Render to framebuffer
			{
				const Vec3		p0	= Vec3(float(ndx % 2) - 1.0f, float(ndx / 2) - 1.0f, 0.0f);
				const Vec3		p1	= p0 + Vec3(1.0f, 1.0f, 0.0f);

				glBindFramebuffer(GL_FRAMEBUFFER, 0);
				glViewport(0, 0, getWidth(), getHeight());

				glActiveTexture(GL_TEXTURE0);
				glBindTexture(GL_TEXTURE_2D_ARRAY, tex);

				arrayTexShader.setLayer(layer);
				arrayTexShader.setUniforms(*getCurrentContext(), arrayTexShaderID);

				sglr::drawQuad(*getCurrentContext(), arrayTexShaderID, p0, p1);
				checkError();
			}
		}

		readPixels(dst, 0, 0, getWidth(), getHeight());
	}

private:
	IVec3			m_texSize;
};

class FboColorTex3DCase : public FboColorbufferCase
{
public:
	FboColorTex3DCase (Context& context, const char* name, const char* description, deUint32 texFmt, const IVec3& texSize)
		: FboColorbufferCase	(context, name, description, texFmt)
		, m_texSize				(texSize)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_format);
	}

	void render (tcu::Surface& dst)
	{
		de::Random				rnd				(deStringHash(getName()) ^ 0x74d947b2);
		tcu::TextureFormat		texFmt			= glu::mapGLInternalFormat(m_format);
		tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(texFmt);

		Texture2DShader			texToFboShader	(DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt), fmtInfo.valueMax-fmtInfo.valueMin, fmtInfo.valueMin);
		Texture3DShader			tdTexShader		(glu::getSampler3DType(texFmt), glu::TYPE_FLOAT_VEC4);

		deUint32				texToFboShaderID= getCurrentContext()->createProgram(&texToFboShader);
		deUint32				tdTexShaderID	= getCurrentContext()->createProgram(&tdTexShader);

		// Setup shaders
		texToFboShader.setUniforms(*getCurrentContext(), texToFboShaderID);
		tdTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias);

		// Framebuffers.
		std::vector<deUint32>	fbos;
		deUint32				tex;

		{
			glu::TransferFormat		transferFmt		= glu::getTransferFormat(texFmt);
			const IVec3&			size			= m_texSize;

			glGenTextures(1, &tex);

			glBindTexture(GL_TEXTURE_3D,		tex);
			glTexParameteri(GL_TEXTURE_3D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_3D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_3D,	GL_TEXTURE_WRAP_R,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_3D,	GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
			glTexParameteri(GL_TEXTURE_3D,	GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
			glTexImage3D(GL_TEXTURE_3D, 0, m_format, size.x(), size.y(), size.z(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);

			// Generate an FBO for each layer
			for (int ndx = 0; ndx < m_texSize.z(); ndx++)
			{
				deUint32			layerFbo;

				glGenFramebuffers(1, &layerFbo);
				glBindFramebuffer(GL_FRAMEBUFFER, layerFbo);
				glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, ndx);
				checkError();
				checkFramebufferStatus(GL_FRAMEBUFFER);

				fbos.push_back(layerFbo);
			}
		}

		// Render test images to random texture layers
		std::vector<int> order;

		for (size_t n = 0; n < fbos.size(); n++)
			order.push_back((int)n);
		rnd.shuffle(order.begin(), order.end());

		for (size_t ndx = 0; ndx < order.size(); ndx++)
		{
			const int			layer		= order[ndx];
			const deUint32		format		= GL_RGBA;
			const deUint32		dataType	= GL_UNSIGNED_BYTE;
			const int			texW		= 128;
			const int			texH		= 128;
			deUint32			tmpTex		= 0;
			const deUint32		fbo			= fbos[layer];
			const IVec3&		viewport	= m_texSize;
			tcu::TextureLevel	data		(glu::mapGLTransferFormat(format, dataType), texW, texH, 1);

			tcu::fillWithGrid(data.getAccess(), 8, generateRandomColor(rnd), Vec4(0.0f));

			glGenTextures(1, &tmpTex);
			glBindTexture(GL_TEXTURE_2D, tmpTex);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());

			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
			glViewport(0, 0, viewport.x(), viewport.y());
			sglr::drawQuad(*getCurrentContext() , texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
			checkError();

			// Render to framebuffer
			{
				const Vec3		p0	= Vec3(float(ndx % 2) - 1.0f, float(ndx / 2) - 1.0f, 0.0f);
				const Vec3		p1	= p0 + Vec3(1.0f, 1.0f, 0.0f);

				glBindFramebuffer(GL_FRAMEBUFFER, 0);
				glViewport(0, 0, getWidth(), getHeight());

				glActiveTexture(GL_TEXTURE0);
				glBindTexture(GL_TEXTURE_3D, tex);

				tdTexShader.setDepth(float(layer) / float(m_texSize.z()-1));
				tdTexShader.setUniforms(*getCurrentContext(), tdTexShaderID);

				sglr::drawQuad(*getCurrentContext(), tdTexShaderID, p0, p1);
				checkError();
			}
		}

		readPixels(dst, 0, 0, getWidth(), getHeight());
	}

private:
	IVec3			m_texSize;
};

class FboBlendCase : public FboColorbufferCase
{
public:
	FboBlendCase (Context& context, const char* name, const char* desc, deUint32 format, IVec2 size, deUint32 funcRGB, deUint32 funcAlpha, deUint32 srcRGB, deUint32 dstRGB, deUint32 srcAlpha, deUint32 dstAlpha)
		: FboColorbufferCase	(context, name, desc, format)
		, m_size				(size)
		, m_funcRGB				(funcRGB)
		, m_funcAlpha			(funcAlpha)
		, m_srcRGB				(srcRGB)
		, m_dstRGB				(dstRGB)
		, m_srcAlpha			(srcAlpha)
		, m_dstAlpha			(dstAlpha)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_format);
	}

	void render (tcu::Surface& dst)
	{
		// \note Assumes floating-point or fixed-point format.
		tcu::TextureFormat			fboFmt			= glu::mapGLInternalFormat(m_format);
		Texture2DShader				texShader		(DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
		GradientShader				gradShader		(glu::TYPE_FLOAT_VEC4);
		deUint32					texShaderID		= getCurrentContext()->createProgram(&texShader);
		deUint32					gradShaderID	= getCurrentContext()->createProgram(&gradShader);
		deUint32					fbo				= 0;
		deUint32					rbo				= 0;

		// Setup shaders
		texShader.setUniforms (*getCurrentContext(), texShaderID);
		gradShader.setGradient(*getCurrentContext(), gradShaderID, tcu::Vec4(0.0f), tcu::Vec4(1.0f));

		glGenFramebuffers(1, &fbo);
		glGenRenderbuffers(1, &rbo);

		glBindRenderbuffer(GL_RENDERBUFFER, rbo);
		glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_size.x(), m_size.y());
		checkError();

		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
		checkError();
		checkFramebufferStatus(GL_FRAMEBUFFER);

		glViewport(0, 0, m_size.x(), m_size.y());

		// Fill framebuffer with grid pattern.
		{
			const deUint32		format		= GL_RGBA;
			const deUint32		dataType	= GL_UNSIGNED_BYTE;
			const int			texW		= 128;
			const int			texH		= 128;
			deUint32			gridTex		= 0;
			tcu::TextureLevel	data		(glu::mapGLTransferFormat(format, dataType), texW, texH, 1);

			tcu::fillWithGrid(data.getAccess(), 8, Vec4(0.2f, 0.7f, 0.1f, 1.0f), Vec4(0.7f, 0.1f, 0.5f, 0.8f));

			glGenTextures(1, &gridTex);
			glBindTexture(GL_TEXTURE_2D, gridTex);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());

			sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		}

		// Setup blend.
		glEnable(GL_BLEND);
		glBlendEquationSeparate(m_funcRGB, m_funcAlpha);
		glBlendFuncSeparate(m_srcRGB, m_dstRGB, m_srcAlpha, m_dstAlpha);

		// Render gradient with blend.
		sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

		readPixels(dst, 0, 0, m_size.x(), m_size.y(), fboFmt, Vec4(1.0f), Vec4(0.0f));
	}

private:
	IVec2		m_size;
	deUint32	m_funcRGB;
	deUint32	m_funcAlpha;
	deUint32	m_srcRGB;
	deUint32	m_dstRGB;
	deUint32	m_srcAlpha;
	deUint32	m_dstAlpha;
};

class FboRepeatedClearSampleTex2DCase : public FboColorbufferCase
{
public:
	FboRepeatedClearSampleTex2DCase (Context& context, const char* name, const char* desc, deUint32 format)
		: FboColorbufferCase(context, name, desc, format)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_format);
	}

	void render (tcu::Surface& dst)
	{
		const tcu::TextureFormat		fboFormat		= glu::mapGLInternalFormat(m_format);
		const tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(fboFormat);
		const int						numRowsCols		= 4;
		const int						cellSize		= 16;
		const int						fboSizes[]		= { cellSize, cellSize*numRowsCols };

		Texture2DShader					fboBlitShader	(DataTypes() << glu::getSampler2DType(fboFormat), getFragmentOutputType(fboFormat), Vec4(1.0f), Vec4(0.0f));
		const deUint32					fboBlitShaderID	= getCurrentContext()->createProgram(&fboBlitShader);

		de::Random						rnd				(18169662);
		deUint32						fbos[]			= { 0, 0 };
		deUint32						textures[]		= { 0, 0 };

		glGenFramebuffers(2, &fbos[0]);
		glGenTextures(2, &textures[0]);

		for (int fboNdx = 0; fboNdx < DE_LENGTH_OF_ARRAY(fbos); fboNdx++)
		{
			glBindTexture(GL_TEXTURE_2D, textures[fboNdx]);
			glTexStorage2D(GL_TEXTURE_2D, 1, m_format, fboSizes[fboNdx], fboSizes[fboNdx]);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
			checkError();

			glBindFramebuffer(GL_FRAMEBUFFER, fbos[fboNdx]);
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[fboNdx], 0);
			checkError();
			checkFramebufferStatus(GL_FRAMEBUFFER);
		}

		// larger fbo bound -- clear to transparent black
		clearColorBuffer(fboFormat, Vec4(0.0f));

		fboBlitShader.setUniforms(*getCurrentContext(), fboBlitShaderID);
		glBindTexture(GL_TEXTURE_2D, textures[0]);

		for (int cellY = 0; cellY < numRowsCols; cellY++)
		for (int cellX = 0; cellX < numRowsCols; cellX++)
		{
			const Vec4	color	= randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax);

			glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
			clearColorBuffer(fboFormat, color);

			glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]);
			glViewport(cellX*cellSize, cellY*cellSize, cellSize, cellSize);
			sglr::drawQuad(*getCurrentContext(), fboBlitShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		}

		readPixels(dst, 0, 0, fboSizes[1], fboSizes[1], fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias);
		checkError();
	}
};

class FboRepeatedClearBlitTex2DCase : public FboColorbufferCase
{
public:
	FboRepeatedClearBlitTex2DCase (Context& context, const char* name, const char* desc, deUint32 format)
		: FboColorbufferCase(context, name, desc, format)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_format);
	}

	void render (tcu::Surface& dst)
	{
		const tcu::TextureFormat		fboFormat		= glu::mapGLInternalFormat(m_format);
		const tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(fboFormat);
		const int						numRowsCols		= 4;
		const int						cellSize		= 16;
		const int						fboSizes[]		= { cellSize, cellSize*numRowsCols };

		de::Random						rnd				(18169662);
		deUint32						fbos[]			= { 0, 0 };
		deUint32						textures[]		= { 0, 0 };

		glGenFramebuffers(2, &fbos[0]);
		glGenTextures(2, &textures[0]);

		for (int fboNdx = 0; fboNdx < DE_LENGTH_OF_ARRAY(fbos); fboNdx++)
		{
			glBindTexture(GL_TEXTURE_2D, textures[fboNdx]);
			glTexStorage2D(GL_TEXTURE_2D, 1, m_format, fboSizes[fboNdx], fboSizes[fboNdx]);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
			checkError();

			glBindFramebuffer(GL_FRAMEBUFFER, fbos[fboNdx]);
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[fboNdx], 0);
			checkError();
			checkFramebufferStatus(GL_FRAMEBUFFER);
		}

		// larger fbo bound -- clear to transparent black
		clearColorBuffer(fboFormat, Vec4(0.0f));

		for (int cellY = 0; cellY < numRowsCols; cellY++)
		for (int cellX = 0; cellX < numRowsCols; cellX++)
		{
			const Vec4	color	= randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax);

			glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
			clearColorBuffer(fboFormat, color);

			glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);
			glBlitFramebuffer(0, 0, cellSize, cellSize, cellX*cellSize, cellY*cellSize, (cellX+1)*cellSize, (cellY+1)*cellSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
		}

		glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]);
		readPixels(dst, 0, 0, fboSizes[1], fboSizes[1], fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias);
		checkError();
	}
};

class FboRepeatedClearBlitRboCase : public FboColorbufferCase
{
public:
	FboRepeatedClearBlitRboCase (Context& context, const char* name, const char* desc, deUint32 format)
		: FboColorbufferCase(context, name, desc, format)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_format);
	}

	void render (tcu::Surface& dst)
	{
		const tcu::TextureFormat		fboFormat		= glu::mapGLInternalFormat(m_format);
		const tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(fboFormat);
		const int						numRowsCols		= 4;
		const int						cellSize		= 16;
		const int						fboSizes[]		= { cellSize, cellSize*numRowsCols };

		de::Random						rnd				(18169662);
		deUint32						fbos[]			= { 0, 0 };
		deUint32						rbos[]			= { 0, 0 };

		glGenFramebuffers(2, &fbos[0]);
		glGenRenderbuffers(2, &rbos[0]);

		for (int fboNdx = 0; fboNdx < DE_LENGTH_OF_ARRAY(fbos); fboNdx++)
		{
			glBindRenderbuffer(GL_RENDERBUFFER, rbos[fboNdx]);
			glRenderbufferStorage(GL_RENDERBUFFER, m_format, fboSizes[fboNdx], fboSizes[fboNdx]);
			checkError();

			glBindFramebuffer(GL_FRAMEBUFFER, fbos[fboNdx]);
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbos[fboNdx]);
			checkError();
			checkFramebufferStatus(GL_FRAMEBUFFER);
		}

		// larger fbo bound -- clear to transparent black
		clearColorBuffer(fboFormat, Vec4(0.0f));

		for (int cellY = 0; cellY < numRowsCols; cellY++)
		for (int cellX = 0; cellX < numRowsCols; cellX++)
		{
			const Vec4	color	= randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax);

			glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
			clearColorBuffer(fboFormat, color);

			glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);
			glBlitFramebuffer(0, 0, cellSize, cellSize, cellX*cellSize, cellY*cellSize, (cellX+1)*cellSize, (cellY+1)*cellSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
		}

		glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]);
		readPixels(dst, 0, 0, fboSizes[1], fboSizes[1], fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias);
		checkError();
	}
};

FboColorTests::FboColorTests (Context& context)
	: TestCaseGroup(context, "color", "Colorbuffer tests")
{
}

FboColorTests::~FboColorTests (void)
{
}

void FboColorTests::init (void)
{
	static const deUint32 colorFormats[] =
	{
		// RGBA formats
		GL_RGBA32I,
		GL_RGBA32UI,
		GL_RGBA16I,
		GL_RGBA16UI,
		GL_RGBA8,
		GL_RGBA8I,
		GL_RGBA8UI,
		GL_SRGB8_ALPHA8,
		GL_RGB10_A2,
		GL_RGB10_A2UI,
		GL_RGBA4,
		GL_RGB5_A1,

		// RGB formats
		GL_RGB8,
		GL_RGB565,

		// RG formats
		GL_RG32I,
		GL_RG32UI,
		GL_RG16I,
		GL_RG16UI,
		GL_RG8,
		GL_RG8I,
		GL_RG8UI,

		// R formats
		GL_R32I,
		GL_R32UI,
		GL_R16I,
		GL_R16UI,
		GL_R8,
		GL_R8I,
		GL_R8UI,

		// GL_EXT_color_buffer_float
		GL_RGBA32F,
		GL_RGBA16F,
		GL_R11F_G11F_B10F,
		GL_RG32F,
		GL_RG16F,
		GL_R32F,
		GL_R16F,

		// GL_EXT_color_buffer_half_float
		GL_RGB16F
	};

	// .clear
	{
		tcu::TestCaseGroup* clearGroup = new tcu::TestCaseGroup(m_testCtx, "clear", "Color clears");
		addChild(clearGroup);

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
			clearGroup->addChild(new FboColorClearCase(m_context, getFormatName(colorFormats[ndx]), "", colorFormats[ndx], 129, 117));
	}

	// .tex2d
	{
		tcu::TestCaseGroup* tex2DGroup = new tcu::TestCaseGroup(m_testCtx, "tex2d", "Texture 2D tests");
		addChild(tex2DGroup);

		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
			tex2DGroup->addChild(new FboColorMultiTex2DCase(m_context, getFormatName(colorFormats[fmtNdx]), "",
															colorFormats[fmtNdx], IVec2(129, 117),
															colorFormats[fmtNdx], IVec2(99, 128)));
	}

	// .texcube
	{
		tcu::TestCaseGroup* texCubeGroup = new tcu::TestCaseGroup(m_testCtx, "texcube", "Texture cube map tests");
		addChild(texCubeGroup);

		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
			texCubeGroup->addChild(new FboColorTexCubeCase(m_context, getFormatName(colorFormats[fmtNdx]), "",
														   colorFormats[fmtNdx], IVec2(128, 128)));
	}

	// .tex2darray
	{
		tcu::TestCaseGroup* tex2DArrayGroup = new tcu::TestCaseGroup(m_testCtx, "tex2darray", "Texture 2D array tests");
		addChild(tex2DArrayGroup);

		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
			tex2DArrayGroup->addChild(new FboColorTex2DArrayCase(m_context, getFormatName(colorFormats[fmtNdx]), "",
																 colorFormats[fmtNdx], IVec3(128, 128, 5)));
	}

	// .tex3d
	{
		tcu::TestCaseGroup* tex3DGroup = new tcu::TestCaseGroup(m_testCtx, "tex3d", "Texture 3D tests");
		addChild(tex3DGroup);

		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
			tex3DGroup->addChild(new FboColorTex3DCase(m_context, getFormatName(colorFormats[fmtNdx]), "",
													   colorFormats[fmtNdx], IVec3(128, 128, 5)));
	}

	// .blend
	{
		tcu::TestCaseGroup* blendGroup = new tcu::TestCaseGroup(m_testCtx, "blend", "Blending tests");
		addChild(blendGroup);

		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
		{
			deUint32					format		= colorFormats[fmtNdx];
			tcu::TextureFormat			texFmt		= glu::mapGLInternalFormat(format);
			tcu::TextureChannelClass	fmtClass	= tcu::getTextureChannelClass(texFmt.type);
			string						fmtName		= getFormatName(format);

			if (texFmt.type	== tcu::TextureFormat::FLOAT				||
				fmtClass	== tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER	||
				fmtClass	== tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
				continue; // Blending is not supported.

			blendGroup->addChild(new FboBlendCase(m_context, (fmtName + "_src_over").c_str(), "", format, IVec2(127, 111), GL_FUNC_ADD, GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE));
		}
	}

	// .repeated_clear
	{
		tcu::TestCaseGroup* const repeatedClearGroup = new tcu::TestCaseGroup(m_testCtx, "repeated_clear", "Repeated clears and blits");
		addChild(repeatedClearGroup);

		// .sample.tex2d
		{
			tcu::TestCaseGroup* const sampleGroup = new tcu::TestCaseGroup(m_testCtx, "sample", "Read by sampling");
			repeatedClearGroup->addChild(sampleGroup);

			tcu::TestCaseGroup* const tex2DGroup = new tcu::TestCaseGroup(m_testCtx, "tex2d", "2D Texture");
			sampleGroup->addChild(tex2DGroup);

			for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
				tex2DGroup->addChild(new FboRepeatedClearSampleTex2DCase(m_context, getFormatName(colorFormats[fmtNdx]),
																		 "", colorFormats[fmtNdx]));
		}

		// .blit
		{
			tcu::TestCaseGroup* const blitGroup = new tcu::TestCaseGroup(m_testCtx, "blit", "Blitted");
			repeatedClearGroup->addChild(blitGroup);

			// .tex2d
			{
				tcu::TestCaseGroup* const tex2DGroup = new tcu::TestCaseGroup(m_testCtx, "tex2d", "2D Texture");
				blitGroup->addChild(tex2DGroup);

				for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
					tex2DGroup->addChild(new FboRepeatedClearBlitTex2DCase(m_context, getFormatName(colorFormats[fmtNdx]),
																		   "", colorFormats[fmtNdx]));
			}

			// .rbo
			{
				tcu::TestCaseGroup* const rboGroup = new tcu::TestCaseGroup(m_testCtx, "rbo", "Renderbuffer");
				blitGroup->addChild(rboGroup);

				for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
					rboGroup->addChild(new FboRepeatedClearBlitRboCase(m_context, getFormatName(colorFormats[fmtNdx]),
																	   "", colorFormats[fmtNdx]));
			}
		}
	}
}

} // Functional
} // gles3
} // deqp
