/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2014-2016 The Khronos Group Inc.
 *
 * 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
 */ /*-------------------------------------------------------------------*/

#include "glcBlendEquationAdvancedTests.hpp"
// de
#include "deRandom.hpp"
#include "deString.h"
// tcu
#include "tcuRGBA.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"
#include "tcuVectorType.hpp"
#include "tcuVectorUtil.hpp"
// glu
#include "gluContextInfo.hpp"
#include "gluDrawUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderProgram.hpp"
// glw
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
// de
#include "deMath.h"
// stl
#include <algorithm>
#include <map>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

namespace glcts
{
using tcu::TestLog;

static const float	s_pos[]	 = { -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f };
static const deUint16 s_indices[] = { 0, 1, 2, 2, 1, 3 };

// Lists all modes introduced by the extension.
static const glw::GLenum s_modes[] = { GL_MULTIPLY_KHR,		  GL_SCREEN_KHR,	 GL_OVERLAY_KHR,	   GL_DARKEN_KHR,
									   GL_LIGHTEN_KHR,		  GL_COLORDODGE_KHR, GL_COLORBURN_KHR,	 GL_HARDLIGHT_KHR,
									   GL_SOFTLIGHT_KHR,	  GL_DIFFERENCE_KHR, GL_EXCLUSION_KHR,	 GL_HSL_HUE_KHR,
									   GL_HSL_SATURATION_KHR, GL_HSL_COLOR_KHR,  GL_HSL_LUMINOSITY_KHR };

static const char* GetModeStr(glw::GLenum mode)
{
	switch (mode)
	{
	case GL_MULTIPLY_KHR:
		return "GL_MULTIPLY_KHR";
	case GL_SCREEN_KHR:
		return "GL_SCREEN_KHR";
	case GL_OVERLAY_KHR:
		return "GL_OVERLAY_KHR";
	case GL_DARKEN_KHR:
		return "GL_DARKEN_KHR";
	case GL_LIGHTEN_KHR:
		return "GL_LIGHTEN_KHR";
	case GL_COLORDODGE_KHR:
		return "GL_COLORDODGE_KHR";
	case GL_COLORBURN_KHR:
		return "GL_COLORBURN_KHR";
	case GL_HARDLIGHT_KHR:
		return "GL_HARDLIGHT_KHR";
	case GL_SOFTLIGHT_KHR:
		return "GL_SOFTLIGHT_KHR";
	case GL_DIFFERENCE_KHR:
		return "GL_DIFFERENCE_KHR";
	case GL_EXCLUSION_KHR:
		return "GL_EXCLUSION_KHR";
	case GL_HSL_HUE_KHR:
		return "GL_HSL_HUE_KHR";
	case GL_HSL_SATURATION_KHR:
		return "GL_HSL_SATURATION_KHR";
	case GL_HSL_COLOR_KHR:
		return "GL_HSL_COLOR_KHR";
	case GL_HSL_LUMINOSITY_KHR:
		return "GL_HSL_LUMINOSITY_KHR";
	default:
		DE_ASSERT(DE_FALSE && "Blend mode not from GL_KHR_blend_equation_advanced.");
		return "Blend mode not from GL_KHR_blend_equation_advanced.";
	}
}

static const char* GetLayoutQualifierStr(glw::GLenum mode)
{
	switch (mode)
	{
	case GL_MULTIPLY_KHR:
		return "blend_support_multiply";
	case GL_SCREEN_KHR:
		return "blend_support_screen";
	case GL_OVERLAY_KHR:
		return "blend_support_overlay";
	case GL_DARKEN_KHR:
		return "blend_support_darken";
	case GL_LIGHTEN_KHR:
		return "blend_support_lighten";
	case GL_COLORDODGE_KHR:
		return "blend_support_colordodge";
	case GL_COLORBURN_KHR:
		return "blend_support_colorburn";
	case GL_HARDLIGHT_KHR:
		return "blend_support_hardlight";
	case GL_SOFTLIGHT_KHR:
		return "blend_support_softlight";
	case GL_DIFFERENCE_KHR:
		return "blend_support_difference";
	case GL_EXCLUSION_KHR:
		return "blend_support_exclusion";
	case GL_HSL_HUE_KHR:
		return "blend_support_hsl_hue";
	case GL_HSL_SATURATION_KHR:
		return "blend_support_hsl_saturation";
	case GL_HSL_COLOR_KHR:
		return "blend_support_hsl_color";
	case GL_HSL_LUMINOSITY_KHR:
		return "blend_support_hsl_luminosity";
	default:
		DE_ASSERT(DE_FALSE && "Blend mode not from GL_KHR_blend_equation_advanced.");
		return "Blend mode not from GL_KHR_blend_equation_advanced.";
	}
}

static bool IsExtensionSupported(deqp::Context& context, const char* extension)
{
	const std::vector<std::string>& v = context.getContextInfo().getExtensions();
	return std::find(v.begin(), v.end(), extension) != v.end();
}

static float GetP0(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	return src[3] * dst[3];
}
static float GetP1(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	return src[3] * (1.f - dst[3]);
}
static float GetP2(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	return dst[3] * (1.f - src[3]);
}

static tcu::Vec4 Blend(const tcu::Vec4& rgb, const tcu::Vec4& src, const tcu::Vec4& dst)
{
	float	 p[3]   = { GetP0(src, dst), GetP1(src, dst), GetP2(src, dst) };
	float	 alpha  = p[0] + p[1] + p[2];
	tcu::Vec4 rgbOut = (p[0] * rgb) + (p[1] * src) + (p[2] * dst);
	return tcu::Vec4(rgbOut[0], rgbOut[1], rgbOut[2], alpha);
}

static tcu::Vec4 BlendMultiply(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb = src * dst;

	return Blend(rgb, src, dst);
}

static tcu::Vec4 BlendScreen(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb = src + dst - src * dst;

	return Blend(rgb, src, dst);
}

static float Overlay(float s, float d)
{
	if (d <= 0.5f)
		return 2.f * s * d;
	else
		return 1.f - 2.f * (1.f - s) * (1.f - d);
}

static tcu::Vec4 BlendOverlay(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb(Overlay(src[0], dst[0]), Overlay(src[1], dst[1]), Overlay(src[2], dst[2]), 0.f);

	return Blend(rgb, src, dst);
}

static tcu::Vec4 BlendDarken(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb(de::min(src[0], dst[0]), de::min(src[1], dst[1]), de::min(src[2], dst[2]), 0.f);

	return Blend(rgb, src, dst);
}

static tcu::Vec4 BlendLighten(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb(de::max(src[0], dst[0]), de::max(src[1], dst[1]), de::max(src[2], dst[2]), 0.f);

	return Blend(rgb, src, dst);
}

static float ColorDodge(float s, float d)
{
	if (d <= 0.f)
		return 0.f;
	else if (d > 0.f && s < 1.f)
		return de::min(1.f, d / (1.f - s));
	else
		return 1.f;
}

static tcu::Vec4 BlendColorDodge(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb(ColorDodge(src[0], dst[0]), ColorDodge(src[1], dst[1]), ColorDodge(src[2], dst[2]), 0.f);

	return Blend(rgb, src, dst);
}

static float ColorBurn(float s, float d)
{
	if (d >= 1.f)
		return 1.f;
	else if (d < 1.f && s > 0.f)
		return 1.f - de::min(1.f, (1.f - d) / s);
	else
	{
		DE_ASSERT(d < 1.f && s <= 0.f);
		return 0.f;
	}
}

static tcu::Vec4 BlendColorBurn(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb(ColorBurn(src[0], dst[0]), ColorBurn(src[1], dst[1]), ColorBurn(src[2], dst[2]), 0.f);

	return Blend(rgb, src, dst);
}

static float HardLight(float s, float d)
{
	if (s <= 0.5f)
		return 2.f * s * d;
	else
		return 1.f - 2.f * (1.f - s) * (1.f - d);
}

static tcu::Vec4 BlendHardLight(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb(HardLight(src[0], dst[0]), HardLight(src[1], dst[1]), HardLight(src[2], dst[2]), 0.f);

	return Blend(rgb, src, dst);
}

static float SoftLight(float s, float d)
{
	if (s <= 0.5f)
		return d - (1.f - 2.f * s) * d * (1.f - d);
	else if (d <= 0.25f)
	{
		DE_ASSERT(s > 0.5f && d <= 0.25f);
		return d + (2.f * s - 1.f) * d * ((16.f * d - 12.f) * d + 3.f);
	}
	else
	{
		DE_ASSERT(s > 0.5f && d > 0.25f);
		return d + (2.f * s - 1.f) * (deFloatSqrt(d) - d);
	}
}

static tcu::Vec4 BlendSoftLight(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb(SoftLight(src[0], dst[0]), SoftLight(src[1], dst[1]), SoftLight(src[2], dst[2]), 0.f);

	return Blend(rgb, src, dst);
}

static tcu::Vec4 BlendDifference(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb(deFloatAbs(src[0] - dst[0]), deFloatAbs(src[1] - dst[1]), deFloatAbs(src[2] - dst[2]), 0.f);

	return Blend(rgb, src, dst);
}

static float Exclusion(float s, float d)
{
	return s + d - 2.f * s * d;
}

static tcu::Vec4 BlendExclusion(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb(Exclusion(src[0], dst[0]), Exclusion(src[1], dst[1]), Exclusion(src[2], dst[2]), 0.f);
	return Blend(rgb, src, dst);
}

static float Luminance(const tcu::Vec4& rgba)
{
	// Coefficients from the KHR_GL_blend_equation_advanced test spec.
	return 0.30f * rgba[0] + 0.59f * rgba[1] + 0.11f * rgba[2];
}

// Minimum of R, G and B components.
static float MinRGB(const tcu::Vec4& rgba)
{
	return deFloatMin(deFloatMin(rgba[0], rgba[1]), rgba[2]);
}

// Maximum of R, G and B components.
static float MaxRGB(const tcu::Vec4& rgba)
{
	return deFloatMax(deFloatMax(rgba[0], rgba[1]), rgba[2]);
}

static float Saturation(const tcu::Vec4& rgba)
{
	return MaxRGB(rgba) - MinRGB(rgba);
}

// Take the base RGB color <cbase> and override its luminosity
// with that of the RGB color <clum>.
static tcu::Vec4 SetLum(const tcu::Vec4& cbase, const tcu::Vec4& clum)
{
	float	 lbase = Luminance(cbase);
	float	 llum  = Luminance(clum);
	float	 ldiff = llum - lbase;
	tcu::Vec4 color = cbase + tcu::Vec4(ldiff);
	tcu::Vec4 vllum = tcu::Vec4(llum);
	if (MinRGB(color) < 0.0f)
	{
		return vllum + ((color - vllum) * llum) / (llum - MinRGB(color));
	}
	else if (MaxRGB(color) > 1.0f)
	{
		return vllum + ((color - vllum) * (1.f - llum)) / (MaxRGB(color) - llum);
	}
	else
	{
		return color;
	}
}

// Take the base RGB color <cbase> and override its saturation with
// that of the RGB color <csat>.  The override the luminosity of the
// result with that of the RGB color <clum>.
static tcu::Vec4 SetLumSat(const tcu::Vec4& cbase, const tcu::Vec4& csat, const tcu::Vec4& clum)
{
	float	 minbase = MinRGB(cbase);
	float	 sbase   = Saturation(cbase);
	float	 ssat	= Saturation(csat);
	tcu::Vec4 color;
	if (sbase > 0)
	{
		// From the extension spec:
		// Equivalent (modulo rounding errors) to setting the
		// smallest (R,G,B) component to 0, the largest to <ssat>,
		// and interpolating the "middle" component based on its
		// original value relative to the smallest/largest.
		color = (cbase - tcu::Vec4(minbase)) * ssat / sbase;
	}
	else
	{
		color = tcu::Vec4(0.0f);
	}
	return SetLum(color, clum);
}

static tcu::Vec4 BlendHSLHue(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb = SetLumSat(src, dst, dst);
	return Blend(rgb, src, dst);
}

static tcu::Vec4 BlendHSLSaturation(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb = SetLumSat(dst, src, dst);
	return Blend(rgb, src, dst);
}

static tcu::Vec4 BlendHSLColor(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb = SetLum(src, dst);
	return Blend(rgb, src, dst);
}

static tcu::Vec4 BlendHSLuminosity(const tcu::Vec4& src, const tcu::Vec4& dst)
{
	tcu::Vec4 rgb = SetLum(dst, src);
	return Blend(rgb, src, dst);
}

typedef tcu::Vec4 (*BlendFunc)(const tcu::Vec4& src, const tcu::Vec4& dst);

static BlendFunc GetBlendFunc(glw::GLenum mode)
{
	switch (mode)
	{
	case GL_MULTIPLY_KHR:
		return BlendMultiply;
	case GL_SCREEN_KHR:
		return BlendScreen;
	case GL_OVERLAY_KHR:
		return BlendOverlay;
	case GL_DARKEN_KHR:
		return BlendDarken;
	case GL_LIGHTEN_KHR:
		return BlendLighten;
	case GL_COLORDODGE_KHR:
		return BlendColorDodge;
	case GL_COLORBURN_KHR:
		return BlendColorBurn;
	case GL_HARDLIGHT_KHR:
		return BlendHardLight;
	case GL_SOFTLIGHT_KHR:
		return BlendSoftLight;
	case GL_DIFFERENCE_KHR:
		return BlendDifference;
	case GL_EXCLUSION_KHR:
		return BlendExclusion;
	case GL_HSL_HUE_KHR:
		return BlendHSLHue;
	case GL_HSL_SATURATION_KHR:
		return BlendHSLSaturation;
	case GL_HSL_COLOR_KHR:
		return BlendHSLColor;
	case GL_HSL_LUMINOSITY_KHR:
		return BlendHSLuminosity;
	default:
		DE_ASSERT(DE_FALSE && "Blend mode not from GL_KHR_blend_equation_advanced.");
		return NULL;
	}
}

static tcu::Vec4 ToNormal(const tcu::Vec4& v)
{
	float a = v[3];
	if (a == 0)
		return tcu::Vec4(0.f, 0.f, 0.f, 0.f);
	return tcu::Vec4(v[0] / a, v[1] / a, v[2] / a, a);
}

// Blend premultiplied src and dst with given blend mode.
static tcu::Vec4 Blend(glw::GLenum mode, const tcu::Vec4& src, const tcu::Vec4& dst)
{
	BlendFunc blend   = GetBlendFunc(mode);
	tcu::Vec4 srcNorm = ToNormal(src);
	tcu::Vec4 dstNorm = ToNormal(dst);

	return blend(srcNorm, dstNorm);
}

static std::string GetDef2DVtxSrc(glu::GLSLVersion glslVersion)
{
	std::stringstream str;

	DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion >= glu::GLSL_VERSION_430);

	str << glu::getGLSLVersionDeclaration(glslVersion) << "\n"
		<< "in highp vec2 aPos;\n"
		   "void main() {\n"
		   "   gl_Position = vec4(aPos, 0.0, 1.0);\n"
		   "}\n";
	return str.str();
}

static std::string GetSolidShader(
	const char* layoutQualifier, const char* glslVersion,
	const char* extensionDirective = "#extension GL_KHR_blend_equation_advanced : require")
{
	static const char* frgSrcTemplate = "${VERSION_DIRECTIVE}\n"
										"${EXTENSION_DIRECTIVE}\n"
										"\n"
										"precision highp float;\n"
										"\n"
										"${LAYOUT_QUALIFIER}\n"
										"layout (location = 0) out vec4 oCol;\n"
										"\n"
										"uniform vec4 uSrcCol;\n"
										"\n"
										"void main (void) {\n"
										"   oCol = uSrcCol;\n"
										"}\n";

	std::map<std::string, std::string> args;
	args["VERSION_DIRECTIVE"]   = glslVersion;
	args["EXTENSION_DIRECTIVE"] = extensionDirective;
	if (layoutQualifier)
		args["LAYOUT_QUALIFIER"] = std::string("layout (") + layoutQualifier + std::string(") out;");
	else
		args["LAYOUT_QUALIFIER"] = ""; // none

	return tcu::StringTemplate(frgSrcTemplate).specialize(args);
}

/*
 * Framebuffer helper.
 * Creates and binds FBO and either one or two renderbuffer color attachments (fmt0, fmt1) with
 * given size (width, height).
 *
 * Note: Does not restore previous 1) fbo binding, 2) scissor or 3) viewport upon exit.
 */
class FBOSentry
{
public:
	FBOSentry(const glw::Functions& gl, int width, int height, glw::GLenum fmt0);
	FBOSentry(const glw::Functions& gl, int width, int height, glw::GLenum fmt0, glw::GLenum fmt1);
	~FBOSentry();

private:
	void init(int width, int height, glw::GLenum fmt0, glw::GLenum fmt1);
	const glw::Functions& m_gl;
	glw::GLuint			  m_fbo;
	glw::GLuint			  m_rbo[2];
};

FBOSentry::FBOSentry(const glw::Functions& gl, int width, int height, glw::GLenum fmt0) : m_gl(gl)
{
	init(width, height, fmt0, GL_NONE);
}

FBOSentry::FBOSentry(const glw::Functions& gl, int width, int height, glw::GLenum fmt0, glw::GLenum fmt1) : m_gl(gl)
{
	init(width, height, fmt0, fmt1);
}

FBOSentry::~FBOSentry()
{
	m_gl.deleteFramebuffers(1, &m_fbo);
	m_gl.deleteRenderbuffers(2, m_rbo);
}

void FBOSentry::init(int width, int height, glw::GLenum fmt0, glw::GLenum fmt1)
{
	m_gl.genFramebuffers(1, &m_fbo);
	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);

	m_gl.genRenderbuffers(2, m_rbo);
	m_gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo[0]);
	m_gl.renderbufferStorage(GL_RENDERBUFFER, fmt0, width, height);
	m_gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo[0]);

	if (fmt1 != GL_NONE)
	{
		m_gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo[1]);
		m_gl.renderbufferStorage(GL_RENDERBUFFER, fmt1, width, height);
		m_gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, m_rbo[1]);
	}

	glw::GLenum status = m_gl.checkFramebufferStatus(GL_FRAMEBUFFER);
	if (m_gl.getError() != GL_NO_ERROR || status != GL_FRAMEBUFFER_COMPLETE)
	{
		TCU_FAIL("Framebuffer failed");
	}

	m_gl.viewport(0, 0, width, height);
	m_gl.scissor(0, 0, width, height);
}

class CoherentBlendTestCaseGroup : public deqp::TestCaseGroup
{
public:
	CoherentBlendTestCaseGroup(deqp::Context& context, glu::GLSLVersion glslVersion)
		: TestCaseGroup(context, "test_coherency", ""), m_glslVersion(glslVersion)
	{
	}

	void init(void)
	{
		addChild(
			new CoherentBlendTest(m_context, "mixedSequence", m_glslVersion, 4, DE_LENGTH_OF_ARRAY(s_mixed), s_mixed));
		addChild(new CoherentBlendTest(m_context, "multiplySequence", m_glslVersion, 1, DE_LENGTH_OF_ARRAY(s_multiply),
									   s_multiply));
	}

private:
	struct BlendStep;

	class CoherentBlendTest : public deqp::TestCase
	{
	public:
		CoherentBlendTest(deqp::Context& context, const char* name, glu::GLSLVersion glslVersion, int repeatCount,
						  int numSteps, const BlendStep* steps)
			: TestCase(context, name, "")
			, m_glslVersion(glslVersion)
			, m_repeatCount(repeatCount)
			, m_numSteps(numSteps)
			, m_steps(steps)
		{
			DE_ASSERT(repeatCount > 0 && numSteps > 0 && steps);
		}

		IterateResult iterate(void);

	private:
		glu::GLSLVersion m_glslVersion;
		int				 m_repeatCount;
		int				 m_numSteps;
		const BlendStep* m_steps;
	};

	struct BlendStep
	{
		glw::GLenum  mode;
		glw::GLfloat src[4]; // rgba
	};

	// Blend sequences.
	static const BlendStep s_mixed[11];
	static const BlendStep s_multiply[7];

	glu::GLSLVersion m_glslVersion;
};

const CoherentBlendTestCaseGroup::BlendStep CoherentBlendTestCaseGroup::s_mixed[] = {
	{ GL_LIGHTEN_KHR, { 0.250f, 0.375f, 1.000f, 1.000f } },	// =>  (0.250, 0.375, 1.000, 1.000) (from src)
	{ GL_OVERLAY_KHR, { 1.000f, 1.000f, 1.000f, 1.000f } },	// => ~(0.500, 0.750, 1.000, 1.000)
	{ GL_HARDLIGHT_KHR, { 0.750f, 0.750f, 0.250f, 1.000f } },  // => ~(0.750, 1.000, 0.500, 1.000)
	{ GL_DARKEN_KHR, { 0.250f, 0.250f, 0.250f, 1.000f } },	 // =>  (0.250, 0.250, 0.250, 1.000) (from src)
	{ GL_COLORDODGE_KHR, { 0.750f, 0.875f, 1.000f, 1.000f } }, // => ~(1.000, 1.000, 1.000, 1.000)
	{ GL_MULTIPLY_KHR, { 0.500f, 0.500f, 0.500f, 1.000f } },   // => ~(0.500, 0.500, 0.500, 1.000)
	{ GL_SCREEN_KHR, { 0.500f, 0.500f, 0.500f, 1.000f } },	 // => ~(0.750, 0.750, 0.750, 1.000)
	{ GL_DARKEN_KHR, { 0.250f, 0.500f, 0.500f, 1.000f } },	 // =>  (0.250, 0.500, 0.500, 1.000) (from src)
	{ GL_DIFFERENCE_KHR, { 0.000f, 0.875f, 0.125f, 1.000f } }, // => ~(0.250, 0.375, 0.375, 1.000)
	{ GL_EXCLUSION_KHR, { 1.000f, 0.500f, 0.750f, 1.000f } },  // => ~(0.750, 0.500, 0.563, 1.000)
	{ GL_DARKEN_KHR, { 0.125f, 0.125f, 0.125f, 1.000f } },	 // =>  (0.125, 0.125, 0.125, 1.000) (from src)
	// Last row is unique and "accurate" since it comes from the source.
	// That means so that it can be easily tested for correctness.
};

const CoherentBlendTestCaseGroup::BlendStep CoherentBlendTestCaseGroup::s_multiply[] = {
	{ GL_LIGHTEN_KHR, { 1.000f, 1.000f, 1.000f, 1.000f } },  { GL_MULTIPLY_KHR, { 0.500f, 0.500f, 0.500f, 1.000f } },
	{ GL_MULTIPLY_KHR, { 0.500f, 0.500f, 0.500f, 1.000f } }, { GL_MULTIPLY_KHR, { 0.500f, 0.500f, 0.500f, 1.000f } },
	{ GL_MULTIPLY_KHR, { 0.500f, 0.500f, 0.500f, 1.000f } }, { GL_MULTIPLY_KHR, { 0.500f, 0.500f, 0.500f, 1.000f } },
	{ GL_MULTIPLY_KHR, { 0.500f, 0.500f, 0.500f, 1.000f } }, // ~4 in 8bits
};

CoherentBlendTestCaseGroup::CoherentBlendTest::IterateResult CoherentBlendTestCaseGroup::CoherentBlendTest::iterate(
	void)
{
	static const int		 dim = 1024;
	const tcu::RenderTarget& rt  = m_context.getRenderContext().getRenderTarget();
	const tcu::PixelFormat&  pf  = rt.getPixelFormat();
	const glw::Functions&	gl  = m_context.getRenderContext().getFunctions();
	TestLog&				 log = m_testCtx.getLog();

	// Check that extension is supported.
	if (!IsExtensionSupported(m_context, "GL_KHR_blend_equation_advanced"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_KHR_blend_equation_advanced");
		return STOP;
	}

	bool needBarrier = !IsExtensionSupported(m_context, "GL_KHR_blend_equation_advanced_coherent");

	tcu::Vec4 dstCol(0.f, 0.f, 0.f, 0.f);

	FBOSentry fbo(gl, dim, dim, GL_RGBA8);

	// Setup progra
	std::string frgSrc = GetSolidShader("blend_support_all_equations", glu::getGLSLVersionDeclaration(m_glslVersion));
	glu::ShaderProgram p(m_context.getRenderContext(),
						 glu::makeVtxFragSources(GetDef2DVtxSrc(m_glslVersion).c_str(), frgSrc.c_str()));
	if (!p.isOk())
	{
		log << p;
		TCU_FAIL("Compile failed");
	}
	gl.useProgram(p.getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Program failed");

	glu::VertexArrayBinding posBinding = glu::va::Float("aPos", 2, 4, 0, &s_pos[0]);

	// Enable blending.
	gl.disable(GL_DITHER);
	gl.enable(GL_BLEND);

	// Clear.
	gl.clearColor(dstCol[0], dstCol[1], dstCol[2], dstCol[3]);
	gl.clear(GL_COLOR_BUFFER_BIT);

	// Blend barrier.
	if (needBarrier)
		gl.blendBarrier();

	// Repeat block.
	for (int i = 0; i < m_repeatCount; i++)
		// Loop blending steps.
		for (int j = 0; j < m_numSteps; j++)
		{
			const BlendStep& s = m_steps[j];
			tcu::Vec4		 srcCol(s.src[0], s.src[1], s.src[2], s.src[3]);
			tcu::Vec4		 refCol = Blend(s.mode, srcCol, dstCol);
			dstCol					= refCol;

			// Set blend equation.
			gl.blendEquation(s.mode);
			GLU_EXPECT_NO_ERROR(gl.getError(), "BlendEquation failed");

			// Set source color.
			gl.uniform4f(gl.getUniformLocation(p.getProgram(), "uSrcCol"), srcCol[0], srcCol[1], srcCol[2], srcCol[3]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Uniforms failed");

			// Draw.
			glu::draw(m_context.getRenderContext(), p.getProgram(), 1, &posBinding,
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(s_indices), &s_indices[0]));
			GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");

			// Blend barrier.
			if (needBarrier)
				gl.blendBarrier();
		}

	// Read the results.
	glw::GLubyte* result = new glw::GLubyte[4 * dim * dim];
	gl.readPixels(0, 0, dim, dim, GL_RGBA, GL_UNSIGNED_BYTE, result);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed");

	// Check that first pixel is ok.
	tcu::RGBA res		= tcu::RGBA::fromBytes(result);
	tcu::RGBA ref		= pf.convertColor(tcu::RGBA(dstCol));
	tcu::RGBA threshold = pf.getColorThreshold() + pf.getColorThreshold();
	bool	  firstOk   = tcu::compareThreshold(ref, res, threshold);

	// Check that all pixels are the same as the first one.
	bool allSame = true;
	for (int i = 0; i < dim * (dim - 1); i++)
		allSame = allSame && (0 == memcmp(result, result + (i * 4), 4));

	bool pass = firstOk && allSame;
	if (!pass)
	{
		log << TestLog::Message << "Exceeds: " << threshold << " diff:" << tcu::computeAbsDiff(ref, res)
			<< "  res:" << res << "  ref:" << tcu::RGBA(dstCol) << TestLog::EndMessage;
	}

	delete[] result;

	m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "" : "results differ");
	return STOP;
}

class BlendTestCaseGroup : public deqp::TestCaseGroup
{
public:
	enum QualifierType
	{
		MATCHING_QUALIFIER, // Use single qualifier that matches used blending mode.
		ALL_QUALIFIER		// Use "all_equations" qualifier.
	};

	BlendTestCaseGroup(deqp::Context& context, glu::GLSLVersion glslVersion, QualifierType qualifierType)
		: TestCaseGroup(context, (qualifierType == ALL_QUALIFIER) ? "blend_all" : "blend_specific",
						"Test all added blends.")
		, m_glslVersion(glslVersion)
		, m_useAllQualifier(qualifierType == ALL_QUALIFIER)
	{
		DE_ASSERT(qualifierType == MATCHING_QUALIFIER || qualifierType == ALL_QUALIFIER);
	}

	void init(void)
	{
		// Pump individual modes.
		for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_modes); i++)
		{
			addChild(new BlendTest(m_context, m_glslVersion, s_modes[i], m_useAllQualifier,
								   DE_LENGTH_OF_ARRAY(s_common) / 8, s_common, DE_LENGTH_OF_ARRAY(s_rgb10a2) / 8, s_rgb10a2));
		}
	}

private:
	glu::GLSLVersion m_glslVersion;
	bool			 m_useAllQualifier;

	class BlendTest : public deqp::TestCase
	{
	public:
		BlendTest(deqp::Context& context, glu::GLSLVersion glslVersion, glw::GLenum mode, bool useAllQualifier,
				  int numColors, const glw::GLfloat* colors, int numSpecificColors, const glw::GLfloat* specificColors)
			: TestCase(context, (std::string(GetModeStr(mode)) + (useAllQualifier ? "_all_qualifier" : "")).c_str(),
					   "Test new blend modes for correctness.")
			, m_glslVersion(glslVersion)
			, m_mode(mode)
			, m_useAllQualifier(useAllQualifier)
			, m_numColors(numColors)
			, m_colors(colors)
			, m_numSpecificColors(numSpecificColors)
			, m_specificColors(specificColors)
			, m_useRGB10A2Data(GL_FALSE)
		{
		}

		IterateResult iterate(void);

	private:
		void getTestColors(int index, tcu::Vec4& src, tcu::Vec4& dst) const;
		void getCoordinates(int index, int& x, int& y) const;

		glu::GLSLVersion	m_glslVersion;
		glw::GLenum			m_mode;
		bool				m_useAllQualifier;
		int					m_numColors;
		const glw::GLfloat* m_colors;
		int					m_numSpecificColors;
		const glw::GLfloat*	m_specificColors;
		bool				m_useRGB10A2Data;
	};

	static const glw::GLfloat s_common[46 * 8];
	static const glw::GLfloat s_rgb10a2[42 * 8];
};

// Alpha values for pre-multiplied colors.
static const float A1 = 0.750f; // Between 1    and 0.5
static const float A2 = 0.375f; // Between 0.5  and 0.25
static const float A3 = 0.125f; // Between 0.25 and 0.0

const glw::GLfloat BlendTestCaseGroup::s_common[] = {
	// Test that pre-multiplied is converted correctly.
	// Should not test invalid premultiplied colours (1, 1, 1, 0).
	1.000f, 0.750f, 0.500f, 1.00f, 0.000f, 0.000f, 0.000f, 0.00f, 0.250f, 0.125f, 0.000f, 1.00f, 0.000f, 0.000f, 0.000f,
	0.00f,

	// Test clamping.
	1.000f, 0.750f, 0.500f, 1.00f, -0.125f, -0.125f, -0.125f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f, -0.125f, -0.125f,
	-0.125f, 1.00f, 1.000f, 0.750f, 0.500f, 1.00f, 1.125f, 1.125f, 1.125f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f, 1.125f,
	1.125f, 1.125f, 1.00f,

	// Cobinations that test other branches of blend equations.
	1.000f, 0.750f, 0.500f, 1.00f, 1.000f, 1.000f, 1.000f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f, 1.000f, 1.000f, 1.000f,
	1.00f, 1.000f, 0.750f, 0.500f, 1.00f, 0.500f, 0.500f, 0.500f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f, 0.500f, 0.500f,
	0.500f, 1.00f, 1.000f, 0.750f, 0.500f, 1.00f, 0.250f, 0.250f, 0.250f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f, 0.250f,
	0.250f, 0.250f, 1.00f, 1.000f, 0.750f, 0.500f, 1.00f, 0.125f, 0.125f, 0.125f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f,
	0.125f, 0.125f, 0.125f, 1.00f, 1.000f, 0.750f, 0.500f, 1.00f, 0.000f, 0.000f, 0.000f, 1.00f, 0.250f, 0.125f, 0.000f,
	1.00f, 0.000f, 0.000f, 0.000f, 1.00f,

	// Above block with few different pre-multiplied alpha values.
	A1 * 1.000f, A1 * 0.750f, A1 * 0.500f, A1 * 1.00f, A1 * 1.000f, A1 * 1.000f, A1 * 1.000f, A1 * 1.00f, A1 * 0.250f,
	A1 * 0.125f, A1 * 0.000f, A1 * 1.00f, A1 * 1.000f, A1 * 1.000f, A1 * 1.000f, A1 * 1.00f, A1 * 1.000f, A1 * 0.750f,
	A1 * 0.500f, A1 * 1.00f, A1 * 0.500f, A1 * 0.500f, A1 * 0.500f, A1 * 1.00f, A1 * 0.250f, A1 * 0.125f, A1 * 0.000f,
	A1 * 1.00f, A1 * 0.500f, A1 * 0.500f, A1 * 0.500f, A1 * 1.00f, A1 * 1.000f, A1 * 0.750f, A1 * 0.500f, A1 * 1.00f,
	A1 * 0.250f, A1 * 0.250f, A1 * 0.250f, A1 * 1.00f, A1 * 0.250f, A1 * 0.125f, A1 * 0.000f, A1 * 1.00f, A1 * 0.250f,
	A1 * 0.250f, A1 * 0.250f, A1 * 1.00f, A1 * 1.000f, A1 * 0.750f, A1 * 0.500f, A1 * 1.00f, A1 * 0.125f, A1 * 0.125f,
	A1 * 0.125f, A1 * 1.00f, A1 * 0.250f, A1 * 0.125f, A1 * 0.000f, A1 * 1.00f, A1 * 0.125f, A1 * 0.125f, A1 * 0.125f,
	A1 * 1.00f, A1 * 1.000f, A1 * 0.750f, A1 * 0.500f, A1 * 1.00f, A1 * 0.000f, A1 * 0.000f, A1 * 0.000f, A1 * 1.00f,
	A1 * 0.250f, A1 * 0.125f, A1 * 0.000f, A1 * 1.00f, A1 * 0.000f, A1 * 0.000f, A1 * 0.000f, A1 * 1.00f,

	A2 * 1.000f, A2 * 0.750f, A2 * 0.500f, A2 * 1.00f, A2 * 1.000f, A2 * 1.000f, A2 * 1.000f, A2 * 1.00f, A2 * 0.250f,
	A2 * 0.125f, A2 * 0.000f, A2 * 1.00f, A2 * 1.000f, A2 * 1.000f, A2 * 1.000f, A2 * 1.00f, A2 * 1.000f, A2 * 0.750f,
	A2 * 0.500f, A2 * 1.00f, A2 * 0.500f, A2 * 0.500f, A2 * 0.500f, A2 * 1.00f, A2 * 0.250f, A2 * 0.125f, A2 * 0.000f,
	A2 * 1.00f, A2 * 0.500f, A2 * 0.500f, A2 * 0.500f, A2 * 1.00f, A2 * 1.000f, A2 * 0.750f, A2 * 0.500f, A2 * 1.00f,
	A2 * 0.250f, A2 * 0.250f, A2 * 0.250f, A2 * 1.00f, A2 * 0.250f, A2 * 0.125f, A2 * 0.000f, A2 * 1.00f, A2 * 0.250f,
	A2 * 0.250f, A2 * 0.250f, A2 * 1.00f, A2 * 1.000f, A2 * 0.750f, A2 * 0.500f, A2 * 1.00f, A2 * 0.125f, A2 * 0.125f,
	A2 * 0.125f, A2 * 1.00f, A2 * 0.250f, A2 * 0.125f, A2 * 0.000f, A2 * 1.00f, A2 * 0.125f, A2 * 0.125f, A2 * 0.125f,
	A2 * 1.00f, A2 * 1.000f, A2 * 0.750f, A2 * 0.500f, A2 * 1.00f, A2 * 0.000f, A2 * 0.000f, A2 * 0.000f, A2 * 1.00f,
	A2 * 0.250f, A2 * 0.125f, A2 * 0.000f, A2 * 1.00f, A2 * 0.000f, A2 * 0.000f, A2 * 0.000f, A2 * 1.00f,

	A3 * 1.000f, A3 * 0.750f, A3 * 0.500f, A3 * 1.00f, A3 * 1.000f, A3 * 1.000f, A3 * 1.000f, A3 * 1.00f, A3 * 0.250f,
	A3 * 0.125f, A3 * 0.000f, A3 * 1.00f, A3 * 1.000f, A3 * 1.000f, A3 * 1.000f, A3 * 1.00f, A3 * 1.000f, A3 * 0.750f,
	A3 * 0.500f, A3 * 1.00f, A3 * 0.500f, A3 * 0.500f, A3 * 0.500f, A3 * 1.00f, A3 * 0.250f, A3 * 0.125f, A3 * 0.000f,
	A3 * 1.00f, A3 * 0.500f, A3 * 0.500f, A3 * 0.500f, A3 * 1.00f, A3 * 1.000f, A3 * 0.750f, A3 * 0.500f, A3 * 1.00f,
	A3 * 0.250f, A3 * 0.250f, A3 * 0.250f, A3 * 1.00f, A3 * 0.250f, A3 * 0.125f, A3 * 0.000f, A3 * 1.00f, A3 * 0.250f,
	A3 * 0.250f, A3 * 0.250f, A3 * 1.00f, A3 * 1.000f, A3 * 0.750f, A3 * 0.500f, A3 * 1.00f, A3 * 0.125f, A3 * 0.125f,
	A3 * 0.125f, A3 * 1.00f, A3 * 0.250f, A3 * 0.125f, A3 * 0.000f, A3 * 1.00f, A3 * 0.125f, A3 * 0.125f, A3 * 0.125f,
	A3 * 1.00f, A3 * 1.000f, A3 * 0.750f, A3 * 0.500f, A3 * 1.00f, A3 * 0.000f, A3 * 0.000f, A3 * 0.000f, A3 * 1.00f,
	A3 * 0.250f, A3 * 0.125f, A3 * 0.000f, A3 * 1.00f, A3 * 0.000f, A3 * 0.000f, A3 * 0.000f, A3 * 1.00f,
};

// Some data in the s_common array are invalid for BlendHSLHue and BlendHSLSaturation function when the render target
// format is GL_RGB10A2. These data will lead to undefine behavior(divide 0). Remove those data and create a new array
// to test this format and the blend functions.
const glw::GLfloat BlendTestCaseGroup::s_rgb10a2[] = {
	// Test that pre-multiplied is converted correctly.
	// Should not test invalid premultiplied colours (1, 1, 1, 0).
	1.000f, 0.750f, 0.500f, 1.00f, 0.000f, 0.000f, 0.000f, 0.00f, 0.250f, 0.125f, 0.000f, 1.00f, 0.000f, 0.000f, 0.000f,
	0.00f,

	// Test clamping.
	1.000f, 0.750f, 0.500f, 1.00f, -0.125f, -0.125f, -0.125f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f, -0.125f, -0.125f,
	-0.125f, 1.00f, 1.000f, 0.750f, 0.500f, 1.00f, 1.125f, 1.125f, 1.125f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f, 1.125f,
	1.125f, 1.125f, 1.00f,

	// Cobinations that test other branches of blend equations.
	1.000f, 0.750f, 0.500f, 1.00f, 1.000f, 1.000f, 1.000f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f, 1.000f, 1.000f, 1.000f,
	1.00f, 1.000f, 0.750f, 0.500f, 1.00f, 0.500f, 0.500f, 0.500f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f, 0.500f, 0.500f,
	0.500f, 1.00f, 1.000f, 0.750f, 0.500f, 1.00f, 0.250f, 0.250f, 0.250f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f, 0.250f,
	0.250f, 0.250f, 1.00f, 1.000f, 0.750f, 0.500f, 1.00f, 0.125f, 0.125f, 0.125f, 1.00f, 0.250f, 0.125f, 0.000f, 1.00f,
	0.125f, 0.125f, 0.125f, 1.00f, 1.000f, 0.750f, 0.500f, 1.00f, 0.000f, 0.000f, 0.000f, 1.00f, 0.250f, 0.125f, 0.000f,
	1.00f, 0.000f, 0.000f, 0.000f, 1.00f,

	// Above block with few different pre-multiplied alpha values.
	A1 * 1.000f, A1 * 0.750f, A1 * 0.500f, A1 * 1.00f, A1 * 0.500f, A1 * 0.500f, A1 * 0.500f, A1 * 1.00f, A1 * 0.250f,
	A1 * 0.125f, A1 * 0.000f, A1 * 1.00f, A1 * 0.500f, A1 * 0.500f, A1 * 0.500f, A1 * 1.00f, A1 * 1.000f, A1 * 0.750f,
	A1 * 0.500f, A1 * 1.00f, A1 * 0.250f, A1 * 0.250f, A1 * 0.250f, A1 * 1.00f, A1 * 0.250f, A1 * 0.125f, A1 * 0.000f,
	A1 * 1.00f, A1 * 0.250f, A1 * 0.250f, A1 * 0.250f, A1 * 1.00f, A1 * 1.000f, A1 * 0.750f, A1 * 0.500f, A1 * 1.00f,
	A1 * 0.125f, A1 * 0.125f, A1 * 0.125f, A1 * 1.00f, A1 * 0.250f, A1 * 0.125f, A1 * 0.000f, A1 * 1.00f, A1 * 0.125f,
	A1 * 0.125f, A1 * 0.125f, A1 * 1.00f, A1 * 1.000f, A1 * 0.750f, A1 * 0.500f, A1 * 1.00f, A1 * 0.000f, A1 * 0.000f,
	A1 * 0.000f, A1 * 1.00f, A1 * 0.250f, A1 * 0.125f, A1 * 0.000f, A1 * 1.00f, A1 * 0.000f, A1 * 0.000f, A1 * 0.000f,
	A1 * 1.00f,

	A2 * 1.000f, A2 * 0.750f, A2 * 0.500f, A2 * 1.00f, A2 * 0.500f, A2 * 0.500f, A2 * 0.500f, A2 * 1.00f, A2 * 0.250f,
	A2 * 0.125f, A2 * 0.000f, A2 * 1.00f, A2 * 0.500f, A2 * 0.500f, A2 * 0.500f, A2 * 1.00f, A2 * 1.000f, A2 * 0.750f,
	A2 * 0.500f, A2 * 1.00f, A2 * 0.250f, A2 * 0.250f, A2 * 0.250f, A2 * 1.00f, A2 * 0.250f, A2 * 0.125f, A2 * 0.000f,
	A2 * 1.00f, A2 * 0.250f, A2 * 0.250f, A2 * 0.250f, A2 * 1.00f, A2 * 1.000f, A2 * 0.750f, A2 * 0.500f, A2 * 1.00f,
	A2 * 0.125f, A2 * 0.125f, A2 * 0.125f, A2 * 1.00f, A2 * 0.250f, A2 * 0.125f, A2 * 0.000f, A2 * 1.00f, A2 * 0.125f,
	A2 * 0.125f, A2 * 0.125f, A2 * 1.00f, A2 * 1.000f, A2 * 0.750f, A2 * 0.500f, A2 * 1.00f, A2 * 0.000f, A2 * 0.000f,
	A2 * 0.000f, A2 * 1.00f, A2 * 0.250f, A2 * 0.125f, A2 * 0.000f, A2 * 1.00f, A2 * 0.000f, A2 * 0.000f, A2 * 0.000f,
	A2 * 1.00f,

	A3 * 1.000f, A3 * 0.750f, A3 * 0.500f, A3 * 1.00f, A3 * 1.000f, A3 * 1.000f, A3 * 1.000f, A3 * 1.00f, A3 * 0.250f,
	A3 * 0.125f, A3 * 0.000f, A3 * 1.00f, A3 * 1.000f, A3 * 1.000f, A3 * 1.000f, A3 * 1.00f, A3 * 1.000f, A3 * 0.750f,
	A3 * 0.500f, A3 * 1.00f, A3 * 0.500f, A3 * 0.500f, A3 * 0.500f, A3 * 1.00f, A3 * 0.250f, A3 * 0.125f, A3 * 0.000f,
	A3 * 1.00f, A3 * 0.500f, A3 * 0.500f, A3 * 0.500f, A3 * 1.00f, A3 * 1.000f, A3 * 0.750f, A3 * 0.500f, A3 * 1.00f,
	A3 * 0.250f, A3 * 0.250f, A3 * 0.250f, A3 * 1.00f, A3 * 0.250f, A3 * 0.125f, A3 * 0.000f, A3 * 1.00f, A3 * 0.250f,
	A3 * 0.250f, A3 * 0.250f, A3 * 1.00f, A3 * 1.000f, A3 * 0.750f, A3 * 0.500f, A3 * 1.00f, A3 * 0.125f, A3 * 0.125f,
	A3 * 0.125f, A3 * 1.00f, A3 * 0.250f, A3 * 0.125f, A3 * 0.000f, A3 * 1.00f, A3 * 0.125f, A3 * 0.125f, A3 * 0.125f,
	A3 * 1.00f, A3 * 1.000f, A3 * 0.750f, A3 * 0.500f, A3 * 1.00f, A3 * 0.000f, A3 * 0.000f, A3 * 0.000f, A3 * 1.00f,
	A3 * 0.250f, A3 * 0.125f, A3 * 0.000f, A3 * 1.00f, A3 * 0.000f, A3 * 0.000f, A3 * 0.000f, A3 * 1.00f,
};

static tcu::Vec4 MaskChannels(const tcu::PixelFormat& pf, const tcu::Vec4& v)
{
	return tcu::Vec4(pf.redBits > 0 ? v[0] : 0.f, pf.greenBits > 0 ? v[1] : 0.f, pf.blueBits > 0 ? v[2] : 0.f,
					 pf.alphaBits > 0 ? v[3] : 1.f);
}

//
// Quantize the input colour by the colour bit depth for each channel.
//
static tcu::Vec4 QuantizeChannels(const tcu::PixelFormat& pf, const tcu::Vec4& v)
{
	float maxChanel[4] = { static_cast<float>(1 << pf.redBits) - 1.0f, static_cast<float>(1 << pf.greenBits) - 1.0f,
						   static_cast<float>(1 << pf.blueBits) - 1.0f, static_cast<float>(1 << pf.alphaBits) - 1.0f };

	return tcu::Vec4(static_cast<float>((unsigned int)(v[0] * maxChanel[0])) / maxChanel[0],
					 static_cast<float>((unsigned int)(v[1] * maxChanel[1])) / maxChanel[1],
					 static_cast<float>((unsigned int)(v[2] * maxChanel[2])) / maxChanel[2],
					 pf.alphaBits ? static_cast<float>((unsigned int)(v[3] * maxChanel[3])) / maxChanel[3] : 1.0f);
}

void BlendTestCaseGroup::BlendTest::getTestColors(int index, tcu::Vec4& src, tcu::Vec4& dst) const
{
	DE_ASSERT(0 <= index && index < (m_useRGB10A2Data ? m_numSpecificColors : m_numColors));

	const tcu::RenderTarget&	rt = m_context.getRenderContext().getRenderTarget();
	const tcu::PixelFormat&		pf = rt.getPixelFormat();
	const glw::GLfloat*			s  = (m_useRGB10A2Data ? m_specificColors : m_colors) + 8 * index;

	src = MaskChannels(pf, tcu::Vec4(s[0], s[1], s[2], s[3]));
	dst = MaskChannels(pf, tcu::Vec4(s[4], s[5], s[6], s[7]));
	src = tcu::clamp(src, tcu::Vec4(0.f), tcu::Vec4(1.f));
	dst = tcu::clamp(dst, tcu::Vec4(0.f), tcu::Vec4(1.f));

	// Quantize the destination channels
	// this matches what implementation does on render target write
	dst = QuantizeChannels(pf, dst);
}

void BlendTestCaseGroup::BlendTest::getCoordinates(int index, int& x, int& y) const
{
	const tcu::RenderTarget& rt = m_context.getRenderContext().getRenderTarget();
	y							= index / rt.getWidth();
	x							= index % rt.getWidth();
}

BlendTestCaseGroup::BlendTest::IterateResult BlendTestCaseGroup::BlendTest::iterate(void)
{
	const tcu::RenderTarget& rt  = m_context.getRenderContext().getRenderTarget();
	const tcu::PixelFormat&  pf  = rt.getPixelFormat();
	const glw::Functions&	gl  = m_context.getRenderContext().getFunctions();
	TestLog&				 log = m_testCtx.getLog();

	// Check that extension is supported.
	if (!IsExtensionSupported(m_context, "GL_KHR_blend_equation_advanced"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_KHR_blend_equation_advanced");
		return STOP;
	}

	if ((GetBlendFunc(m_mode) == BlendHSLHue || GetBlendFunc(m_mode) == BlendHSLSaturation)
		&& (pf.redBits == 10 && pf.greenBits == 10 && pf.blueBits == 10 && pf.alphaBits == 2))
	{
		m_useRGB10A2Data = GL_TRUE;
	}

	// Setup program.
	std::string frgSrc =
		GetSolidShader(m_useAllQualifier ? "blend_support_all_equations" : GetLayoutQualifierStr(m_mode),
					   glu::getGLSLVersionDeclaration(m_glslVersion));
	glu::ShaderProgram p(m_context.getRenderContext(),
						 glu::makeVtxFragSources(GetDef2DVtxSrc(m_glslVersion).c_str(), frgSrc.c_str()));
	if (!p.isOk())
	{
		log << p;
		TCU_FAIL("Compile failed");
	}
	gl.useProgram(p.getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Program failed");

	glu::VertexArrayBinding posBinding = glu::va::Float("aPos", 2, 4, 0, &s_pos[0]);

	// Enable blending and set blend equation.
	gl.disable(GL_DITHER);
	gl.enable(GL_SCISSOR_TEST);
	gl.enable(GL_BLEND);
	gl.blendEquation(m_mode);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BlendEquation failed");

	bool needBarrier = !IsExtensionSupported(m_context, "GL_KHR_blend_equation_advanced_coherent");

	// Render loop.
	for (int colorIndex = 0; colorIndex < (m_useRGB10A2Data ? m_numSpecificColors : m_numColors); colorIndex++)
	{
		tcu::Vec4 srcCol, dstCol;
		getTestColors(colorIndex, srcCol, dstCol);

		// Get pixel to blend.
		int x, y;
		getCoordinates(colorIndex, x, y);
		gl.scissor(x, y, 1, 1);

		// Clear to destination color.
		gl.clearColor(dstCol[0], dstCol[1], dstCol[2], dstCol[3]);
		gl.clear(GL_COLOR_BUFFER_BIT);
		if (needBarrier)
			gl.blendBarrier();

		// Set source color.
		gl.uniform4f(gl.getUniformLocation(p.getProgram(), "uSrcCol"), srcCol[0], srcCol[1], srcCol[2], srcCol[3]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Uniforms failed");

		// Draw.
		glu::draw(m_context.getRenderContext(), p.getProgram(), 1, &posBinding,
				  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(s_indices), &s_indices[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");
		if (needBarrier)
			gl.blendBarrier();
	}

	// Read the results.
	const int	 w			  = rt.getWidth();
	const int	 h			  = rt.getHeight();
	glw::GLubyte* resultBytes = new glw::GLubyte[4 * w * h];
	gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
	gl.readPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, resultBytes);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed");

	bool pass = true;
	for (int colorIndex = 0; colorIndex < (m_useRGB10A2Data ? m_numSpecificColors : m_numColors); colorIndex++)
	{
		tcu::Vec4 srcCol, dstCol;
		getTestColors(colorIndex, srcCol, dstCol);

		// Get result and calculate reference.
		int x, y;
		getCoordinates(colorIndex, x, y);

		tcu::Vec4 refCol	= Blend(m_mode, srcCol, dstCol);
		tcu::RGBA ref		= pf.convertColor(tcu::RGBA(refCol));
		tcu::RGBA res		= tcu::RGBA::fromBytes(resultBytes + 4 * (x + w * y));
		tcu::RGBA tmp		= pf.getColorThreshold();
		tcu::RGBA threshold = tcu::RGBA(std::min(2 + 2 * tmp.getRed(), 255), std::min(2 + 2 * tmp.getGreen(), 255),
										std::min(2 + 2 * tmp.getBlue(), 255), std::min(2 + 2 * tmp.getAlpha(), 255));
		bool pixelOk = tcu::compareThreshold(ref, res, threshold);
		pass		 = pass && pixelOk;
		if (!pixelOk)
		{
			log << TestLog::Message << "(" << x << "," << y << ")  "
				<< "(" << colorIndex << ") "
				<< "Exceeds: " << threshold << " diff:" << tcu::computeAbsDiff(ref, res) << "  res:" << res
				<< "  ref:" << ref << "  dst:" << tcu::RGBA(dstCol) << "  src:" << tcu::RGBA(srcCol)
				<< TestLog::EndMessage;
		}
	}

	m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "" : "results differ");
	delete[] resultBytes;
	return STOP;
}

/*
 * From 'Other' part of the spec:
 *    "Test different behaviors for GLSL #extension
 *     GL_XXX_blend_equation_advanced"
 *
 * - require : Covered by "Blend" tests.
 * - enable  : Use layout modifier from GL_KHR_blend_equation_advanced and
 *             expect compile to succeed. (warn if not supported)
 * - warn    : Use layout modifier from GL_KHR_blend_equation_advanced and
 *             expect compile to succeed. (work, but issue warning)
 * - disable : Use layout modifier from GL_KHR_blend_equation_advanced and
 *             expect compile to fail with error.
 *
 */
class ExtensionDirectiveTestCaseGroup : public deqp::TestCaseGroup
{
public:
	ExtensionDirectiveTestCaseGroup(deqp::Context& context, glu::GLSLVersion glslVersion)
		: TestCaseGroup(context, "extension_directive", "Test #extension directive."), m_glslVersion(glslVersion)
	{
	}

	void init(void)
	{
		addChild(new ExtensionDirectiveTestCase(m_context, m_glslVersion, "disable"));
		addChild(new ExtensionDirectiveTestCase(m_context, m_glslVersion, "enable"));
		addChild(new ExtensionDirectiveTestCase(m_context, m_glslVersion, "warn"));
	}

private:
	class ExtensionDirectiveTestCase : public deqp::TestCase
	{
	public:
		ExtensionDirectiveTestCase(deqp::Context& context, glu::GLSLVersion glslVersion, const char* behaviour)
			: TestCase(context, (std::string("extension_directive_") + behaviour).c_str(), "Test #extension directive.")
			, m_glslVersion(glslVersion)
			, m_behaviourStr(behaviour)
		{
			// Initialize expected compiler behaviour.
			std::string b(behaviour);
			if (b == "disable")
			{
				m_requireInfoLog = true;
				m_requireCompile = false;
			}
			else if (b == "enable")
			{
				m_requireInfoLog = false;
				m_requireCompile = true;
			}
			else
			{
				DE_ASSERT(b == "warn");
				m_requireInfoLog = false;
				m_requireCompile = true;
			}
		}

		IterateResult iterate(void)
		{
			const glw::Functions& gl  = m_context.getRenderContext().getFunctions();
			TestLog&			  log = m_testCtx.getLog();
			const int			  dim = 4;

			// Check that extension is supported.
			if (!IsExtensionSupported(m_context, "GL_KHR_blend_equation_advanced"))
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_KHR_blend_equation_advanced");
				return STOP;
			}

			FBOSentry fbo(gl, dim, dim, GL_RGBA8);

			tcu::Vec4 dstCol(1.f, 1.f, 1.f, 1.f);
			tcu::Vec4 srcCol(0.f, 0.f, 0.f, 1.f);

			// Clear to destination color.
			gl.clearColor(dstCol.x(), dstCol.y(), dstCol.z(), dstCol.w());
			gl.clear(GL_COLOR_BUFFER_BIT);

			// Setup program.
			std::string directive = "#extension GL_KHR_blend_equation_advanced : " + m_behaviourStr;
			std::string frgSrc = GetSolidShader("blend_support_multiply", glu::getGLSLVersionDeclaration(m_glslVersion),
												directive.c_str());
			glu::ShaderProgram p(m_context.getRenderContext(),
								 glu::makeVtxFragSources(GetDef2DVtxSrc(m_glslVersion).c_str(), frgSrc.c_str()));
			// If check that there is some info log if it is expected.
			const bool infoLogOk =
				m_requireInfoLog ? p.getShaderInfo(glu::SHADERTYPE_FRAGMENT).infoLog.size() > 0 : true;
			if (!p.isOk())
			{
				if (m_requireCompile)
				{
					log << p;
					TCU_FAIL("Compile failed");
				}
				else
				{
					// If shader was expected to fail, so assume info log has something.
					bool pass = infoLogOk;
					m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
											pass ? "Pass" : "Fail. Expected info log.");
				}
				return STOP;
			}
			gl.useProgram(p.getProgram());
			GLU_EXPECT_NO_ERROR(gl.getError(), "Program failed");

			// Program ok, check whether info log was as expected.
			if (!infoLogOk)
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail. No warnings were generated.");
				return STOP;
			}

			// Enable blending and set blend equation.
			gl.disable(GL_DITHER);
			gl.enable(GL_BLEND);
			gl.blendEquation(GL_MULTIPLY_KHR);
			GLU_EXPECT_NO_ERROR(gl.getError(), "BlendEquation failed");

			// Setup source color.
			gl.uniform4f(gl.getUniformLocation(p.getProgram(), "uSrcCol"), srcCol.x(), srcCol.y(), srcCol.z(),
						 srcCol.w());
			GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform failed");

			glu::VertexArrayBinding posBinding = glu::va::Float("aPos", 2, 4, 0, &s_pos[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Attributes failed");

			glu::draw(m_context.getRenderContext(), p.getProgram(), 1, &posBinding,
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(s_indices), &s_indices[0]));
			GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");

			// Check the result to see that extension was actually enabled.
			glw::GLubyte result[4] = { 1, 2, 3, 4 };
			gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, result);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed");
			bool pass = tcu::RGBA::fromBytes(result) == tcu::RGBA(0, 0, 0, 0xFF);
			m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "Pass" : "Fail");

			return STOP;
		}

	private:
		glu::GLSLVersion m_glslVersion;
		std::string		 m_behaviourStr;
		bool			 m_requireInfoLog;
		bool			 m_requireCompile;
	};

	glu::GLSLVersion m_glslVersion;
};

/*
 * From 'Other' part of the spec:
 *    "If XXX_blend_equation_advanced_coherent is supported, test
 *     Each blending mode needs to be tested without specifying the proper
 *     blend_support_[mode] or blend_support_all layout qualifier in the
 *     fragment shader. Expect INVALID_OPERATION GL error after calling
 *     DrawElements/Arrays."
 */
class MissingQualifierTestGroup : public deqp::TestCaseGroup
{
public:
	enum MissingType
	{
		MISMATCH, // wrong qualifier in the shader.
		MISSING,  // no qualifier at all.
	};

	MissingQualifierTestGroup(deqp::Context& context, glu::GLSLVersion glslVersion, MissingType missingType)
		: TestCaseGroup(context, missingType == MISMATCH ? "mismatching_qualifier" : "missing_qualifier", "")
		, m_glslVersion(glslVersion)
		, m_missingType(missingType)
	{
	}

	void init(void)
	{
		// Pump individual modes.
		for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_modes); i++)
		{
			const char* qualifier = m_missingType == MISSING ?
										DE_NULL :
										GetLayoutQualifierStr(s_modes[(i + 1) % DE_LENGTH_OF_ARRAY(s_modes)]);
			addChild(new MissingCase(m_context, m_glslVersion, s_modes[i], qualifier));
		}
	}

private:
	class MissingCase : public deqp::TestCase
	{
	public:
		MissingCase(deqp::Context& context, glu::GLSLVersion glslVersion, glw::GLenum mode, const char* layoutQualifier)
			: TestCase(context, GetModeStr(mode), "")
			, m_glslVersion(glslVersion)
			, m_mode(mode)
			, m_layoutQualifier(layoutQualifier)
		{
		}

		IterateResult iterate(void);

	private:
		glu::GLSLVersion m_glslVersion;
		glw::GLenum		 m_mode;
		const char*		 m_layoutQualifier; // NULL => no qualifier at all.
	};

	glu::GLSLVersion m_glslVersion;
	MissingType		 m_missingType;
};

MissingQualifierTestGroup::MissingCase::IterateResult MissingQualifierTestGroup::MissingCase::iterate(void)
{
	const int			  dim = 4;
	const glw::Functions& gl  = m_context.getRenderContext().getFunctions();
	TestLog&			  log = m_testCtx.getLog();

	// Check that extension is supported.
	if (!IsExtensionSupported(m_context, "GL_KHR_blend_equation_advanced"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_KHR_blend_equation_advanced");
		return STOP;
	}

	FBOSentry fbo(gl, dim, dim, GL_RGBA8);

	tcu::Vec4 dstCol(1.f, 1.f, 1.f, 1.f);
	tcu::Vec4 srcCol(0.f, 0.f, 0.f, 1.f);

	// Clear to destination color.
	gl.clearColor(dstCol.x(), dstCol.y(), dstCol.z(), dstCol.w());
	gl.clear(GL_COLOR_BUFFER_BIT);

	// Setup program.
	glu::ShaderProgram p(m_context.getRenderContext(),
						 glu::makeVtxFragSources(
							 GetDef2DVtxSrc(m_glslVersion).c_str(),
							 GetSolidShader(m_layoutQualifier, glu::getGLSLVersionDeclaration(m_glslVersion)).c_str()));
	if (!p.isOk())
	{
		log << p;
		TCU_FAIL("Compile failed");
	}

	gl.useProgram(p.getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Program failed");

	// Enable blending and set blend equation.
	gl.disable(GL_DITHER);
	gl.enable(GL_BLEND);
	gl.blendEquation(m_mode);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BlendEquation failed");

	// Setup source color.
	gl.uniform4f(gl.getUniformLocation(p.getProgram(), "uSrcCol"), srcCol.x(), srcCol.y(), srcCol.z(), srcCol.w());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform failed");

	glu::VertexArrayBinding posBinding = glu::va::Float("aPos", 2, 4, 0, &s_pos[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Attributes failed");

	glu::draw(m_context.getRenderContext(), p.getProgram(), 1, &posBinding,
			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(s_indices), &s_indices[0]));

	glw::GLenum error = gl.getError();
	bool		pass  = (error == GL_INVALID_OPERATION);

	m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "Pass" : "Fail");

	return STOP;
}

/*
 * From 'Other' part of the spec:
 *    "If XXX_blend_equation_advanced_coherent is supported, test
 *     BLEND_ADVANCED_COHERENT_XXX setting:
 *     - The setting should work with Enable, Disable and IsEnable without producing errors
 *     - Default value should be TRUE"
 *
 *  1. Test that coherent is enabled by default.
 *  2. Disable and check the state.
 *  3. Enable and check the state and test that rendering does not produce errors.
 */

class CoherentEnableCaseGroup : public deqp::TestCaseGroup
{
public:
	CoherentEnableCaseGroup(deqp::Context& context) : TestCaseGroup(context, "coherent", "")
	{
	}

	void init(void)
	{
		addChild(new CoherentEnableCase(m_context));
	}

private:
	class CoherentEnableCase : public deqp::TestCase
	{
	public:
		CoherentEnableCase(deqp::Context& context) : TestCase(context, "enableDisable", "")
		{
		}
		IterateResult iterate(void);
	};
};

CoherentEnableCaseGroup::CoherentEnableCase::IterateResult CoherentEnableCaseGroup::CoherentEnableCase::iterate(void)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	// Check that extension is supported.
	if (!IsExtensionSupported(m_context, "GL_KHR_blend_equation_advanced"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_KHR_blend_equation_advanced");
		return STOP;
	}
	if (!IsExtensionSupported(m_context, "GL_KHR_blend_equation_advanced_coherent"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_KHR_blend_equation_advanced_coherent");
		return STOP;
	}

	std::vector<bool> res;
	// Enabled by default.
	res.push_back(gl.isEnabled(GL_BLEND_ADVANCED_COHERENT_KHR) == GL_TRUE);
	res.push_back(gl.getError() == GL_NO_ERROR);

	// Check disabling.
	gl.disable(GL_BLEND_ADVANCED_COHERENT_KHR);
	res.push_back(gl.getError() == GL_NO_ERROR);
	res.push_back(gl.isEnabled(GL_BLEND_ADVANCED_COHERENT_KHR) == GL_FALSE);
	res.push_back(gl.getError() == GL_NO_ERROR);

	// Check enabling.
	gl.enable(GL_BLEND_ADVANCED_COHERENT_KHR);
	res.push_back(gl.getError() == GL_NO_ERROR);
	res.push_back(gl.isEnabled(GL_BLEND_ADVANCED_COHERENT_KHR) == GL_TRUE);
	res.push_back(gl.getError() == GL_NO_ERROR);

	// Pass if no failures found.
	bool pass = std::find(res.begin(), res.end(), false) == res.end();

	m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "Pass" : "Fail");

	return STOP;
}
/*
 * From 'Other' part of the spec:
 *    "Test that rendering into more than one color buffers at once produces
 *     INVALID_OPERATION error when calling drawArrays/drawElements"
 */
class MRTCaseGroup : public deqp::TestCaseGroup
{
public:
	MRTCaseGroup(deqp::Context& context, glu::GLSLVersion glslVersion)
		: TestCaseGroup(context, "MRT", "GL_KHR_blend_equation_advanced"), m_glslVersion(glslVersion)
	{
	}

	void init(void)
	{
		addChild(new MRTCase(m_context, m_glslVersion, MRTCase::ARRAY));
		addChild(new MRTCase(m_context, m_glslVersion, MRTCase::SEPARATE));
	}

private:
	class MRTCase : public deqp::TestCase
	{
	public:
		enum DeclarationType
		{
			ARRAY,
			SEPARATE
		};

		MRTCase(deqp::Context& context, glu::GLSLVersion glslVersion, DeclarationType declType)
			: TestCase(context, (declType == ARRAY ? "MRT_array" : "MRT_separate"), "GL_KHR_blend_equation_advanced")
			, m_glslVersion(glslVersion)
			, m_declarationType(declType)
		{
			DE_ASSERT(m_declarationType == ARRAY || m_declarationType == SEPARATE);
		}

		IterateResult iterate(void);

	private:
		glu::GLSLVersion m_glslVersion;
		DeclarationType  m_declarationType;
	};

	glu::GLSLVersion m_glslVersion;
};

MRTCaseGroup::MRTCase::IterateResult MRTCaseGroup::MRTCase::iterate(void)
{
	TestLog&			  log = m_testCtx.getLog();
	const glw::Functions& gl  = m_context.getRenderContext().getFunctions();

	if (!IsExtensionSupported(m_context, "GL_KHR_blend_equation_advanced"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_KHR_blend_equation_advanced");
		return STOP;
	}

	static const char* frgSrcTemplateArray = "${VERSION_DIRECTIVE}\n"
											 "#extension GL_KHR_blend_equation_advanced : require\n"
											 "\n"
											 "precision highp float;\n"
											 "layout (blend_support_multiply) out;\n"
											 "layout (location = 0) out vec4 oCol[2];\n"
											 "\n"
											 "uniform vec4 uMultCol;\n"
											 "\n"
											 "void main (void) {\n"
											 "   oCol[0] = uMultCol;\n"
											 "   oCol[1] = uMultCol;\n"
											 "}\n";

	static const char* frgSrcTemplateSeparate = "${VERSION_DIRECTIVE}\n"
												"#extension GL_KHR_blend_equation_advanced : require\n"
												"\n"
												"precision highp float;\n"
												"layout (blend_support_multiply) out;\n"
												"layout (location = 0) out vec4 oCol0;\n"
												"layout (location = 1) out vec4 oCol1;\n"
												"\n"
												"uniform vec4 uMultCol;\n"
												"\n"
												"void main (void) {\n"
												"   oCol0 = uMultCol;\n"
												"   oCol1 = uMultCol;\n"
												"}\n";

	static const char* frgSrcTemplate = m_declarationType == ARRAY ? frgSrcTemplateArray : frgSrcTemplateSeparate;

	std::map<std::string, std::string> args;
	args["VERSION_DIRECTIVE"] = glu::getGLSLVersionDeclaration(m_glslVersion);
	std::string frgSrc		  = tcu::StringTemplate(frgSrcTemplate).specialize(args);

	FBOSentry fbo(gl, 4, 4, GL_RGBA8, GL_RGBA8);

	static const glw::GLenum bufs[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
	gl.drawBuffers(2, bufs);

	// Clear buffers to white.
	gl.clearColor(1.f, 1.f, 1.f, 1.f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	// Setup program.
	glu::ShaderProgram p(m_context.getRenderContext(),
						 glu::makeVtxFragSources(GetDef2DVtxSrc(m_glslVersion).c_str(), frgSrc.c_str()));
	if (!p.isOk())
	{
		log << p;
		TCU_FAIL("Compile failed");
	}

	gl.useProgram(p.getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Program failed");

	// Enable blending and set blend equation.
	gl.disable(GL_DITHER);
	gl.enable(GL_BLEND);
	gl.blendEquation(GL_DARKEN_KHR);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BlendEquation failed");

	// Multiply with zero.
	gl.uniform4f(gl.getUniformLocation(p.getProgram(), "uMultCol"), 0.f, 0.f, 0.f, 1.00f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniforms failed");

	// Set vertex buffer
	glw::GLuint vbo;
	gl.genBuffers(1, &vbo);
	gl.bindBuffer(GL_ARRAY_BUFFER, vbo);
	gl.bufferData(GL_ARRAY_BUFFER, sizeof(s_pos), s_pos, GL_STATIC_DRAW);

	// Set vertices.
	glw::GLuint vao;
	gl.genVertexArrays(1, &vao);
	gl.bindVertexArray(vao);
	glw::GLint loc = gl.getAttribLocation(p.getProgram(), "aPos");
	gl.enableVertexAttribArray(loc);
	gl.vertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 8, DE_NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Attributes failed");

	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	bool errorOk = (gl.getError() == GL_INVALID_OPERATION);

	gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, s_indices);
	errorOk = errorOk && (gl.getError() == GL_INVALID_OPERATION);

	if (!errorOk)
		log << TestLog::Message << "DrawArrays/DrawElements didn't produce error." << TestLog::EndMessage;

	// Expect unaltered destination pixels.
	bool contentsOk = true;
	for (int i = 0; i < 2; i++)
	{
		glw::GLubyte result[4] = { 1, 2, 3, 4 };
		gl.readBuffer(bufs[0]);
		gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, result);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed");
		if (tcu::RGBA::fromBytes(result) != tcu::RGBA::white())
		{
			contentsOk = false;
			log << TestLog::Message << "Buffer " << i << " "
				<< "contents changed: " << tcu::RGBA::fromBytes(result) << " expected:" << tcu::RGBA::white()
				<< TestLog::EndMessage;
		}
	}

	gl.deleteVertexArrays(1, &vao);
	gl.deleteBuffers(1, &vbo);

	bool pass = errorOk && contentsOk;
	m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "Pass" : "Fail");
	return STOP;
}

/*
 * From "Other" part of the spec:
 *    "Test that the new blending modes cannot be used with
 *     BlendEquationSeparate(i). Expect INVALID_ENUM GL error"
 *
 * Tests that BlendEquationSeparate does not accept extension's blending modes
 * either in rgb or alpha parameter.
 */
class BlendEquationSeparateCase : public deqp::TestCaseGroup
{
public:
	BlendEquationSeparateCase(deqp::Context& context)
		: TestCaseGroup(context, "BlendEquationSeparate",
						"Test that advanced blend modes are correctly rejected from glBlendEquationSeparate.")
	{
	}

	void init(void)
	{
		// Pump individual modes.
		for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_modes); i++)
			addChild(new ModeCase(m_context, s_modes[i]));
	}

private:
	class ModeCase : public deqp::TestCase
	{
	public:
		ModeCase(deqp::Context& context, glw::GLenum mode)
			: TestCase(context, GetModeStr(mode), "Test one mode"), m_mode(mode)
		{
		}

		IterateResult iterate(void)
		{
			// Check that extension is supported.
			if (!IsExtensionSupported(m_context, "GL_KHR_blend_equation_advanced"))
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_KHR_blend_equation_advanced");
				return STOP;
			}

			const glw::Functions& gl = m_context.getRenderContext().getFunctions();

			// Set separate blend equations.
			// Expect error and that default value (FUNC_ADD) is not changed.

			// RGB.
			gl.blendEquationSeparate(m_mode, GL_FUNC_ADD);
			bool	   rgbOk = gl.getError() == GL_INVALID_ENUM;
			glw::GLint rgbEq = GL_NONE;
			gl.getIntegerv(GL_BLEND_EQUATION_RGB, &rgbEq);
			rgbOk = rgbOk && (rgbEq == GL_FUNC_ADD);

			// Alpha.
			gl.blendEquationSeparate(GL_FUNC_ADD, m_mode);
			bool	   alphaOk = gl.getError() == GL_INVALID_ENUM;
			glw::GLint alphaEq = GL_NONE;
			gl.getIntegerv(GL_BLEND_EQUATION_ALPHA, &alphaEq);
			alphaOk = alphaOk && (alphaEq == GL_FUNC_ADD);

			bool pass = rgbOk && alphaOk;
			m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "Pass" : "Fail");
			return STOP;
		}

	private:
		glw::GLenum m_mode;
	};
};

/*
 *  From "Other" part of the spec:
 *     "Check that GLSL GL_KHR_blend_equation_advanced #define exists and is 1"
 *
 *  Test that regardless of extension directive the definition exists and has value 1.
 */

class PreprocessorCaseGroup : public deqp::TestCaseGroup
{
public:
	PreprocessorCaseGroup(deqp::Context& context, glu::GLSLVersion glslVersion)
		: TestCaseGroup(context, "preprocessor", "GL_KHR_blend_equation_advanced"), m_glslVersion(glslVersion)
	{
	}

	void init(void)
	{
		addChild(new PreprocessorCase(m_context, m_glslVersion, DE_NULL));
		addChild(new PreprocessorCase(m_context, m_glslVersion, "require"));
		addChild(new PreprocessorCase(m_context, m_glslVersion, "enable"));
		addChild(new PreprocessorCase(m_context, m_glslVersion, "warn"));
		addChild(new PreprocessorCase(m_context, m_glslVersion, "disable"));
	}

private:
	class PreprocessorCase : public deqp::TestCase
	{
	public:
		PreprocessorCase(deqp::Context& context, glu::GLSLVersion glslVersion, const char* behaviour)
			: TestCase(context, behaviour ? behaviour : "none", "GL_KHR_blend_equation_advanced")
			, m_glslVersion(glslVersion)
			, m_behaviour(behaviour)
		{
		}

		IterateResult iterate(void);

	private:
		glu::GLSLVersion m_glslVersion;
		const char*		 m_behaviour;
	};

	glu::GLSLVersion m_glslVersion;
};

PreprocessorCaseGroup::PreprocessorCase::IterateResult PreprocessorCaseGroup::PreprocessorCase::iterate(void)
{
	TestLog&			  log = m_testCtx.getLog();
	const glw::Functions& gl  = m_context.getRenderContext().getFunctions();
	const int			  dim = 4;

	if (!IsExtensionSupported(m_context, "GL_KHR_blend_equation_advanced"))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_KHR_blend_equation_advanced");
		return STOP;
	}

	FBOSentry fbo(gl, dim, dim, GL_RGBA8);
	gl.clearColor(0.125f, 0.125f, 0.125f, 1.f);
	gl.clear(GL_COLOR_BUFFER_BIT);

	// Test that GL_KHR_blend_equation_advanced is defined and it has value 1.
	// Renders green pixels if above is true, red pixels otherwise.
	static const char* frgSrcTemplate = "${VERSION_DIRECTIVE}\n"
										"${EXTENSION_DIRECTIVE}\n"
										"precision highp float;\n"
										"\n"
										"uniform vec4 uDefined;\n"
										"uniform vec4 uNonDefined;\n"
										"\n"
										"uniform int  uValue;\n"
										"\n"
										"layout(location = 0) out vec4 oCol;\n"
										"\n"
										"void main (void) {\n"
										"    vec4 col = uNonDefined;\n"
										"#if defined(GL_KHR_blend_equation_advanced)\n"
										"    int val = GL_KHR_blend_equation_advanced;\n"
										"    if (uValue == val) {\n"
										"        col = uDefined;\n"
										"    }\n"
										"#endif\n"
										"    oCol = col;\n"
										"}\n";

	std::map<std::string, std::string> args;
	args["VERSION_DIRECTIVE"] = glu::getGLSLVersionDeclaration(m_glslVersion);
	if (m_behaviour)
		args["EXTENSION_DIRECTIVE"] = std::string("#extension GL_KHR_blend_equation_advanced : ") + m_behaviour;
	else
		args["EXTENSION_DIRECTIVE"] = "";
	std::string frgSrc				= tcu::StringTemplate(frgSrcTemplate).specialize(args);

	glu::ShaderProgram p(m_context.getRenderContext(),
						 glu::makeVtxFragSources(GetDef2DVtxSrc(m_glslVersion).c_str(), frgSrc.c_str()));
	if (!p.isOk())
	{
		log << p;
		TCU_FAIL("Compile failed");
	}
	gl.useProgram(p.getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Program failed");

	gl.uniform1i(gl.getUniformLocation(p.getProgram(), "uValue"), 1);
	gl.uniform4f(gl.getUniformLocation(p.getProgram(), "uDefined"), 0.f, 1.f, 0.f, 1.f);
	gl.uniform4f(gl.getUniformLocation(p.getProgram(), "uNonDefined"), 1.f, 0.f, 1.f, 1.f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniforms failed");

	glu::VertexArrayBinding posBinding = glu::va::Float("aPos", 2, 4, 0, &s_pos[0]);
	glu::draw(m_context.getRenderContext(), p.getProgram(), 1, &posBinding,
			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(s_indices), &s_indices[0]));
	GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");

	// Check the results.
	tcu::Surface resultSurface(dim, dim);
	glu::readPixels(m_context.getRenderContext(), 0, 0, resultSurface.getAccess());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed");
	bool pass = tcu::RGBA::green() == resultSurface.getPixel(0, 0);

	m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "Pass" : "Fail");

	return STOP;
}

BlendEquationAdvancedTests::BlendEquationAdvancedTests(deqp::Context& context, glu::GLSLVersion glslVersion)
	: TestCaseGroup(context, "blend_equation_advanced", "KHR_blend_equation_advanced tests"), m_glslVersion(glslVersion)
{
}

BlendEquationAdvancedTests::~BlendEquationAdvancedTests(void)
{
}

void BlendEquationAdvancedTests::init(void)
{
	// Test that enable/disable and getting status works.
	addChild(new CoherentEnableCaseGroup(m_context));

	// Test that preprocessor macro GL_KHR_blend_equation_advanced
	// is always defined and its value is 1.
	addChild(new PreprocessorCaseGroup(m_context, m_glslVersion));

	// Test that BlendEquationSeparate rejects advanced blend modes.
	addChild(new BlendEquationSeparateCase(m_context));

	// Test that advanced blend equations cannot be used with multiple render targets.
	addChild(new MRTCaseGroup(m_context, m_glslVersion));

	// Test that using new blend modes produce errors if appropriate qualifier
	// is not in the shader (test without any blend qualifier and with mismatching qualifier).
	addChild(new MissingQualifierTestGroup(m_context, m_glslVersion, MissingQualifierTestGroup::MISMATCH));
	addChild(new MissingQualifierTestGroup(m_context, m_glslVersion, MissingQualifierTestGroup::MISSING));

	// Test #extension directive behaviour.
	// Case "require" is tested indirectly by blending tests.
	addChild(new ExtensionDirectiveTestCaseGroup(m_context, m_glslVersion));

	// Test that each blend mode produces correct results.
	addChild(new BlendTestCaseGroup(m_context, m_glslVersion, BlendTestCaseGroup::ALL_QUALIFIER));
	addChild(new BlendTestCaseGroup(m_context, m_glslVersion, BlendTestCaseGroup::MATCHING_QUALIFIER));

	// Test that coherent blending or barrier works.
	addChild(new CoherentBlendTestCaseGroup(m_context, m_glslVersion));
}

} // glcts
