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

#include "es3fTextureSwizzleTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTexture.hpp"
#include "gluRenderContext.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuRenderTarget.hpp"
#include "deString.h"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"

namespace deqp
{
namespace gles3
{
namespace Functional
{

using std::string;
using std::vector;
using tcu::TestLog;
using namespace deqp::gls;
using namespace deqp::gls::TextureTestUtil;
using namespace glu::TextureTestUtil;

static int swizzle (const tcu::RGBA& c, deUint32 swz)
{
	switch (swz)
	{
		case GL_RED:	return c.getRed();
		case GL_GREEN:	return c.getGreen();
		case GL_BLUE:	return c.getBlue();
		case GL_ALPHA:	return c.getAlpha();
		case GL_ZERO:	return 0;
		case GL_ONE:	return (1<<8)-1;
		default:
			DE_ASSERT(false);
			return 0;
	}
}

static void swizzle (tcu::Surface& surface, deUint32 swzR, deUint32 swzG, deUint32 swzB, deUint32 swzA)
{
	for (int y = 0; y < surface.getHeight(); y++)
	{
		for (int x = 0; x < surface.getWidth(); x++)
		{
			tcu::RGBA p = surface.getPixel(x, y);
			surface.setPixel(x, y, tcu::RGBA(swizzle(p, swzR), swizzle(p, swzG), swizzle(p, swzB), swizzle(p, swzA)));
		}
	}
}

class Texture2DSwizzleCase : public TestCase
{
public:
							Texture2DSwizzleCase	(Context& context, const char* name, const char* description, deUint32 internalFormat, deUint32 format, deUint32 dataType, deUint32 swizzleR, deUint32 swizzleG, deUint32 swizzleB, deUint32 swizzleA);
							~Texture2DSwizzleCase	(void);

	void					init					(void);
	void					deinit					(void);
	IterateResult			iterate					(void);

private:
							Texture2DSwizzleCase	(const Texture2DSwizzleCase& other);
	Texture2DSwizzleCase&	operator=				(const Texture2DSwizzleCase& other);

	deUint32				m_internalFormat;
	deUint32				m_format;
	deUint32				m_dataType;
	deUint32				m_swizzleR;
	deUint32				m_swizzleG;
	deUint32				m_swizzleB;
	deUint32				m_swizzleA;

	glu::Texture2D*			m_texture;
	TextureRenderer			m_renderer;
};

Texture2DSwizzleCase::Texture2DSwizzleCase (Context& context, const char* name, const char* description, deUint32 internalFormat, deUint32 format, deUint32 dataType, deUint32 swizzleR, deUint32 swizzleG, deUint32 swizzleB, deUint32 swizzleA)
	: TestCase			(context, name, description)
	, m_internalFormat	(internalFormat)
	, m_format			(format)
	, m_dataType		(dataType)
	, m_swizzleR		(swizzleR)
	, m_swizzleG		(swizzleG)
	, m_swizzleB		(swizzleB)
	, m_swizzleA		(swizzleA)
	, m_texture			(DE_NULL)
	, m_renderer		(context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
{
}

Texture2DSwizzleCase::~Texture2DSwizzleCase (void)
{
	deinit();
}

void Texture2DSwizzleCase::init (void)
{
	int	width	= de::min(128, m_context.getRenderContext().getRenderTarget().getWidth());
	int	height	= de::min(128, m_context.getRenderContext().getRenderTarget().getHeight());

	m_texture = (m_internalFormat == m_format) ? new glu::Texture2D(m_context.getRenderContext(), m_format, m_dataType, width, height)
											   : new glu::Texture2D(m_context.getRenderContext(), m_internalFormat, width, height);

	tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());

	// Fill level 0.
	m_texture->getRefTexture().allocLevel(0);
	tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);
}

void Texture2DSwizzleCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;

	m_renderer.clear();
}

Texture2DSwizzleCase::IterateResult Texture2DSwizzleCase::iterate (void)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	TestLog&				log					= m_testCtx.getLog();
	RandomViewport			viewport			(m_context.getRenderContext().getRenderTarget(), m_texture->getRefTexture().getWidth(), m_texture->getRefTexture().getHeight(), deStringHash(getName()));
	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
	tcu::RGBA				threshold			= m_context.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
	vector<float>			texCoord;
	ReferenceParams			renderParams		(TEXTURETYPE_2D);
	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());

	renderParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
	renderParams.sampler		= tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
	renderParams.colorScale		= spec.lookupScale;
	renderParams.colorBias		= spec.lookupBias;

	computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));

	// Setup base viewport.
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

	// Upload texture data to GL.
	m_texture->upload();

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());

	// Setup nearest neighbor filtering and clamp-to-edge.
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	// Setup texture swizzle.
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R,	m_swizzleR);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G,	m_swizzleG);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B,	m_swizzleB);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A,	m_swizzleA);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	// Draw.
	m_renderer.renderQuad(0, &texCoord[0], renderParams);
	glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, renderedFrame.getAccess());

	// Compute reference
	{
		const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();

		// Do initial rendering to RGBA8 in order to keep alpha
		sampleTexture(tcu::SurfaceAccess(referenceFrame, tcu::PixelFormat(8,8,8,8)), m_texture->getRefTexture(), &texCoord[0], renderParams);

		// Swizzle channels
		swizzle(referenceFrame, m_swizzleR, m_swizzleG, m_swizzleB, m_swizzleA);

		// Convert to destination format
		if (pixelFormat != tcu::PixelFormat(8,8,8,8))
		{
			for (int y = 0; y < referenceFrame.getHeight(); y++)
			{
				for (int x = 0; x < referenceFrame.getWidth(); x++)
				{
					tcu::RGBA p = referenceFrame.getPixel(x, y);
					referenceFrame.setPixel(x, y, pixelFormat.convertColor(p));
				}
			}
		}
	}

	// Compare and log.
	bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);

	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
							isOk ? "Pass"				: "Image comparison failed");

	return STOP;
}

TextureSwizzleTests::TextureSwizzleTests (Context& context)
	: TestCaseGroup(context, "swizzle", "Texture Swizzle Tests")
{
}

TextureSwizzleTests::~TextureSwizzleTests (void)
{
}

void TextureSwizzleTests::init (void)
{
	static const struct
	{
		const char*		name;
		deUint32		internalFormat;
		deUint32		format;
		deUint32		dataType;
	} formats[] =
	{
		{ "alpha",				GL_ALPHA,				GL_ALPHA,			GL_UNSIGNED_BYTE },
		{ "luminance",			GL_LUMINANCE,			GL_LUMINANCE,		GL_UNSIGNED_BYTE },
		{ "luminance_alpha",	GL_LUMINANCE_ALPHA,		GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE },
		{ "red",				GL_R8,					GL_RED,				GL_UNSIGNED_BYTE },
		{ "rg",					GL_RG8,					GL_RG,				GL_UNSIGNED_BYTE },
		{ "rgb",				GL_RGB8,				GL_RGB,				GL_UNSIGNED_BYTE },
		{ "rgba",				GL_RGBA8,				GL_RGBA,			GL_UNSIGNED_BYTE }
	};

	static const struct
	{
		const char*		name;
		deUint32		channel;
	} channels[] =
	{
		{ "r",	GL_TEXTURE_SWIZZLE_R },
		{ "g",	GL_TEXTURE_SWIZZLE_G },
		{ "b",	GL_TEXTURE_SWIZZLE_B },
		{ "a",	GL_TEXTURE_SWIZZLE_A }
	};

	static const struct
	{
		const char*		name;
		deUint32		swizzle;
	} swizzles[] =
	{
		{ "red",		GL_RED		},
		{ "green",		GL_GREEN	},
		{ "blue",		GL_BLUE		},
		{ "alpha",		GL_ALPHA	},
		{ "zero",		GL_ZERO		},
		{ "one",		GL_ONE		}
	};

	static const struct
	{
		const char*		name;
		deUint32		swzR;
		deUint32		swzG;
		deUint32		swzB;
		deUint32		swzA;
	} swizzleCases[] =
	{
		{ "all_red",			GL_RED,		GL_RED,		GL_RED,		GL_RED		},
		{ "all_green",			GL_GREEN,	GL_GREEN,	GL_GREEN,	GL_GREEN	},
		{ "all_blue",			GL_BLUE,	GL_BLUE,	GL_BLUE,	GL_BLUE		},
		{ "all_alpha",			GL_ALPHA,	GL_ALPHA,	GL_ALPHA,	GL_ALPHA	},
		{ "all_zero",			GL_ZERO,	GL_ZERO,	GL_ZERO,	GL_ZERO		},
		{ "all_one",			GL_ONE,		GL_ONE,		GL_ONE,		GL_ONE		},
		{ "bgra",				GL_BLUE,	GL_GREEN,	GL_RED,		GL_ALPHA	},
		{ "abgr",				GL_ALPHA,	GL_BLUE,	GL_GREEN,	GL_RED		},
		{ "one_one_red_green",	GL_ONE,		GL_ONE,		GL_RED,		GL_GREEN	}
	};

	static const deUint32 defaultSwizzles[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };

	// All swizzles applied to each channel.
	tcu::TestCaseGroup* singleChannelGroup = new tcu::TestCaseGroup(m_testCtx, "single_channel", "Single-channel swizzle");
	addChild(singleChannelGroup);
	for (int chanNdx = 0; chanNdx < DE_LENGTH_OF_ARRAY(channels); chanNdx++)
	{
		for (int swzNdx = 0; swzNdx < DE_LENGTH_OF_ARRAY(swizzles); swzNdx++)
		{
			if (swizzles[swzNdx].swizzle == defaultSwizzles[chanNdx])
				continue; // No need to test default case.

			string		name	= string(channels[chanNdx].name) + "_" + swizzles[swzNdx].name;
			deUint32	swz		= swizzles[swzNdx].swizzle;
			deUint32	swzR	= (chanNdx == 0) ? swz : defaultSwizzles[0];
			deUint32	swzG	= (chanNdx == 1) ? swz : defaultSwizzles[1];
			deUint32	swzB	= (chanNdx == 2) ? swz : defaultSwizzles[2];
			deUint32	swzA	= (chanNdx == 3) ? swz : defaultSwizzles[3];

			singleChannelGroup->addChild(new Texture2DSwizzleCase(m_context, name.c_str(), "Single-channel swizzle", GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, swzR, swzG, swzB, swzA));
		}
	}

	// Swizzles for all formats.
	tcu::TestCaseGroup* multiChannelGroup = new tcu::TestCaseGroup(m_testCtx, "multi_channel", "Multi-channel swizzle");
	addChild(multiChannelGroup);
	for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); fmtNdx++)
	{
		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(swizzleCases); caseNdx++)
		{
			string		name		= string(formats[fmtNdx].name) + "_" + swizzleCases[caseNdx].name;
			deUint32	swzR		= swizzleCases[caseNdx].swzR;
			deUint32	swzG		= swizzleCases[caseNdx].swzG;
			deUint32	swzB		= swizzleCases[caseNdx].swzB;
			deUint32	swzA		= swizzleCases[caseNdx].swzA;
			deUint32	intFormat	= formats[fmtNdx].internalFormat;
			deUint32	format		= formats[fmtNdx].format;
			deUint32	dataType	= formats[fmtNdx].dataType;

			multiChannelGroup->addChild(new Texture2DSwizzleCase(m_context, name.c_str(), "Multi-channel swizzle", intFormat, format, dataType, swzR, swzG, swzB, swzA));
		}
	}
}

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