/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Framebuffer Object Tests.
 *
 * Notes:
 *   + Like in API tests, tcu::sgl2s::Context class is used.
 *   + ReferenceContext is used to generate reference images.
 *   + API calls can be logged \todo [pyry] Implement.
 *//*--------------------------------------------------------------------*/

#include "es2fFboRenderTest.hpp"
#include "sglrContextUtil.hpp"
#include "sglrGLContext.hpp"
#include "sglrReferenceContext.hpp"
#include "tcuSurface.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTextureUtil.hpp"
#include "gluStrUtil.hpp"
#include "deRandom.hpp"
#include "deString.h"

#include "glwFunctions.hpp"
#include "glwEnums.hpp"

using std::vector;
using std::string;
using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::RGBA;
using tcu::Surface;
using namespace glw; // GL types

namespace deqp
{
namespace gles2
{
namespace Functional
{

// Shaders.

class FlatColorShader : public sglr::ShaderProgram
{
public:
	FlatColorShader (void)
		: sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
								<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
								<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
								<< sglr::pdec::Uniform("u_color", glu::TYPE_FLOAT_VEC4)
								<< sglr::pdec::VertexSource(
										"attribute highp vec4 a_position;\n"
										"void main (void)\n"
										"{\n"
										"	gl_Position = a_position;\n"
										"}\n")
								<< sglr::pdec::FragmentSource(
										"uniform mediump vec4 u_color;\n"
										"void main (void)\n"
										"{\n"
										"	gl_FragColor = u_color;\n"
										"}\n"))
	{
	}

	void setColor (sglr::Context& gl, deUint32 program, const tcu::Vec4& color)
	{
		gl.useProgram(program);
		gl.uniform4fv(gl.getUniformLocation(program, "u_color"), 1, color.getPtr());
	}

	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
			packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
	}

	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
	{
		const tcu::Vec4 color(m_uniforms[0].value.f4);

		DE_UNREF(packets);

		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
			rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
	}
};

class SingleTex2DShader : public sglr::ShaderProgram
{
public:
	SingleTex2DShader (void)
		: sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
								<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
								<< sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT)
								<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
								<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
								<< sglr::pdec::Uniform("u_sampler0", glu::TYPE_SAMPLER_2D)
								<< sglr::pdec::VertexSource(
										"attribute highp vec4 a_position;\n"
										"attribute mediump vec2 a_coord;\n"
										"varying mediump vec2 v_coord;\n"
										"void main (void)\n"
										"{\n"
										"	gl_Position = a_position;\n"
										"	v_coord = a_coord;\n"
										"}\n")
								<< sglr::pdec::FragmentSource(
										"uniform sampler2D u_sampler0;\n"
										"varying mediump vec2 v_coord;\n"
										"void main (void)\n"
										"{\n"
										"	gl_FragColor = texture2D(u_sampler0, v_coord);\n"
										"}\n"))
	{
	}

	void setUnit (sglr::Context& gl, deUint32 program, int unitNdx)
	{
		gl.useProgram(program);
		gl.uniform1i(gl.getUniformLocation(program, "u_sampler0"), unitNdx);
	}

	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		{
			rr::VertexPacket& packet = *packets[packetNdx];

			packet.position		= rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx);
			packet.outputs[0]	= rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx);
		}
	}

	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
		{
			const tcu::Vec4 v_coord = rr::readVarying<float>(packets[packetNdx], context, 0, fragNdx);
			const float		lod		= 0.0f;

			rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, this->m_uniforms[0].sampler.tex2D->sample(v_coord.x(), v_coord.y(), lod));
		}
	}

};

class MixTexturesShader : public sglr::ShaderProgram
{
public:
	MixTexturesShader (void)
		: sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
								<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
								<< sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT)
								<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
								<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
								<< sglr::pdec::Uniform("u_sampler0", glu::TYPE_SAMPLER_2D)
								<< sglr::pdec::Uniform("u_sampler1", glu::TYPE_SAMPLER_2D)
								<< sglr::pdec::VertexSource(
										"attribute highp vec4 a_position;\n"
										"attribute mediump vec2 a_coord;\n"
										"varying mediump vec2 v_coord;\n"
										"void main (void)\n"
										"{\n"
										"	gl_Position = a_position;\n"
										"	v_coord = a_coord;\n"
										"}\n")
								<< sglr::pdec::FragmentSource(
										"uniform sampler2D u_sampler0;\n"
										"uniform sampler2D u_sampler1;\n"
										"varying mediump vec2 v_coord;\n"
										"void main (void)\n"
										"{\n"
										"	gl_FragColor = texture2D(u_sampler0, v_coord)*0.5 + texture2D(u_sampler1, v_coord)*0.5;\n"
										"}\n"))
	{
	}

	void setUnits (sglr::Context& gl, deUint32 program, int unit0, int unit1)
	{
		gl.useProgram(program);
		gl.uniform1i(gl.getUniformLocation(program, "u_sampler0"), unit0);
		gl.uniform1i(gl.getUniformLocation(program, "u_sampler1"), unit1);
	}

	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		{
			rr::VertexPacket& packet = *packets[packetNdx];

			packet.position		= rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx);
			packet.outputs[0]	= rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx);
		}
	}

	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
		{
			const tcu::Vec4 v_coord = rr::readVarying<float>(packets[packetNdx], context, 0, fragNdx);
			const float		lod		= 0.0f;

			rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,   this->m_uniforms[0].sampler.tex2D->sample(v_coord.x(), v_coord.y(), lod) * 0.5f
			                                                        + this->m_uniforms[1].sampler.tex2D->sample(v_coord.x(), v_coord.y(), lod) * 0.5f);
		}
	}
};

// Framebuffer config.

class FboConfig
{
public:
	FboConfig (void)
		: colorbufferType		(GL_NONE)
		, colorbufferFormat		(GL_NONE)
		, depthbufferType		(GL_NONE)
		, depthbufferFormat		(GL_NONE)
		, stencilbufferType		(GL_NONE)
		, stencilbufferFormat	(GL_NONE)
	{
	}

	std::string				getName			(void) const;

	GLenum					colorbufferType;		//!< GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, GL_RENDERBUFFER
	GLenum					colorbufferFormat;		//!< Internal format for color buffer texture or renderbuffer

	GLenum					depthbufferType;		//!< GL_RENDERBUFFER
	GLenum					depthbufferFormat;

	GLenum					stencilbufferType;		//!< GL_RENDERBUFFER
	GLenum					stencilbufferFormat;

private:
	static const char*		getFormatName	(GLenum format);
};

const char* FboConfig::getFormatName (GLenum format)
{
	switch (format)
	{
		case GL_RGB:				return "rgb";
		case GL_RGBA:				return "rgba";
		case GL_ALPHA:				return "alpha";
		case GL_LUMINANCE:			return "luminance";
		case GL_LUMINANCE_ALPHA:	return "luminance_alpha";
		case GL_RGB565:				return "rgb565";
		case GL_RGB5_A1:			return "rgb5_a1";
		case GL_RGBA4:				return "rgba4";
		case GL_RGBA16F:			return "rgba16f";
		case GL_RGB16F:				return "rgb16f";
		case GL_DEPTH_COMPONENT16:	return "depth_component16";
		case GL_STENCIL_INDEX8:		return "stencil_index8";
		default:					DE_ASSERT(false); return DE_NULL;
	}
}

std::string FboConfig::getName (void) const
{
	std::string name = "";

	if (colorbufferType != GL_NONE)
	{
		switch (colorbufferType)
		{
			case GL_TEXTURE_2D:			name += "tex2d_";	break;
			case GL_TEXTURE_CUBE_MAP:	name += "texcube_";	break;
			case GL_RENDERBUFFER:		name += "rbo_";		break;
			default:					DE_ASSERT(false);	break;
		}
		name += getFormatName(colorbufferFormat);
	}

	if (depthbufferType != GL_NONE)
	{
		DE_ASSERT(depthbufferType == GL_RENDERBUFFER);
		if (name.length() > 0)
			name += "_";
		name += getFormatName(depthbufferFormat);
	}

	if (stencilbufferType != GL_NONE)
	{
		DE_ASSERT(stencilbufferType == GL_RENDERBUFFER);
		if (name.length() > 0)
			name += "_";
		name += getFormatName(stencilbufferFormat);
	}

	return name;
}

class FboIncompleteException : public tcu::TestError
{
public:
						FboIncompleteException		(const FboConfig& config, GLenum reason, const char* file, int line);
	virtual				~FboIncompleteException		(void) throw() {}

	const FboConfig&	getConfig					(void) const { return m_config; }
	GLenum				getReason					(void) const { return m_reason; }

private:
	FboConfig			m_config;
	GLenum				m_reason;
};

static const char* getFboIncompleteReasonName (GLenum reason)
{
	switch (reason)
	{
		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:			return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:	return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
		case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:			return "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
		case GL_FRAMEBUFFER_UNSUPPORTED:					return "GL_FRAMEBUFFER_UNSUPPORTED";
		case GL_FRAMEBUFFER_COMPLETE:						return "GL_FRAMEBUFFER_COMPLETE";
		default:											return "UNKNOWN";
	}
}

FboIncompleteException::FboIncompleteException (const FboConfig& config, GLenum reason, const char* file, int line)
	: TestError("Framebuffer is not complete", getFboIncompleteReasonName(reason), file, line)
	, m_config(config)
	, m_reason(reason)
{
}

class Framebuffer
{
public:
						Framebuffer			(sglr::Context& context, const FboConfig& config, int width, int height, deUint32 fbo = 0, deUint32 colorbuffer = 0, deUint32 depthbuffer = 0, deUint32 stencilbuffer = 0);
						~Framebuffer		(void);

	const FboConfig&	getConfig			(void) const { return m_config; }
	deUint32			getFramebuffer		(void) const { return m_framebuffer; }
	deUint32			getColorbuffer		(void) const { return m_colorbuffer; }
	deUint32			getDepthbuffer		(void) const { return m_depthbuffer; }
	deUint32			getStencilbuffer	(void) const { return m_stencilbuffer; }

	void				checkCompleteness	(void);

private:
	void				createRbo			(deUint32& name, GLenum format, int width, int height);
	void				destroyBuffer		(deUint32 name, GLenum type);

	FboConfig			m_config;
	sglr::Context&		m_context;
	deUint32			m_framebuffer;
	deUint32			m_colorbuffer;
	deUint32			m_depthbuffer;
	deUint32			m_stencilbuffer;
};

static bool isExtensionSupported (sglr::Context& context, const char* name)
{
	std::istringstream extensions(context.getString(GL_EXTENSIONS));
	std::string extension;

	while (std::getline(extensions, extension, ' '))
	{
		if (extension == name)
			return true;
	}

	return false;
}

static void checkColorFormatSupport (sglr::Context& context, deUint32 sizedFormat)
{
	switch (sizedFormat)
	{
		case GL_RGBA16F:
		case GL_RGB16F:
		case GL_RG16F:
		case GL_R16F:
			if (!isExtensionSupported(context, "GL_EXT_color_buffer_half_float"))
				throw tcu::NotSupportedError("GL_EXT_color_buffer_half_float is not supported");

		default:
			break;
	}
}

Framebuffer::Framebuffer (sglr::Context& context, const FboConfig& config, int width, int height, deUint32 fbo, deUint32 colorbuffer, deUint32 depthbuffer, deUint32 stencilbuffer)
	: m_config			(config)
	, m_context			(context)
	, m_framebuffer		(fbo)
	, m_colorbuffer		(colorbuffer)
	, m_depthbuffer		(depthbuffer)
	, m_stencilbuffer	(stencilbuffer)
{
	// Verify that color format is supported
	checkColorFormatSupport(context, config.colorbufferFormat);

	if (m_framebuffer == 0)
		context.genFramebuffers(1, &m_framebuffer);
	context.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);

	switch (m_config.colorbufferType)
	{
		case GL_TEXTURE_2D:
			if (m_colorbuffer == 0)
				context.genTextures(1, &m_colorbuffer);
			context.bindTexture(GL_TEXTURE_2D, m_colorbuffer);
			context.texImage2D(GL_TEXTURE_2D, 0, m_config.colorbufferFormat, width, height);
			context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

			if (!deIsPowerOfTwo32(width) || !deIsPowerOfTwo32(height))
			{
				// Set wrap mode to clamp for NPOT FBOs
				context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
				context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
			}

			context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorbuffer, 0);
			break;

		case GL_TEXTURE_CUBE_MAP:
			DE_ASSERT(!"TODO");
			break;

		case GL_RENDERBUFFER:
			createRbo(m_colorbuffer, m_config.colorbufferFormat, width, height);
			context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorbuffer);
			break;

		default:
			DE_ASSERT(m_config.colorbufferType == GL_NONE);
			break;
	}

	if (m_config.depthbufferType == GL_RENDERBUFFER)
	{
		createRbo(m_depthbuffer, m_config.depthbufferFormat, width, height);
		context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthbuffer);
	}
	else
		DE_ASSERT(m_config.depthbufferType == GL_NONE);

	if (m_config.stencilbufferType == GL_RENDERBUFFER)
	{
		createRbo(m_stencilbuffer, m_config.stencilbufferFormat, width, height);
		context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencilbuffer);
	}
	else
		DE_ASSERT(m_config.stencilbufferType == GL_NONE);

	context.bindFramebuffer(GL_FRAMEBUFFER, 0);
}

Framebuffer::~Framebuffer (void)
{
	m_context.deleteFramebuffers(1, &m_framebuffer);
	destroyBuffer(m_colorbuffer, m_config.colorbufferType);
	destroyBuffer(m_depthbuffer, m_config.depthbufferType);
	destroyBuffer(m_stencilbuffer, m_config.stencilbufferType);
}

void Framebuffer::checkCompleteness (void)
{
	m_context.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
	GLenum status = m_context.checkFramebufferStatus(GL_FRAMEBUFFER);
	m_context.bindFramebuffer(GL_FRAMEBUFFER, 0);
	if (status != GL_FRAMEBUFFER_COMPLETE)
		throw FboIncompleteException(m_config, status, __FILE__, __LINE__);
}

void Framebuffer::createRbo (deUint32& name, GLenum format, int width, int height)
{
	if (name == 0)
		m_context.genRenderbuffers(1, &name);
	m_context.bindRenderbuffer(GL_RENDERBUFFER, name);
	m_context.renderbufferStorage(GL_RENDERBUFFER, format, width, height);
}

void Framebuffer::destroyBuffer (deUint32 name, GLenum type)
{
	if (type == GL_TEXTURE_2D || type == GL_TEXTURE_CUBE_MAP)
		m_context.deleteTextures(1, &name);
	else if (type == GL_RENDERBUFFER)
		m_context.deleteRenderbuffers(1, &name);
	else
		DE_ASSERT(type == GL_NONE);
}

static void createMetaballsTex2D (sglr::Context& context, deUint32 name, GLenum format, GLenum dataType, int width, int height)
{
	tcu::TextureFormat	texFormat	= glu::mapGLTransferFormat(format, dataType);
	tcu::TextureLevel	level		(texFormat, width, height);

	tcu::fillWithMetaballs(level.getAccess(), 5, name ^ width ^ height);

	context.bindTexture(GL_TEXTURE_2D, name);
	context.texImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, dataType, level.getAccess().getDataPtr());
	context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}

static void createQuadsTex2D (sglr::Context& context, deUint32 name, GLenum format, GLenum dataType, int width, int height)
{
	tcu::TextureFormat	texFormat	= glu::mapGLTransferFormat(format, dataType);
	tcu::TextureLevel	level		(texFormat, width, height);

	tcu::fillWithRGBAQuads(level.getAccess());

	context.bindTexture(GL_TEXTURE_2D, name);
	context.texImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, dataType, level.getAccess().getDataPtr());
	context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}

class FboRenderCase : public TestCase
{
public:
								FboRenderCase			(Context& context, const char* name, const char* description, const FboConfig& config);
	virtual						~FboRenderCase			(void) {}

	virtual IterateResult		iterate					(void);
	virtual void				render					(sglr::Context& fboContext, Surface& dst) = DE_NULL;

	const FboConfig&			getConfig				(void) const { return m_config; }

	static bool					isConfigSupported		(const FboConfig& config) { DE_UNREF(config); return true; }

private:
	FboConfig					m_config;
};

FboRenderCase::FboRenderCase (Context& context, const char* name, const char* description, const FboConfig& config)
	: TestCase(context, name, description)
	, m_config(config)
{
}

TestCase::IterateResult FboRenderCase::iterate (void)
{
	Vec4						clearColor				(0.125f, 0.25f, 0.5f, 1.0f);
	glu::RenderContext&			renderCtx				= m_context.getRenderContext();
	const tcu::RenderTarget&	renderTarget			= m_context.getRenderTarget();
	tcu::TestLog&				log						= m_testCtx.getLog();
	const char*					failReason				= DE_NULL;

	// Position & size for context
	deRandom rnd;
	deRandom_init(&rnd, deStringHash(getName()));

	int		width	= deMin32(renderTarget.getWidth(), 128);
	int		height	= deMin32(renderTarget.getHeight(), 128);
	int		xMax	= renderTarget.getWidth()-width+1;
	int		yMax	= renderTarget.getHeight()-height+1;
	int		x		= deRandom_getUint32(&rnd) % xMax;
	int		y		= deRandom_getUint32(&rnd) % yMax;

	tcu::Surface	gles2Frame	(width, height);
	tcu::Surface	refFrame	(width, height);
	GLenum			gles2Error;
	GLenum			refError;

	// Render using GLES2
	try
	{
		sglr::GLContext context(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height));

		context.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
		context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		render(context, gles2Frame); // Call actual render func
		gles2Error = context.getError();
	}
	catch (const FboIncompleteException& e)
	{
		if (e.getReason() == GL_FRAMEBUFFER_UNSUPPORTED)
		{
			// Mark test case as unsupported
			log << e;
			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
			return STOP;
		}
		else
			throw; // Propagate error
	}

	// Render reference image
	{
		sglr::ReferenceContextBuffers	buffers	(tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), renderTarget.getDepthBits(), renderTarget.getStencilBits(), width, height);
		sglr::ReferenceContext			context	(sglr::ReferenceContextLimits(renderCtx), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());

		context.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
		context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		render(context, refFrame);
		refError = context.getError();
	}

	// Compare error codes
	bool errorCodesOk = (gles2Error == refError);

	if (!errorCodesOk)
	{
		log << tcu::TestLog::Message << "Error code mismatch: got " << glu::getErrorStr(gles2Error) << ", expected " << glu::getErrorStr(refError) << tcu::TestLog::EndMessage;
		failReason = "Got unexpected error";
	}

	// Compare images
	const float		threshold	= 0.02f;
	bool			imagesOk	= tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refFrame, gles2Frame, threshold, tcu::COMPARE_LOG_RESULT);

	if (!imagesOk && !failReason)
		failReason = "Image comparison failed";

	// Store test result
	bool isOk = errorCodesOk && imagesOk;
	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
							isOk ? "Pass"				: failReason);

	return STOP;
}

namespace FboCases
{

class ColorClearsTest : public FboRenderCase
{
public:
						ColorClearsTest				(Context& context, const FboConfig& config);
						~ColorClearsTest			(void) {}

	void				render						(sglr::Context& context, Surface& dst);
};

ColorClearsTest::ColorClearsTest (Context& context, const FboConfig& config)
	: FboRenderCase(context, config.getName().c_str(), "Color buffer clears", config)
{
}

void ColorClearsTest::render (sglr::Context& context, Surface& dst)
{
	int			width	= 128;
	int			height	= 128;
	deRandom	rnd;

	deRandom_init(&rnd, 0);

	// Create framebuffer
	Framebuffer fbo(context, getConfig(), width, height);
	fbo.checkCompleteness();

	// Clear fbo
	context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
	context.viewport(0, 0, width, height);
	context.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

	// Enable scissor test.
	context.enable(GL_SCISSOR_TEST);

	// Do 10 random color clears
	for (int i = 0; i < 15; i++)
	{
		int		cX		= (int)(deRandom_getUint32(&rnd) & 0x7fffffff) % width;
		int		cY		= (int)(deRandom_getUint32(&rnd) & 0x7fffffff) % height;
		int		cWidth	= (int)(deRandom_getUint32(&rnd) & 0x7fffffff) % (width-cX);
		int		cHeight	= (int)(deRandom_getUint32(&rnd) & 0x7fffffff) % (height-cY);
		Vec4	color	= RGBA(deRandom_getUint32(&rnd)).toVec();

		context.scissor(cX, cY, cWidth, cHeight);
		context.clearColor(color.x(), color.y(), color.z(), color.w());
		context.clear(GL_COLOR_BUFFER_BIT);
	}

	// Disable scissor.
	context.disable(GL_SCISSOR_TEST);

	if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		// Unbind fbo
		context.bindFramebuffer(GL_FRAMEBUFFER, 0);

		// Draw to screen
		SingleTex2DShader	shader;
		deUint32			shaderID = context.createProgram(&shader);

		shader.setUnit(context, shaderID, 0);

		context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer());
		context.viewport(0, 0, context.getWidth(), context.getHeight());
		sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

		// Read from screen
		context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
	}
	else
	{
		// Read from fbo
		context.readPixels(dst, 0, 0, width, height);
	}
}

class IntersectingQuadsTest : public FboRenderCase
{
public:
					IntersectingQuadsTest			(Context& context, const FboConfig& config, bool npot = false);
	virtual			~IntersectingQuadsTest			(void) {}

	virtual void	render							(sglr::Context& context, Surface& dst);

	static bool		isConfigSupported				(const FboConfig& config);

private:
	int				m_fboWidth;
	int				m_fboHeight;
};

class IntersectingQuadsNpotTest : public IntersectingQuadsTest
{
public:
	IntersectingQuadsNpotTest (Context& context, const FboConfig& config)
		: IntersectingQuadsTest(context, config, true)
	{
	}
};

IntersectingQuadsTest::IntersectingQuadsTest (Context& context, const FboConfig& config, bool npot)
	: FboRenderCase	(context, (string(npot ? "npot_" : "") + config.getName()).c_str(), "Intersecting textured quads", config)
	, m_fboWidth	(npot ? 127 : 128)
	, m_fboHeight	(npot ?  95 : 128)
{
}

bool IntersectingQuadsTest::isConfigSupported (const FboConfig& config)
{
	// \note Disabled for stencil configurations since doesn't exercise stencil buffer
	return config.depthbufferType	!= GL_NONE &&
		   config.stencilbufferType	== GL_NONE;
}

void IntersectingQuadsTest::render (sglr::Context& ctx, Surface& dst)
{
	SingleTex2DShader	texShader;
	deUint32			texShaderID = ctx.createProgram(&texShader);

	deUint32 metaballsTex	= 1;
	deUint32 quadsTex		= 2;

	createMetaballsTex2D(ctx, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
	createQuadsTex2D(ctx, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);

	int width	= m_fboWidth;
	int height	= m_fboHeight;
	Framebuffer fbo(ctx, getConfig(), width, height);
	fbo.checkCompleteness();

	// Setup shaders
	texShader.setUnit(ctx, texShaderID, 0);

	// Draw scene
	ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
	ctx.viewport(0, 0, width, height);
	ctx.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
	ctx.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

	ctx.enable(GL_DEPTH_TEST);

	ctx.bindTexture(GL_TEXTURE_2D, metaballsTex);
	sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

	ctx.bindTexture(GL_TEXTURE_2D, quadsTex);
	sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 1.0f), Vec3(1.0f, 1.0f, -1.0f));

	ctx.disable(GL_DEPTH_TEST);

	if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		// Unbind fbo
		ctx.bindFramebuffer(GL_FRAMEBUFFER, 0);

		// Draw to screen
		ctx.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer());
		ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight());
		sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

		// Read from screen
		ctx.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
	}
	else
	{
		// Read from fbo
		ctx.readPixels(dst, 0, 0, width, height);
	}
}

class MixTest : public FboRenderCase
{
public:
						MixTest				(Context& context, const FboConfig& config, bool npot = false);
	virtual				~MixTest			(void) {}

	void				render				(sglr::Context& context, Surface& dst);

	static bool			isConfigSupported	(const FboConfig& config);

private:
	int					m_fboAWidth;
	int					m_fboAHeight;
	int					m_fboBWidth;
	int					m_fboBHeight;
};

class MixNpotTest : public MixTest
{
public:
	MixNpotTest (Context& context, const FboConfig& config)
		: MixTest(context, config, true)
	{
	}
};

MixTest::MixTest (Context& context, const FboConfig& config, bool npot)
	: FboRenderCase	(context, (string(npot ? "mix_npot_" : "mix_") + config.getName()).c_str(), "Use two fbos as sources in draw operation", config)
	, m_fboAWidth	(npot ? 127 : 128)
	, m_fboAHeight	(npot ?  95 : 128)
	, m_fboBWidth	(npot ?  55 :  64)
	, m_fboBHeight	(npot ?  63 :  64)
{
}

bool MixTest::isConfigSupported (const FboConfig& config)
{
	// \note Disabled for stencil configurations since doesn't exercise stencil buffer
	return config.colorbufferType	== GL_TEXTURE_2D &&
		   config.stencilbufferType	== GL_NONE;
}

void MixTest::render (sglr::Context& context, Surface& dst)
{
	SingleTex2DShader	singleTexShader;
	MixTexturesShader	mixShader;

	deUint32			singleTexShaderID	= context.createProgram(&singleTexShader);
	deUint32			mixShaderID			= context.createProgram(&mixShader);

	// Texture with metaballs
	deUint32 metaballsTex = 1;
	context.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
	createMetaballsTex2D(context, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);

	// Setup shaders
	singleTexShader.setUnit(context, singleTexShaderID, 0);
	mixShader.setUnits(context, mixShaderID, 0, 1);

	// Fbo, quad with metaballs texture
	Framebuffer fboA(context, getConfig(), m_fboAWidth, m_fboAHeight);
	fboA.checkCompleteness();
	context.bindFramebuffer(GL_FRAMEBUFFER, fboA.getFramebuffer());
	context.viewport(0, 0, m_fboAWidth, m_fboAHeight);
	context.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
	context.bindTexture(GL_TEXTURE_2D, metaballsTex);
	sglr::drawQuad(context, singleTexShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

	// Fbo, color clears
	Framebuffer fboB(context, getConfig(), m_fboBWidth, m_fboBHeight);
	fboB.checkCompleteness();
	context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer());
	context.viewport(0, 0, m_fboBWidth, m_fboBHeight);
	context.enable(GL_SCISSOR_TEST);
	context.scissor(0, 0, 32, 64);
	context.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT);
	context.scissor(32, 0, 32, 64);
	context.clearColor(0.0f, 1.0f, 0.0f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT);
	context.disable(GL_SCISSOR_TEST);

	// Final mix op
	context.activeTexture(GL_TEXTURE0);
	context.bindTexture(GL_TEXTURE_2D, fboA.getColorbuffer());
	context.activeTexture(GL_TEXTURE1);
	context.bindTexture(GL_TEXTURE_2D, fboB.getColorbuffer());
	context.bindFramebuffer(GL_FRAMEBUFFER, 0);
	context.viewport(0, 0, context.getWidth(), context.getHeight());
	sglr::drawQuad(context, mixShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

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

class BlendTest : public FboRenderCase
{
public:
						BlendTest			(Context& context, const FboConfig& config, bool npot = false);
	virtual				~BlendTest			(void) {}

	void				render				(sglr::Context& context, Surface& dst);

	static bool			isConfigSupported	(const FboConfig& config);

private:
	int					m_fboWidth;
	int					m_fboHeight;
};

class BlendNpotTest : public BlendTest
{
public:
	BlendNpotTest (Context& context, const FboConfig& config)
		: BlendTest(context, config, true)
	{
	}
};

BlendTest::BlendTest (Context& context, const FboConfig& config, bool npot)
	: FboRenderCase	(context, (string(npot ? "blend_npot_" : "blend_") + config.getName()).c_str(), "Blend to fbo", config)
	, m_fboWidth	(npot ? 111 : 128)
	, m_fboHeight	(npot ? 122 : 128)
{
}

bool BlendTest::isConfigSupported (const FboConfig& config)
{
	// \note Disabled for stencil configurations since doesn't exercise stencil buffer
	return config.stencilbufferType	== GL_NONE;
}

void BlendTest::render (sglr::Context& context, Surface& dst)
{
	SingleTex2DShader	shader;
	deUint32			shaderID		= context.createProgram(&shader);
	int					width			= m_fboWidth;
	int					height			= m_fboHeight;
	deUint32			metaballsTex	= 1;

	createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, 64, 64);

	Framebuffer fbo(context, getConfig(), width, height);
	fbo.checkCompleteness();

	shader.setUnit(context, shaderID, 0);

	context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
	context.viewport(0, 0, width, height);
	context.bindTexture(GL_TEXTURE_2D, metaballsTex);
	context.clearColor(0.6f, 0.0f, 0.6f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

	context.enable(GL_BLEND);
	context.blendEquation(GL_FUNC_ADD);
	context.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
	sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
	context.disable(GL_BLEND);

	if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		context.bindFramebuffer(GL_FRAMEBUFFER, 0);
		context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer());
		context.viewport(0, 0, context.getWidth(), context.getHeight());
		sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
	}
	else
		context.readPixels(dst, 0, 0, width, height);
}

class StencilClearsTest : public FboRenderCase
{
public:
						StencilClearsTest		(Context& context, const FboConfig& config);
	virtual				~StencilClearsTest		(void) {};

	void				render					(sglr::Context& context, Surface& dst);

	static bool			isConfigSupported		(const FboConfig& config);
};

StencilClearsTest::StencilClearsTest (Context& context, const FboConfig& config)
	: FboRenderCase(context, config.getName().c_str(), "Stencil clears", config)
{
}

void StencilClearsTest::render (sglr::Context& context, Surface& dst)
{
	SingleTex2DShader	shader;
	deUint32			shaderID		= context.createProgram(&shader);
	int					width			= 128;
	int					height			= 128;
	deUint32			quadsTex		= 1;
	deUint32			metaballsTex	= 2;

	createQuadsTex2D(context, quadsTex, GL_RGBA, GL_UNSIGNED_BYTE, width, height);
	createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, width, height);

	Framebuffer fbo(context, getConfig(), width, height);
	fbo.checkCompleteness();

	// Bind framebuffer and clear
	context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
	context.viewport(0, 0, width, height);
	context.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

	// Do stencil clears
	context.enable(GL_SCISSOR_TEST);
	context.scissor(10, 16, 32, 120);
	context.clearStencil(1);
	context.clear(GL_STENCIL_BUFFER_BIT);
	context.scissor(16, 32, 100, 64);
	context.clearStencil(2);
	context.clear(GL_STENCIL_BUFFER_BIT);
	context.disable(GL_SCISSOR_TEST);

	// Draw 2 textures with stecil tests
	context.activeTexture(GL_TEXTURE0);
	context.bindTexture(GL_TEXTURE_2D, quadsTex);
	context.activeTexture(GL_TEXTURE1);
	context.bindTexture(GL_TEXTURE_2D, metaballsTex);

	context.enable(GL_STENCIL_TEST);
	context.stencilFunc(GL_EQUAL, 1, 0xffffffffu);
	shader.setUnit(context, shaderID, 0);
	sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

	context.stencilFunc(GL_EQUAL, 2, 0xffffffffu);
	shader.setUnit(context, shaderID, 1);
	sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

	context.disable(GL_STENCIL_TEST);

	if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		context.bindFramebuffer(GL_FRAMEBUFFER, 0);
		context.activeTexture(GL_TEXTURE0);
		context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer());
		context.viewport(0, 0, context.getWidth(), context.getHeight());
		shader.setUnit(context, shaderID, 0);
		sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
	}
	else
		context.readPixels(dst, 0, 0, width, height);
}

bool StencilClearsTest::isConfigSupported (const FboConfig& config)
{
	return config.stencilbufferType != GL_NONE;
}

class StencilTest : public FboRenderCase
{
public:
						StencilTest				(Context& context, const FboConfig& config, bool npot = false);
	virtual				~StencilTest			(void) {};

	void				render					(sglr::Context& context, Surface& dst);

	static bool			isConfigSupported		(const FboConfig& config);

private:
	int					m_fboWidth;
	int					m_fboHeight;
};

class StencilNpotTest : public StencilTest
{
public:
	StencilNpotTest (Context& context, const FboConfig& config)
		: StencilTest(context, config, true)
	{
	}
};

StencilTest::StencilTest (Context& context, const FboConfig& config, bool npot)
	: FboRenderCase	(context, (string(npot ? "npot_" : "") + config.getName()).c_str(), "Stencil ops", config)
	, m_fboWidth	(npot ?  99 : 128)
	, m_fboHeight	(npot ? 110 : 128)
{
}

bool StencilTest::isConfigSupported (const FboConfig& config)
{
	return config.stencilbufferType != GL_NONE;
}

void StencilTest::render (sglr::Context& ctx, Surface& dst)
{
	FlatColorShader		colorShader;
	SingleTex2DShader	texShader;
	deUint32			colorShaderID	= ctx.createProgram(&colorShader);
	deUint32			texShaderID		= ctx.createProgram(&texShader);
	int					width			= m_fboWidth;
	int					height			= m_fboHeight;
	int					texWidth		= 64;
	int					texHeight		= 64;
	deUint32			quadsTex		= 1;
	deUint32			metaballsTex	= 2;
	bool				depth			= getConfig().depthbufferType != GL_NONE;

	createQuadsTex2D(ctx, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight);
	createMetaballsTex2D(ctx, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight);

	Framebuffer fbo(ctx, getConfig(), width, height);
	fbo.checkCompleteness();

	// Bind framebuffer and clear
	ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
	ctx.viewport(0, 0, width, height);
	ctx.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	ctx.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

	// Render intersecting quads - increment stencil on depth pass
	ctx.enable(GL_DEPTH_TEST);
	ctx.enable(GL_STENCIL_TEST);
	ctx.stencilFunc(GL_ALWAYS, 0, 0xffu);
	ctx.stencilOp(GL_KEEP, GL_KEEP, GL_INCR);

	colorShader.setColor(ctx, colorShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
	sglr::drawQuad(ctx, colorShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));

	ctx.bindTexture(GL_TEXTURE_2D, quadsTex);
	texShader.setUnit(ctx, texShaderID, 0);
	sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(+1.0f, +1.0f, +1.0f));

	// Draw quad with stencil test (stencil == 1 or 2 depending on depth) - decrement on stencil failure
	ctx.disable(GL_DEPTH_TEST);
	ctx.stencilFunc(GL_EQUAL, depth ? 2 : 1, 0xffu);
	ctx.stencilOp(GL_DECR, GL_KEEP, GL_KEEP);
	colorShader.setColor(ctx, colorShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
	sglr::drawQuad(ctx, colorShaderID, Vec3(-0.5f, -0.5f, 0.0f), Vec3(+0.5f, +0.5f, 0.0f));

	// Draw metaballs with stencil test where stencil > 1 or 2 depending on depth buffer
	ctx.bindTexture(GL_TEXTURE_2D, metaballsTex);
	ctx.stencilFunc(GL_GREATER, depth ? 1 : 2, 0xffu);
	ctx.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
	sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));

	ctx.disable(GL_STENCIL_TEST);

	if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		ctx.bindFramebuffer(GL_FRAMEBUFFER, 0);
		ctx.activeTexture(GL_TEXTURE0);
		ctx.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer());
		ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight());
		sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		ctx.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
	}
	else
		ctx.readPixels(dst, 0, 0, width, height);
}

class SharedColorbufferTest : public FboRenderCase
{
public:
						SharedColorbufferTest			(Context& context, const FboConfig& config);
	virtual				~SharedColorbufferTest			(void) {};

	void				render							(sglr::Context& context, Surface& dst);
};

SharedColorbufferTest::SharedColorbufferTest (Context& context, const FboConfig& config)
	: FboRenderCase(context, config.getName().c_str(), "Shared colorbuffer", config)
{
}

void SharedColorbufferTest::render (sglr::Context& context, Surface& dst)
{
	SingleTex2DShader	shader;
	deUint32			shaderID		= context.createProgram(&shader);
	int					width			= 128;
	int					height			= 128;
//	bool				depth			= getConfig().depthbufferFormat		!= GL_NONE;
	bool				stencil			= getConfig().stencilbufferFormat	!= GL_NONE;

	// Textures
	deUint32	quadsTex		= 1;
	deUint32	metaballsTex	= 2;
	createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
	createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, 64, 64);

	context.viewport(0, 0, width, height);

	shader.setUnit(context, shaderID, 0);

	// Fbo A
	Framebuffer fboA(context, getConfig(), width, height);
	fboA.checkCompleteness();

	// Fbo B - don't create colorbuffer
	FboConfig cfg = getConfig();
	cfg.colorbufferType		= GL_NONE;
	cfg.colorbufferFormat	= GL_NONE;
	Framebuffer fboB(context, cfg, width, height);

	// Attach color buffer from fbo A
	context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer());
	switch (getConfig().colorbufferType)
	{
		case GL_TEXTURE_2D:
			context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboA.getColorbuffer(), 0);
			break;

		case GL_RENDERBUFFER:
			context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fboA.getColorbuffer());
			break;

		default:
			DE_ASSERT(false);
	}

	// Clear depth and stencil in fbo B
	context.clear(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

	// Render quads to fbo 1, with depth 0.0
	context.bindFramebuffer(GL_FRAMEBUFFER, fboA.getFramebuffer());
	context.bindTexture(GL_TEXTURE_2D, quadsTex);
	context.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

	if (stencil)
	{
		// Stencil to 1 in fbo A
		context.clearStencil(1);
		context.clear(GL_STENCIL_BUFFER_BIT);
	}

	context.enable(GL_DEPTH_TEST);
	sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
	context.disable(GL_DEPTH_TEST);

	// Blend metaballs to fbo 2
	context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer());
	context.bindTexture(GL_TEXTURE_2D, metaballsTex);
	context.enable(GL_BLEND);
	context.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
	sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

	// Render small quad that is only visible if depth buffer is not shared with fbo A - or there is no depth bits
	context.bindTexture(GL_TEXTURE_2D, quadsTex);
	context.enable(GL_DEPTH_TEST);
	sglr::drawQuad(context, shaderID, Vec3(0.5f, 0.5f, 0.5f), Vec3(1.0f, 1.0f, 0.5f));
	context.disable(GL_DEPTH_TEST);

	if (stencil)
	{
		FlatColorShader flatShader;
		deUint32		flatShaderID = context.createProgram(&flatShader);

		flatShader.setColor(context, flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));

		// Clear subset of stencil buffer to 1
		context.enable(GL_SCISSOR_TEST);
		context.scissor(10, 10, 12, 25);
		context.clearStencil(1);
		context.clear(GL_STENCIL_BUFFER_BIT);
		context.disable(GL_SCISSOR_TEST);

		// Render quad with stencil mask == 1
		context.enable(GL_STENCIL_TEST);
		context.stencilFunc(GL_EQUAL, 1, 0xffu);
		sglr::drawQuad(context, flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		context.disable(GL_STENCIL_TEST);
	}

	// Get results
	if (fboA.getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		context.bindFramebuffer(GL_FRAMEBUFFER, 0);
		context.bindTexture(GL_TEXTURE_2D, fboA.getColorbuffer());
		context.viewport(0, 0, context.getWidth(), context.getHeight());
		sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
	}
	else
		context.readPixels(dst, 0, 0, width, height);
}

class SharedColorbufferClearsTest : public FboRenderCase
{
public:
					SharedColorbufferClearsTest		(Context& context, const FboConfig& config);
	virtual			~SharedColorbufferClearsTest	(void) {}

	static bool		isConfigSupported				(const FboConfig& config);
	void			render							(sglr::Context& context, Surface& dst);
};

SharedColorbufferClearsTest::SharedColorbufferClearsTest (Context& context, const FboConfig& config)
	: FboRenderCase(context, config.getName().c_str(), "Shared colorbuffer clears", config)
{
}

bool SharedColorbufferClearsTest::isConfigSupported (const FboConfig& config)
{
	return config.colorbufferType	!= GL_NONE &&
		   config.depthbufferType	== GL_NONE &&
		   config.stencilbufferType	== GL_NONE;
}

void SharedColorbufferClearsTest::render (sglr::Context& context, Surface& dst)
{
	int			width			= 128;
	int			height			= 128;
	deUint32	colorbuffer		= 1;

	checkColorFormatSupport(context, getConfig().colorbufferFormat);

	// Single colorbuffer
	if (getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		context.bindTexture(GL_TEXTURE_2D, colorbuffer);
		context.texImage2D(GL_TEXTURE_2D, 0, getConfig().colorbufferFormat, width, height);
		context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	}
	else
	{
		DE_ASSERT(getConfig().colorbufferType == GL_RENDERBUFFER);
		context.bindRenderbuffer(GL_RENDERBUFFER, colorbuffer);
		context.renderbufferStorage(GL_RENDERBUFFER, getConfig().colorbufferFormat, width, height);
	}

	// Multiple framebuffers sharing the colorbuffer
	for (int fbo = 1; fbo <= 3; fbo++)
	{
		context.bindFramebuffer(GL_FRAMEBUFFER, fbo);

		if (getConfig().colorbufferType == GL_TEXTURE_2D)
			context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
		else
			context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer);
	}

	context.bindFramebuffer(GL_FRAMEBUFFER, 1);

	// Check completeness
	{
		GLenum status = context.checkFramebufferStatus(GL_FRAMEBUFFER);
		if (status != GL_FRAMEBUFFER_COMPLETE)
			throw FboIncompleteException(getConfig(), status, __FILE__, __LINE__);
	}

	// Render to them
	context.viewport(0, 0, width, height);
	context.clearColor(0.0f, 0.0f, 1.0f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT);

	context.enable(GL_SCISSOR_TEST);

	context.bindFramebuffer(GL_FRAMEBUFFER, 2);
	context.clearColor(0.6f, 0.0f, 0.0f, 1.0f);
	context.scissor(10, 10, 64, 64);
	context.clear(GL_COLOR_BUFFER_BIT);
	context.clearColor(0.0f, 0.6f, 0.0f, 1.0f);
	context.scissor(60, 60, 40, 20);
	context.clear(GL_COLOR_BUFFER_BIT);

	context.bindFramebuffer(GL_FRAMEBUFFER, 3);
	context.clearColor(0.0f, 0.0f, 0.6f, 1.0f);
	context.scissor(20, 20, 100, 10);
	context.clear(GL_COLOR_BUFFER_BIT);

	context.bindFramebuffer(GL_FRAMEBUFFER, 1);
	context.clearColor(0.6f, 0.0f, 0.6f, 1.0f);
	context.scissor(20, 20, 5, 100);
	context.clear(GL_COLOR_BUFFER_BIT);

	context.disable(GL_SCISSOR_TEST);

	if (getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		SingleTex2DShader	shader;
		deUint32			shaderID = context.createProgram(&shader);

		shader.setUnit(context, shaderID, 0);

		context.bindFramebuffer(GL_FRAMEBUFFER, 0);
		context.viewport(0, 0, context.getWidth(), context.getHeight());
		sglr::drawQuad(context, shaderID, Vec3(-0.9f, -0.9f, 0.0f), Vec3(0.9f, 0.9f, 0.0f));
		context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
	}
	else
		context.readPixels(dst, 0, 0, width, height);
}

class SharedDepthbufferTest : public FboRenderCase
{
public:
					SharedDepthbufferTest		(Context& context, const FboConfig& config);
	virtual			~SharedDepthbufferTest		(void) {};

	static bool		isConfigSupported			(const FboConfig& config);
	void			render						(sglr::Context& context, Surface& dst);
};

SharedDepthbufferTest::SharedDepthbufferTest (Context& context, const FboConfig& config)
	: FboRenderCase(context, config.getName().c_str(), "Shared depthbuffer", config)
{
}

bool SharedDepthbufferTest::isConfigSupported (const FboConfig& config)
{
	return config.depthbufferType == GL_RENDERBUFFER;
}

void SharedDepthbufferTest::render (sglr::Context& context, Surface& dst)
{
	SingleTex2DShader	texShader;
	FlatColorShader		colorShader;
	deUint32			texShaderID		= context.createProgram(&texShader);
	deUint32			colorShaderID	= context.createProgram(&colorShader);
	int					width			= 128;
	int					height			= 128;
	bool				stencil			= getConfig().stencilbufferType != GL_NONE;

	// Setup shaders
	texShader.setUnit(context, texShaderID, 0);
	colorShader.setColor(context, colorShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));

	// Textures
	deUint32 metaballsTex	= 5;
	deUint32 quadsTex		= 6;
	createMetaballsTex2D(context, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
	createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);

	context.viewport(0, 0, width, height);

	// Fbo A
	Framebuffer fboA(context, getConfig(), width, height);
	fboA.checkCompleteness();

	// Fbo B
	FboConfig cfg = getConfig();
	cfg.depthbufferType		= GL_NONE;
	cfg.depthbufferFormat	= GL_NONE;
	Framebuffer fboB(context, cfg, width, height);

	// Bind depth buffer from fbo A to fbo B
	DE_ASSERT(fboA.getConfig().depthbufferType == GL_RENDERBUFFER);
	context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer());
	context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fboA.getDepthbuffer());

	// Clear fbo B color to red and stencil to 1
	context.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
	context.clearStencil(1);
	context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

	// Enable depth test.
	context.enable(GL_DEPTH_TEST);

	// Render quad to fbo A
	context.bindFramebuffer(GL_FRAMEBUFFER, fboA.getFramebuffer());
	context.bindTexture(GL_TEXTURE_2D, quadsTex);
	context.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
	sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

	// Render metaballs to fbo B
	context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer());
	context.bindTexture(GL_TEXTURE_2D, metaballsTex);
	sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

	context.disable(GL_DEPTH_TEST);

	if (stencil)
	{
		// Clear subset of stencil buffer to 0
		context.enable(GL_SCISSOR_TEST);
		context.scissor(10, 10, 12, 25);
		context.clearStencil(0);
		context.clear(GL_STENCIL_BUFFER_BIT);
		context.disable(GL_SCISSOR_TEST);

		// Render quad with stencil mask == 0
		context.enable(GL_STENCIL_TEST);
		context.stencilFunc(GL_EQUAL, 0, 0xffu);
		sglr::drawQuad(context, colorShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		context.disable(GL_STENCIL_TEST);
	}

	if (getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		// Render both to screen
		context.bindFramebuffer(GL_FRAMEBUFFER, 0);
		context.viewport(0, 0, context.getWidth(), context.getHeight());
		context.bindTexture(GL_TEXTURE_2D, fboA.getColorbuffer());
		sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(0.0f, 1.0f, 0.0f));
		context.bindTexture(GL_TEXTURE_2D, fboB.getColorbuffer());
		sglr::drawQuad(context, texShaderID, Vec3(0.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

		context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
	}
	else
	{
		// Read results from fbo B
		context.readPixels(dst, 0, 0, width, height);
	}
}

class TexSubImageAfterRenderTest : public FboRenderCase
{
public:
					TexSubImageAfterRenderTest		(Context& context, const FboConfig& config);
	virtual			~TexSubImageAfterRenderTest		(void) {}

	static bool		isConfigSupported				(const FboConfig& config);
	void			render							(sglr::Context& context, Surface& dst);
};

TexSubImageAfterRenderTest::TexSubImageAfterRenderTest (Context& context, const FboConfig& config)
	: FboRenderCase(context, (string("after_render_") + config.getName()).c_str(), "TexSubImage after rendering to texture", config)
{
}

bool TexSubImageAfterRenderTest::isConfigSupported (const FboConfig& config)
{
	return config.colorbufferType == GL_TEXTURE_2D &&
		   (config.colorbufferFormat == GL_RGB || config.colorbufferFormat == GL_RGBA) &&
		   config.depthbufferType == GL_NONE &&
		   config.stencilbufferType == GL_NONE;
}

void TexSubImageAfterRenderTest::render (sglr::Context& context, Surface& dst)
{
	SingleTex2DShader	shader;
	deUint32			shaderID	= context.createProgram(&shader);
	bool				isRGBA		= getConfig().colorbufferFormat == GL_RGBA;

	tcu::TextureLevel fourQuads(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), 64, 64);
	tcu::fillWithRGBAQuads(fourQuads.getAccess());

	tcu::TextureLevel metaballs(tcu::TextureFormat(isRGBA ? tcu::TextureFormat::RGBA : tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), 64, 64);
	tcu::fillWithMetaballs(metaballs.getAccess(), 5, 3);

	shader.setUnit(context, shaderID, 0);

	deUint32 fourQuadsTex = 1;
	context.bindTexture(GL_TEXTURE_2D, fourQuadsTex);
	context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	context.texImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, fourQuads.getAccess().getDataPtr());

	context.bindFramebuffer(GL_FRAMEBUFFER, 1);

	deUint32 fboTex = 2;
	context.bindTexture(GL_TEXTURE_2D, fboTex);
	context.texImage2D(GL_TEXTURE_2D, 0, isRGBA ? GL_RGBA : GL_RGB, 128, 128);
	context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);

	// Render to fbo
	context.viewport(0, 0, 128, 128);
	context.bindTexture(GL_TEXTURE_2D, fourQuadsTex);
	sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

	// Update texture using TexSubImage2D
	context.bindTexture(GL_TEXTURE_2D, fboTex);
	context.texSubImage2D(GL_TEXTURE_2D, 0, 32, 32, 64, 64, isRGBA ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, metaballs.getAccess().getDataPtr());

	// Draw to screen
	context.bindFramebuffer(GL_FRAMEBUFFER, 0);
	context.viewport(0, 0, context.getWidth(), context.getHeight());
	sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
	context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
}

class TexSubImageBetweenRenderTest : public FboRenderCase
{
public:
					TexSubImageBetweenRenderTest		(Context& context, const FboConfig& config);
	virtual			~TexSubImageBetweenRenderTest		(void) {}

	static bool		isConfigSupported					(const FboConfig& config);
	void			render								(sglr::Context& context, Surface& dst);
};

TexSubImageBetweenRenderTest::TexSubImageBetweenRenderTest (Context& context, const FboConfig& config)
	: FboRenderCase(context, (string("between_render_") + config.getName()).c_str(), "TexSubImage between rendering calls", config)
{
}

bool TexSubImageBetweenRenderTest::isConfigSupported (const FboConfig& config)
{
	return config.colorbufferType == GL_TEXTURE_2D &&
		   (config.colorbufferFormat == GL_RGB || config.colorbufferFormat == GL_RGBA) &&
		   config.depthbufferType == GL_NONE &&
		   config.stencilbufferType == GL_NONE;
}

void TexSubImageBetweenRenderTest::render (sglr::Context& context, Surface& dst)
{
	SingleTex2DShader	shader;
	deUint32			shaderID	= context.createProgram(&shader);
	bool				isRGBA		= getConfig().colorbufferFormat == GL_RGBA;

	tcu::TextureLevel fourQuads(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), 64, 64);
	tcu::fillWithRGBAQuads(fourQuads.getAccess());

	tcu::TextureLevel metaballs(tcu::TextureFormat(isRGBA ? tcu::TextureFormat::RGBA : tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), 64, 64);
	tcu::fillWithMetaballs(metaballs.getAccess(), 5, 3);

	tcu::TextureLevel metaballs2(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 64, 64);
	tcu::fillWithMetaballs(metaballs2.getAccess(), 5, 4);

	deUint32 metaballsTex = 3;
	context.bindTexture(GL_TEXTURE_2D, metaballsTex);
	context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	context.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, metaballs2.getAccess().getDataPtr());

	deUint32 fourQuadsTex = 1;
	context.bindTexture(GL_TEXTURE_2D, fourQuadsTex);
	context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	context.texImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, fourQuads.getAccess().getDataPtr());

	context.bindFramebuffer(GL_FRAMEBUFFER, 1);

	deUint32 fboTex = 2;
	context.bindTexture(GL_TEXTURE_2D, fboTex);
	context.texImage2D(GL_TEXTURE_2D, 0, isRGBA ? GL_RGBA : GL_RGB, 128, 128);
	context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);

	shader.setUnit(context, shaderID, 0);

	// Render to fbo
	context.viewport(0, 0, 128, 128);
	context.bindTexture(GL_TEXTURE_2D, fourQuadsTex);
	sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

	// Update texture using TexSubImage2D
	context.bindTexture(GL_TEXTURE_2D, fboTex);
	context.texSubImage2D(GL_TEXTURE_2D, 0, 32, 32, 64, 64, isRGBA ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, metaballs.getAccess().getDataPtr());

	// Render again to fbo
	context.bindTexture(GL_TEXTURE_2D, metaballsTex);
	context.enable(GL_BLEND);
	context.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
	sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
	context.disable(GL_BLEND);

	// Draw to screen
	context.bindFramebuffer(GL_FRAMEBUFFER, 0);
	context.viewport(0, 0, context.getWidth(), context.getHeight());
	context.bindTexture(GL_TEXTURE_2D, fboTex);
	sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

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

class ResizeTest : public FboRenderCase
{
public:
					ResizeTest				(Context& context, const FboConfig& config);
	virtual			~ResizeTest				(void) {}

	void			render					(sglr::Context& context, Surface& dst);
};

ResizeTest::ResizeTest (Context& context, const FboConfig& config)
	: FboRenderCase(context, config.getName().c_str(), "Resize framebuffer", config)
{
}

void ResizeTest::render (sglr::Context& context, Surface& dst)
{
	SingleTex2DShader	texShader;
	FlatColorShader		colorShader;
	deUint32			texShaderID		= context.createProgram(&texShader);
	deUint32			colorShaderID	= context.createProgram(&colorShader);
	deUint32			quadsTex		= 1;
	deUint32			metaballsTex	= 2;
	bool				depth			= getConfig().depthbufferType	 != GL_NONE;
	bool				stencil			= getConfig().stencilbufferType	 != GL_NONE;

	createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
	createMetaballsTex2D(context, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 32, 32);

	Framebuffer fbo(context, getConfig(), 128, 128);
	fbo.checkCompleteness();

	// Setup shaders
	texShader.setUnit(context, texShaderID, 0);
	colorShader.setColor(context, colorShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));

	// Render quads
	context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
	context.viewport(0, 0, 128, 128);
	context.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
	context.bindTexture(GL_TEXTURE_2D, quadsTex);
	sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

	if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		// Render fbo to screen
		context.bindFramebuffer(GL_FRAMEBUFFER, 0);
		context.viewport(0, 0, context.getWidth(), context.getHeight());
		context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer());
		sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

		// Restore binding
		context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
	}

	int newWidth	= 64;
	int newHeight	= 32;

	// Resize buffers
	switch (fbo.getConfig().colorbufferType)
	{
		case GL_TEXTURE_2D:
			context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer());
			context.texImage2D(GL_TEXTURE_2D, 0, fbo.getConfig().colorbufferFormat, newWidth, newHeight);
			break;

		case GL_RENDERBUFFER:
			context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getColorbuffer());
			context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().colorbufferFormat, newWidth, newHeight);
			break;

		default:
			DE_ASSERT(false);
	}

	if (depth)
	{
		DE_ASSERT(fbo.getConfig().depthbufferType == GL_RENDERBUFFER);
		context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getDepthbuffer());
		context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().depthbufferFormat, newWidth, newHeight);
	}

	if (stencil)
	{
		DE_ASSERT(fbo.getConfig().stencilbufferType == GL_RENDERBUFFER);
		context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getStencilbuffer());
		context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().stencilbufferFormat, newWidth, newHeight);
	}

	// Render to resized fbo
	context.viewport(0, 0, newWidth, newHeight);
	context.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

	context.enable(GL_DEPTH_TEST);

	context.bindTexture(GL_TEXTURE_2D, metaballsTex);
	sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));

	context.bindTexture(GL_TEXTURE_2D, quadsTex);
	sglr::drawQuad(context, texShaderID, Vec3(0.0f, 0.0f, -1.0f), Vec3(+1.0f, +1.0f, 1.0f));

	context.disable(GL_DEPTH_TEST);

	if (stencil)
	{
		context.enable(GL_SCISSOR_TEST);
		context.scissor(10, 10, 5, 15);
		context.clearStencil(1);
		context.clear(GL_STENCIL_BUFFER_BIT);
		context.disable(GL_SCISSOR_TEST);

		context.enable(GL_STENCIL_TEST);
		context.stencilFunc(GL_EQUAL, 1, 0xffu);
		sglr::drawQuad(context, colorShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
		context.disable(GL_STENCIL_TEST);
	}

	if (getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		context.bindFramebuffer(GL_FRAMEBUFFER, 0);
		context.viewport(0, 0, context.getWidth(), context.getHeight());
		context.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer());
		sglr::drawQuad(context, texShaderID, Vec3(-0.5f, -0.5f, 0.0f), Vec3(0.5f, 0.5f, 0.0f));
		context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
	}
	else
		context.readPixels(dst, 0, 0, newWidth, newHeight);
}

template <GLenum Buffers>
class RecreateBuffersTest : public FboRenderCase
{
public:
					RecreateBuffersTest			(Context& context, const FboConfig& config, bool rebind);
	virtual			~RecreateBuffersTest		(void) {}

	static bool		isConfigSupported			(const FboConfig& config);
	void			render						(sglr::Context& context, Surface& dst);

private:
	bool			m_rebind;
};

template <GLenum Buffers>
class RecreateBuffersNoRebindTest : public RecreateBuffersTest<Buffers>
{
public:
	RecreateBuffersNoRebindTest (Context& context, const FboConfig& config)
		: RecreateBuffersTest<Buffers>(context, config, false)
	{
	}
};

template <GLenum Buffers>
class RecreateBuffersRebindTest : public RecreateBuffersTest<Buffers>
{
public:
	RecreateBuffersRebindTest (Context& context, const FboConfig& config)
		: RecreateBuffersTest<Buffers>(context, config, true)
	{
	}
};

template <GLenum Buffers>
RecreateBuffersTest<Buffers>::RecreateBuffersTest (Context& context, const FboConfig& config, bool rebind)
	: FboRenderCase		(context, (string(rebind ? "rebind_" : "no_rebind_") + config.getName()).c_str(), "Recreate buffers", config)
	, m_rebind			(rebind)
{
}

template <GLenum Buffers>
bool RecreateBuffersTest<Buffers>::isConfigSupported (const FboConfig& config)
{
	if ((Buffers & GL_COLOR_BUFFER_BIT) && config.colorbufferType == GL_NONE)
		return false;
	if ((Buffers & GL_DEPTH_BUFFER_BIT) && config.depthbufferType == GL_NONE)
		return false;
	if ((Buffers & GL_STENCIL_BUFFER_BIT) && config.stencilbufferType == GL_NONE)
		return false;
	return true;
}

template <GLenum Buffers>
void RecreateBuffersTest<Buffers>::render (sglr::Context& ctx, Surface& dst)
{
	SingleTex2DShader	texShader;
	deUint32			texShaderID		= ctx.createProgram(&texShader);
	int					width			= 128;
	int					height			= 128;
	deUint32			metaballsTex	= 1;
	deUint32			quadsTex		= 2;
	bool				stencil			= getConfig().stencilbufferType != GL_NONE;

	createQuadsTex2D(ctx, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
	createMetaballsTex2D(ctx, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);

	Framebuffer fbo(ctx, getConfig(), width, height);
	fbo.checkCompleteness();

	// Setup shader
	texShader.setUnit(ctx, texShaderID, 0);

	// Draw scene
	ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
	ctx.viewport(0, 0, width, height);
	ctx.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
	ctx.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

	ctx.enable(GL_DEPTH_TEST);

	ctx.bindTexture(GL_TEXTURE_2D, quadsTex);
	sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

	if (stencil)
	{
		ctx.enable(GL_SCISSOR_TEST);
		ctx.scissor(width/4, height/4, width/2, height/2);
		ctx.clearStencil(1);
		ctx.clear(GL_STENCIL_BUFFER_BIT);
		ctx.disable(GL_SCISSOR_TEST);
	}

	// Recreate buffers
	if (!m_rebind)
		ctx.bindFramebuffer(GL_FRAMEBUFFER, 0);

	if (Buffers & GL_COLOR_BUFFER_BIT)
	{
		deUint32 colorbuf = fbo.getColorbuffer();
		switch (fbo.getConfig().colorbufferType)
		{
			case GL_TEXTURE_2D:
				ctx.deleteTextures(1, &colorbuf);
				ctx.bindTexture(GL_TEXTURE_2D, colorbuf);
				ctx.texImage2D(GL_TEXTURE_2D, 0, fbo.getConfig().colorbufferFormat, width, height);
				ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

				if (m_rebind)
					ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuf, 0);
				break;

			case GL_RENDERBUFFER:
				ctx.deleteRenderbuffers(1, &colorbuf);
				ctx.bindRenderbuffer(GL_RENDERBUFFER, colorbuf);
				ctx.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().colorbufferFormat, width, height);

				if (m_rebind)
					ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
				break;

			default:
				DE_ASSERT(false);
		}
	}

	if (Buffers & GL_DEPTH_BUFFER_BIT)
	{
		deUint32 depthbuf = fbo.getDepthbuffer();
		DE_ASSERT(fbo.getConfig().depthbufferType == GL_RENDERBUFFER);

		ctx.deleteRenderbuffers(1, &depthbuf);
		ctx.bindRenderbuffer(GL_RENDERBUFFER, depthbuf);
		ctx.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().depthbufferFormat, width, height);

		if (m_rebind)
			ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuf);
	}

	if (Buffers & GL_STENCIL_BUFFER_BIT)
	{
		deUint32 stencilbuf = fbo.getStencilbuffer();
		DE_ASSERT(fbo.getConfig().stencilbufferType == GL_RENDERBUFFER);

		ctx.deleteRenderbuffers(1, &stencilbuf);
		ctx.bindRenderbuffer(GL_RENDERBUFFER, stencilbuf);
		ctx.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().stencilbufferFormat, width, height);

		if (m_rebind)
			ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilbuf);
	}

	if (!m_rebind)
		ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());

	ctx.clearColor(0.0f, 0.0f, 1.0f, 0.0f);
	ctx.clearStencil(0);
	ctx.clear(Buffers); // \note Clear only buffers that were re-created

	if (stencil)
	{
		// \note Stencil test enabled only if we have stencil buffer
		ctx.enable(GL_STENCIL_TEST);
		ctx.stencilFunc(GL_EQUAL, 0, 0xffu);
	}
	ctx.bindTexture(GL_TEXTURE_2D, metaballsTex);
	sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 1.0f), Vec3(1.0f, 1.0f, -1.0f));
	if (stencil)
		ctx.disable(GL_STENCIL_TEST);

	ctx.disable(GL_DEPTH_TEST);

	if (fbo.getConfig().colorbufferType == GL_TEXTURE_2D)
	{
		// Unbind fbo
		ctx.bindFramebuffer(GL_FRAMEBUFFER, 0);

		// Draw to screen
		ctx.bindTexture(GL_TEXTURE_2D, fbo.getColorbuffer());
		ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight());
		sglr::drawQuad(ctx, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

		// Read from screen
		ctx.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
	}
	else
	{
		// Read from fbo
		ctx.readPixels(dst, 0, 0, width, height);
	}
}

class RepeatedClearCase : public FboRenderCase
{
private:
	static FboConfig makeConfig (deUint32 format)
	{
		FboConfig cfg;
		cfg.colorbufferType		= GL_TEXTURE_2D;
		cfg.colorbufferFormat	= format;
		cfg.depthbufferType		= GL_NONE;
		cfg.stencilbufferType	= GL_NONE;
		return cfg;
	}

public:
	RepeatedClearCase (Context& context, deUint32 format)
		: FboRenderCase(context, makeConfig(format).getName().c_str(), "Repeated clears", makeConfig(format))
	{
	}

protected:
	void render (sglr::Context& ctx, Surface& dst)
	{
		const int						numRowsCols		= 4;
		const int						cellSize		= 16;
		const int						fboSizes[]		= { cellSize, cellSize*numRowsCols };

		SingleTex2DShader				fboBlitShader;
		const deUint32					fboBlitShaderID	= ctx.createProgram(&fboBlitShader);

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

		ctx.genFramebuffers(2, &fbos[0]);
		ctx.genTextures(2, &textures[0]);

		for (int fboNdx = 0; fboNdx < DE_LENGTH_OF_ARRAY(fbos); fboNdx++)
		{
			ctx.bindTexture(GL_TEXTURE_2D, textures[fboNdx]);
			ctx.texImage2D(GL_TEXTURE_2D, 0, getConfig().colorbufferFormat, fboSizes[fboNdx], fboSizes[fboNdx], 0,
						   getConfig().colorbufferFormat, GL_UNSIGNED_BYTE, DE_NULL);
			ctx.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			ctx.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			ctx.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
			ctx.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

			ctx.bindFramebuffer(GL_FRAMEBUFFER, fbos[fboNdx]);
			ctx.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[fboNdx], 0);

			{
				const GLenum status = ctx.checkFramebufferStatus(GL_FRAMEBUFFER);
				if (status != GL_FRAMEBUFFER_COMPLETE)
					throw FboIncompleteException(getConfig(), status, __FILE__, __LINE__);
			}
		}

		// larger fbo bound -- clear to transparent black
		ctx.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
		ctx.clear(GL_COLOR_BUFFER_BIT);

		fboBlitShader.setUnit(ctx, fboBlitShaderID, 0);
		ctx.bindTexture(GL_TEXTURE_2D, textures[0]);

		for (int cellY = 0; cellY < numRowsCols; cellY++)
		for (int cellX = 0; cellX < numRowsCols; cellX++)
		{
			const float	r	= rnd.getFloat();
			const float	g	= rnd.getFloat();
			const float	b	= rnd.getFloat();
			const float	a	= rnd.getFloat();

			ctx.bindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
			ctx.clearColor(r, g, b, a);
			ctx.clear(GL_COLOR_BUFFER_BIT);

			ctx.bindFramebuffer(GL_FRAMEBUFFER, fbos[1]);
			ctx.viewport(cellX*cellSize, cellY*cellSize, cellSize, cellSize);
			sglr::drawQuad(ctx, fboBlitShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		}

		ctx.readPixels(dst, 0, 0, fboSizes[1], fboSizes[1]);
	}
};

} // FboCases

FboRenderTestGroup::FboRenderTestGroup (Context& context)
	: TestCaseGroup(context, "render", "Rendering Tests")
{
}

FboRenderTestGroup::~FboRenderTestGroup (void)
{
}

namespace
{

struct TypeFormatPair
{
	GLenum		type;
	GLenum		format;
};

template <typename CaseType>
void addChildVariants (deqp::gles2::TestCaseGroup* group)
{
	TypeFormatPair colorbufferConfigs[] =
	{
//		{ GL_TEXTURE_2D,	GL_ALPHA },
//		{ GL_TEXTURE_2D,	GL_LUMINANCE },
//		{ GL_TEXTURE_2D,	GL_LUMINANCE_ALPHA },
		{ GL_TEXTURE_2D,	GL_RGB },
		{ GL_TEXTURE_2D,	GL_RGBA },
		{ GL_RENDERBUFFER,	GL_RGB565 },
		{ GL_RENDERBUFFER,	GL_RGB5_A1 },
		{ GL_RENDERBUFFER,	GL_RGBA4 },
//		{ GL_RENDERBUFFER,	GL_RGBA16F },
//		{ GL_RENDERBUFFER,	GL_RGB16F }
	};
	TypeFormatPair depthbufferConfigs[] =
	{
		{ GL_NONE,			GL_NONE },
		{ GL_RENDERBUFFER,	GL_DEPTH_COMPONENT16 }
	};
	TypeFormatPair stencilbufferConfigs[] =
	{
		{ GL_NONE,			GL_NONE },
		{ GL_RENDERBUFFER,	GL_STENCIL_INDEX8 }
	};

	for (int colorbufferNdx = 0; colorbufferNdx < DE_LENGTH_OF_ARRAY(colorbufferConfigs); colorbufferNdx++)
	for (int depthbufferNdx = 0; depthbufferNdx < DE_LENGTH_OF_ARRAY(depthbufferConfigs); depthbufferNdx++)
	for (int stencilbufferNdx = 0; stencilbufferNdx < DE_LENGTH_OF_ARRAY(stencilbufferConfigs); stencilbufferNdx++)
	{
		FboConfig config;
		config.colorbufferType		= colorbufferConfigs[colorbufferNdx].type;
		config.colorbufferFormat	= colorbufferConfigs[colorbufferNdx].format;
		config.depthbufferType		= depthbufferConfigs[depthbufferNdx].type;
		config.depthbufferFormat	= depthbufferConfigs[depthbufferNdx].format;
		config.stencilbufferType	= stencilbufferConfigs[stencilbufferNdx].type;
		config.stencilbufferFormat	= stencilbufferConfigs[stencilbufferNdx].format;

		if (CaseType::isConfigSupported(config))
			group->addChild(new CaseType(group->getContext(), config));
	}
}

template <typename CaseType>
void createChildGroup (deqp::gles2::TestCaseGroup* parent, const char* name, const char* description)
{
	deqp::gles2::TestCaseGroup* tmpGroup = new deqp::gles2::TestCaseGroup(parent->getContext(), name, description);
	parent->addChild(tmpGroup);
	addChildVariants<CaseType>(tmpGroup);
}

template <GLbitfield Buffers>
void createRecreateBuffersGroup (deqp::gles2::TestCaseGroup* parent, const char* name, const char* description)
{
	deqp::gles2::TestCaseGroup* tmpGroup = new deqp::gles2::TestCaseGroup(parent->getContext(), name, description);
	parent->addChild(tmpGroup);
	addChildVariants<FboCases::RecreateBuffersRebindTest<Buffers> >		(tmpGroup);
	addChildVariants<FboCases::RecreateBuffersNoRebindTest<Buffers> >	(tmpGroup);
}

} // anonymous

void FboRenderTestGroup::init (void)
{
	createChildGroup<FboCases::ColorClearsTest>					(this, "color_clear",		"Color buffer clears");
	createChildGroup<FboCases::StencilClearsTest>				(this, "stencil_clear",		"Stencil buffer clears");

	deqp::gles2::TestCaseGroup* colorGroup = new deqp::gles2::TestCaseGroup(m_context, "color", "Color buffer tests");
	addChild(colorGroup);
	addChildVariants<FboCases::MixTest>			(colorGroup);
	addChildVariants<FboCases::MixNpotTest>		(colorGroup);
	addChildVariants<FboCases::BlendTest>		(colorGroup);
	addChildVariants<FboCases::BlendNpotTest>	(colorGroup);

	deqp::gles2::TestCaseGroup* depthGroup = new deqp::gles2::TestCaseGroup(m_context, "depth", "Depth bufer tests");
	addChild(depthGroup);
	addChildVariants<FboCases::IntersectingQuadsTest>		(depthGroup);
	addChildVariants<FboCases::IntersectingQuadsNpotTest>	(depthGroup);

	deqp::gles2::TestCaseGroup* stencilGroup = new deqp::gles2::TestCaseGroup(m_context, "stencil", "Stencil buffer tests");
	addChild(stencilGroup);
	addChildVariants<FboCases::StencilTest>		(stencilGroup);
	addChildVariants<FboCases::StencilNpotTest>	(stencilGroup);

	createChildGroup<FboCases::SharedColorbufferClearsTest>		(this, "shared_colorbuffer_clear",	"Shared colorbuffer clears");
	createChildGroup<FboCases::SharedColorbufferTest>			(this, "shared_colorbuffer",		"Shared colorbuffer tests");
	createChildGroup<FboCases::SharedDepthbufferTest>			(this, "shared_depthbuffer",		"Shared depthbuffer tests");
	createChildGroup<FboCases::ResizeTest>						(this, "resize",					"FBO resize tests");

	createRecreateBuffersGroup<GL_COLOR_BUFFER_BIT>				(this, "recreate_colorbuffer",		"Recreate colorbuffer tests");
	createRecreateBuffersGroup<GL_DEPTH_BUFFER_BIT>				(this, "recreate_depthbuffer",		"Recreate depthbuffer tests");
	createRecreateBuffersGroup<GL_STENCIL_BUFFER_BIT>			(this, "recreate_stencilbuffer",	"Recreate stencilbuffer tests");

	deqp::gles2::TestCaseGroup* texSubImageGroup = new deqp::gles2::TestCaseGroup(m_context, "texsubimage", "TexSubImage interop with FBO colorbuffer texture");
	addChild(texSubImageGroup);
	addChildVariants<FboCases::TexSubImageAfterRenderTest>		(texSubImageGroup);
	addChildVariants<FboCases::TexSubImageBetweenRenderTest>	(texSubImageGroup);

	{
		tcu::TestCaseGroup* const repeatedClearGroup = new tcu::TestCaseGroup(m_testCtx, "repeated_clear", "Repeated FBO clears");
		addChild(repeatedClearGroup);

		repeatedClearGroup->addChild(new FboCases::RepeatedClearCase(m_context, GL_RGB));
		repeatedClearGroup->addChild(new FboCases::RepeatedClearCase(m_context, GL_RGBA));
	}
}

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