es3fShaderDerivateTests.cpp revision 3c827367444ee418f129b2c238299f49d3264554
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 Shader derivate function tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo [2013-06-25 pyry] Missing features:
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *  - lines and points
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *  - projected coordinates
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *  - continous non-trivial functions (sin, exp)
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *  - non-continous functions (step)
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fShaderDerivateTests.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDrawUtil.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderUtil.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTexture.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuStringTemplate.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRGBA.hpp"
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFloat.hpp"
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deUniquePtr.hpp"
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderRenderCase.hpp" // gls::setupDefaultUniforms()
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream>
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::ostringstream;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VIEWPORT_WIDTH		= 167,
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VIEWPORT_HEIGHT		= 103,
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FBO_WIDTH			= 99,
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FBO_HEIGHT			= 133,
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAX_FAILED_MESSAGES	= 10
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum DerivateFunc
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DERIVATE_DFDX	= 0,
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DERIVATE_DFDY,
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DERIVATE_FWIDTH,
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DERIVATE_LAST
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum SurfaceType
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SURFACETYPE_DEFAULT_FRAMEBUFFER = 0,
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SURFACETYPE_UNORM_FBO,
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SURFACETYPE_FLOAT_FBO,	// \note Uses RGBA32UI fbo actually, since FP rendertargets are not in core spec.
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SURFACETYPE_LAST
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Utilities
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AutoFbo
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	AutoFbo (const glw::Functions& gl)
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_gl	(gl)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_fbo	(0)
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	~AutoFbo (void)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_fbo)
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_gl.deleteFramebuffers(1, &m_fbo);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void gen (void)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!m_fbo);
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gl.genFramebuffers(1, &m_fbo);
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 operator* (void) const { return m_fbo; }
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	m_gl;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32				m_fbo;
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AutoRbo
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	AutoRbo (const glw::Functions& gl)
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_gl	(gl)
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_rbo	(0)
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	~AutoRbo (void)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_rbo)
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_gl.deleteRenderbuffers(1, &m_rbo);
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void gen (void)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!m_rbo);
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_gl.genRenderbuffers(1, &m_rbo);
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 operator* (void) const { return m_rbo; }
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	m_gl;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32				m_rbo;
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getDerivateFuncName (DerivateFunc func)
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (func)
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case DERIVATE_DFDX:		return "dFdx";
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case DERIVATE_DFDY:		return "dFdy";
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case DERIVATE_FWIDTH:	return "fwidth";
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getDerivateFuncCaseName (DerivateFunc func)
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (func)
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case DERIVATE_DFDX:		return "dfdx";
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case DERIVATE_DFDY:		return "dfdy";
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case DERIVATE_FWIDTH:	return "fwidth";
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::BVec4 getDerivateMask (glu::DataType type)
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT:		return tcu::BVec4(true, false, false, false);
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT_VEC2:	return tcu::BVec4(true, true, false, false);
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT_VEC3:	return tcu::BVec4(true, true, true, false);
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT_VEC4:	return tcu::BVec4(true, true, true, true);
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return tcu::BVec4(true);
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::Vec4 readDerivate (const tcu::ConstPixelBufferAccess& surface, const tcu::Vec4& derivScale, const tcu::Vec4& derivBias, int x, int y)
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (surface.getPixel(x, y) - derivBias) / derivScale;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::UVec4 getCompExpBits (const tcu::Vec4& v)
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::UVec4(tcu::Float32(v[0]).exponentBits(),
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  tcu::Float32(v[1]).exponentBits(),
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  tcu::Float32(v[2]).exponentBits(),
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  tcu::Float32(v[3]).exponentBits());
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat computeFloatingPointError (const float value, const int numAccurateBits)
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		numGarbageBits	= 23-numAccurateBits;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	mask			= (1u<<numGarbageBits)-1u;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		exp				= tcu::Float32(value).exponent();
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::Float32::construct(+1, exp, (1u<<23) | mask).asFloat() - tcu::Float32::construct(+1, exp, 1u<<23).asFloat();
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::Vec4 getDerivateThreshold (const glu::Precision precision, const tcu::Vec4& valueMin, const tcu::Vec4& valueMax, const tcu::Vec4& expectedDerivate)
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			baseBits		= precision == glu::PRECISION_HIGHP		? 23	:
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  precision == glu::PRECISION_MEDIUMP	? 10	:
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  precision == glu::PRECISION_LOWP		? 6		: 0;
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::UVec4	derivExp		= getCompExpBits(expectedDerivate);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::UVec4	maxValueExp		= max(getCompExpBits(valueMin), getCompExpBits(valueMax));
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::UVec4	numBitsLost		= maxValueExp - min(maxValueExp, derivExp);
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec4	numAccurateBits	= max(baseBits - numBitsLost.asInt() - 3, tcu::IVec4(0));
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::Vec4(computeFloatingPointError(expectedDerivate[0], numAccurateBits[0]),
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 computeFloatingPointError(expectedDerivate[1], numAccurateBits[1]),
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 computeFloatingPointError(expectedDerivate[2], numAccurateBits[2]),
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 computeFloatingPointError(expectedDerivate[3], numAccurateBits[3]));
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct LogVecComps
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4&	v;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					numComps;
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LogVecComps (const tcu::Vec4& v_, int numComps_)
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: v			(v_)
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, numComps	(numComps_)
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const LogVecComps& v)
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inRange(v.numComps, 1, 4));
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (v.numComps == 1)		return str << v.v[0];
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (v.numComps == 2)	return str << v.v.toWidth<2>();
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (v.numComps == 3)	return str << v.v.toWidth<3>();
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else						return str << v.v;
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool verifyConstantDerivate (tcu::TestLog&						log,
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const tcu::ConstPixelBufferAccess&	result,
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const tcu::PixelBufferAccess&		errorMask,
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									glu::DataType						dataType,
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const tcu::Vec4&					reference,
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const tcu::Vec4&					threshold,
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const tcu::Vec4&					scale,
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const tcu::Vec4&					bias)
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			numComps		= glu::getDataTypeFloatScalars(dataType);
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::BVec4	mask			= tcu::logicalNot(getDerivateMask(dataType));
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					numFailedPixels	= 0;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Expecting " << LogVecComps(reference, numComps) << " with threshold " << LogVecComps(threshold, numComps) << TestLog::EndMessage;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < result.getHeight(); y++)
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < result.getWidth(); x++)
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::Vec4		resDerivate		= readDerivate(result, scale, bias, x, y);
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool			isOk			= tcu::allEqual(tcu::logicalOr(tcu::lessThanEqual(tcu::abs(reference - resDerivate), threshold), mask), tcu::BVec4(true));
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isOk)
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (numFailedPixels < MAX_FAILED_MESSAGES)
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "FAIL: got " << LogVecComps(resDerivate, numComps)
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											<< ", diff = " << LogVecComps(tcu::abs(reference - resDerivate), numComps)
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											<< ", at x = " << x << ", y = " << y
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::EndMessage;
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numFailedPixels += 1;
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				errorMask.setPixel(tcu::RGBA::red.toVec(), x, y);
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numFailedPixels >= MAX_FAILED_MESSAGES)
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "..." << TestLog::EndMessage;
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numFailedPixels > 0)
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "FAIL: found " << numFailedPixels << " failed pixels" << TestLog::EndMessage;
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return numFailedPixels == 0;
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TriangleDerivateCase
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TriangleDerivateCase : public TestCase
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						TriangleDerivateCase	(Context& context, const char* name, const char* description);
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~TriangleDerivateCase	(void);
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate					(void);
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void		setupRenderState		(deUint32 program) { DE_UNREF(program); }
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual bool		verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask) = DE_NULL;
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::IVec2			getViewportSize			(void) const;
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4			getSurfaceThreshold		(void) const;
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::DataType		m_dataType;
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Precision		m_precision;
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::DataType		m_coordDataType;
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Precision		m_coordPrecision;
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			m_fragmentSrc;
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4			m_coordMin;
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4			m_coordMax;
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4			m_derivScale;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4			m_derivBias;
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SurfaceType			m_surfaceType;
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_numSamples;
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32			m_hint;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTriangleDerivateCase::TriangleDerivateCase (Context& context, const char* name, const char* description)
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase			(context, name, description)
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_dataType		(glu::TYPE_LAST)
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_precision		(glu::PRECISION_LAST)
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_coordDataType	(glu::TYPE_LAST)
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_coordPrecision	(glu::PRECISION_LAST)
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_surfaceType		(SURFACETYPE_DEFAULT_FRAMEBUFFER)
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numSamples		(0)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_hint			(GL_DONT_CARE)
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_surfaceType != SURFACETYPE_DEFAULT_FRAMEBUFFER || m_numSamples == 0);
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTriangleDerivateCase::~TriangleDerivateCase (void)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TriangleDerivateCase::deinit();
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic std::string genVertexSource (glu::DataType coordType, glu::Precision precision)
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeFloatOrVec(coordType));
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* vertexTmpl =
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec4 a_position;\n"
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in ${PRECISION} ${DATATYPE} a_coord;\n"
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"out ${PRECISION} ${DATATYPE} v_coord;\n"
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main (void)\n"
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = a_position;\n"
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_coord = a_coord;\n"
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> vertexParams;
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertexParams["PRECISION"]	= glu::getPrecisionName(precision);
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertexParams["DATATYPE"]	= glu::getDataTypeName(coordType);
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::StringTemplate(vertexTmpl).specialize(vertexParams);
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::IVec2 TriangleDerivateCase::getViewportSize (void) const
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_surfaceType == SURFACETYPE_DEFAULT_FRAMEBUFFER)
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	width	= de::min<int>(m_context.getRenderTarget().getWidth(),	VIEWPORT_WIDTH);
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	height	= de::min<int>(m_context.getRenderTarget().getHeight(),	VIEWPORT_HEIGHT);
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return tcu::IVec2(width, height);
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return tcu::IVec2(FBO_WIDTH, FBO_HEIGHT);
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTriangleDerivateCase::IterateResult TriangleDerivateCase::iterate (void)
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderProgram	program			(m_context.getRenderContext(), glu::makeVtxFragSources(genVertexSource(m_coordDataType, m_coordPrecision), m_fragmentSrc));
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random					rnd				(deStringHash(getName()) ^ 0xbbc24);
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool					useFbo			= m_surfaceType != SURFACETYPE_DEFAULT_FRAMEBUFFER;
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				fboFormat		= m_surfaceType == SURFACETYPE_FLOAT_FBO ? GL_RGBA32UI : GL_RGBA8;
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec2			viewportSize	= getViewportSize();
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportX		= useFbo ? 0 : rnd.getInt(0, m_context.getRenderTarget().getWidth()		- viewportSize.x());
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportY		= useFbo ? 0 : rnd.getInt(0, m_context.getRenderTarget().getHeight()	- viewportSize.y());
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	AutoFbo						fbo				(gl);
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	AutoRbo						rbo				(gl);
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureLevel			result;
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << program;
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!program.isOk())
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_FAIL("Compile failed");
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (useFbo)
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::Message
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   << "Rendering to FBO, format = " << glu::getPixelFormatStr(fboFormat)
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   << ", samples = " << m_numSamples
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   << TestLog::EndMessage;
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fbo.gen();
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rbo.gen();
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindRenderbuffer(GL_RENDERBUFFER, *rbo);
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_numSamples, fboFormat, viewportSize.x(), viewportSize.y());
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *rbo);
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::Message << "Rendering to default framebuffer" << TestLog::EndMessage;
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "in: " << m_coordMin << " -> " << m_coordMax << "\n"
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   << "v_coord.x = in.x * x\n"
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   << "v_coord.y = in.y * y\n"
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   << "v_coord.z = in.z * (x+y)/2\n"
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   << "v_coord.w = in.w * (1 - (x+y)/2)\n"
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << TestLog::EndMessage
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << TestLog::Message << "u_scale: " << m_derivScale << ", u_bias: " << m_derivBias << " (displayed values have scale/bias removed)" << TestLog::EndMessage
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << TestLog::Message << "Viewport: " << viewportSize.x() << "x" << viewportSize.y() << TestLog::EndMessage
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << TestLog::Message << "GL_FRAGMENT_SHADER_DERIVATE_HINT: " << glu::getHintModeStr(m_hint) << TestLog::EndMessage;
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float positions[] =
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			-1.0f, -1.0f, 0.0f, 1.0f,
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			-1.0f,  1.0f, 0.0f, 1.0f,
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 1.0f, -1.0f, 0.0f, 1.0f,
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 1.0f,  1.0f, 0.0f, 1.0f
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float coords[] =
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordMin.x(), m_coordMin.y(), m_coordMin.z(),							m_coordMax.w(),
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordMin.x(), m_coordMax.y(), (m_coordMin.z()+m_coordMax.z())*0.5f,	(m_coordMin.w()+m_coordMax.w())*0.5f,
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordMax.x(), m_coordMin.y(), (m_coordMin.z()+m_coordMax.z())*0.5f,	(m_coordMin.w()+m_coordMax.w())*0.5f,
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordMax.x(), m_coordMax.y(), m_coordMax.z(),							m_coordMin.w()
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::VertexArrayBinding vertexArrays[] =
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::va::Float("a_position",	4, 4, 0, &positions[0]),
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::va::Float("a_coord",		4, 4, 0, &coords[0])
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint16 indices[] = { 0, 2, 1, 2, 3, 1 };
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clearColor(0.125f, 0.25f, 0.5f, 1.0f);
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(program.getProgram());
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int	scaleLoc	= gl.getUniformLocation(program.getProgram(), "u_scale");
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int	biasLoc		= gl.getUniformLocation(program.getProgram(), "u_bias");
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (m_dataType)
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT:
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					gl.uniform1f(scaleLoc, m_derivScale.x());
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					gl.uniform1f(biasLoc, m_derivBias.x());
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_VEC2:
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					gl.uniform2fv(scaleLoc, 1, m_derivScale.getPtr());
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					gl.uniform2fv(biasLoc, 1, m_derivBias.getPtr());
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_VEC3:
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					gl.uniform3fv(scaleLoc, 1, m_derivScale.getPtr());
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					gl.uniform3fv(biasLoc, 1, m_derivBias.getPtr());
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_VEC4:
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					gl.uniform4fv(scaleLoc, 1, m_derivScale.getPtr());
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					gl.uniform4fv(biasLoc, 1, m_derivBias.getPtr());
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gls::setupDefaultUniforms(m_context.getRenderContext(), program.getProgram());
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setupRenderState(program.getProgram());
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, m_hint);
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Setup program state");
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.viewport(viewportX, viewportY, viewportSize.x(), viewportSize.y());
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read back results
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool		isMSAA		= useFbo && m_numSamples > 0;
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		AutoFbo			resFbo		(gl);
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		AutoRbo			resRbo		(gl);
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Resolve if necessary
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isMSAA)
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resFbo.gen();
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resRbo.gen();
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindRenderbuffer(GL_RENDERBUFFER, *resRbo);
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 0, fboFormat, viewportSize.x(), viewportSize.y());
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, *resFbo);
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *resRbo);
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.blitFramebuffer(0, 0, viewportSize.x(), viewportSize.y(), 0, 0, viewportSize.x(), viewportSize.y(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_EXPECT_NO_ERROR(gl.getError(), "Resolve blit");
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_READ_FRAMEBUFFER, *resFbo);
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (m_surfaceType)
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case SURFACETYPE_DEFAULT_FRAMEBUFFER:
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case SURFACETYPE_UNORM_FBO:
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result.setStorage(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), viewportSize.x(), viewportSize.y());
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, result);
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case SURFACETYPE_FLOAT_FBO:
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::TextureFormat	dataFormat		(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::TextureFormat	transferFormat	(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result.setStorage(dataFormat, viewportSize.x(), viewportSize.y());
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				glu::readPixels(m_context.getRenderContext(), viewportX, viewportY,
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								tcu::PixelBufferAccess(transferFormat, result.getWidth(), result.getHeight(), result.getDepth(), result.getAccess().getDataPtr()));
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Verify
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Surface errorMask(result.getWidth(), result.getHeight());
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(errorMask.getAccess(), tcu::RGBA::green.toVec());
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isOk = verify(result.getAccess(), errorMask.getAccess());
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::ImageSet("Result", "Result images")
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						   << TestLog::Image("Rendered", "Rendered image", result);
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isOk)
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog() << TestLog::Image("ErrorMask", "Error mask", errorMask);
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::EndImageSet;
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								isOk ? "Pass"				: "Image comparison failed");
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TriangleDerivateCase::getSurfaceThreshold (void) const
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_surfaceType)
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SURFACETYPE_DEFAULT_FRAMEBUFFER:
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::PixelFormat	pixelFormat		= m_context.getRenderTarget().getPixelFormat();
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::IVec4		channelBits		(pixelFormat.redBits, pixelFormat.greenBits, pixelFormat.blueBits, pixelFormat.alphaBits);
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::IVec4		intThreshold	= tcu::IVec4(1) << (8 - channelBits);
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::Vec4			normThreshold	= intThreshold.asFloat() / 255.0f;
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return normThreshold;
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SURFACETYPE_UNORM_FBO:				return tcu::IVec4(1).asFloat() / 255.0f;
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case SURFACETYPE_FLOAT_FBO:				return tcu::Vec4(0.0f);
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return tcu::Vec4(0.0f);
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ConstantDerivateCase
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ConstantDerivateCase : public TriangleDerivateCase
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ConstantDerivateCase		(Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type);
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~ConstantDerivateCase		(void) {}
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init						(void);
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				verify						(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DerivateFunc		m_func;
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6253c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstantDerivateCase::ConstantDerivateCase (Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type)
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TriangleDerivateCase	(context, name, description)
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_func				(func)
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_dataType			= type;
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_precision			= glu::PRECISION_HIGHP;
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_coordDataType		= m_dataType;
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_coordPrecision	= m_precision;
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConstantDerivateCase::init (void)
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* fragmentTmpl =
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"layout(location = 0) out mediump vec4 o_color;\n"
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main (void)\n"
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	${PRECISION} ${DATATYPE} res = ${FUNC}(${VALUE}) * u_scale + u_bias;\n"
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	o_color = ${CAST_TO_OUTPUT};\n"
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> fragmentParams;
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragmentParams["PRECISION"]			= glu::getPrecisionName(m_precision);
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragmentParams["DATATYPE"]			= glu::getDataTypeName(m_dataType);
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragmentParams["FUNC"]				= getDerivateFuncName(m_func);
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragmentParams["VALUE"]				= m_dataType == glu::TYPE_FLOAT_VEC4 ? "vec4(1.0, 7.2, -1e5, 0.0)" :
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec3(1e2, 8.0, 0.01)" :
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec2(-0.0, 2.7)" :
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  /* TYPE_FLOAT */					   "7.7";
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragmentParams["CAST_TO_OUTPUT"]	= m_dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  /* TYPE_FLOAT */					   "vec4(res, 0.0, 0.0, 1.0)";
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fragmentSrc = tcu::StringTemplate(fragmentTmpl).specialize(fragmentParams);
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_derivScale	= tcu::Vec4(1e3f, 1e3f, 1e3f, 1e3f);
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_derivBias		= tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ConstantDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4 reference	(0.0f); // Derivate of constant argument should always be 0
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4	threshold	= getSurfaceThreshold() / abs(m_derivScale);
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  reference, threshold, m_derivScale, m_derivBias);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// LinearDerivateCase
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LinearDerivateCase : public TriangleDerivateCase
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						LinearDerivateCase		(Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type, glu::Precision precision, deUint32 hint, SurfaceType surfaceType, int numSamples, const char* fragmentSrcTmpl);
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~LinearDerivateCase		(void) {}
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init					(void);
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DerivateFunc		m_func;
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			m_fragmentTmpl;
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6933c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLinearDerivateCase::LinearDerivateCase (Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type, glu::Precision precision, deUint32 hint, SurfaceType surfaceType, int numSamples, const char* fragmentSrcTmpl)
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TriangleDerivateCase	(context, name, description)
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_func				(func)
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fragmentTmpl		(fragmentSrcTmpl)
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_dataType			= type;
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_precision			= precision;
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_coordDataType		= m_dataType;
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_coordPrecision	= m_precision;
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_hint				= hint;
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_surfaceType		= surfaceType;
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numSamples		= numSamples;
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LinearDerivateCase::init (void)
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec2	viewportSize	= getViewportSize();
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float			w				= float(viewportSize.x());
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float			h				= float(viewportSize.y());
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			packToInt		= m_surfaceType == SURFACETYPE_FLOAT_FBO;
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string>	fragmentParams;
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragmentParams["OUTPUT_TYPE"]		= glu::getDataTypeName(packToInt ? glu::TYPE_UINT_VEC4 : glu::TYPE_FLOAT_VEC4);
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragmentParams["OUTPUT_PREC"]		= glu::getPrecisionName(packToInt ? glu::PRECISION_HIGHP : m_precision);
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragmentParams["PRECISION"]			= glu::getPrecisionName(m_precision);
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragmentParams["DATATYPE"]			= glu::getDataTypeName(m_dataType);
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	fragmentParams["FUNC"]				= getDerivateFuncName(m_func);
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (packToInt)
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentParams["CAST_TO_OUTPUT"]	= m_dataType == glu::TYPE_FLOAT_VEC4 ? "floatBitsToUint(res)" :
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  m_dataType == glu::TYPE_FLOAT_VEC3 ? "floatBitsToUint(vec4(res, 1.0))" :
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  m_dataType == glu::TYPE_FLOAT_VEC2 ? "floatBitsToUint(vec4(res, 0.0, 1.0))" :
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  /* TYPE_FLOAT */					   "floatBitsToUint(vec4(res, 0.0, 0.0, 1.0))";
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentParams["CAST_TO_OUTPUT"]	= m_dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  /* TYPE_FLOAT */					   "vec4(res, 0.0, 0.0, 1.0)";
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fragmentSrc = tcu::StringTemplate(m_fragmentTmpl.c_str()).specialize(fragmentParams);
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_precision)
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::PRECISION_HIGHP:
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordMin = tcu::Vec4(-97.f, 0.2f, 71.f, 74.f);
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordMax = tcu::Vec4(-13.2f, -77.f, 44.f, 76.f);
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::PRECISION_MEDIUMP:
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordMin = tcu::Vec4(-37.0f, 47.f, -7.f, 0.0f);
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordMax = tcu::Vec4(-1.0f, 12.f, 7.f, 19.f);
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::PRECISION_LOWP:
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordMin = tcu::Vec4(0.0f, -1.0f, 0.0f, 1.0f);
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordMax = tcu::Vec4(1.0f, 1.0f, -1.0f, -1.0f);
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_surfaceType == SURFACETYPE_FLOAT_FBO)
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// No scale or bias used for accuracy.
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_derivScale	= tcu::Vec4(1.0f);
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_derivBias		= tcu::Vec4(0.0f);
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute scale - bias that normalizes to 0..1 range.
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4 dx = (m_coordMax - m_coordMin) / tcu::Vec4(w, w, w*0.5f, -w*0.5f);
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4 dy = (m_coordMax - m_coordMin) / tcu::Vec4(h, h, h*0.5f, -h*0.5f);
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (m_func)
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case DERIVATE_DFDX:
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_derivScale = 0.5f / dx;
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case DERIVATE_DFDY:
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_derivScale = 0.5f / dy;
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case DERIVATE_FWIDTH:
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_derivScale = 0.5f / (tcu::abs(dx) + tcu::abs(dy));
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_derivBias = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool LinearDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4		xScale				= tcu::Vec4(1.0f, 0.0f, 0.5f, -0.5f);
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4		yScale				= tcu::Vec4(0.0f, 1.0f, 0.5f, -0.5f);
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4		surfaceThreshold	= getSurfaceThreshold() / abs(m_derivScale);
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_func == DERIVATE_DFDX || m_func == DERIVATE_DFDY)
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			isX			= m_func == DERIVATE_DFDX;
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			div			= isX ? float(result.getWidth()) : float(result.getHeight());
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		scale		= isX ? xScale : yScale;
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		reference	= ((m_coordMax - m_coordMin) / div) * scale;
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		opThreshold	= getDerivateThreshold(m_precision, m_coordMin*scale, m_coordMax*scale, reference);
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		threshold	= max(surfaceThreshold, opThreshold);
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  reference, threshold, m_derivScale, m_derivBias);
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_func == DERIVATE_FWIDTH);
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			w			= float(result.getWidth());
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			h			= float(result.getHeight());
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		dx			= ((m_coordMax - m_coordMin) / w) * xScale;
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		dy			= ((m_coordMax - m_coordMin) / h) * yScale;
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		reference	= tcu::abs(dx) + tcu::abs(dy);
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		dxThreshold	= getDerivateThreshold(m_precision, m_coordMin*xScale, m_coordMax*xScale, dx);
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		dyThreshold	= getDerivateThreshold(m_precision, m_coordMin*yScale, m_coordMax*yScale, dy);
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		threshold	= max(surfaceThreshold, max(dxThreshold, dyThreshold));
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType,
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  reference, threshold, m_derivScale, m_derivBias);
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// TextureDerivateCase
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TextureDerivateCase : public TriangleDerivateCase
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						TextureDerivateCase		(Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type, glu::Precision precision, deUint32 hint, SurfaceType surfaceType, int numSamples);
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~TextureDerivateCase	(void);
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init					(void);
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit					(void);
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				setupRenderState		(deUint32 program);
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				verify					(const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask);
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DerivateFunc		m_func;
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4			m_texValueMin;
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4			m_texValueMax;
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture2D*		m_texture;
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureDerivateCase::TextureDerivateCase (Context& context, const char* name, const char* description, DerivateFunc func, glu::DataType type, glu::Precision precision, deUint32 hint, SurfaceType surfaceType, int numSamples)
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TriangleDerivateCase	(context, name, description)
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_func				(func)
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texture				(DE_NULL)
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_dataType			= type;
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_precision			= precision;
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_coordDataType		= glu::TYPE_FLOAT_VEC2;
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_coordPrecision	= glu::PRECISION_HIGHP;
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_hint				= hint;
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_surfaceType		= surfaceType;
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numSamples		= numSamples;
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureDerivateCase::~TextureDerivateCase (void)
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texture;
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureDerivateCase::init (void)
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate shader
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* fragmentTmpl =
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec2 v_coord;\n"
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} sampler2D u_sampler;\n"
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	${PRECISION} vec4 tex = texture(u_sampler, v_coord);\n"
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	${PRECISION} ${DATATYPE} res = ${FUNC}(tex${SWIZZLE}) * u_scale + u_bias;\n"
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = ${CAST_TO_OUTPUT};\n"
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			packToInt		= m_surfaceType == SURFACETYPE_FLOAT_FBO;
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		map<string, string> fragmentParams;
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentParams["OUTPUT_TYPE"]		= glu::getDataTypeName(packToInt ? glu::TYPE_UINT_VEC4 : glu::TYPE_FLOAT_VEC4);
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentParams["OUTPUT_PREC"]		= glu::getPrecisionName(packToInt ? glu::PRECISION_HIGHP : m_precision);
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentParams["PRECISION"]			= glu::getPrecisionName(m_precision);
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentParams["DATATYPE"]			= glu::getDataTypeName(m_dataType);
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentParams["FUNC"]				= getDerivateFuncName(m_func);
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fragmentParams["SWIZZLE"]			= m_dataType == glu::TYPE_FLOAT_VEC4 ? "" :
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  m_dataType == glu::TYPE_FLOAT_VEC3 ? ".xyz" :
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  m_dataType == glu::TYPE_FLOAT_VEC2 ? ".xy" :
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  /* TYPE_FLOAT */					   ".x";
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (packToInt)
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fragmentParams["CAST_TO_OUTPUT"]	= m_dataType == glu::TYPE_FLOAT_VEC4 ? "floatBitsToUint(res)" :
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  m_dataType == glu::TYPE_FLOAT_VEC3 ? "floatBitsToUint(vec4(res, 1.0))" :
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  m_dataType == glu::TYPE_FLOAT_VEC2 ? "floatBitsToUint(vec4(res, 0.0, 1.0))" :
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  /* TYPE_FLOAT */					   "floatBitsToUint(vec4(res, 0.0, 0.0, 1.0))";
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fragmentParams["CAST_TO_OUTPUT"]	= m_dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												  /* TYPE_FLOAT */					   "vec4(res, 0.0, 0.0, 1.0)";
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_fragmentSrc = tcu::StringTemplate(fragmentTmpl).specialize(fragmentParams);
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Texture size matches viewport and nearest sampling is used. Thus texture sampling
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// is equal to just interpolating the texture value range.
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Determine value range for texture.
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_precision)
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::PRECISION_HIGHP:
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texValueMin = tcu::Vec4(-97.f, 0.2f, 71.f, 74.f);
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texValueMax = tcu::Vec4(-13.2f, -77.f, 44.f, 76.f);
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::PRECISION_MEDIUMP:
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texValueMin = tcu::Vec4(-37.0f, 47.f, -7.f, 0.0f);
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texValueMax = tcu::Vec4(-1.0f, 12.f, 7.f, 19.f);
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::PRECISION_LOWP:
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texValueMin = tcu::Vec4(0.0f, -1.0f, 0.0f, 1.0f);
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texValueMax = tcu::Vec4(1.0f, 1.0f, -1.0f, -1.0f);
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Lowp and mediump cases use RGBA16F format, while highp uses RGBA32F.
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec2 viewportSize = getViewportSize();
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!m_texture);
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texture = new glu::Texture2D(m_context.getRenderContext(), m_precision == glu::PRECISION_HIGHP ? GL_RGBA32F : GL_RGBA16F, viewportSize.x(), viewportSize.y());
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texture->getRefTexture().allocLevel(0);
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Texture coordinates
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_coordMin = tcu::Vec4(0.0f);
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_coordMax = tcu::Vec4(1.0f);
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill with gradients.
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::PixelBufferAccess level0 = m_texture->getRefTexture().getLevel(0);
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < level0.getHeight(); y++)
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int x = 0; x < level0.getWidth(); x++)
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float		xf		= (float(x)+0.5f) / float(level0.getWidth());
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float		yf		= (float(y)+0.5f) / float(level0.getHeight());
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::Vec4	s		= tcu::Vec4(xf, yf, (xf+yf)/2.0f, 1.0f - (xf+yf)/2.0f);
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				level0.setPixel(m_texValueMin + (m_texValueMax - m_texValueMin)*s, x, y);
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->upload();
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_surfaceType == SURFACETYPE_FLOAT_FBO)
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// No scale or bias used for accuracy.
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_derivScale	= tcu::Vec4(1.0f);
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_derivBias		= tcu::Vec4(0.0f);
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute scale - bias that normalizes to 0..1 range.
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec2	viewportSize	= getViewportSize();
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			w				= float(viewportSize.x());
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			h				= float(viewportSize.y());
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		dx				= (m_texValueMax - m_texValueMin) / tcu::Vec4(w, w, w*0.5f, -w*0.5f);
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		dy				= (m_texValueMax - m_texValueMin) / tcu::Vec4(h, h, h*0.5f, -h*0.5f);
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (m_func)
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case DERIVATE_DFDX:
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_derivScale = 0.5f / dx;
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case DERIVATE_DFDY:
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_derivScale = 0.5f / dy;
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case DERIVATE_FWIDTH:
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_derivScale = 0.5f / (tcu::abs(dx) + tcu::abs(dy));
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_derivBias = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureDerivateCase::deinit (void)
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texture;
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = DE_NULL;
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureDerivateCase::setupRenderState (deUint32 program)
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				texUnit		= 1;
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.activeTexture	(GL_TEXTURE0+texUnit);
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture		(GL_TEXTURE_2D, m_texture->getGLTexture());
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.uniform1i		(gl.getUniformLocation(program, "u_sampler"), texUnit);
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool TextureDerivateCase::verify (const tcu::ConstPixelBufferAccess& result, const tcu::PixelBufferAccess& errorMask)
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Edges are ignored in comparison
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (result.getWidth() < 2 || result.getHeight() < 2)
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Too small viewport");
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::ConstPixelBufferAccess	compareArea			= tcu::getSubregion(result, 1, 1, result.getWidth()-2, result.getHeight()-2);
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::PixelBufferAccess		maskArea			= tcu::getSubregion(errorMask, 1, 1, errorMask.getWidth()-2, errorMask.getHeight()-2);
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4				xScale				= tcu::Vec4(1.0f, 0.0f, 0.5f, -0.5f);
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4				yScale				= tcu::Vec4(0.0f, 1.0f, 0.5f, -0.5f);
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float					w					= float(result.getWidth());
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float					h					= float(result.getHeight());
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4				surfaceThreshold	= getSurfaceThreshold() / abs(m_derivScale);
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_func == DERIVATE_DFDX || m_func == DERIVATE_DFDY)
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			isX			= m_func == DERIVATE_DFDX;
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			div			= isX ? w : h;
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		scale		= isX ? xScale : yScale;
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		reference	= ((m_texValueMax - m_texValueMin) / div) * scale;
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		opThreshold	= getDerivateThreshold(m_precision, m_texValueMin*scale, m_texValueMax*scale, reference);
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4		threshold	= max(surfaceThreshold, opThreshold);
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  reference, threshold, m_derivScale, m_derivBias);
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_func == DERIVATE_FWIDTH);
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4	dx			= ((m_texValueMax - m_texValueMin) / w) * xScale;
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4	dy			= ((m_texValueMax - m_texValueMin) / h) * yScale;
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4	reference	= tcu::abs(dx) + tcu::abs(dy);
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4	dxThreshold	= getDerivateThreshold(m_precision, m_texValueMin*xScale, m_texValueMax*xScale, dx);
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4	dyThreshold	= getDerivateThreshold(m_precision, m_texValueMin*yScale, m_texValueMax*yScale, dy);
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec4	threshold	= max(surfaceThreshold, max(dxThreshold, dyThreshold));
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  reference, threshold, m_derivScale, m_derivBias);
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderDerivateTests::ShaderDerivateTests (Context& context)
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "derivate", "Derivate Function Tests")
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderDerivateTests::~ShaderDerivateTests (void)
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct FunctionSpec
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string		name;
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DerivateFunc	function;
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::DataType	dataType;
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Precision	precision;
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FunctionSpec (const std::string& name_, DerivateFunc function_, glu::DataType dataType_, glu::Precision precision_)
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: name		(name_)
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, function	(function_)
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, dataType	(dataType_)
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, precision	(precision_)
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderDerivateTests::init (void)
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		description;
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		source;
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} s_linearDerivateCases[] =
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"linear",
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Basic derivate of linearly interpolated argument",
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in ${PRECISION} ${DATATYPE} v_coord;\n"
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	${PRECISION} ${DATATYPE} res = ${FUNC}(v_coord) * u_scale + u_bias;\n"
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = ${CAST_TO_OUTPUT};\n"
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in_function",
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Derivate of linear function argument",
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in ${PRECISION} ${DATATYPE} v_coord;\n"
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"${PRECISION} ${DATATYPE} computeRes (${PRECISION} ${DATATYPE} value)\n"
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	return ${FUNC}(v_coord) * u_scale + u_bias;\n"
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	${PRECISION} ${DATATYPE} res = computeRes(v_coord);\n"
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = ${CAST_TO_OUTPUT};\n"
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"static_if",
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Derivate of linearly interpolated value in static if",
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in ${PRECISION} ${DATATYPE} v_coord;\n"
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	${PRECISION} ${DATATYPE} res;\n"
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	if (false)\n"
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		res = ${FUNC}(-v_coord) * u_scale + u_bias;\n"
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	else\n"
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		res = ${FUNC}(v_coord) * u_scale + u_bias;\n"
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = ${CAST_TO_OUTPUT};\n"
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"static_loop",
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Derivate of linearly interpolated value in static loop",
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in ${PRECISION} ${DATATYPE} v_coord;\n"
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	${PRECISION} ${DATATYPE} res = ${DATATYPE}(0.0);\n"
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	for (int i = 0; i < 2; i++)\n"
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		res += ${FUNC}(v_coord * float(i));\n"
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	res = res * u_scale + u_bias;\n"
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = ${CAST_TO_OUTPUT};\n"
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"static_switch",
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Derivate of linearly interpolated value in static switch",
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in ${PRECISION} ${DATATYPE} v_coord;\n"
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	${PRECISION} ${DATATYPE} res;\n"
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	switch (1)\n"
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	{\n"
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		case 0:	res = ${FUNC}(-v_coord) * u_scale + u_bias;	break;\n"
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		case 1:	res = ${FUNC}(v_coord) * u_scale + u_bias;	break;\n"
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	}\n"
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = ${CAST_TO_OUTPUT};\n"
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform_if",
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Derivate of linearly interpolated value in uniform if",
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in ${PRECISION} ${DATATYPE} v_coord;\n"
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform bool ub_true;\n"
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	${PRECISION} ${DATATYPE} res;\n"
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	if (ub_true)"
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		res = ${FUNC}(v_coord) * u_scale + u_bias;\n"
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	else\n"
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		res = ${FUNC}(-v_coord) * u_scale + u_bias;\n"
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = ${CAST_TO_OUTPUT};\n"
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform_loop",
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Derivate of linearly interpolated value in uniform loop",
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in ${PRECISION} ${DATATYPE} v_coord;\n"
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform int ui_two;\n"
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	${PRECISION} ${DATATYPE} res = ${DATATYPE}(0.0);\n"
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	for (int i = 0; i < ui_two; i++)\n"
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		res += ${FUNC}(v_coord * float(i));\n"
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	res = res * u_scale + u_bias;\n"
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = ${CAST_TO_OUTPUT};\n"
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform_switch",
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"Derivate of linearly interpolated value in uniform switch",
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#version 300 es\n"
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in ${PRECISION} ${DATATYPE} v_coord;\n"
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_scale;\n"
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform ${PRECISION} ${DATATYPE} u_bias;\n"
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform int ui_one;\n"
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	${PRECISION} ${DATATYPE} res;\n"
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	switch (ui_one)\n"
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	{\n"
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		case 0:	res = ${FUNC}(-v_coord) * u_scale + u_bias;	break;\n"
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		case 1:	res = ${FUNC}(v_coord) * u_scale + u_bias;	break;\n"
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	}\n"
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	o_color = ${CAST_TO_OUTPUT};\n"
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SurfaceType		surfaceType;
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				numSamples;
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} s_fboConfigs[] =
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "fbo",		SURFACETYPE_DEFAULT_FRAMEBUFFER,	0 },
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "fbo_msaa2",	SURFACETYPE_UNORM_FBO,				2 },
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "fbo_msaa4",	SURFACETYPE_UNORM_FBO,				4 },
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "fbo_float",	SURFACETYPE_FLOAT_FBO,				0 },
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		hint;
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} s_hints[] =
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "fastest",	GL_FASTEST	},
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nicest",		GL_NICEST	},
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SurfaceType		surfaceType;
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				numSamples;
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} s_hintFboConfigs[] =
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "default",		SURFACETYPE_DEFAULT_FRAMEBUFFER,	0 },
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "fbo_msaa4",		SURFACETYPE_UNORM_FBO,				4 },
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "fbo_float",		SURFACETYPE_FLOAT_FBO,				0 }
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SurfaceType		surfaceType;
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				numSamples;
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		hint;
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} s_textureConfigs[] =
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "basic",			SURFACETYPE_DEFAULT_FRAMEBUFFER,	0,	GL_DONT_CARE	},
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "msaa4",			SURFACETYPE_UNORM_FBO,				4,	GL_DONT_CARE	},
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "float_fastest",	SURFACETYPE_FLOAT_FBO,				0,	GL_FASTEST		},
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "float_nicest",	SURFACETYPE_FLOAT_FBO,				0,	GL_NICEST		},
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// .dfdx, .dfdy, .fwidth
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int funcNdx = 0; funcNdx < DERIVATE_LAST; funcNdx++)
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const DerivateFunc			function		= DerivateFunc(funcNdx);
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const	functionGroup	= new tcu::TestCaseGroup(m_testCtx, getDerivateFuncCaseName(function), getDerivateFuncName(function));
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(functionGroup);
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// .constant - no precision variants, checks that derivate of constant arguments is 0
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup* const constantGroup = new tcu::TestCaseGroup(m_testCtx, "constant", "Derivate of constant argument");
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			functionGroup->addChild(constantGroup);
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int vecSize = 1; vecSize <= 4; vecSize++)
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const glu::DataType dataType = vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				constantGroup->addChild(new ConstantDerivateCase(m_context, glu::getDataTypeName(dataType), "", function, dataType));
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Cases based on LinearDerivateCase
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_linearDerivateCases); caseNdx++)
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup* const linearCaseGroup	= new tcu::TestCaseGroup(m_testCtx, s_linearDerivateCases[caseNdx].name, s_linearDerivateCases[caseNdx].description);
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*			source					= s_linearDerivateCases[caseNdx].source;
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			functionGroup->addChild(linearCaseGroup);
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int vecSize = 1; vecSize <= 4; vecSize++)
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const glu::DataType		dataType		= vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const glu::Precision	precision		= glu::Precision(precNdx);
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const SurfaceType		surfaceType		= SURFACETYPE_DEFAULT_FRAMEBUFFER;
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int				numSamples		= 0;
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const deUint32			hint			= GL_DONT_CARE;
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ostringstream			caseName;
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (caseNdx != 0 && precision == glu::PRECISION_LOWP)
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						continue; // Skip as lowp doesn't actually produce any bits when rendered to default FB.
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					linearCaseGroup->addChild(new LinearDerivateCase(m_context, caseName.str().c_str(), "", function, dataType, precision, hint, surfaceType, numSamples, source));
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fbo cases
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_fboConfigs); caseNdx++)
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup*	const	fboGroup		= new tcu::TestCaseGroup(m_testCtx, s_fboConfigs[caseNdx].name, "Derivate usage when rendering into FBO");
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*					source			= s_linearDerivateCases[0].source; // use source from .linear group
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const SurfaceType			surfaceType		= s_fboConfigs[caseNdx].surfaceType;
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int					numSamples		= s_fboConfigs[caseNdx].numSamples;
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			functionGroup->addChild(fboGroup);
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int vecSize = 1; vecSize <= 4; vecSize++)
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const glu::DataType		dataType		= vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const glu::Precision	precision		= glu::Precision(precNdx);
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const deUint32			hint			= GL_DONT_CARE;
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ostringstream			caseName;
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (surfaceType != SURFACETYPE_FLOAT_FBO && precision == glu::PRECISION_LOWP)
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					fboGroup->addChild(new LinearDerivateCase(m_context, caseName.str().c_str(), "", function, dataType, precision, hint, surfaceType, numSamples, source));
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// .fastest, .nicest
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int hintCaseNdx = 0; hintCaseNdx < DE_LENGTH_OF_ARRAY(s_hints); hintCaseNdx++)
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup* const	hintGroup		= new tcu::TestCaseGroup(m_testCtx, s_hints[hintCaseNdx].name, "Shader derivate hints");
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*					source			= s_linearDerivateCases[0].source; // use source from .linear group
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32				hint			= s_hints[hintCaseNdx].hint;
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			functionGroup->addChild(hintGroup);
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int fboCaseNdx = 0; fboCaseNdx < DE_LENGTH_OF_ARRAY(s_hintFboConfigs); fboCaseNdx++)
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::TestCaseGroup*	const	fboGroup		= new tcu::TestCaseGroup(m_testCtx, s_hintFboConfigs[fboCaseNdx].name, "");
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const SurfaceType			surfaceType		= s_hintFboConfigs[fboCaseNdx].surfaceType;
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int					numSamples		= s_hintFboConfigs[fboCaseNdx].numSamples;
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				hintGroup->addChild(fboGroup);
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int vecSize = 1; vecSize <= 4; vecSize++)
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const glu::DataType		dataType		= vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const glu::Precision	precision		= glu::Precision(precNdx);
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ostringstream			caseName;
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (surfaceType != SURFACETYPE_FLOAT_FBO && precision == glu::PRECISION_LOWP)
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						fboGroup->addChild(new LinearDerivateCase(m_context, caseName.str().c_str(), "", function, dataType, precision, hint, surfaceType, numSamples, source));
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// .texture
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup* const textureGroup = new tcu::TestCaseGroup(m_testCtx, "texture", "Derivate of texture lookup result");
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			functionGroup->addChild(textureGroup);
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int texCaseNdx = 0; texCaseNdx < DE_LENGTH_OF_ARRAY(s_textureConfigs); texCaseNdx++)
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::TestCaseGroup*	const	caseGroup		= new tcu::TestCaseGroup(m_testCtx, s_textureConfigs[texCaseNdx].name, "");
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const SurfaceType			surfaceType		= s_textureConfigs[texCaseNdx].surfaceType;
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int					numSamples		= s_textureConfigs[texCaseNdx].numSamples;
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32				hint			= s_textureConfigs[texCaseNdx].hint;
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				textureGroup->addChild(caseGroup);
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int vecSize = 1; vecSize <= 4; vecSize++)
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const glu::DataType		dataType		= vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const glu::Precision	precision		= glu::Precision(precNdx);
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ostringstream			caseName;
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (surfaceType != SURFACETYPE_FLOAT_FBO && precision == glu::PRECISION_LOWP)
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						caseGroup->addChild(new TextureDerivateCase(m_context, caseName.str().c_str(), "", function, dataType, precision, hint, surfaceType, numSamples));
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1460