13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program EGL 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 Rendering tests for different config and api combinations.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo [2013-03-19 pyry] GLES1 and VG support.
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "teglRenderTests.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "teglRenderCase.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSharedPtr.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSemaphore.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deThread.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm>
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iterator>
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <memory>
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set>
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <EGL/eglext.h>
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(EGL_OPENGL_ES3_BIT_KHR)
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	define EGL_OPENGL_ES3_BIT_KHR	0x0040
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(EGL_CONTEXT_MAJOR_VERSION_KHR)
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DEQP_SUPPORT_GLES2)
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	include <GLES2/gl2.h>
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#elif defined(DEQP_SUPPORT_GLES3)
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	include <GLES3/gl3.h>
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrRenderer.hpp"
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrFragmentOperations.hpp"
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DEQP_SUPPORT_GLES2) || defined(DEQP_SUPPORT_GLES3)
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#      include "gluDefs.hpp"
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#else
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry       // \todo [pyry] Move renderer to common utils
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry       // \note [jarkko] gluDefs is required for GLU_CHECK_MSG
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#      error "Reference renderer requires GLES2 or GLES3 support"
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace egl
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::set;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const tcu::Vec4	CLEAR_COLOR		= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float		CLEAR_DEPTH		= 1.0f;
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int		CLEAR_STENCIL	= 0;
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum PrimitiveType
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PRIMITIVETYPE_TRIANGLE = 0,	//!< Triangles, requires 3 coordinates per primitive
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//	PRIMITIVETYPE_POINT,		//!< Points, requires 1 coordinate per primitive (w is used as size)
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//	PRIMITIVETYPE_LINE,			//!< Lines, requires 2 coordinates per primitive
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PRIMITIVETYPE_LAST
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum BlendMode
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BLENDMODE_NONE = 0,			//!< No blending
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BLENDMODE_ADDITIVE,			//!< Blending with ONE, ONE
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BLENDMODE_SRC_OVER,			//!< Blending with SRC_ALPHA, ONE_MINUS_SRC_ALPHA
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BLENDMODE_LAST
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum DepthMode
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DEPTHMODE_NONE = 0,			//!< No depth test or depth writes
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DEPTHMODE_LESS,				//!< Depth test with less & depth write
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DEPTHMODE_LAST
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum StencilMode
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	STENCILMODE_NONE = 0,		//!< No stencil test or write
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	STENCILMODE_LEQUAL_INC,		//!< Stencil test with LEQUAL, increment on pass
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	STENCILMODE_LAST
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct DrawPrimitiveOp
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PrimitiveType	type;
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				count;
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Vec4>	positions;
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Vec4>	colors;
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BlendMode		blend;
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DepthMode		depth;
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StencilMode		stencil;
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				stencilRef;
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid randomizeDrawOp (de::Random& rnd, DrawPrimitiveOp& drawOp)
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	minStencilRef	= 0;
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	maxStencilRef	= 8;
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	minPrimitives	= 2;
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	maxPrimitives	= 4;
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	maxTriOffset	= 1.0f;
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	minDepth		= -1.0f; // \todo [pyry] Reference doesn't support Z clipping yet
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	maxDepth		= 1.0f;
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	minRGB			= 0.2f;
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	maxRGB			= 0.9f;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	minAlpha		= 0.3f;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	maxAlpha		= 1.0f;
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawOp.type			= (PrimitiveType)rnd.getInt(0, PRIMITIVETYPE_LAST-1);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawOp.count		= rnd.getInt(minPrimitives, maxPrimitives);
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawOp.blend		= (BlendMode)rnd.getInt(0, BLENDMODE_LAST-1);
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawOp.depth		= (DepthMode)rnd.getInt(0, DEPTHMODE_LAST-1);
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawOp.stencil		= (StencilMode)rnd.getInt(0, STENCILMODE_LAST-1);
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawOp.stencilRef	= rnd.getInt(minStencilRef, maxStencilRef);
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (drawOp.type == PRIMITIVETYPE_TRIANGLE)
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawOp.positions.resize(drawOp.count*3);
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawOp.colors.resize(drawOp.count*3);
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int triNdx = 0; triNdx < drawOp.count; triNdx++)
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		cx		= rnd.getFloat(-1.0f, 1.0f);
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		cy		= rnd.getFloat(-1.0f, 1.0f);
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int coordNdx = 0; coordNdx < 3; coordNdx++)
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4&	position	= drawOp.positions[triNdx*3 + coordNdx];
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4&	color		= drawOp.colors[triNdx*3 + coordNdx];
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				position.x()	= cx + rnd.getFloat(-maxTriOffset, maxTriOffset);
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				position.y()	= cy + rnd.getFloat(-maxTriOffset, maxTriOffset);
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				position.z()	= rnd.getFloat(minDepth, maxDepth);
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				position.w()	= 1.0f;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				color.x()		= rnd.getFloat(minRGB, maxRGB);
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				color.y()		= rnd.getFloat(minRGB, maxRGB);
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				color.z()		= rnd.getFloat(minRGB, maxRGB);
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				color.w()		= rnd.getFloat(minAlpha, maxAlpha);
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Reference rendering code
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ReferenceShader : public rr::VertexShader, public rr::FragmentShader
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VaryingLoc_Color = 0
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ReferenceShader ()
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: rr::VertexShader	(2, 1)		// color and pos in => color out
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, rr::FragmentShader(1, 1)		// color in => color out
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::VertexShader::m_inputs[0].type		= rr::GENERICVECTYPE_FLOAT;
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::VertexShader::m_inputs[1].type		= rr::GENERICVECTYPE_FLOAT;
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::VertexShader::m_outputs[0].type		= rr::GENERICVECTYPE_FLOAT;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::VertexShader::m_outputs[0].flatshade	= false;
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::FragmentShader::m_inputs[0].type		= rr::GENERICVECTYPE_FLOAT;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::FragmentShader::m_inputs[0].flatshade	= false;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		this->rr::FragmentShader::m_outputs[0].type		= rr::GENERICVECTYPE_FLOAT;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int positionAttrLoc = 0;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int colorAttrLoc = 1;
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::VertexPacket& packet = *packets[packetNdx];
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Transform to position
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.position = rr::readVertexAttribFloat(inputs[positionAttrLoc], packet.instanceNdx, packet.vertexNdx);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Pass color to FS
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.outputs[VaryingLoc_Color] = rr::readVertexAttribFloat(inputs[colorAttrLoc], packet.instanceNdx, packet.vertexNdx);
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::FragmentPacket& packet = packets[packetNdx];
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, rr::readVarying<float>(packet, context, VaryingLoc_Color, fragNdx));
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid toReferenceRenderState (rr::RenderState& state, const DrawPrimitiveOp& drawOp)
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	state.cullMode	= rr::CULLMODE_NONE;
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (drawOp.blend != BLENDMODE_NONE)
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendMode = rr::BLENDMODE_STANDARD;
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (drawOp.blend)
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case BLENDMODE_ADDITIVE:
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.fragOps.blendRGBState.srcFunc		= rr::BLENDFUNC_ONE;
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.fragOps.blendRGBState.dstFunc		= rr::BLENDFUNC_ONE;
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.fragOps.blendRGBState.equation	= rr::BLENDEQUATION_ADD;
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.fragOps.blendAState				= state.fragOps.blendRGBState;
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case BLENDMODE_SRC_OVER:
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.fragOps.blendRGBState.srcFunc		= rr::BLENDFUNC_SRC_ALPHA;
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.fragOps.blendRGBState.dstFunc		= rr::BLENDFUNC_ONE_MINUS_SRC_ALPHA;
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.fragOps.blendRGBState.equation	= rr::BLENDEQUATION_ADD;
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.fragOps.blendAState				= state.fragOps.blendRGBState;
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (drawOp.depth != DEPTHMODE_NONE)
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.depthTestEnabled = true;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(drawOp.depth == DEPTHMODE_LESS);
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.depthFunc = rr::TESTFUNC_LESS;
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (drawOp.stencil != STENCILMODE_NONE)
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.stencilTestEnabled = true;
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(drawOp.stencil == STENCILMODE_LEQUAL_INC);
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.stencilStates[0].func		= rr::TESTFUNC_LEQUAL;
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.stencilStates[0].sFail	= rr::STENCILOP_KEEP;
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.stencilStates[0].dpFail	= rr::STENCILOP_INCR;
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.stencilStates[0].dpPass	= rr::STENCILOP_INCR;
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.stencilStates[0].ref		= drawOp.stencilRef;
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.stencilStates[1]			= state.fragOps.stencilStates[0];
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::TextureFormat getColorFormat (const tcu::PixelFormat& colorBits)
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using tcu::TextureFormat;
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(colorBits.redBits,	0, 0xff) &&
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  de::inBounds(colorBits.greenBits,	0, 0xff) &&
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  de::inBounds(colorBits.blueBits,	0, 0xff) &&
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  de::inBounds(colorBits.alphaBits,	0, 0xff));
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PACK_FMT(R, G, B, A) (((R) << 24) | ((G) << 16) | ((B) << 8) | (A))
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note [pyry] This may not hold true on some implementations - best effort guess only.
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (PACK_FMT(colorBits.redBits, colorBits.greenBits, colorBits.blueBits, colorBits.alphaBits))
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PACK_FMT(8,8,8,8):		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PACK_FMT(8,8,8,0):		return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT8);
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PACK_FMT(4,4,4,4):		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_4444);
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PACK_FMT(5,5,5,1):		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_5551);
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case PACK_FMT(5,6,5,0):		return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_SHORT_565);
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Defaults to RGBA8
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PACK_FMT
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::TextureFormat getDepthFormat (const int depthBits)
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (depthBits)
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 0:		return tcu::TextureFormat();
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 8:		return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT8);
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 16:	return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 24:	return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8);
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 32:
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:	return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::TextureFormat getStencilFormat (int stencilBits)
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (stencilBits)
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 0:		return tcu::TextureFormat();
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 8:
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:	return tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid renderReference (const tcu::PixelBufferAccess& dst, const vector<DrawPrimitiveOp>& drawOps, const tcu::PixelFormat& colorBits, const int depthBits, const int stencilBits, const int numSamples)
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						width			= dst.getWidth();
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						height			= dst.getHeight();
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureLevel				colorBuffer;
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureLevel				depthBuffer;
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureLevel				stencilBuffer;
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::Renderer					referenceRenderer;
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::VertexAttrib				attributes[2];
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ReferenceShader			shader;
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attributes[0].type				= rr::VERTEXATTRIBTYPE_FLOAT;
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attributes[0].size				= 4;
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attributes[0].stride			= 0;
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attributes[0].instanceDivisor	= 0;
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attributes[1].type				= rr::VERTEXATTRIBTYPE_FLOAT;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attributes[1].size				= 4;
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attributes[1].stride			= 0;
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	attributes[1].instanceDivisor	= 0;
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize buffers.
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	colorBuffer.setStorage(getColorFormat(colorBits), numSamples, width, height);
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::clearMultisampleColorBuffer(colorBuffer, CLEAR_COLOR, rr::WindowRectangle(0, 0, width, height));
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (depthBits > 0)
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		depthBuffer.setStorage(getDepthFormat(depthBits), numSamples, width, height);
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::clearMultisampleDepthBuffer(depthBuffer, CLEAR_DEPTH, rr::WindowRectangle(0, 0, width, height));
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (stencilBits > 0)
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		stencilBuffer.setStorage(getStencilFormat(stencilBits), numSamples, width, height);
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::clearMultisampleStencilBuffer(stencilBuffer, CLEAR_STENCIL, rr::WindowRectangle(0, 0, width, height));
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const rr::RenderTarget renderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(colorBuffer.getAccess()),
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										rr::MultisamplePixelBufferAccess::fromMultisampleAccess(depthBuffer.getAccess()),
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										rr::MultisamplePixelBufferAccess::fromMultisampleAccess(stencilBuffer.getAccess()));
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<DrawPrimitiveOp>::const_iterator drawOp = drawOps.begin(); drawOp != drawOps.end(); drawOp++)
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Translate state
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::RenderState renderState((rr::ViewportState)(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(colorBuffer.getAccess())));
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		toReferenceRenderState(renderState, *drawOp);
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(drawOp->type == PRIMITIVETYPE_TRIANGLE);
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attributes[0].pointer = &drawOp->positions[0];
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		attributes[1].pointer = &drawOp->colors[0];
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		referenceRenderer.draw(
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::DrawCommand(
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				renderState,
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				renderTarget,
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::Program(static_cast<const rr::VertexShader*>(&shader), static_cast<const rr::FragmentShader*>(&shader)),
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				2,
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				attributes,
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, drawOp->count * 3, 0)));
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::resolveMultisampleColorBuffer(dst, rr::MultisamplePixelBufferAccess::fromMultisampleAccess(colorBuffer.getAccess()));
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// API rendering code
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Program
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Program				(void) {}
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual			~Program			(void) {}
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void	setup				(void) const = DE_NULL;
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef de::SharedPtr<Program> ProgramSp;
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DEQP_SUPPORT_GLES2) || defined(DEQP_SUPPORT_GLES3)
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* s_vertexSrc =
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"attribute highp vec4 a_position;\n"
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"attribute mediump vec4 a_color;\n"
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"varying mediump vec4 v_color;\n"
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"void main (void)\n"
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"{\n"
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"	gl_Position = a_position;\n"
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"	v_color = a_color;\n"
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"}\n";
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* s_fragmentSrc =
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"varying mediump vec4 v_color;\n"
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"void main (void)\n"
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"{\n"
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"	gl_FragColor = v_color;\n"
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	"}\n";
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deUint32 createShader (deUint32 shaderType, const char* source)
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 shader = glCreateShader(shaderType);
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glShaderSource(shader, 1, &source, DE_NULL);
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glCompileShader(shader);
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int compileStatus = 0;
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!compileStatus)
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDeleteShader(shader);
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0;
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return shader;
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deUint32 createProgram (deUint32 vertexShader, deUint32 fragmentShader)
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 program = glCreateProgram();
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glAttachShader(program, vertexShader);
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glAttachShader(program, fragmentShader);
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glLinkProgram(program);
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int linkStatus = 0;
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!linkStatus)
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glDeleteProgram(program);
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0;
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return program;
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GLES2Program : public Program
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLES2Program (void)
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_program			(0)
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_vertexShader	(0)
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_fragmentShader	(0)
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_positionLoc		(0)
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_colorLoc		(0)
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexShader		= createShader(GL_VERTEX_SHADER, s_vertexSrc);
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_fragmentShader	= createShader(GL_FRAGMENT_SHADER, s_fragmentSrc);
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_vertexShader || !m_fragmentShader)
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glDeleteShader(m_vertexShader);
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glDeleteShader(m_fragmentShader);
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("Failed to compile shaders");
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_program = createProgram(m_vertexShader, m_fragmentShader);
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_program)
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glDeleteShader(m_vertexShader);
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glDeleteShader(m_fragmentShader);
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("Failed to link program");
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_positionLoc	= glGetAttribLocation(m_program, "a_position");
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_colorLoc		= glGetAttribLocation(m_program, "a_color");
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	~GLES2Program (void)
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void setup (void) const
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glUseProgram(m_program);
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glEnableVertexAttribArray(m_positionLoc);
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glEnableVertexAttribArray(m_colorLoc);
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_MSG("Program setup failed");
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			getPositionLoc		(void) const { return m_positionLoc;	}
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			getColorLoc			(void) const { return m_colorLoc;		}
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	m_program;
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	m_vertexShader;
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32	m_fragmentShader;
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			m_positionLoc;
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			m_colorLoc;
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid clearGLES2 (const tcu::Vec4& color, const float depth, const int stencil)
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClearColor(color.x(), color.y(), color.z(), color.w());
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClearDepthf(depth);
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClearStencil(stencil);
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid drawGLES2 (const Program& program, const DrawPrimitiveOp& drawOp)
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLES2Program& gles2Program = dynamic_cast<const GLES2Program&>(program);
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (drawOp.blend)
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case BLENDMODE_NONE:
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glDisable(GL_BLEND);
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case BLENDMODE_ADDITIVE:
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnable(GL_BLEND);
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glBlendFunc(GL_ONE, GL_ONE);
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case BLENDMODE_SRC_OVER:
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnable(GL_BLEND);
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (drawOp.depth)
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case DEPTHMODE_NONE:
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glDisable(GL_DEPTH_TEST);
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case DEPTHMODE_LESS:
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnable(GL_DEPTH_TEST);
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (drawOp.stencil)
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case STENCILMODE_NONE:
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glDisable(GL_STENCIL_TEST);
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case STENCILMODE_LEQUAL_INC:
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnable(GL_STENCIL_TEST);
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glStencilFunc(GL_LEQUAL, drawOp.stencilRef, ~0u);
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glVertexAttribPointer(gles2Program.getPositionLoc(), 4, GL_FLOAT, GL_FALSE, 0, &drawOp.positions[0]);
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glVertexAttribPointer(gles2Program.getColorLoc(), 4, GL_FLOAT, GL_FALSE, 0, &drawOp.colors[0]);
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(drawOp.type == PRIMITIVETYPE_TRIANGLE);
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDrawArrays(GL_TRIANGLES, 0, drawOp.count*3);
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void readPixelsGLES2 (tcu::Surface& dst)
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glReadPixels(0, 0, dst.getWidth(), dst.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, dst.getAccess().getDataPtr());
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgram* createProgram (EGLint api)
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (api)
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DEQP_SUPPORT_GLES2) || defined(DEQP_SUPPORT_GLES3)
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case EGL_OPENGL_ES2_BIT:		return new GLES2Program();
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case EGL_OPENGL_ES3_BIT_KHR:	return new GLES2Program();
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Unsupported API");
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid draw (EGLint api, const Program& program, const DrawPrimitiveOp& drawOp)
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (api)
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DEQP_SUPPORT_GLES2) || defined(DEQP_SUPPORT_GLES3)
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case EGL_OPENGL_ES2_BIT:		drawGLES2(program, drawOp);		break;
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case EGL_OPENGL_ES3_BIT_KHR:	drawGLES2(program, drawOp);		break;
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Unsupported API");
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid clear (EGLint api, const tcu::Vec4& color, const float depth, const int stencil)
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (api)
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DEQP_SUPPORT_GLES2) || defined(DEQP_SUPPORT_GLES3)
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case EGL_OPENGL_ES2_BIT:		clearGLES2(color, depth, stencil);		break;
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case EGL_OPENGL_ES3_BIT_KHR:	clearGLES2(color, depth, stencil);		break;
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Unsupported API");
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void readPixels (EGLint api, tcu::Surface& dst)
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (api)
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DEQP_SUPPORT_GLES2) || defined(DEQP_SUPPORT_GLES3)
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case EGL_OPENGL_ES2_BIT:		readPixelsGLES2(dst);		break;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case EGL_OPENGL_ES3_BIT_KHR:	readPixelsGLES2(dst);		break;
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Unsupported API");
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::PixelFormat getPixelFormat (const tcu::egl::Display& display, EGLConfig config)
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::PixelFormat fmt;
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	display.describeConfig(config, fmt);
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return fmt;
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// SingleThreadRenderCase
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SingleThreadRenderCase : public MultiContextRenderCase
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						SingleThreadRenderCase		(EglTestContext& eglTestCtx, const char* name, const char* description, EGLint api, EGLint surfaceType, const std::vector<EGLint>& configIds, int numContextsPerApi);
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void		executeForContexts			(tcu::egl::Display& display, tcu::egl::Surface& surface, EGLConfig config, const std::vector<std::pair<EGLint, tcu::egl::Context*> >& contexts);
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// SingleThreadColorClearCase
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6873c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySingleThreadRenderCase::SingleThreadRenderCase (EglTestContext& eglTestCtx, const char* name, const char* description, EGLint api, EGLint surfaceType, const std::vector<EGLint>& configIds, int numContextsPerApi)
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: MultiContextRenderCase(eglTestCtx, name, description, api, surfaceType, configIds, numContextsPerApi)
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SingleThreadRenderCase::executeForContexts (tcu::egl::Display& display, tcu::egl::Surface& surface, EGLConfig config, const std::vector<std::pair<EGLint, tcu::egl::Context*> >& contexts)
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				width		= surface.getWidth();
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				height		= surface.getHeight();
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numContexts	= (int)contexts.size();
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				drawsPerCtx	= 2;
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numIters	= 2;
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float				threshold	= 0.02f;
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::PixelFormat	pixelFmt	= getPixelFormat(display, config);
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				depthBits	= display.getConfigAttrib(config, EGL_DEPTH_SIZE);
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				stencilBits	= display.getConfigAttrib(config, EGL_STENCIL_SIZE);
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numSamples	= display.getConfigAttrib(config, EGL_SAMPLES);
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log			= m_testCtx.getLog();
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			refFrame	(width, height);
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			frame		(width, height);
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rnd			(deStringHash(getName()) ^ deInt32Hash(numContexts));
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ProgramSp>		programs	(contexts.size());
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<DrawPrimitiveOp>	drawOps;
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Log basic information about config.
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_RED_SIZE = "		<< pixelFmt.redBits << TestLog::EndMessage;
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_GREEN_SIZE = "		<< pixelFmt.greenBits << TestLog::EndMessage;
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_BLUE_SIZE = "		<< pixelFmt.blueBits << TestLog::EndMessage;
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_ALPHA_SIZE = "		<< pixelFmt.alphaBits << TestLog::EndMessage;
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_DEPTH_SIZE = "		<< depthBits << TestLog::EndMessage;
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_STENCIL_SIZE = "	<< stencilBits << TestLog::EndMessage;
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_SAMPLES = "			<< numSamples << TestLog::EndMessage;
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate draw ops.
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawOps.resize(numContexts*drawsPerCtx*numIters);
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<DrawPrimitiveOp>::iterator drawOp = drawOps.begin(); drawOp != drawOps.end(); ++drawOp)
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		randomizeDrawOp(rnd, *drawOp);
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create and setup programs per context
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ctxNdx = 0; ctxNdx < numContexts; ctxNdx++)
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGLint				api			= contexts[ctxNdx].first;
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::egl::Context*	context		= contexts[ctxNdx].second;
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		eglMakeCurrent(display.getEGLDisplay(), surface.getEGLSurface(), surface.getEGLSurface(), context->getEGLContext());
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_EGL();
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		programs[ctxNdx] = ProgramSp(createProgram(api));
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		programs[ctxNdx]->setup();
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clear to black using first context.
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGLint				api			= contexts[0].first;
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::egl::Context*	context		= contexts[0].second;
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		eglMakeCurrent(display.getEGLDisplay(), surface.getEGLSurface(), surface.getEGLSurface(), context->getEGLContext());
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_EGL();
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		clear(api, CLEAR_COLOR, CLEAR_DEPTH, CLEAR_STENCIL);
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render.
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int iterNdx = 0; iterNdx < numIters; iterNdx++)
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ctxNdx = 0; ctxNdx < numContexts; ctxNdx++)
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			EGLint				api			= contexts[ctxNdx].first;
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::egl::Context*	context		= contexts[ctxNdx].second;
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			eglMakeCurrent(display.getEGLDisplay(), surface.getEGLSurface(), surface.getEGLSurface(), context->getEGLContext());
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK_EGL();
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int drawNdx = 0; drawNdx < drawsPerCtx; drawNdx++)
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const DrawPrimitiveOp& drawOp = drawOps[iterNdx*numContexts*drawsPerCtx + ctxNdx*drawsPerCtx + drawNdx];
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				draw(api, *programs[ctxNdx], drawOp);
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read pixels using first context. \todo [pyry] Randomize?
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGLint				api		= contexts[0].first;
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::egl::Context*	context	= contexts[0].second;
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		eglMakeCurrent(display.getEGLDisplay(), surface.getEGLSurface(), surface.getEGLSurface(), context->getEGLContext());
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_EGL();
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		readPixels(api, frame);
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render reference.
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Reference image is always generated using single-sampling.
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderReference(refFrame.getAccess(), drawOps, pixelFmt, depthBits, stencilBits, 1);
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare images
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool imagesOk = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refFrame, frame, threshold, tcu::COMPARE_LOG_RESULT);
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!imagesOk)
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// MultiThreadRenderCase
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MultiThreadRenderCase : public MultiContextRenderCase
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						MultiThreadRenderCase		(EglTestContext& eglTestCtx, const char* name, const char* description, EGLint api, EGLint surfaceType, const std::vector<EGLint>& configIds, int numContextsPerApi);
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void		executeForContexts			(tcu::egl::Display& display, tcu::egl::Surface& surface, EGLConfig config, const std::vector<std::pair<EGLint, tcu::egl::Context*> >& contexts);
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass RenderTestThread;
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef de::SharedPtr<RenderTestThread>	RenderTestThreadSp;
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef de::SharedPtr<de::Semaphore>	SemaphoreSp;
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct DrawOpPacket
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DrawOpPacket (void)
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: drawOps	(DE_NULL)
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, numOps	(0)
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const DrawPrimitiveOp*	drawOps;
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						numOps;
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SemaphoreSp				wait;
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SemaphoreSp				signal;
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass RenderTestThread : public de::Thread
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderTestThread (tcu::egl::Display& display, tcu::egl::Surface& surface, tcu::egl::Context& context, EGLint api, const Program& program, const std::vector<DrawOpPacket>& packets)
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_display	(display)
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_surface	(surface)
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_context	(context)
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_api		(api)
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_program	(program)
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_packets	(packets)
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void run (void)
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (std::vector<DrawOpPacket>::const_iterator packetIter = m_packets.begin(); packetIter != m_packets.end(); packetIter++)
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Wait until it is our turn.
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packetIter->wait->decrement();
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Acquire context.
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			eglMakeCurrent(m_display.getEGLDisplay(), m_surface.getEGLSurface(), m_surface.getEGLSurface(), m_context.getEGLContext());
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Execute rendering.
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < packetIter->numOps; ndx++)
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				draw(m_api, m_program, packetIter->drawOps[ndx]);
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Release context.
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			eglMakeCurrent(m_display.getEGLDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Signal completion.
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packetIter->signal->increment();
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::egl::Display&					m_display;
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::egl::Surface&					m_surface;
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::egl::Context&					m_context;
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EGLint								m_api;
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Program&						m_program;
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::vector<DrawOpPacket>&	m_packets;
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMultiThreadRenderCase::MultiThreadRenderCase (EglTestContext& eglTestCtx, const char* name, const char* description, EGLint api, EGLint surfaceType, const std::vector<EGLint>& configIds, int numContextsPerApi)
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: MultiContextRenderCase(eglTestCtx, name, description, api, surfaceType, configIds, numContextsPerApi)
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MultiThreadRenderCase::executeForContexts (tcu::egl::Display& display, tcu::egl::Surface& surface, EGLConfig config, const std::vector<std::pair<EGLint, tcu::egl::Context*> >& contexts)
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				width				= surface.getWidth();
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				height				= surface.getHeight();
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numContexts			= (int)contexts.size();
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				opsPerPacket		= 2;
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				packetsPerThread	= 2;
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numThreads			= numContexts;
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numPackets			= numThreads * packetsPerThread;
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float				threshold			= 0.02f;
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::PixelFormat	pixelFmt			= getPixelFormat(display, config);
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				depthBits			= display.getConfigAttrib(config, EGL_DEPTH_SIZE);
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				stencilBits			= display.getConfigAttrib(config, EGL_STENCIL_SIZE);
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				numSamples			= display.getConfigAttrib(config, EGL_SAMPLES);
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log					= m_testCtx.getLog();
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			refFrame			(width, height);
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface			frame				(width, height);
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rnd					(deStringHash(getName()) ^ deInt32Hash(numContexts));
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Resources that need cleanup
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ProgramSp>				programs	(numContexts);
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<SemaphoreSp>				semaphores	(numPackets+1);
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<DrawPrimitiveOp>			drawOps		(numPackets*opsPerPacket);
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<vector<DrawOpPacket> >	packets		(numThreads);
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<RenderTestThreadSp>		threads		(numThreads);
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Log basic information about config.
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_RED_SIZE = "		<< pixelFmt.redBits << TestLog::EndMessage;
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_GREEN_SIZE = "		<< pixelFmt.greenBits << TestLog::EndMessage;
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_BLUE_SIZE = "		<< pixelFmt.blueBits << TestLog::EndMessage;
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_ALPHA_SIZE = "		<< pixelFmt.alphaBits << TestLog::EndMessage;
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_DEPTH_SIZE = "		<< depthBits << TestLog::EndMessage;
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_STENCIL_SIZE = "	<< stencilBits << TestLog::EndMessage;
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "EGL_SAMPLES = "			<< numSamples << TestLog::EndMessage;
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize semaphores.
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<SemaphoreSp>::iterator sem = semaphores.begin(); sem != semaphores.end(); ++sem)
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*sem = SemaphoreSp(new de::Semaphore(0));
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create draw ops.
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<DrawPrimitiveOp>::iterator drawOp = drawOps.begin(); drawOp != drawOps.end(); ++drawOp)
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		randomizeDrawOp(rnd, *drawOp);
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create packets.
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packets[threadNdx].resize(packetsPerThread);
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int packetNdx = 0; packetNdx < packetsPerThread; packetNdx++)
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DrawOpPacket& packet = packets[threadNdx][packetNdx];
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Threads take turns with packets.
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.wait		= semaphores[packetNdx*numThreads + threadNdx];
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.signal	= semaphores[packetNdx*numThreads + threadNdx + 1];
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.numOps	= opsPerPacket;
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.drawOps	= &drawOps[(packetNdx*numThreads + threadNdx)*opsPerPacket];
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create and setup programs per context
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ctxNdx = 0; ctxNdx < numContexts; ctxNdx++)
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGLint				api			= contexts[ctxNdx].first;
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::egl::Context*	context		= contexts[ctxNdx].second;
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		eglMakeCurrent(display.getEGLDisplay(), surface.getEGLSurface(), surface.getEGLSurface(), context->getEGLContext());
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_EGL();
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		programs[ctxNdx] = ProgramSp(createProgram(api));
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		programs[ctxNdx]->setup();
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Release context
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		eglMakeCurrent(display.getEGLDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clear to black using first context.
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGLint				api			= contexts[0].first;
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::egl::Context*	context		= contexts[0].second;
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		eglMakeCurrent(display.getEGLDisplay(), surface.getEGLSurface(), surface.getEGLSurface(), context->getEGLContext());
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_EGL();
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		clear(api, CLEAR_COLOR, CLEAR_DEPTH, CLEAR_STENCIL);
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Release context
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		eglMakeCurrent(display.getEGLDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create and launch threads (actual rendering starts once first semaphore is signaled).
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threads[threadNdx] = RenderTestThreadSp(new RenderTestThread(display, surface, *contexts[threadNdx].second, contexts[threadNdx].first, *programs[threadNdx], packets[threadNdx]));
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threads[threadNdx]->start();
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Signal start and wait until complete.
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	semaphores.front()->increment();
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	semaphores.back()->decrement();
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read pixels using first context. \todo [pyry] Randomize?
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		EGLint				api		= contexts[0].first;
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::egl::Context*	context	= contexts[0].second;
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		eglMakeCurrent(display.getEGLDisplay(), surface.getEGLSurface(), surface.getEGLSurface(), context->getEGLContext());
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_EGL();
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		readPixels(api, frame);
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Join threads.
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threads[threadNdx]->join();
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render reference.
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderReference(refFrame.getAccess(), drawOps, pixelFmt, depthBits, stencilBits, 1);
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare images
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool imagesOk = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refFrame, frame, threshold, tcu::COMPARE_LOG_RESULT);
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!imagesOk)
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderTests::RenderTests (EglTestContext& eglTestCtx)
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(eglTestCtx, "render", "Basic rendering with different client APIs")
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderTests::~RenderTests (void)
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct RenderGroupSpec
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		name;
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		desc;
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EGLint			apiBits;
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numContextsPerApi;
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class RenderClass>
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void createRenderGroups (EglTestContext& eglTestCtx, tcu::TestCaseGroup* group, const RenderGroupSpec* first, const RenderGroupSpec* last)
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (const RenderGroupSpec* groupIter = first; groupIter != last; groupIter++)
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* configGroup = new tcu::TestCaseGroup(eglTestCtx.getTestContext(), groupIter->name, groupIter->desc);
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		group->addChild(configGroup);
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<RenderConfigIdSet>	configSets;
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		eglu::FilterList			filters;
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		filters << (eglu::ConfigRenderableType() & groupIter->apiBits);
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getDefaultRenderConfigIdSets(configSets, eglTestCtx.getConfigs(), filters);
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<RenderConfigIdSet>::const_iterator setIter = configSets.begin(); setIter != configSets.end(); setIter++)
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			configGroup->addChild(new RenderClass(eglTestCtx, setIter->getName(), "", groupIter->apiBits, setIter->getSurfaceTypeMask(), setIter->getConfigIds(), groupIter->numContextsPerApi));
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid RenderTests::init (void)
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const RenderGroupSpec singleContextCases[] =
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		{ "gles1",			"Primitive rendering using GLES1",												EGL_OPENGL_ES_BIT,										1 },
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "gles2",			"Primitive rendering using GLES2",												EGL_OPENGL_ES2_BIT,										1 },
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "gles3",			"Primitive rendering using GLES3",												EGL_OPENGL_ES3_BIT_KHR,									1 },
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		{ "vg",				"Primitive rendering using OpenVG",												EGL_OPENVG_BIT,											1 }
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const RenderGroupSpec multiContextCases[] =
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		{ "gles1",				"Primitive rendering using multiple GLES1 contexts to shared surface",		EGL_OPENGL_ES_BIT,												3 },
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "gles2",				"Primitive rendering using multiple GLES2 contexts to shared surface",		EGL_OPENGL_ES2_BIT,												3 },
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "gles3",				"Primitive rendering using multiple GLES3 contexts to shared surface",		EGL_OPENGL_ES3_BIT_KHR,											3 },
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		{ "vg",					"Primitive rendering using multiple OpenVG contexts to shared surface",		EGL_OPENVG_BIT,													3 },
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		{ "gles1_gles2",		"Primitive rendering using multiple APIs to shared surface",				EGL_OPENGL_ES_BIT|EGL_OPENGL_ES2_BIT,							1 },
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		{ "gles1_gles2_gles3",	"Primitive rendering using multiple APIs to shared surface",				EGL_OPENGL_ES_BIT|EGL_OPENGL_ES2_BIT|EGL_OPENGL_ES3_BIT_KHR,	1 },
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "gles2_gles3",		"Primitive rendering using multiple APIs to shared surface",				EGL_OPENGL_ES2_BIT|EGL_OPENGL_ES3_BIT_KHR,						1 },
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		{ "gles1_vg",			"Primitive rendering using multiple APIs to shared surface",				EGL_OPENGL_ES_BIT|EGL_OPENVG_BIT,								1 },
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		{ "gles2_vg",			"Primitive rendering using multiple APIs to shared surface",				EGL_OPENGL_ES2_BIT|EGL_OPENVG_BIT,								1 },
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		{ "gles3_vg",			"Primitive rendering using multiple APIs to shared surface",				EGL_OPENGL_ES3_BIT_KHR|EGL_OPENVG_BIT,							1 },
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		{ "gles1_gles2_vg",		"Primitive rendering using multiple APIs to shared surface",				EGL_OPENGL_ES_BIT|EGL_OPENGL_ES2_BIT|EGL_OPENVG_BIT,			1 }
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* singleContextGroup = new tcu::TestCaseGroup(m_testCtx, "single_context", "Single-context rendering");
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(singleContextGroup);
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	createRenderGroups<SingleThreadRenderCase>(m_eglTestCtx, singleContextGroup, &singleContextCases[0], &singleContextCases[DE_LENGTH_OF_ARRAY(singleContextCases)]);
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* multiContextGroup = new tcu::TestCaseGroup(m_testCtx, "multi_context", "Multi-context rendering with shared surface");
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(multiContextGroup);
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	createRenderGroups<SingleThreadRenderCase>(m_eglTestCtx, multiContextGroup, &multiContextCases[0], &multiContextCases[DE_LENGTH_OF_ARRAY(multiContextCases)]);
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* multiThreadGroup = new tcu::TestCaseGroup(m_testCtx, "multi_thread", "Multi-thread rendering with shared surface");
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(multiThreadGroup);
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	createRenderGroups<MultiThreadRenderCase>(m_eglTestCtx, multiThreadGroup, &multiContextCases[0], &multiContextCases[DE_LENGTH_OF_ARRAY(multiContextCases)]);
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // egl
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1082