/*-------------------------------------------------------------------------
 * 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 ? "Pass" : "Fail (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 ? "Pass" : "Fail (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
