/*-------------------------------------------------------------------------
 * 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 invalidate tests.
 *//*--------------------------------------------------------------------*/

#include "es3fFboInvalidateTests.hpp"
#include "es3fFboTestCase.hpp"
#include "es3fFboTestUtil.hpp"
#include "gluTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuTextureUtil.hpp"
#include "sglrContextUtil.hpp"

#include "glwEnums.hpp"

#include <algorithm>

namespace deqp
{
namespace gles3
{
namespace Functional
{

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

static std::vector<deUint32> getDefaultFBDiscardAttachments (deUint32 discardBufferBits)
{
	vector<deUint32> attachments;

	if (discardBufferBits & GL_COLOR_BUFFER_BIT)
		attachments.push_back(GL_COLOR);

	if (discardBufferBits & GL_DEPTH_BUFFER_BIT)
		attachments.push_back(GL_DEPTH);

	if (discardBufferBits & GL_STENCIL_BUFFER_BIT)
		attachments.push_back(GL_STENCIL);

	return attachments;
}

static std::vector<deUint32> getFBODiscardAttachments (deUint32 discardBufferBits)
{
	vector<deUint32> attachments;

	if (discardBufferBits & GL_COLOR_BUFFER_BIT)
		attachments.push_back(GL_COLOR_ATTACHMENT0);

	// \note DEPTH_STENCIL_ATTACHMENT is allowed when discarding FBO, but not with default FB
	if ((discardBufferBits & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) == (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))
		attachments.push_back(GL_DEPTH_STENCIL_ATTACHMENT);
	else if (discardBufferBits & GL_DEPTH_BUFFER_BIT)
		attachments.push_back(GL_DEPTH_ATTACHMENT);
	else if (discardBufferBits & GL_STENCIL_BUFFER_BIT)
		attachments.push_back(GL_STENCIL_ATTACHMENT);

	return attachments;
}

static inline bool hasAttachment (const std::vector<deUint32>& attachmentList, deUint32 attachment)
{
	return std::find(attachmentList.begin(), attachmentList.end(), attachment) != attachmentList.end();
}

static deUint32 getCompatibleColorFormat (const tcu::RenderTarget& renderTargetInfo)
{
	const tcu::PixelFormat& pxFmt = renderTargetInfo.getPixelFormat();
	DE_ASSERT(de::inBounds(pxFmt.redBits,	0, 0xff) &&
			  de::inBounds(pxFmt.greenBits,	0, 0xff) &&
			  de::inBounds(pxFmt.blueBits,	0, 0xff) &&
			  de::inBounds(pxFmt.alphaBits,	0, 0xff));

#define PACK_FMT(R, G, B, A) (((R) << 24) | ((G) << 16) | ((B) << 8) | (A))

	// \note [pyry] This may not hold true on some implementations - best effort guess only.
	switch (PACK_FMT(pxFmt.redBits, pxFmt.greenBits, pxFmt.blueBits, pxFmt.alphaBits))
	{
		case PACK_FMT(8,8,8,8):		return GL_RGBA8;
		case PACK_FMT(8,8,8,0):		return GL_RGB8;
		case PACK_FMT(4,4,4,4):		return GL_RGBA4;
		case PACK_FMT(5,5,5,1):		return GL_RGB5_A1;
		case PACK_FMT(5,6,5,0):		return GL_RGB565;
		default:					return GL_NONE;
	}

#undef PACK_FMT
}

static deUint32 getCompatibleDepthStencilFormat (const tcu::RenderTarget& renderTargetInfo)
{
	const int	depthBits		= renderTargetInfo.getDepthBits();
	const int	stencilBits		= renderTargetInfo.getStencilBits();
	const bool	hasDepth		= depthBits > 0;
	const bool	hasStencil		= stencilBits > 0;

	if (!hasDepth || !hasStencil || (stencilBits != 8))
		return GL_NONE;

	if (depthBits == 32)
		return GL_DEPTH32F_STENCIL8;
	else if (depthBits == 24)
		return GL_DEPTH24_STENCIL8;
	else
		return GL_NONE;
}

class InvalidateDefaultFramebufferRenderCase : public FboTestCase
{
public:
	InvalidateDefaultFramebufferRenderCase (Context& context, const char* name, const char* description, deUint32 buffers, deUint32 fboTarget = GL_FRAMEBUFFER)
		: FboTestCase	(context, name, description)
		, m_buffers		(buffers)
		, m_fboTarget	(fboTarget)
	{
	}

	void render (tcu::Surface& dst)
	{
		FlatColorShader		flatShader	(glu::TYPE_FLOAT_VEC4);
		vector<deUint32>	attachments	= getDefaultFBDiscardAttachments(m_buffers);
		deUint32			flatShaderID= getCurrentContext()->createProgram(&flatShader);

		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc	(GL_ALWAYS, 1, 0xff);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		glInvalidateFramebuffer(m_fboTarget, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]);

		if ((m_buffers & GL_COLOR_BUFFER_BIT) != 0)
		{
			// Color was not preserved - fill with green.
			glDisable(GL_DEPTH_TEST);
			glDisable(GL_STENCIL_TEST);

			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

			glEnable(GL_DEPTH_TEST);
			glEnable(GL_STENCIL_TEST);
		}

		if ((m_buffers & GL_DEPTH_BUFFER_BIT) != 0)
		{
			// Depth was not preserved.
			glDepthFunc(GL_ALWAYS);
		}

		if ((m_buffers & GL_STENCIL_BUFFER_BIT) == 0)
		{
			// Stencil was preserved.
			glStencilFunc(GL_EQUAL, 1, 0xff);
		}

		glEnable		(GL_BLEND);
		glBlendFunc		(GL_ONE, GL_ONE);
		glBlendEquation	(GL_FUNC_ADD);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

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

private:
	deUint32 m_buffers;
	deUint32 m_fboTarget;
};

class InvalidateDefaultFramebufferBindCase : public FboTestCase
{
public:
	InvalidateDefaultFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers)
		: FboTestCase	(context, name, description)
		, m_buffers		(buffers)
	{
	}

	void render (tcu::Surface& dst)
	{
		deUint32			fbo			= 0;
		deUint32			tex			= 0;
		FlatColorShader		flatShader	(glu::TYPE_FLOAT_VEC4);
		Texture2DShader		texShader	(DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
		GradientShader		gradShader	(glu::TYPE_FLOAT_VEC4);
		vector<deUint32>	attachments	= getDefaultFBDiscardAttachments(m_buffers);
		deUint32			flatShaderID= getCurrentContext()->createProgram(&flatShader);
		deUint32			texShaderID = getCurrentContext()->createProgram(&texShader);
		deUint32			gradShaderID= getCurrentContext()->createProgram(&gradShader);

		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		// Create fbo.
		glGenFramebuffers		(1, &fbo);
		glGenTextures			(1, &tex);
		glBindTexture			(GL_TEXTURE_2D, tex);
		glTexImage2D			(GL_TEXTURE_2D, 0, GL_RGBA8, getWidth(), getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
		glTexParameteri			(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glBindFramebuffer		(GL_FRAMEBUFFER, fbo);
		glFramebufferTexture2D	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
		glBindTexture			(GL_TEXTURE_2D, 0);
		checkFramebufferStatus	(GL_FRAMEBUFFER);

		glBindFramebuffer		(GL_FRAMEBUFFER, 0);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc	(GL_ALWAYS, 1, 0xff);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]);

		// Switch to fbo and render gradient into it.
		glDisable			(GL_DEPTH_TEST);
		glDisable			(GL_STENCIL_TEST);
		glBindFramebuffer	(GL_FRAMEBUFFER, fbo);

		gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f));
		sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

		// Restore default fbo.
		glBindFramebuffer	(GL_FRAMEBUFFER, 0);

		if ((m_buffers & GL_COLOR_BUFFER_BIT) != 0)
		{
			// Color was not preserved - fill with green.
			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		}

		if ((m_buffers & GL_DEPTH_BUFFER_BIT) != 0)
		{
			// Depth was not preserved.
			glDepthFunc(GL_ALWAYS);
		}

		if ((m_buffers & GL_STENCIL_BUFFER_BIT) == 0)
		{
			// Stencil was preserved.
			glStencilFunc(GL_EQUAL, 1, 0xff);
		}

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glEnable		(GL_BLEND);
		glBlendFunc		(GL_ONE, GL_ONE);
		glBlendEquation	(GL_FUNC_ADD);
		glBindTexture	(GL_TEXTURE_2D, tex);

		texShader.setUniforms(*getCurrentContext(), texShaderID);
		sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

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

private:
	deUint32 m_buffers;
};

class InvalidateDefaultSubFramebufferRenderCase : public FboTestCase
{
public:
	InvalidateDefaultSubFramebufferRenderCase (Context& context, const char* name, const char* description, deUint32 buffers)
		: FboTestCase	(context, name, description)
		, m_buffers		(buffers)
	{
	}

	void render (tcu::Surface& dst)
	{
		int					invalidateX		= getWidth()	/ 4;
		int					invalidateY		= getHeight()	/ 4;
		int					invalidateW		= getWidth()	/ 2;
		int					invalidateH		= getHeight()	/ 2;
		FlatColorShader		flatShader		(glu::TYPE_FLOAT_VEC4);
		vector<deUint32>	attachments		= getDefaultFBDiscardAttachments(m_buffers);
		deUint32			flatShaderID	= getCurrentContext()->createProgram(&flatShader);

		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc	(GL_ALWAYS, 1, 0xff);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);

		// Clear invalidated buffers.
		glClearColor	(0.0f, 1.0f, 0.0f, 1.0f);
		glClearStencil	(1);
		glScissor		(invalidateX, invalidateY, invalidateW, invalidateH);
		glEnable		(GL_SCISSOR_TEST);
		glClear			(m_buffers);
		glDisable		(GL_SCISSOR_TEST);

		glEnable		(GL_BLEND);
		glBlendFunc		(GL_ONE, GL_ONE);
		glBlendEquation	(GL_FUNC_ADD);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

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

private:
	deUint32 m_buffers;
};

class InvalidateDefaultSubFramebufferBindCase : public FboTestCase
{
public:
	InvalidateDefaultSubFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers)
		: FboTestCase	(context, name, description)
		, m_buffers		(buffers)
	{
	}

	void render (tcu::Surface& dst)
	{
		deUint32			fbo				= 0;
		deUint32			tex				= 0;
		FlatColorShader		flatShader		(glu::TYPE_FLOAT_VEC4);
		Texture2DShader		texShader		(DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
		GradientShader		gradShader		(glu::TYPE_FLOAT_VEC4);
		vector<deUint32>	attachments		= getDefaultFBDiscardAttachments(m_buffers);
		deUint32			flatShaderID	= getCurrentContext()->createProgram(&flatShader);
		deUint32			texShaderID		= getCurrentContext()->createProgram(&texShader);
		deUint32			gradShaderID	= getCurrentContext()->createProgram(&gradShader);

		int				invalidateX		= getWidth()	/ 4;
		int				invalidateY		= getHeight()	/ 4;
		int				invalidateW		= getWidth()	/ 2;
		int				invalidateH		= getHeight()	/ 2;


		flatShader.setColor   (*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
		texShader.setUniforms (*getCurrentContext(), texShaderID);
		gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f));

		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		// Create fbo.
		glGenFramebuffers		(1, &fbo);
		glGenTextures			(1, &tex);
		glBindTexture			(GL_TEXTURE_2D, tex);
		glTexImage2D			(GL_TEXTURE_2D, 0, GL_RGBA8, getWidth(), getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
		glTexParameteri			(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glBindFramebuffer		(GL_FRAMEBUFFER, fbo);
		glFramebufferTexture2D	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
		glBindTexture			(GL_TEXTURE_2D, 0);
		checkFramebufferStatus	(GL_FRAMEBUFFER);

		glBindFramebuffer		(GL_FRAMEBUFFER, 0);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc	(GL_ALWAYS, 1, 0xff);

		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);

		// Switch to fbo and render gradient into it.
		glDisable			(GL_DEPTH_TEST);
		glDisable			(GL_STENCIL_TEST);
		glBindFramebuffer	(GL_FRAMEBUFFER, fbo);

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

		// Restore default fbo.
		glBindFramebuffer	(GL_FRAMEBUFFER, 0);

		// Clear invalidated buffers.
		glClearColor	(0.0f, 1.0f, 0.0f, 1.0f);
		glClearStencil	(1);
		glScissor		(invalidateX, invalidateY, invalidateW, invalidateH);
		glEnable		(GL_SCISSOR_TEST);
		glClear			(m_buffers);
		glDisable		(GL_SCISSOR_TEST);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glEnable		(GL_BLEND);
		glBlendFunc		(GL_ONE, GL_ONE);
		glBlendEquation	(GL_FUNC_ADD);
		glBindTexture	(GL_TEXTURE_2D, tex);

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

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

private:
	deUint32 m_buffers;
};

class InvalidateFboRenderCase : public FboTestCase
{
public:
	InvalidateFboRenderCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
		: FboTestCase			(context, name, description)
		, m_colorFmt			(colorFmt)
		, m_depthStencilFmt		(depthStencilFmt)
		, m_invalidateBuffers	(invalidateBuffers)
	{
	}

protected:
	void preCheck (void)
	{
		if (m_colorFmt != GL_NONE)			checkFormatSupport(m_colorFmt);
		if (m_depthStencilFmt != GL_NONE)	checkFormatSupport(m_depthStencilFmt);
	}

	void render (tcu::Surface& dst)
	{
		tcu::TextureFormat		colorFmt				= glu::mapGLInternalFormat(m_colorFmt);
		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
		tcu::TextureFormatInfo	colorFmtInfo			= tcu::getTextureFormatInfo(colorFmt);
		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
		const tcu::Vec4&		cBias					= colorFmtInfo.valueMin;
		tcu::Vec4				cScale					= colorFmtInfo.valueMax-colorFmtInfo.valueMin;
		deUint32				fbo						= 0;
		deUint32				colorRbo				= 0;
		deUint32				depthStencilRbo			= 0;
		FlatColorShader			flatShader				(glu::TYPE_FLOAT_VEC4);
		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
		deUint32				flatShaderID			= getCurrentContext()->createProgram(&flatShader);

		// Create fbo.
		glGenRenderbuffers		(1, &colorRbo);
		glBindRenderbuffer		(GL_RENDERBUFFER, colorRbo);
		glRenderbufferStorage	(GL_RENDERBUFFER, m_colorFmt, getWidth(), getHeight());

		if (m_depthStencilFmt != GL_NONE)
		{
			glGenRenderbuffers		(1, &depthStencilRbo);
			glBindRenderbuffer		(GL_RENDERBUFFER, depthStencilRbo);
			glRenderbufferStorage	(GL_RENDERBUFFER, m_depthStencilFmt, getWidth(), getHeight());
		}

		glGenFramebuffers			(1, &fbo);
		glBindFramebuffer			(GL_FRAMEBUFFER, fbo);
		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);

		if (depth)
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);

		if (stencil)
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);

		checkFramebufferStatus		(GL_FRAMEBUFFER);

		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc	(GL_ALWAYS, 1, 0xff);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias);
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]);

		if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
		{
			// Color was not preserved - fill with green.
			glDisable(GL_DEPTH_TEST);
			glDisable(GL_STENCIL_TEST);

			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias);
			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

			glEnable(GL_DEPTH_TEST);
			glEnable(GL_STENCIL_TEST);
		}

		if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
		{
			// Depth was not preserved.
			glDepthFunc(GL_ALWAYS);
		}

		if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0)
		{
			// Stencil was preserved.
			glStencilFunc(GL_EQUAL, 1, 0xff);
		}

		glEnable		(GL_BLEND);
		glBlendFunc		(GL_ONE, GL_ONE);
		glBlendEquation	(GL_FUNC_ADD);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias);
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

		readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
	}

private:
	deUint32	m_colorFmt;
	deUint32	m_depthStencilFmt;
	deUint32	m_invalidateBuffers;
};

class InvalidateFboUnbindReadCase : public FboTestCase
{
public:
	InvalidateFboUnbindReadCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
		: FboTestCase			(context, name, description)
		, m_colorFmt			(colorFmt)
		, m_depthStencilFmt		(depthStencilFmt)
		, m_invalidateBuffers	(invalidateBuffers)
	{
		DE_ASSERT((m_invalidateBuffers & (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)) != (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT));
	}

protected:
	void preCheck (void)
	{
		if (m_colorFmt != GL_NONE)			checkFormatSupport(m_colorFmt);
		if (m_depthStencilFmt != GL_NONE)	checkFormatSupport(m_depthStencilFmt);
	}

	void render (tcu::Surface& dst)
	{
		tcu::TextureFormat		colorFmt				= glu::mapGLInternalFormat(m_colorFmt);
		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
		tcu::TextureFormatInfo	colorFmtInfo			= tcu::getTextureFormatInfo(colorFmt);
		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
		deUint32				fbo						= 0;
		deUint32				colorTex				= 0;
		deUint32				depthStencilTex			= 0;
		GradientShader			gradShader				(getFragmentOutputType(colorFmt));
		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
		deUint32				gradShaderID			= getCurrentContext()->createProgram(&gradShader);

		// Create fbo.
		{
			glu::TransferFormat transferFmt = glu::getTransferFormat(colorFmt);

			glGenTextures	(1, &colorTex);
			glBindTexture	(GL_TEXTURE_2D, colorTex);
			glTexImage2D	(GL_TEXTURE_2D, 0, m_colorFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		}

		if (m_depthStencilFmt != GL_NONE)
		{
			glu::TransferFormat transferFmt = glu::getTransferFormat(depthStencilFmt);

			glGenTextures	(1, &depthStencilTex);
			glBindTexture	(GL_TEXTURE_2D, depthStencilTex);
			glTexImage2D	(GL_TEXTURE_2D, 0, m_depthStencilFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		}

		glGenFramebuffers		(1, &fbo);
		glBindFramebuffer		(GL_FRAMEBUFFER, fbo);
		glFramebufferTexture2D	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);

		if (depth)
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);

		if (stencil)
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);

		checkFramebufferStatus		(GL_FRAMEBUFFER);

		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc	(GL_ALWAYS, 1, 0xff);

		gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
		sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0]);

		glBindFramebuffer	(GL_FRAMEBUFFER, 0);
		glDisable			(GL_DEPTH_TEST);
		glDisable			(GL_STENCIL_TEST);

		if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
		{
			// Render color.
			Texture2DShader texShader(DataTypes() << glu::getSampler2DType(colorFmt), glu::TYPE_FLOAT_VEC4);
			deUint32		texShaderID = getCurrentContext()->createProgram(&texShader);

			texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
			texShader.setUniforms(*getCurrentContext(), texShaderID);

			glBindTexture(GL_TEXTURE_2D, colorTex);
			sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		}
		else
		{
			// Render depth.
			Texture2DShader texShader(DataTypes() << glu::getSampler2DType(depthStencilFmt), glu::TYPE_FLOAT_VEC4);
			deUint32		texShaderID = getCurrentContext()->createProgram(&texShader);

			texShader.setUniforms(*getCurrentContext(), texShaderID);

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

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

private:
	deUint32	m_colorFmt;
	deUint32	m_depthStencilFmt;
	deUint32	m_invalidateBuffers;
};

class InvalidateFboUnbindBlitCase : public FboTestCase
{
public:
	InvalidateFboUnbindBlitCase (Context& context, const char* name, const char* description, int numSamples, deUint32 invalidateBuffers)
		: FboTestCase			(context, name, description, numSamples > 0)	// \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
																				//		 behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
																				//		 source and destination rectangles must match when multisampling.
		, m_colorFmt			(0)
		, m_depthStencilFmt		(0)
		, m_numSamples			(numSamples)
		, m_invalidateBuffers	(invalidateBuffers)
	{
		// Figure out formats that are compatible with default framebuffer.
		m_colorFmt			= getCompatibleColorFormat(m_context.getRenderTarget());
		m_depthStencilFmt	= getCompatibleDepthStencilFormat(m_context.getRenderTarget());
	}

protected:
	void preCheck (void)
	{
		if (m_context.getRenderTarget().getNumSamples() > 0)
			throw tcu::NotSupportedError("Not supported in MSAA config");

		if (m_colorFmt == GL_NONE)
			throw tcu::NotSupportedError("Unsupported color format");

		if (m_depthStencilFmt == GL_NONE)
			throw tcu::NotSupportedError("Unsupported depth/stencil format");

		checkFormatSupport(m_colorFmt);
		checkFormatSupport(m_depthStencilFmt);
	}

	void render (tcu::Surface& dst)
	{
		// \note When using fullscreen viewport (when m_numSamples > 0), still only use a 128x128 pixel quad at most.
		IVec2					quadSizePixels			(m_numSamples == 0 ? getWidth() : de::min(128, getWidth()),
														 m_numSamples == 0 ? getHeight() : de::min(128, getHeight()));
		Vec2					quadNDCLeftBottomXY		(-1.0f, -1.0f);
		Vec2					quadNDCSize				(2.0f*(float)quadSizePixels.x()/(float)getWidth(), 2.0f*(float)quadSizePixels.y()/(float)getHeight());
		Vec2					quadNDCRightTopXY		= quadNDCLeftBottomXY + quadNDCSize;
		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
		deUint32				fbo						= 0;
		deUint32				colorRbo				= 0;
		deUint32				depthStencilRbo			= 0;
		FlatColorShader			flatShader				(glu::TYPE_FLOAT_VEC4);
		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
		deUint32				flatShaderID			= getCurrentContext()->createProgram(&flatShader);

		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		// Create fbo.
		glGenRenderbuffers					(1, &colorRbo);
		glBindRenderbuffer					(GL_RENDERBUFFER, colorRbo);
		glRenderbufferStorageMultisample	(GL_RENDERBUFFER, m_numSamples, m_colorFmt, quadSizePixels.x(), quadSizePixels.y());

		if (m_depthStencilFmt != GL_NONE)
		{
			glGenRenderbuffers					(1, &depthStencilRbo);
			glBindRenderbuffer					(GL_RENDERBUFFER, depthStencilRbo);
			glRenderbufferStorageMultisample	(GL_RENDERBUFFER, m_numSamples, m_depthStencilFmt, quadSizePixels.x(), quadSizePixels.y());
		}

		glGenFramebuffers			(1, &fbo);
		glBindFramebuffer			(GL_FRAMEBUFFER, fbo);
		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);

		if (depth)
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);

		if (stencil)
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);

		checkFramebufferStatus		(GL_FRAMEBUFFER);

		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc	(GL_ALWAYS, 1, 0xff);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), -1.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 1.0f));

		glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0]);

		// Set default framebuffer as draw framebuffer and blit preserved buffers.
		glBindFramebuffer	(GL_DRAW_FRAMEBUFFER, 0);
		glBlitFramebuffer	(0, 0, quadSizePixels.x(), quadSizePixels.y(),
							 0, 0, quadSizePixels.x(), quadSizePixels.y(),
							 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) & ~m_invalidateBuffers, GL_NEAREST);
		glBindFramebuffer	(GL_READ_FRAMEBUFFER, 0);

		if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
		{
			// Color was not preserved - fill with green.
			glDisable(GL_DEPTH_TEST);
			glDisable(GL_STENCIL_TEST);

			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));

			glEnable(GL_DEPTH_TEST);
			glEnable(GL_STENCIL_TEST);
		}

		if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
		{
			// Depth was not preserved.
			glDepthFunc(GL_ALWAYS);
		}

		if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0)
		{
			// Stencil was preserved.
			glStencilFunc(GL_EQUAL, 1, 0xff);
		}

		glEnable		(GL_BLEND);
		glBlendFunc		(GL_ONE, GL_ONE);
		glBlendEquation	(GL_FUNC_ADD);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));

		readPixels(dst, 0, 0, quadSizePixels.x(), quadSizePixels.y());
	}

private:
	deUint32	m_colorFmt;
	deUint32	m_depthStencilFmt;
	int			m_numSamples;
	deUint32	m_invalidateBuffers;
};

class InvalidateSubFboRenderCase : public FboTestCase
{
public:
	InvalidateSubFboRenderCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
		: FboTestCase			(context, name, description)
		, m_colorFmt			(colorFmt)
		, m_depthStencilFmt		(depthStencilFmt)
		, m_invalidateBuffers	(invalidateBuffers)
	{
	}

protected:
	void preCheck (void)
	{
		if (m_colorFmt != GL_NONE)			checkFormatSupport(m_colorFmt);
		if (m_depthStencilFmt != GL_NONE)	checkFormatSupport(m_depthStencilFmt);
	}

	void render (tcu::Surface& dst)
	{
		tcu::TextureFormat		colorFmt				= glu::mapGLInternalFormat(m_colorFmt);
		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
		tcu::TextureFormatInfo	colorFmtInfo			= tcu::getTextureFormatInfo(colorFmt);
		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
		const tcu::Vec4&		cBias					= colorFmtInfo.valueMin;
		tcu::Vec4				cScale					= colorFmtInfo.valueMax-colorFmtInfo.valueMin;
		deUint32				fbo						= 0;
		deUint32				colorRbo				= 0;
		deUint32				depthStencilRbo			= 0;
		int						invalidateX				= getWidth()	/ 4;
		int						invalidateY				= getHeight()	/ 4;
		int						invalidateW				= getWidth()	/ 2;
		int						invalidateH				= getHeight()	/ 2;
		FlatColorShader			flatShader				(glu::TYPE_FLOAT_VEC4);
		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
		deUint32				flatShaderID			= getCurrentContext()->createProgram(&flatShader);

		// Create fbo.
		glGenRenderbuffers		(1, &colorRbo);
		glBindRenderbuffer		(GL_RENDERBUFFER, colorRbo);
		glRenderbufferStorage	(GL_RENDERBUFFER, m_colorFmt, getWidth(), getHeight());

		if (m_depthStencilFmt != GL_NONE)
		{
			glGenRenderbuffers		(1, &depthStencilRbo);
			glBindRenderbuffer		(GL_RENDERBUFFER, depthStencilRbo);
			glRenderbufferStorage	(GL_RENDERBUFFER, m_depthStencilFmt, getWidth(), getHeight());
		}

		glGenFramebuffers			(1, &fbo);
		glBindFramebuffer			(GL_FRAMEBUFFER, fbo);
		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);

		if (depth)
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);

		if (stencil)
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);

		checkFramebufferStatus		(GL_FRAMEBUFFER);

		glClearBufferfv	(GL_COLOR, 0, (Vec4(0.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias).getPtr());
		glClearBufferfi	(GL_DEPTH_STENCIL, 0, 1.0f, 0);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc	(GL_ALWAYS, 1, 0xff);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias);
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);

		// Clear invalidated buffers.
		glScissor	(invalidateX, invalidateY, invalidateW, invalidateH);
		glEnable	(GL_SCISSOR_TEST);

		if (m_invalidateBuffers & GL_COLOR_BUFFER_BIT)
			glClearBufferfv(GL_COLOR, 0, (Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias).getPtr());

		glClear		(m_invalidateBuffers & ~GL_COLOR_BUFFER_BIT);
		glDisable	(GL_SCISSOR_TEST);

		glEnable		(GL_BLEND);
		glBlendFunc		(GL_ONE, GL_ONE);
		glBlendEquation	(GL_FUNC_ADD);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias);
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

		readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
	}

private:
	deUint32	m_colorFmt;
	deUint32	m_depthStencilFmt;
	deUint32	m_invalidateBuffers;
};

class InvalidateSubFboUnbindReadCase : public FboTestCase
{
public:
	InvalidateSubFboUnbindReadCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
		: FboTestCase			(context, name, description)
		, m_colorFmt			(colorFmt)
		, m_depthStencilFmt		(depthStencilFmt)
		, m_invalidateBuffers	(invalidateBuffers)
	{
		DE_ASSERT((m_invalidateBuffers & (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)) != (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT));
	}

protected:
	void preCheck (void)
	{
		if (m_colorFmt != GL_NONE)			checkFormatSupport(m_colorFmt);
		if (m_depthStencilFmt != GL_NONE)	checkFormatSupport(m_depthStencilFmt);
	}

	void render (tcu::Surface& dst)
	{
		tcu::TextureFormat		colorFmt				= glu::mapGLInternalFormat(m_colorFmt);
		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
		tcu::TextureFormatInfo	colorFmtInfo			= tcu::getTextureFormatInfo(colorFmt);
		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
		deUint32				fbo						= 0;
		deUint32				colorTex				= 0;
		deUint32				depthStencilTex			= 0;
		int						invalidateX				= 0;
		int						invalidateY				= 0;
		int						invalidateW				= getWidth()/2;
		int						invalidateH				= getHeight();
		int						readX					= invalidateW;
		int						readY					= 0;
		int						readW					= getWidth()/2;
		int						readH					= getHeight();
		GradientShader			gradShader				(getFragmentOutputType(colorFmt));
		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
		deUint32				gradShaderID			= getCurrentContext()->createProgram(&gradShader);

		// Create fbo.
		{
			glu::TransferFormat transferFmt = glu::getTransferFormat(colorFmt);

			glGenTextures	(1, &colorTex);
			glBindTexture	(GL_TEXTURE_2D, colorTex);
			glTexImage2D	(GL_TEXTURE_2D, 0, m_colorFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		}

		if (m_depthStencilFmt != GL_NONE)
		{
			glu::TransferFormat transferFmt = glu::getTransferFormat(depthStencilFmt);

			glGenTextures	(1, &depthStencilTex);
			glBindTexture	(GL_TEXTURE_2D, depthStencilTex);
			glTexImage2D	(GL_TEXTURE_2D, 0, m_depthStencilFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		}

		glGenFramebuffers		(1, &fbo);
		glBindFramebuffer		(GL_FRAMEBUFFER, fbo);
		glFramebufferTexture2D	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);

		if (depth)
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);

		if (stencil)
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);

		checkFramebufferStatus		(GL_FRAMEBUFFER);

		clearColorBuffer(colorFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
		glClear			(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc	(GL_ALWAYS, 1, 0xff);

		gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
		sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);

		glBindFramebuffer	(GL_FRAMEBUFFER, 0);
		glDisable			(GL_DEPTH_TEST);
		glDisable			(GL_STENCIL_TEST);

		glClearColor		(0.25f, 0.5f, 0.75f, 1.0f);
		glClear				(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		// Limit read area using scissor.
		glScissor			(readX, readY, readW, readH);
		glEnable			(GL_SCISSOR_TEST);

		if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
		{
			// Render color.
			Texture2DShader texShader(DataTypes() << glu::getSampler2DType(colorFmt), glu::TYPE_FLOAT_VEC4);
			deUint32		texShaderID = getCurrentContext()->createProgram(&texShader);

			texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
			texShader.setUniforms(*getCurrentContext(), texShaderID);

			glBindTexture(GL_TEXTURE_2D, colorTex);
			sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		}
		else
		{
			// Render depth.
			Texture2DShader texShader(DataTypes() << glu::getSampler2DType(depthStencilFmt), glu::TYPE_FLOAT_VEC4);
			deUint32		texShaderID = getCurrentContext()->createProgram(&texShader);

			texShader.setUniforms(*getCurrentContext(), texShaderID);

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

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

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

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

private:
	deUint32	m_colorFmt;
	deUint32	m_depthStencilFmt;
	deUint32	m_invalidateBuffers;
};

class InvalidateSubFboUnbindBlitCase : public FboTestCase
{
public:
	InvalidateSubFboUnbindBlitCase (Context& context, const char* name, const char* description, int numSamples, deUint32 invalidateBuffers)
		: FboTestCase			(context, name, description, numSamples > 0)	// \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
																				//		 behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
																				//		 source and destination rectangles must match when multisampling.
		, m_colorFmt			(0)
		, m_depthStencilFmt		(0)
		, m_numSamples			(numSamples)
		, m_invalidateBuffers	(invalidateBuffers)
	{
		// Figure out formats that are compatible with default framebuffer.
		m_colorFmt			= getCompatibleColorFormat(m_context.getRenderTarget());
		m_depthStencilFmt	= getCompatibleDepthStencilFormat(m_context.getRenderTarget());
	}

protected:
	void preCheck (void)
	{
		if (m_context.getRenderTarget().getNumSamples() > 0)
			throw tcu::NotSupportedError("Not supported in MSAA config");

		if (m_colorFmt == GL_NONE)
			throw tcu::NotSupportedError("Unsupported color format");

		if (m_depthStencilFmt == GL_NONE)
			throw tcu::NotSupportedError("Unsupported depth/stencil format");

		checkFormatSupport(m_colorFmt);
		checkFormatSupport(m_depthStencilFmt);
	}

	void render (tcu::Surface& dst)
	{
		// \note When using fullscreen viewport (when m_numSamples > 0), still only use a 128x128 pixel quad at most.
		IVec2					quadSizePixels			(m_numSamples == 0 ? getWidth() : de::min(128, getWidth()),
														 m_numSamples == 0 ? getHeight() : de::min(128, getHeight()));
		Vec2					quadNDCLeftBottomXY		(-1.0f, -1.0f);
		Vec2					quadNDCSize				(2.0f*(float)quadSizePixels.x()/(float)getWidth(), 2.0f*(float)quadSizePixels.y()/(float)getHeight());
		Vec2					quadNDCRightTopXY		= quadNDCLeftBottomXY + quadNDCSize;
		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
		deUint32				fbo						= 0;
		deUint32				colorRbo				= 0;
		deUint32				depthStencilRbo			= 0;
		int						invalidateX				= 0;
		int						invalidateY				= 0;
		int						invalidateW				= quadSizePixels.x()/2;
		int						invalidateH				= quadSizePixels.y();
		int						blitX0					= invalidateW;
		int						blitY0					= 0;
		int						blitX1					= blitX0 + quadSizePixels.x()/2;
		int						blitY1					= blitY0 + quadSizePixels.y();
		FlatColorShader			flatShader				(glu::TYPE_FLOAT_VEC4);
		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
		deUint32				flatShaderID			= getCurrentContext()->createProgram(&flatShader);

		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		// Create fbo.
		glGenRenderbuffers					(1, &colorRbo);
		glBindRenderbuffer					(GL_RENDERBUFFER, colorRbo);
		glRenderbufferStorageMultisample	(GL_RENDERBUFFER, m_numSamples, m_colorFmt, quadSizePixels.x(), quadSizePixels.y());

		if (m_depthStencilFmt != GL_NONE)
		{
			glGenRenderbuffers					(1, &depthStencilRbo);
			glBindRenderbuffer					(GL_RENDERBUFFER, depthStencilRbo);
			glRenderbufferStorageMultisample	(GL_RENDERBUFFER, m_numSamples, m_depthStencilFmt, quadSizePixels.x(), quadSizePixels.y());
		}

		glGenFramebuffers			(1, &fbo);
		glBindFramebuffer			(GL_FRAMEBUFFER, fbo);
		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);

		if (depth)
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);

		if (stencil)
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);

		checkFramebufferStatus		(GL_FRAMEBUFFER);

		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc	(GL_ALWAYS, 1, 0xff);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), -1.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 1.0f));

		glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);

		// Set default framebuffer as draw framebuffer and blit preserved buffers.
		glBindFramebuffer	(GL_DRAW_FRAMEBUFFER, 0);
		glBlitFramebuffer	(blitX0, blitY0, blitX1, blitY1, blitX0, blitY0, blitX1, blitY1, (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) & ~m_invalidateBuffers, GL_NEAREST);
		glBindFramebuffer	(GL_READ_FRAMEBUFFER, 0);

		if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
		{
			// Color was not preserved - fill with green.
			glDisable(GL_DEPTH_TEST);
			glDisable(GL_STENCIL_TEST);

			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));

			glEnable(GL_DEPTH_TEST);
			glEnable(GL_STENCIL_TEST);
		}

		if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
		{
			// Depth was not preserved.
			glDepthFunc(GL_ALWAYS);
		}

		if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0)
		{
			// Stencil was preserved.
			glStencilFunc(GL_EQUAL, 1, 0xff);
		}

		glEnable		(GL_BLEND);
		glBlendFunc		(GL_ONE, GL_ONE);
		glBlendEquation	(GL_FUNC_ADD);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));

		readPixels(dst, 0, 0, quadSizePixels.x(), quadSizePixels.y());
	}

private:
	deUint32	m_colorFmt;
	deUint32	m_depthStencilFmt;
	int			m_numSamples;
	deUint32	m_invalidateBuffers;
};

class InvalidateFboTargetCase : public FboTestCase
{
public:
	InvalidateFboTargetCase (Context& context, const char* name, const char* description, deUint32 boundTarget, deUint32 invalidateTarget, const deUint32* invalidateAttachments, int numAttachments)
		: FboTestCase				(context, name, description)
		, m_boundTarget				(boundTarget)
		, m_invalidateTarget		(invalidateTarget)
		, m_invalidateAttachments	(invalidateAttachments, invalidateAttachments+numAttachments)
	{
	}

protected:
	void render (tcu::Surface& dst)
	{
		const deUint32					colorFormat				= GL_RGBA8;
		const deUint32					depthStencilFormat		= GL_DEPTH24_STENCIL8;
		const tcu::TextureFormat		colorFmt				= glu::mapGLInternalFormat(colorFormat);
		const tcu::TextureFormatInfo	colorFmtInfo			= tcu::getTextureFormatInfo(colorFmt);
		const tcu::Vec4&				cBias					= colorFmtInfo.valueMin;
		const tcu::Vec4					cScale					= colorFmtInfo.valueMax-colorFmtInfo.valueMin;
		const bool						isDiscarded				= (m_boundTarget == GL_FRAMEBUFFER) ||
																  (m_invalidateTarget == GL_FRAMEBUFFER && m_boundTarget == GL_DRAW_FRAMEBUFFER) ||
																  (m_invalidateTarget == m_boundTarget);
		const bool						isColorDiscarded		= isDiscarded && hasAttachment(m_invalidateAttachments, GL_COLOR_ATTACHMENT0);
		const bool						isDepthDiscarded		= isDiscarded && (hasAttachment(m_invalidateAttachments, GL_DEPTH_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT));
		const bool						isStencilDiscarded		= isDiscarded && (hasAttachment(m_invalidateAttachments, GL_STENCIL_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT));

		deUint32						fbo						= 0;
		deUint32						colorRbo				= 0;
		deUint32						depthStencilRbo			= 0;
		FlatColorShader					flatShader				(glu::TYPE_FLOAT_VEC4);
		deUint32						flatShaderID			= getCurrentContext()->createProgram(&flatShader);

		// Create fbo.
		glGenRenderbuffers		(1, &colorRbo);
		glBindRenderbuffer		(GL_RENDERBUFFER, colorRbo);
		glRenderbufferStorage	(GL_RENDERBUFFER, colorFormat, getWidth(), getHeight());

		glGenRenderbuffers		(1, &depthStencilRbo);
		glBindRenderbuffer		(GL_RENDERBUFFER, depthStencilRbo);
		glRenderbufferStorage	(GL_RENDERBUFFER, depthStencilFormat, getWidth(), getHeight());

		glGenFramebuffers			(1, &fbo);
		glBindFramebuffer			(GL_FRAMEBUFFER, fbo);
		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);

		checkFramebufferStatus		(GL_FRAMEBUFFER);

		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		glEnable		(GL_DEPTH_TEST);
		glEnable		(GL_STENCIL_TEST);
		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc	(GL_ALWAYS, 1, 0xff);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias);
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));

		// Bound FBO to test target and default to other
		if (m_boundTarget != GL_FRAMEBUFFER)
		{
			// Dummy fbo is used as complemeting target (read when discarding draw for example).
			// \note Framework takes care of deleting objects at the end of test case.
			const deUint32	dummyTarget		= m_boundTarget == GL_DRAW_FRAMEBUFFER ?  GL_READ_FRAMEBUFFER : GL_DRAW_FRAMEBUFFER;
			deUint32		dummyFbo		= 0;
			deUint32		dummyColorRbo	= 0;

			glGenRenderbuffers			(1, &dummyColorRbo);
			glBindRenderbuffer			(GL_RENDERBUFFER, dummyColorRbo);
			glRenderbufferStorage		(GL_RENDERBUFFER, GL_RGBA8, 64, 64);
			glGenFramebuffers			(1, &dummyFbo);
			glBindFramebuffer			(dummyTarget, dummyFbo);
			glFramebufferRenderbuffer	(dummyTarget, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, dummyColorRbo);

			glBindFramebuffer			(m_boundTarget, fbo);
		}

		glInvalidateFramebuffer(m_invalidateTarget, (int)m_invalidateAttachments.size(), m_invalidateAttachments.empty() ? DE_NULL : &m_invalidateAttachments[0]);

		if (m_boundTarget != GL_FRAMEBUFFER)
			glBindFramebuffer(GL_FRAMEBUFFER, fbo);

		if (isColorDiscarded)
		{
			// Color was not preserved - fill with green.
			glDisable(GL_DEPTH_TEST);
			glDisable(GL_STENCIL_TEST);

			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias);
			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

			glEnable(GL_DEPTH_TEST);
			glEnable(GL_STENCIL_TEST);
		}

		if (isDepthDiscarded)
		{
			// Depth was not preserved.
			glDepthFunc(GL_ALWAYS);
		}

		if (!isStencilDiscarded)
		{
			// Stencil was preserved.
			glStencilFunc(GL_EQUAL, 1, 0xff);
		}

		glEnable		(GL_BLEND);
		glBlendFunc		(GL_ONE, GL_ONE);
		glBlendEquation	(GL_FUNC_ADD);

		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias);
		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));

		readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
	}

private:
	deUint32				m_boundTarget;
	deUint32				m_invalidateTarget;
	std::vector<deUint32>	m_invalidateAttachments;
};

FboInvalidateTests::FboInvalidateTests (Context& context)
	: TestCaseGroup(context, "invalidate", "Framebuffer invalidate tests")
{
}

FboInvalidateTests::~FboInvalidateTests (void)
{
}

void FboInvalidateTests::init (void)
{
	// invalidate.default.
	{
		tcu::TestCaseGroup* defaultFbGroup = new tcu::TestCaseGroup(m_testCtx, "default", "Default framebuffer invalidate tests");
		addChild(defaultFbGroup);

		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_none",				"Invalidating no framebuffers (ref)",						0));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_color",				"Rendering after invalidating colorbuffer",					GL_COLOR_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_depth",				"Rendering after invalidating depthbuffer",					GL_DEPTH_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_stencil",			"Rendering after invalidating stencilbuffer",				GL_STENCIL_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_depth_stencil",		"Rendering after invalidating depth- and stencilbuffers",	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_all",				"Rendering after invalidating all buffers",					GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));

		defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase		(m_context,	"bind_color",				"Binding fbo after invalidating colorbuffer",				GL_COLOR_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase		(m_context,	"bind_depth",				"Binding fbo after invalidating depthbuffer",				GL_DEPTH_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase		(m_context,	"bind_stencil",				"Binding fbo after invalidating stencilbuffer",				GL_STENCIL_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase		(m_context,	"bind_depth_stencil",		"Binding fbo after invalidating depth- and stencilbuffers",	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase		(m_context,	"bind_all",					"Binding fbo after invalidating all buffers",				GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));

		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase	(m_context,	"sub_render_color",			"Rendering after invalidating colorbuffer",					GL_COLOR_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase	(m_context,	"sub_render_depth",			"Rendering after invalidating depthbuffer",					GL_DEPTH_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase	(m_context,	"sub_render_stencil",		"Rendering after invalidating stencilbuffer",				GL_STENCIL_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase	(m_context,	"sub_render_depth_stencil",	"Rendering after invalidating depth- and stencilbuffers",	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase	(m_context,	"sub_render_all",			"Rendering after invalidating all buffers",					GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));

		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase	(m_context,	"sub_bind_color",			"Binding fbo after invalidating colorbuffer",				GL_COLOR_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase	(m_context,	"sub_bind_depth",			"Binding fbo after invalidating depthbuffer",				GL_DEPTH_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase	(m_context,	"sub_bind_stencil",			"Binding fbo after invalidating stencilbuffer",				GL_STENCIL_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase	(m_context,	"sub_bind_depth_stencil",	"Binding fbo after invalidating depth- and stencilbuffers",	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase	(m_context,	"sub_bind_all",				"Binding fbo after invalidating all buffers",				GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));

		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"draw_framebuffer_color",	"Invalidating GL_COLOR in GL_DRAW_FRAMEBUFFER",				GL_COLOR_BUFFER_BIT,											GL_DRAW_FRAMEBUFFER));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"draw_framebuffer_all",		"Invalidating all in GL_DRAW_FRAMEBUFFER",					GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT,	GL_DRAW_FRAMEBUFFER));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"read_framebuffer_color",	"Invalidating GL_COLOR in GL_READ_FRAMEBUFFER",				GL_COLOR_BUFFER_BIT,											GL_READ_FRAMEBUFFER));
		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"read_framebuffer_all",		"Invalidating all in GL_READ_FRAMEBUFFER",					GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT,	GL_READ_FRAMEBUFFER));
	}

	// invalidate.whole.
	{
		tcu::TestCaseGroup* wholeFboGroup = new tcu::TestCaseGroup(m_testCtx, "whole", "Invalidating whole framebuffer object");
		addChild(wholeFboGroup);

		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_none",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	0));
		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_color",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_depth",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_stencil",					"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_STENCIL_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_depth_stencil",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_all",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));

		wholeFboGroup->addChild(new InvalidateFboUnbindReadCase	(m_context, "unbind_read_color",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboUnbindReadCase	(m_context, "unbind_read_depth",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboUnbindReadCase	(m_context, "unbind_read_stencil",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_STENCIL_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboUnbindReadCase	(m_context, "unbind_read_depth_stencil",		"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboUnbindReadCase	(m_context, "unbind_read_color_stencil",		"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));

		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_color",				"",		0,	GL_COLOR_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_depth",				"",		0,	GL_DEPTH_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_stencil",				"",		0,	GL_STENCIL_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_depth_stencil",		"",		0,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));

		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_msaa_color",			"",		4,	GL_COLOR_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_msaa_depth",			"",		4,	GL_DEPTH_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_msaa_stencil",			"",		4,	GL_STENCIL_BUFFER_BIT));
		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_msaa_depth_stencil",	"",		4,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
	}

	// invalidate.sub.
	{
		tcu::TestCaseGroup* subFboGroup = new tcu::TestCaseGroup(m_testCtx, "sub", "Invalidating subsection of framebuffer object");
		addChild(subFboGroup);

		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_none",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	0));
		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_color",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_depth",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_stencil",					"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_STENCIL_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_depth_stencil",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_all",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));

		subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_color",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_depth",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_stencil",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_STENCIL_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_depth_stencil",		"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_color_stencil",		"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));

		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_color",				"",		0,	GL_COLOR_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_depth",				"",		0,	GL_DEPTH_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_stencil",				"",		0,	GL_STENCIL_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_depth_stencil",		"",		0,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));

		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_color",			"",		4,	GL_COLOR_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_depth",			"",		4,	GL_DEPTH_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_stencil",			"",		4,	GL_STENCIL_BUFFER_BIT));
		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_depth_stencil",	"",		4,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
	}

	// invalidate.format.
	{
		tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "Invalidating framebuffers with selected formats");
		addChild(formatGroup);

		// Color buffer formats.
		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
		};

		// Depth/stencilbuffer formats.
		static const deUint32 depthStencilFormats[] =
		{
			GL_DEPTH_COMPONENT32F,
			GL_DEPTH_COMPONENT24,
			GL_DEPTH_COMPONENT16,
			GL_DEPTH32F_STENCIL8,
			GL_DEPTH24_STENCIL8,
			GL_STENCIL_INDEX8
		};

		// Colorbuffer tests use invalidate, unbind, read test.
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
			formatGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, getFormatName(colorFormats[ndx]), "", colorFormats[ndx], GL_NONE, GL_COLOR_BUFFER_BIT));

		// Depth/stencilbuffer tests use invalidate, render test.
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
			formatGroup->addChild(new InvalidateSubFboRenderCase(m_context, getFormatName(depthStencilFormats[ndx]), "", GL_RGBA8, depthStencilFormats[ndx], GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
	}

	// invalidate.target
	{
		tcu::TestCaseGroup* targetGroup = new tcu::TestCaseGroup(m_testCtx, "target", "Invalidate target");
		addChild(targetGroup);

		static const struct
		{
			const char*		name;
			deUint32		invalidateTarget;
			deUint32		boundTarget;
		} s_targetCases[] =
		{
			{ "framebuffer_framebuffer",			GL_FRAMEBUFFER,			GL_FRAMEBUFFER		},
			{ "framebuffer_read_framebuffer",		GL_FRAMEBUFFER,			GL_READ_FRAMEBUFFER },
			{ "framebuffer_draw_framebuffer",		GL_FRAMEBUFFER,			GL_DRAW_FRAMEBUFFER },
			{ "read_framebuffer_framebuffer",		GL_READ_FRAMEBUFFER,	GL_FRAMEBUFFER		},
			{ "read_framebuffer_read_framebuffer",	GL_READ_FRAMEBUFFER,	GL_READ_FRAMEBUFFER },
			{ "read_framebuffer_draw_framebuffer",	GL_READ_FRAMEBUFFER,	GL_DRAW_FRAMEBUFFER },
			{ "draw_framebuffer_framebuffer",		GL_DRAW_FRAMEBUFFER,	GL_FRAMEBUFFER		},
			{ "draw_framebuffer_read_framebuffer",	GL_DRAW_FRAMEBUFFER,	GL_READ_FRAMEBUFFER },
			{ "draw_framebuffer_draw_framebuffer",	GL_DRAW_FRAMEBUFFER,	GL_DRAW_FRAMEBUFFER },
		};

		static const deUint32 colorAttachment[]			= { GL_COLOR_ATTACHMENT0 };
		static const deUint32 depthStencilAttachment[]	= { GL_DEPTH_STENCIL_ATTACHMENT };
		static const deUint32 allAttachments[]			= { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };

		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_targetCases); caseNdx++)
		{
			const std::string	baseName		= s_targetCases[caseNdx].name;
			const deUint32		invalidateT		= s_targetCases[caseNdx].invalidateTarget;
			const deUint32		boundT			= s_targetCases[caseNdx].boundTarget;

			targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_color").c_str(),			"",	boundT, invalidateT, &colorAttachment[0],			DE_LENGTH_OF_ARRAY(colorAttachment)));
			targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_depth_stencil").c_str(),	"",	boundT, invalidateT, &depthStencilAttachment[0],	DE_LENGTH_OF_ARRAY(depthStencilAttachment)));
			targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_all").c_str(),			"",	boundT, invalidateT, &allAttachments[0],			DE_LENGTH_OF_ARRAY(allAttachments)));
		}
	}
}

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