13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Blend tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fBlendTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsFragmentOpUtil.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuPixelFormat.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTexture.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrFragmentOperations.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "sglrReferenceUtils.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glw.h"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::FragmentOpUtil::Quad;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::FragmentOpUtil::IntegerQuad;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::FragmentOpUtil::QuadRenderer;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::FragmentOpUtil::ReferenceQuadRenderer;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::getBlendEquationName;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::getBlendFactorName;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::UVec4;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TextureLevel;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TextureFormat;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_VIEWPORT_WIDTH		= 64;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_VIEWPORT_HEIGHT	= 64;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic TextureLevel sRGBATextureLevelToLinear (const tcu::ConstPixelBufferAccess& sRGBAAccess)
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sRGBAAccess.getFormat().order == TextureFormat::sRGBA);
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						width			= sRGBAAccess.getWidth();
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						height			= sRGBAAccess.getHeight();
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevel			linear			(TextureFormat(TextureFormat::RGBA, sRGBAAccess.getFormat().type), width, height);
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::PixelBufferAccess	linearAccess	= linear.getAccess();
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < height; y++)
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < width; x++)
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		linearAccess.setPixel(tcu::sRGBToLinear(sRGBAAccess.getPixel(x, y)), x, y);
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return linear;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct BlendParams
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum	equationRGB;
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum	srcFuncRGB;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum	dstFuncRGB;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum	equationAlpha;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum	srcFuncAlpha;
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum	dstFuncAlpha;
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4	blendColor;
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BlendParams (GLenum		equationRGB_,
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 GLenum		srcFuncRGB_,
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 GLenum		dstFuncRGB_,
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 GLenum		equationAlpha_,
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 GLenum		srcFuncAlpha_,
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 GLenum		dstFuncAlpha_,
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				 Vec4		blendColor_)
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: equationRGB	(equationRGB_)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, srcFuncRGB	(srcFuncRGB_)
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, dstFuncRGB	(dstFuncRGB_)
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, equationAlpha	(equationAlpha_)
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, srcFuncAlpha	(srcFuncAlpha_)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, dstFuncAlpha	(dstFuncAlpha_)
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, blendColor	(blendColor_)
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BlendCase : public TestCase
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							BlendCase	(Context&						context,
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 const char*					name,
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 const char*					desc,
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 const vector<BlendParams>&		paramSets,
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 bool							useSrgbFbo);
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~BlendCase	(void);
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					init		(void);
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					deinit		(void);
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult			iterate		(void);
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							BlendCase	(const BlendCase& other);
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BlendCase&				operator=	(const BlendCase& other);
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BlendParams>		m_paramSets;
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_curParamSetNdx;
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					m_useSrgbFbo;
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32				m_colorRbo;
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32				m_fbo;
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	QuadRenderer*			m_renderer;
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceQuadRenderer*	m_referenceRenderer;
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevel*			m_refColorBuffer;
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Quad					m_firstQuad;
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Quad					m_secondQuad;
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IntegerQuad				m_firstQuadInt;
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IntegerQuad				m_secondQuadInt;
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_renderWidth;
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_renderHeight;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_viewportWidth;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_viewportHeight;
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlendCase::BlendCase (Context&						context,
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char*					name,
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char*					desc,
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const vector<BlendParams>&	paramSets,
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  bool							useSrgbFbo)
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, desc)
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_paramSets			(paramSets)
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_curParamSetNdx		(0)
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_useSrgbFbo			(useSrgbFbo)
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_colorRbo			(0)
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fbo					(0)
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderer			(DE_NULL)
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_referenceRenderer	(DE_NULL)
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_refColorBuffer		(DE_NULL)
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderWidth			(m_useSrgbFbo ? 2*MAX_VIEWPORT_WIDTH	: m_context.getRenderTarget().getWidth())
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderHeight		(m_useSrgbFbo ? 2*MAX_VIEWPORT_HEIGHT	: m_context.getRenderTarget().getHeight())
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportWidth		(0)
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportHeight		(0)
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_paramSets.empty());
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlendCase::init (void)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool useRGB = !m_useSrgbFbo && m_context.getRenderTarget().getPixelFormat().alphaBits == 0;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const Vec4 baseGradientColors[4] =
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(0.0f, 0.5f, 1.0f, 0.5f),
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(0.5f, 0.0f, 0.5f, 1.0f),
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(0.5f, 1.0f, 0.5f, 0.0f),
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4(1.0f, 0.5f, 0.0f, 0.5f)
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(m_firstQuad.color) == DE_LENGTH_OF_ARRAY(m_firstQuadInt.color));
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_firstQuad.color); i++)
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_firstQuad.color[i]		= (baseGradientColors[i] - 0.5f) * 0.2f + 0.5f;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_firstQuadInt.color[i]		= m_firstQuad.color[i];
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_secondQuad.color[i]		= (Vec4(1.0f) - baseGradientColors[i] - 0.5f) * 1.0f + 0.5f;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_secondQuadInt.color[i]	= m_secondQuad.color[i];
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportWidth		= de::min<int>(m_renderWidth,	MAX_VIEWPORT_WIDTH);
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportHeight	= de::min<int>(m_renderHeight,	MAX_VIEWPORT_HEIGHT);
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_firstQuadInt.posA		= tcu::IVec2(0,						0);
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_secondQuadInt.posA	= tcu::IVec2(0,						0);
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_firstQuadInt.posB		= tcu::IVec2(m_viewportWidth-1,		m_viewportHeight-1);
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_secondQuadInt.posB	= tcu::IVec2(m_viewportWidth-1,		m_viewportHeight-1);
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_renderer);
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_referenceRenderer);
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_refColorBuffer);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer				= new QuadRenderer(m_context.getRenderContext(), glu::GLSL_VERSION_300_ES);
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_referenceRenderer		= new ReferenceQuadRenderer;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_refColorBuffer		= new TextureLevel(TextureFormat(m_useSrgbFbo ? TextureFormat::sRGBA : useRGB ? TextureFormat::RGB : TextureFormat::RGBA, TextureFormat::UNORM_INT8),
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											   m_viewportWidth, m_viewportHeight);
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_curParamSetNdx = 0;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_useSrgbFbo)
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::Message << "Using FBO of size (" << m_renderWidth << ", " << m_renderHeight << ") with format GL_SRGB8_ALPHA8" << TestLog::EndMessage;
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glGenRenderbuffers(1, &m_colorRbo));
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo));
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8, m_renderWidth, m_renderHeight));
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glGenFramebuffers(1, &m_fbo));
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo));
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRbo));
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlendCase::~BlendCase (void)
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BlendCase::deinit();
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlendCase::deinit (void)
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_renderer;
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_referenceRenderer;
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_refColorBuffer;
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer			= DE_NULL;
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_referenceRenderer	= DE_NULL;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_refColorBuffer	= DE_NULL;
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_colorRbo != 0)
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &m_colorRbo));
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_colorRbo = 0;
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_fbo != 0)
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glDeleteFramebuffers(1, &m_fbo));
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_fbo = 0;
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlendCase::IterateResult BlendCase::iterate (void)
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random						rnd				(deStringHash(getName()) ^ deInt32Hash(m_curParamSetNdx));
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								viewportX		= rnd.getInt(0, m_renderWidth - m_viewportWidth);
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								viewportY		= rnd.getInt(0, m_renderHeight - m_viewportHeight);
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureLevel					renderedImg		(TextureFormat(m_useSrgbFbo ? TextureFormat::sRGBA : TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_viewportWidth, m_viewportHeight);
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&						log				(m_testCtx.getLog());
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const BlendParams&				paramSet		= m_paramSets[m_curParamSetNdx];
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::FragmentOperationState		referenceState;
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Log the blend parameters.
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "RGB equation = " << getBlendEquationName(paramSet.equationRGB) << TestLog::EndMessage;
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "RGB src func = " << getBlendFactorName(paramSet.srcFuncRGB) << TestLog::EndMessage;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "RGB dst func = " << getBlendFactorName(paramSet.dstFuncRGB) << TestLog::EndMessage;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Alpha equation = " << getBlendEquationName(paramSet.equationAlpha) << TestLog::EndMessage;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Alpha src func = " << getBlendFactorName(paramSet.srcFuncAlpha) << TestLog::EndMessage;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Alpha dst func = " << getBlendFactorName(paramSet.dstFuncAlpha) << TestLog::EndMessage;
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Blend color = (" << paramSet.blendColor.x() << ", " << paramSet.blendColor.y() << ", " << paramSet.blendColor.z() << ", " << paramSet.blendColor.w() << ")" << TestLog::EndMessage;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set GL state.
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glBlendEquationSeparate(paramSet.equationRGB, paramSet.equationAlpha));
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glBlendFuncSeparate(paramSet.srcFuncRGB, paramSet.dstFuncRGB, paramSet.srcFuncAlpha, paramSet.dstFuncAlpha));
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glBlendColor(paramSet.blendColor.x(), paramSet.blendColor.y(), paramSet.blendColor.z(), paramSet.blendColor.w()));
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set reference state.
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceState.blendRGBState.equation	= sglr::rr_util::mapGLBlendEquation(paramSet.equationRGB);
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceState.blendRGBState.srcFunc	= sglr::rr_util::mapGLBlendFunc(paramSet.srcFuncRGB);
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceState.blendRGBState.dstFunc	= sglr::rr_util::mapGLBlendFunc(paramSet.dstFuncRGB);
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceState.blendAState.equation		= sglr::rr_util::mapGLBlendEquation(paramSet.equationAlpha);
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceState.blendAState.srcFunc		= sglr::rr_util::mapGLBlendFunc(paramSet.srcFuncAlpha);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceState.blendAState.dstFunc		= sglr::rr_util::mapGLBlendFunc(paramSet.dstFuncAlpha);
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceState.blendColor				= paramSet.blendColor;
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render with GL.
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDisable(GL_BLEND);
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glViewport(viewportX, viewportY, m_viewportWidth, m_viewportHeight);
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer->render(m_firstQuad);
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glEnable(GL_BLEND);
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderer->render(m_secondQuad);
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glFlush();
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render reference.
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::PixelBufferAccess nullAccess(TextureFormat(), 0, 0, 0, DE_NULL);
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceState.blendMode = rr::BLENDMODE_NONE;
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_referenceRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()), nullAccess /* no depth */, nullAccess /* no stencil */, m_firstQuadInt, referenceState);
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceState.blendMode = rr::BLENDMODE_STANDARD;
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_referenceRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()), nullAccess /* no depth */, nullAccess /* no stencil */, m_secondQuadInt, referenceState);
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read GL image.
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess());
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare images.
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note In sRGB cases, convert to linear space for comparison.
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UVec4 compareThreshold = (m_useSrgbFbo ? tcu::PixelFormat(8, 8, 8, 8) : m_context.getRenderTarget().getPixelFormat()).getColorThreshold().toIVec().asUint()
3228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry							 * UVec4(5) / UVec4(2) + UVec4(m_useSrgbFbo ? 5 : 2); // \note Non-scientific ad hoc formula. Need big threshold when few color bits; blending brings extra inaccuracy.
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool comparePass = tcu::intThresholdCompare(m_testCtx.getLog(), "CompareResult", "Image Comparison Result",
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												(m_useSrgbFbo ? sRGBATextureLevelToLinear(*m_refColorBuffer) : *m_refColorBuffer).getAccess(),
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												(m_useSrgbFbo ? sRGBATextureLevelToLinear(renderedImg) : renderedImg).getAccess(),
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												compareThreshold, tcu::COMPARE_LOG_RESULT);
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fail now if images don't match.
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!comparePass)
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Image compare failed");
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Continue if param sets still remain in m_paramSets; otherwise stop.
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_curParamSetNdx++;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_curParamSetNdx < (int)m_paramSets.size())
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CONTINUE;
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlendTests::BlendTests (Context& context)
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "blend", "Blend tests")
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlendTests::~BlendTests (void)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlendTests::init (void)
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct EnumGL
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum			glValue;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		nameStr;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const EnumGL blendEquations[] =
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_FUNC_ADD,					"add"					},
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_FUNC_SUBTRACT,				"subtract"				},
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_FUNC_REVERSE_SUBTRACT,		"reverse_subtract"		},
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_MIN,						"min"					},
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_MAX,						"max"					}
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const EnumGL blendFunctions[] =
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_ZERO,							"zero"						},
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_ONE,							"one"						},
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_SRC_COLOR,						"src_color"					},
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_ONE_MINUS_SRC_COLOR,			"one_minus_src_color"		},
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_DST_COLOR,						"dst_color"					},
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_ONE_MINUS_DST_COLOR,			"one_minus_dst_color"		},
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_SRC_ALPHA,						"src_alpha"					},
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_ONE_MINUS_SRC_ALPHA,			"one_minus_src_alpha"		},
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_DST_ALPHA,						"dst_alpha"					},
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_ONE_MINUS_DST_ALPHA,			"one_minus_dst_alpha"		},
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_CONSTANT_COLOR,				"constant_color"			},
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_ONE_MINUS_CONSTANT_COLOR,		"one_minus_constant_color"	},
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_CONSTANT_ALPHA,				"constant_alpha"			},
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_ONE_MINUS_CONSTANT_ALPHA,		"one_minus_constant_alpha"	},
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ GL_SRC_ALPHA_SATURATE,			"src_alpha_saturate"		}
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4 defaultBlendColor(0.2f, 0.4f, 0.6f, 0.8f);
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int useSrgbFboI = 0; useSrgbFboI <= 1; useSrgbFboI++)
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			useSrgbFbo	= useSrgbFboI != 0;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup*	fbGroup		= new TestCaseGroup(m_context, useSrgbFbo ? "fbo_srgb" : "default_framebuffer", useSrgbFbo ? "Use a FBO with GL_SRGB8_ALPHA8" : "Use the default framebuffer");
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(fbGroup);
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Test all blend equation, src blend function, dst blend function combinations. RGB and alpha modes are the same.
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* group = new TestCaseGroup(m_context, "equation_src_func_dst_func", "Combinations of Blend Equations and Functions");
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fbGroup->addChild(group);
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int equationNdx = 0;	equationNdx < DE_LENGTH_OF_ARRAY(blendEquations);	equationNdx++)
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int srcFuncNdx = 0;	srcFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions);	srcFuncNdx++)
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int dstFuncNdx = 0;	dstFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions);	dstFuncNdx++)
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const EnumGL& eq	= blendEquations[equationNdx];
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const EnumGL& src	= blendFunctions[srcFuncNdx];
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const EnumGL& dst	= blendFunctions[dstFuncNdx];
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if ((eq.glValue == GL_MIN || eq.glValue == GL_MAX) && (srcFuncNdx > 0 || dstFuncNdx > 0)) // MIN and MAX don't depend on factors.
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string name			= eq.nameStr;
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string description	= string("") +
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "Equations "		+ getBlendEquationName(eq.glValue) +
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  ", src funcs "	+ getBlendFactorName(src.glValue) +
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  ", dst funcs "	+ getBlendFactorName(dst.glValue);
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (eq.glValue != GL_MIN && eq.glValue != GL_MAX)
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					name += string("") + "_" + src.nameStr + "_" + dst.nameStr;
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<BlendParams> paramSets;
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				paramSets.push_back(BlendParams(eq.glValue, src.glValue, dst.glValue, eq.glValue, src.glValue, dst.glValue, defaultBlendColor));
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				group->addChild(new BlendCase(m_context, name.c_str(), description.c_str(), paramSets, useSrgbFbo));
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Test all RGB src, alpha src and RGB dst, alpha dst combinations. Equations are ADD.
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note For all RGB src, alpha src combinations, also test a couple of different RGBA dst functions, and vice versa.
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* mainGroup = new TestCaseGroup(m_context, "rgb_func_alpha_func", "Combinations of RGB and Alpha Functions");
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fbGroup->addChild(mainGroup);
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* srcGroup = new TestCaseGroup(m_context, "src", "Source functions");
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* dstGroup = new TestCaseGroup(m_context, "dst", "Destination functions");
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mainGroup->addChild(srcGroup);
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mainGroup->addChild(dstGroup);
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int isDstI = 0;		isDstI <= 1;										isDstI++)
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int rgbFuncNdx = 0;	rgbFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions);	rgbFuncNdx++)
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int alphaFuncNdx = 0;	alphaFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions);	alphaFuncNdx++)
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool			isSrc			= isDstI == 0;
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup*	curGroup		= isSrc ? srcGroup : dstGroup;
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const EnumGL&	funcRGB			= blendFunctions[rgbFuncNdx];
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const EnumGL&	funcAlpha		= blendFunctions[alphaFuncNdx];
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*		dstOrSrcStr		= isSrc ? "src" : "dst";
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string name			= string("") + funcRGB.nameStr + "_" + funcAlpha.nameStr;
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string description	= string("") +
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "RGB "		+ dstOrSrcStr + " func " + getBlendFactorName(funcRGB.glValue) +
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  ", alpha "	+ dstOrSrcStr + " func " + getBlendFactorName(funcAlpha.glValue);
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// First, make param sets as if this was a src case.
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<BlendParams> paramSets;
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_ONE,			GL_FUNC_ADD, funcAlpha.glValue, GL_ONE,			defaultBlendColor));
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_ZERO,			GL_FUNC_ADD, funcAlpha.glValue, GL_ZERO,		defaultBlendColor));
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_SRC_COLOR,		GL_FUNC_ADD, funcAlpha.glValue, GL_SRC_COLOR,	defaultBlendColor));
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_DST_COLOR,		GL_FUNC_ADD, funcAlpha.glValue, GL_DST_COLOR,	defaultBlendColor));
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Swap src and dst params if this is a dst case.
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!isSrc)
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int i = 0; i < (int)paramSets.size(); i++)
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						std::swap(paramSets[i].srcFuncRGB,		paramSets[i].dstFuncRGB);
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						std::swap(paramSets[i].srcFuncAlpha,	paramSets[i].dstFuncAlpha);
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				curGroup->addChild(new BlendCase(m_context, name.c_str(), description.c_str(), paramSets, useSrgbFbo));
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Test all RGB and alpha equation combinations. Src and dst funcs are ONE for both.
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* group = new TestCaseGroup(m_context, "rgb_equation_alpha_equation", "Combinations of RGB and Alpha Equation Combinations");
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fbGroup->addChild(group);
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int equationRGBNdx = 0;	equationRGBNdx < DE_LENGTH_OF_ARRAY(blendEquations);	equationRGBNdx++)
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int equationAlphaNdx = 0;	equationAlphaNdx < DE_LENGTH_OF_ARRAY(blendEquations);	equationAlphaNdx++)
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const EnumGL& eqRGB			= blendEquations[equationRGBNdx];
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const EnumGL& eqAlpha		= blendEquations[equationAlphaNdx];
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string name			= string("") + eqRGB.nameStr + "_" + eqAlpha.nameStr;
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string description	= string("") +
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  "RGB equation "		+ getBlendEquationName(eqRGB.glValue) +
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  ", alpha equation "	+ getBlendEquationName(eqAlpha.glValue);
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<BlendParams> paramSets;
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				paramSets.push_back(BlendParams(eqRGB.glValue, GL_ONE, GL_ONE, eqAlpha.glValue, GL_ONE, GL_ONE, defaultBlendColor));
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				group->addChild(new BlendCase(m_context, name.c_str(), description.c_str(), paramSets, useSrgbFbo));
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
514