teglColorClearCase.cpp revision 3c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4
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 Color clear case.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "teglColorClearCase.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
263c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos#include "eglwLibrary.hpp"
273c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos#include "eglwEnums.hpp"
283c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos#include "egluUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
343c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos#include "tcuPixelFormat.hpp"
353c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos#include "glwFunctions.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deThread.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSemaphore.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSharedPtr.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "teglGLES1RenderUtil.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "teglGLES2RenderUtil.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "teglVGRenderUtil.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <memory>
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iterator>
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace egl
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
513c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosusing tcu::TestLog;
523c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosusing tcu::RGBA;
533c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosusing std::vector;
543c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosusing namespace eglw;
553c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Utilities.
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ClearOp
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ClearOp (int x_, int y_, int width_, int height_, const tcu::RGBA& color_)
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: x			(x_)
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, y			(y_)
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, width		(width_)
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, height	(height_)
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, color		(color_)
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ClearOp (void)
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: x			(0)
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, y			(0)
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, width		(0)
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, height	(0)
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, color		(0)
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			width;
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			height;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::RGBA	color;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosstruct ApiFunctions
863c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos{
873c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	glw::Functions	gl;
883c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos};
893c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ClearOp computeRandomClear (de::Random& rnd, int width, int height)
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			w		= rnd.getInt(1, width);
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			h		= rnd.getInt(1, height);
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			x		= rnd.getInt(0, width-w);
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			y		= rnd.getInt(0, height-h);
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::RGBA	col		(rnd.getUint32());
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ClearOp(x, y, w, h, col);
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void renderReference (tcu::Surface& dst, const vector<ClearOp>& clears, const tcu::PixelFormat& pixelFormat)
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<ClearOp>::const_iterator clearIter = clears.begin(); clearIter != clears.end(); clearIter++)
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::PixelBufferAccess access = tcu::getSubregion(dst.getAccess(), clearIter->x, clearIter->y, 0, clearIter->width, clearIter->height, 1);
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::clear(access, pixelFormat.convertColor(clearIter->color).toIVec());
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosstatic void renderClear (EGLint api, const ApiFunctions& func, const ClearOp& clear)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (api)
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1143c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENGL_ES_BIT:			gles1::clear(clear.x, clear.y, clear.width, clear.height, clear.color.toVec());				break;
1153c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENGL_ES2_BIT:		gles2::clear(func.gl, clear.x, clear.y, clear.width, clear.height, clear.color.toVec());	break;
1163c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENGL_ES3_BIT_KHR:	gles2::clear(func.gl, clear.x, clear.y, clear.width, clear.height, clear.color.toVec());	break;
1173c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENVG_BIT:			vg::clear	(clear.x, clear.y, clear.width, clear.height, clear.color.toVec());				break;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1233c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosstatic void readPixels (EGLint api, const ApiFunctions& func, tcu::Surface& dst)
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (api)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1273c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENGL_ES_BIT:			gles1::readPixels	(dst, 0, 0, dst.getWidth(), dst.getHeight());			break;
1283c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENGL_ES2_BIT:		gles2::readPixels	(func.gl, dst, 0, 0, dst.getWidth(), dst.getHeight());	break;
1293c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENGL_ES3_BIT_KHR:	gles2::readPixels	(func.gl, dst, 0, 0, dst.getWidth(), dst.getHeight());	break;
1303c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENVG_BIT:			vg::readPixels		(dst, 0, 0, dst.getWidth(), dst.getHeight());			break;
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1363c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosstatic tcu::PixelFormat getPixelFormat (const Library& egl, EGLDisplay display, EGLConfig config)
1373c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos{
1383c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	tcu::PixelFormat pixelFmt;
1393c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1403c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	egl.getConfigAttrib(display, config, EGL_RED_SIZE,		&pixelFmt.redBits);
1413c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	egl.getConfigAttrib(display, config, EGL_GREEN_SIZE,	&pixelFmt.greenBits);
1423c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	egl.getConfigAttrib(display, config, EGL_BLUE_SIZE,		&pixelFmt.blueBits);
1433c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	egl.getConfigAttrib(display, config, EGL_ALPHA_SIZE,	&pixelFmt.alphaBits);
1443c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1453c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	return pixelFmt;
1463c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos}
1473c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// SingleThreadColorClearCase
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry HaulosSingleThreadColorClearCase::SingleThreadColorClearCase (EglTestContext& eglTestCtx, const char* name, const char* description, EGLint api, EGLint surfaceType, const eglu::FilterList& filters, int numContextsPerApi)
1513c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	: MultiContextRenderCase(eglTestCtx, name, description, api, surfaceType, filters, numContextsPerApi)
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1553c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosvoid SingleThreadColorClearCase::executeForContexts (EGLDisplay display, EGLSurface surface, const Config& config, const std::vector<std::pair<EGLint, EGLContext> >& contexts)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1573c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const Library&		egl			= m_eglTestCtx.getLibrary();
1583c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1593c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const tcu::IVec2	surfaceSize	= eglu::getSurfaceSize(egl, display, surface);
1603c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const int			width		= surfaceSize.x();
1613c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const int			height		= surfaceSize.y();
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&			log			= m_testCtx.getLog();
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		refFrame	(width, height);
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		frame		(width, height);
1673c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	tcu::PixelFormat	pixelFmt	= getPixelFormat(egl, display, config.config);
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random			rnd			(deStringHash(getName()));
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ClearOp>		clears;
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			ctxClears	= 2;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			numIters	= 3;
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1743c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	ApiFunctions		funcs;
1753c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1763c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	m_eglTestCtx.initGLFunctions(&funcs.gl, glu::ApiType::es(2,0));
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clear to black using first context.
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1803c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLint		api			= contexts[0].first;
1813c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLContext	context		= contexts[0].second;
1823c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		ClearOp		clear		(0, 0, width, height, RGBA::black);
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.makeCurrent(display, surface, surface, context);
1853c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLU_CHECK_MSG(egl, "eglMakeCurrent");
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1873c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		renderClear(api, funcs, clear);
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		clears.push_back(clear);
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render.
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int iterNdx = 0; iterNdx < numIters; iterNdx++)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1943c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		for (vector<std::pair<EGLint, EGLContext> >::const_iterator ctxIter = contexts.begin(); ctxIter != contexts.end(); ctxIter++)
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1963c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			EGLint		api			= ctxIter->first;
1973c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			EGLContext	context		= ctxIter->second;
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			egl.makeCurrent(display, surface, surface, context);
2003c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			EGLU_CHECK_MSG(egl, "eglMakeCurrent");
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int clearNdx = 0; clearNdx < ctxClears; clearNdx++)
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ClearOp clear = computeRandomClear(rnd, width, height);
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos				renderClear(api, funcs, clear);
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				clears.push_back(clear);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read pixels using first context. \todo [pyry] Randomize?
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2143c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLint		api		= contexts[0].first;
2153c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLContext	context	= contexts[0].second;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2173c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.makeCurrent(display, surface, surface, context);
2183c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLU_CHECK_MSG(egl, "eglMakeCurrent");
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2203c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		readPixels(api, funcs, frame);
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render reference.
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderReference(refFrame, clears, pixelFmt);
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare images
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool imagesOk = tcu::pixelThresholdCompare(log, "ComparisonResult", "Image comparison result", refFrame, frame, RGBA(1,1,1,1) + pixelFmt.getColorThreshold(), tcu::COMPARE_LOG_RESULT);
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!imagesOk)
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// MultiThreadColorClearCase
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	NUM_CLEARS_PER_PACKET	= 2 //!< Number of clears performed in one context activation in one thread.
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ColorClearThread;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef de::SharedPtr<ColorClearThread>	ColorClearThreadSp;
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef de::SharedPtr<de::Semaphore>	SemaphoreSp;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ClearPacket
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ClearPacket (void)
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ClearOp			clears[NUM_CLEARS_PER_PACKET];
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SemaphoreSp		wait;
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SemaphoreSp		signal;
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ColorClearThread : public de::Thread
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2613c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	ColorClearThread (const Library& egl, EGLDisplay display, EGLSurface surface, EGLContext context, EGLint api, const ApiFunctions& funcs, const std::vector<ClearPacket>& packets)
2623c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		: m_egl		(egl)
2633c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		, m_display	(display)
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_surface	(surface)
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_context	(context)
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_api		(api)
2673c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		, m_funcs	(funcs)
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_packets	(packets)
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void run (void)
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (std::vector<ClearPacket>::const_iterator packetIter = m_packets.begin(); packetIter != m_packets.end(); packetIter++)
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Wait until it is our turn.
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packetIter->wait->decrement();
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Acquire context.
2803c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			m_egl.makeCurrent(m_display, m_surface, m_surface, m_context);
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Execute clears.
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(packetIter->clears); ndx++)
2843c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos				renderClear(m_api, m_funcs, packetIter->clears[ndx]);
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Release context.
2873c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			m_egl.makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Signal completion.
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packetIter->signal->increment();
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2953c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const Library&					m_egl;
2963c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	EGLDisplay						m_display;
2973c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	EGLSurface						m_surface;
2983c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	EGLContext						m_context;
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EGLint							m_api;
3003c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const ApiFunctions&				m_funcs;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::vector<ClearPacket>&	m_packets;
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3043c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry HaulosMultiThreadColorClearCase::MultiThreadColorClearCase (EglTestContext& eglTestCtx, const char* name, const char* description, EGLint api, EGLint surfaceType, const eglu::FilterList& filters, int numContextsPerApi)
3053c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	: MultiContextRenderCase(eglTestCtx, name, description, api, surfaceType, filters, numContextsPerApi)
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosvoid MultiThreadColorClearCase::executeForContexts (EGLDisplay display, EGLSurface surface, const Config& config, const std::vector<std::pair<EGLint, EGLContext> >& contexts)
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3113c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const Library&		egl			= m_eglTestCtx.getLibrary();
3123c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
3133c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const tcu::IVec2	surfaceSize	= eglu::getSurfaceSize(egl, display, surface);
3143c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const int			width		= surfaceSize.x();
3153c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const int			height		= surfaceSize.y();
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&			log			= m_testCtx.getLog();
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		refFrame	(width, height);
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		frame		(width, height);
3213c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	tcu::PixelFormat	pixelFmt	= getPixelFormat(egl, display, config.config);
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random			rnd			(deStringHash(getName()));
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3253c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	ApiFunctions		funcs;
3263c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
3273c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	m_eglTestCtx.initGLFunctions(&funcs.gl, glu::ApiType::es(2,0));
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create clear packets.
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numPacketsPerThread		= 2;
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								numThreads				= (int)contexts.size();
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								numPackets				= numThreads * numPacketsPerThread;
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<SemaphoreSp>				semaphores				(numPackets+1);
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<vector<ClearPacket> >	packets					(numThreads);
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ColorClearThreadSp>		threads					(numThreads);
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize semaphores.
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<SemaphoreSp>::iterator sem = semaphores.begin(); sem != semaphores.end(); ++sem)
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*sem = SemaphoreSp(new de::Semaphore(0));
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create packets.
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packets[threadNdx].resize(numPacketsPerThread);
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int packetNdx = 0; packetNdx < numPacketsPerThread; packetNdx++)
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ClearPacket& packet = packets[threadNdx][packetNdx];
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Threads take turns with packets.
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.wait		= semaphores[packetNdx*numThreads + threadNdx];
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.signal	= semaphores[packetNdx*numThreads + threadNdx + 1];
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int clearNdx = 0; clearNdx < DE_LENGTH_OF_ARRAY(packet.clears); clearNdx++)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// First clear is always full-screen black.
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (threadNdx == 0 && packetNdx == 0 && clearNdx == 0)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					packet.clears[clearNdx] = ClearOp(0, 0, width, height, RGBA::black);
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					packet.clears[clearNdx] = computeRandomClear(rnd, width, height);
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create and launch threads (actual rendering starts once first semaphore is signaled).
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3693c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		threads[threadNdx] = ColorClearThreadSp(new ColorClearThread(egl, display, surface, contexts[threadNdx].second, contexts[threadNdx].first, funcs, packets[threadNdx]));
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threads[threadNdx]->start();
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Signal start and wait until complete.
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	semaphores.front()->increment();
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	semaphores.back()->decrement();
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read pixels using first context. \todo [pyry] Randomize?
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3793c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLint		api		= contexts[0].first;
3803c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLContext	context	= contexts[0].second;
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.makeCurrent(display, surface, surface, context);
3833c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLU_CHECK_MSG(egl, "eglMakeCurrent");
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3853c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		readPixels(api, funcs, frame);
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Join threads.
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threads[threadNdx]->join();
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render reference.
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int packetNdx = 0; packetNdx < numPacketsPerThread; packetNdx++)
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ClearPacket& packet = packets[threadNdx][packetNdx];
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int clearNdx = 0; clearNdx < DE_LENGTH_OF_ARRAY(packet.clears); clearNdx++)
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::PixelBufferAccess access = tcu::getSubregion(refFrame.getAccess(),
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  packet.clears[clearNdx].x, packet.clears[clearNdx].y, 0,
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  packet.clears[clearNdx].width, packet.clears[clearNdx].height, 1);
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::clear(access, pixelFmt.convertColor(packet.clears[clearNdx].color).toIVec());
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare images
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool imagesOk = tcu::pixelThresholdCompare(log, "ComparisonResult", "Image comparison result", refFrame, frame, RGBA(1,1,1,1) + pixelFmt.getColorThreshold(), tcu::COMPARE_LOG_RESULT);
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!imagesOk)
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // egl
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
419