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

#include "es3fFramebufferBlitTests.hpp"
#include "es3fFboTestCase.hpp"
#include "es3fFboTestUtil.hpp"
#include "gluTextureUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "sglrContextUtil.hpp"
#include "glwEnums.hpp"
#include "deStringUtil.hpp"

namespace deqp
{
namespace gles3
{
namespace Functional
{

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

class BlitRectCase : public FboTestCase
{
public:
	BlitRectCase (Context& context, const char* name, const char* desc, deUint32 filter, const IVec2& srcSize, const IVec4& srcRect, const IVec2& dstSize, const IVec4& dstRect, int cellSize = 8)
		: FboTestCase		(context, name, desc)
		, m_filter			(filter)
		, m_srcSize			(srcSize)
		, m_srcRect			(srcRect)
		, m_dstSize			(dstSize)
		, m_dstRect			(dstRect)
		, m_cellSize		(cellSize)
		, m_gridCellColorA	(0.2f, 0.7f, 0.1f, 1.0f)
		, m_gridCellColorB	(0.7f, 0.1f, 0.5f, 0.8f)
	{
	}

	void render (tcu::Surface& dst)
	{
		const deUint32			colorFormat		= GL_RGBA8;

		GradientShader			gradShader		(glu::TYPE_FLOAT_VEC4);
		Texture2DShader			texShader		(DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
		deUint32				gradShaderID	= getCurrentContext()->createProgram(&gradShader);
		deUint32				texShaderID		= getCurrentContext()->createProgram(&texShader);

		deUint32				srcFbo, dstFbo;
		deUint32				srcRbo, dstRbo;

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

		// Create framebuffers.
		for (int ndx = 0; ndx < 2; ndx++)
		{
			deUint32&		fbo		= ndx ? dstFbo : srcFbo;
			deUint32&		rbo		= ndx ? dstRbo : srcRbo;
			const IVec2&	size	= ndx ? m_dstSize : m_srcSize;

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

			glBindRenderbuffer(GL_RENDERBUFFER, rbo);
			glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, size.x(), size.y());

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

		// Fill destination with gradient.
		glBindFramebuffer(GL_FRAMEBUFFER, dstFbo);
		glViewport(0, 0, m_dstSize.x(), m_dstSize.y());

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

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

			tcu::fillWithGrid(data.getAccess(), m_cellSize, m_gridCellColorA, m_gridCellColorB);

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

			glBindFramebuffer(GL_FRAMEBUFFER, srcFbo);
			glViewport(0, 0, m_srcSize.x(), m_srcSize.y());
			sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		}

		// Perform copy.
		glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFbo);
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFbo);
		glBlitFramebuffer(m_srcRect.x(), m_srcRect.y(), m_srcRect.z(), m_srcRect.w(), m_dstRect.x(), m_dstRect.y(), m_dstRect.z(), m_dstRect.w(), GL_COLOR_BUFFER_BIT, m_filter);

		// Read back results.
		glBindFramebuffer(GL_READ_FRAMEBUFFER, dstFbo);
		readPixels(dst, 0, 0, m_dstSize.x(), m_dstSize.y(), glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
	}

	virtual bool compare (const tcu::Surface& reference, const tcu::Surface& result)
	{
		// Use pixel-threshold compare for rect cases since 1px off will mean failure.
		tcu::RGBA threshold = TestCase::m_context.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(7,7,7,7);
		return tcu::pixelThresholdCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference, result, threshold, tcu::COMPARE_LOG_RESULT);
	}

protected:
	const deUint32	m_filter;
	const IVec2		m_srcSize;
	const IVec4		m_srcRect;
	const IVec2		m_dstSize;
	const IVec4		m_dstRect;
	const int		m_cellSize;
	const Vec4		m_gridCellColorA;
	const Vec4		m_gridCellColorB;
};

class BlitNearestFilterConsistencyCase : public BlitRectCase
{
public:
			BlitNearestFilterConsistencyCase	(Context& context, const char* name, const char* desc, const IVec2& srcSize, const IVec4& srcRect, const IVec2& dstSize, const IVec4& dstRect);

	bool	compare								(const tcu::Surface& reference, const tcu::Surface& result);
};

BlitNearestFilterConsistencyCase::BlitNearestFilterConsistencyCase (Context& context, const char* name, const char* desc, const IVec2& srcSize, const IVec4& srcRect, const IVec2& dstSize, const IVec4& dstRect)
	: BlitRectCase(context, name, desc, GL_NEAREST, srcSize, srcRect, dstSize, dstRect, 1)
{
}

bool BlitNearestFilterConsistencyCase::compare (const tcu::Surface& reference, const tcu::Surface& result)
{
	DE_ASSERT(reference.getWidth() == result.getWidth());
	DE_ASSERT(reference.getHeight() == result.getHeight());
	DE_UNREF(reference);

	// Image origin must be visible (for baseColor)
	DE_ASSERT(de::min(m_dstRect.x(), m_dstRect.z()) >= 0);
	DE_ASSERT(de::min(m_dstRect.y(), m_dstRect.w()) >= 0);

	const tcu::RGBA		cellColorA		(m_gridCellColorA);
	const tcu::RGBA		cellColorB		(m_gridCellColorB);
	const tcu::RGBA		threshold		= TestCase::m_context.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(7,7,7,7);
	const tcu::IVec4	destinationArea	= tcu::IVec4(de::clamp(de::min(m_dstRect.x(), m_dstRect.z()), 0, result.getWidth()),
													 de::clamp(de::min(m_dstRect.y(), m_dstRect.w()), 0, result.getHeight()),
													 de::clamp(de::max(m_dstRect.x(), m_dstRect.z()), 0, result.getWidth()),
													 de::clamp(de::max(m_dstRect.y(), m_dstRect.w()), 0, result.getHeight()));
	const tcu::RGBA		baseColor		= result.getPixel(destinationArea.x(), destinationArea.y());
	const bool			signConfig		= tcu::compareThreshold(baseColor, cellColorA, threshold);

	bool				error			= false;
	tcu::Surface		errorMask		(result.getWidth(), result.getHeight());
	std::vector<bool>	horisontalSign	(destinationArea.z() - destinationArea.x());
	std::vector<bool>	verticalSign	(destinationArea.w() - destinationArea.y());

	tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));

	// Checking only area in our destination rect

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Verifying consistency of NEAREST filtering. Verifying rect " << m_dstRect << ".\n"
		<< "Rounding direction of the NEAREST filter at the horisontal texel edge (x = n + 0.5) should not depend on the y-coordinate.\n"
		<< "Rounding direction of the NEAREST filter at the vertical texel edge (y = n + 0.5) should not depend on the x-coordinate.\n"
		<< "Blitting a grid (with uniform sized cells) should result in a grid (with non-uniform sized cells)."
		<< tcu::TestLog::EndMessage;

	// Verify that destination only contains valid colors

	for (int dy = 0; dy < destinationArea.w() - destinationArea.y(); ++dy)
	for (int dx = 0; dx < destinationArea.z() - destinationArea.x(); ++dx)
	{
		const tcu::RGBA	color	= result.getPixel(destinationArea.x() + dx, destinationArea.y() + dy);
		const bool isValidColor = tcu::compareThreshold(color, cellColorA, threshold) || tcu::compareThreshold(color, cellColorB, threshold);

		if (!isValidColor)
		{
			errorMask.setPixel(destinationArea.x() + dx, destinationArea.y() + dy, tcu::RGBA::red());
			error = true;
		}
	}
	if (error)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image verification failed, destination rect contains unexpected values. "
			<< "Expected either " << cellColorA << " or " << cellColorB << "."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Result", "Image verification result")
			<< tcu::TestLog::Image("Result",	"Result",		result)
			<< tcu::TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< tcu::TestLog::EndImageSet;
		return false;
	}

	// Detect result edges by reading the first row and first column of the blitted area.
	// Blitting a grid should result in a grid-like image. ("sign changes" should be consistent)

	for (int dx = 0; dx < destinationArea.z() - destinationArea.x(); ++dx)
	{
		const tcu::RGBA color = result.getPixel(destinationArea.x() + dx, destinationArea.y());

		if (tcu::compareThreshold(color, cellColorA, threshold))
			horisontalSign[dx] = true;
		else if (tcu::compareThreshold(color, cellColorB, threshold))
			horisontalSign[dx] = false;
		else
			DE_ASSERT(DE_FALSE);
	}
	for (int dy = 0; dy < destinationArea.w() - destinationArea.y(); ++dy)
	{
		const tcu::RGBA color = result.getPixel(destinationArea.x(), destinationArea.y() + dy);

		if (tcu::compareThreshold(color, cellColorA, threshold))
			verticalSign[dy] = true;
		else if (tcu::compareThreshold(color, cellColorB, threshold))
			verticalSign[dy] = false;
		else
			DE_ASSERT(DE_FALSE);
	}

	// Verify grid-like image

	for (int dy = 0; dy < destinationArea.w() - destinationArea.y(); ++dy)
	for (int dx = 0; dx < destinationArea.z() - destinationArea.x(); ++dx)
	{
		const tcu::RGBA	color		= result.getPixel(destinationArea.x() + dx, destinationArea.y() + dy);
		const bool		resultSign	= tcu::compareThreshold(cellColorA, color, threshold);
		const bool		correctSign	= (horisontalSign[dx] == verticalSign[dy]) == signConfig;

		if (resultSign != correctSign)
		{
			errorMask.setPixel(destinationArea.x() + dx, destinationArea.y() + dy, tcu::RGBA::red());
			error = true;
		}
	}

	// Report result

	if (error)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image verification failed, nearest filter is not consistent."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Result", "Image verification result")
			<< tcu::TestLog::Image("Result",	"Result",		result)
			<< tcu::TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< tcu::TestLog::EndImageSet;
	}
	else
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Image verification passed."
			<< tcu::TestLog::EndMessage
			<< tcu::TestLog::ImageSet("Result", "Image verification result")
			<< tcu::TestLog::Image("Result", "Result", result)
			<< tcu::TestLog::EndImageSet;
	}

	return !error;
}

static tcu::BVec4 getChannelMask (tcu::TextureFormat::ChannelOrder order)
{
	switch (order)
	{
		case tcu::TextureFormat::R:		return tcu::BVec4(true,	false,	false,	false);
		case tcu::TextureFormat::RG:	return tcu::BVec4(true,	true,	false,	false);
		case tcu::TextureFormat::RGB:	return tcu::BVec4(true,	true,	true,	false);
		case tcu::TextureFormat::RGBA:	return tcu::BVec4(true,	true,	true,	true);
		case tcu::TextureFormat::sRGB:	return tcu::BVec4(true,	true,	true,	false);
		case tcu::TextureFormat::sRGBA:	return tcu::BVec4(true,	true,	true,	true);
		default:
			DE_ASSERT(false);
			return tcu::BVec4(false);
	}
}

class BlitColorConversionCase : public FboTestCase
{
public:
	BlitColorConversionCase (Context& context, const char* name, const char* desc, deUint32 srcFormat, deUint32 dstFormat, const IVec2& size)
		: FboTestCase	(context, name, desc)
		, m_srcFormat	(srcFormat)
		, m_dstFormat	(dstFormat)
		, m_size		(size)
	{
	}

protected:
	void preCheck (void)
	{
		checkFormatSupport(m_srcFormat);
		checkFormatSupport(m_dstFormat);
	}

	void render (tcu::Surface& dst)
	{
		tcu::TextureFormat		srcFormat			= glu::mapGLInternalFormat(m_srcFormat);
		tcu::TextureFormat		dstFormat			= glu::mapGLInternalFormat(m_dstFormat);
		glu::DataType			srcOutputType		= getFragmentOutputType(srcFormat);
		glu::DataType			dstOutputType		= getFragmentOutputType(dstFormat);

		// Compute ranges \note Doesn't handle case where src or dest is not subset of the another!
		tcu::TextureFormatInfo	srcFmtRangeInfo		= tcu::getTextureFormatInfo(srcFormat);
		tcu::TextureFormatInfo	dstFmtRangeInfo		= tcu::getTextureFormatInfo(dstFormat);
		tcu::BVec4				copyMask			= tcu::logicalAnd(getChannelMask(srcFormat.order), getChannelMask(dstFormat.order));
		tcu::BVec4				srcIsGreater		= tcu::greaterThan(srcFmtRangeInfo.valueMax-srcFmtRangeInfo.valueMin, dstFmtRangeInfo.valueMax-dstFmtRangeInfo.valueMin);
		tcu::TextureFormatInfo	srcRangeInfo		(tcu::select(dstFmtRangeInfo.valueMin,		srcFmtRangeInfo.valueMin,		tcu::logicalAnd(copyMask, srcIsGreater)),
													 tcu::select(dstFmtRangeInfo.valueMax,		srcFmtRangeInfo.valueMax,		tcu::logicalAnd(copyMask, srcIsGreater)),
													 tcu::select(dstFmtRangeInfo.lookupScale,	srcFmtRangeInfo.lookupScale,	tcu::logicalAnd(copyMask, srcIsGreater)),
													 tcu::select(dstFmtRangeInfo.lookupBias,	srcFmtRangeInfo.lookupBias,		tcu::logicalAnd(copyMask, srcIsGreater)));
		tcu::TextureFormatInfo	dstRangeInfo		(tcu::select(dstFmtRangeInfo.valueMin,		srcFmtRangeInfo.valueMin,		tcu::logicalOr(tcu::logicalNot(copyMask), srcIsGreater)),
													 tcu::select(dstFmtRangeInfo.valueMax,		srcFmtRangeInfo.valueMax,		tcu::logicalOr(tcu::logicalNot(copyMask), srcIsGreater)),
													 tcu::select(dstFmtRangeInfo.lookupScale,	srcFmtRangeInfo.lookupScale,	tcu::logicalOr(tcu::logicalNot(copyMask), srcIsGreater)),
													 tcu::select(dstFmtRangeInfo.lookupBias,	srcFmtRangeInfo.lookupBias,		tcu::logicalOr(tcu::logicalNot(copyMask), srcIsGreater)));

		// Shaders.
		GradientShader			gradientToSrcShader	(srcOutputType);
		GradientShader			gradientToDstShader	(dstOutputType);

		deUint32				gradShaderSrcID		= getCurrentContext()->createProgram(&gradientToSrcShader);
		deUint32				gradShaderDstID		= getCurrentContext()->createProgram(&gradientToDstShader);

		deUint32				srcFbo, dstFbo;
		deUint32				srcRbo, dstRbo;

		// Create framebuffers.
		for (int ndx = 0; ndx < 2; ndx++)
		{
			deUint32&	fbo		= ndx ? dstFbo : srcFbo;
			deUint32&	rbo		= ndx ? dstRbo : srcRbo;
			deUint32	format	= ndx ? m_dstFormat : m_srcFormat;

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

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

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

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

		// Render gradients.
		for (int ndx = 0; ndx < 2; ndx++)
		{
			glBindFramebuffer(GL_FRAMEBUFFER, ndx ? dstFbo : srcFbo);

			if (ndx)
			{
				gradientToDstShader.setGradient(*getCurrentContext(), gradShaderDstID, dstRangeInfo.valueMax, dstRangeInfo.valueMin);
				sglr::drawQuad(*getCurrentContext(), gradShaderDstID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
			}
			else
			{
				gradientToSrcShader.setGradient(*getCurrentContext(), gradShaderSrcID, srcRangeInfo.valueMin, dstRangeInfo.valueMax);
				sglr::drawQuad(*getCurrentContext(), gradShaderSrcID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
			}
		}

		// Execute copy.
		glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFbo);
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFbo);
		glBlitFramebuffer(0, 0, m_size.x(), m_size.y(), 0, 0, m_size.x(), m_size.y(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
		checkError();

		// Read results.
		glBindFramebuffer(GL_READ_FRAMEBUFFER, dstFbo);
		readPixels(dst, 0, 0, m_size.x(), m_size.y(), dstFormat, dstRangeInfo.lookupScale, dstRangeInfo.lookupBias);
	}

	bool compare (const tcu::Surface& reference, const tcu::Surface& result)
	{
		const tcu::TextureFormat	srcFormat	= glu::mapGLInternalFormat(m_srcFormat);
		const tcu::TextureFormat	dstFormat	= glu::mapGLInternalFormat(m_dstFormat);
		const bool					srcIsSRGB	= tcu::isSRGB(srcFormat);
		const bool					dstIsSRGB	= tcu::isSRGB(dstFormat);

		tcu::RGBA					threshold;

		if (dstIsSRGB)
		{
			threshold = getToSRGBConversionThreshold(srcFormat, dstFormat);
		}
		else
		{
			const tcu::RGBA	srcMaxDiff	= getFormatThreshold(srcFormat) * (srcIsSRGB ? 2 : 1);
			const tcu::RGBA	dstMaxDiff	= getFormatThreshold(dstFormat);

			threshold = tcu::max(srcMaxDiff, dstMaxDiff);
		}

		m_testCtx.getLog() << tcu::TestLog::Message << "threshold = " << threshold << tcu::TestLog::EndMessage;
		return tcu::pixelThresholdCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference, result, threshold, tcu::COMPARE_LOG_RESULT);
	}

private:
	deUint32		m_srcFormat;
	deUint32		m_dstFormat;
	IVec2			m_size;
};

class BlitDepthStencilCase : public FboTestCase
{
public:
	BlitDepthStencilCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 srcBuffers, const IVec2& srcSize, const IVec4& srcRect, deUint32 dstBuffers, const IVec2& dstSize, const IVec4& dstRect, deUint32 copyBuffers)
		: FboTestCase	(context, name, desc)
		, m_format		(format)
		, m_srcBuffers	(srcBuffers)
		, m_srcSize		(srcSize)
		, m_srcRect		(srcRect)
		, m_dstBuffers	(dstBuffers)
		, m_dstSize		(dstSize)
		, m_dstRect		(dstRect)
		, m_copyBuffers	(copyBuffers)
	{
	}

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

	void render (tcu::Surface& dst)
	{
		const deUint32			colorFormat			= GL_RGBA8;

		GradientShader			gradShader			(glu::TYPE_FLOAT_VEC4);
		Texture2DShader			texShader			(DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
		FlatColorShader			flatShader			(glu::TYPE_FLOAT_VEC4);

		deUint32				flatShaderID		= getCurrentContext()->createProgram(&flatShader);
		deUint32				texShaderID			= getCurrentContext()->createProgram(&texShader);
		deUint32				gradShaderID		= getCurrentContext()->createProgram(&gradShader);

		deUint32				srcFbo				= 0;
		deUint32				dstFbo				= 0;
		deUint32				srcColorRbo			= 0;
		deUint32				dstColorRbo			= 0;
		deUint32				srcDepthStencilRbo	= 0;
		deUint32				dstDepthStencilRbo	= 0;

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

		// Create framebuffers.
		for (int ndx = 0; ndx < 2; ndx++)
		{
			deUint32&		fbo				= ndx ? dstFbo : srcFbo;
			deUint32&		colorRbo		= ndx ? dstColorRbo : srcColorRbo;
			deUint32&		depthStencilRbo	= ndx ? dstDepthStencilRbo : srcDepthStencilRbo;
			deUint32		bufs			= ndx ? m_dstBuffers : m_srcBuffers;
			const IVec2&	size			= ndx ? m_dstSize : m_srcSize;

			glGenFramebuffers(1, &fbo);
			glGenRenderbuffers(1, &colorRbo);
			glGenRenderbuffers(1, &depthStencilRbo);

			glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
			glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, size.x(), size.y());

			glBindRenderbuffer(GL_RENDERBUFFER, depthStencilRbo);
			glRenderbufferStorage(GL_RENDERBUFFER, m_format, size.x(), size.y());

			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);

			if (bufs & GL_DEPTH_BUFFER_BIT)
				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
			if (bufs & GL_STENCIL_BUFFER_BIT)
				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);

			checkError();
			checkFramebufferStatus(GL_FRAMEBUFFER);

			// Clear depth to 1 and stencil to 0.
			glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);
		}

		// Fill source with gradient, depth = [-1..1], stencil = 7
		glBindFramebuffer(GL_FRAMEBUFFER, srcFbo);
		glViewport(0, 0, m_srcSize.x(), m_srcSize.y());
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_STENCIL_TEST);
		glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
		glStencilFunc(GL_ALWAYS, 7, 0xffu);

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

		// Fill destination with grid pattern, depth = 0 and stencil = 1
		{
			const deUint32		format		= GL_RGBA;
			const deUint32		dataType	= GL_UNSIGNED_BYTE;
			const int			texW		= m_srcSize.x();
			const int			texH		= m_srcSize.y();
			deUint32			gridTex		= 0;
			tcu::TextureLevel	data		(glu::mapGLTransferFormat(format, dataType), texW, texH, 1);

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

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

			glBindFramebuffer(GL_FRAMEBUFFER, dstFbo);
			glViewport(0, 0, m_dstSize.x(), m_dstSize.y());
			glStencilFunc(GL_ALWAYS, 1, 0xffu);
			sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
		}

		// Perform copy.
		glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFbo);
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFbo);
		glBlitFramebuffer(m_srcRect.x(), m_srcRect.y(), m_srcRect.z(), m_srcRect.w(), m_dstRect.x(), m_dstRect.y(), m_dstRect.z(), m_dstRect.w(), m_copyBuffers, GL_NEAREST);

		// Render blue color where depth < 0, decrement on depth failure.
		glBindFramebuffer(GL_FRAMEBUFFER, dstFbo);
		glViewport(0, 0, m_dstSize.x(), m_dstSize.y());
		glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
		glStencilFunc(GL_ALWAYS, 0, 0xffu);

		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));

		if (m_dstBuffers & GL_STENCIL_BUFFER_BIT)
		{
			// Render green color where stencil == 6.
			glDisable(GL_DEPTH_TEST);
			glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
			glStencilFunc(GL_EQUAL, 6, 0xffu);

			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));
		}

		readPixels(dst, 0, 0, m_dstSize.x(), m_dstSize.y(), glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
	}

private:
	deUint32	m_format;
	deUint32	m_srcBuffers;
	IVec2		m_srcSize;
	IVec4		m_srcRect;
	deUint32	m_dstBuffers;
	IVec2		m_dstSize;
	IVec4		m_dstRect;
	deUint32	m_copyBuffers;
};

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

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

		checkFormatSupport(m_format);
	}

	virtual void render (tcu::Surface& dst)
	{
		tcu::TextureFormat		colorFormat		= glu::mapGLInternalFormat(m_format);
		glu::TransferFormat		transferFmt		= glu::getTransferFormat(colorFormat);
		GradientShader			gradShader		(glu::TYPE_FLOAT_VEC4);
		Texture2DShader			texShader		(DataTypes() << glu::getSampler2DType(colorFormat), glu::TYPE_FLOAT_VEC4);
		deUint32				gradShaderID	= getCurrentContext()->createProgram(&gradShader);
		deUint32				texShaderID		= getCurrentContext()->createProgram(&texShader);
		deUint32				fbo				= 0;
		deUint32				tex				= 0;
		const int				texW			= 128;
		const int				texH			= 128;

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

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

		glBindTexture(GL_TEXTURE_2D, tex);
		glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	m_filter);
		glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	m_filter);
		glTexImage2D(GL_TEXTURE_2D, 0, m_format, texW, texH, 0, transferFmt.format, transferFmt.dataType, DE_NULL);

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

		// Render gradient to screen.
		glBindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());

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

		// Blit gradient from screen to fbo.
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
		glBlitFramebuffer(0, 0, getWidth(), getHeight(), 0, 0, texW, texH, GL_COLOR_BUFFER_BIT, m_filter);

		// Fill left half of viewport with quad that uses texture.
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
		glClearBufferfv(GL_COLOR, 0, Vec4(1.0f, 0.0f, 0.0f, 1.0f).getPtr());
		sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(0.0f, 1.0f, 0.0f));

		// Blit fbo to right half.
		glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
		glBlitFramebuffer(0, 0, texW, texH, getWidth()/2, 0, getWidth(), getHeight(), GL_COLOR_BUFFER_BIT, m_filter);

		glBindFramebuffer(GL_READ_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
		readPixels(dst, 0, 0, getWidth(), getHeight());
	}

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

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

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

protected:
	const deUint32	m_format;
	const deUint32	m_filter;
};

class DefaultFramebufferBlitCase : public BlitDefaultFramebufferCase
{
public:
	enum BlitDirection
	{
		BLIT_DEFAULT_TO_TARGET,
		BLIT_TO_DEFAULT_FROM_TARGET,

		BLIT_LAST
	};
	enum BlitArea
	{
		AREA_SCALE,
		AREA_OUT_OF_BOUNDS,

		AREA_LAST
	};

	DefaultFramebufferBlitCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 filter, BlitDirection dir, BlitArea area)
		: BlitDefaultFramebufferCase	(context, name, desc, format, filter)
		, m_blitDir						(dir)
		, m_blitArea					(area)
		, m_srcRect						(-1, -1, -1, -1)
		, m_dstRect						(-1, -1, -1, -1)
		, m_interestingArea				(-1, -1, -1, -1)
	{
		DE_ASSERT(dir < BLIT_LAST);
		DE_ASSERT(area < AREA_LAST);
	}

	void init (void)
	{
		// requirements
		const int minViewportSize = 128;
		if (m_context.getRenderTarget().getWidth() < minViewportSize || m_context.getRenderTarget().getHeight() < minViewportSize)
			throw tcu::NotSupportedError("Viewport size " + de::toString(minViewportSize) + "x" + de::toString(minViewportSize) + " required");

		// prevent viewport randoming
		m_viewportWidth = m_context.getRenderTarget().getWidth();
		m_viewportHeight = m_context.getRenderTarget().getHeight();

		// set proper areas
		if (m_blitArea == AREA_SCALE)
		{
			m_srcRect = IVec4( 10,  20,  65, 100);
			m_dstRect = IVec4( 25,  30, 125,  94);
			m_interestingArea = IVec4(0, 0, 128, 128);
		}
		else if (m_blitArea == AREA_OUT_OF_BOUNDS)
		{
			const tcu::IVec2 ubound = (m_blitDir == BLIT_DEFAULT_TO_TARGET) ? (tcu::IVec2(128, 128)) : (tcu::IVec2(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight()));

			m_srcRect = IVec4(-10, -15, 100,  63);
			m_dstRect = ubound.swizzle(0, 1, 0, 1) + IVec4(-75, -99, 8, 16);
			m_interestingArea = IVec4(ubound.x() - 128, ubound.y() - 128, ubound.x(), ubound.y());
		}
		else
			DE_ASSERT(false);
	}

	void render (tcu::Surface& dst)
	{
		const tcu::TextureFormat		colorFormat		= glu::mapGLInternalFormat(m_format);
		const glu::TransferFormat		transferFmt		= glu::getTransferFormat(colorFormat);
		const tcu::TextureChannelClass	targetClass		= (m_blitDir == BLIT_DEFAULT_TO_TARGET) ? (tcu::getTextureChannelClass(colorFormat.type)) : (tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT);
		deUint32						fbo				= 0;
		deUint32						fboTex			= 0;
		const int						fboTexW			= 128;
		const int						fboTexH			= 128;
		const int						sourceWidth		= (m_blitDir == BLIT_DEFAULT_TO_TARGET) ? (getWidth()) : (fboTexW);
		const int						sourceHeight	= (m_blitDir == BLIT_DEFAULT_TO_TARGET) ? (getHeight()) : (fboTexH);
		const int						gridRenderWidth	= de::min(256, sourceWidth);
		const int						gridRenderHeight= de::min(256, sourceHeight);

		int								targetFbo		= -1;
		int								sourceFbo		= -1;

		// FBO
		glGenFramebuffers(1, &fbo);
		glGenTextures(1, &fboTex);

		glBindTexture(GL_TEXTURE_2D, fboTex);
		glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	m_filter);
		glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	m_filter);
		glTexImage2D(GL_TEXTURE_2D, 0, m_format, fboTexW, fboTexH, 0, transferFmt.format, transferFmt.dataType, DE_NULL);

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

		targetFbo = (m_blitDir == BLIT_DEFAULT_TO_TARGET) ? (fbo) : (m_context.getRenderContext().getDefaultFramebuffer());
		sourceFbo = (m_blitDir == BLIT_DEFAULT_TO_TARGET) ? (m_context.getRenderContext().getDefaultFramebuffer()) : (fbo);

		// Render grid to source framebuffer
		{
			Texture2DShader		texShader		(DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
			const deUint32		texShaderID		= getCurrentContext()->createProgram(&texShader);
			const deUint32		internalFormat	= GL_RGBA8;
			const deUint32		format			= GL_RGBA;
			const deUint32		dataType		= GL_UNSIGNED_BYTE;
			const int			gridTexW		= 128;
			const int			gridTexH		= 128;
			deUint32			gridTex			= 0;
			tcu::TextureLevel	data			(glu::mapGLTransferFormat(format, dataType), gridTexW, gridTexH, 1);

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

			glGenTextures(1, &gridTex);
			glBindTexture(GL_TEXTURE_2D, gridTex);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
			glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, gridTexW, gridTexH, 0, format, dataType, data.getAccess().getDataPtr());

			glBindFramebuffer(GL_FRAMEBUFFER, sourceFbo);
			glViewport(0, 0, gridRenderWidth, gridRenderHeight);
			glClearBufferfv(GL_COLOR, 0, Vec4(1.0f, 0.0f, 0.0f, 1.0f).getPtr());

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

		// Blit source framebuffer to destination

		glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFbo);
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFbo);
		checkError();

		if (targetClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT || targetClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT || targetClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
			glClearBufferfv(GL_COLOR, 0, Vec4(1.0f, 1.0f, 0.0f, 1.0f).getPtr());
		else if (targetClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
			glClearBufferiv(GL_COLOR, 0, IVec4(0, 0, 0, 0).getPtr());
		else if (targetClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
			glClearBufferuiv(GL_COLOR, 0, UVec4(0, 0, 0, 0).getPtr());
		else
			DE_ASSERT(false);

		glBlitFramebuffer(m_srcRect.x(), m_srcRect.y(), m_srcRect.z(), m_srcRect.w(), m_dstRect.x(), m_dstRect.y(), m_dstRect.z(), m_dstRect.w(), GL_COLOR_BUFFER_BIT, m_filter);
		checkError();

		// Read target

		glBindFramebuffer(GL_FRAMEBUFFER, targetFbo);

		if (m_blitDir == BLIT_TO_DEFAULT_FROM_TARGET)
			readPixels(dst, m_interestingArea.x(), m_interestingArea.y(), m_interestingArea.z() - m_interestingArea.x(), m_interestingArea.w() - m_interestingArea.y());
		else
			readPixels(dst, m_interestingArea.x(), m_interestingArea.y(), m_interestingArea.z() - m_interestingArea.x(), m_interestingArea.w() - m_interestingArea.y(), colorFormat, tcu::Vec4(1.0f), tcu::Vec4(0.0f));

		checkError();
	}

private:
	const BlitDirection	m_blitDir;
	const BlitArea		m_blitArea;
	tcu::IVec4			m_srcRect;
	tcu::IVec4			m_dstRect;
	tcu::IVec4			m_interestingArea;
};

FramebufferBlitTests::FramebufferBlitTests (Context& context)
	: TestCaseGroup(context, "blit", "Framebuffer blit tests")
{
}

FramebufferBlitTests::~FramebufferBlitTests (void)
{
}

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

		// RGB formats
		GL_RGB8,
		GL_RGB565,

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

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

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

	static const deUint32 depthStencilFormats[] =
	{
		GL_DEPTH_COMPONENT32F,
		GL_DEPTH_COMPONENT24,
		GL_DEPTH_COMPONENT16,
		GL_DEPTH32F_STENCIL8,
		GL_DEPTH24_STENCIL8,
		GL_STENCIL_INDEX8
	};

	// .rect
	{
		static const struct
		{
			const char*	name;
			IVec4		srcRect;
			IVec4		dstRect;
		} copyRects[] =
		{
			{ "basic",						IVec4( 10,  20,  65, 100),		IVec4( 45,   5, 100,  85) },
			{ "scale",						IVec4( 10,  20,  65, 100),		IVec4( 25,  30, 125,  94) },
			{ "out_of_bounds",				IVec4(-10, -15, 100,  63),		IVec4( 50,  30, 136, 144) },
		};

		static const struct
		{
			const char*	name;
			IVec4		srcRect;
			IVec4		dstRect;
		} filterConsistencyRects[] =
		{
			{ "mag",						IVec4( 20,  10,  74, 88),		IVec4( 10,  10,  91, 101) },
			{ "min",						IVec4( 10,  20,  78, 100),		IVec4( 20,  20,  71,  80) },
			{ "out_of_bounds_mag",			IVec4( 21,  10,  73, 82),		IVec4( 11,  43, 141, 151) },
			{ "out_of_bounds_min",			IVec4( 11,  21,  77, 97),		IVec4( 80,  82, 135, 139) },
		};

		static const struct
		{
			const char* name;
			IVec4		srcSwizzle;
			IVec4		dstSwizzle;
		} swizzles[] =
		{
			{ DE_NULL,				IVec4(0,1,2,3),	IVec4(0,1,2,3) },
			{ "reverse_src_x",		IVec4(2,1,0,3), IVec4(0,1,2,3) },
			{ "reverse_src_y",		IVec4(0,3,2,1), IVec4(0,1,2,3) },
			{ "reverse_dst_x",		IVec4(0,1,2,3), IVec4(2,1,0,3) },
			{ "reverse_dst_y",		IVec4(0,1,2,3), IVec4(0,3,2,1) },
			{ "reverse_src_dst_x",	IVec4(2,1,0,3), IVec4(2,1,0,3) },
			{ "reverse_src_dst_y",	IVec4(0,3,2,1), IVec4(0,3,2,1) }
		};

		const IVec2 srcSize(127, 119);
		const IVec2 dstSize(132, 128);

		// Blit rectangle tests.
		tcu::TestCaseGroup* rectGroup = new tcu::TestCaseGroup(m_testCtx, "rect", "Blit rectangle tests");
		addChild(rectGroup);
		for (int rectNdx = 0; rectNdx < DE_LENGTH_OF_ARRAY(copyRects); rectNdx++)
		{
			for (int swzNdx = 0; swzNdx < DE_LENGTH_OF_ARRAY(swizzles); swzNdx++)
			{
				string		name	= string(copyRects[rectNdx].name) + (swizzles[swzNdx].name ? (string("_") + swizzles[swzNdx].name) : string());
				IVec4		srcSwz	= swizzles[swzNdx].srcSwizzle;
				IVec4		dstSwz	= swizzles[swzNdx].dstSwizzle;
				IVec4		srcRect	= copyRects[rectNdx].srcRect.swizzle(srcSwz[0], srcSwz[1], srcSwz[2], srcSwz[3]);
				IVec4		dstRect	= copyRects[rectNdx].dstRect.swizzle(dstSwz[0], dstSwz[1], dstSwz[2], dstSwz[3]);

				rectGroup->addChild(new BlitRectCase(m_context, (name + "_nearest").c_str(),	"", GL_NEAREST,	srcSize, srcRect, dstSize, dstRect));
				rectGroup->addChild(new BlitRectCase(m_context, (name + "_linear").c_str(),		"", GL_LINEAR,	srcSize, srcRect, dstSize, dstRect));
			}
		}

		// Nearest filter tests
		for (int rectNdx = 0; rectNdx < DE_LENGTH_OF_ARRAY(filterConsistencyRects); rectNdx++)
		{
			for (int swzNdx = 0; swzNdx < DE_LENGTH_OF_ARRAY(swizzles); swzNdx++)
			{
				string		name	= string("nearest_consistency_") + filterConsistencyRects[rectNdx].name + (swizzles[swzNdx].name ? (string("_") + swizzles[swzNdx].name) : string());
				IVec4		srcSwz	= swizzles[swzNdx].srcSwizzle;
				IVec4		dstSwz	= swizzles[swzNdx].dstSwizzle;
				IVec4		srcRect	= filterConsistencyRects[rectNdx].srcRect.swizzle(srcSwz[0], srcSwz[1], srcSwz[2], srcSwz[3]);
				IVec4		dstRect	= filterConsistencyRects[rectNdx].dstRect.swizzle(dstSwz[0], dstSwz[1], dstSwz[2], dstSwz[3]);

				rectGroup->addChild(new BlitNearestFilterConsistencyCase(m_context, name.c_str(), "Test consistency of the nearest filter", srcSize, srcRect, dstSize, dstRect));
			}
		}
	}

	// .conversion
	{
		tcu::TestCaseGroup* conversionGroup = new tcu::TestCaseGroup(m_testCtx, "conversion", "Color conversion tests");
		addChild(conversionGroup);

		for (int srcFmtNdx = 0; srcFmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); srcFmtNdx++)
		{
			for (int dstFmtNdx = 0; dstFmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); dstFmtNdx++)
			{
				deUint32					srcFormat	= colorFormats[srcFmtNdx];
				tcu::TextureFormat			srcTexFmt	= glu::mapGLInternalFormat(srcFormat);
				tcu::TextureChannelClass	srcType		= tcu::getTextureChannelClass(srcTexFmt.type);
				deUint32					dstFormat	= colorFormats[dstFmtNdx];
				tcu::TextureFormat			dstTexFmt	= glu::mapGLInternalFormat(dstFormat);
				tcu::TextureChannelClass	dstType		= tcu::getTextureChannelClass(dstTexFmt.type);

				if (((srcType == tcu::TEXTURECHANNELCLASS_FLOATING_POINT || srcType == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT) !=
					 (dstType == tcu::TEXTURECHANNELCLASS_FLOATING_POINT || dstType == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)) ||
					((srcType == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) != (dstType == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)) ||
					((srcType == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) != (dstType == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)))
					continue; // Conversion not supported.

				string						name		= string(getFormatName(srcFormat)) + "_to_" + getFormatName(dstFormat);

				conversionGroup->addChild(new BlitColorConversionCase(m_context, name.c_str(), "", srcFormat, dstFormat, IVec2(127, 113)));
			}
		}
	}

	// .depth_stencil
	{
		tcu::TestCaseGroup* depthStencilGroup = new tcu::TestCaseGroup(m_testCtx, "depth_stencil", "Depth and stencil blits");
		addChild(depthStencilGroup);

		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); fmtNdx++)
		{
			deUint32			format		= depthStencilFormats[fmtNdx];
			tcu::TextureFormat	texFmt		= glu::mapGLInternalFormat(format);
			string				fmtName		= getFormatName(format);
			bool				depth		= texFmt.order == tcu::TextureFormat::D || texFmt.order == tcu::TextureFormat::DS;
			bool				stencil		= texFmt.order == tcu::TextureFormat::S || texFmt.order == tcu::TextureFormat::DS;
			deUint32			buffers		= (depth ? GL_DEPTH_BUFFER_BIT : 0) | (stencil ? GL_STENCIL_BUFFER_BIT : 0);

			depthStencilGroup->addChild(new BlitDepthStencilCase(m_context, (fmtName + "_basic").c_str(), "", format, buffers, IVec2(128, 128), IVec4(0, 0, 128, 128), buffers, IVec2(128, 128), IVec4(0, 0, 128, 128), buffers));
			depthStencilGroup->addChild(new BlitDepthStencilCase(m_context, (fmtName + "_scale").c_str(), "", format, buffers, IVec2(127, 119), IVec4(10, 30, 100, 70), buffers, IVec2(111, 130), IVec4(20, 5, 80, 130), buffers));

			if (depth && stencil)
			{
				depthStencilGroup->addChild(new BlitDepthStencilCase(m_context, (fmtName + "_depth_only").c_str(),		"", format, buffers, IVec2(128, 128), IVec4(0, 0, 128, 128), buffers, IVec2(128, 128), IVec4(0, 0, 128, 128), GL_DEPTH_BUFFER_BIT));
				depthStencilGroup->addChild(new BlitDepthStencilCase(m_context, (fmtName + "_stencil_only").c_str(),	"", format, buffers, IVec2(128, 128), IVec4(0, 0, 128, 128), buffers, IVec2(128, 128), IVec4(0, 0, 128, 128), GL_STENCIL_BUFFER_BIT));
			}
		}
	}

	// .default_framebuffer
	{
		static const struct
		{
			const char*								name;
			DefaultFramebufferBlitCase::BlitArea	area;
		} areas[] =
		{
			{ "scale",						DefaultFramebufferBlitCase::AREA_SCALE			},
			{ "out_of_bounds",				DefaultFramebufferBlitCase::AREA_OUT_OF_BOUNDS	},
		};

		tcu::TestCaseGroup* defaultFbGroup = new tcu::TestCaseGroup(m_testCtx, "default_framebuffer", "Blits with default framebuffer");
		addChild(defaultFbGroup);

		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
		{
			const deUint32					format		= colorFormats[fmtNdx];
			const tcu::TextureFormat		texFmt		= glu::mapGLInternalFormat(format);
			const tcu::TextureChannelClass	fmtClass	= tcu::getTextureChannelClass(texFmt.type);
			const deUint32					filter		= glu::isGLInternalColorFormatFilterable(format) ? GL_LINEAR : GL_NEAREST;
			const bool						filterable	= glu::isGLInternalColorFormatFilterable(format);

			if (fmtClass != tcu::TEXTURECHANNELCLASS_FLOATING_POINT &&
				fmtClass != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT &&
				fmtClass != tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
				continue; // Conversion not supported.

			defaultFbGroup->addChild(new BlitDefaultFramebufferCase(m_context, getFormatName(format), "", format, filter));

			for (int areaNdx = 0; areaNdx < DE_LENGTH_OF_ARRAY(areas); areaNdx++)
			{
				const string	name				= string(areas[areaNdx].name);
				const bool		addLinear			= filterable;
				const bool		addNearest			= !addLinear || (areas[areaNdx].area != DefaultFramebufferBlitCase::AREA_OUT_OF_BOUNDS); // No need to check out-of-bounds with different filtering

				if (addNearest)
				{
					defaultFbGroup->addChild(new DefaultFramebufferBlitCase(m_context, (std::string(getFormatName(format)) + "_nearest_" + name + "_blit_from_default").c_str(), "", format, GL_NEAREST, DefaultFramebufferBlitCase::BLIT_DEFAULT_TO_TARGET, areas[areaNdx].area));
					defaultFbGroup->addChild(new DefaultFramebufferBlitCase(m_context, (std::string(getFormatName(format)) + "_nearest_" + name + "_blit_to_default").c_str(), "", format, GL_NEAREST, DefaultFramebufferBlitCase::BLIT_TO_DEFAULT_FROM_TARGET, areas[areaNdx].area));
				}

				if (addLinear)
				{
					defaultFbGroup->addChild(new DefaultFramebufferBlitCase(m_context, (std::string(getFormatName(format)) + "_linear_" + name + "_blit_from_default").c_str(), "", format, GL_LINEAR, DefaultFramebufferBlitCase::BLIT_DEFAULT_TO_TARGET, areas[areaNdx].area));
					defaultFbGroup->addChild(new DefaultFramebufferBlitCase(m_context, (std::string(getFormatName(format)) + "_linear_" + name + "_blit_to_default").c_str(), "", format, GL_LINEAR, DefaultFramebufferBlitCase::BLIT_TO_DEFAULT_FROM_TARGET, areas[areaNdx].area));
				}
			}
		}
	}
}

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