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
123ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvistatic void finish (EGLint api, const ApiFunctions& func)
124ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi{
125ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi	switch (api)
126ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi	{
127ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi		case EGL_OPENGL_ES_BIT:			gles1::finish();		break;
128ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi		case EGL_OPENGL_ES2_BIT:		gles2::finish(func.gl);	break;
129ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi		case EGL_OPENGL_ES3_BIT_KHR:	gles2::finish(func.gl);	break;
130ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi		case EGL_OPENVG_BIT:			vg::finish();			break;
131ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi		default:
132ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi			DE_ASSERT(DE_FALSE);
133ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi	}
134ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi}
135ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi
1363c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosstatic void readPixels (EGLint api, const ApiFunctions& func, tcu::Surface& dst)
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (api)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1403c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENGL_ES_BIT:			gles1::readPixels	(dst, 0, 0, dst.getWidth(), dst.getHeight());			break;
1413c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENGL_ES2_BIT:		gles2::readPixels	(func.gl, dst, 0, 0, dst.getWidth(), dst.getHeight());	break;
1423c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENGL_ES3_BIT_KHR:	gles2::readPixels	(func.gl, dst, 0, 0, dst.getWidth(), dst.getHeight());	break;
1433c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		case EGL_OPENVG_BIT:			vg::readPixels		(dst, 0, 0, dst.getWidth(), dst.getHeight());			break;
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1493c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosstatic tcu::PixelFormat getPixelFormat (const Library& egl, EGLDisplay display, EGLConfig config)
1503c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos{
1513c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	tcu::PixelFormat pixelFmt;
1523c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1533c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	egl.getConfigAttrib(display, config, EGL_RED_SIZE,		&pixelFmt.redBits);
1543c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	egl.getConfigAttrib(display, config, EGL_GREEN_SIZE,	&pixelFmt.greenBits);
1553c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	egl.getConfigAttrib(display, config, EGL_BLUE_SIZE,		&pixelFmt.blueBits);
1563c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	egl.getConfigAttrib(display, config, EGL_ALPHA_SIZE,	&pixelFmt.alphaBits);
1573c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1583c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	return pixelFmt;
1593c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos}
1603c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// SingleThreadColorClearCase
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry HaulosSingleThreadColorClearCase::SingleThreadColorClearCase (EglTestContext& eglTestCtx, const char* name, const char* description, EGLint api, EGLint surfaceType, const eglu::FilterList& filters, int numContextsPerApi)
1643c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	: MultiContextRenderCase(eglTestCtx, name, description, api, surfaceType, filters, numContextsPerApi)
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosvoid SingleThreadColorClearCase::executeForContexts (EGLDisplay display, EGLSurface surface, const Config& config, const std::vector<std::pair<EGLint, EGLContext> >& contexts)
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1703c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const Library&		egl			= m_eglTestCtx.getLibrary();
1713c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1723c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const tcu::IVec2	surfaceSize	= eglu::getSurfaceSize(egl, display, surface);
1733c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const int			width		= surfaceSize.x();
1743c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const int			height		= surfaceSize.y();
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&			log			= m_testCtx.getLog();
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		refFrame	(width, height);
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		frame		(width, height);
1803c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	tcu::PixelFormat	pixelFmt	= getPixelFormat(egl, display, config.config);
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random			rnd			(deStringHash(getName()));
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ClearOp>		clears;
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			ctxClears	= 2;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			numIters	= 3;
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1873c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	ApiFunctions		funcs;
1883c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
1893c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	m_eglTestCtx.initGLFunctions(&funcs.gl, glu::ApiType::es(2,0));
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clear to black using first context.
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1933c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLint		api			= contexts[0].first;
1943c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLContext	context		= contexts[0].second;
195c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski		ClearOp		clear		(0, 0, width, height, RGBA::black());
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1973c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.makeCurrent(display, surface, surface, context);
1983c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLU_CHECK_MSG(egl, "eglMakeCurrent");
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		renderClear(api, funcs, clear);
201ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi		finish(api, funcs);
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		clears.push_back(clear);
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render.
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int iterNdx = 0; iterNdx < numIters; iterNdx++)
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2083c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		for (vector<std::pair<EGLint, EGLContext> >::const_iterator ctxIter = contexts.begin(); ctxIter != contexts.end(); ctxIter++)
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2103c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			EGLint		api			= ctxIter->first;
2113c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			EGLContext	context		= ctxIter->second;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2133c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			egl.makeCurrent(display, surface, surface, context);
2143c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			EGLU_CHECK_MSG(egl, "eglMakeCurrent");
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int clearNdx = 0; clearNdx < ctxClears; clearNdx++)
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				ClearOp clear = computeRandomClear(rnd, width, height);
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2203c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos				renderClear(api, funcs, clear);
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				clears.push_back(clear);
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
223ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi
224ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi			finish(api, funcs);
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read pixels using first context. \todo [pyry] Randomize?
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2303c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLint		api		= contexts[0].first;
2313c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLContext	context	= contexts[0].second;
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.makeCurrent(display, surface, surface, context);
2343c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLU_CHECK_MSG(egl, "eglMakeCurrent");
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2363c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		readPixels(api, funcs, frame);
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
239d2722f6ec95d6f745a9ee1bfa5f033574b91f235Mika Isojärvi	egl.makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
240d2722f6ec95d6f745a9ee1bfa5f033574b91f235Mika Isojärvi	EGLU_CHECK_MSG(egl, "eglMakeCurrent");
241d2722f6ec95d6f745a9ee1bfa5f033574b91f235Mika Isojärvi
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render reference.
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderReference(refFrame, clears, pixelFmt);
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare images
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2479da1b45a8ed2489a46dd698953d963fa8bfbf1e7Alexander Galazin		tcu::RGBA eps = pixelFmt.alphaBits == 1 ? RGBA(1,1,1,127) : RGBA(1,1,1,1);
2489da1b45a8ed2489a46dd698953d963fa8bfbf1e7Alexander Galazin		bool imagesOk = tcu::pixelThresholdCompare(log, "ComparisonResult", "Image comparison result", refFrame, frame, eps + pixelFmt.getColorThreshold(), tcu::COMPARE_LOG_RESULT);
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!imagesOk)
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// MultiThreadColorClearCase
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	NUM_CLEARS_PER_PACKET	= 2 //!< Number of clears performed in one context activation in one thread.
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ColorClearThread;
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef de::SharedPtr<ColorClearThread>	ColorClearThreadSp;
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef de::SharedPtr<de::Semaphore>	SemaphoreSp;
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ClearPacket
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ClearPacket (void)
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ClearOp			clears[NUM_CLEARS_PER_PACKET];
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SemaphoreSp		wait;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SemaphoreSp		signal;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ColorClearThread : public de::Thread
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2813c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	ColorClearThread (const Library& egl, EGLDisplay display, EGLSurface surface, EGLContext context, EGLint api, const ApiFunctions& funcs, const std::vector<ClearPacket>& packets)
2823c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		: m_egl		(egl)
2833c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		, m_display	(display)
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_surface	(surface)
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_context	(context)
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_api		(api)
2873c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		, m_funcs	(funcs)
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_packets	(packets)
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void run (void)
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (std::vector<ClearPacket>::const_iterator packetIter = m_packets.begin(); packetIter != m_packets.end(); packetIter++)
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Wait until it is our turn.
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packetIter->wait->decrement();
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Acquire context.
3003c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			m_egl.makeCurrent(m_display, m_surface, m_surface, m_context);
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Execute clears.
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(packetIter->clears); ndx++)
3043c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos				renderClear(m_api, m_funcs, packetIter->clears[ndx]);
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
306ba82a431f067d1a30d06db2e754cd48738ad1a3aMika Isojärvi			finish(m_api, m_funcs);
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Release context.
3083c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos			m_egl.makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Signal completion.
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packetIter->signal->increment();
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
313b885fba8c17c03e2000783038dc2e76fe827b099Michael Chock		m_egl.releaseThread();
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
3173c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const Library&					m_egl;
3183c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	EGLDisplay						m_display;
3193c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	EGLSurface						m_surface;
3203c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	EGLContext						m_context;
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EGLint							m_api;
3223c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const ApiFunctions&				m_funcs;
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const std::vector<ClearPacket>&	m_packets;
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3263c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry HaulosMultiThreadColorClearCase::MultiThreadColorClearCase (EglTestContext& eglTestCtx, const char* name, const char* description, EGLint api, EGLint surfaceType, const eglu::FilterList& filters, int numContextsPerApi)
3273c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	: MultiContextRenderCase(eglTestCtx, name, description, api, surfaceType, filters, numContextsPerApi)
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3313c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulosvoid MultiThreadColorClearCase::executeForContexts (EGLDisplay display, EGLSurface surface, const Config& config, const std::vector<std::pair<EGLint, EGLContext> >& contexts)
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3333c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const Library&		egl			= m_eglTestCtx.getLibrary();
3343c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
3353c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const tcu::IVec2	surfaceSize	= eglu::getSurfaceSize(egl, display, surface);
3363c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const int			width		= surfaceSize.x();
3373c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	const int			height		= surfaceSize.y();
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&			log			= m_testCtx.getLog();
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		refFrame	(width, height);
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface		frame		(width, height);
3433c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	tcu::PixelFormat	pixelFmt	= getPixelFormat(egl, display, config.config);
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random			rnd			(deStringHash(getName()));
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3473c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	ApiFunctions		funcs;
3483c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos
3493c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos	m_eglTestCtx.initGLFunctions(&funcs.gl, glu::ApiType::es(2,0));
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create clear packets.
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						numPacketsPerThread		= 2;
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								numThreads				= (int)contexts.size();
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								numPackets				= numThreads * numPacketsPerThread;
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<SemaphoreSp>				semaphores				(numPackets+1);
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<vector<ClearPacket> >	packets					(numThreads);
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ColorClearThreadSp>		threads					(numThreads);
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize semaphores.
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<SemaphoreSp>::iterator sem = semaphores.begin(); sem != semaphores.end(); ++sem)
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*sem = SemaphoreSp(new de::Semaphore(0));
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create packets.
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packets[threadNdx].resize(numPacketsPerThread);
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int packetNdx = 0; packetNdx < numPacketsPerThread; packetNdx++)
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ClearPacket& packet = packets[threadNdx][packetNdx];
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Threads take turns with packets.
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.wait		= semaphores[packetNdx*numThreads + threadNdx];
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			packet.signal	= semaphores[packetNdx*numThreads + threadNdx + 1];
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int clearNdx = 0; clearNdx < DE_LENGTH_OF_ARRAY(packet.clears); clearNdx++)
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// First clear is always full-screen black.
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (threadNdx == 0 && packetNdx == 0 && clearNdx == 0)
381c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski					packet.clears[clearNdx] = ClearOp(0, 0, width, height, RGBA::black());
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					packet.clears[clearNdx] = computeRandomClear(rnd, width, height);
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create and launch threads (actual rendering starts once first semaphore is signaled).
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3913c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		threads[threadNdx] = ColorClearThreadSp(new ColorClearThread(egl, display, surface, contexts[threadNdx].second, contexts[threadNdx].first, funcs, packets[threadNdx]));
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threads[threadNdx]->start();
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Signal start and wait until complete.
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	semaphores.front()->increment();
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	semaphores.back()->decrement();
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read pixels using first context. \todo [pyry] Randomize?
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4013c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLint		api		= contexts[0].first;
4023c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLContext	context	= contexts[0].second;
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4043c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		egl.makeCurrent(display, surface, surface, context);
4053c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		EGLU_CHECK_MSG(egl, "eglMakeCurrent");
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4073c67e4f0ec73f9c30c6b2ed2adfbfe7faaf576a4Pyry Haulos		readPixels(api, funcs, frame);
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
410d2722f6ec95d6f745a9ee1bfa5f033574b91f235Mika Isojärvi	egl.makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
411d2722f6ec95d6f745a9ee1bfa5f033574b91f235Mika Isojärvi	EGLU_CHECK_MSG(egl, "eglMakeCurrent");
412d2722f6ec95d6f745a9ee1bfa5f033574b91f235Mika Isojärvi
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Join threads.
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		threads[threadNdx]->join();
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render reference.
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int packetNdx = 0; packetNdx < numPacketsPerThread; packetNdx++)
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ClearPacket& packet = packets[threadNdx][packetNdx];
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int clearNdx = 0; clearNdx < DE_LENGTH_OF_ARRAY(packet.clears); clearNdx++)
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::PixelBufferAccess access = tcu::getSubregion(refFrame.getAccess(),
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  packet.clears[clearNdx].x, packet.clears[clearNdx].y, 0,
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																  packet.clears[clearNdx].width, packet.clears[clearNdx].height, 1);
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::clear(access, pixelFmt.convertColor(packet.clears[clearNdx].color).toIVec());
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare images
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4359da1b45a8ed2489a46dd698953d963fa8bfbf1e7Alexander Galazin		tcu::RGBA eps = pixelFmt.alphaBits == 1 ? RGBA(1,1,1,127) : RGBA(1,1,1,1);
4369da1b45a8ed2489a46dd698953d963fa8bfbf1e7Alexander Galazin		bool imagesOk = tcu::pixelThresholdCompare(log, "ComparisonResult", "Image comparison result", refFrame, frame, eps + pixelFmt.getColorThreshold(), tcu::COMPARE_LOG_RESULT);
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!imagesOk)
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // egl
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
445