/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) Module
 * -----------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Framebuffer completeness tests.
 *//*--------------------------------------------------------------------*/

#include "es3fFboCompletenessTests.hpp"

#include "glsFboCompletenessTests.hpp"
#include <sstream>

using namespace glw;
using deqp::gls::Range;
using namespace deqp::gls::FboUtil;
using namespace deqp::gls::FboUtil::config;
namespace fboc = deqp::gls::fboc;
typedef tcu::TestCase::IterateResult IterateResult;
using std::string;
using std::ostringstream;

namespace deqp
{
namespace gles3
{
namespace Functional
{

static const FormatKey s_es3ColorRenderables[] =
{
	// GLES3, 4.4.4: "An internal format is color-renderable if it is one of
	// the formats from table 3.12 noted as color-renderable..."
	GL_R8, GL_RG8, GL_RGB8, GL_RGB565, GL_RGBA4, GL_RGB5_A1, GL_RGBA8,
	GL_RGB10_A2, GL_RGB10_A2UI, GL_SRGB8_ALPHA8,
	GL_R8I, GL_R8UI, GL_R16I, GL_R16UI, GL_R32I, GL_R32UI,
	GL_RG8I, GL_RG8UI, GL_RG16I, GL_RG16UI, GL_RG32I, GL_RG32UI,
	GL_RGBA8I, GL_RGBA8UI, GL_RGBA16I, GL_RGBA16UI, GL_RGBA32I, GL_RGBA32UI,
};

static const FormatKey s_es3UnsizedColorRenderables[] =
{
	// "...or if it is unsized format RGBA or RGB."
	// See Table 3.3 in GLES3.
	GLS_UNSIZED_FORMATKEY(GL_RGBA,	GL_UNSIGNED_BYTE),
	GLS_UNSIZED_FORMATKEY(GL_RGBA,	GL_UNSIGNED_SHORT_4_4_4_4),
	GLS_UNSIZED_FORMATKEY(GL_RGBA,	GL_UNSIGNED_SHORT_5_5_5_1),
	GLS_UNSIZED_FORMATKEY(GL_RGB,	GL_UNSIGNED_BYTE),
	GLS_UNSIZED_FORMATKEY(GL_RGB,	GL_UNSIGNED_SHORT_5_6_5),
};

static const FormatKey s_es3DepthRenderables[] =
{
	// GLES3, 4.4.4: "An internal format is depth-renderable if it is one of
	// the formats from table 3.13."
	GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32F,
	GL_DEPTH24_STENCIL8, GL_DEPTH32F_STENCIL8,
};

static const FormatKey s_es3StencilRboRenderables[] =
{
	// GLES3, 4.4.4: "An internal format is stencil-renderable if it is
	// STENCIL_INDEX8..."
	GL_STENCIL_INDEX8,
};

static const FormatKey s_es3StencilRenderables[] =
{
	// "...or one of the formats from table 3.13 whose base internal format is
	// DEPTH_STENCIL."
	GL_DEPTH24_STENCIL8, GL_DEPTH32F_STENCIL8,
};

static const FormatKey s_es3TextureFloatFormats[] =
{
	GL_RGBA32F, GL_RGBA16F, GL_R11F_G11F_B10F,
	GL_RG32F, GL_RG16F, GL_R32F, GL_R16F,
	GL_RGBA16F, GL_RGB16F, GL_RG16F, GL_R16F,
};

static const FormatKey s_es3NotRenderableTextureFormats[] =
{
	GL_R8_SNORM, GL_RG8_SNORM, GL_RGB8_SNORM, GL_RGBA8_SNORM,
	GL_RGB9_E5, GL_SRGB8,
	GL_RGB8I, GL_RGB16I, GL_RGB32I,
	GL_RGB8UI, GL_RGB16UI,GL_RGB32UI,
};

static const FormatEntry s_es3Formats[] =
{
	// Renderbuffers don't support unsized formats
	{ REQUIRED_RENDERABLE | COLOR_RENDERABLE | TEXTURE_VALID,
	  GLS_ARRAY_RANGE(s_es3UnsizedColorRenderables) },
	{ REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID | TEXTURE_VALID,
	  GLS_ARRAY_RANGE(s_es3ColorRenderables) },
	{ REQUIRED_RENDERABLE | DEPTH_RENDERABLE | RENDERBUFFER_VALID | TEXTURE_VALID,
	  GLS_ARRAY_RANGE(s_es3DepthRenderables) },
	{ REQUIRED_RENDERABLE | STENCIL_RENDERABLE | RENDERBUFFER_VALID,
	  GLS_ARRAY_RANGE(s_es3StencilRboRenderables) },
	{ REQUIRED_RENDERABLE | STENCIL_RENDERABLE | RENDERBUFFER_VALID | TEXTURE_VALID,
	  GLS_ARRAY_RANGE(s_es3StencilRenderables) },
	{ TEXTURE_VALID,
	  GLS_ARRAY_RANGE(s_es3NotRenderableTextureFormats) },

	// These are not color-renderable in vanilla ES3, but we need to mark them
	// as valid for textures, since EXT_color_buffer_(half_)float brings in
	// color-renderability and only renderbuffer-validity.
	{ TEXTURE_VALID,
	  GLS_ARRAY_RANGE(s_es3TextureFloatFormats) },
};

// GL_EXT_color_buffer_float
static const FormatKey s_extColorBufferFloatFormats[] =
{
	GL_RGBA32F, GL_RGBA16F, GL_R11F_G11F_B10F, GL_RG32F, GL_RG16F, GL_R32F, GL_R16F,
};

// GL_QCOM_render_shared_exponent
static const FormatKey s_qcomRenderSharedExponent[] =
{
	GL_RGB9_E5,
};
// GL_OES_texture_stencil8
static const FormatKey s_extOESTextureStencil8[] =
{
	GL_STENCIL_INDEX8,
};

// GL_EXT_render_snorm
static const FormatKey s_extRenderSnorm[] =
{
	GL_R8_SNORM, GL_RG8_SNORM, GL_RGBA8_SNORM,
};

static const FormatExtEntry s_es3ExtFormats[] =
{
	{
		"GL_EXT_color_buffer_float",
		// These are already texture-valid in ES3, the extension just adds RBO
		// support and makes them color-renderable.
		(deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID),
		GLS_ARRAY_RANGE(s_extColorBufferFloatFormats)
	},
	{
		"GL_OES_texture_stencil8",
		// \note: es3 RBO tests actually cover the first two requirements
		// - kept here for completeness
		(deUint32)(REQUIRED_RENDERABLE | STENCIL_RENDERABLE | TEXTURE_VALID),
		GLS_ARRAY_RANGE(s_extOESTextureStencil8)
	},

	// Since GLES31 is backwards compatible to GLES3, we might actually be running on a GLES31.
	// Add rule changes of GLES31 that have no corresponding GLES3 extension.
	//
	// \note Not all feature changes are listed here but only those that alter GLES3 subset of
	//       the formats
	{
		"DEQP_gles31_core_compatible GL_EXT_render_snorm",
		(deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE | TEXTURE_VALID | RENDERBUFFER_VALID),
		GLS_ARRAY_RANGE(s_extRenderSnorm)
		},

	{
		"GL_QCOM_render_shared_exponent",
		// This is already texture-valid in ES3, the extension just adds RBO
		// support to RGB9_E5 and make it color-renderable.
		(deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID | TEXTURE_VALID),
		GLS_ARRAY_RANGE(s_qcomRenderSharedExponent)
	},
};

class ES3Checker : public Checker
{
public:
				ES3Checker	(const glu::RenderContext& ctx)
					: Checker				(ctx)
					, m_numSamples			(-1)
					, m_depthStencilImage	(0)
					, m_depthStencilType	(GL_NONE) {}
	void		check		(GLenum attPoint, const Attachment& att, const Image* image);

private:
	//! The common number of samples of images.
	GLsizei		m_numSamples;

	//! The common image for depth and stencil attachments.
	GLuint		m_depthStencilImage;
	GLenum		m_depthStencilType;
};

void ES3Checker::check (GLenum attPoint, const Attachment& att, const Image* image)
{
	GLsizei imgSamples = imageNumSamples(*image);

	if (m_numSamples == -1)
	{
		m_numSamples = imgSamples;
	}
	else
	{
		// GLES3: "The value of RENDERBUFFER_SAMPLES is the same for all attached
		// renderbuffers and, if the attached images are a mix of renderbuffers
		// and textures, the value of RENDERBUFFER_SAMPLES is zero."
		//
		// On creating a renderbuffer: "If _samples_ is zero, then
		// RENDERBUFFER_SAMPLES is set to zero. Otherwise [...] the resulting
		// value for RENDERBUFFER_SAMPLES is guaranteed to be greater than or
		// equal to _samples_ and no more than the next larger sample count
		// supported by the implementation."

		// Either all attachments are zero-sample renderbuffers and/or
		// textures, or none of them are.
		if ((m_numSamples == 0) != (imgSamples == 0))
			addFBOStatus(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, "Mixed multi- and single-sampled attachments");

		// If the attachments requested a different number of samples, the
		// implementation is allowed to report this as incomplete. However, it
		// is also possible that despite the different requests, the
		// implementation allocated the same number of samples to both. Hence
		// reporting the framebuffer as complete is also legal.
		if (m_numSamples != imgSamples)
			addPotentialFBOStatus(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, "Number of samples differ");
	}

	// "Depth and stencil attachments, if present, are the same image."
	if (attPoint == GL_DEPTH_ATTACHMENT || attPoint == GL_STENCIL_ATTACHMENT)
	{
		if (m_depthStencilImage == 0)
		{
			m_depthStencilImage = att.imageName;
			m_depthStencilType = attachmentType(att);
		}
		else
		{
			if (m_depthStencilImage != att.imageName || m_depthStencilType != attachmentType(att))
				addFBOStatus(GL_FRAMEBUFFER_UNSUPPORTED, "Depth and stencil attachments are not the same image");
		}
	}
}

struct NumLayersParams
{
	GLenum		textureKind;		//< GL_TEXTURE_3D or GL_TEXTURE_2D_ARRAY
	GLsizei		numLayers;			//< Number of layers in texture
	GLsizei		attachmentLayer;	//< Layer referenced by attachment

	static string	getName			(const NumLayersParams& params);
	static string	getDescription	(const NumLayersParams& params);
};

string NumLayersParams::getName (const NumLayersParams& params)
{
	ostringstream os;
	const string kindStr = params.textureKind == GL_TEXTURE_3D ? "3d" : "2darr";
	os << kindStr << "_" << params.numLayers << "_" << params.attachmentLayer;
	return os.str();
}

string NumLayersParams::getDescription (const NumLayersParams& params)
{
	ostringstream os;
	const string kindStr = (params.textureKind == GL_TEXTURE_3D
							? "3D Texture"
							: "2D Array Texture");
	os << kindStr + ", "
	   << params.numLayers << " layers, "
	   << "attached layer " << params.attachmentLayer << ".";
	return os.str();
}

class NumLayersTest : public fboc::ParamTest<NumLayersParams>
{
public:
					NumLayersTest		(fboc::Context& ctx, NumLayersParams param)
						: fboc::ParamTest<NumLayersParams> (ctx, param) {}

	IterateResult	build				(FboBuilder& builder);
};

IterateResult NumLayersTest::build (FboBuilder& builder)
{
	TextureLayered* texCfg = DE_NULL;
	const GLenum target = GL_COLOR_ATTACHMENT0;

	switch (m_params.textureKind)
	{
		case GL_TEXTURE_3D:
			texCfg = &builder.makeConfig<Texture3D>();
			break;
		case GL_TEXTURE_2D_ARRAY:
			texCfg = &builder.makeConfig<Texture2DArray>();
			break;
		default:
			DE_FATAL("Impossible case");
	}
	texCfg->internalFormat = getDefaultFormat(target, GL_TEXTURE);
	texCfg->width = 64;
	texCfg->height = 64;
	texCfg->numLayers = m_params.numLayers;
	const GLuint tex = builder.glCreateTexture(*texCfg);

	TextureLayerAttachment* att = &builder.makeConfig<TextureLayerAttachment>();
	att->layer = m_params.attachmentLayer;
	att->imageName = tex;

	builder.glAttach(target, att);

	return STOP;
}

enum
{
	SAMPLES_NONE = -2,
	SAMPLES_TEXTURE = -1
};
struct NumSamplesParams
{
	// >= 0: renderbuffer with N samples, -1: texture, -2: no attachment
	GLsizei		numSamples[3];

	static string	getName			(const NumSamplesParams& params);
	static string	getDescription	(const NumSamplesParams& params);
};

string NumSamplesParams::getName (const NumSamplesParams& params)
{
	ostringstream os;
	bool first = true;
	for (const GLsizei* ns	=	DE_ARRAY_BEGIN(params.numSamples);
		 ns					!=	DE_ARRAY_END(params.numSamples);
		 ns++)
	{
		if (first)
			first = false;
		else
			os << "_";

		if (*ns == SAMPLES_NONE)
			os << "none";
		else if (*ns == SAMPLES_TEXTURE)
			os << "tex";
		else
			os << "rbo" << *ns;
	}
	return os.str();
}

string NumSamplesParams::getDescription (const NumSamplesParams& params)
{
	ostringstream os;
	bool first = true;
	static const char* const s_names[] = { "color", "depth", "stencil" };
	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == DE_LENGTH_OF_ARRAY(params.numSamples));

	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_names); i++)
	{
		GLsizei ns = params.numSamples[i];

		if (ns == SAMPLES_NONE)
			continue;

		if (first)
			first = false;
		else
			os << ", ";

		if (ns == SAMPLES_TEXTURE)
			os << "texture " << s_names[i] << " attachment";
		else
			os << ns << "-sample renderbuffer " << s_names[i] << " attachment";
	}
	return os.str();
}

class NumSamplesTest : public fboc::ParamTest<NumSamplesParams>
{
public:
					NumSamplesTest		(fboc::Context& ctx, NumSamplesParams param)
						: fboc::ParamTest<NumSamplesParams> (ctx, param) {}

	IterateResult	build				(FboBuilder& builder);
};

IterateResult NumSamplesTest::build (FboBuilder& builder)
{
	static const GLenum s_targets[] =
		{
			GL_COLOR_ATTACHMENT0,	GL_COLOR_ATTACHMENT1,	GL_DEPTH_ATTACHMENT,
		};
	// Non-integer formats for each attachment type.
	// \todo [2013-12-17 lauri] Add fixed/floating/integer metadata for formats so
	// we can pick one smartly or maybe try several.
	static const GLenum s_formats[] =
		{
			GL_RGBA8,				GL_RGB565,				GL_DEPTH_COMPONENT24,
		};
	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_targets) == DE_LENGTH_OF_ARRAY(m_params.numSamples));

	for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_targets); i++)
	{
		const GLenum target = s_targets[i];
		const ImageFormat fmt = { s_formats[i], GL_NONE };

		const GLsizei ns = m_params.numSamples[i];
		if (ns == -2)
			continue;

		if (ns == -1)
		{
			attachTargetToNew(target, GL_TEXTURE, fmt, 64, 64, builder);
		}
		else
		{
			Renderbuffer& rboCfg = builder.makeConfig<Renderbuffer>();
			rboCfg.internalFormat = fmt;
			rboCfg.width = rboCfg.height = 64;
			rboCfg.numSamples = ns;

			const GLuint rbo = builder.glCreateRbo(rboCfg);
			// Implementations do not necessarily support sample sizes greater than 1.
			TCU_CHECK_AND_THROW(NotSupportedError,
								builder.getError() != GL_INVALID_OPERATION,
								"Unsupported number of samples");
			RenderbufferAttachment& att = builder.makeConfig<RenderbufferAttachment>();
			att.imageName = rbo;
			builder.glAttach(target, &att);
		}
	}

	return STOP;
}

class ES3CheckerFactory : public CheckerFactory
{
public:
	Checker*			createChecker	(const glu::RenderContext& ctx) { return new ES3Checker(ctx); }
};

class TestGroup : public TestCaseGroup
{
public:
						TestGroup		(Context& context);
	void				init			(void);
private:
	ES3CheckerFactory	m_checkerFactory;
	fboc::Context		m_fboc;
};

void TestGroup::init (void)
{
	addChild(m_fboc.createRenderableTests());
	addChild(m_fboc.createAttachmentTests());
	addChild(m_fboc.createSizeTests());

	TestCaseGroup* layerTests = new TestCaseGroup(
		getContext(), "layer", "Tests for layer attachments");

	static const NumLayersParams s_layersParams[] =
		{ //  textureKind			numLayers	attachmentKind
			{ GL_TEXTURE_2D_ARRAY,	1,			0 },
			{ GL_TEXTURE_2D_ARRAY,	1,			3 },
			{ GL_TEXTURE_2D_ARRAY,	4,			3 },
			{ GL_TEXTURE_2D_ARRAY,	4,			15 },
			{ GL_TEXTURE_3D,		1,			0 },
			{ GL_TEXTURE_3D,		1,			15 },
			{ GL_TEXTURE_3D,		4,			15 },
			{ GL_TEXTURE_3D,		64,			15 },
		};

	for (const NumLayersParams* lp	=	DE_ARRAY_BEGIN(s_layersParams);
		 lp							!=  DE_ARRAY_END(s_layersParams);
		 ++lp)
		layerTests->addChild(new NumLayersTest(m_fboc, *lp));

	addChild(layerTests);

	TestCaseGroup* sampleTests = new TestCaseGroup(
		getContext(), "samples", "Tests for multisample attachments");

	static const NumSamplesParams s_samplesParams[] =
	{
		{ { 0,					SAMPLES_NONE,		SAMPLES_NONE } },
		{ { 1,					SAMPLES_NONE,		SAMPLES_NONE } },
		{ { 2,					SAMPLES_NONE,		SAMPLES_NONE } },
		{ { 0,					SAMPLES_TEXTURE,	SAMPLES_NONE } },
		{ { 1,					SAMPLES_TEXTURE,	SAMPLES_NONE } },
		{ { 2,					SAMPLES_TEXTURE,	SAMPLES_NONE } },
		{ { 2,					1,					SAMPLES_NONE } },
		{ { 2,					2,					SAMPLES_NONE } },
		{ { 0,					0,					SAMPLES_TEXTURE } },
		{ { 1,					2,					0 } },
		{ { 2,					2,					0 } },
		{ { 1,					1,					1 } },
		{ { 1,					2,					4 } },
	};

	for (const NumSamplesParams* lp	=	DE_ARRAY_BEGIN(s_samplesParams);
		 lp							!=  DE_ARRAY_END(s_samplesParams);
		 ++lp)
		sampleTests->addChild(new NumSamplesTest(m_fboc, *lp));

	addChild(sampleTests);
}

TestGroup::TestGroup (Context& ctx)
	: TestCaseGroup		(ctx, "completeness", "Completeness tests")
	, m_checkerFactory	()
	, m_fboc			(ctx.getTestContext(), ctx.getRenderContext(), m_checkerFactory)
{
	const FormatEntries stdRange = GLS_ARRAY_RANGE(s_es3Formats);
	const FormatExtEntries extRange = GLS_ARRAY_RANGE(s_es3ExtFormats);

	m_fboc.addFormats(stdRange);
	m_fboc.addExtFormats(extRange);
	m_fboc.setHaveMulticolorAtts(true); // Vanilla ES3 has multiple color attachments
}

tcu::TestCaseGroup* createFboCompletenessTests (Context& context)
{
	return new TestGroup(context);
}

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