/*-------------------------------------------------------------------------
 * 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 "deUniquePtr.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, const FormatDB& formats)
					: Checker				(ctx, formats)
					, m_ctxInfo				(glu::ContextInfo::create(ctx))
					, m_numSamples			(-1)
					, m_depthStencilImage	(0)
					, m_depthStencilType	(GL_NONE) {}
	void		check		(GLenum attPoint, const Attachment& att, const Image* image);

private:
	de::UniquePtr<glu::ContextInfo> m_ctxInfo;

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

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

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

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

			// "The combination of internal formats of the attached images does not violate
			//  an implementation-dependent set of restrictions."
			ImageFormat depthFormat = attPoint == GL_DEPTH_ATTACHMENT ? image->internalFormat : m_depthStencilFormat;
			ImageFormat stencilFormat = attPoint == GL_STENCIL_ATTACHMENT ? image->internalFormat : m_depthStencilFormat;
			if (m_formats.getFormatInfo(depthFormat) & STENCIL_RENDERABLE)
				addPotentialFBOStatus(GL_FRAMEBUFFER_UNSUPPORTED, "Separate depth attachment has combined depth and stencil format");
			if (m_formats.getFormatInfo(stencilFormat) & DEPTH_RENDERABLE)
				addPotentialFBOStatus(GL_FRAMEBUFFER_UNSUPPORTED, "Separate stencil attachment has combined depth and stencil format");
		}
	}
}

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, const FormatDB& formats) { return new ES3Checker(ctx, formats); }
};

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
