diff --git a/Android.mk b/Android.mk
index 06adb08..e1235d4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -314,6 +314,7 @@
 	modules/gles31/functional/es31fVertexAttributeBindingStateQueryTests.cpp \
 	modules/gles31/functional/es31fVertexAttributeBindingTests.cpp \
 	modules/gles31/functional/es31fCopyImageTests.cpp \
+	modules/gles31/functional/es31fDrawBuffersIndexedTests.cpp \
 	modules/gles31/stress/es31sDrawTests.cpp \
 	modules/gles31/stress/es31sStressTests.cpp \
 	modules/gles31/stress/es31sTessellationGeometryInteractionTests.cpp \
diff --git a/doc/testspecs/GLES31/functional.draw_buffers_indexed.txt b/doc/testspecs/GLES31/functional.draw_buffers_indexed.txt
new file mode 100644
index 0000000..3c93868
--- /dev/null
+++ b/doc/testspecs/GLES31/functional.draw_buffers_indexed.txt
@@ -0,0 +1,60 @@
+-------------------------------------------------------------------------
+drawElements Quality Program Test Specification
+-----------------------------------------------
+
+Copyright 2015 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-------------------------------------------------------------------------
+    GL_EXT_draw_buffers_indexed tests.
+
+Tests:
+ + dEQP-GLES31.functional.draw_buffers_indexed.*
+
+Includes:
+ + Blend equations, blend functions, blend enable and color masks.
+ + Setting common state first and then per draw buffer state.
+ + Setting per draw buffer state first and then common state.
+ + Overriding per draw buffer state with common state.
+ + Overriding common state with per draw buffer state.
+ + Random tests for different states and renderbuffer formats.
+
+Excludes:
+ + Query tests.
+ + Exhaustive blend state combinations.
+ + Exhaustive tests for all renderbuffer formats.
+
+Description:
+
+Each test cases begins by creating framebuffer object and required renderbuffer
+objects. Depending on test case it sets some common blend state with original
+non-indexed functions, then some draw buffer specific state with indexed
+functions and finally tries to set some common blend state again with original
+functions. Different test cases set different state before and after setting per
+draw buffer state. Results are verified by rendering single quad using the
+framebuffer object and reading back each renderbuffer, which are then compared
+to reference.
+
+pre_common -group uses two RGBA8 renderbuffers. It first sets some common state
+and changes that same state for second draw buffer using indexed functions.
+
+post_common -group is similar to pre_common -group except it first sets the draw
+buffer specific state for second renderbuffer and then overrides it by using
+non-indexed functions.
+
+min_max_random -group uses specification minimum maximum number of draw buffers
+and randomizes renderbuffer formats, pre- and post-common state and per draw
+buffer state.
+
+max_random -group works as min_max_random -group, but uses the implementation
+maximum number of draw buffers.
diff --git a/modules/gles31/functional/CMakeLists.txt b/modules/gles31/functional/CMakeLists.txt
index dc34f7e..a4240f1 100644
--- a/modules/gles31/functional/CMakeLists.txt
+++ b/modules/gles31/functional/CMakeLists.txt
@@ -155,6 +155,8 @@
 	es31fPrimitiveBoundingBoxTests.hpp
 	es31fCopyImageTests.hpp
 	es31fCopyImageTests.cpp
+	es31fDrawBuffersIndexedTests.hpp
+	es31fDrawBuffersIndexedTests.cpp
 	)
 
 add_library(deqp-gles31-functional STATIC ${DEQP_GLES31_FUNCTIONAL_SRCS})
diff --git a/modules/gles31/functional/es31fDrawBuffersIndexedTests.cpp b/modules/gles31/functional/es31fDrawBuffersIndexedTests.cpp
new file mode 100644
index 0000000..ceccb05
--- /dev/null
+++ b/modules/gles31/functional/es31fDrawBuffersIndexedTests.cpp
@@ -0,0 +1,1585 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Indexed blend operation tests (GL_EXT_draw_buffers_indexed)
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fDrawBuffersIndexedTests.hpp"
+
+#include "gluContextInfo.hpp"
+#include "gluDrawUtil.hpp"
+#include "gluObjectWrapper.hpp"
+#include "gluPixelTransfer.hpp"
+#include "gluShaderProgram.hpp"
+#include "gluStrUtil.hpp"
+#include "gluTextureUtil.hpp"
+
+#include "sglrReferenceUtils.hpp"
+
+#include "rrMultisamplePixelBufferAccess.hpp"
+#include "rrRenderer.hpp"
+
+#include "glwEnums.hpp"
+#include "glwFunctions.hpp"
+
+#include "tcuEither.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuMaybe.hpp"
+#include "tcuResultCollector.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuTexture.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuVector.hpp"
+#include "tcuVectorUtil.hpp"
+
+#include "deRandom.hpp"
+#include "deStringUtil.hpp"
+#include "deUniquePtr.hpp"
+
+#include "deInt32.h"
+
+#include <string>
+#include <vector>
+
+using tcu::BVec4;
+using tcu::Either;
+using tcu::IVec2;
+using tcu::IVec4;
+using tcu::Maybe;
+using tcu::TestLog;
+using tcu::TextureFormat;
+using tcu::TextureLevel;
+using tcu::UVec4;
+using tcu::Vec2;
+using tcu::Vec4;
+using tcu::just;
+
+using std::string;
+using std::vector;
+
+using sglr::rr_util::mapGLBlendEquation;
+using sglr::rr_util::mapGLBlendFunc;
+using sglr::rr_util::mapGLBlendEquationAdvanced;
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace
+{
+
+typedef deUint32 BlendEq;
+
+bool isAdvancedBlendEq (BlendEq eq)
+{
+	switch (eq)
+	{
+		case GL_MULTIPLY_KHR:		return true;
+		case GL_SCREEN_KHR:			return true;
+		case GL_OVERLAY_KHR:		return true;
+		case GL_DARKEN_KHR:			return true;
+		case GL_LIGHTEN_KHR:		return true;
+		case GL_COLORDODGE_KHR:		return true;
+		case GL_COLORBURN_KHR:		return true;
+		case GL_HARDLIGHT_KHR:		return true;
+		case GL_SOFTLIGHT_KHR:		return true;
+		case GL_DIFFERENCE_KHR:		return true;
+		case GL_EXCLUSION_KHR:		return true;
+		case GL_HSL_HUE_KHR:		return true;
+		case GL_HSL_SATURATION_KHR:	return true;
+		case GL_HSL_COLOR_KHR:		return true;
+		case GL_HSL_LUMINOSITY_KHR:	return true;
+		default:
+			return false;
+	}
+}
+
+struct SeparateBlendEq
+{
+	SeparateBlendEq (BlendEq rgb_, BlendEq alpha_)
+		: rgb	(rgb_)
+		, alpha	(alpha_)
+	{
+	}
+
+	BlendEq rgb;
+	BlendEq alpha;
+};
+
+struct BlendFunc
+{
+	BlendFunc (deUint32 src_, deUint32 dst_)
+		: src (src_)
+		, dst (dst_)
+	{
+	}
+
+	deUint32 src;
+	deUint32 dst;
+};
+
+struct SeparateBlendFunc
+{
+	SeparateBlendFunc (BlendFunc rgb_, BlendFunc alpha_)
+		: rgb	(rgb_)
+		, alpha	(alpha_)
+	{
+	}
+
+	BlendFunc rgb;
+	BlendFunc alpha;
+};
+
+typedef deUint32 DrawBuffer;
+
+struct BlendState
+{
+	BlendState (void) {}
+
+	BlendState (const Maybe<bool>&									enableBlend_,
+				const Maybe<Either<BlendEq, SeparateBlendEq> >&		blendEq_,
+				const Maybe<Either<BlendFunc, SeparateBlendFunc> >&	blendFunc_,
+				const Maybe<BVec4>&									colorMask_)
+		: enableBlend	(enableBlend_)
+		, blendEq		(blendEq_)
+		, blendFunc		(blendFunc_)
+		, colorMask		(colorMask_)
+	{
+	}
+
+	bool isEmpty (void) const
+	{
+		return (!enableBlend) && (!blendEq) && (!blendFunc) && (!colorMask);
+	}
+
+	Maybe<bool>										enableBlend;
+	Maybe<Either<BlendEq, SeparateBlendEq> >		blendEq;
+	Maybe<Either<BlendFunc, SeparateBlendFunc> >	blendFunc;
+	Maybe<BVec4>									colorMask;
+};
+
+void setCommonBlendState (const glw::Functions& gl, const BlendState& blend)
+{
+	if (blend.enableBlend)
+	{
+		if (*blend.enableBlend)
+			gl.enable(GL_BLEND);
+		else
+			gl.disable(GL_BLEND);
+	}
+
+	if (blend.colorMask)
+	{
+		const BVec4& mask = *blend.colorMask;
+
+		gl.colorMask(mask.x(), mask.y(), mask.z(), mask.w());
+	}
+
+	if (blend.blendEq)
+	{
+		const Either<BlendEq, SeparateBlendEq>& blendEq = *blend.blendEq;
+
+		if (blendEq.is<BlendEq>())
+			gl.blendEquation(blendEq.get<BlendEq>());
+		else if (blendEq.is<SeparateBlendEq>())
+			gl.blendEquationSeparate(blendEq.get<SeparateBlendEq>().rgb, blendEq.get<SeparateBlendEq>().alpha);
+		else
+			DE_ASSERT(false);
+	}
+
+	if (blend.blendFunc)
+	{
+		const Either<BlendFunc, SeparateBlendFunc>& blendFunc = *blend.blendFunc;
+
+		if (blendFunc.is<BlendFunc>())
+			gl.blendFunc(blendFunc.get<BlendFunc>().src, blendFunc.get<BlendFunc>().dst);
+		else if (blendFunc.is<SeparateBlendFunc>())
+			gl.blendFuncSeparate(blendFunc.get<SeparateBlendFunc>().rgb.src, blendFunc.get<SeparateBlendFunc>().rgb.dst, blendFunc.get<SeparateBlendFunc>().alpha.src, blendFunc.get<SeparateBlendFunc>().alpha.dst);
+		else
+			DE_ASSERT(false);
+	}
+
+	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set common blend state.");
+}
+
+void setIndexedBlendState (const glw::Functions& gl, const BlendState& blend, deUint32 index)
+{
+	if (blend.enableBlend)
+	{
+		if (*blend.enableBlend)
+			gl.enablei(GL_BLEND, index);
+		else
+			gl.disablei(GL_BLEND, index);
+	}
+
+	if (blend.colorMask)
+	{
+		const BVec4 mask = *blend.colorMask;
+
+		gl.colorMaski(index, mask.x(), mask.y(), mask.z(), mask.w());
+	}
+
+	if (blend.blendEq)
+	{
+		const Either<BlendEq, SeparateBlendEq>& blendEq = *blend.blendEq;
+
+		if (blendEq.is<BlendEq>())
+			gl.blendEquationi(index, blendEq.get<BlendEq>());
+		else if (blendEq.is<SeparateBlendEq>())
+			gl.blendEquationSeparatei(index, blendEq.get<SeparateBlendEq>().rgb, blendEq.get<SeparateBlendEq>().alpha);
+		else
+			DE_ASSERT(false);
+	}
+
+	if (blend.blendFunc)
+	{
+		const Either<BlendFunc, SeparateBlendFunc>& blendFunc = *blend.blendFunc;
+
+		if (blendFunc.is<BlendFunc>())
+			gl.blendFunci(index, blendFunc.get<BlendFunc>().src, blendFunc.get<BlendFunc>().dst);
+		else if (blendFunc.is<SeparateBlendFunc>())
+			gl.blendFuncSeparatei(index, blendFunc.get<SeparateBlendFunc>().rgb.src, blendFunc.get<SeparateBlendFunc>().rgb.dst, blendFunc.get<SeparateBlendFunc>().alpha.src, blendFunc.get<SeparateBlendFunc>().alpha.dst);
+		else
+			DE_ASSERT(false);
+	}
+
+	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set draw buffer specifig blend state.");
+}
+
+class DrawBufferInfo
+{
+public:
+							DrawBufferInfo	(bool					render,
+											 const IVec2&			size,
+											 const BlendState&		blendState,
+											 const TextureFormat&	format);
+
+	const TextureFormat&	getFormat		(void) const { return m_format;		}
+	const IVec2&			getSize			(void) const { return m_size;		}
+	const BlendState&		getBlendState	(void) const { return m_blendState;	}
+	bool					getRender		(void) const { return m_render;		}
+
+private:
+	bool					m_render;
+	IVec2					m_size;
+	TextureFormat			m_format;
+	BlendState				m_blendState;
+};
+
+DrawBufferInfo::DrawBufferInfo (bool render, const IVec2& size, const BlendState& blendState, const TextureFormat& format)
+	: m_render		(render)
+	, m_size		(size)
+	, m_format		(format)
+	, m_blendState	(blendState)
+{
+}
+
+void clearRenderbuffer (const glw::Functions&			gl,
+						const tcu::TextureFormat&		format,
+						int								renderbufferNdx,
+						int								renderbufferCount,
+						tcu::TextureLevel&				refRenderbuffer)
+{
+	const tcu::TextureFormatInfo	info		= tcu::getTextureFormatInfo(format);
+
+	// Clear each buffer to different color
+	const float						redScale	= float(renderbufferNdx + 1) / float(renderbufferCount);
+	const float						blueScale	= float(renderbufferCount - renderbufferNdx) / float(renderbufferCount);
+	const float						greenScale	= float(((renderbufferCount/2) + renderbufferNdx) % renderbufferCount) / float(renderbufferCount);
+	// Alpha should never be zero as advanced blend equations assume premultiplied alpha.
+	const float						alphaScale	= float(1 + (((renderbufferCount/2) + renderbufferCount - renderbufferNdx) % renderbufferCount)) / float(renderbufferCount);
+
+	switch (tcu::getTextureChannelClass(format.type))
+	{
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+		{
+			const float red		= -1000.0f + 2000.0f * redScale;
+			const float green	= -1000.0f + 2000.0f * greenScale;
+			const float blue	= -1000.0f + 2000.0f * blueScale;
+			const float alpha	= -1000.0f + 2000.0f * alphaScale;
+			const Vec4	color	(red, green, blue, alpha);
+
+			tcu::clear(refRenderbuffer, color);
+			gl.clearBufferfv(GL_COLOR, renderbufferNdx, color.getPtr());
+			break;
+		}
+
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+		{
+			const deInt32	red		= deInt32(info.valueMin.x() + (info.valueMax.x() - info.valueMin.x()) * redScale);
+			const deInt32	green	= deInt32(info.valueMin.y() + (info.valueMax.y() - info.valueMin.y()) * greenScale);
+			const deInt32	blue	= deInt32(info.valueMin.z() + (info.valueMax.z() - info.valueMin.z()) * blueScale);
+			const deInt32	alpha	= deInt32(info.valueMin.w() + (info.valueMax.w() - info.valueMin.w()) * alphaScale);
+			const IVec4		color	(red, green, blue, alpha);
+
+			tcu::clear(refRenderbuffer, color);
+			gl.clearBufferiv(GL_COLOR, renderbufferNdx, color.getPtr());
+			break;
+		}
+
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+		{
+			const deUint32	red		= deUint32(info.valueMax.x() * redScale);
+			const deUint32	green	= deUint32(info.valueMax.y() * greenScale);
+			const deUint32	blue	= deUint32(info.valueMax.z() * blueScale);
+			const deUint32	alpha	= deUint32(info.valueMax.w() * alphaScale);
+			const UVec4		color	(red, green, blue, alpha);
+
+			tcu::clear(refRenderbuffer, color);
+			gl.clearBufferuiv(GL_COLOR, renderbufferNdx, color.getPtr());
+			break;
+		}
+
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		{
+			const float red		= info.valueMin.x() + (info.valueMax.x() - info.valueMin.x()) * redScale;
+			const float green	= info.valueMin.y() + (info.valueMax.y() - info.valueMin.y()) * greenScale;
+			const float blue	= info.valueMin.z() + (info.valueMax.z() - info.valueMin.z()) * blueScale;
+			const float alpha	= info.valueMin.w() + (info.valueMax.w() - info.valueMin.w()) * alphaScale;
+			const Vec4	color	(red, green, blue, alpha);
+
+			tcu::clear(refRenderbuffer, color);
+			gl.clearBufferfv(GL_COLOR, renderbufferNdx, color.getPtr());
+			break;
+		}
+
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		{
+			const float red		= info.valueMax.x() * redScale;
+			const float green	= info.valueMax.y() * greenScale;
+			const float blue	= info.valueMax.z() * blueScale;
+			const float alpha	= info.valueMax.w() * alphaScale;
+			const Vec4	color	(red, green, blue, alpha);
+
+			tcu::clear(refRenderbuffer, color);
+			gl.clearBufferfv(GL_COLOR, renderbufferNdx, color.getPtr());
+			break;
+		}
+
+		default:
+			DE_ASSERT(DE_FALSE);
+	}
+
+	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear renderbuffer.");
+}
+
+void genRenderbuffers (const glw::Functions&			gl,
+					   const vector<DrawBufferInfo>&	drawBuffers,
+					   const glu::Framebuffer&			framebuffer,
+					   const glu::RenderbufferVector&	renderbuffers,
+					   vector<TextureLevel>&			refRenderbuffers)
+{
+	vector<deUint32> bufs;
+
+	bufs.resize(drawBuffers.size());
+
+	DE_ASSERT(drawBuffers.size() == renderbuffers.size());
+	DE_ASSERT(drawBuffers.size() == refRenderbuffers.size());
+
+	gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
+
+	for (int renderbufferNdx = 0; renderbufferNdx < (int)drawBuffers.size(); renderbufferNdx++)
+	{
+		const DrawBufferInfo&		drawBuffer	= drawBuffers[renderbufferNdx];
+		const TextureFormat&		format		= drawBuffer.getFormat();
+		const IVec2&				size		= drawBuffer.getSize();
+		const deUint32				glFormat	= glu::getInternalFormat(format);
+
+		bufs[renderbufferNdx]					= GL_COLOR_ATTACHMENT0 + renderbufferNdx;
+		refRenderbuffers[renderbufferNdx]		= TextureLevel(drawBuffer.getFormat(), size.x(), size.y());
+
+		gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffers[renderbufferNdx]);
+		gl.renderbufferStorage(GL_RENDERBUFFER, glFormat, size.x(), size.y());
+		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + renderbufferNdx, GL_RENDERBUFFER, renderbuffers[renderbufferNdx]);
+		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create renderbuffer.");
+	}
+
+	gl.drawBuffers(bufs.size(), &(bufs[0]));
+
+	for (int renderbufferNdx = 0; renderbufferNdx < (int)drawBuffers.size(); renderbufferNdx++)
+	{
+		const DrawBufferInfo&		drawBuffer	= drawBuffers[renderbufferNdx];
+		const TextureFormat&		format		= drawBuffer.getFormat();
+
+		clearRenderbuffer(gl, format, renderbufferNdx, (int)refRenderbuffers.size(),  refRenderbuffers[renderbufferNdx]);
+	}
+
+	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
+	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+Vec4 getFixedPointFormatThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
+{
+	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
+	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
+
+	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
+	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
+
+	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
+	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
+
+	const tcu::IVec4	srcBits		= tcu::getTextureFormatBitDepth(sourceFormat);
+	const tcu::IVec4	readBits	= tcu::getTextureFormatBitDepth(readPixelsFormat);
+
+	return Vec4(3.0f) / ((tcu::Vector<deUint64, 4>(1) << (tcu::min(srcBits, readBits).cast<deUint64>())) - tcu::Vector<deUint64, 4>(1)).cast<float>();
+}
+
+void verifyRenderbuffer (TestLog&					log,
+						 tcu::ResultCollector&		results,
+						 const tcu::TextureFormat&	format,
+						 int						renderbufferNdx,
+						 const tcu::TextureLevel&	refRenderbuffer,
+						 const tcu::TextureLevel&	result)
+{
+	switch (tcu::getTextureChannelClass(format.type))
+	{
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+		{
+			const string	name		= "Renderbuffer" + de::toString(renderbufferNdx);
+			const string	desc		= "Compare renderbuffer " + de::toString(renderbufferNdx);
+			const UVec4		threshold	(1, 1, 1, 1);
+
+			if (!tcu::floatUlpThresholdCompare(log, name.c_str(), desc.c_str(), refRenderbuffer, result, threshold, tcu::COMPARE_LOG_RESULT))
+				results.fail("Verification of renderbuffer " + de::toString(renderbufferNdx) + " failed.");
+
+			break;
+		}
+
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+		{
+			const string	name		= "Renderbuffer" + de::toString(renderbufferNdx);
+			const string	desc		= "Compare renderbuffer " + de::toString(renderbufferNdx);
+			const UVec4		threshold	(1, 1, 1, 1);
+
+			if (!tcu::intThresholdCompare(log, name.c_str(), desc.c_str(), refRenderbuffer, result, threshold, tcu::COMPARE_LOG_RESULT))
+				results.fail("Verification of renderbuffer " + de::toString(renderbufferNdx) + " failed.");
+
+			break;
+		}
+
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		{
+			const string	name		= "Renderbuffer" + de::toString(renderbufferNdx);
+			const string	desc		= "Compare renderbuffer " + de::toString(renderbufferNdx);
+			const Vec4		threshold	= getFixedPointFormatThreshold(format, result.getFormat());
+
+			if (!tcu::floatThresholdCompare(log, name.c_str(), desc.c_str(), refRenderbuffer, result, threshold, tcu::COMPARE_LOG_RESULT))
+				results.fail("Verification of renderbuffer " + de::toString(renderbufferNdx) + " failed.");
+
+			break;
+		}
+
+
+		default:
+			DE_ASSERT(DE_FALSE);
+	}
+}
+
+TextureFormat getReadPixelFormat (const TextureFormat& format)
+{
+	switch (tcu::getTextureChannelClass(format.type))
+	{
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			return TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32);
+
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+			return TextureFormat(TextureFormat::RGBA, TextureFormat::SIGNED_INT32);
+
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+			return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
+
+		default:
+			DE_ASSERT(false);
+			return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
+	}
+}
+
+void verifyRenderbuffers (TestLog&							log,
+						  tcu::ResultCollector&				results,
+						  glu::RenderContext&				renderContext,
+						  const glu::RenderbufferVector&	renderbuffers,
+						  const glu::Framebuffer&			framebuffer,
+						  const vector<TextureLevel>&		refRenderbuffers)
+{
+	const glw::Functions& gl = renderContext.getFunctions();
+
+	DE_ASSERT(renderbuffers.size() == refRenderbuffers.size());
+
+	gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
+
+	for (int renderbufferNdx = 0; renderbufferNdx < (int)renderbuffers.size(); renderbufferNdx++)
+	{
+		const TextureLevel&	refRenderbuffer	= refRenderbuffers[renderbufferNdx];
+		const int			width			= refRenderbuffer.getWidth();
+		const int			height			= refRenderbuffer.getHeight();
+		const TextureFormat	format			= refRenderbuffer.getFormat();
+
+		tcu::TextureLevel	result			(getReadPixelFormat(format), width, height);
+
+		gl.readBuffer(GL_COLOR_ATTACHMENT0 + renderbufferNdx);
+		glu::readPixels(renderContext, 0, 0, result.getAccess());
+		GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels from renderbuffer failed.");
+
+		verifyRenderbuffer(log, results, format, renderbufferNdx, refRenderbuffer, result);
+	}
+
+	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+static const float s_quadCoords[] =
+{
+	-0.5f, -0.5f,
+	 0.5f, -0.5f,
+	 0.5f,  0.5f,
+
+	 0.5f,  0.5f,
+	-0.5f,  0.5f,
+	-0.5f, -0.5f
+};
+
+void setBlendState (rr::FragmentOperationState& fragOps, const BlendState& state)
+{
+	if (state.blendEq)
+	{
+		if (state.blendEq->is<BlendEq>())
+		{
+			if (isAdvancedBlendEq(state.blendEq->get<BlendEq>()))
+			{
+				const rr::BlendEquationAdvanced	equation = mapGLBlendEquationAdvanced(state.blendEq->get<BlendEq>());
+
+				fragOps.blendMode				= rr::BLENDMODE_ADVANCED;
+				fragOps.blendEquationAdvaced	= equation;
+			}
+			else
+			{
+				const rr::BlendEquation equation = mapGLBlendEquation(state.blendEq->get<BlendEq>());
+
+				fragOps.blendMode				= rr::BLENDMODE_STANDARD;
+				fragOps.blendRGBState.equation	= equation;
+				fragOps.blendAState.equation	= equation;
+			}
+		}
+		else
+		{
+			DE_ASSERT(state.blendEq->is<SeparateBlendEq>());
+
+			fragOps.blendMode				= rr::BLENDMODE_STANDARD;
+			fragOps.blendRGBState.equation	= mapGLBlendEquation(state.blendEq->get<SeparateBlendEq>().rgb);
+			fragOps.blendAState.equation	= mapGLBlendEquation(state.blendEq->get<SeparateBlendEq>().alpha);
+		}
+	}
+
+	if (state.blendFunc)
+	{
+		if (state.blendFunc->is<BlendFunc>())
+		{
+			const rr::BlendFunc srcFunction = mapGLBlendFunc(state.blendFunc->get<BlendFunc>().src);
+			const rr::BlendFunc dstFunction = mapGLBlendFunc(state.blendFunc->get<BlendFunc>().dst);
+
+			fragOps.blendRGBState.srcFunc	= srcFunction;
+			fragOps.blendRGBState.dstFunc	= dstFunction;
+
+			fragOps.blendAState.srcFunc		= srcFunction;
+			fragOps.blendAState.dstFunc		= dstFunction;
+		}
+		else
+		{
+			DE_ASSERT(state.blendFunc->is<SeparateBlendFunc>());
+
+			fragOps.blendRGBState.srcFunc	= mapGLBlendFunc(state.blendFunc->get<SeparateBlendFunc>().rgb.src);
+			fragOps.blendRGBState.dstFunc	= mapGLBlendFunc(state.blendFunc->get<SeparateBlendFunc>().rgb.dst);
+
+			fragOps.blendAState.srcFunc		= mapGLBlendFunc(state.blendFunc->get<SeparateBlendFunc>().alpha.src);
+			fragOps.blendAState.dstFunc		= mapGLBlendFunc(state.blendFunc->get<SeparateBlendFunc>().alpha.dst);
+		}
+	}
+
+	if (state.colorMask)
+		fragOps.colorMask = *state.colorMask;
+}
+
+rr::RenderState createRenderState (const BlendState& preCommonBlendState, const BlendState& postCommonBlendState, const DrawBufferInfo& info)
+{
+	const IVec2		size	= info.getSize();
+	rr::RenderState	state	(rr::ViewportState(rr::WindowRectangle(0, 0, size.x(), size.y())));
+
+	state.fragOps.blendMode = rr::BLENDMODE_STANDARD;
+
+	setBlendState(state.fragOps, preCommonBlendState);
+	setBlendState(state.fragOps, info.getBlendState());
+	setBlendState(state.fragOps, postCommonBlendState);
+
+	if (postCommonBlendState.enableBlend)
+		state.fragOps.blendMode = (*(postCommonBlendState.enableBlend) ? state.fragOps.blendMode : rr::BLENDMODE_NONE);
+	else  if (info.getBlendState().enableBlend)
+		state.fragOps.blendMode = (*(info.getBlendState().enableBlend) ? state.fragOps.blendMode : rr::BLENDMODE_NONE);
+	else if (preCommonBlendState.enableBlend)
+		state.fragOps.blendMode = (*(preCommonBlendState.enableBlend) ? state.fragOps.blendMode : rr::BLENDMODE_NONE);
+	else
+		state.fragOps.blendMode = rr::BLENDMODE_NONE;
+
+	if (tcu::getTextureChannelClass(info.getFormat().type) != tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT && tcu::getTextureChannelClass(info.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
+		state.fragOps.blendMode = rr::BLENDMODE_NONE;
+
+	return state;
+}
+
+class VertexShader : public rr::VertexShader
+{
+public:
+					VertexShader	(void);
+	virtual void	shadeVertices	(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
+};
+
+VertexShader::VertexShader (void)
+	: rr::VertexShader	(1, 1)
+{
+	m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
+	m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
+}
+
+void VertexShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
+{
+	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
+	{
+		rr::VertexPacket& packet = *packets[packetNdx];
+
+		packet.position		= rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx);
+		packet.outputs[0]	= 0.5f * (Vec4(1.0f) + rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx));
+	}
+}
+
+class FragmentShader : public rr::FragmentShader
+{
+public:
+			FragmentShader	(int drawBufferNdx, const DrawBufferInfo& info);
+	void	shadeFragments	(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;
+
+private:
+	const int				m_drawBufferNdx;
+	const DrawBufferInfo	m_info;
+};
+
+FragmentShader::FragmentShader (int drawBufferNdx, const DrawBufferInfo& info)
+	: rr::FragmentShader	(1, 1)
+	, m_drawBufferNdx		(drawBufferNdx)
+	, m_info				(info)
+{
+	m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
+
+	switch (tcu::getTextureChannelClass(m_info.getFormat().type))
+	{
+		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+			m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
+			break;
+
+		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+			m_outputs[0].type = rr::GENERICVECTYPE_UINT32;
+			break;
+
+		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+			m_outputs[0].type = rr::GENERICVECTYPE_INT32;
+			break;
+
+		default:
+			DE_ASSERT(false);
+	};
+}
+
+void FragmentShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
+{
+	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
+	{
+		rr::FragmentPacket& packet = packets[packetNdx];
+
+		DE_ASSERT(m_drawBufferNdx >= 0);
+		DE_UNREF(m_info);
+
+		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
+		{
+			const Vec2	vColor		= rr::readVarying<float>(packet, context, 0, fragNdx).xy();
+			const float	values[]	=
+			{
+				vColor.x(),
+				vColor.y(),
+				(1.0f - vColor.x()),
+				(1.0f - vColor.y())
+			};
+
+			switch (tcu::getTextureChannelClass(m_info.getFormat().type))
+			{
+				case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+				case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+				case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+				{
+					const Vec4 color (values[(m_drawBufferNdx + 0) % 4],
+									  values[(m_drawBufferNdx + 1) % 4],
+									  values[(m_drawBufferNdx + 2) % 4],
+									  values[(m_drawBufferNdx + 3) % 4]);
+
+					rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
+					break;
+				}
+
+				case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+				{
+					const UVec4 color ((deUint32)(values[(m_drawBufferNdx + 0) % 4]),
+									   (deUint32)(values[(m_drawBufferNdx + 1) % 4]),
+									   (deUint32)(values[(m_drawBufferNdx + 2) % 4]),
+									   (deUint32)(values[(m_drawBufferNdx + 3) % 4]));
+
+					rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
+					break;
+				}
+
+				case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+				{
+					const IVec4 color ((deInt32)(values[(m_drawBufferNdx + 0) % 4]),
+									   (deInt32)(values[(m_drawBufferNdx + 1) % 4]),
+									   (deInt32)(values[(m_drawBufferNdx + 2) % 4]),
+									   (deInt32)(values[(m_drawBufferNdx + 3) % 4]));
+
+					rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
+					break;
+				}
+
+				default:
+					DE_ASSERT(DE_FALSE);
+			};
+		}
+	}
+}
+
+rr::VertexAttrib createVertexAttrib (const float* coords)
+{
+	rr::VertexAttrib attrib;
+
+	attrib.type		= rr::VERTEXATTRIBTYPE_FLOAT;
+	attrib.size		= 2;
+	attrib.pointer	= coords;
+
+	return attrib;
+}
+
+void renderRefQuad (const BlendState&				preCommonBlendState,
+					const BlendState&				postCommonBlendState,
+					const vector<DrawBufferInfo>&	drawBuffers,
+					vector<TextureLevel>&			refRenderbuffers)
+{
+	const rr::Renderer			renderer;
+	const rr::PrimitiveList		primitives		(rr::PRIMITIVETYPE_TRIANGLES, 6, 0);
+	const rr::VertexAttrib		vertexAttribs[] =
+	{
+		createVertexAttrib(s_quadCoords)
+	};
+
+	for (int drawBufferNdx = 0; drawBufferNdx < (int)drawBuffers.size(); drawBufferNdx++)
+	{
+		if (drawBuffers[drawBufferNdx].getRender())
+		{
+			const rr::RenderState	renderState		(createRenderState(preCommonBlendState, postCommonBlendState, drawBuffers[drawBufferNdx]));
+			const rr::RenderTarget	renderTarget	(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(refRenderbuffers[drawBufferNdx].getAccess()));
+			const VertexShader		vertexShader;
+			const FragmentShader	fragmentShader	(drawBufferNdx, drawBuffers[drawBufferNdx]);
+			const rr::Program		program			(&vertexShader, &fragmentShader);
+			const rr::DrawCommand	command			(renderState, renderTarget, program, DE_LENGTH_OF_ARRAY(vertexAttribs), vertexAttribs, primitives);
+
+			renderer.draw(command);
+		}
+	}
+}
+
+bool requiresAdvancedBlendEq (const BlendState& pre, const BlendState post, const vector<DrawBufferInfo>& drawBuffers)
+{
+	bool requiresAdvancedBlendEq = false;
+
+	if (pre.blendEq && pre.blendEq->is<BlendEq>())
+		requiresAdvancedBlendEq |= isAdvancedBlendEq(pre.blendEq->get<BlendEq>());
+
+	if (post.blendEq && post.blendEq->is<BlendEq>())
+		requiresAdvancedBlendEq |= isAdvancedBlendEq(post.blendEq->get<BlendEq>());
+
+	for (int drawBufferNdx = 0; drawBufferNdx < (int)drawBuffers.size(); drawBufferNdx++)
+	{
+		const BlendState& drawBufferBlendState = drawBuffers[drawBufferNdx].getBlendState();
+
+		if (drawBufferBlendState.blendEq && drawBufferBlendState.blendEq->is<BlendEq>())
+			requiresAdvancedBlendEq |= isAdvancedBlendEq(drawBufferBlendState.blendEq->get<BlendEq>());
+	}
+
+	return requiresAdvancedBlendEq;
+}
+
+glu::VertexSource genVertexSource (void)
+{
+	const char* const vertexSource =
+		"#version 310 es\n"
+		"layout(location=0) in highp vec2 i_coord;\n"
+		"out highp vec2 v_color;\n"
+		"void main (void)\n"
+		"{\n"
+		"\tv_color = 0.5 * (vec2(1.0) + i_coord);\n"
+		"\tgl_Position = vec4(i_coord, 0.0, 1.0);\n"
+		"}";
+
+	return glu::VertexSource(vertexSource);
+}
+
+glu::FragmentSource genFragmentSource (const BlendState& preCommonBlendState, const BlendState& postCommonBlendState, const vector<DrawBufferInfo>& drawBuffers)
+{
+	std::ostringstream stream;
+
+	stream << "#version 310 es\n";
+
+	if (requiresAdvancedBlendEq(preCommonBlendState, postCommonBlendState, drawBuffers))
+	{
+		stream << "#extension GL_KHR_blend_equation_advanced : require\n"
+			   <<  "layout(blend_support_all_equations) out;\n";
+	}
+
+	stream << "in highp vec2 v_color;\n";
+
+	for (int drawBufferNdx = 0; drawBufferNdx < (int)drawBuffers.size(); drawBufferNdx++)
+	{
+		const DrawBufferInfo&	drawBuffer			= drawBuffers[drawBufferNdx];
+		const TextureFormat&	format				= drawBuffer.getFormat();
+
+		stream << "layout(location=" << drawBufferNdx << ") out highp ";
+
+		switch (tcu::getTextureChannelClass(format.type))
+		{
+			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+				stream << "vec4";
+				break;
+
+			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+				stream << "uvec4";
+				break;
+
+			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+				stream << "ivec4";
+				break;
+
+			default:
+				DE_ASSERT(DE_FALSE);
+		};
+
+		stream << " o_drawBuffer" <<  drawBufferNdx << ";\n";
+	}
+
+	stream << "void main (void)\n"
+		   << "{\n";
+
+	for (int drawBufferNdx = 0; drawBufferNdx < (int)drawBuffers.size(); drawBufferNdx++)
+	{
+		const DrawBufferInfo&	drawBuffer		= drawBuffers[drawBufferNdx];
+		const TextureFormat&	format			= drawBuffer.getFormat();
+		const char* const		values[]		=
+		{
+			"v_color.x",
+			"v_color.y",
+			"(1.0 - v_color.x)",
+			"(1.0 - v_color.y)"
+		};
+
+		stream << "\to_drawBuffer" <<  drawBufferNdx;
+
+		switch (tcu::getTextureChannelClass(format.type))
+		{
+			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
+			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
+				stream << " = vec4(" << values[(drawBufferNdx + 0) % 4]
+					   << ", " << values[(drawBufferNdx + 1) % 4]
+					   << ", " << values[(drawBufferNdx + 2) % 4]
+					   << ", " << values[(drawBufferNdx + 3) % 4] << ");\n";
+				break;
+
+			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+				stream << " = uvec4(uint(" << values[(drawBufferNdx + 0) % 4]
+					   << "), uint(" << values[(drawBufferNdx + 1) % 4]
+					   << "), uint(" << values[(drawBufferNdx + 2) % 4]
+					   << "), uint(" << values[(drawBufferNdx + 3) % 4] << "));\n";
+				break;
+
+			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+				stream << " = ivec4(int(" << values[(drawBufferNdx + 0) % 4]
+					   << "), int(" << values[(drawBufferNdx + 1) % 4]
+					   << "), int(" << values[(drawBufferNdx + 2) % 4]
+					   << "), int(" << values[(drawBufferNdx + 3) % 4] << "));\n";
+				break;
+
+			default:
+				DE_ASSERT(DE_FALSE);
+		};
+	}
+
+	stream << "}";
+
+	return glu::FragmentSource(stream.str());
+}
+
+glu::ProgramSources genShaderSources (const BlendState& preCommonBlendState, const BlendState& postCommonBlendState, const vector<DrawBufferInfo>& drawBuffers)
+{
+	return glu::ProgramSources() << genVertexSource() << genFragmentSource(preCommonBlendState, postCommonBlendState, drawBuffers);
+}
+
+void renderGLQuad (glu::RenderContext&			renderContext,
+				   const glu::ShaderProgram&	program)
+{
+	const glu::VertexArrayBinding vertexArrays[] =
+	{
+		glu::VertexArrayBinding(glu::BindingPoint(0), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 2, 6, 0, s_quadCoords))
+	};
+
+	glu::draw(renderContext, program.getProgram(), 1, vertexArrays, glu::pr::Triangles(6));
+}
+
+void renderQuad (TestLog&						log,
+				 glu::RenderContext&			renderContext,
+				 const BlendState&				preCommonBlendState,
+				 const BlendState&				postCommonBlendState,
+				 const vector<DrawBufferInfo>&	drawBuffers,
+				 const glu::Framebuffer&		framebuffer,
+				 vector<TextureLevel>&			refRenderbuffers)
+{
+	const glw::Functions&		gl						= renderContext.getFunctions();
+	const glu::ShaderProgram	program					(gl, genShaderSources(preCommonBlendState, postCommonBlendState, drawBuffers));
+	const IVec2					size					= drawBuffers[0].getSize();
+	const bool					requiresBlendBarriers	= requiresAdvancedBlendEq(preCommonBlendState, postCommonBlendState, drawBuffers);
+
+	vector<deUint32> bufs;
+
+	bufs.resize(drawBuffers.size());
+
+	for (int bufNdx = 0; bufNdx < (int)bufs.size(); bufNdx++)
+		bufs[bufNdx] = (drawBuffers[bufNdx].getRender() ? GL_COLOR_ATTACHMENT0 + bufNdx : GL_NONE);
+
+	log << program;
+
+	gl.viewport(0, 0, size.x(), size.y());
+	gl.useProgram(program.getProgram());
+	gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
+
+	setCommonBlendState(gl, preCommonBlendState);
+
+	for (int renderbufferNdx = 0; renderbufferNdx < (int)drawBuffers.size(); renderbufferNdx++)
+		setIndexedBlendState(gl, drawBuffers[renderbufferNdx].getBlendState(), renderbufferNdx);
+
+	setCommonBlendState(gl, postCommonBlendState);
+
+	gl.drawBuffers(bufs.size(), &(bufs[0]));
+
+	if (requiresBlendBarriers)
+		gl.blendBarrierKHR();
+
+	renderGLQuad(renderContext, program);
+
+	if (requiresBlendBarriers)
+		gl.blendBarrierKHR();
+
+	gl.drawBuffers(0, 0);
+	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
+	gl.useProgram(0);
+
+	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render");
+
+	renderRefQuad(preCommonBlendState, postCommonBlendState, drawBuffers, refRenderbuffers);
+}
+
+void logBlendState (TestLog&			log,
+					const BlendState&	blend)
+{
+	if (blend.enableBlend)
+	{
+		if (*blend.enableBlend)
+			log << TestLog::Message << "Enable blending." << TestLog::EndMessage;
+		else
+			log << TestLog::Message << "Disable blending." << TestLog::EndMessage;
+	}
+
+	if (blend.colorMask)
+	{
+		const BVec4 mask = *blend.colorMask;
+
+		log << TestLog::Message << "Set color mask: " << mask << "." << TestLog::EndMessage;
+	}
+
+
+	if (blend.blendEq)
+	{
+		const Either<BlendEq, SeparateBlendEq>& blendEq = *blend.blendEq;
+
+		if (blendEq.is<BlendEq>())
+			log << TestLog::Message << "Set blend equation: " << glu::getBlendEquationStr(blendEq.get<BlendEq>()) << "." << TestLog::EndMessage;
+		else if (blendEq.is<SeparateBlendEq>())
+			log << TestLog::Message << "Set blend equation rgb: " << glu::getBlendEquationStr(blendEq.get<SeparateBlendEq>().rgb) << ", alpha: " << glu::getBlendEquationStr(blendEq.get<SeparateBlendEq>().alpha) << "." << TestLog::EndMessage;
+		else
+			DE_ASSERT(false);
+	}
+
+	if (blend.blendFunc)
+	{
+		const Either<BlendFunc, SeparateBlendFunc>& blendFunc = *blend.blendFunc;
+
+		if (blendFunc.is<BlendFunc>())
+			log << TestLog::Message << "Set blend function source: " << glu::getBlendFactorStr(blendFunc.get<BlendFunc>().src) << ", destination: " << glu::getBlendFactorStr(blendFunc.get<BlendFunc>().dst) << "." << TestLog::EndMessage;
+		else if (blendFunc.is<SeparateBlendFunc>())
+		{
+			log << TestLog::Message << "Set blend function rgb source: " << glu::getBlendFactorStr(blendFunc.get<SeparateBlendFunc>().rgb.src) << ", destination: " << glu::getBlendFactorStr(blendFunc.get<SeparateBlendFunc>().rgb.dst) << "." << TestLog::EndMessage;
+			log << TestLog::Message << "Set blend function alpha source: " << glu::getBlendFactorStr(blendFunc.get<SeparateBlendFunc>().alpha.src) << ", destination: " << glu::getBlendFactorStr(blendFunc.get<SeparateBlendFunc>().alpha.dst) << "." << TestLog::EndMessage;
+		}
+		else
+			DE_ASSERT(false);
+	}
+}
+
+void logTestCaseInfo (TestLog&						log,
+					  const BlendState&				preCommonBlendState,
+					  const BlendState&				postCommonBlendState,
+					  const vector<DrawBufferInfo>&	drawBuffers)
+{
+	{
+		tcu::ScopedLogSection drawBuffersSection(log, "DrawBuffers", "Draw buffers");
+
+		for (int drawBufferNdx = 0; drawBufferNdx < (int)drawBuffers.size(); drawBufferNdx++)
+		{
+			const tcu::ScopedLogSection	drawBufferSection	(log, "DrawBuffer" + de::toString(drawBufferNdx), "Draw Buffer " + de::toString(drawBufferNdx));
+			const DrawBufferInfo&		drawBuffer			= drawBuffers[drawBufferNdx];
+
+			log << TestLog::Message << "Format: " << drawBuffer.getFormat() << TestLog::EndMessage;
+			log << TestLog::Message << "Size: " << drawBuffer.getSize() << TestLog::EndMessage;
+			log << TestLog::Message << "Render: " << (drawBuffer.getRender() ? "true" : "false") << TestLog::EndMessage;
+		}
+	}
+
+	if (!preCommonBlendState.isEmpty())
+	{
+		tcu::ScopedLogSection s(log, "PreCommonState", "First set common blend state");
+		logBlendState(log, preCommonBlendState);
+	}
+
+	for (int drawBufferNdx = 0; drawBufferNdx < (int)drawBuffers.size(); drawBufferNdx++)
+	{
+		if (!drawBuffers[drawBufferNdx].getBlendState().isEmpty())
+		{
+			const tcu::ScopedLogSection s(log, "DrawBufferState" + de::toString(drawBufferNdx), "Set DrawBuffer " + de::toString(drawBufferNdx) + " state to");
+
+			logBlendState(log, drawBuffers[drawBufferNdx].getBlendState());
+		}
+	}
+
+	if (!postCommonBlendState.isEmpty())
+	{
+		tcu::ScopedLogSection s(log, "PostCommonState", "After set common blend state");
+		logBlendState(log, postCommonBlendState);
+	}
+}
+
+void runTest (TestLog&						log,
+			  tcu::ResultCollector&			results,
+			  glu::RenderContext&			renderContext,
+
+			  const BlendState&				preCommonBlendState,
+			  const BlendState&				postCommonBlendState,
+			  const vector<DrawBufferInfo>&	drawBuffers)
+{
+	const glw::Functions&	gl					= renderContext.getFunctions();
+	glu::RenderbufferVector	renderbuffers		(gl, drawBuffers.size());
+	glu::Framebuffer		framebuffer			(gl);
+	vector<TextureLevel>	refRenderbuffers	(drawBuffers.size());
+
+	logTestCaseInfo(log, preCommonBlendState, postCommonBlendState, drawBuffers);
+
+	genRenderbuffers(gl, drawBuffers, framebuffer, renderbuffers, refRenderbuffers);
+
+	renderQuad(log, renderContext, preCommonBlendState, postCommonBlendState, drawBuffers, framebuffer, refRenderbuffers);
+
+	verifyRenderbuffers(log, results, renderContext, renderbuffers, framebuffer, refRenderbuffers);
+}
+
+class DrawBuffersIndexedTest : public TestCase
+{
+public:
+					DrawBuffersIndexedTest (Context&						context,
+											const BlendState&				preCommonBlendState,
+											const BlendState&				postCommonBlendState,
+											const vector<DrawBufferInfo>&	drawBuffers,
+											const string&					name,
+											const string&					description);
+
+	void			init					(void);
+	IterateResult	iterate					(void);
+
+private:
+	const BlendState				m_preCommonBlendState;
+	const BlendState				m_postCommonBlendState;
+	const vector<DrawBufferInfo>	m_drawBuffers;
+};
+
+DrawBuffersIndexedTest::DrawBuffersIndexedTest (Context&						context,
+												const BlendState&				preCommonBlendState,
+												const BlendState&				postCommonBlendState,
+												const vector<DrawBufferInfo>&	drawBuffers,
+												const string&					name,
+												const string&					description)
+	: TestCase					(context, name.c_str(), description.c_str())
+	, m_preCommonBlendState		(preCommonBlendState)
+	, m_postCommonBlendState	(postCommonBlendState)
+	, m_drawBuffers				(drawBuffers)
+{
+}
+
+void DrawBuffersIndexedTest::init (void)
+{
+	if (requiresAdvancedBlendEq(m_preCommonBlendState, m_postCommonBlendState, m_drawBuffers) && !m_context.getContextInfo().isExtensionSupported("GL_KHR_blend_equation_advanced"))
+		throw tcu::NotSupportedError("Extension GL_KHR_blend_equation_advanced not supported", "", __FILE__, __LINE__);
+
+	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_draw_buffers_indexed"))
+		throw tcu::NotSupportedError("Extension GL_EXT_draw_buffers_indexed not supported", "", __FILE__, __LINE__);
+}
+
+TestCase::IterateResult DrawBuffersIndexedTest::iterate (void)
+{
+	TestLog&				log		= m_testCtx.getLog();
+	tcu::ResultCollector	results	(log);
+
+	runTest(log, results, m_context.getRenderContext(), m_preCommonBlendState, m_postCommonBlendState, m_drawBuffers);
+
+	results.setTestContextResult(m_testCtx);
+
+	return STOP;
+}
+
+BlendEq getRandomBlendEq (de::Random& rng)
+{
+	const BlendEq eqs[] =
+	{
+		GL_FUNC_ADD,
+		GL_FUNC_SUBTRACT,
+		GL_FUNC_REVERSE_SUBTRACT,
+		GL_MIN,
+		GL_MAX
+	};
+
+	return de::getSizedArrayElement<DE_LENGTH_OF_ARRAY(eqs)>(eqs, rng.getUint32() % DE_LENGTH_OF_ARRAY(eqs));
+}
+
+BlendFunc getRandomBlendFunc (de::Random& rng)
+{
+	const deUint32 funcs[] =
+	{
+		GL_ZERO,
+		GL_ONE,
+		GL_SRC_COLOR,
+		GL_ONE_MINUS_SRC_COLOR,
+		GL_DST_COLOR,
+		GL_ONE_MINUS_DST_COLOR,
+		GL_SRC_ALPHA,
+		GL_ONE_MINUS_SRC_ALPHA,
+		GL_DST_ALPHA,
+		GL_ONE_MINUS_DST_ALPHA,
+		GL_CONSTANT_COLOR,
+		GL_ONE_MINUS_CONSTANT_COLOR,
+		GL_CONSTANT_ALPHA,
+		GL_ONE_MINUS_CONSTANT_ALPHA,
+		GL_SRC_ALPHA_SATURATE
+	};
+
+	const deUint32 src = de::getSizedArrayElement<DE_LENGTH_OF_ARRAY(funcs)>(funcs, rng.getUint32() % DE_LENGTH_OF_ARRAY(funcs));
+	const deUint32 dst = de::getSizedArrayElement<DE_LENGTH_OF_ARRAY(funcs)>(funcs, rng.getUint32() % DE_LENGTH_OF_ARRAY(funcs));
+
+	return BlendFunc(src, dst);
+}
+
+void genRandomBlendState (de::Random& rng, BlendState& blendState)
+{
+	if (rng.getBool())
+		blendState.enableBlend = rng.getBool();
+
+	if (rng.getBool())
+	{
+		if (rng.getBool())
+			blendState.blendEq = getRandomBlendEq(rng);
+		else
+		{
+			const BlendEq	rgb		= getRandomBlendEq(rng);
+			const BlendEq	alpha	= getRandomBlendEq(rng);
+
+			blendState.blendEq		= SeparateBlendEq(rgb, alpha);
+		}
+	}
+
+	if (rng.getBool())
+	{
+		if (rng.getBool())
+			blendState.blendFunc = getRandomBlendFunc(rng);
+		else
+		{
+			const BlendFunc	rgb		= getRandomBlendFunc(rng);
+			const BlendFunc	alpha	= getRandomBlendFunc(rng);
+
+			blendState.blendFunc	= SeparateBlendFunc(rgb, alpha);
+		}
+	}
+
+	if (rng.getBool())
+	{
+		const bool red		= rng.getBool();
+		const bool green	= rng.getBool();
+		const bool blue		= rng.getBool();
+		const bool alpha	= rng.getBool();
+
+		blendState.colorMask = BVec4(red, blue, green, alpha);
+	}
+}
+
+TextureFormat getRandomFormat (de::Random& rng)
+{
+	const deUint32 glFormats[] =
+	{
+		GL_R8,
+		GL_RG8,
+		GL_RGB8,
+		GL_RGB565,
+		GL_RGBA4,
+		GL_RGB5_A1,
+		GL_RGBA8,
+		GL_RGB10_A2,
+		GL_RGB10_A2UI,
+		GL_R8I,
+		GL_R8UI,
+		GL_R16I,
+		GL_R16UI,
+		GL_R32I,
+		GL_R32UI,
+		GL_RG8I,
+		GL_RG8UI,
+		GL_RG16I,
+		GL_RG16UI,
+		GL_RG32I,
+		GL_RG32UI,
+		GL_RGBA8I,
+		GL_RGBA8UI,
+		GL_RGBA16I,
+		GL_RGBA16UI,
+		GL_RGBA32I,
+		GL_RGBA32UI
+	};
+
+	return glu::mapGLInternalFormat(de::getSizedArrayElement(glFormats, rng.getUint32() % DE_LENGTH_OF_ARRAY(glFormats)));
+}
+
+void genRandomTest (de::Random& rng, BlendState& preCommon, BlendState& postCommon, vector<DrawBufferInfo>& drawBuffers, int maxDrawBufferCount)
+{
+	genRandomBlendState(rng, preCommon);
+	genRandomBlendState(rng, postCommon);
+
+	for (int drawBufferNdx = 0; drawBufferNdx < maxDrawBufferCount; drawBufferNdx++)
+	{
+		const bool			render		= rng.getFloat() > 0.1f;
+		const IVec2			size		(64, 64);
+		const TextureFormat	format		(getRandomFormat(rng));
+		BlendState			blendState;
+
+		genRandomBlendState(rng, blendState);
+		drawBuffers.push_back(DrawBufferInfo(render, size, blendState, format));
+	}
+}
+
+class MaxDrawBuffersIndexedTest : public TestCase
+{
+public:
+					MaxDrawBuffersIndexedTest	(Context& contet, int seed);
+
+	void			init						(void);
+	IterateResult	iterate						(void);
+
+private:
+	const int		m_seed;
+};
+
+MaxDrawBuffersIndexedTest::MaxDrawBuffersIndexedTest (Context& context, int seed)
+	: TestCase	(context, de::toString(seed).c_str(), de::toString(seed).c_str())
+	, m_seed	(deInt32Hash(seed) ^ 1558001307u)
+{
+}
+
+void MaxDrawBuffersIndexedTest::init (void)
+{
+	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_draw_buffers_indexed"))
+		throw tcu::NotSupportedError("Extension GL_EXT_draw_buffers_indexed not supported", "", __FILE__, __LINE__);
+}
+
+TestCase::IterateResult MaxDrawBuffersIndexedTest::iterate (void)
+{
+	TestLog&				log						= m_testCtx.getLog();
+	tcu::ResultCollector	results					(log);
+	de::Random				rng						(m_seed);
+	BlendState				preCommonBlendState;
+	BlendState				postCommonBlendState;
+	vector<DrawBufferInfo>	drawBuffers;
+
+	genRandomTest(rng, preCommonBlendState, postCommonBlendState, drawBuffers, 4);
+
+	runTest(log, results, m_context.getRenderContext(), preCommonBlendState, postCommonBlendState, drawBuffers);
+
+	results.setTestContextResult(m_testCtx);
+
+	return STOP;
+}
+
+class ImplMaxDrawBuffersIndexedTest : public TestCase
+{
+public:
+					ImplMaxDrawBuffersIndexedTest	(Context& contet, int seed);
+
+	void			init							(void);
+	IterateResult	iterate							(void);
+
+private:
+	const int		m_seed;
+};
+
+ImplMaxDrawBuffersIndexedTest::ImplMaxDrawBuffersIndexedTest (Context& context, int seed)
+	: TestCase	(context, de::toString(seed).c_str(), de::toString(seed).c_str())
+	, m_seed	(deInt32Hash(seed) ^ 2686315738u)
+{
+}
+
+void ImplMaxDrawBuffersIndexedTest::init (void)
+{
+	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_draw_buffers_indexed"))
+		throw tcu::NotSupportedError("Extension GL_EXT_draw_buffers_indexed not supported", "", __FILE__, __LINE__);
+}
+
+TestCase::IterateResult ImplMaxDrawBuffersIndexedTest::iterate (void)
+{
+	TestLog&				log						= m_testCtx.getLog();
+	tcu::ResultCollector	results					(log);
+	const glw::Functions&	gl						= m_context.getRenderContext().getFunctions();
+	de::Random				rng						(m_seed);
+	deInt32					maxDrawBuffers			= 0;
+	BlendState				preCommonBlendState;
+	BlendState				postCommonBlendState;
+	vector<DrawBufferInfo>	drawBuffers;
+
+	gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_MAX_DRAW_BUFFERS) failed");
+
+	TCU_CHECK(maxDrawBuffers > 0);
+
+	genRandomTest(rng, preCommonBlendState, postCommonBlendState, drawBuffers, maxDrawBuffers);
+
+	runTest(log, results, m_context.getRenderContext(), preCommonBlendState, postCommonBlendState, drawBuffers);
+
+	results.setTestContextResult(m_testCtx);
+
+	return STOP;
+}
+
+enum PrePost
+{
+	PRE,
+	POST
+};
+
+TestCase* createDiffTest (Context& context, PrePost prepost, const char* name, const BlendState& commonState, const BlendState& drawBufferState)
+{
+	const BlendState emptyState = BlendState(tcu::nothing<bool>(), tcu::nothing<Either<BlendEq, SeparateBlendEq> >(), tcu::nothing<Either<BlendFunc, SeparateBlendFunc> >(), tcu::nothing<BVec4>());
+
+	if (prepost == PRE)
+	{
+		const BlendState		preState	= BlendState((commonState.enableBlend ? commonState.enableBlend : just(true)),
+														 commonState.blendEq,
+														 (commonState.blendFunc ? commonState.blendFunc : just(Either<BlendFunc, SeparateBlendFunc>(BlendFunc(GL_ONE, GL_ONE)))),
+														 tcu::nothing<BVec4>());
+		vector<DrawBufferInfo>	drawBuffers;
+
+		drawBuffers.push_back(DrawBufferInfo(true, IVec2(64, 64), emptyState, TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)));
+		drawBuffers.push_back(DrawBufferInfo(true, IVec2(64, 64), drawBufferState, TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)));
+
+		return new DrawBuffersIndexedTest(context, preState, emptyState, drawBuffers, name, name);
+	}
+	else if (prepost == POST)
+	{
+		const BlendState		preState	= BlendState(just(true),
+														 tcu::nothing<Either<BlendEq, SeparateBlendEq> >(),
+														 Maybe<Either<BlendFunc, SeparateBlendFunc> >(BlendFunc(GL_ONE, GL_ONE)),
+														 tcu::nothing<BVec4>());
+		vector<DrawBufferInfo>	drawBuffers;
+
+		drawBuffers.push_back(DrawBufferInfo(true, IVec2(64, 64), emptyState, TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)));
+		drawBuffers.push_back(DrawBufferInfo(true, IVec2(64, 64), drawBufferState, TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)));
+
+		return new DrawBuffersIndexedTest(context, preState, commonState, drawBuffers, name, name);
+	}
+	else
+	{
+		DE_ASSERT(false);
+		return DE_NULL;
+	}
+}
+
+TestCase* createAdvancedEqDiffTest (Context& context, PrePost prepost, const char* name, const BlendState& commonState, const BlendState& drawBufferState)
+{
+	const BlendState emptyState = BlendState(tcu::nothing<bool>(), tcu::nothing<Either<BlendEq, SeparateBlendEq> >(), tcu::nothing<Either<BlendFunc, SeparateBlendFunc> >(), tcu::nothing<BVec4>());
+
+	if (prepost == PRE)
+	{
+		const BlendState		preState	= BlendState((commonState.enableBlend ? commonState.enableBlend : just(true)),
+														 commonState.blendEq,
+														 (commonState.blendFunc ? commonState.blendFunc : just(Either<BlendFunc, SeparateBlendFunc>(BlendFunc(GL_ONE, GL_ONE)))),
+														 tcu::nothing<BVec4>());
+		vector<DrawBufferInfo>	drawBuffers;
+
+		drawBuffers.push_back(DrawBufferInfo(true, IVec2(64, 64), drawBufferState, TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)));
+
+		return new DrawBuffersIndexedTest(context, preState, emptyState, drawBuffers, name, name);
+	}
+	else if (prepost == POST)
+	{
+		const BlendState		preState	= BlendState(just(true),
+														 tcu::nothing<Either<BlendEq, SeparateBlendEq> >(),
+														 Maybe<Either<BlendFunc, SeparateBlendFunc> >(BlendFunc(GL_ONE, GL_ONE)),
+														 tcu::nothing<BVec4>());
+		vector<DrawBufferInfo>	drawBuffers;
+
+		drawBuffers.push_back(DrawBufferInfo(true, IVec2(64, 64), drawBufferState, TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)));
+
+		return new DrawBuffersIndexedTest(context, preState, commonState, drawBuffers, name, name);
+	}
+	else
+	{
+		DE_ASSERT(false);
+		return DE_NULL;
+	}
+}
+
+void addDrawBufferCommonTests (TestCaseGroup* root, PrePost prepost)
+{
+	const BlendState		emptyState	= BlendState(Maybe<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>());
+
+	{
+		const BlendState	disableState	= BlendState(just(false), Maybe<Either<BlendEq, SeparateBlendEq> >(), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>());
+		const BlendState	enableState		= BlendState(just(true), Maybe<Either<BlendEq, SeparateBlendEq> >(), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>());
+
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_enable_buffer_enable",	enableState,	enableState));
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_disable_buffer_disable",	disableState,	disableState));
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_disable_buffer_enable",	disableState,	enableState));
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_enable_buffer_disable",	enableState,	disableState));
+	}
+
+	{
+		const BlendState	eqStateA			= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(GL_FUNC_ADD), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>());
+		const BlendState	eqStateB			= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(GL_FUNC_SUBTRACT), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>());
+
+		const BlendState	separateEqStateA	= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(SeparateBlendEq(GL_FUNC_ADD, GL_FUNC_SUBTRACT)), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>());
+		const BlendState	separateEqStateB	= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(SeparateBlendEq(GL_FUNC_SUBTRACT, GL_FUNC_ADD)), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>());
+
+		const BlendState	advancedEqStateA	= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(GL_DIFFERENCE_KHR), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>());
+		const BlendState	advancedEqStateB	= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(GL_SCREEN_KHR), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>());
+
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_blend_eq_buffer_blend_eq", eqStateA, eqStateB));
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_blend_eq_buffer_separate_blend_eq", eqStateA, separateEqStateB));
+		root->addChild(createAdvancedEqDiffTest(root->getContext(), prepost, "common_blend_eq_buffer_advanced_blend_eq", eqStateA, advancedEqStateB));
+
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_separate_blend_eq_buffer_blend_eq", separateEqStateA, eqStateB));
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_separate_blend_eq_buffer_separate_blend_eq", separateEqStateA, separateEqStateB));
+		root->addChild(createAdvancedEqDiffTest(root->getContext(), prepost, "common_separate_blend_eq_buffer_advanced_blend_eq", separateEqStateA, advancedEqStateB));
+
+		root->addChild(createAdvancedEqDiffTest(root->getContext(), prepost, "common_advanced_blend_eq_buffer_blend_eq", advancedEqStateA, eqStateB));
+		root->addChild(createAdvancedEqDiffTest(root->getContext(), prepost, "common_advanced_blend_eq_buffer_separate_blend_eq", advancedEqStateA, separateEqStateB));
+		root->addChild(createAdvancedEqDiffTest(root->getContext(), prepost, "common_advanced_blend_eq_buffer_advanced_blend_eq", advancedEqStateA, advancedEqStateB));
+	}
+
+	{
+		const BlendState	funcStateA			= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(), Maybe<Either<BlendFunc, SeparateBlendFunc> >(BlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA)), Maybe<BVec4>());
+		const BlendState	funcStateB			= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(), Maybe<Either<BlendFunc, SeparateBlendFunc> >(BlendFunc(GL_DST_ALPHA, GL_SRC_ALPHA)), Maybe<BVec4>());
+		const BlendState	separateFuncStateA	= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(), Maybe<Either<BlendFunc, SeparateBlendFunc> >(SeparateBlendFunc(BlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA), BlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA))), Maybe<BVec4>());
+		const BlendState	separateFuncStateB	= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(), Maybe<Either<BlendFunc, SeparateBlendFunc> >(SeparateBlendFunc(BlendFunc(GL_DST_ALPHA, GL_SRC_ALPHA), BlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA))), Maybe<BVec4>());
+
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_blend_func_buffer_blend_func",					funcStateA,			funcStateB));
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_blend_func_buffer_separate_blend_func",			funcStateA,			separateFuncStateB));
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_separate_blend_func_buffer_blend_func",			separateFuncStateA,	funcStateB));
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_separate_blend_func_buffer_separate_blend_func",	separateFuncStateA,	separateFuncStateB));
+	}
+
+	{
+		const BlendState	commonColorMaskState	= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>(BVec4(true, false, true, false)));
+		const BlendState	bufferColorMaskState	= BlendState(tcu::nothing<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>(BVec4(false, true, false, true)));
+
+		root->addChild(createDiffTest(root->getContext(), prepost, "common_color_mask_buffer_color_mask", commonColorMaskState, bufferColorMaskState));
+	}
+}
+
+void addRandomMaxTest (TestCaseGroup* root)
+{
+	for (int i = 0; i < 20; i++)
+		root->addChild(new MaxDrawBuffersIndexedTest(root->getContext(), i));
+}
+
+void addRandomImplMaxTest (TestCaseGroup* root)
+{
+	for (int i = 0; i < 20; i++)
+		root->addChild(new ImplMaxDrawBuffersIndexedTest(root->getContext(), i));
+}
+
+} // anonymous
+
+TestCaseGroup* createDrawBuffersIndexedTests (Context& context)
+{
+	const BlendState		emptyState		= BlendState(Maybe<bool>(), Maybe<Either<BlendEq, SeparateBlendEq> >(), Maybe<Either<BlendFunc, SeparateBlendFunc> >(), Maybe<BVec4>());
+	TestCaseGroup* const	group			= new TestCaseGroup(context, "draw_buffers_indexed", "Test for indexed draw buffers. GL_EXT_draw_buffers_indexed.");
+
+	TestCaseGroup* const	preGroup		= new TestCaseGroup(context, "overwrite_common", "Set common state and overwrite it with draw buffer blend state.");
+	TestCaseGroup* const	postGroup		= new TestCaseGroup(context, "overwrite_indexed", "Set indexed blend state and overwrite it ith common state.");
+	TestCaseGroup* const	randomGroup		= new TestCaseGroup(context, "random", "Random indexed blend state tests.");
+	TestCaseGroup* const	maxGroup		= new TestCaseGroup(context, "max_required_draw_buffers", "Random tests using minimum maximum number of draw buffers.");
+	TestCaseGroup* const	maxImplGroup	= new TestCaseGroup(context, "max_implementation_draw_buffers", "Random tests using maximum number of draw buffers reported by implementation.");
+
+	group->addChild(preGroup);
+	group->addChild(postGroup);
+	group->addChild(randomGroup);
+
+	randomGroup->addChild(maxGroup);
+	randomGroup->addChild(maxImplGroup);
+
+	addDrawBufferCommonTests(preGroup, PRE);
+	addDrawBufferCommonTests(postGroup, POST);
+	addRandomMaxTest(maxGroup);
+	addRandomImplMaxTest(maxImplGroup);
+
+	return group;
+}
+
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fDrawBuffersIndexedTests.hpp b/modules/gles31/functional/es31fDrawBuffersIndexedTests.hpp
new file mode 100644
index 0000000..5d716f9
--- /dev/null
+++ b/modules/gles31/functional/es31fDrawBuffersIndexedTests.hpp
@@ -0,0 +1,42 @@
+#ifndef _ES31FDRAWBUFFERSINDEXEDTESTS_HPP
+#define _ES31FDRAWBUFFERSINDEXEDTESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Indexed blend operation tests (GL_EXT_draw_buffers_indexed)
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tes31TestCase.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+
+TestCaseGroup* createDrawBuffersIndexedTests (Context& context);
+
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FDRAWBUFFERSINDEXEDTESTS_HPP
diff --git a/modules/gles31/functional/es31fFunctionalTests.cpp b/modules/gles31/functional/es31fFunctionalTests.cpp
index 0a9b0b7..3720cc0 100644
--- a/modules/gles31/functional/es31fFunctionalTests.cpp
+++ b/modules/gles31/functional/es31fFunctionalTests.cpp
@@ -85,6 +85,7 @@
 #include "es31fPrimitiveBoundingBoxTests.hpp"
 #include "es31fAndroidExtensionPackES31ATests.hpp"
 #include "es31fCopyImageTests.hpp"
+#include "es31fDrawBuffersIndexedTests.hpp"
 
 namespace deqp
 {
@@ -328,6 +329,7 @@
 	addChild(new PrimitiveBoundingBoxTests				(m_context));
 	addChild(new AndroidExtensionPackES31ATests			(m_context));
 	addChild(createCopyImageTests						(m_context));
+	addChild(createDrawBuffersIndexedTests				(m_context));
 }
 
 } // Functional
