/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2016 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 Negative Advanced Blend Equation Tests
 *//*--------------------------------------------------------------------*/

#include "es31fNegativeAdvancedBlendEquationTests.hpp"

#include "gluShaderProgram.hpp"
#include "glwEnums.hpp"

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace NegativeTestShared
{
namespace
{

enum BlendEquation
{
	BLEND_EQUATION_MULTIPLY = 0,
	BLEND_EQUATION_SCREEN,
	BLEND_EQUATION_OVERLAY,
	BLEND_EQUATION_DARKEN,
	BLEND_EQUATION_LIGHTEN,
	BLEND_EQUATION_COLORDODGE,
	BLEND_EQUATION_COLORBURN,
	BLEND_EQUATION_HARDLIGHT,
	BLEND_EQUATION_SOFTLIGHT,
	BLEND_EQUATION_DIFFERENCE,
	BLEND_EQUATION_EXCLUSION,
	BLEND_EQUATION_HSL_HUE,
	BLEND_EQUATION_HSL_SATURATION,
	BLEND_EQUATION_HSL_COLOR,
	BLEND_EQUATION_HSL_LUMINOSITY,
	BLEND_EQUATION_ALL_EQUATIONS,

	BLEND_EQUATION_LAST
};

static const BlendEquation s_equations[] =
{
	BLEND_EQUATION_MULTIPLY,
	BLEND_EQUATION_SCREEN,
	BLEND_EQUATION_OVERLAY,
	BLEND_EQUATION_DARKEN,
	BLEND_EQUATION_LIGHTEN,
	BLEND_EQUATION_COLORDODGE,
	BLEND_EQUATION_COLORBURN,
	BLEND_EQUATION_HARDLIGHT,
	BLEND_EQUATION_SOFTLIGHT,
	BLEND_EQUATION_DIFFERENCE,
	BLEND_EQUATION_EXCLUSION,
	BLEND_EQUATION_HSL_HUE,
	BLEND_EQUATION_HSL_SATURATION,
	BLEND_EQUATION_HSL_COLOR,
	BLEND_EQUATION_HSL_LUMINOSITY
};

std::string getShaderLayoutEquation (BlendEquation equation)
{
	switch (equation)
	{
		case BLEND_EQUATION_MULTIPLY:          return "blend_support_multiply";
		case BLEND_EQUATION_SCREEN:            return "blend_support_screen";
		case BLEND_EQUATION_OVERLAY:           return "blend_support_overlay";
		case BLEND_EQUATION_DARKEN:            return "blend_support_darken";
		case BLEND_EQUATION_LIGHTEN:           return "blend_support_lighten";
		case BLEND_EQUATION_COLORDODGE:        return "blend_support_colordodge";
		case BLEND_EQUATION_COLORBURN:         return "blend_support_colorburn";
		case BLEND_EQUATION_HARDLIGHT:         return "blend_support_hardlight";
		case BLEND_EQUATION_SOFTLIGHT:         return "blend_support_softlight";
		case BLEND_EQUATION_DIFFERENCE:        return "blend_support_difference";
		case BLEND_EQUATION_EXCLUSION:         return "blend_support_exclusion";
		case BLEND_EQUATION_HSL_HUE:           return "blend_support_hsl_hue";
		case BLEND_EQUATION_HSL_SATURATION:    return "blend_support_hsl_saturation";
		case BLEND_EQUATION_HSL_COLOR:         return "blend_support_hsl_color";
		case BLEND_EQUATION_HSL_LUMINOSITY:    return "blend_support_hsl_luminosity";
		case BLEND_EQUATION_ALL_EQUATIONS:     return "blend_support_all_equations";
		default:
			DE_FATAL("Equation not supported.");
	}
	return "";
}

glw::GLenum getEquation (BlendEquation equation)
{
	switch (equation)
	{
		case BLEND_EQUATION_MULTIPLY:          return GL_MULTIPLY;
		case BLEND_EQUATION_SCREEN:            return GL_SCREEN;
		case BLEND_EQUATION_OVERLAY:           return GL_OVERLAY;
		case BLEND_EQUATION_DARKEN:            return GL_DARKEN;
		case BLEND_EQUATION_LIGHTEN:           return GL_LIGHTEN;
		case BLEND_EQUATION_COLORDODGE:        return GL_COLORDODGE;
		case BLEND_EQUATION_COLORBURN:         return GL_COLORBURN;
		case BLEND_EQUATION_HARDLIGHT:         return GL_HARDLIGHT;
		case BLEND_EQUATION_SOFTLIGHT:         return GL_SOFTLIGHT;
		case BLEND_EQUATION_DIFFERENCE:        return GL_DIFFERENCE;
		case BLEND_EQUATION_EXCLUSION:         return GL_EXCLUSION;
		case BLEND_EQUATION_HSL_HUE:           return GL_HSL_HUE;
		case BLEND_EQUATION_HSL_SATURATION:    return GL_HSL_SATURATION;
		case BLEND_EQUATION_HSL_COLOR:         return GL_HSL_COLOR;
		case BLEND_EQUATION_HSL_LUMINOSITY:    return GL_HSL_LUMINOSITY;
		default:
			DE_FATAL("Equation not supported.");
	}
	return DE_NULL;
}

std::string generateVertexShaderSource (NegativeTestContext& ctx)
{
	const bool				supportsES32	= contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	const glu::GLSLVersion	version	= supportsES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
	std::ostringstream		source;

	source	<< glu::getGLSLVersionDeclaration(version) << "\n"
			<< "void main ()\n"
			<< "{\n"
			<< "	gl_Position = vec4(0.0);\n"
			<< "}\n";

	return source.str();
}

std::string generateFragmentShaderSource (NegativeTestContext& ctx, BlendEquation equation)
{
	const bool				supportsES32	= contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	const glu::GLSLVersion	version	= supportsES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
	std::ostringstream		source;

	source	<< glu::getGLSLVersionDeclaration(version) << "\n"
			<< (supportsES32 ? "" : "#extension GL_KHR_blend_equation_advanced : enable\n")
			<< "layout(" << getShaderLayoutEquation(equation) << ") out;\n"
			<< "layout(location=0) out mediump vec4 o_color;\n"
			<< "void main ()\n"
			<< "{\n"
			<< "	o_color = vec4(0);\n"
			<< "}\n";

	return source.str();
}

glu::ProgramSources generateProgramSources (NegativeTestContext& ctx, BlendEquation equation)
{
	return glu::ProgramSources()
		<< glu::VertexSource(generateVertexShaderSource(ctx))
		<< glu::FragmentSource(generateFragmentShaderSource(ctx, equation));
}

void blend_qualifier_mismatch (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError,
		ctx.isExtensionSupported("GL_KHR_blend_equation_advanced") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
		"This test requires support for the extension GL_KHR_blend_equation_advanced or context version 3.2 or higher.");

	ctx.beginSection("GL_INVALID_OPERATION is generated if blending is enabled, and the blend qualifier is different from blend_support_all_equations and does not match the blend equation.");
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
	{
		glu::ShaderProgram program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx]));

		ctx.getLog() << program;
		TCU_CHECK(program.isOk());

		ctx.glUseProgram(program.getProgram());
		ctx.expectError(GL_NO_ERROR);

		for (int ndx2 = 0; ndx2 < DE_LENGTH_OF_ARRAY(s_equations); ++ndx2)
		{
			if (s_equations[ndx] == s_equations[ndx2])
				continue;

			ctx.glEnable(GL_BLEND);
			ctx.glBlendEquation(getEquation(s_equations[ndx2]));
			ctx.expectError(GL_NO_ERROR);
			ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
			ctx.expectError(GL_INVALID_OPERATION);

			ctx.glDisable(GL_BLEND);
			ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
			ctx.expectError(GL_NO_ERROR);
		}
	}
	ctx.endSection();
}

void attachment_advanced_equation (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError,
		ctx.isExtensionSupported("GL_KHR_blend_equation_advanced") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
		"This test requires support for the extension GL_KHR_blend_equation_advanced or context version 3.2 or higher.");

	glw::GLuint			fbo				= 0x1234;
	glw::GLuint			texture			= 0x1234;
	const glw::GLenum	attachments[]	= { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };

	ctx.glGenTextures(1, &texture);
	ctx.glBindTexture(GL_TEXTURE_2D, texture);
	ctx.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	ctx.glGenFramebuffers(1, &fbo);
	ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
	ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
	ctx.expectError(GL_NO_ERROR);
	ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);

	ctx.beginSection("GL_INVALID_OPERATION is generated if blending is enabled, advanced equations are used, and the draw buffer for other color outputs is not NONE unless NVX_blend_equation_advanced_multi_draw_buffers is supported.");
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
	{
		glu::ShaderProgram	program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx]));
		ctx.getLog() << program;
		TCU_CHECK(program.isOk());

		ctx.glUseProgram(program.getProgram());
		ctx.glEnable(GL_BLEND);
		ctx.glDrawBuffers(2, attachments);
		ctx.expectError(GL_NO_ERROR);
		ctx.glBlendEquation(getEquation(s_equations[ndx]));
		ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
		if (ctx.isExtensionSupported("GL_NVX_blend_equation_advanced_multi_draw_buffers"))
			ctx.expectError(GL_NO_ERROR);
		else
			ctx.expectError(GL_INVALID_OPERATION);
	}
	ctx.endSection();

	ctx.beginSection("GL_NO_ERROR is generated if no advanced blend equations are used.");
	ctx.glBlendEquation(GL_FUNC_ADD);
	ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
	ctx.expectError(GL_NO_ERROR);
	ctx.endSection();

	ctx.beginSection("GL_NO_ERROR is generated if blending is disabled.");
	ctx.glDisable(GL_BLEND);
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
	{
		ctx.glBlendEquation(getEquation(s_equations[ndx]));
		ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
		ctx.expectError(GL_NO_ERROR);
	}
	ctx.endSection();

	ctx.glDeleteFramebuffers(1, &fbo);
	ctx.glDeleteTextures(1, &texture);
}

} // anonymous

std::vector<FunctionContainer> getNegativeAdvancedBlendEquationTestFunctions (void)
{
	const FunctionContainer funcs[] =
	{
		{blend_qualifier_mismatch,			"blend_qualifier_mismatch",			"Test blend qualifier mismatch."			},
		{attachment_advanced_equation,		"attachment_advanced_equation",		"Test draw buffer for other color outputs." },
	};

	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
}

} // NegativeTestShared
} // Functional
} // gles31
} // deqp
