/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 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 Blend tests.
 *//*--------------------------------------------------------------------*/

#include "es3fBlendTests.hpp"
#include "gluStrUtil.hpp"
#include "glsFragmentOpUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "tcuPixelFormat.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuTestLog.hpp"
#include "deRandom.hpp"
#include "rrFragmentOperations.hpp"
#include "sglrReferenceUtils.hpp"

#include <string>
#include <vector>

#include "glw.h"

namespace deqp
{

using gls::FragmentOpUtil::Quad;
using gls::FragmentOpUtil::IntegerQuad;
using gls::FragmentOpUtil::QuadRenderer;
using gls::FragmentOpUtil::ReferenceQuadRenderer;
using glu::getBlendEquationName;
using glu::getBlendFactorName;
using tcu::Vec4;
using tcu::UVec4;
using tcu::TestLog;
using tcu::TextureLevel;
using tcu::TextureFormat;
using std::string;
using std::vector;

namespace gles3
{
namespace Functional
{

static const int MAX_VIEWPORT_WIDTH		= 64;
static const int MAX_VIEWPORT_HEIGHT	= 64;

// \note src and dst can point to same memory as long as there is 1-to-1 correspondence between
//		 pixels.
static void sRGBAToLinear (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src)
{
	const int	width	= src.getWidth();
	const int	height	= src.getHeight();

	for (int y = 0; y < height; y++)
	for (int x = 0; x < width; x++)
		dst.setPixel(tcu::sRGBToLinear(src.getPixel(x, y)), x, y);
}

struct BlendParams
{
	GLenum	equationRGB;
	GLenum	srcFuncRGB;
	GLenum	dstFuncRGB;
	GLenum	equationAlpha;
	GLenum	srcFuncAlpha;
	GLenum	dstFuncAlpha;
	Vec4	blendColor;

	BlendParams (GLenum		equationRGB_,
				 GLenum		srcFuncRGB_,
				 GLenum		dstFuncRGB_,
				 GLenum		equationAlpha_,
				 GLenum		srcFuncAlpha_,
				 GLenum		dstFuncAlpha_,
				 Vec4		blendColor_)
	: equationRGB	(equationRGB_)
	, srcFuncRGB	(srcFuncRGB_)
	, dstFuncRGB	(dstFuncRGB_)
	, equationAlpha	(equationAlpha_)
	, srcFuncAlpha	(srcFuncAlpha_)
	, dstFuncAlpha	(dstFuncAlpha_)
	, blendColor	(blendColor_)
	{
	}
};

class BlendCase : public TestCase
{
public:
							BlendCase	(Context&						context,
										 const char*					name,
										 const char*					desc,
										 const vector<BlendParams>&		paramSets,
										 bool							useSrgbFbo);

							~BlendCase	(void);

	void					init		(void);
	void					deinit		(void);

	IterateResult			iterate		(void);

private:
							BlendCase	(const BlendCase& other);
	BlendCase&				operator=	(const BlendCase& other);

	vector<BlendParams>		m_paramSets;
	int						m_curParamSetNdx;

	bool					m_useSrgbFbo;
	deUint32				m_colorRbo;
	deUint32				m_fbo;

	QuadRenderer*			m_renderer;
	ReferenceQuadRenderer*	m_referenceRenderer;
	TextureLevel*			m_refColorBuffer;
	Quad					m_firstQuad;
	Quad					m_secondQuad;
	IntegerQuad				m_firstQuadInt;
	IntegerQuad				m_secondQuadInt;

	int						m_renderWidth;
	int						m_renderHeight;
	int						m_viewportWidth;
	int						m_viewportHeight;
};

BlendCase::BlendCase (Context&						context,
					  const char*					name,
					  const char*					desc,
					  const vector<BlendParams>&	paramSets,
					  bool							useSrgbFbo)
	: TestCase				(context, name, desc)
	, m_paramSets			(paramSets)
	, m_curParamSetNdx		(0)
	, m_useSrgbFbo			(useSrgbFbo)
	, m_colorRbo			(0)
	, m_fbo					(0)
	, m_renderer			(DE_NULL)
	, m_referenceRenderer	(DE_NULL)
	, m_refColorBuffer		(DE_NULL)
	, m_renderWidth			(m_useSrgbFbo ? 2*MAX_VIEWPORT_WIDTH	: m_context.getRenderTarget().getWidth())
	, m_renderHeight		(m_useSrgbFbo ? 2*MAX_VIEWPORT_HEIGHT	: m_context.getRenderTarget().getHeight())
	, m_viewportWidth		(0)
	, m_viewportHeight		(0)
{
	DE_ASSERT(!m_paramSets.empty());
}

void BlendCase::init (void)
{
	bool useRGB = !m_useSrgbFbo && m_context.getRenderTarget().getPixelFormat().alphaBits == 0;

	static const Vec4 baseGradientColors[4] =
	{
		Vec4(0.0f, 0.5f, 1.0f, 0.5f),
		Vec4(0.5f, 0.0f, 0.5f, 1.0f),
		Vec4(0.5f, 1.0f, 0.5f, 0.0f),
		Vec4(1.0f, 0.5f, 0.0f, 0.5f)
	};

	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(m_firstQuad.color) == DE_LENGTH_OF_ARRAY(m_firstQuadInt.color));
	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_firstQuad.color); i++)
	{
		m_firstQuad.color[i]		= (baseGradientColors[i] - 0.5f) * 0.2f + 0.5f;
		m_firstQuadInt.color[i]		= m_firstQuad.color[i];

		m_secondQuad.color[i]		= (Vec4(1.0f) - baseGradientColors[i] - 0.5f) * 1.0f + 0.5f;
		m_secondQuadInt.color[i]	= m_secondQuad.color[i];
	}

	m_viewportWidth		= de::min<int>(m_renderWidth,	MAX_VIEWPORT_WIDTH);
	m_viewportHeight	= de::min<int>(m_renderHeight,	MAX_VIEWPORT_HEIGHT);

	m_firstQuadInt.posA		= tcu::IVec2(0,						0);
	m_secondQuadInt.posA	= tcu::IVec2(0,						0);
	m_firstQuadInt.posB		= tcu::IVec2(m_viewportWidth-1,		m_viewportHeight-1);
	m_secondQuadInt.posB	= tcu::IVec2(m_viewportWidth-1,		m_viewportHeight-1);

	DE_ASSERT(!m_renderer);
	DE_ASSERT(!m_referenceRenderer);
	DE_ASSERT(!m_refColorBuffer);

	m_renderer				= new QuadRenderer(m_context.getRenderContext(), glu::GLSL_VERSION_300_ES);
	m_referenceRenderer		= new ReferenceQuadRenderer;
	m_refColorBuffer		= new TextureLevel(TextureFormat(m_useSrgbFbo ? TextureFormat::sRGBA : useRGB ? TextureFormat::RGB : TextureFormat::RGBA, TextureFormat::UNORM_INT8),
											   m_viewportWidth, m_viewportHeight);

	m_curParamSetNdx = 0;

	if (m_useSrgbFbo)
	{
		m_testCtx.getLog() << TestLog::Message << "Using FBO of size (" << m_renderWidth << ", " << m_renderHeight << ") with format GL_SRGB8_ALPHA8" << TestLog::EndMessage;

		GLU_CHECK_CALL(glGenRenderbuffers(1, &m_colorRbo));
		GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo));
		GLU_CHECK_CALL(glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8, m_renderWidth, m_renderHeight));

		GLU_CHECK_CALL(glGenFramebuffers(1, &m_fbo));
		GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo));
		GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRbo));
	}
}

BlendCase::~BlendCase (void)
{
	BlendCase::deinit();
}

void BlendCase::deinit (void)
{
	delete m_renderer;
	delete m_referenceRenderer;
	delete m_refColorBuffer;

	m_renderer			= DE_NULL;
	m_referenceRenderer	= DE_NULL;
	m_refColorBuffer	= DE_NULL;

	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));

	if (m_colorRbo != 0)
	{
		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &m_colorRbo));
		m_colorRbo = 0;
	}
	if (m_fbo != 0)
	{
		GLU_CHECK_CALL(glDeleteFramebuffers(1, &m_fbo));
		m_fbo = 0;
	}
}

BlendCase::IterateResult BlendCase::iterate (void)
{
	de::Random						rnd				(deStringHash(getName()) ^ deInt32Hash(m_curParamSetNdx));
	int								viewportX		= rnd.getInt(0, m_renderWidth - m_viewportWidth);
	int								viewportY		= rnd.getInt(0, m_renderHeight - m_viewportHeight);
	TextureLevel					renderedImg		(TextureFormat(m_useSrgbFbo ? TextureFormat::sRGBA : TextureFormat::RGBA, TextureFormat::UNORM_INT8), m_viewportWidth, m_viewportHeight);
	TextureLevel					referenceImg	(renderedImg.getFormat(), m_viewportWidth, m_viewportHeight);
	TestLog&						log				(m_testCtx.getLog());
	const BlendParams&				paramSet		= m_paramSets[m_curParamSetNdx];
	rr::FragmentOperationState		referenceState;

	// Log the blend parameters.

	log << TestLog::Message << "RGB equation = " << getBlendEquationName(paramSet.equationRGB) << TestLog::EndMessage;
	log << TestLog::Message << "RGB src func = " << getBlendFactorName(paramSet.srcFuncRGB) << TestLog::EndMessage;
	log << TestLog::Message << "RGB dst func = " << getBlendFactorName(paramSet.dstFuncRGB) << TestLog::EndMessage;
	log << TestLog::Message << "Alpha equation = " << getBlendEquationName(paramSet.equationAlpha) << TestLog::EndMessage;
	log << TestLog::Message << "Alpha src func = " << getBlendFactorName(paramSet.srcFuncAlpha) << TestLog::EndMessage;
	log << TestLog::Message << "Alpha dst func = " << getBlendFactorName(paramSet.dstFuncAlpha) << TestLog::EndMessage;
	log << TestLog::Message << "Blend color = (" << paramSet.blendColor.x() << ", " << paramSet.blendColor.y() << ", " << paramSet.blendColor.z() << ", " << paramSet.blendColor.w() << ")" << TestLog::EndMessage;

	// Set GL state.

	GLU_CHECK_CALL(glBlendEquationSeparate(paramSet.equationRGB, paramSet.equationAlpha));
	GLU_CHECK_CALL(glBlendFuncSeparate(paramSet.srcFuncRGB, paramSet.dstFuncRGB, paramSet.srcFuncAlpha, paramSet.dstFuncAlpha));
	GLU_CHECK_CALL(glBlendColor(paramSet.blendColor.x(), paramSet.blendColor.y(), paramSet.blendColor.z(), paramSet.blendColor.w()));

	// Set reference state.

	referenceState.blendRGBState.equation	= sglr::rr_util::mapGLBlendEquation(paramSet.equationRGB);
	referenceState.blendRGBState.srcFunc	= sglr::rr_util::mapGLBlendFunc(paramSet.srcFuncRGB);
	referenceState.blendRGBState.dstFunc	= sglr::rr_util::mapGLBlendFunc(paramSet.dstFuncRGB);
	referenceState.blendAState.equation		= sglr::rr_util::mapGLBlendEquation(paramSet.equationAlpha);
	referenceState.blendAState.srcFunc		= sglr::rr_util::mapGLBlendFunc(paramSet.srcFuncAlpha);
	referenceState.blendAState.dstFunc		= sglr::rr_util::mapGLBlendFunc(paramSet.dstFuncAlpha);
	referenceState.blendColor				= paramSet.blendColor;

	// Render with GL.

	glDisable(GL_BLEND);
	glViewport(viewportX, viewportY, m_viewportWidth, m_viewportHeight);
	m_renderer->render(m_firstQuad);
	glEnable(GL_BLEND);
	m_renderer->render(m_secondQuad);
	glFlush();

	// Render reference.

	const tcu::PixelBufferAccess nullAccess = tcu::PixelBufferAccess();

	referenceState.blendMode = rr::BLENDMODE_NONE;
	m_referenceRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()), nullAccess /* no depth */, nullAccess /* no stencil */, m_firstQuadInt, referenceState);
	referenceState.blendMode = rr::BLENDMODE_STANDARD;
	m_referenceRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()), nullAccess /* no depth */, nullAccess /* no stencil */, m_secondQuadInt, referenceState);

	// Copy to reference (expansion to RGBA happens here if necessary)
	copy(referenceImg, m_refColorBuffer->getAccess());

	// Read GL image.

	glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess());

	// Compare images.
	// \note In sRGB cases, convert to linear space for comparison.

	if (m_useSrgbFbo)
	{
		sRGBAToLinear(renderedImg, renderedImg);
		sRGBAToLinear(referenceImg, referenceImg);
	}

	UVec4 compareThreshold = (m_useSrgbFbo ? tcu::PixelFormat(8, 8, 8, 8) : m_context.getRenderTarget().getPixelFormat()).getColorThreshold().toIVec().asUint()
							 * UVec4(5) / UVec4(2) + UVec4(m_useSrgbFbo ? 5 : 3); // \note Non-scientific ad hoc formula. Need big threshold when few color bits; blending brings extra inaccuracy.

	bool comparePass = tcu::intThresholdCompare(m_testCtx.getLog(), "CompareResult", "Image Comparison Result",
												referenceImg.getAccess(), renderedImg.getAccess(),
												compareThreshold, tcu::COMPARE_LOG_RESULT);

	// Fail now if images don't match.

	if (!comparePass)
	{
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Image compare failed");
		return STOP;
	}

	// Continue if param sets still remain in m_paramSets; otherwise stop.

	m_curParamSetNdx++;

	if (m_curParamSetNdx < (int)m_paramSets.size())
		return CONTINUE;
	else
	{
		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
		return STOP;
	}
}

BlendTests::BlendTests (Context& context)
	: TestCaseGroup(context, "blend", "Blend tests")
{
}

BlendTests::~BlendTests (void)
{
}

void BlendTests::init (void)
{
	struct EnumGL
	{
		GLenum			glValue;
		const char*		nameStr;
	};

	static const EnumGL blendEquations[] =
	{
		{ GL_FUNC_ADD,					"add"					},
		{ GL_FUNC_SUBTRACT,				"subtract"				},
		{ GL_FUNC_REVERSE_SUBTRACT,		"reverse_subtract"		},
		{ GL_MIN,						"min"					},
		{ GL_MAX,						"max"					}
	};

	static const EnumGL blendFunctions[] =
	{
		{ GL_ZERO,							"zero"						},
		{ GL_ONE,							"one"						},
		{ GL_SRC_COLOR,						"src_color"					},
		{ GL_ONE_MINUS_SRC_COLOR,			"one_minus_src_color"		},
		{ GL_DST_COLOR,						"dst_color"					},
		{ GL_ONE_MINUS_DST_COLOR,			"one_minus_dst_color"		},
		{ GL_SRC_ALPHA,						"src_alpha"					},
		{ GL_ONE_MINUS_SRC_ALPHA,			"one_minus_src_alpha"		},
		{ GL_DST_ALPHA,						"dst_alpha"					},
		{ GL_ONE_MINUS_DST_ALPHA,			"one_minus_dst_alpha"		},
		{ GL_CONSTANT_COLOR,				"constant_color"			},
		{ GL_ONE_MINUS_CONSTANT_COLOR,		"one_minus_constant_color"	},
		{ GL_CONSTANT_ALPHA,				"constant_alpha"			},
		{ GL_ONE_MINUS_CONSTANT_ALPHA,		"one_minus_constant_alpha"	},
		{ GL_SRC_ALPHA_SATURATE,			"src_alpha_saturate"		}
	};

	const Vec4 defaultBlendColor(0.2f, 0.4f, 0.6f, 0.8f);

	for (int useSrgbFboI = 0; useSrgbFboI <= 1; useSrgbFboI++)
	{
		bool			useSrgbFbo	= useSrgbFboI != 0;
		TestCaseGroup*	fbGroup		= new TestCaseGroup(m_context, useSrgbFbo ? "fbo_srgb" : "default_framebuffer", useSrgbFbo ? "Use a FBO with GL_SRGB8_ALPHA8" : "Use the default framebuffer");
		addChild(fbGroup);

		// Test all blend equation, src blend function, dst blend function combinations. RGB and alpha modes are the same.

		{
			TestCaseGroup* group = new TestCaseGroup(m_context, "equation_src_func_dst_func", "Combinations of Blend Equations and Functions");
			fbGroup->addChild(group);

			for (int equationNdx = 0;	equationNdx < DE_LENGTH_OF_ARRAY(blendEquations);	equationNdx++)
			for (int srcFuncNdx = 0;	srcFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions);	srcFuncNdx++)
			for (int dstFuncNdx = 0;	dstFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions);	dstFuncNdx++)
			{
				const EnumGL& eq	= blendEquations[equationNdx];
				const EnumGL& src	= blendFunctions[srcFuncNdx];
				const EnumGL& dst	= blendFunctions[dstFuncNdx];

				if ((eq.glValue == GL_MIN || eq.glValue == GL_MAX) && (srcFuncNdx > 0 || dstFuncNdx > 0)) // MIN and MAX don't depend on factors.
					continue;

				string name			= eq.nameStr;
				string description	= string("") +
									  "Equations "		+ getBlendEquationName(eq.glValue) +
									  ", src funcs "	+ getBlendFactorName(src.glValue) +
									  ", dst funcs "	+ getBlendFactorName(dst.glValue);

				if (eq.glValue != GL_MIN && eq.glValue != GL_MAX)
					name += string("") + "_" + src.nameStr + "_" + dst.nameStr;

				vector<BlendParams> paramSets;
				paramSets.push_back(BlendParams(eq.glValue, src.glValue, dst.glValue, eq.glValue, src.glValue, dst.glValue, defaultBlendColor));

				group->addChild(new BlendCase(m_context, name.c_str(), description.c_str(), paramSets, useSrgbFbo));
			}
		}

		// Test all RGB src, alpha src and RGB dst, alpha dst combinations. Equations are ADD.
		// \note For all RGB src, alpha src combinations, also test a couple of different RGBA dst functions, and vice versa.

		{
			TestCaseGroup* mainGroup = new TestCaseGroup(m_context, "rgb_func_alpha_func", "Combinations of RGB and Alpha Functions");
			fbGroup->addChild(mainGroup);
			TestCaseGroup* srcGroup = new TestCaseGroup(m_context, "src", "Source functions");
			TestCaseGroup* dstGroup = new TestCaseGroup(m_context, "dst", "Destination functions");
			mainGroup->addChild(srcGroup);
			mainGroup->addChild(dstGroup);

			for (int isDstI = 0;		isDstI <= 1;										isDstI++)
			for (int rgbFuncNdx = 0;	rgbFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions);	rgbFuncNdx++)
			for (int alphaFuncNdx = 0;	alphaFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions);	alphaFuncNdx++)
			{
				bool			isSrc			= isDstI == 0;
				TestCaseGroup*	curGroup		= isSrc ? srcGroup : dstGroup;
				const EnumGL&	funcRGB			= blendFunctions[rgbFuncNdx];
				const EnumGL&	funcAlpha		= blendFunctions[alphaFuncNdx];
				const char*		dstOrSrcStr		= isSrc ? "src" : "dst";

				string name			= string("") + funcRGB.nameStr + "_" + funcAlpha.nameStr;
				string description	= string("") +
									  "RGB "		+ dstOrSrcStr + " func " + getBlendFactorName(funcRGB.glValue) +
									  ", alpha "	+ dstOrSrcStr + " func " + getBlendFactorName(funcAlpha.glValue);

				// First, make param sets as if this was a src case.

				vector<BlendParams> paramSets;
				paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_ONE,			GL_FUNC_ADD, funcAlpha.glValue, GL_ONE,			defaultBlendColor));
				paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_ZERO,			GL_FUNC_ADD, funcAlpha.glValue, GL_ZERO,		defaultBlendColor));
				paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_SRC_COLOR,		GL_FUNC_ADD, funcAlpha.glValue, GL_SRC_COLOR,	defaultBlendColor));
				paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_DST_COLOR,		GL_FUNC_ADD, funcAlpha.glValue, GL_DST_COLOR,	defaultBlendColor));

				// Swap src and dst params if this is a dst case.

				if (!isSrc)
				{
					for (int i = 0; i < (int)paramSets.size(); i++)
					{
						std::swap(paramSets[i].srcFuncRGB,		paramSets[i].dstFuncRGB);
						std::swap(paramSets[i].srcFuncAlpha,	paramSets[i].dstFuncAlpha);
					}
				}

				curGroup->addChild(new BlendCase(m_context, name.c_str(), description.c_str(), paramSets, useSrgbFbo));
			}
		}

		// Test all RGB and alpha equation combinations. Src and dst funcs are ONE for both.

		{
			TestCaseGroup* group = new TestCaseGroup(m_context, "rgb_equation_alpha_equation", "Combinations of RGB and Alpha Equation Combinations");
			fbGroup->addChild(group);

			for (int equationRGBNdx = 0;	equationRGBNdx < DE_LENGTH_OF_ARRAY(blendEquations);	equationRGBNdx++)
			for (int equationAlphaNdx = 0;	equationAlphaNdx < DE_LENGTH_OF_ARRAY(blendEquations);	equationAlphaNdx++)
			{
				const EnumGL& eqRGB			= blendEquations[equationRGBNdx];
				const EnumGL& eqAlpha		= blendEquations[equationAlphaNdx];

				string name			= string("") + eqRGB.nameStr + "_" + eqAlpha.nameStr;
				string description	= string("") +
									  "RGB equation "		+ getBlendEquationName(eqRGB.glValue) +
									  ", alpha equation "	+ getBlendEquationName(eqAlpha.glValue);

				vector<BlendParams> paramSets;
				paramSets.push_back(BlendParams(eqRGB.glValue, GL_ONE, GL_ONE, eqAlpha.glValue, GL_ONE, GL_ONE, defaultBlendColor));

				group->addChild(new BlendCase(m_context, name.c_str(), description.c_str(), paramSets, useSrgbFbo));
			}
		}
	}
}

} // Functional
} // gles3
} // deqp
