/*-------------------------------------------------------------------------
 * 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.");

	glw::GLuint vao = 0;
	bool isES = glu::isContextTypeES(ctx.getRenderContext().getType());
	if (!isES)
	{
		ctx.glGenVertexArrays(1, &vao);
		ctx.glBindVertexArray(vao);
	}

	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();

	if (!isES)
		ctx.glDeleteVertexArrays(1, &vao);
}

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			vao				= 0;
	glw::GLuint			fbo				= 0x1234;
	glw::GLuint			texture			= 0x1234;
	const glw::GLenum	attachments[]	= { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
	const bool			isES			= glu::isContextTypeES(ctx.getRenderContext().getType());

	if (!isES)
	{
		ctx.glGenVertexArrays(1, &vao);
		ctx.glBindVertexArray(vao);
	}

	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();

	if (!isES)
		ctx.glDeleteVertexArrays(1, &vao);

	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
