13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 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 gl_HelperInvocation tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fShaderHelperInvocationTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDrawUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deUniquePtr.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::ShaderProgram;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec2;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::MovePtr;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum PrimitiveType
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PRIMITIVETYPE_TRIANGLE = 0,
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PRIMITIVETYPE_LINE,
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PRIMITIVETYPE_WIDE_LINE,
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PRIMITIVETYPE_POINT,
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PRIMITIVETYPE_WIDE_POINT,
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PRIMITIVETYPE_LAST
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumVerticesPerPrimitive (PrimitiveType primType)
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (primType)
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PRIMITIVETYPE_TRIANGLE:	return 3;
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PRIMITIVETYPE_LINE:		return 2;
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PRIMITIVETYPE_WIDE_LINE:	return 2;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PRIMITIVETYPE_POINT:		return 1;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PRIMITIVETYPE_WIDE_POINT:	return 1;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic glu::PrimitiveType getGluPrimitiveType (PrimitiveType primType)
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (primType)
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PRIMITIVETYPE_TRIANGLE:	return glu::PRIMITIVETYPE_TRIANGLES;
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PRIMITIVETYPE_LINE:		return glu::PRIMITIVETYPE_LINES;
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PRIMITIVETYPE_WIDE_LINE:	return glu::PRIMITIVETYPE_LINES;
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PRIMITIVETYPE_POINT:		return glu::PRIMITIVETYPE_POINTS;
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PRIMITIVETYPE_WIDE_POINT:	return glu::PRIMITIVETYPE_POINTS;
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::PRIMITIVETYPE_LAST;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void genVertices (PrimitiveType primType, int numPrimitives, de::Random* rnd, vector<Vec2>* dst)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		isTri		= primType == PRIMITIVETYPE_TRIANGLE;
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		minCoord	= isTri ? -1.5f : -1.0f;
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		maxCoord	= isTri ? +1.5f : +1.0f;
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		numVert		= getNumVerticesPerPrimitive(primType)*numPrimitives;
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst->resize(numVert);
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < dst->size(); ndx++)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(*dst)[ndx][0] = rnd->getFloat(minCoord, maxCoord);
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(*dst)[ndx][1] = rnd->getFloat(minCoord, maxCoord);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getInteger (const glw::Functions& gl, deUint32 pname)
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int v = 0;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(pname, &v);
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return v;
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic Vec2 getRange (const glw::Functions& gl, deUint32 pname)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2 v(0.0f);
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getFloatv(pname, v.getPtr());
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv()");
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return v;
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void drawRandomPrimitives (const glu::RenderContext& renderCtx, deUint32 program, PrimitiveType primType, int numPrimitives, de::Random* rnd)
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl				= renderCtx.getFunctions();
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float						minPointSize	= 16.0f;
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float						maxPointSize	= 32.0f;
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float						minLineWidth	= 16.0f;
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float						maxLineWidth	= 32.0f;
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Vec2>					vertices;
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::VertexArrayBinding>	vertexArrays;
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	genVertices(primType, numPrimitives, rnd, &vertices);
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vertexArrays.push_back(glu::va::Float("a_position", 2, (int)vertices.size(), 0, (const float*)&vertices[0]));
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(program);
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Special state for certain primitives
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (primType == PRIMITIVETYPE_POINT || primType == PRIMITIVETYPE_WIDE_POINT)
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2		range			= getRange(gl, GL_ALIASED_POINT_SIZE_RANGE);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool		isWidePoint		= primType == PRIMITIVETYPE_WIDE_POINT;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float		pointSize		= isWidePoint ? de::min(rnd->getFloat(minPointSize, maxPointSize), range.y()) : 1.0f;
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		pointSizeLoc	= gl.getUniformLocation(program, "u_pointSize");
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.uniform1f(pointSizeLoc, pointSize);
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (primType == PRIMITIVETYPE_WIDE_LINE)
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2		range			= getRange(gl, GL_ALIASED_LINE_WIDTH_RANGE);
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float		lineWidth		= de::min(rnd->getFloat(minLineWidth, maxLineWidth), range.y());
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.lineWidth(lineWidth);
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::draw(renderCtx, program, (int)vertexArrays.size(), &vertexArrays[0],
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  glu::PrimitiveList(getGluPrimitiveType(primType), (int)vertices.size()));
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FboHelper
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								FboHelper			(const glu::RenderContext& renderCtx, int width, int height, deUint32 format, int numSamples);
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~FboHelper			(void);
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						bindForRendering	(void);
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						readPixels			(int x, int y, const tcu::PixelBufferAccess& dst);
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&	m_renderCtx;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					m_numSamples;
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Renderbuffer			m_colorbuffer;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Framebuffer			m_framebuffer;
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Renderbuffer			m_resolveColorbuffer;
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Framebuffer			m_resolveFramebuffer;
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFboHelper::FboHelper (const glu::RenderContext& renderCtx, int width, int height, deUint32 format, int numSamples)
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_renderCtx			(renderCtx)
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numSamples			(numSamples)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_colorbuffer			(renderCtx)
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_framebuffer			(renderCtx)
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_resolveColorbuffer	(renderCtx)
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_resolveFramebuffer	(renderCtx)
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl			= m_renderCtx.getFunctions();
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				maxSamples	= getInteger(gl, GL_MAX_SAMPLES);
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindRenderbuffer(GL_RENDERBUFFER, *m_colorbuffer);
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_numSamples, format, width, height);
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindFramebuffer(GL_FRAMEBUFFER, *m_framebuffer);
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *m_colorbuffer);
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	if (m_numSamples > maxSamples && gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Sample count exceeds GL_MAX_SAMPLES");
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_numSamples != 0)
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindRenderbuffer(GL_RENDERBUFFER, *m_resolveColorbuffer);
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.renderbufferStorage(GL_RENDERBUFFER, format, width, height);
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_FRAMEBUFFER, *m_resolveFramebuffer);
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *m_resolveColorbuffer);
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create framebuffer");
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFboHelper::~FboHelper (void)
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboHelper::bindForRendering (void)
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_renderCtx.getFunctions();
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindFramebuffer(GL_FRAMEBUFFER, *m_framebuffer);
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer()");
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboHelper::readPixels (int x, int y, const tcu::PixelBufferAccess& dst)
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_renderCtx.getFunctions();
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				width	= dst.getWidth();
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				height	= dst.getHeight();
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_numSamples != 0)
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, *m_resolveFramebuffer);
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.blitFramebuffer(x, y, width, height, x, y, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, *m_resolveFramebuffer);
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_renderCtx, x, y, dst);
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FRAMEBUFFER_WIDTH	= 256,
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FRAMEBUFFER_HEIGHT	= 256,
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FRAMEBUFFER_FORMAT	= GL_RGBA8,
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	NUM_SAMPLES_MAX		= -1
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Verifies that gl_HelperInvocation is false in all rendered pixels.
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass HelperInvocationValueCase : public TestCase
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							HelperInvocationValueCase	(Context& context, const char* name, const char* description, PrimitiveType primType, int numSamples);
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~HelperInvocationValueCase	(void);
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					init						(void);
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					deinit						(void);
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult			iterate						(void);
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const PrimitiveType		m_primitiveType;
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				m_numSamples;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				m_numIters;
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				m_numPrimitivesPerIter;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MovePtr<ShaderProgram>	m_program;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MovePtr<FboHelper>		m_fbo;
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_iterNdx;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryHelperInvocationValueCase::HelperInvocationValueCase (Context& context, const char* name, const char* description, PrimitiveType primType, int numSamples)
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase					(context, name, description)
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_primitiveType			(primType)
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numSamples				(numSamples)
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numIters				(5)
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numPrimitivesPerIter	(10)
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_iterNdx					(0)
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryHelperInvocationValueCase::~HelperInvocationValueCase (void)
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid HelperInvocationValueCase::init (void)
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&	renderCtx		= m_context.getRenderContext();
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl				= renderCtx.getFunctions();
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					maxSamples		= getInteger(gl, GL_MAX_SAMPLES);
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					actualSamples	= m_numSamples == NUM_SAMPLES_MAX ? maxSamples : m_numSamples;
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = MovePtr<ShaderProgram>(new ShaderProgram(m_context.getRenderContext(),
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::ProgramSources()
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< glu::VertexSource(
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"#version 310 es\n"
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"in highp vec2 a_position;\n"
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"uniform highp float u_pointSize;\n"
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"void main (void)\n"
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"{\n"
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	gl_PointSize = u_pointSize;\n"
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"}\n")
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< glu::FragmentSource(
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"#version 310 es\n"
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"out mediump vec4 o_color;\n"
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"void main (void)\n"
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"{\n"
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	if (gl_HelperInvocation)\n"
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"		o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	else\n"
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"		o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"}\n")));
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << *m_program;
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_program->isOk())
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program.clear();
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_FAIL("Compile failed");
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Using GL_RGBA8 framebuffer with "
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << actualSamples << " samples" << TestLog::EndMessage;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fbo = MovePtr<FboHelper>(new FboHelper(renderCtx, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 FRAMEBUFFER_FORMAT, actualSamples));
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid HelperInvocationValueCase::deinit (void)
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program.clear();
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fbo.clear();
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool verifyHelperInvocationValue (TestLog& log, const tcu::Surface& result, bool isMultiSample)
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA		bgRef				(0, 0, 0, 255);
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA		fgRef				(0, 255, 0, 255);
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA		threshold			(1, isMultiSample ? 254 : 1, 1, 1);
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					numInvalidPixels	= 0;
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < result.getHeight(); ++y)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < result.getWidth(); ++x)
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::RGBA	resPix	= result.getPixel(x, y);
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!tcu::compareThreshold(resPix, bgRef, threshold) &&
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!tcu::compareThreshold(resPix, fgRef, threshold))
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numInvalidPixels += 1;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numInvalidPixels > 0)
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("Result", "Result image", result);
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "ERROR: Found " << numInvalidPixels << " invalid result pixels!" << TestLog::EndMessage;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "All result pixels are valid" << TestLog::EndMessage;
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return numInvalidPixels == 0;
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryHelperInvocationValueCase::IterateResult HelperInvocationValueCase::iterate (void)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&		renderCtx	= m_context.getRenderContext();
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl			= renderCtx.getFunctions();
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string					sectionName	= string("Iteration ") + de::toString(m_iterNdx+1) + " / " + de::toString(m_numIters);
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection		section		(m_testCtx.getLog(), (string("Iter") + de::toString(m_iterNdx)), sectionName);
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random						rnd			(deStringHash(getName()) ^ deInt32Hash(m_iterNdx));
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface					result		(FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fbo->bindForRendering();
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawRandomPrimitives(renderCtx, m_program->getProgram(), m_primitiveType, m_numPrimitivesPerIter, &rnd);
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fbo->readPixels(0, 0, result.getAccess());
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!verifyHelperInvocationValue(m_testCtx.getLog(), result, m_numSamples != 0))
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid pixels found");
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_iterNdx += 1;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (m_iterNdx < m_numIters) ? CONTINUE : STOP;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Checks derivates when value depends on gl_HelperInvocation.
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass HelperInvocationDerivateCase : public TestCase
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							HelperInvocationDerivateCase	(Context& context, const char* name, const char* description, PrimitiveType primType, int numSamples, const char* derivateFunc);
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~HelperInvocationDerivateCase	(void);
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					init							(void);
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					deinit							(void);
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult			iterate							(void);
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const PrimitiveType		m_primitiveType;
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				m_numSamples;
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::string		m_derivateFunc;
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				m_numIters;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MovePtr<ShaderProgram>	m_program;
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MovePtr<FboHelper>		m_fbo;
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_iterNdx;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4253c827367444ee418f129b2c238299f49d3264554Jarkko PoyryHelperInvocationDerivateCase::HelperInvocationDerivateCase (Context& context, const char* name, const char* description, PrimitiveType primType, int numSamples, const char* derivateFunc)
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase					(context, name, description)
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_primitiveType			(primType)
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numSamples				(numSamples)
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_derivateFunc			(derivateFunc)
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numIters				(16)
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_iterNdx					(0)
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryHelperInvocationDerivateCase::~HelperInvocationDerivateCase (void)
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid HelperInvocationDerivateCase::init (void)
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&	renderCtx		= m_context.getRenderContext();
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl				= renderCtx.getFunctions();
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					maxSamples		= getInteger(gl, GL_MAX_SAMPLES);
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					actualSamples	= m_numSamples == NUM_SAMPLES_MAX ? maxSamples : m_numSamples;
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = MovePtr<ShaderProgram>(new ShaderProgram(m_context.getRenderContext(),
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::ProgramSources()
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< glu::VertexSource(
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"#version 310 es\n"
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"in highp vec2 a_position;\n"
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"uniform highp float u_pointSize;\n"
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"void main (void)\n"
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"{\n"
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	gl_PointSize = u_pointSize;\n"
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"}\n")
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< glu::FragmentSource(string(
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"#version 310 es\n"
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"out mediump vec4 o_color;\n"
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"void main (void)\n"
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"{\n"
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	highp float value		= gl_HelperInvocation ? 1.0 : 0.0;\n"
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	highp float derivate	= ") + m_derivateFunc + "(value);\n"
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	if (gl_HelperInvocation)\n"
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"		o_color = vec4(1.0, 0.0, derivate, 1.0);\n"
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	else\n"
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"		o_color = vec4(0.0, 1.0, derivate, 1.0);\n"
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"}\n")));
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << *m_program;
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_program->isOk())
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program.clear();
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_FAIL("Compile failed");
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::Message << "Using GL_RGBA8 framebuffer with "
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << actualSamples << " samples" << TestLog::EndMessage;
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fbo = MovePtr<FboHelper>(new FboHelper(renderCtx, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 FRAMEBUFFER_FORMAT, actualSamples));
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid HelperInvocationDerivateCase::deinit (void)
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program.clear();
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fbo.clear();
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool hasNeighborWithColor (const tcu::Surface& surface, int x, int y, tcu::RGBA color, tcu::RGBA threshold)
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const IVec2 s_neighbors[] =
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(-1, -1),
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2( 0, -1),
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(+1, -1),
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(-1,  0),
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(+1,  0),
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(-1, +1),
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2( 0, +1),
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec2(+1, +1)
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	w	= surface.getWidth();
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	h	= surface.getHeight();
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int sample = 0; sample < DE_LENGTH_OF_ARRAY(s_neighbors); sample++)
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const IVec2	pos	= IVec2(x, y) + s_neighbors[sample];
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (de::inBounds(pos.x(), 0, w) && de::inBounds(pos.y(), 0, h))
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::RGBA neighborColor = surface.getPixel(pos.x(), pos.y());
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (tcu::compareThreshold(color, neighborColor, threshold))
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true; // Can't know for certain
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return false;
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool verifyHelperInvocationDerivate (TestLog& log, const tcu::Surface& result, bool isMultiSample)
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA		bgRef				(0, 0, 0, 255);
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA		fgRef				(0, 255, 0, 255);
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA		isBgThreshold		(1, isMultiSample ? 254 : 1, 0, 1);
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA		isFgThreshold		(1, isMultiSample ? 254 : 1, 255, 1);
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					numInvalidPixels	= 0;
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					numNonZeroDeriv		= 0;
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < result.getHeight(); ++y)
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < result.getWidth(); ++x)
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::RGBA	resPix			= result.getPixel(x, y);
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		isBg			= tcu::compareThreshold(resPix, bgRef, isBgThreshold);
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		isFg			= tcu::compareThreshold(resPix, fgRef, isFgThreshold);
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		nonZeroDeriv	= resPix.getBlue() > 0;
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		neighborBg		= nonZeroDeriv ? hasNeighborWithColor(result, x, y, bgRef, isBgThreshold) : false;
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (nonZeroDeriv)
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numNonZeroDeriv	+= 1;
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((!isBg && !isFg) ||				// Neither of valid colors (ignoring blue channel that has derivate)
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(nonZeroDeriv && !neighborBg))	// Has non-zero derivate, but sample not at primitive edge
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numInvalidPixels += 1;
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numInvalidPixels > 0)
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("Result", "Result image", result);
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "ERROR: Found " << numInvalidPixels << " invalid result pixels!" << TestLog::EndMessage;
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "All result pixels are valid" << TestLog::EndMessage;
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Found " << numNonZeroDeriv << " pixels with non-zero derivate (neighbor sample has gl_HelperInvocation = true)" << TestLog::EndMessage;
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return numInvalidPixels == 0;
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryHelperInvocationDerivateCase::IterateResult HelperInvocationDerivateCase::iterate (void)
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&		renderCtx	= m_context.getRenderContext();
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl			= renderCtx.getFunctions();
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string					sectionName	= string("Iteration ") + de::toString(m_iterNdx+1) + " / " + de::toString(m_numIters);
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection		section		(m_testCtx.getLog(), (string("Iter") + de::toString(m_iterNdx)), sectionName);
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random						rnd			(deStringHash(getName()) ^ deInt32Hash(m_iterNdx));
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface					result		(FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fbo->bindForRendering();
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawRandomPrimitives(renderCtx, m_program->getProgram(), m_primitiveType, 1, &rnd);
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fbo->readPixels(0, 0, result.getAccess());
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!verifyHelperInvocationDerivate(m_testCtx.getLog(), result, m_numSamples != 0))
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid pixels found");
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_iterNdx += 1;
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (m_iterNdx < m_numIters) ? CONTINUE : STOP;
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderHelperInvocationTests::ShaderHelperInvocationTests (Context& context)
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "helper_invocation", "gl_HelperInvocation tests")
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderHelperInvocationTests::~ShaderHelperInvocationTests (void)
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderHelperInvocationTests::init (void)
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		caseName;
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PrimitiveType	primType;
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} s_primTypes[] =
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "triangles",		PRIMITIVETYPE_TRIANGLE		},
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "lines",			PRIMITIVETYPE_LINE			},
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "wide_lines",		PRIMITIVETYPE_WIDE_LINE		},
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "points",			PRIMITIVETYPE_POINT			},
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "wide_points",	PRIMITIVETYPE_WIDE_POINT	}
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		suffix;
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				numSamples;
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} s_sampleCounts[] =
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "",					0				},
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "_4_samples",			4				},
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "_8_samples",			8				},
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "_max_samples",		NUM_SAMPLES_MAX	}
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// value
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const valueGroup = new tcu::TestCaseGroup(m_testCtx, "value", "gl_HelperInvocation value in rendered pixels");
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(valueGroup);
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(s_sampleCounts); sampleCountNdx++)
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int primTypeNdx = 0; primTypeNdx < DE_LENGTH_OF_ARRAY(s_primTypes); primTypeNdx++)
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string		name		= string(s_primTypes[primTypeNdx].caseName) + s_sampleCounts[sampleCountNdx].suffix;
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const PrimitiveType	primType	= s_primTypes[primTypeNdx].primType;
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			numSamples	= s_sampleCounts[sampleCountNdx].numSamples;
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valueGroup->addChild(new HelperInvocationValueCase(m_context, name.c_str(), "", primType, numSamples));
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// derivate
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const derivateGroup = new tcu::TestCaseGroup(m_testCtx, "derivate", "Derivate of gl_HelperInvocation-dependent value");
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(derivateGroup);
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(s_sampleCounts); sampleCountNdx++)
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int primTypeNdx = 0; primTypeNdx < DE_LENGTH_OF_ARRAY(s_primTypes); primTypeNdx++)
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string		name		= string(s_primTypes[primTypeNdx].caseName) + s_sampleCounts[sampleCountNdx].suffix;
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const PrimitiveType	primType	= s_primTypes[primTypeNdx].primType;
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			numSamples	= s_sampleCounts[sampleCountNdx].numSamples;
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				derivateGroup->addChild(new HelperInvocationDerivateCase(m_context, (name + "_dfdx").c_str(),	"", primType, numSamples, "dFdx"));
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				derivateGroup->addChild(new HelperInvocationDerivateCase(m_context, (name + "_dfdy").c_str(),	"", primType, numSamples, "dFdy"));
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				derivateGroup->addChild(new HelperInvocationDerivateCase(m_context, (name + "_fwidth").c_str(),	"", primType, numSamples, "fwidth"));
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
674