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 Tessellation and geometry shader interaction stress tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31sTessellationGeometryInteractionTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deUniquePtr.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream>
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Stress
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AllowedRenderFailureException : public std::runtime_error
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	AllowedRenderFailureException (const char* message) : std::runtime_error(message) { }
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GridRenderCase : public TestCase
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum Flags
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FLAG_TESSELLATION_MAX_SPEC						= 0x0001,
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FLAG_TESSELLATION_MAX_IMPLEMENTATION			= 0x0002,
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FLAG_GEOMETRY_MAX_SPEC							= 0x0004,
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FLAG_GEOMETRY_MAX_IMPLEMENTATION				= 0x0008,
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC				= 0x0010,
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION	= 0x0020,
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						GridRenderCase					(Context& context, const char* name, const char* description, int flags);
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~GridRenderCase					(void);
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				init							(void);
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				deinit							(void);
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate							(void);
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				renderTo						(std::vector<tcu::Surface>& dst);
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				verifyResultLayer				(int layerNdx, const tcu::Surface& dst);
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*			getVertexSource					(void);
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*			getFragmentSource				(void);
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			getTessellationControlSource	(int tessLevel);
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			getTessellationEvaluationSource	(int tessLevel);
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			getGeometryShaderSource			(int numPrimitives, int numInstances);
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RENDER_SIZE = 256
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			m_flags;
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ShaderProgram*	m_program;
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_numLayers;
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGridRenderCase::GridRenderCase (Context& context, const char* name, const char* description, int flags)
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase		(context, name, description)
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_flags		(flags)
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program		(DE_NULL)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLayers	(1)
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(((m_flags & FLAG_TESSELLATION_MAX_SPEC) == 0)			|| ((m_flags & FLAG_TESSELLATION_MAX_IMPLEMENTATION) == 0));
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(((m_flags & FLAG_GEOMETRY_MAX_SPEC) == 0)				|| ((m_flags & FLAG_GEOMETRY_MAX_IMPLEMENTATION) == 0));
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(((m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC) == 0)	|| ((m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION) == 0));
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGridRenderCase::~GridRenderCase (void)
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deinit();
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GridRenderCase::init (void)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Requirements
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") ||
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions");
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_context.getRenderTarget().getWidth() < RENDER_SIZE ||
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context.getRenderTarget().getHeight() < RENDER_SIZE)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_SIZE) + "x" + de::toString<int>(RENDER_SIZE) + " or larger render target.");
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Log
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog()
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< tcu::TestLog::Message
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "Testing tessellation and geometry shaders that output a large number of primitives.\n"
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< getDescription()
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< tcu::TestLog::EndMessage;
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Gen program
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::ProgramSources	sources;
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int					tessGenLevel = -1;
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		sources	<< glu::VertexSource(getVertexSource())
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::FragmentSource(getFragmentSource());
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Tessellation limits
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_flags & FLAG_TESSELLATION_MAX_IMPLEMENTATION)
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.getIntegerv(GL_MAX_TESS_GEN_LEVEL, &tessGenLevel);
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_EXPECT_NO_ERROR(gl.getError(), "query tessellation limits");
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_flags & FLAG_TESSELLATION_MAX_SPEC)
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tessGenLevel = 64;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tessGenLevel = 5;
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.getLog()
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::Message
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "Tessellation level: " << tessGenLevel << ", mode = quad.\n"
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\tEach input patch produces " << (tessGenLevel*tessGenLevel) << " (" << (tessGenLevel*tessGenLevel*2) << " triangles)\n"
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::EndMessage;
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sources << glu::TessellationControlSource(getTessellationControlSource(tessGenLevel))
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< glu::TessellationEvaluationSource(getTessellationEvaluationSource(tessGenLevel));
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Geometry limits
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		geometryOutputComponents		= -1;
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		geometryOutputVertices			= -1;
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		geometryTotalOutputComponents	= -1;
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		geometryShaderInvocations		= -1;
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool	logGeometryLimits				= false;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool	logInvocationLimits				= false;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_flags & FLAG_GEOMETRY_MAX_IMPLEMENTATION)
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << tcu::TestLog::Message << "Using implementation maximum geometry shader output limits." << tcu::TestLog::EndMessage;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &geometryOutputComponents);
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &geometryOutputVertices);
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &geometryTotalOutputComponents);
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_EXPECT_NO_ERROR(gl.getError(), "query geometry limits");
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				logGeometryLimits = true;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_flags & FLAG_GEOMETRY_MAX_SPEC)
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog() << tcu::TestLog::Message << "Using geometry shader extension minimum maximum output limits." << tcu::TestLog::EndMessage;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				geometryOutputComponents = 128;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				geometryOutputVertices = 256;
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				geometryTotalOutputComponents = 1024;
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				logGeometryLimits = true;
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				geometryOutputComponents = 128;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				geometryOutputVertices = 16;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				geometryTotalOutputComponents = 1024;
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION)
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_INVOCATIONS, &geometryShaderInvocations);
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_EXPECT_NO_ERROR(gl.getError(), "query geometry invocation limits");
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				logInvocationLimits = true;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC)
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				geometryShaderInvocations = 32;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				logInvocationLimits = true;
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				geometryShaderInvocations = 4;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (logGeometryLimits || logInvocationLimits)
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::MessageBuilder msg(&m_testCtx.getLog());
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				msg << "Geometry shader, targeting following limits:\n";
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (logGeometryLimits)
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					msg	<< "\tGL_MAX_GEOMETRY_OUTPUT_COMPONENTS = " << geometryOutputComponents << "\n"
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "\tGL_MAX_GEOMETRY_OUTPUT_VERTICES = " << geometryOutputVertices << "\n"
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "\tGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = " << geometryTotalOutputComponents << "\n";
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (logInvocationLimits)
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					msg << "\tGL_MAX_GEOMETRY_SHADER_INVOCATIONS = " << geometryShaderInvocations;
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				msg << tcu::TestLog::EndMessage;
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int	numComponentsPerVertex		= 8; // vec4 pos, vec4 color
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// If FLAG_GEOMETRY_SEPARATE_PRIMITIVES is not set, geometry shader fills a rectangle area in slices.
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Each slice is a triangle strip and is generated by a single shader invocation.
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// One slice with 4 segment ends (nodes) and 3 segments:
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				//    .__.__.__.
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				//    |\ |\ |\ |
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				//    |_\|_\|_\|
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int	numSliceNodesComponentLimit			= geometryTotalOutputComponents / (2 * numComponentsPerVertex);			// each node 2 vertices
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int	numSliceNodesOutputLimit			= geometryOutputVertices / 2;											// each node 2 vertices
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int	numSliceNodes						= de::min(numSliceNodesComponentLimit, numSliceNodesOutputLimit);
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int	numVerticesPerInvocation			= numSliceNodes * 2;
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int	numPrimitivesPerInvocation			= (numSliceNodes - 1) * 2;
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int	geometryVerticesPerPrimitive		= numVerticesPerInvocation * geometryShaderInvocations;
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int	geometryPrimitivesOutPerPrimitive	= numPrimitivesPerInvocation * geometryShaderInvocations;
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog()
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::Message
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "Geometry shader:\n"
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\tTotal output vertex count per invocation: " << (numVerticesPerInvocation) << "\n"
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\tTotal output primitive count per invocation: " << (numPrimitivesPerInvocation) << "\n"
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\tNumber of invocations per primitive: " << geometryShaderInvocations << "\n"
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\tTotal output vertex count per input primitive: " << (geometryVerticesPerPrimitive) << "\n"
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\tTotal output primitive count per input primitive: " << (geometryPrimitivesOutPerPrimitive) << "\n"
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::EndMessage;
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sources	<< glu::GeometrySource(getGeometryShaderSource(numPrimitivesPerInvocation, geometryShaderInvocations));
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_testCtx.getLog()
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::Message
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "Program:\n"
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\tTotal program output vertices count per input patch: " << (tessGenLevel*tessGenLevel*2 * geometryVerticesPerPrimitive) << "\n"
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "\tTotal program output primitive count per input patch: " << (tessGenLevel*tessGenLevel*2 * geometryPrimitivesOutPerPrimitive) << "\n"
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< tcu::TestLog::EndMessage;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program = new glu::ShaderProgram(m_context.getRenderContext(), sources);
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << *m_program;
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_program->isOk())
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("failed to build program");
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GridRenderCase::deinit (void)
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_program;
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = DE_NULL;
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGridRenderCase::IterateResult GridRenderCase::iterate (void)
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<tcu::Surface>	renderedLayers	(m_numLayers);
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						allLayersOk		= true;
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < m_numLayers; ++ndx)
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderedLayers[ndx].setSize(RENDER_SIZE, RENDER_SIZE);
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Rendering single point at the origin. Expecting yellow and green colored grid-like image. (High-frequency grid may appear unicolored)." << tcu::TestLog::EndMessage;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		renderTo(renderedLayers);
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const AllowedRenderFailureException& ex)
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Got accepted failure
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog()
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::Message
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "Could not render, reason: " << ex.what() << "\n"
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< "Failure is allowed."
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::EndMessage;
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < m_numLayers; ++ndx)
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		allLayersOk &= verifyResultLayer(ndx, renderedLayers[ndx]);
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (allLayersOk)
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GridRenderCase::renderTo (std::vector<tcu::Surface>& dst)
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&			gl					= m_context.getRenderContext().getFunctions();
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						positionLocation	= gl.getAttribLocation(m_program->getProgram(), "a_position");
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::VertexArray			vao					(m_context.getRenderContext());
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (positionLocation == -1)
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("Attribute a_position location was -1");
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(0, 0, dst.front().getWidth(), dst.front().getHeight());
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindVertexArray(*vao);
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "bind vao");
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(m_program->getProgram());
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "use program");
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.patchParameteri(GL_PATCH_VERTICES, 1);
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param");
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.vertexAttrib4f(positionLocation, 0.0f, 0.0f, 0.0f, 1.0f);
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// clear viewport
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT);
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// draw
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glw::GLenum glerror;
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.drawArrays(GL_PATCHES, 0, 1);
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// allow always OOM
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glerror = gl.getError();
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glerror == GL_OUT_OF_MEMORY)
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw AllowedRenderFailureException("got GL_OUT_OF_MEMORY while drawing");
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(glerror, "draw patches");
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read layers
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), 0, 0, dst.front().getAccess());
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool GridRenderCase::verifyResultLayer (int layerNdx, const tcu::Surface& image)
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface	errorMask	(image.getWidth(), image.getHeight());
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			foundError	= false;
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output layer " << layerNdx  << tcu::TestLog::EndMessage;
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < image.getHeight(); ++y)
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < image.getWidth(); ++x)
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		threshold	= 8;
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::RGBA	color		= image.getPixel(x, y);
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Color must be a linear combination of green and yellow
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (color.getGreen() < 255 - threshold || color.getBlue() > threshold)
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
397c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski			errorMask.setPixel(x, y, tcu::RGBA::red());
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			foundError = true;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!foundError)
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog()
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::Message << "Image valid." << tcu::TestLog::EndMessage
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::ImageSet("ImageVerification", "Image verification")
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::Image("Result", "Rendered result", image.getAccess())
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::EndImageSet;
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog()
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::Message << "Image verification failed, found invalid pixels." << tcu::TestLog::EndMessage
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::ImageSet("ImageVerification", "Image verification")
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::Image("Result", "Rendered result", image.getAccess())
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess())
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< tcu::TestLog::EndImageSet;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* GridRenderCase::getVertexSource (void)
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return	"#version 310 es\n"
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in highp vec4 a_position;\n"
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_position;\n"
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* GridRenderCase::getFragmentSource (void)
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return	"#version 310 es\n"
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"flat in mediump vec4 v_color;\n"
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(location = 0) out mediump vec4 fragColor;\n"
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	fragColor = v_color;\n"
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string GridRenderCase::getTessellationControlSource (int tessLevel)
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream buf;
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"#version 310 es\n"
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#extension GL_EXT_tessellation_shader : require\n"
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(vertices=1) out;\n"
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main()\n"
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_TessLevelOuter[0] = " << tessLevel << ".0;\n"
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_TessLevelOuter[1] = " << tessLevel << ".0;\n"
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_TessLevelOuter[2] = " << tessLevel << ".0;\n"
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_TessLevelOuter[3] = " << tessLevel << ".0;\n"
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_TessLevelInner[0] = " << tessLevel << ".0;\n"
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_TessLevelInner[1] = " << tessLevel << ".0;\n"
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buf.str();
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string GridRenderCase::getTessellationEvaluationSource (int tessLevel)
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream buf;
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf <<	"#version 310 es\n"
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#extension GL_EXT_tessellation_shader : require\n"
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(quads) in;\n"
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"out mediump ivec2 v_tessellationGridPosition;\n"
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
4760a0dd88d111d0bfcecd63d3cb19c3f428c04ca82Jarkko Pöyry			"// note: No need to use precise gl_Position since position does not depend on order\n"
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main (void)\n"
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	// Fill the whole viewport\n"
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = vec4(gl_TessCoord.x * 2.0 - 1.0, gl_TessCoord.y * 2.0 - 1.0, 0.0, 1.0);\n"
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	// Calculate position in tessellation grid\n"
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	v_tessellationGridPosition = ivec2(round(gl_TessCoord.xy * float(" << tessLevel << ")));\n"
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buf.str();
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string GridRenderCase::getGeometryShaderSource (int numPrimitives, int numInstances)
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream buf;
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buf	<<	"#version 310 es\n"
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"#extension GL_EXT_geometry_shader : require\n"
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(triangles, invocations=" << numInstances << ") in;\n"
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"layout(triangle_strip, max_vertices=" << (numPrimitives + 2) << ") out;\n"
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"in mediump ivec2 v_tessellationGridPosition[];\n"
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"flat out highp vec4 v_color;\n"
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main ()\n"
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	const float equalThreshold = 0.001;\n"
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	const float gapOffset = 0.0001; // subdivision performed by the geometry shader might produce gaps. Fill potential gaps by enlarging the output slice a little.\n"
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	// Input triangle is generated from an axis-aligned rectangle by splitting it in half\n"
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	// Original rectangle can be found by finding the bounding AABB of the triangle\n"
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	vec4 aabb = vec4(min(gl_in[0].gl_Position.x, min(gl_in[1].gl_Position.x, gl_in[2].gl_Position.x)),\n"
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	                 min(gl_in[0].gl_Position.y, min(gl_in[1].gl_Position.y, gl_in[2].gl_Position.y)),\n"
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	                 max(gl_in[0].gl_Position.x, max(gl_in[1].gl_Position.x, gl_in[2].gl_Position.x)),\n"
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	                 max(gl_in[0].gl_Position.y, max(gl_in[1].gl_Position.y, gl_in[2].gl_Position.y)));\n"
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	// Location in tessellation grid\n"
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	ivec2 gridPosition = ivec2(min(v_tessellationGridPosition[0], min(v_tessellationGridPosition[1], v_tessellationGridPosition[2])));\n"
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	// Which triangle of the two that split the grid cell\n"
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	int numVerticesOnBottomEdge = 0;\n"
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	for (int ndx = 0; ndx < 3; ++ndx)\n"
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		if (abs(gl_in[ndx].gl_Position.y - aabb.w) < equalThreshold)\n"
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"			++numVerticesOnBottomEdge;\n"
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	bool isBottomTriangle = numVerticesOnBottomEdge == 2;\n"
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	// Fill the input area with slices\n"
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	// Upper triangle produces slices only to the upper half of the quad and vice-versa\n"
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	float triangleOffset = (isBottomTriangle) ? ((aabb.w + aabb.y) / 2.0) : (aabb.y);\n"
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	// Each slice is a invocation\n"
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	float sliceHeight = (aabb.w - aabb.y) / float(2 * " << numInstances << ");\n"
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	float invocationOffset = float(gl_InvocationID) * sliceHeight;\n"
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	vec4 outputSliceArea;\n"
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	outputSliceArea.x = aabb.x - gapOffset;\n"
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	outputSliceArea.y = triangleOffset + invocationOffset - gapOffset;\n"
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	outputSliceArea.z = aabb.z + gapOffset;\n"
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	outputSliceArea.w = triangleOffset + invocationOffset + sliceHeight + gapOffset;\n""\n"
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	// Draw slice\n"
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	for (int ndx = 0; ndx < " << ((numPrimitives+2)/2) << "; ++ndx)\n"
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	{\n"
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		vec4 outputColor = (((gl_InvocationID + ndx) % 2) == 0) ? (green) : (yellow);\n"
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		float xpos = mix(outputSliceArea.x, outputSliceArea.z, float(ndx) / float(" << (numPrimitives/2) << "));\n"
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		gl_Position = vec4(xpos, outputSliceArea.y, 0.0, 1.0);\n"
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		v_color = outputColor;\n"
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		EmitVertex();\n"
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		gl_Position = vec4(xpos, outputSliceArea.w, 0.0, 1.0);\n"
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		v_color = outputColor;\n"
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		EmitVertex();\n"
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	}\n"
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n";
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return buf.str();
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTessellationGeometryInteractionTests::TessellationGeometryInteractionTests (Context& context)
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "tessellation_geometry_interaction", "Tessellation and geometry shader interaction stress tests")
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTessellationGeometryInteractionTests::~TessellationGeometryInteractionTests (void)
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TessellationGeometryInteractionTests::init (void)
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* const multilimitGroup = new tcu::TestCaseGroup(m_testCtx, "render_multiple_limits", "Various render tests");
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(multilimitGroup);
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// .render_multiple_limits
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const struct LimitCaseDef
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*	name;
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*	desc;
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int			flags;
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} cases[] =
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Test multiple limits at the same time
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"output_required_max_tessellation_max_geometry",
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"Minimum maximum tessellation level and geometry shader output vertices",
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GridRenderCase::FLAG_TESSELLATION_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_MAX_SPEC
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			},
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"output_implementation_max_tessellation_max_geometry",
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"Maximum tessellation level and geometry shader output vertices supported by the implementation",
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GridRenderCase::FLAG_TESSELLATION_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_MAX_IMPLEMENTATION
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			},
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"output_required_max_tessellation_max_invocations",
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"Minimum maximum tessellation level and geometry shader invocations",
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GridRenderCase::FLAG_TESSELLATION_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			},
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"output_implementation_max_tessellation_max_invocations",
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"Maximum tessellation level and geometry shader invocations supported by the implementation",
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GridRenderCase::FLAG_TESSELLATION_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			},
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"output_required_max_geometry_max_invocations",
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"Minimum maximum geometry shader output vertices and invocations",
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GridRenderCase::FLAG_GEOMETRY_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			},
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"output_implementation_max_geometry_max_invocations",
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"Maximum geometry shader output vertices and invocations invocations supported by the implementation",
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GridRenderCase::FLAG_GEOMETRY_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			},
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Test all limits simultaneously
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"output_max_required",
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"Output minimum maximum number of vertices",
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GridRenderCase::FLAG_TESSELLATION_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			},
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"output_max_implementation",
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"Output maximum number of vertices supported by the implementation",
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GridRenderCase::FLAG_TESSELLATION_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			},
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ++ndx)
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			multilimitGroup->addChild(new GridRenderCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].flags));
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Stress
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
635