/*-------------------------------------------------------------------------
 * 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 = 0;
		deUint32				fbo1 = 0;
		deUint32				tex0 = 0;
		deUint32				tex1 = 0;

		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
