/*-------------------------------------------------------------------------
 * 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 "gluContextInfo.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 = 0;
		deUint32				dstFbo = 0;
		deUint32				srcRbo = 0;
		deUint32				dstRbo = 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&		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 depthFormat, deUint32 stencilFormat, deUint32 srcBuffers, const IVec2& srcSize, const IVec4& srcRect, deUint32 dstBuffers, const IVec2& dstSize, const IVec4& dstRect, deUint32 copyBuffers)
		: FboTestCase	(context, name, desc)
		, m_depthFormat	(depthFormat)
		, m_stencilFormat(stencilFormat)
		, 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)
	{
		if (m_depthFormat != GL_NONE)
			checkFormatSupport(m_depthFormat);
		if (m_stencilFormat != GL_NONE)
			checkFormatSupport(m_stencilFormat);
		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_separate_depth_stencil")
				&& m_depthFormat != GL_NONE && m_stencilFormat != GL_NONE)
			throw tcu::NotSupportedError("Separate depth and stencil buffers not supported");
	}

	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				srcDepthRbo			= 0;
		deUint32				srcStencilRbo		= 0;
		deUint32				dstDepthRbo			= 0;
		deUint32				dstStencilRbo		= 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&		depthRbo		= ndx ? dstDepthRbo : srcDepthRbo;
			deUint32&		stencilRbo		= ndx ? dstStencilRbo : srcStencilRbo;
			deUint32		bufs			= ndx ? m_dstBuffers : m_srcBuffers;
			const IVec2&	size			= ndx ? m_dstSize : m_srcSize;

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

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

			if (m_depthFormat != GL_NONE) {
				glGenRenderbuffers(1, &depthRbo);
				glBindRenderbuffer(GL_RENDERBUFFER, depthRbo);
				glRenderbufferStorage(GL_RENDERBUFFER, m_depthFormat, size.x(), size.y());
			}

			if (m_stencilFormat != GL_NONE) {
				glGenRenderbuffers(1, &stencilRbo);
				glBindRenderbuffer(GL_RENDERBUFFER, stencilRbo);
				glRenderbufferStorage(GL_RENDERBUFFER, m_stencilFormat, 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, depthRbo);
			if (bufs & GL_STENCIL_BUFFER_BIT)
				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
					m_stencilFormat == GL_NONE? depthRbo : stencilRbo);

			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_depthFormat;
	deUint32	m_stencilFormat;
	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_NONE,
		GL_DEPTH_COMPONENT32F,
		GL_DEPTH_COMPONENT24,
		GL_DEPTH_COMPONENT16,
		GL_DEPTH32F_STENCIL8,
		GL_DEPTH24_STENCIL8
	};

	static const deUint32 stencilFormats[] =
	{
		GL_NONE,
		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 dFmtNdx = 0; dFmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); dFmtNdx++)
		{
			for (int sFmtNdx = 0; sFmtNdx < DE_LENGTH_OF_ARRAY(stencilFormats); sFmtNdx++)
			{
				deUint32	depthFormat		= depthStencilFormats[dFmtNdx];
				deUint32	stencilFormat	= stencilFormats[sFmtNdx];
				bool		depth			= false;
				bool		stencil			= false;
				string		fmtName;

				if (depthFormat != GL_NONE)
				{
					tcu::TextureFormat info = glu::mapGLInternalFormat(depthFormat);

					fmtName += getFormatName(depthFormat);
					if (info.order == tcu::TextureFormat::D || info.order == tcu::TextureFormat::DS)
						depth = true;
					if (info.order == tcu::TextureFormat::DS)
						stencil = true;
				}

				if (stencilFormat != GL_NONE)
				{
					// Do not try separate stencil along with a combined depth/stencil
					if (stencil)
						continue;

					if (depthFormat != GL_NONE)
						fmtName += "_";
					fmtName += getFormatName(stencilFormat);
					stencil = true;
				}

				if (!stencil && !depth)
					continue;

				deUint32 buffers = (depth ? GL_DEPTH_BUFFER_BIT : 0) | (stencil ? GL_STENCIL_BUFFER_BIT : 0);

				depthStencilGroup->addChild(new BlitDepthStencilCase(m_context, (fmtName + "_basic").c_str(), "", depthFormat, stencilFormat, 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(), "", depthFormat, stencilFormat, 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(),		"", depthFormat, stencilFormat, 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(),	"", depthFormat, stencilFormat, 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
