Home | History | Annotate | Download | only in egl
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program EGL Module
      3  * ---------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief EGL gles2 sharing threaded tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "teglGLES2SharingThreadedTests.hpp"
     25 
     26 #include "tcuTestLog.hpp"
     27 
     28 #include "deRandom.hpp"
     29 #include "deThread.hpp"
     30 #include "deSharedPtr.hpp"
     31 #include "deMutex.hpp"
     32 #include "deSemaphore.hpp"
     33 #include "deStringUtil.hpp"
     34 
     35 #include "deClock.h"
     36 #include "deString.h"
     37 #include "deMemory.h"
     38 #include "deMath.h"
     39 
     40 #include "gluDefs.hpp"
     41 
     42 #include "tcuThreadUtil.hpp"
     43 
     44 #include <GLES2/gl2.h>
     45 #include <GLES2/gl2ext.h>
     46 #include <EGL/egl.h>
     47 #include <EGL/eglext.h>
     48 
     49 #ifndef EGL_KHR_wait_sync
     50 #define EGL_KHR_wait_sync 1
     51 typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
     52 #ifdef EGL_EGLEXT_PROTOTYPES
     53 EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
     54 #endif
     55 #endif /* EGL_KHR_wait_sync */
     56 
     57 #include <vector>
     58 #include <string>
     59 #include <memory>
     60 #include <sstream>
     61 
     62 using std::vector;
     63 using std::string;
     64 using de::SharedPtr;
     65 
     66 namespace deqp
     67 {
     68 namespace egl
     69 {
     70 
     71 namespace GLES2ThreadTest
     72 {
     73 
     74 class Texture;
     75 class Buffer;
     76 class Shader;
     77 class Program;
     78 class GLES2ResourceManager
     79 {
     80 public:
     81 
     82 	SharedPtr<Texture>			popTexture			(int index);
     83 	const SharedPtr<Texture>	getTexture			(int index) const { return m_textures[index]; }
     84 	void						addTexture			(SharedPtr<Texture> texture) { m_textures.push_back(texture); }
     85 	int							getTextureCount		(void) const { return (int)m_textures.size(); }
     86 
     87 	SharedPtr<Buffer>			popBuffer			(int index);
     88 	const SharedPtr<Buffer>		getBuffer			(int index) const { return m_buffers[index]; }
     89 	void						addBuffer			(SharedPtr<Buffer> buffer) { m_buffers.push_back(buffer); }
     90 	int							getBufferCount		(void) const { return (int)m_buffers.size(); }
     91 
     92 	SharedPtr<Shader>			popShader			(int index);
     93 	const SharedPtr<Shader>		getShader			(int index) const { return m_shaders[index]; }
     94 	void						addShader			(SharedPtr<Shader> shader) { m_shaders.push_back(shader); }
     95 	int							getShaderCount		(void) const { return (int)m_shaders.size(); }
     96 
     97 	SharedPtr<Program>			popProgram			(int index);
     98 	const SharedPtr<Program>	getProgram			(int index) const { return m_programs[index]; }
     99 	void						addProgram			(SharedPtr<Program> program) { m_programs.push_back(program); }
    100 	int							getProgramCount		(void) const { return (int)m_programs.size(); }
    101 
    102 private:
    103 	std::vector<SharedPtr<Texture> >	m_textures;
    104 	std::vector<SharedPtr<Buffer> >		m_buffers;
    105 	std::vector<SharedPtr<Shader> >		m_shaders;
    106 	std::vector<SharedPtr<Program> >	m_programs;
    107 };
    108 
    109 SharedPtr<Texture> GLES2ResourceManager::popTexture (int index)
    110 {
    111 	SharedPtr<Texture> texture = m_textures[index];
    112 
    113 	m_textures.erase(m_textures.begin() + index);
    114 
    115 	return texture;
    116 }
    117 
    118 SharedPtr<Buffer> GLES2ResourceManager::popBuffer (int index)
    119 {
    120 	SharedPtr<Buffer> buffer = m_buffers[index];
    121 
    122 	m_buffers.erase(m_buffers.begin() + index);
    123 
    124 	return buffer;
    125 }
    126 
    127 SharedPtr<Shader> GLES2ResourceManager::popShader (int index)
    128 {
    129 	SharedPtr<Shader> shader = m_shaders[index];
    130 
    131 	m_shaders.erase(m_shaders.begin() + index);
    132 
    133 	return shader;
    134 }
    135 
    136 SharedPtr<Program> GLES2ResourceManager::popProgram (int index)
    137 {
    138 	SharedPtr<Program> program = m_programs[index];
    139 
    140 	m_programs.erase(m_programs.begin() + index);
    141 
    142 	return program;
    143 }
    144 
    145 class GLES2Context : public tcu::ThreadUtil::Object
    146 {
    147 public:
    148 				GLES2Context		(SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<GLES2ResourceManager> resourceManager);
    149 				~GLES2Context		(void);
    150 
    151 	// Call generation time attributes
    152 	SharedPtr<GLES2ResourceManager>	resourceManager;
    153 
    154 	// Run time attributes
    155 	EGLDisplay		display;
    156 	EGLContext		context;
    157 
    158 	struct
    159 	{
    160 		PFNGLEGLIMAGETARGETTEXTURE2DOESPROC	imageTargetTexture2D;
    161 	} glExtensions;
    162 private:
    163 					GLES2Context		(const GLES2Context&);
    164 	GLES2Context&	operator=			(const GLES2Context&);
    165 };
    166 
    167 GLES2Context::GLES2Context (SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<GLES2ResourceManager> resourceManager_)
    168 	: tcu::ThreadUtil::Object	("Context", event)
    169 	, resourceManager			(resourceManager_)
    170 	, display					(EGL_NO_DISPLAY)
    171 	, context					(EGL_NO_CONTEXT)
    172 {
    173 	glExtensions.imageTargetTexture2D = NULL;
    174 }
    175 
    176 GLES2Context::~GLES2Context (void)
    177 {
    178 }
    179 
    180 class Surface : public tcu::ThreadUtil::Object
    181 {
    182 public:
    183 				Surface		(SharedPtr<tcu::ThreadUtil::Event> event);
    184 				~Surface	(void);
    185 
    186 	// Run time attributes
    187 	EGLSurface	surface;
    188 
    189 private:
    190 	Surface		(const Surface&);
    191 	Surface&	operator=	(const Surface&);
    192 };
    193 
    194 Surface::Surface (SharedPtr<tcu::ThreadUtil::Event> event)
    195 	: tcu::ThreadUtil::Object	("Surface", event)
    196 	, surface					(EGL_NO_SURFACE)
    197 {
    198 }
    199 
    200 Surface::~Surface (void)
    201 {
    202 }
    203 
    204 // EGL thread with thread specifig state
    205 class EGLThread : public tcu::ThreadUtil::Thread
    206 {
    207 public:
    208 								EGLThread	(int seed);
    209 								~EGLThread	(void);
    210 	virtual void				deinit		(void);
    211 
    212 	// Generation time attributes
    213 	SharedPtr<GLES2Context>		context;
    214 	SharedPtr<Surface>			surface;
    215 
    216 	// Runtime attributes
    217 
    218 	SharedPtr<GLES2Context>		runtimeContext;
    219 	EGLSurface					eglSurface;
    220 
    221 	struct
    222 	{
    223 		PFNEGLCREATESYNCKHRPROC		createSync;
    224 		PFNEGLDESTROYSYNCKHRPROC	destroySync;
    225 		PFNEGLCLIENTWAITSYNCKHRPROC	clientWaitSync;
    226 
    227 		PFNEGLWAITSYNCKHRPROC		waitSync;
    228 
    229 		PFNEGLCREATEIMAGEKHRPROC	createImage;
    230 		PFNEGLDESTROYIMAGEKHRPROC	destroyImage;
    231 	} eglExtensions;
    232 
    233 private:
    234 };
    235 
    236 EGLThread::EGLThread (int seed)
    237 	: tcu::ThreadUtil::Thread	(seed)
    238 	, eglSurface				(EGL_NO_SURFACE)
    239 {
    240 	eglExtensions.createSync		= NULL;
    241 	eglExtensions.destroySync		= NULL;
    242 	eglExtensions.clientWaitSync	= NULL;
    243 
    244 	eglExtensions.createImage		= NULL;
    245 	eglExtensions.destroyImage		= NULL;
    246 
    247 	eglExtensions.createSync		= (PFNEGLCREATESYNCKHRPROC)eglGetProcAddress("eglCreateSyncKHR");
    248 	eglExtensions.destroySync		= (PFNEGLDESTROYSYNCKHRPROC)eglGetProcAddress("eglDestroySyncKHR");
    249 	eglExtensions.clientWaitSync	= (PFNEGLCLIENTWAITSYNCKHRPROC)eglGetProcAddress("eglClientWaitSyncKHR");
    250 
    251 	eglExtensions.waitSync			= (PFNEGLWAITSYNCKHRPROC)eglGetProcAddress("eglWaitSyncKHR");
    252 
    253 	eglExtensions.createImage		= (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR");
    254 	eglExtensions.destroyImage		= (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR");
    255 }
    256 
    257 void EGLThread::deinit (void)
    258 {
    259 	if (runtimeContext)
    260 	{
    261 		if (runtimeContext->context != EGL_NO_CONTEXT)
    262 			eglMakeCurrent(runtimeContext->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    263 
    264 		eglDestroyContext(runtimeContext->display, runtimeContext->context);
    265 		eglDestroySurface(runtimeContext->display, eglSurface);
    266 
    267 		runtimeContext->context	= EGL_NO_CONTEXT;
    268 		eglSurface	= EGL_NO_SURFACE;
    269 	}
    270 
    271 	eglReleaseThread();
    272 }
    273 
    274 EGLThread::~EGLThread (void)
    275 {
    276 }
    277 
    278 class FenceSync
    279 {
    280 public:
    281 				FenceSync	(void);
    282 				~FenceSync	(void);
    283 
    284 	void		init		(EGLThread& thread, bool serverSync);
    285 	bool		waitReady	(EGLThread& thread);
    286 
    287 	void		addWaiter	(void);
    288 
    289 private:
    290 	EGLDisplay	m_display;
    291 	EGLSyncKHR	m_sync;
    292 	de::Mutex	m_lock;
    293 	int			m_waiterCount;
    294 	bool		m_serverSync;
    295 };
    296 
    297 FenceSync::FenceSync (void)
    298 	: m_display		(EGL_NO_DISPLAY)
    299 	, m_sync		(NULL)
    300 	, m_waiterCount	(0)
    301 	, m_serverSync	(false)
    302 {
    303 }
    304 
    305 FenceSync::~FenceSync (void)
    306 {
    307 }
    308 
    309 void FenceSync::addWaiter (void)
    310 {
    311 	m_lock.lock();
    312 	m_waiterCount++;
    313 	m_lock.unlock();
    314 }
    315 
    316 void FenceSync::init (EGLThread& thread, bool serverSync)
    317 {
    318 	m_display		= thread.runtimeContext->display;
    319 	m_serverSync	= serverSync;
    320 
    321 	// Use sync only if somebody will actualy depend on it
    322 	m_lock.lock();
    323 	if (m_waiterCount > 0)
    324 	{
    325 		thread.newMessage() << "Begin -- eglCreateSyncKHR(" << ((size_t)m_display) << ", EGL_SYNC_FENCE_KHR, NULL)" << tcu::ThreadUtil::Message::End;
    326 		m_sync = thread.eglExtensions.createSync(m_display, EGL_SYNC_FENCE_KHR, NULL);
    327 		thread.newMessage() << "End -- " << ((size_t)m_sync) << " = eglCreateSyncKHR()" << tcu::ThreadUtil::Message::End;
    328 		TCU_CHECK(m_sync);
    329 	}
    330 	m_lock.unlock();
    331 }
    332 
    333 bool FenceSync::waitReady (EGLThread& thread)
    334 {
    335 	bool ok = true;
    336 	if (m_serverSync)
    337 	{
    338 		thread.newMessage() << "Begin -- eglWaitSyncKHR(" << ((size_t)m_display) << ", " << ((size_t)m_sync) << ", 0)" << tcu::ThreadUtil::Message::End;
    339 		EGLint result = thread.eglExtensions.waitSync(m_display, m_sync, 0);
    340 		thread.newMessage() << "End -- " << result << " = eglWaitSyncKHR()" << tcu::ThreadUtil::Message::End;
    341 		ok = result == EGL_TRUE;
    342 	}
    343 	else
    344 	{
    345 		thread.newMessage() << "Begin -- eglClientWaitSyncKHR(" << ((size_t)m_display) << ", " << ((size_t)m_sync) << ", EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 1000 000 000)" << tcu::ThreadUtil::Message::End;
    346 		EGLint result = thread.eglExtensions.clientWaitSync(m_display, m_sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 1000000000);
    347 		thread.newMessage() << "End -- " << result << " = eglClientWaitSyncKHR()" << tcu::ThreadUtil::Message::End;
    348 		ok = result == EGL_CONDITION_SATISFIED_KHR;
    349 	}
    350 
    351 	m_lock.lock();
    352 	m_waiterCount--;
    353 	DE_ASSERT(m_waiterCount >= 0);
    354 
    355 	if (m_waiterCount == 0)
    356 	{
    357 		// \note [mika] This is no longer deterministic and eglDestroySyncKHR might happen in different places and in different threads
    358 		thread.newMessage() << "Begin -- eglDestroySyncKHR(" << ((size_t)m_display) << ", " << ((size_t)m_sync) << ")" << tcu::ThreadUtil::Message::End;
    359 		EGLint destroyResult = thread.eglExtensions.destroySync(m_display, m_sync);
    360 		thread.newMessage() << "End -- " << destroyResult << " = eglDestroySyncKHR()" << tcu::ThreadUtil::Message::End;
    361 		m_sync = NULL;
    362 	}
    363 
    364 	m_lock.unlock();
    365 
    366 	return ok;
    367 }
    368 
    369 class Object : public tcu::ThreadUtil::Object
    370 {
    371 public:
    372 							Object			(const char* type, SharedPtr<tcu::ThreadUtil::Event> e, SharedPtr<FenceSync> sync);
    373 							~Object			(void);
    374 
    375 	void					readGL			(SharedPtr<FenceSync> sync, std::vector<SharedPtr<FenceSync> >& deps);
    376 	void					modifyGL		(SharedPtr<FenceSync> sync, std::vector<SharedPtr<FenceSync> >& deps);
    377 
    378 private:
    379 	SharedPtr<FenceSync>			m_modifySync;
    380 	vector<SharedPtr<FenceSync> >	m_readSyncs;
    381 };
    382 
    383 Object::Object (const char* type, SharedPtr<tcu::ThreadUtil::Event> e, SharedPtr<FenceSync> sync)
    384 	: tcu::ThreadUtil::Object	(type, e)
    385 	, m_modifySync				(sync)
    386 {
    387 }
    388 
    389 Object::~Object	(void)
    390 {
    391 }
    392 
    393 void Object::readGL (SharedPtr<FenceSync> sync, std::vector<SharedPtr<FenceSync> >& deps)
    394 {
    395 	if (m_modifySync)
    396 		m_modifySync->addWaiter();
    397 
    398 	// Make call depend on last modifying call
    399 	deps.push_back(m_modifySync);
    400 
    401 	// Add read dependency
    402 	m_readSyncs.push_back(sync);
    403 }
    404 
    405 void Object::modifyGL (SharedPtr<FenceSync> sync, std::vector<SharedPtr<FenceSync> >& deps)
    406 {
    407 	// Make call depend on all reads
    408 	for (int readNdx = 0; readNdx < (int)m_readSyncs.size(); readNdx++)
    409 	{
    410 		if (m_readSyncs[readNdx])
    411 			m_readSyncs[readNdx]->addWaiter();
    412 
    413 		deps.push_back(m_readSyncs[readNdx]);
    414 	}
    415 
    416 	if (m_modifySync)
    417 		m_modifySync->addWaiter();
    418 
    419 	deps.push_back(m_modifySync);
    420 
    421 	// Update last modifying call
    422 	m_modifySync = sync;
    423 
    424 	// Clear read dependencies of last "version" of this object
    425 	m_readSyncs.clear();
    426 }
    427 
    428 class Operation : public tcu::ThreadUtil::Operation
    429 {
    430 public:
    431 							Operation		(const char* name, bool useSync, bool serverSync);
    432 	virtual					~Operation		(void);
    433 
    434 	SharedPtr<FenceSync>	getSync			(void) { return m_sync; }
    435 	void					readGLObject	(SharedPtr<Object> object);
    436 	void					modifyGLObject	(SharedPtr<Object> object);
    437 
    438 	virtual void			execute			(tcu::ThreadUtil::Thread& thread);
    439 
    440 private:
    441 	bool								m_useSync;
    442 	bool								m_serverSync;
    443 	std::vector<SharedPtr<FenceSync> >	m_syncDeps;
    444 	SharedPtr<FenceSync>				m_sync;
    445 };
    446 
    447 Operation::Operation (const char* name, bool useSync, bool serverSync)
    448 	: tcu::ThreadUtil::Operation	(name)
    449 	, m_useSync						(useSync)
    450 	, m_serverSync					(serverSync)
    451 	, m_sync						(useSync ? SharedPtr<FenceSync>(new FenceSync()) : SharedPtr<FenceSync>())
    452 {
    453 }
    454 
    455 Operation::~Operation (void)
    456 {
    457 }
    458 
    459 void Operation::readGLObject (SharedPtr<Object> object)
    460 {
    461 	object->read(m_event, m_deps);
    462 	object->readGL(m_sync, m_syncDeps);
    463 }
    464 
    465 void Operation::modifyGLObject (SharedPtr<Object> object)
    466 {
    467 	object->modify(m_event, m_deps);
    468 	object->modifyGL(m_sync, m_syncDeps);
    469 }
    470 
    471 void Operation::execute (tcu::ThreadUtil::Thread& thread)
    472 {
    473 	bool success = true;
    474 
    475 	// Wait for dependencies and check that they succeeded
    476 	for (int depNdx = 0; depNdx < (int)m_deps.size(); depNdx++)
    477 	{
    478 		if (!m_deps[depNdx]->waitReady())
    479 			success = false;
    480 	}
    481 
    482 	// Try execute operation
    483 	if (success)
    484 	{
    485 		try
    486 		{
    487 			if (m_useSync)
    488 			{
    489 				for (int depNdx = 0; depNdx < (int)m_syncDeps.size(); depNdx++)
    490 				{
    491 					EGLThread* eglThread = dynamic_cast<EGLThread*>(&thread);
    492 					DE_ASSERT(eglThread);
    493 					if (m_syncDeps[depNdx]->waitReady(*eglThread) != tcu::ThreadUtil::Event::RESULT_OK)
    494 					{
    495 						success = false;
    496 						break;
    497 					}
    498 				}
    499 			}
    500 
    501 			if (success)
    502 			{
    503 				exec(thread);
    504 				if (m_useSync)
    505 				{
    506 					EGLThread* eglThread = dynamic_cast<EGLThread*>(&thread);
    507 					DE_ASSERT(eglThread);
    508 					m_sync->init(*eglThread, m_serverSync);
    509 					thread.newMessage() << "Begin -- glFlush()" << tcu::ThreadUtil::Message::End;
    510 					GLU_CHECK_CALL(glFlush());
    511 					thread.newMessage() << "End -- glFlush()" << tcu::ThreadUtil::Message::End;
    512 				}
    513 				else
    514 				{
    515 					thread.newMessage() << "Begin -- glFinish()" << tcu::ThreadUtil::Message::End;
    516 					GLU_CHECK_CALL(glFinish());
    517 					thread.newMessage() << "End -- glFinish()" << tcu::ThreadUtil::Message::End;
    518 				}
    519 			}
    520 		}
    521 		catch (...)
    522 		{
    523 			// Got exception event failed
    524 			m_event->setResult(tcu::ThreadUtil::Event::RESULT_FAILED);
    525 			throw;
    526 		}
    527 
    528 		m_event->setResult(tcu::ThreadUtil::Event::RESULT_OK);
    529 	}
    530 
    531 	if (!success)
    532 		m_event->setResult(tcu::ThreadUtil::Event::RESULT_FAILED);
    533 
    534 	m_deps.clear();
    535 	m_event = SharedPtr<tcu::ThreadUtil::Event>();
    536 	m_syncDeps.clear();
    537 	m_sync = SharedPtr<FenceSync>();
    538 }
    539 
    540 class EGLImage : public Object
    541 {
    542 public:
    543 				EGLImage	(SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<FenceSync> sync);
    544 	virtual		~EGLImage	(void) {}
    545 
    546 	EGLImageKHR	image;
    547 };
    548 
    549 // EGLResource manager
    550 class EGLResourceManager
    551 {
    552 public:
    553 
    554 	void					addContext		(SharedPtr<GLES2Context> context) { m_contexts.push_back(context); }
    555 	void					addSurface		(SharedPtr<Surface> surface) { m_surfaces.push_back(surface); }
    556 	void					addImage		(SharedPtr<EGLImage> image) { m_images.push_back(image); }
    557 
    558 	SharedPtr<Surface>		popSurface		(int index);
    559 	SharedPtr<GLES2Context>	popContext		(int index);
    560 	SharedPtr<EGLImage>		popImage		(int index);
    561 
    562 	int						getContextCount	(void) const { return (int)m_contexts.size(); }
    563 	int						getSurfaceCount	(void) const { return (int)m_surfaces.size(); }
    564 	int						getImageCount	(void) const { return (int)m_images.size(); }
    565 
    566 private:
    567 	std::vector<SharedPtr<GLES2Context> >	m_contexts;
    568 	std::vector<SharedPtr<Surface> >		m_surfaces;
    569 	std::vector<SharedPtr<EGLImage> >		m_images;
    570 };
    571 
    572 SharedPtr<Surface> EGLResourceManager::popSurface (int index)
    573 {
    574 	SharedPtr<Surface> surface = m_surfaces[index];
    575 	m_surfaces.erase(m_surfaces.begin() + index);
    576 	return surface;
    577 }
    578 
    579 SharedPtr<GLES2Context> EGLResourceManager::popContext (int index)
    580 {
    581 	SharedPtr<GLES2Context> context = m_contexts[index];
    582 	m_contexts.erase(m_contexts.begin() + index);
    583 	return context;
    584 }
    585 
    586 SharedPtr<EGLImage> EGLResourceManager::popImage (int index)
    587 {
    588 	SharedPtr<EGLImage> image = m_images[index];
    589 	m_images.erase(m_images.begin() + index);
    590 	return image;
    591 }
    592 
    593 class CreateContext : public tcu::ThreadUtil::Operation
    594 {
    595 public:
    596 				CreateContext	(EGLDisplay display, EGLConfig config, SharedPtr<GLES2Context> shared, SharedPtr<GLES2Context>& context);
    597 
    598 	void		exec			(tcu::ThreadUtil::Thread& thread);
    599 
    600 private:
    601 	EGLDisplay					m_display;
    602 	EGLConfig					m_config;
    603 	SharedPtr<GLES2Context>		m_shared;
    604 	SharedPtr<GLES2Context>		m_context;
    605 };
    606 
    607 CreateContext::CreateContext (EGLDisplay display, EGLConfig config, SharedPtr<GLES2Context> shared, SharedPtr<GLES2Context>& context)
    608 	: tcu::ThreadUtil::Operation	("CreateContext")
    609 	, m_display					(display)
    610 	, m_config					(config)
    611 	, m_shared					(shared)
    612 {
    613 	if (shared)
    614 		modifyObject(SharedPtr<tcu::ThreadUtil::Object>(shared));
    615 
    616 	context = SharedPtr<GLES2Context>(new GLES2Context(getEvent(), (shared ? shared->resourceManager : SharedPtr<GLES2ResourceManager>(new GLES2ResourceManager))));
    617 	m_context = context;
    618 }
    619 
    620 void CreateContext::exec (tcu::ThreadUtil::Thread& thread)
    621 {
    622 	DE_UNREF(thread);
    623 	m_context->display = m_display;
    624 
    625 	EGLint attriblist[] =
    626 	{
    627 		EGL_CONTEXT_CLIENT_VERSION, 2,
    628 		EGL_NONE
    629 	};
    630 
    631 	thread.newMessage() << "Begin -- eglBindAPI(EGL_OPENGL_ES_API)" << tcu::ThreadUtil::Message::End;
    632 	TCU_CHECK_EGL_CALL(eglBindAPI(EGL_OPENGL_ES_API));
    633 	thread.newMessage() << "End -- eglBindAPI()" << tcu::ThreadUtil::Message::End;
    634 
    635 	if (m_shared)
    636 	{
    637 		DE_ASSERT(m_shared->context != EGL_NO_CONTEXT);
    638 		DE_ASSERT(m_shared->display != EGL_NO_DISPLAY);
    639 		DE_ASSERT(m_shared->display == m_display);
    640 
    641 		thread.newMessage() << "Begin -- eglCreateContext(" << m_display << ", " << m_config << ", " << m_shared->context << ", { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE })" << tcu::ThreadUtil::Message::End;
    642 		m_context->context = eglCreateContext(m_display, m_config, m_shared->context, attriblist);
    643 		thread.newMessage() << "End -- " << m_context->context << " = eglCreateContext()" << tcu::ThreadUtil::Message::End;
    644 	}
    645 	else
    646 	{
    647 		thread.newMessage() << "Begin -- eglCreateContext(" << m_display << ", " << m_config << ", EGL_NO_CONTEXT, { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE })" << tcu::ThreadUtil::Message::End;
    648 		m_context->context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, attriblist);
    649 		thread.newMessage() << "End -- " << m_context->context << " = eglCreateContext()" << tcu::ThreadUtil::Message::End;
    650 	}
    651 
    652 	TCU_CHECK_EGL_MSG("Failed to create GLES2 context");
    653 	TCU_CHECK(m_context->context != EGL_NO_CONTEXT);
    654 }
    655 
    656 class DestroyContext : public tcu::ThreadUtil::Operation
    657 {
    658 public:
    659 							DestroyContext	(SharedPtr<GLES2Context> contex);
    660 	void					exec			(tcu::ThreadUtil::Thread& thread);
    661 
    662 private:
    663 	SharedPtr<GLES2Context>	m_context;
    664 };
    665 
    666 DestroyContext::DestroyContext (SharedPtr<GLES2Context> contex)
    667 	: tcu::ThreadUtil::Operation	("DestroyContext")
    668 	, m_context					(contex)
    669 {
    670 	modifyObject(SharedPtr<tcu::ThreadUtil::Object>(m_context));
    671 }
    672 
    673 void DestroyContext::exec (tcu::ThreadUtil::Thread& thread)
    674 {
    675 	DE_UNREF(thread);
    676 	thread.newMessage() << "Begin -- eglDestroyContext(" << m_context->display << ", " << m_context->context << ")" << tcu::ThreadUtil::Message::End;
    677 	TCU_CHECK_EGL_CALL(eglDestroyContext(m_context->display, m_context->context));
    678 	thread.newMessage() << "End -- eglDestroyContext()" << tcu::ThreadUtil::Message::End;
    679 	m_context->display	= EGL_NO_DISPLAY;
    680 	m_context->context	= EGL_NO_CONTEXT;
    681 }
    682 
    683 class MakeCurrent : public tcu::ThreadUtil::Operation
    684 {
    685 public:
    686 			MakeCurrent	(EGLThread& thread, EGLDisplay display, SharedPtr<Surface> surface, SharedPtr<GLES2Context> context);
    687 
    688 	void	exec		(tcu::ThreadUtil::Thread& thread);
    689 
    690 private:
    691 	EGLDisplay				m_display;
    692 	SharedPtr<Surface>		m_surface;
    693 	SharedPtr<GLES2Context>	m_context;
    694 };
    695 
    696 MakeCurrent::MakeCurrent (EGLThread& thread, EGLDisplay display, SharedPtr<Surface> surface, SharedPtr<GLES2Context> context)
    697 	: tcu::ThreadUtil::Operation	("MakeCurrent")
    698 	, m_display					(display)
    699 	, m_surface					(surface)
    700 	, m_context					(context)
    701 {
    702 	if (m_context)
    703 		modifyObject(SharedPtr<tcu::ThreadUtil::Object>(m_context));
    704 
    705 	if (m_surface)
    706 		modifyObject(SharedPtr<tcu::ThreadUtil::Object>(m_surface));
    707 
    708 	// Release old contexts
    709 	if (thread.context)
    710 	{
    711 		modifyObject(SharedPtr<tcu::ThreadUtil::Object>(thread.context));
    712 	}
    713 
    714 	// Release old surface
    715 	if (thread.surface)
    716 	{
    717 		modifyObject(SharedPtr<tcu::ThreadUtil::Object>(thread.surface));
    718 	}
    719 
    720 	thread.context	= m_context;
    721 	thread.surface	= m_surface;
    722 }
    723 
    724 void MakeCurrent::exec (tcu::ThreadUtil::Thread& t)
    725 {
    726 	EGLThread& thread = *(dynamic_cast<EGLThread*>(&t));
    727 	DE_ASSERT(&thread);
    728 
    729 	if (m_context)
    730 	{
    731 		thread.eglSurface = m_surface->surface;
    732 		thread.runtimeContext = m_context;
    733 
    734 		DE_ASSERT(m_surface);
    735 		thread.newMessage() << "Begin -- eglMakeCurrent(" << m_display << ", " << m_surface->surface << ", " << m_surface->surface << ", " << m_context->context << ")" << tcu::ThreadUtil::Message::End;
    736 		TCU_CHECK_EGL_CALL(eglMakeCurrent(m_display, m_surface->surface, m_surface->surface, m_context->context));
    737 		thread.newMessage() << "End -- eglMakeCurrent()" << tcu::ThreadUtil::Message::End;
    738 	}
    739 	else
    740 	{
    741 		thread.runtimeContext = m_context;
    742 
    743 		thread.newMessage() << "Begin -- eglMakeCurrent(" << m_display << ", EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)" << tcu::ThreadUtil::Message::End;
    744 		TCU_CHECK_EGL_CALL(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    745 		thread.newMessage() << "End -- eglMakeCurrent()" << tcu::ThreadUtil::Message::End;
    746 	}
    747 }
    748 
    749 class InitGLExtension : public tcu::ThreadUtil::Operation
    750 {
    751 public:
    752 			InitGLExtension		(const char* extension);
    753 
    754 	void	exec				(tcu::ThreadUtil::Thread& thread);
    755 
    756 private:
    757 	std::string					m_extension;
    758 };
    759 
    760 InitGLExtension::InitGLExtension (const char* extension)
    761 	: tcu::ThreadUtil::Operation	("InitGLExtension")
    762 	, m_extension					(extension)
    763 {
    764 }
    765 
    766 void InitGLExtension::exec (tcu::ThreadUtil::Thread& t)
    767 {
    768 	EGLThread& thread = *(dynamic_cast<EGLThread*>(&t));
    769 
    770 	// Check extensions
    771 	bool found = false;
    772 
    773 	thread.newMessage() << "Begin -- glGetString(GL_EXTENSIONS)" << tcu::ThreadUtil::Message::End;
    774 	std::string extensions = (const char*)glGetString(GL_EXTENSIONS);
    775 	thread.newMessage() << "End -- glGetString()" << tcu::ThreadUtil::Message::End;
    776 
    777 	std::string::size_type pos = extensions.find(" ");
    778 
    779 	do
    780 	{
    781 		std::string extension;
    782 		if (pos != std::string::npos)
    783 		{
    784 			extension = extensions.substr(0, pos);
    785 			extensions = extensions.substr(pos+1);
    786 		}
    787 		else
    788 		{
    789 			extension = extensions;
    790 			extensions = "";
    791 		}
    792 
    793 		if (extension == m_extension)
    794 		{
    795 			found = true;
    796 			break;
    797 		}
    798 		pos = extensions.find(" ");
    799 	} while (pos != std::string::npos);
    800 
    801 	if (!found)
    802 		throw tcu::NotSupportedError((m_extension + " not supported").c_str(), "", __FILE__, __LINE__);
    803 
    804 
    805 	// Query function pointers
    806 	if (m_extension == "GL_OES_EGL_image")
    807 	{
    808 		thread.newMessage() << "Begin -- eglGetProcAddress(\"glEGLImageTargetTexture2DOES\")" << tcu::ThreadUtil::Message::End;
    809 		thread.runtimeContext->glExtensions.imageTargetTexture2D = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
    810 		thread.newMessage() << "End --  " << ((void*)thread.runtimeContext->glExtensions.imageTargetTexture2D) << " = eglGetProcAddress()"<< tcu::ThreadUtil::Message::End;
    811 	}
    812 }
    813 
    814 class CreatePBufferSurface : public tcu::ThreadUtil::Operation
    815 {
    816 public:
    817 				CreatePBufferSurface	(EGLDisplay display, EGLConfig config, EGLint width, EGLint height, SharedPtr<Surface>& surface);
    818 	void		exec					(tcu::ThreadUtil::Thread& thread);
    819 
    820 private:
    821 	EGLDisplay			m_display;
    822 	EGLConfig			m_config;
    823 	EGLint				m_width;
    824 	EGLint				m_height;
    825 	SharedPtr<Surface>	m_surface;
    826 };
    827 
    828 CreatePBufferSurface::CreatePBufferSurface (EGLDisplay display, EGLConfig config, EGLint width, EGLint height, SharedPtr<Surface>& surface)
    829 	: tcu::ThreadUtil::Operation	("CreatePBufferSurface")
    830 	, m_display					(display)
    831 	, m_config					(config)
    832 	, m_width					(width)
    833 	, m_height					(height)
    834 {
    835 	surface = SharedPtr<Surface>(new Surface(getEvent()));
    836 	m_surface = surface;
    837 }
    838 
    839 void CreatePBufferSurface::exec (tcu::ThreadUtil::Thread& thread)
    840 {
    841 	EGLint attriblist[] = {
    842 		EGL_WIDTH, m_width,
    843 		EGL_HEIGHT, m_height,
    844 		EGL_NONE
    845 	};
    846 
    847 	thread.newMessage() << "Begin -- eglCreatePbufferSurface(" << m_display << ", " << m_config << ", { EGL_WIDTH, " << m_width << ", EGL_HEIGHT, " << m_height << ", EGL_NONE })" << tcu::ThreadUtil::Message::End;
    848 	m_surface->surface = eglCreatePbufferSurface(m_display, m_config, attriblist);
    849 	thread.newMessage() << "End -- " << m_surface->surface << "= eglCreatePbufferSurface()" << tcu::ThreadUtil::Message::End;
    850 	TCU_CHECK_EGL_MSG("eglCreatePbufferSurface()");
    851 }
    852 
    853 class DestroySurface : public tcu::ThreadUtil::Operation
    854 {
    855 public:
    856 			DestroySurface	(EGLDisplay display, SharedPtr<Surface> surface);
    857 	void	exec			(tcu::ThreadUtil::Thread& thread);
    858 
    859 private:
    860 	EGLDisplay			m_display;
    861 	SharedPtr<Surface>	m_surface;
    862 };
    863 
    864 DestroySurface::DestroySurface (EGLDisplay display, SharedPtr<Surface> surface)
    865 	: tcu::ThreadUtil::Operation	("DestroySurface")
    866 	, m_display					(display)
    867 	, m_surface					(surface)
    868 {
    869 	modifyObject(SharedPtr<tcu::ThreadUtil::Object>(m_surface));
    870 }
    871 
    872 void DestroySurface::exec (tcu::ThreadUtil::Thread& thread)
    873 {
    874 	thread.newMessage() << "Begin -- eglDestroySurface(" << m_display << ",  " << m_surface->surface << ")" << tcu::ThreadUtil::Message::End;
    875 	TCU_CHECK_EGL_CALL(eglDestroySurface(m_display, m_surface->surface));
    876 	thread.newMessage() << "End -- eglDestroySurface()" << tcu::ThreadUtil::Message::End;
    877 }
    878 
    879 EGLImage::EGLImage (SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<FenceSync> sync)
    880 	: Object	("EGLImage", event, sync)
    881 	, image		(EGL_NO_IMAGE_KHR)
    882 {
    883 }
    884 
    885 class Texture : public Object
    886 {
    887 public:
    888 			Texture (SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<FenceSync> sync);
    889 
    890 	// Runtime parameters
    891 	GLuint	texture;
    892 
    893 	// Call generation time parameters
    894 	bool	isDefined;
    895 
    896 	SharedPtr<EGLImage>	sourceImage;
    897 };
    898 
    899 Texture::Texture (SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<FenceSync> sync)
    900 	: Object					("Texture", event, sync)
    901 	, texture					(0)
    902 	, isDefined					(false)
    903 {
    904 }
    905 
    906 class CreateTexture : public Operation
    907 {
    908 public:
    909 			CreateTexture	(SharedPtr<Texture>& texture, bool useSync, bool serverSync);
    910 	void	exec			(tcu::ThreadUtil::Thread& thread);
    911 
    912 private:
    913 	SharedPtr<Texture> m_texture;
    914 };
    915 
    916 CreateTexture::CreateTexture (SharedPtr<Texture>& texture, bool useSync, bool serverSync)
    917 	: Operation	("CreateTexture", useSync, serverSync)
    918 {
    919 	texture = SharedPtr<Texture>(new Texture(getEvent(), getSync()));
    920 	m_texture = texture;
    921 }
    922 
    923 void CreateTexture::exec (tcu::ThreadUtil::Thread& thread)
    924 {
    925 	GLuint tex = 0;
    926 
    927 	thread.newMessage() << "Begin -- glGenTextures(1, { 0 })" << tcu::ThreadUtil::Message::End;
    928 	GLU_CHECK_CALL(glGenTextures(1, &tex));
    929 	thread.newMessage() << "End -- glGenTextures(1, { " << tex << " })" << tcu::ThreadUtil::Message::End;
    930 
    931 	m_texture->texture = tex;
    932 }
    933 
    934 class DeleteTexture : public Operation
    935 {
    936 public:
    937 			DeleteTexture	(SharedPtr<Texture> texture, bool useSync, bool serverSync);
    938 	void	exec			(tcu::ThreadUtil::Thread& thread);
    939 
    940 private:
    941 	SharedPtr<Texture> m_texture;
    942 };
    943 
    944 DeleteTexture::DeleteTexture (SharedPtr<Texture> texture, bool useSync, bool serverSync)
    945 	: Operation		("DeleteTexture", useSync, serverSync)
    946 	, m_texture		(texture)
    947 {
    948 	modifyGLObject(SharedPtr<Object>(m_texture));
    949 }
    950 
    951 void DeleteTexture::exec (tcu::ThreadUtil::Thread& thread)
    952 {
    953 	GLuint tex = m_texture->texture;
    954 
    955 	thread.newMessage() << "Begin -- glDeleteTextures(1, { " << tex << " })" << tcu::ThreadUtil::Message::End;
    956 	GLU_CHECK_CALL(glDeleteTextures(1, &tex));
    957 	thread.newMessage() << "End -- glDeleteTextures()" << tcu::ThreadUtil::Message::End;
    958 
    959 	m_texture->texture = 0;
    960 }
    961 
    962 class TexImage2D : public Operation
    963 {
    964 public:
    965 			TexImage2D	(SharedPtr<Texture> texture, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, bool useSync, bool serverSync);
    966 	void	exec		(tcu::ThreadUtil::Thread& thread);
    967 
    968 private:
    969 	SharedPtr<Texture>	m_texture;
    970 	GLint				m_level;
    971 	GLint				m_internalFormat;
    972 	GLsizei				m_width;
    973 	GLsizei				m_height;
    974 	GLenum				m_format;
    975 	GLenum				m_type;
    976 };
    977 
    978 TexImage2D::TexImage2D (SharedPtr<Texture> texture, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, bool useSync, bool serverSync)
    979 	: Operation			("TexImage2D", useSync, serverSync)
    980 	, m_texture			(texture)
    981 	, m_level			(level)
    982 	, m_internalFormat	(internalFormat)
    983 	, m_width			(width)
    984 	, m_height			(height)
    985 	, m_format			(format)
    986 	, m_type			(type)
    987 {
    988 	modifyGLObject(SharedPtr<Object>(m_texture));
    989 	m_texture->isDefined = true;
    990 
    991 	// Orphang texture
    992 	texture->sourceImage = SharedPtr<EGLImage>();
    993 }
    994 
    995 void TexImage2D::exec (tcu::ThreadUtil::Thread& thread)
    996 {
    997 	void* dummyData = thread.getDummyData(m_width*m_height*4);
    998 
    999 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, " << m_texture->texture << ")" << tcu::ThreadUtil::Message::End;
   1000 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, m_texture->texture));
   1001 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1002 
   1003 	thread.newMessage() << "Begin -- glTexImage2D(GL_TEXTURE_2D, " << m_level << ", " << m_internalFormat << ", " << m_width << ", " << m_height << ", 0, " << m_format << ", " << m_type << ", data)" << tcu::ThreadUtil::Message::End;
   1004 	GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_2D, m_level, m_internalFormat, m_width, m_height, 0, m_format, m_type, dummyData));
   1005 	thread.newMessage() << "End -- glTexImage2D()" << tcu::ThreadUtil::Message::End;
   1006 
   1007 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, 0)" << tcu::ThreadUtil::Message::End;
   1008 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0));
   1009 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1010 }
   1011 
   1012 class TexSubImage2D : public Operation
   1013 {
   1014 public:
   1015 			TexSubImage2D	(SharedPtr<Texture> texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, bool useSync, bool serverSync);
   1016 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1017 
   1018 private:
   1019 	SharedPtr<Texture>	m_texture;
   1020 	GLint				m_level;
   1021 	GLint				m_xoffset;
   1022 	GLint				m_yoffset;
   1023 	GLsizei				m_width;
   1024 	GLsizei				m_height;
   1025 	GLenum				m_format;
   1026 	GLenum				m_type;
   1027 };
   1028 
   1029 TexSubImage2D::TexSubImage2D (SharedPtr<Texture> texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, bool useSync, bool serverSync)
   1030 	: Operation		("TexSubImage2D", useSync, serverSync)
   1031 	, m_texture		(texture)
   1032 	, m_level		(level)
   1033 	, m_xoffset		(xoffset)
   1034 	, m_yoffset		(yoffset)
   1035 	, m_width		(width)
   1036 	, m_height		(height)
   1037 	, m_format		(format)
   1038 	, m_type		(type)
   1039 {
   1040 	modifyGLObject(SharedPtr<Object>(m_texture));
   1041 
   1042 	if (m_texture->sourceImage)
   1043 		modifyGLObject(SharedPtr<Object>(m_texture->sourceImage));
   1044 }
   1045 
   1046 void TexSubImage2D::exec (tcu::ThreadUtil::Thread& thread)
   1047 {
   1048 	void* dummyData = thread.getDummyData(m_width*m_height*4);
   1049 
   1050 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, " << m_texture->texture << ")" << tcu::ThreadUtil::Message::End;
   1051 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, m_texture->texture));
   1052 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1053 
   1054 	thread.newMessage() << "Begin -- glTexSubImage2D(GL_TEXTURE_2D, " << m_level << ", " << m_xoffset << ", " << m_yoffset << ", " << m_width << ", " << m_height << ", 0, " << m_format << ", " << m_type << ", <data>)" << tcu::ThreadUtil::Message::End;
   1055 	GLU_CHECK_CALL(glTexSubImage2D(GL_TEXTURE_2D, m_level, m_xoffset, m_yoffset, m_width, m_height, m_format, m_type, dummyData));
   1056 	thread.newMessage() << "End -- glSubTexImage2D()" << tcu::ThreadUtil::Message::End;
   1057 
   1058 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, 0)" << tcu::ThreadUtil::Message::End;
   1059 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0));
   1060 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1061 }
   1062 
   1063 class CopyTexImage2D : public Operation
   1064 {
   1065 public:
   1066 			CopyTexImage2D	(SharedPtr<Texture> texture, GLint level, GLint internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border, bool useSync, bool serverSync);
   1067 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1068 
   1069 private:
   1070 	SharedPtr<Texture>	m_texture;
   1071 	GLint				m_level;
   1072 	GLint				m_internalFormat;
   1073 	GLint				m_x;
   1074 	GLint				m_y;
   1075 	GLsizei				m_width;
   1076 	GLsizei				m_height;
   1077 	GLint				m_border;
   1078 };
   1079 
   1080 CopyTexImage2D::CopyTexImage2D (SharedPtr<Texture> texture, GLint level, GLint internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border, bool useSync, bool serverSync)
   1081 	: Operation			("CopyTexImage2D", useSync, serverSync)
   1082 	, m_texture			(texture)
   1083 	, m_level			(level)
   1084 	, m_internalFormat	(internalFormat)
   1085 	, m_x				(x)
   1086 	, m_y				(y)
   1087 	, m_width			(width)
   1088 	, m_height			(height)
   1089 	, m_border			(border)
   1090 {
   1091 	modifyGLObject(SharedPtr<Object>(m_texture));
   1092 	texture->isDefined = true;
   1093 
   1094 	// Orphang texture
   1095 	texture->sourceImage = SharedPtr<EGLImage>();
   1096 }
   1097 
   1098 void CopyTexImage2D::exec (tcu::ThreadUtil::Thread& thread)
   1099 {
   1100 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, " << m_texture->texture << ")" << tcu::ThreadUtil::Message::End;
   1101 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, m_texture->texture));
   1102 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1103 
   1104 	thread.newMessage() << "Begin -- glCopyTexImage2D(GL_TEXTURE_2D, " << m_level << ", " << m_internalFormat << ", " << m_x << ", " << m_y << ", " << m_width << ", " << m_height << ", " << m_border << ")" << tcu::ThreadUtil::Message::End;
   1105 	GLU_CHECK_CALL(glCopyTexImage2D(GL_TEXTURE_2D, m_level, m_internalFormat, m_x, m_y, m_width, m_height, m_border));
   1106 	thread.newMessage() << "End -- glCopyTexImage2D()" << tcu::ThreadUtil::Message::End;
   1107 
   1108 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, 0)" << tcu::ThreadUtil::Message::End;
   1109 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0));
   1110 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1111 }
   1112 
   1113 class CopyTexSubImage2D : public Operation
   1114 {
   1115 public:
   1116 			CopyTexSubImage2D		(SharedPtr<Texture> texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, bool useSync, bool serverSync);
   1117 	void	exec					(tcu::ThreadUtil::Thread& thread);
   1118 
   1119 private:
   1120 	SharedPtr<Texture>	m_texture;
   1121 	GLint				m_level;
   1122 	GLint				m_xoffset;
   1123 	GLint				m_yoffset;
   1124 	GLint				m_x;
   1125 	GLint				m_y;
   1126 	GLsizei				m_width;
   1127 	GLsizei				m_height;
   1128 };
   1129 
   1130 CopyTexSubImage2D::CopyTexSubImage2D (SharedPtr<Texture> texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, bool useSync, bool serverSync)
   1131 	: Operation		("CopyTexSubImage2D", useSync, serverSync)
   1132 	, m_texture		(texture)
   1133 	, m_level		(level)
   1134 	, m_xoffset		(xoffset)
   1135 	, m_yoffset		(yoffset)
   1136 	, m_x			(x)
   1137 	, m_y			(y)
   1138 	, m_width		(width)
   1139 	, m_height		(height)
   1140 {
   1141 	modifyGLObject(SharedPtr<Object>(m_texture));
   1142 
   1143 	if (m_texture->sourceImage)
   1144 		modifyGLObject(SharedPtr<Object>(m_texture->sourceImage));
   1145 }
   1146 
   1147 void CopyTexSubImage2D::exec (tcu::ThreadUtil::Thread& thread)
   1148 {
   1149 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, " << m_texture->texture << ")" << tcu::ThreadUtil::Message::End;
   1150 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, m_texture->texture));
   1151 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1152 
   1153 	thread.newMessage() << "Begin -- glCopyTexSubImage2D(GL_TEXTURE_2D, " << m_level << ", " << m_xoffset << ", " << m_yoffset << ", " << m_x << ", " << m_y << ", " << m_width << ", " << m_height << ")" << tcu::ThreadUtil::Message::End;
   1154 	GLU_CHECK_CALL(glCopyTexSubImage2D(GL_TEXTURE_2D, m_level, m_xoffset, m_yoffset, m_x, m_y, m_width, m_height));
   1155 	thread.newMessage() << "End -- glCopyTexSubImage2D()" << tcu::ThreadUtil::Message::End;
   1156 
   1157 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, 0)" << tcu::ThreadUtil::Message::End;
   1158 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0));
   1159 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1160 }
   1161 
   1162 class Buffer : public Object
   1163 {
   1164 public:
   1165 				Buffer		(SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<FenceSync> sync);
   1166 
   1167 	// Runtime attributes
   1168 	GLuint		buffer;
   1169 	GLsizeiptr	size;
   1170 
   1171 	// Call generation time parameters
   1172 	bool		isDefined;
   1173 };
   1174 
   1175 Buffer::Buffer (SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<FenceSync> sync)
   1176 	: Object		("Buffer", event, sync)
   1177 	, buffer		(0)
   1178 	, size			(0)
   1179 	, isDefined		(false)
   1180 {
   1181 }
   1182 
   1183 class CreateBuffer : public Operation
   1184 {
   1185 public:
   1186 			CreateBuffer	(SharedPtr<Buffer>& buffer, bool useSync, bool serverSync);
   1187 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1188 
   1189 private:
   1190 	SharedPtr<Buffer> m_buffer;
   1191 };
   1192 
   1193 CreateBuffer::CreateBuffer (SharedPtr<Buffer>& buffer, bool useSync, bool serverSync)
   1194 	: Operation	("CreateBuffer", useSync, serverSync)
   1195 {
   1196 	buffer = SharedPtr<Buffer>(new Buffer(getEvent(), getSync()));
   1197 	m_buffer = buffer;
   1198 }
   1199 
   1200 void CreateBuffer::exec (tcu::ThreadUtil::Thread& thread)
   1201 {
   1202 	GLuint buffer = 0;
   1203 
   1204 	thread.newMessage() << "Begin -- glGenBuffers(1, { 0 })" << tcu::ThreadUtil::Message::End;
   1205 	GLU_CHECK_CALL(glGenBuffers(1, &buffer));
   1206 	thread.newMessage() << "End -- glGenBuffers(1, { " << buffer << " })" << tcu::ThreadUtil::Message::End;
   1207 
   1208 	m_buffer->buffer = buffer;
   1209 }
   1210 
   1211 class DeleteBuffer : public Operation
   1212 {
   1213 public:
   1214 			DeleteBuffer	(SharedPtr<Buffer> buffer, bool useSync, bool serverSync);
   1215 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1216 
   1217 private:
   1218 	SharedPtr<Buffer> m_buffer;
   1219 };
   1220 
   1221 DeleteBuffer::DeleteBuffer (SharedPtr<Buffer> buffer, bool useSync, bool serverSync)
   1222 	: Operation	("DeleteBuffer", useSync, serverSync)
   1223 	, m_buffer	(buffer)
   1224 {
   1225 	modifyGLObject(SharedPtr<Object>(m_buffer));
   1226 }
   1227 
   1228 void DeleteBuffer::exec (tcu::ThreadUtil::Thread& thread)
   1229 {
   1230 	GLuint buffer = m_buffer->buffer;
   1231 
   1232 	thread.newMessage() << "Begin -- glDeleteBuffers(1, { " << buffer << " })" << tcu::ThreadUtil::Message::End;
   1233 	GLU_CHECK_CALL(glDeleteBuffers(1, &buffer));
   1234 	thread.newMessage() << "End -- glDeleteBuffers()" << tcu::ThreadUtil::Message::End;
   1235 
   1236 	m_buffer->buffer = 0;
   1237 }
   1238 
   1239 class BufferData : public Operation
   1240 {
   1241 public:
   1242 			BufferData	(SharedPtr<Buffer> buffer, GLenum target, GLsizeiptr size, GLenum usage, bool useSync, bool serverSync);
   1243 	void	exec		(tcu::ThreadUtil::Thread& thread);
   1244 
   1245 private:
   1246 	SharedPtr<Buffer>	m_buffer;
   1247 	GLenum				m_target;
   1248 	GLsizeiptr			m_size;
   1249 	GLenum				m_usage;
   1250 };
   1251 
   1252 BufferData::BufferData (SharedPtr<Buffer> buffer, GLenum target, GLsizeiptr size, GLenum usage, bool useSync, bool serverSync)
   1253 	: Operation	("BufferData", useSync, serverSync)
   1254 	, m_buffer	(buffer)
   1255 	, m_target	(target)
   1256 	, m_size	(size)
   1257 	, m_usage	(usage)
   1258 {
   1259 	modifyGLObject(SharedPtr<Object>(m_buffer));
   1260 	buffer->isDefined	= true;
   1261 	buffer->size		= size;
   1262 }
   1263 
   1264 void BufferData::exec (tcu::ThreadUtil::Thread& thread)
   1265 {
   1266 	void* dummyData = thread.getDummyData(m_size);
   1267 
   1268 	thread.newMessage() << "Begin -- glBindBuffer(" << m_target << ", " << m_buffer->buffer << ")" << tcu::ThreadUtil::Message::End;
   1269 	GLU_CHECK_CALL(glBindBuffer(m_target, m_buffer->buffer));
   1270 	thread.newMessage() << "End -- glBindBuffer()" << tcu::ThreadUtil::Message::End;
   1271 
   1272 	thread.newMessage() << "Begin -- glBufferData(" << m_target << ", " << m_size << ", <DATA>, " << m_usage << ")" << tcu::ThreadUtil::Message::End;
   1273 	GLU_CHECK_CALL(glBufferData(m_target, m_size, dummyData, m_usage));
   1274 	thread.newMessage() << "End -- glBufferData()" << tcu::ThreadUtil::Message::End;
   1275 
   1276 	thread.newMessage() << "Begin -- glBindBuffer(" << m_target << ", 0)" << tcu::ThreadUtil::Message::End;
   1277 	GLU_CHECK_CALL(glBindBuffer(m_target, 0));
   1278 	thread.newMessage() << "End -- glBindBuffer()" << tcu::ThreadUtil::Message::End;
   1279 }
   1280 
   1281 class BufferSubData : public Operation
   1282 {
   1283 public:
   1284 			BufferSubData	(SharedPtr<Buffer> buffer, GLenum target, GLintptr offset, GLsizeiptr size, bool useSync, bool serverSync);
   1285 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1286 
   1287 private:
   1288 	SharedPtr<Buffer>	m_buffer;
   1289 	GLenum				m_target;
   1290 	GLintptr			m_offset;
   1291 	GLsizeiptr			m_size;
   1292 };
   1293 
   1294 BufferSubData::BufferSubData (SharedPtr<Buffer> buffer, GLenum target, GLintptr offset, GLsizeiptr size, bool useSync, bool serverSync)
   1295 	: Operation	("BufferSubData", useSync, serverSync)
   1296 	, m_buffer	(buffer)
   1297 	, m_target	(target)
   1298 	, m_offset	(offset)
   1299 	, m_size	(size)
   1300 {
   1301 	modifyGLObject(SharedPtr<Object>(m_buffer));
   1302 }
   1303 
   1304 void BufferSubData::exec (tcu::ThreadUtil::Thread& thread)
   1305 {
   1306 	void* dummyData = thread.getDummyData(m_size);
   1307 
   1308 	thread.newMessage() << "Begin -- glBindBuffer(" << m_target << ", " << m_buffer->buffer << ")" << tcu::ThreadUtil::Message::End;
   1309 	GLU_CHECK_CALL(glBindBuffer(m_target, m_buffer->buffer));
   1310 	thread.newMessage() << "End -- glBindBuffer()" << tcu::ThreadUtil::Message::End;
   1311 
   1312 	thread.newMessage() << "Begin -- glBufferSubData(" << m_target << ", " << m_offset << ", " << m_size << ", <DATA>)" << tcu::ThreadUtil::Message::End;
   1313 	GLU_CHECK_CALL(glBufferSubData(m_target, m_offset, m_size, dummyData));
   1314 	thread.newMessage() << "End -- glBufferSubData()" << tcu::ThreadUtil::Message::End;
   1315 
   1316 	thread.newMessage() << "Begin -- glBindBuffer(" << m_target << ", 0)" << tcu::ThreadUtil::Message::End;
   1317 	GLU_CHECK_CALL(glBindBuffer(m_target, 0));
   1318 	thread.newMessage() << "End -- glBindBuffer()" << tcu::ThreadUtil::Message::End;
   1319 }
   1320 
   1321 class Shader : public Object
   1322 {
   1323 public:
   1324 				Shader		(SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<FenceSync> sync);
   1325 
   1326 	GLuint		shader;
   1327 	GLenum		type;
   1328 	bool		isDefined;
   1329 	bool		compiled;
   1330 };
   1331 
   1332 Shader::Shader (SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<FenceSync> sync)
   1333 	: Object		("Shader", event, sync)
   1334 	, shader		(0)
   1335 	, type			(GL_NONE)
   1336 	, isDefined		(false)
   1337 	, compiled		(false)
   1338 {
   1339 }
   1340 
   1341 class CreateShader : public Operation
   1342 {
   1343 public:
   1344 			CreateShader	(GLenum type, SharedPtr<Shader>& shader, bool useSync, bool serverSync);
   1345 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1346 
   1347 private:
   1348 	SharedPtr<Shader>	m_shader;
   1349 	GLenum				m_type;
   1350 };
   1351 
   1352 CreateShader::CreateShader (GLenum type, SharedPtr<Shader>& shader, bool useSync, bool serverSync)
   1353 	: Operation	("CreateShader", useSync, serverSync)
   1354 	, m_type	(type)
   1355 {
   1356 	shader = SharedPtr<Shader>(new Shader(getEvent(), getSync()));
   1357 	shader->type = type;
   1358 
   1359 	m_shader = shader;
   1360 }
   1361 
   1362 void CreateShader::exec (tcu::ThreadUtil::Thread& thread)
   1363 {
   1364 	GLuint shader = 0;
   1365 
   1366 	thread.newMessage() << "Begin -- glCreateShader(" << m_type << ")" << tcu::ThreadUtil::Message::End;
   1367 	shader = glCreateShader(m_type);
   1368 	GLU_CHECK_MSG("glCreateShader()");
   1369 	thread.newMessage() << "End -- " << shader  << " = glCreateShader(" << m_type << ")" << tcu::ThreadUtil::Message::End;
   1370 
   1371 	m_shader->shader	= shader;
   1372 }
   1373 
   1374 class DeleteShader : public Operation
   1375 {
   1376 public:
   1377 			DeleteShader	(SharedPtr<Shader> shader, bool useSync, bool serverSync);
   1378 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1379 
   1380 private:
   1381 	SharedPtr<Shader> m_shader;
   1382 };
   1383 
   1384 DeleteShader::DeleteShader (SharedPtr<Shader> shader, bool useSync, bool serverSync)
   1385 	: Operation	("DeleteShader", useSync, serverSync)
   1386 	, m_shader	(shader)
   1387 {
   1388 	modifyGLObject(SharedPtr<Object>(m_shader));
   1389 }
   1390 
   1391 void DeleteShader::exec (tcu::ThreadUtil::Thread& thread)
   1392 {
   1393 	GLuint shader = m_shader->shader;
   1394 
   1395 	thread.newMessage() << "Begin -- glDeleteShader(" << shader << ")" << tcu::ThreadUtil::Message::End;
   1396 	GLU_CHECK_CALL(glDeleteShader(shader));
   1397 	thread.newMessage() << "End -- glDeleteShader()" << tcu::ThreadUtil::Message::End;
   1398 
   1399 	m_shader->shader = 0;
   1400 }
   1401 
   1402 class ShaderSource : public Operation
   1403 {
   1404 public:
   1405 			ShaderSource	(SharedPtr<Shader> sharder, const char* source, bool useSync, bool serverSync);
   1406 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1407 
   1408 private:
   1409 	SharedPtr<Shader>	m_shader;
   1410 	string				m_source;
   1411 };
   1412 
   1413 ShaderSource::ShaderSource (SharedPtr<Shader> shader, const char* source, bool useSync, bool serverSync)
   1414 	: Operation	("ShaderSource", useSync, serverSync)
   1415 	, m_shader	(shader)
   1416 	, m_source	(source)
   1417 {
   1418 	modifyGLObject(SharedPtr<Object>(m_shader));
   1419 	m_shader->isDefined = true;
   1420 }
   1421 
   1422 void ShaderSource::exec (tcu::ThreadUtil::Thread& thread)
   1423 {
   1424 	const char* shaderSource = m_source.c_str();
   1425 
   1426 	thread.newMessage() << "Begin -- glShaderSource(" << m_shader->shader << ", 1, \"" << shaderSource << "\", NULL)" << tcu::ThreadUtil::Message::End;
   1427 	GLU_CHECK_CALL(glShaderSource(m_shader->shader, 1, &shaderSource, NULL));
   1428 	thread.newMessage() << "End -- glShaderSource()" << tcu::ThreadUtil::Message::End;
   1429 }
   1430 
   1431 class ShaderCompile : public Operation
   1432 {
   1433 public:
   1434 			ShaderCompile	(SharedPtr<Shader> sharder, bool useSync, bool serverSync);
   1435 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1436 
   1437 private:
   1438 	SharedPtr<Shader> m_shader;
   1439 };
   1440 
   1441 ShaderCompile::ShaderCompile (SharedPtr<Shader> shader, bool useSync, bool serverSync)
   1442 	: Operation	("ShaderCompile", useSync, serverSync)
   1443 	, m_shader	(shader)
   1444 {
   1445 	m_shader->compiled = true;
   1446 	modifyGLObject(SharedPtr<Object>(m_shader));
   1447 }
   1448 
   1449 void ShaderCompile::exec (tcu::ThreadUtil::Thread& thread)
   1450 {
   1451 	thread.newMessage() << "Begin -- glCompileShader(" << m_shader->shader << ")" << tcu::ThreadUtil::Message::End;
   1452 	GLU_CHECK_CALL(glCompileShader(m_shader->shader));
   1453 	thread.newMessage() << "End -- glCompileShader()" << tcu::ThreadUtil::Message::End;
   1454 }
   1455 
   1456 class Program : public Object
   1457 {
   1458 public:
   1459 						Program		(SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<FenceSync> sync);
   1460 
   1461 	// Generation time attributes
   1462 	SharedPtr<Shader>	vertexShader;
   1463 	SharedPtr<Shader>	fragmentShader;
   1464 	bool				linked;
   1465 
   1466 	// Runtime attributes
   1467 	GLuint				program;
   1468 	GLuint				runtimeVertexShader;
   1469 	GLuint				runtimeFragmentShader;
   1470 };
   1471 
   1472 Program::Program (SharedPtr<tcu::ThreadUtil::Event> event, SharedPtr<FenceSync> sync)
   1473 	: Object					("Program", event, sync)
   1474 	, linked					(false)
   1475 	, program					(0)
   1476 	, runtimeVertexShader		(0)
   1477 	, runtimeFragmentShader		(0)
   1478 {
   1479 }
   1480 
   1481 class CreateProgram : public Operation
   1482 {
   1483 public:
   1484 			CreateProgram	(SharedPtr<Program>& program, bool useSync, bool serverSync);
   1485 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1486 
   1487 private:
   1488 	SharedPtr<Program> m_program;
   1489 };
   1490 
   1491 CreateProgram::CreateProgram (SharedPtr<Program>& program, bool useSync, bool serverSync)
   1492 	: Operation	("CreateProgram", useSync, serverSync)
   1493 {
   1494 	program = SharedPtr<Program>(new Program(getEvent(), getSync()));
   1495 	m_program = program;
   1496 }
   1497 
   1498 void CreateProgram::exec (tcu::ThreadUtil::Thread& thread)
   1499 {
   1500 	GLuint program = 0;
   1501 
   1502 	thread.newMessage() << "Begin -- glCreateProgram()" << tcu::ThreadUtil::Message::End;
   1503 	program = glCreateProgram();
   1504 	GLU_CHECK_MSG("glCreateProgram()");
   1505 	thread.newMessage() << "End -- " << program  << " = glCreateProgram()" << tcu::ThreadUtil::Message::End;
   1506 
   1507 	m_program->program	= program;
   1508 }
   1509 
   1510 class DeleteProgram : public Operation
   1511 {
   1512 public:
   1513 			DeleteProgram	(SharedPtr<Program> program, bool useSync, bool serverSync);
   1514 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1515 
   1516 private:
   1517 	SharedPtr<Program> m_program;
   1518 };
   1519 
   1520 DeleteProgram::DeleteProgram (SharedPtr<Program> program, bool useSync, bool serverSync)
   1521 	: Operation	("DeleteProgram", useSync, serverSync)
   1522 	, m_program	(program)
   1523 {
   1524 	modifyGLObject(SharedPtr<Object>(m_program));
   1525 }
   1526 
   1527 void DeleteProgram::exec (tcu::ThreadUtil::Thread& thread)
   1528 {
   1529 	GLuint program = m_program->program;
   1530 
   1531 	thread.newMessage() << "Begin -- glDeleteProgram(" << program << ")" << tcu::ThreadUtil::Message::End;
   1532 	GLU_CHECK_CALL(glDeleteProgram(program));
   1533 	thread.newMessage() << "End -- glDeleteProgram()" << tcu::ThreadUtil::Message::End;
   1534 
   1535 	m_program->program = 0;
   1536 }
   1537 
   1538 class AttachShader : public Operation
   1539 {
   1540 public:
   1541 			AttachShader	(SharedPtr<Program> sharder, SharedPtr<Shader> shader, bool useSync, bool serverSync);
   1542 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1543 
   1544 private:
   1545 	SharedPtr<Program>	m_program;
   1546 	SharedPtr<Shader>	m_shader;
   1547 };
   1548 
   1549 AttachShader::AttachShader (SharedPtr<Program> program, SharedPtr<Shader> shader, bool useSync, bool serverSync)
   1550 	: Operation	("AttachShader", useSync, serverSync)
   1551 	, m_program	(program)
   1552 	, m_shader	(shader)
   1553 {
   1554 	modifyGLObject(SharedPtr<Object>(m_program));
   1555 	readGLObject(SharedPtr<Object>(m_shader));
   1556 
   1557 	if (m_shader->type == GL_VERTEX_SHADER)
   1558 		m_program->vertexShader = shader;
   1559 	else if (m_shader->type == GL_FRAGMENT_SHADER)
   1560 		m_program->fragmentShader = shader;
   1561 	else
   1562 		DE_ASSERT(false);
   1563 }
   1564 
   1565 void AttachShader::exec (tcu::ThreadUtil::Thread& thread)
   1566 {
   1567 	thread.newMessage() << "Begin -- glAttachShader(" << m_program->program << ", " << m_shader->shader << ")" << tcu::ThreadUtil::Message::End;
   1568 	GLU_CHECK_CALL(glAttachShader(m_program->program, m_shader->shader));
   1569 	thread.newMessage() << "End -- glAttachShader()" << tcu::ThreadUtil::Message::End;
   1570 
   1571 	if (m_shader->type == GL_VERTEX_SHADER)
   1572 		m_program->runtimeVertexShader = m_shader->shader;
   1573 	else if (m_shader->type == GL_FRAGMENT_SHADER)
   1574 		m_program->runtimeFragmentShader = m_shader->shader;
   1575 	else
   1576 		DE_ASSERT(false);
   1577 }
   1578 
   1579 class DetachShader : public Operation
   1580 {
   1581 public:
   1582 			DetachShader	(SharedPtr<Program> sharder, GLenum type, bool useSync, bool serverSync);
   1583 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1584 
   1585 private:
   1586 	SharedPtr<Program>	m_program;
   1587 	GLenum				m_type;
   1588 };
   1589 
   1590 DetachShader::DetachShader (SharedPtr<Program> program, GLenum type, bool useSync, bool serverSync)
   1591 	: Operation	("DetachShader", useSync, serverSync)
   1592 	, m_program	(program)
   1593 	, m_type	(type)
   1594 {
   1595 	modifyGLObject(SharedPtr<Object>(m_program));
   1596 
   1597 	if (m_type == GL_VERTEX_SHADER)
   1598 	{
   1599 		DE_ASSERT(m_program->vertexShader);
   1600 		m_program->vertexShader = SharedPtr<Shader>();
   1601 	}
   1602 	else if (m_type == GL_FRAGMENT_SHADER)
   1603 	{
   1604 		DE_ASSERT(m_program->fragmentShader);
   1605 		m_program->fragmentShader = SharedPtr<Shader>();
   1606 	}
   1607 	else
   1608 		DE_ASSERT(false);
   1609 }
   1610 
   1611 void DetachShader::exec (tcu::ThreadUtil::Thread& thread)
   1612 {
   1613 	if (m_type == GL_VERTEX_SHADER)
   1614 	{
   1615 		thread.newMessage() << "Begin -- glDetachShader(" << m_program->program << ", " << m_program->runtimeVertexShader << ")" << tcu::ThreadUtil::Message::End;
   1616 		GLU_CHECK_CALL(glDetachShader(m_program->program, m_program->runtimeVertexShader));
   1617 		thread.newMessage() << "End -- glDetachShader()" << tcu::ThreadUtil::Message::End;
   1618 		m_program->runtimeVertexShader = 0;
   1619 	}
   1620 	else if (m_type == GL_FRAGMENT_SHADER)
   1621 	{
   1622 		thread.newMessage() << "Begin -- glDetachShader(" << m_program->program << ", " << m_program->runtimeFragmentShader << ")" << tcu::ThreadUtil::Message::End;
   1623 		GLU_CHECK_CALL(glDetachShader(m_program->program, m_program->runtimeFragmentShader));
   1624 		thread.newMessage() << "End -- glDetachShader()" << tcu::ThreadUtil::Message::End;
   1625 		m_program->runtimeFragmentShader = 0;
   1626 	}
   1627 	else
   1628 		DE_ASSERT(false);
   1629 }
   1630 
   1631 class LinkProgram : public Operation
   1632 {
   1633 public:
   1634 			LinkProgram	(SharedPtr<Program> program, bool useSync, bool serverSync);
   1635 	void	exec		(tcu::ThreadUtil::Thread& thread);
   1636 
   1637 private:
   1638 	SharedPtr<Program> m_program;
   1639 };
   1640 
   1641 LinkProgram::LinkProgram (SharedPtr<Program> program, bool useSync, bool serverSync)
   1642 	: Operation	("LinkProgram", useSync, serverSync)
   1643 	, m_program	(program)
   1644 {
   1645 	modifyGLObject(SharedPtr<Object>(m_program));
   1646 	program->linked = true;
   1647 }
   1648 
   1649 void LinkProgram::exec (tcu::ThreadUtil::Thread& thread)
   1650 {
   1651 	GLuint program = m_program->program;
   1652 
   1653 	thread.newMessage() << "Begin -- glLinkProgram(" << program << ")" << tcu::ThreadUtil::Message::End;
   1654 	GLU_CHECK_CALL(glLinkProgram(program));
   1655 	thread.newMessage() << "End -- glLinkProgram()" << tcu::ThreadUtil::Message::End;
   1656 }
   1657 
   1658 class RenderBuffer : public Operation
   1659 {
   1660 public:
   1661 			RenderBuffer	(SharedPtr<Program> program, SharedPtr<Buffer> buffer, bool useSync, bool serverSync);
   1662 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1663 
   1664 private:
   1665 	SharedPtr<Program>	m_program;
   1666 	SharedPtr<Buffer>	m_buffer;
   1667 };
   1668 
   1669 RenderBuffer::RenderBuffer (SharedPtr<Program> program, SharedPtr<Buffer> buffer, bool useSync, bool serverSync)
   1670 	: Operation	("RenderBuffer", useSync, serverSync)
   1671 	, m_program	(program)
   1672 	, m_buffer	(buffer)
   1673 {
   1674 	readGLObject(SharedPtr<Object>(program));
   1675 	readGLObject(SharedPtr<Object>(buffer));
   1676 }
   1677 
   1678 void RenderBuffer::exec (tcu::ThreadUtil::Thread& thread)
   1679 {
   1680 	thread.newMessage() << "Begin -- glClearColor(0.5f, 0.5f, 0.5f, 1.0f)" << tcu::ThreadUtil::Message::End;
   1681 	GLU_CHECK_CALL(glClearColor(0.5f, 0.5f, 0.5f, 1.0f));
   1682 	thread.newMessage() << "End -- glClearColor()" << tcu::ThreadUtil::Message::End;
   1683 
   1684 	thread.newMessage() << "Begin -- glClear(GL_COLOR_BUFFER_BIT)" << tcu::ThreadUtil::Message::End;
   1685 	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
   1686 	thread.newMessage() << "End -- glClear()" << tcu::ThreadUtil::Message::End;
   1687 
   1688 	thread.newMessage() << "Begin -- glUseProgram(" << m_program->program << ")" << tcu::ThreadUtil::Message::End;
   1689 	GLU_CHECK_CALL(glUseProgram(m_program->program));
   1690 	thread.newMessage() << "End -- glUseProgram()" << tcu::ThreadUtil::Message::End;
   1691 
   1692 	thread.newMessage() << "Begin -- glGetAttribLocation(" << m_program->program << ", \"a_pos\")" << tcu::ThreadUtil::Message::End;
   1693 	GLint posLoc = glGetAttribLocation(m_program->program, "a_pos");
   1694 	GLU_CHECK_MSG("glGetAttribLocation()");
   1695 	thread.newMessage() << "End -- " << posLoc << " = glGetAttribLocation()" << tcu::ThreadUtil::Message::End;
   1696 
   1697 	thread.newMessage() << "Begin -- glEnableVertexAttribArray(" << posLoc << ")" << tcu::ThreadUtil::Message::End;
   1698 	GLU_CHECK_CALL(glEnableVertexAttribArray(posLoc));
   1699 	thread.newMessage() << "End -- glEnableVertexAttribArray()" << tcu::ThreadUtil::Message::End;
   1700 
   1701 	thread.newMessage() << "Begin -- glBindBuffer(GL_ARRAY_BUFFER, " << m_buffer->buffer << ")" << tcu::ThreadUtil::Message::End;
   1702 	GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_buffer->buffer));
   1703 	thread.newMessage() << "End -- glBindBuffer()" << tcu::ThreadUtil::Message::End;
   1704 
   1705 	thread.newMessage() << "Begin -- glVertexAttribPointer(" << posLoc << ", GL_BYTE, GL_TRUE, 0, 0)" << tcu::ThreadUtil::Message::End;
   1706 	GLU_CHECK_CALL(glVertexAttribPointer(posLoc, 2, GL_BYTE, GL_TRUE, 0, 0));
   1707 	thread.newMessage() << "End -- glVertexAttribPointer()" << tcu::ThreadUtil::Message::End;
   1708 
   1709 	thread.newMessage() << "Begin -- glDrawArrays(GL_TRIANGLES, 0, " << (m_buffer->size / 2) << ")" << tcu::ThreadUtil::Message::End;
   1710 	GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, (GLsizei)m_buffer->size / 2));
   1711 	thread.newMessage() << "End -- glDrawArrays()" << tcu::ThreadUtil::Message::End;
   1712 
   1713 	thread.newMessage() << "Begin -- glBindBuffer(GL_ARRAY_BUFFER, 0)" << tcu::ThreadUtil::Message::End;
   1714 	GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
   1715 	thread.newMessage() << "End -- glBindBuffer()" << tcu::ThreadUtil::Message::End;
   1716 
   1717 	thread.newMessage() << "Begin -- glDisableVertexAttribArray(" << posLoc << ")" << tcu::ThreadUtil::Message::End;
   1718 	GLU_CHECK_CALL(glDisableVertexAttribArray(posLoc));
   1719 	thread.newMessage() << "End -- glDisableVertexAttribArray()" << tcu::ThreadUtil::Message::End;
   1720 
   1721 	thread.newMessage() << "Begin -- glUseProgram(0)" << tcu::ThreadUtil::Message::End;
   1722 	GLU_CHECK_CALL(glUseProgram(0));
   1723 	thread.newMessage() << "End -- glUseProgram()" << tcu::ThreadUtil::Message::End;
   1724 }
   1725 
   1726 class RenderTexture : public Operation
   1727 {
   1728 public:
   1729 			RenderTexture	(SharedPtr<Program> program, SharedPtr<Texture> texture, bool useSync, bool serverSync);
   1730 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1731 
   1732 private:
   1733 	SharedPtr<Program>	m_program;
   1734 	SharedPtr<Texture>	m_texture;
   1735 };
   1736 
   1737 RenderTexture::RenderTexture (SharedPtr<Program> program, SharedPtr<Texture> texture, bool useSync, bool serverSync)
   1738 	: Operation	("RenderTexture", useSync, serverSync)
   1739 	, m_program	(program)
   1740 	, m_texture	(texture)
   1741 {
   1742 	readGLObject(SharedPtr<Object>(program));
   1743 	readGLObject(SharedPtr<Object>(texture));
   1744 }
   1745 
   1746 void RenderTexture::exec (tcu::ThreadUtil::Thread& thread)
   1747 {
   1748 	thread.newMessage() << "Begin -- glClearColor(0.5f, 0.5f, 0.5f, 1.0f)" << tcu::ThreadUtil::Message::End;
   1749 	GLU_CHECK_CALL(glClearColor(0.5f, 0.5f, 0.5f, 1.0f));
   1750 	thread.newMessage() << "End -- glClearColor()" << tcu::ThreadUtil::Message::End;
   1751 
   1752 	thread.newMessage() << "Begin -- glClear(GL_COLOR_BUFFER_BIT)" << tcu::ThreadUtil::Message::End;
   1753 	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
   1754 	thread.newMessage() << "End -- glClear()" << tcu::ThreadUtil::Message::End;
   1755 
   1756 	thread.newMessage() << "Begin -- glUseProgram(" << m_program->program << ")" << tcu::ThreadUtil::Message::End;
   1757 	GLU_CHECK_CALL(glUseProgram(m_program->program));
   1758 	thread.newMessage() << "End -- glUseProgram()" << tcu::ThreadUtil::Message::End;
   1759 
   1760 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, " << m_texture->texture << ")" << tcu::ThreadUtil::Message::End;
   1761 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, m_texture->texture));
   1762 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1763 
   1764 	thread.newMessage() << "Begin -- glGetUniformLocation(" << m_program->program << ", \"u_sampler\")" << tcu::ThreadUtil::Message::End;
   1765 	GLint samplerPos = glGetUniformLocation(m_program->program, "u_sampler");
   1766 	GLU_CHECK_MSG("glGetUniformLocation()");
   1767 	thread.newMessage() << "End -- glGetUniformLocation()" << tcu::ThreadUtil::Message::End;
   1768 
   1769 	thread.newMessage() << "Begin -- glUniform1i(" << samplerPos << ", 0)" << tcu::ThreadUtil::Message::End;
   1770 	GLU_CHECK_CALL(glUniform1i(samplerPos, 0));
   1771 	thread.newMessage() << "End -- glUniform1i()" << tcu::ThreadUtil::Message::End;
   1772 
   1773 
   1774 	thread.newMessage() << "Begin -- glGetAttribLocation(" << m_program->program << ", \"a_pos\")" << tcu::ThreadUtil::Message::End;
   1775 	GLint posLoc = glGetAttribLocation(m_program->program, "a_pos");
   1776 	GLU_CHECK_MSG("glGetAttribLocation()");
   1777 	thread.newMessage() << "End -- " << posLoc << " = glGetAttribLocation()" << tcu::ThreadUtil::Message::End;
   1778 
   1779 	thread.newMessage() << "Begin -- glEnableVertexAttribArray(" << posLoc << ")" << tcu::ThreadUtil::Message::End;
   1780 	GLU_CHECK_CALL(glEnableVertexAttribArray(posLoc));
   1781 	thread.newMessage() << "End -- glEnableVertexAttribArray()" << tcu::ThreadUtil::Message::End;
   1782 
   1783 	thread.newMessage() << "Begin -- glBindBuffer(GL_ARRAY_BUFFER, 0)" << tcu::ThreadUtil::Message::End;
   1784 	GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
   1785 	thread.newMessage() << "End -- glBindBuffer()" << tcu::ThreadUtil::Message::End;
   1786 
   1787 
   1788 	float coords[] = {
   1789 		-1.0, -1.0,
   1790 		 1.0, -1.0,
   1791 		 1.0,  1.0,
   1792 
   1793 		 1.0,  1.0,
   1794 		-1.0,  1.0,
   1795 		-1.0, -1.0
   1796 	};
   1797 
   1798 	thread.newMessage() << "Begin -- glVertexAttribPointer(" << posLoc << ", GL_FLOAT, GL_FALSE, 0, <data>)" << tcu::ThreadUtil::Message::End;
   1799 	GLU_CHECK_CALL(glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, coords));
   1800 	thread.newMessage() << "End -- glVertexAttribPointer()" << tcu::ThreadUtil::Message::End;
   1801 
   1802 	thread.newMessage() << "Begin -- glDrawArrays(GL_TRIANGLES, 0, 6)" << tcu::ThreadUtil::Message::End;
   1803 	GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 6));
   1804 	thread.newMessage() << "End -- glDrawArrays()" << tcu::ThreadUtil::Message::End;
   1805 
   1806 	thread.newMessage() << "Begin -- glBindBuffer(GL_ARRAY_BUFFER, 0)" << tcu::ThreadUtil::Message::End;
   1807 	GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
   1808 	thread.newMessage() << "End -- glBindBuffer()" << tcu::ThreadUtil::Message::End;
   1809 
   1810 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, 0)" << tcu::ThreadUtil::Message::End;
   1811 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0));
   1812 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1813 
   1814 	thread.newMessage() << "Begin -- glDisableVertexAttribArray(" << posLoc << ")" << tcu::ThreadUtil::Message::End;
   1815 	GLU_CHECK_CALL(glDisableVertexAttribArray(posLoc));
   1816 	thread.newMessage() << "End -- glDisableVertexAttribArray()" << tcu::ThreadUtil::Message::End;
   1817 
   1818 	thread.newMessage() << "Begin -- glUseProgram(0)" << tcu::ThreadUtil::Message::End;
   1819 	GLU_CHECK_CALL(glUseProgram(0));
   1820 	thread.newMessage() << "End -- glUseProgram()" << tcu::ThreadUtil::Message::End;
   1821 }
   1822 
   1823 class ReadPixels : public Operation
   1824 {
   1825 public:
   1826 			ReadPixels		(int x, int y, int width, int height, GLenum format, GLenum type, SharedPtr<tcu::ThreadUtil::DataBlock>& data, bool useSync, bool serverSync);
   1827 	void	exec			(tcu::ThreadUtil::Thread& thread);
   1828 
   1829 private:
   1830 	int										m_x;
   1831 	int										m_y;
   1832 	int										m_width;
   1833 	int										m_height;
   1834 	GLenum									m_format;
   1835 	GLenum									m_type;
   1836 	SharedPtr<tcu::ThreadUtil::DataBlock>	m_data;
   1837 };
   1838 
   1839 ReadPixels::ReadPixels (int x, int y, int width, int height, GLenum format, GLenum type, SharedPtr<tcu::ThreadUtil::DataBlock>& data, bool useSync, bool serverSync)
   1840 	: Operation	("ReadPixels", useSync, serverSync)
   1841 	, m_x		(x)
   1842 	, m_y		(y)
   1843 	, m_width	(width)
   1844 	, m_height	(height)
   1845 	, m_format	(format)
   1846 	, m_type	(type)
   1847 {
   1848 	data = SharedPtr<tcu::ThreadUtil::DataBlock>(new tcu::ThreadUtil::DataBlock(getEvent()));
   1849 	m_data = data;
   1850 }
   1851 
   1852 void ReadPixels::exec (tcu::ThreadUtil::Thread& thread)
   1853 {
   1854 	DE_ASSERT(m_type == GL_UNSIGNED_BYTE);
   1855 	DE_ASSERT(m_format == GL_RGBA);
   1856 
   1857 	std::vector<deUint8> data((m_width-m_x)*(m_height-m_y)*4);
   1858 
   1859 	thread.newMessage() << "Begin -- glReadPixels(" << m_x << ", " << m_y << ", " << m_width << ", " << m_height << ", " << m_format << ", " << m_type << ", <data>)" << tcu::ThreadUtil::Message::End;
   1860 	GLU_CHECK_CALL(glReadPixels(m_x, m_y, m_width, m_height, m_format, m_type, &(data[0])));
   1861 	thread.newMessage() << "End -- glReadPixels()" << tcu::ThreadUtil::Message::End;
   1862 
   1863 	m_data->setData(data.size(), &(data[0]));
   1864 }
   1865 
   1866 class CreateImageFromTexture : public Operation
   1867 {
   1868 public:
   1869 	// \note [mika] Unlike eglCreateImageKHR this operation requires current context and uses it for creating EGLImage
   1870 	//				Current context is required to support EGL sync objects in current tests system
   1871 			CreateImageFromTexture	(SharedPtr<EGLImage>& image, SharedPtr<Texture> texture, bool useSync, bool serverSync);
   1872 	void	exec					(tcu::ThreadUtil::Thread& thread);
   1873 
   1874 private:
   1875 	SharedPtr<Texture>		m_texture;
   1876 	SharedPtr<EGLImage>		m_image;
   1877 };
   1878 
   1879 CreateImageFromTexture::CreateImageFromTexture (SharedPtr<EGLImage>& image, SharedPtr<Texture> texture, bool useSync, bool serverSync)
   1880 	: Operation	("CreateImageFromTexture", useSync, serverSync)
   1881 {
   1882 	modifyGLObject(SharedPtr<Object>(texture));
   1883 	image = SharedPtr<EGLImage>(new EGLImage(getEvent(), getSync()));
   1884 
   1885 	m_image					= image;
   1886 	m_texture				= texture;
   1887 	m_texture->sourceImage	= m_image;
   1888 }
   1889 
   1890 void CreateImageFromTexture::exec (tcu::ThreadUtil::Thread& t)
   1891 {
   1892 	EGLThread& thread = *(dynamic_cast<EGLThread*>(&t));
   1893 
   1894 	EGLint attribList[] = {
   1895 		EGL_GL_TEXTURE_LEVEL_KHR, 0,
   1896 		EGL_NONE
   1897 	};
   1898 
   1899 	TCU_CHECK(thread.eglExtensions.createImage);
   1900 
   1901 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, " << m_texture->texture << ")" << tcu::ThreadUtil::Message::End;
   1902 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, m_texture->texture));
   1903 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1904 
   1905 	// Make texture image complete...
   1906 	thread.newMessage() << "Begin -- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)" << tcu::ThreadUtil::Message::End;
   1907 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
   1908 	thread.newMessage() << "End -- glTexParameteri()" << tcu::ThreadUtil::Message::End;
   1909 
   1910 	thread.newMessage() << "Begin -- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)" << tcu::ThreadUtil::Message::End;
   1911 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
   1912 	thread.newMessage() << "End -- glTexParameteri()" << tcu::ThreadUtil::Message::End;
   1913 
   1914 	thread.newMessage() << "Begin -- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)" << tcu::ThreadUtil::Message::End;
   1915 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
   1916 	thread.newMessage() << "End -- glTexParameteri()" << tcu::ThreadUtil::Message::End;
   1917 
   1918 	thread.newMessage() << "Begin -- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)" << tcu::ThreadUtil::Message::End;
   1919 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
   1920 	thread.newMessage() << "End -- glTexParameteri()" << tcu::ThreadUtil::Message::End;
   1921 
   1922 	thread.newMessage() << "Begin -- eglCreateImageKHR(" << thread.runtimeContext->display << ", " << thread.runtimeContext->context << ", EGL_GL_TEXTURE_2D_KHR, " << m_texture->texture << ", { EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_NONE })" << tcu::ThreadUtil::Message::End;
   1923 	m_image->image = thread.eglExtensions.createImage(thread.runtimeContext->display, thread.runtimeContext->context, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(deUintptr)m_texture->texture, attribList);
   1924 	TCU_CHECK_EGL_MSG("eglCreateImageKHR()");
   1925 	thread.newMessage() << "End -- " << m_image->image << " = eglCreateImageKHR()" << tcu::ThreadUtil::Message::End;
   1926 
   1927 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, 0)" << tcu::ThreadUtil::Message::End;
   1928 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0));
   1929 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1930 }
   1931 
   1932 class DestroyImage : public Operation
   1933 {
   1934 public:
   1935 	// \note [mika] Unlike eglDestroyImageKHR this operation requires current context and uses it for creating EGLImage
   1936 	//				Current context is required to support EGL sync objects in current tests system
   1937 			DestroyImage		(SharedPtr<EGLImage> image, bool useSync, bool serverSync);
   1938 	void	exec				(tcu::ThreadUtil::Thread& thread);
   1939 
   1940 private:
   1941 	SharedPtr<EGLImage>		m_image;
   1942 };
   1943 
   1944 DestroyImage::DestroyImage (SharedPtr<EGLImage> image, bool useSync, bool serverSync)
   1945 	: Operation	("CreateImageFromTexture", useSync, serverSync)
   1946 	, m_image	(image)
   1947 {
   1948 	modifyGLObject(SharedPtr<Object>(image));
   1949 }
   1950 
   1951 void DestroyImage::exec (tcu::ThreadUtil::Thread& t)
   1952 {
   1953 	EGLThread& thread = *(dynamic_cast<EGLThread*>(&t));
   1954 
   1955 	TCU_CHECK(thread.eglExtensions.destroyImage);
   1956 
   1957 	thread.newMessage() << "Begin -- eglDestroyImageKHR(" << thread.runtimeContext->display << ", " << m_image->image << ")" << tcu::ThreadUtil::Message::End;
   1958 	thread.eglExtensions.destroyImage(thread.runtimeContext->display, m_image->image);
   1959 	m_image->image = EGL_NO_IMAGE_KHR;
   1960 	TCU_CHECK_EGL_MSG("eglDestroyImageKHR()");
   1961 	thread.newMessage() << "End -- eglDestroyImageKHR()" << tcu::ThreadUtil::Message::End;
   1962 }
   1963 
   1964 class DefineTextureFromImage : public Operation
   1965 {
   1966 public:
   1967 			DefineTextureFromImage	(SharedPtr<Texture> texture, SharedPtr<EGLImage> image, bool useSync, bool serverSync);
   1968 	void	exec					(tcu::ThreadUtil::Thread& thread);
   1969 
   1970 private:
   1971 	SharedPtr<Texture>	m_texture;
   1972 	SharedPtr<EGLImage>	m_image;
   1973 };
   1974 
   1975 DefineTextureFromImage::DefineTextureFromImage (SharedPtr<Texture> texture, SharedPtr<EGLImage> image, bool useSync, bool serverSync)
   1976 	: Operation	("DefineTextureFromImage", useSync, serverSync)
   1977 {
   1978 	readGLObject(SharedPtr<Object>(image));
   1979 	modifyGLObject(SharedPtr<Object>(texture));
   1980 
   1981 	texture->isDefined		= true;
   1982 	texture->sourceImage	= image;
   1983 
   1984 	m_image		= image;
   1985 	m_texture	= texture;
   1986 }
   1987 
   1988 void DefineTextureFromImage::exec (tcu::ThreadUtil::Thread& t)
   1989 {
   1990 	EGLThread& thread = *(dynamic_cast<EGLThread*>(&t));
   1991 
   1992 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, " << m_texture->texture << ")" << tcu::ThreadUtil::Message::End;
   1993 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, m_texture->texture));
   1994 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   1995 
   1996 	thread.newMessage() << "Begin -- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, " << m_image->image << ")" << tcu::ThreadUtil::Message::End;
   1997 	thread.runtimeContext->glExtensions.imageTargetTexture2D(GL_TEXTURE_2D, m_image->image);
   1998 	GLU_CHECK_MSG("glEGLImageTargetTexture2DOES()");
   1999 	thread.newMessage() << "End -- glEGLImageTargetTexture2DOES()" << tcu::ThreadUtil::Message::End;
   2000 
   2001 	thread.newMessage() << "Begin -- glBindTexture(GL_TEXTURE_2D, 0)" << tcu::ThreadUtil::Message::End;
   2002 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0));
   2003 	thread.newMessage() << "End -- glBindTexture()" << tcu::ThreadUtil::Message::End;
   2004 }
   2005 
   2006 } // GLES2ThreadTest
   2007 
   2008 static void requireEGLExtension (EGLDisplay eglDisplay, const char* requiredExtension)
   2009 {
   2010 	// Check extensions
   2011 	bool found = false;
   2012 
   2013 	std::string extensions = eglQueryString(eglDisplay, EGL_EXTENSIONS);
   2014 
   2015 	std::string::size_type pos = extensions.find(" ");
   2016 	do
   2017 	{
   2018 		std::string extension;
   2019 		if (pos != std::string::npos)
   2020 		{
   2021 			extension = extensions.substr(0, pos);
   2022 			extensions = extensions.substr(pos+1);
   2023 		}
   2024 		else
   2025 		{
   2026 			extension = extensions;
   2027 			extensions = "";
   2028 		}
   2029 
   2030 		if (extension == requiredExtension)
   2031 		{
   2032 			found = true;
   2033 			break;
   2034 		}
   2035 		pos = extensions.find(" ");
   2036 	} while (pos != std::string::npos);
   2037 
   2038 	if (!found)
   2039 		throw tcu::NotSupportedError((string(requiredExtension) + " not supported").c_str(), "", __FILE__, __LINE__);
   2040 }
   2041 
   2042 enum OperationId
   2043 {
   2044 	THREADOPERATIONID_NONE = 0,
   2045 
   2046 	THREADOPERATIONID_CREATE_BUFFER,
   2047 	THREADOPERATIONID_DESTROY_BUFFER,
   2048 	THREADOPERATIONID_BUFFER_DATA,
   2049 	THREADOPERATIONID_BUFFER_SUBDATA,
   2050 
   2051 	THREADOPERATIONID_CREATE_TEXTURE,
   2052 	THREADOPERATIONID_DESTROY_TEXTURE,
   2053 	THREADOPERATIONID_TEXIMAGE2D,
   2054 	THREADOPERATIONID_TEXSUBIMAGE2D,
   2055 	THREADOPERATIONID_COPYTEXIMAGE2D,
   2056 	THREADOPERATIONID_COPYTEXSUBIMAGE2D,
   2057 
   2058 	THREADOPERATIONID_CREATE_VERTEX_SHADER,
   2059 	THREADOPERATIONID_CREATE_FRAGMENT_SHADER,
   2060 	THREADOPERATIONID_DESTROY_SHADER,
   2061 	THREADOPERATIONID_SHADER_SOURCE,
   2062 	THREADOPERATIONID_SHADER_COMPILE,
   2063 
   2064 	THREADOPERATIONID_ATTACH_SHADER,
   2065 	THREADOPERATIONID_DETACH_SHADER,
   2066 
   2067 	THREADOPERATIONID_CREATE_PROGRAM,
   2068 	THREADOPERATIONID_DESTROY_PROGRAM,
   2069 	THREADOPERATIONID_LINK_PROGRAM,
   2070 
   2071 	THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE,
   2072 	THREADOPERATIONID_DESTROY_IMAGE,
   2073 	THREADOPERATIONID_TEXTURE_FROM_IMAGE,
   2074 
   2075 	THREADOPERATIONID_LAST
   2076 };
   2077 
   2078 class GLES2SharingRandomTest : public TestCase
   2079 {
   2080 public:
   2081 	struct TestConfig
   2082 	{
   2083 				TestConfig		(void);
   2084 		int		threadCount;
   2085 		int		operationCount;
   2086 		bool	serverSync;
   2087 		bool	useFenceSync;
   2088 		bool	useImages;
   2089 
   2090 		float probabilities[THREADOPERATIONID_LAST][THREADOPERATIONID_LAST];
   2091 	};
   2092 						GLES2SharingRandomTest		(EglTestContext& context, const TestConfig& config, const char* name, const char* description);
   2093 						~GLES2SharingRandomTest		(void);
   2094 
   2095 	void				init						(void);
   2096 	void				deinit						(void);
   2097 	IterateResult		iterate						(void);
   2098 
   2099 	void				addRandomOperation			(GLES2ThreadTest::EGLResourceManager& resourceManager);
   2100 
   2101 private:
   2102 	TestConfig				m_config;
   2103 	int						m_seed;
   2104 	de::Random				m_random;
   2105 	tcu::TestLog&			m_log;
   2106 	bool					m_threadsStarted;
   2107 	bool					m_threadsRunning;
   2108 	bool					m_executionReady;
   2109 	bool					m_requiresRestart;
   2110 	deUint64				m_beginTimeUs;
   2111 	deUint64				m_timeOutUs;
   2112 	deUint32				m_sleepTimeMs;
   2113 	deUint64				m_timeOutTimeUs;
   2114 
   2115 	std::vector<GLES2ThreadTest::EGLThread*>	m_threads;
   2116 
   2117 	EGLDisplay				m_eglDisplay;
   2118 	EGLConfig				m_eglConfig;
   2119 	OperationId				m_lastOperation;
   2120 };
   2121 
   2122 GLES2SharingRandomTest::TestConfig::TestConfig (void)
   2123 	: threadCount		(0)
   2124 	, operationCount	(0)
   2125 	, serverSync		(false)
   2126 	, useFenceSync		(false)
   2127 	, useImages			(false)
   2128 {
   2129 	deMemset(probabilities, 0, sizeof(probabilities));
   2130 }
   2131 
   2132 GLES2SharingRandomTest::GLES2SharingRandomTest (EglTestContext& context, const TestConfig& config, const char* name, const char* description)
   2133 	: TestCase			(context, name, description)
   2134 	, m_config			(config)
   2135 	, m_seed			(deStringHash(name))
   2136 	, m_random			(deStringHash(name))
   2137 	, m_log				(m_testCtx.getLog())
   2138 	, m_threadsStarted	(false)
   2139 	, m_threadsRunning	(false)
   2140 	, m_executionReady	(false)
   2141 	, m_requiresRestart	(false)
   2142 	, m_beginTimeUs		(0)
   2143 	, m_timeOutUs		(10000000)	// 10 seconds
   2144 	, m_sleepTimeMs		(1)		// 1 milliseconds
   2145 	, m_timeOutTimeUs	(0)
   2146 	, m_eglDisplay		(EGL_NO_DISPLAY)
   2147 	, m_eglConfig		(0)
   2148 	, m_lastOperation	(THREADOPERATIONID_NONE)
   2149 {
   2150 }
   2151 
   2152 GLES2SharingRandomTest::~GLES2SharingRandomTest (void)
   2153 {
   2154 	GLES2SharingRandomTest::deinit();
   2155 }
   2156 
   2157 void GLES2SharingRandomTest::init (void)
   2158 {
   2159 	tcu::egl::Display& display = m_eglTestCtx.getDisplay();
   2160 
   2161 	vector<EGLConfig>	configs;
   2162 
   2163 	EGLint attribList[] =
   2164 	{
   2165 		EGL_RENDERABLE_TYPE,	EGL_OPENGL_ES2_BIT,
   2166 		EGL_SURFACE_TYPE,		EGL_WINDOW_BIT,
   2167 		EGL_ALPHA_SIZE,			1,
   2168 		EGL_NONE
   2169 	};
   2170 
   2171 	display.chooseConfig(attribList, configs);
   2172 	m_eglDisplay	= display.getEGLDisplay();
   2173 	m_eglConfig 	= configs[0];
   2174 
   2175 	// Check extensions
   2176 	if (m_config.useFenceSync)
   2177 		requireEGLExtension(m_eglDisplay, "EGL_KHR_fence_sync");
   2178 
   2179 	if (m_config.serverSync)
   2180 		requireEGLExtension(m_eglDisplay, "EGL_KHR_wait_sync");
   2181 
   2182 	if (m_config.useImages)
   2183 	{
   2184 		requireEGLExtension(m_eglDisplay, "EGL_KHR_image_base");
   2185 		requireEGLExtension(m_eglDisplay, "EGL_KHR_gl_texture_2D_image");
   2186 	}
   2187 
   2188 	GLES2ThreadTest::EGLResourceManager resourceManager;
   2189 	// Create contexts
   2190 	for (int threadNdx = 0; threadNdx < m_config.threadCount; threadNdx++)
   2191 	{
   2192 		m_threads.push_back(new GLES2ThreadTest::EGLThread(deInt32Hash(m_seed+threadNdx)));
   2193 		SharedPtr<GLES2ThreadTest::GLES2Context> context;
   2194 		SharedPtr<GLES2ThreadTest::GLES2Context> shared = (threadNdx > 0 ? resourceManager.popContext(0) : SharedPtr<GLES2ThreadTest::GLES2Context>());
   2195 		m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateContext(m_eglDisplay, m_eglConfig, shared, context));
   2196 
   2197 		resourceManager.addContext(context);
   2198 
   2199 		if (shared)
   2200 			resourceManager.addContext(shared);
   2201 	}
   2202 
   2203 	// Create surfaces
   2204 	for (int threadNdx = 0; threadNdx < m_config.threadCount; threadNdx++)
   2205 	{
   2206 		SharedPtr<GLES2ThreadTest::Surface> surface;
   2207 		m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreatePBufferSurface(m_eglDisplay, m_eglConfig, 400, 400, surface));
   2208 		resourceManager.addSurface(surface);
   2209 	}
   2210 
   2211 	// Make contexts current
   2212 	for (int threadNdx = 0; threadNdx < m_config.threadCount; threadNdx++)
   2213 	{
   2214 		m_threads[threadNdx]->addOperation(new GLES2ThreadTest::MakeCurrent(*m_threads[threadNdx], m_eglDisplay, resourceManager.popSurface(0), resourceManager.popContext(0)));
   2215 	}
   2216 
   2217 	// Operations to check fence sync support
   2218 	if (m_config.useFenceSync)
   2219 	{
   2220 		for (int threadNdx = 0; threadNdx < m_config.threadCount; threadNdx++)
   2221 		{
   2222 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::InitGLExtension("GL_OES_EGL_sync"));
   2223 		}
   2224 	}
   2225 
   2226 	// Init EGLimage support
   2227 	if (m_config.useImages)
   2228 	{
   2229 		for (int threadNdx = 0; threadNdx < m_config.threadCount; threadNdx++)
   2230 		{
   2231 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::InitGLExtension("GL_OES_EGL_image"));
   2232 		}
   2233 	}
   2234 
   2235 	// Add random operations
   2236 	for (int operationNdx = 0; operationNdx < m_config.operationCount; operationNdx++)
   2237 		addRandomOperation(resourceManager);
   2238 
   2239 	// Release contexts
   2240 	for (int threadNdx = 0; threadNdx < m_config.threadCount; threadNdx++)
   2241 	{
   2242 		SharedPtr<GLES2ThreadTest::GLES2Context>	context = m_threads[threadNdx]->context;
   2243 		SharedPtr<GLES2ThreadTest::Surface>			surface = m_threads[threadNdx]->surface;
   2244 
   2245 		m_threads[threadNdx]->addOperation(new GLES2ThreadTest::MakeCurrent(*m_threads[threadNdx], m_eglDisplay, SharedPtr<GLES2ThreadTest::Surface>(), SharedPtr<GLES2ThreadTest::GLES2Context>()));
   2246 
   2247 		resourceManager.addSurface(surface);
   2248 		resourceManager.addContext(context);
   2249 	}
   2250 
   2251 	// Destroy contexts
   2252 	for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   2253 		m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DestroyContext(resourceManager.popContext(0)));
   2254 
   2255 	// Destroy surfaces
   2256 	for (int threadNdx = 0; threadNdx < m_config.threadCount; threadNdx++)
   2257 		m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DestroySurface(m_eglDisplay, resourceManager.popSurface(0)));
   2258 }
   2259 
   2260 void GLES2SharingRandomTest::deinit (void)
   2261 {
   2262 	for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   2263 		delete m_threads[threadNdx];
   2264 
   2265 	m_threads.clear();
   2266 
   2267 	TCU_CHECK(!m_requiresRestart);
   2268 }
   2269 
   2270 void GLES2SharingRandomTest::addRandomOperation (GLES2ThreadTest::EGLResourceManager& resourceManager)
   2271 {
   2272 	int threadNdx	= m_random.getUint32() % m_threads.size();
   2273 
   2274 	std::vector<OperationId>	operations;
   2275 	std::vector<float>			weights;
   2276 
   2277 	operations.push_back(THREADOPERATIONID_CREATE_BUFFER);
   2278 	weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_BUFFER]);
   2279 
   2280 	operations.push_back(THREADOPERATIONID_CREATE_TEXTURE);
   2281 	weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_TEXTURE]);
   2282 
   2283 	operations.push_back(THREADOPERATIONID_CREATE_VERTEX_SHADER);
   2284 	weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_VERTEX_SHADER]);
   2285 
   2286 	operations.push_back(THREADOPERATIONID_CREATE_FRAGMENT_SHADER);
   2287 	weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]);
   2288 
   2289 	operations.push_back(THREADOPERATIONID_CREATE_PROGRAM);
   2290 	weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_PROGRAM]);
   2291 
   2292 	int destroyableBufferNdx				= -1;
   2293 	int destroyableTextureNdx				= -1;
   2294 	int destroyableShaderNdx				= -1;
   2295 	int destroyableProgramNdx				= -1;
   2296 
   2297 	int vertexShaderNdx						= -1;
   2298 	int fragmentShaderNdx					= -1;
   2299 
   2300 	int definedTextureNdx					= -1;
   2301 
   2302 	int definedBufferNdx					= -1;
   2303 
   2304 	int definedShaderNdx					= -1;
   2305 
   2306 	int detachableProgramNdx				= -1;
   2307 	GLenum detachShaderType					= GL_VERTEX_SHADER;
   2308 
   2309 	int unusedVertexAttachmentProgramNdx	= -1;
   2310 	int unusedFragmentAttachmentProgramNdx	= -1;
   2311 
   2312 	int linkableProgramNdx					= -1;
   2313 
   2314 	int attachProgramNdx					= -1;
   2315 	int attachShaderNdx						= -1;
   2316 
   2317 	int nonSiblingTextureNdx				= -1;
   2318 
   2319 	if (m_threads[threadNdx]->context->resourceManager->getBufferCount() > 0)
   2320 		destroyableBufferNdx = m_random.getUint32() % m_threads[threadNdx]->context->resourceManager->getBufferCount();
   2321 
   2322 	if (m_threads[threadNdx]->context->resourceManager->getTextureCount() > 0)
   2323 		destroyableTextureNdx = m_random.getUint32() % m_threads[threadNdx]->context->resourceManager->getTextureCount();
   2324 
   2325 	if (m_threads[threadNdx]->context->resourceManager->getShaderCount() > 0)
   2326 		destroyableShaderNdx = m_random.getUint32() % m_threads[threadNdx]->context->resourceManager->getShaderCount();
   2327 
   2328 	if (m_threads[threadNdx]->context->resourceManager->getProgramCount() > 0)
   2329 		destroyableProgramNdx = m_random.getUint32() % m_threads[threadNdx]->context->resourceManager->getProgramCount();
   2330 
   2331 	// Check what kind of buffers we have
   2332 	for (int bufferNdx = 0; bufferNdx < m_threads[threadNdx]->context->resourceManager->getBufferCount(); bufferNdx++)
   2333 	{
   2334 		SharedPtr<GLES2ThreadTest::Buffer> buffer = m_threads[threadNdx]->context->resourceManager->getBuffer(bufferNdx);
   2335 
   2336 		if (buffer->isDefined)
   2337 		{
   2338 			if (definedBufferNdx == -1)
   2339 				definedBufferNdx = bufferNdx;
   2340 			else if (m_random.getBool())
   2341 				definedBufferNdx = bufferNdx;
   2342 		}
   2343 	}
   2344 
   2345 	// Check what kind of textures we have
   2346 	for (int textureNdx = 0; textureNdx < m_threads[threadNdx]->context->resourceManager->getTextureCount(); textureNdx++)
   2347 	{
   2348 		SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->getTexture(textureNdx);
   2349 
   2350 		if (texture->isDefined)
   2351 		{
   2352 			if (definedTextureNdx == -1)
   2353 				definedTextureNdx = textureNdx;
   2354 			else if (m_random.getBool())
   2355 				definedTextureNdx = textureNdx;
   2356 
   2357 			if (!texture->sourceImage)
   2358 			{
   2359 				if (nonSiblingTextureNdx == -1)
   2360 					nonSiblingTextureNdx = textureNdx;
   2361 				else if (m_random.getBool())
   2362 					nonSiblingTextureNdx = textureNdx;
   2363 			}
   2364 		}
   2365 
   2366 	}
   2367 
   2368 	// Check what kind of shaders we have
   2369 	for (int shaderNdx = 0; shaderNdx < m_threads[threadNdx]->context->resourceManager->getShaderCount(); shaderNdx++)
   2370 	{
   2371 		SharedPtr<GLES2ThreadTest::Shader> shader = m_threads[threadNdx]->context->resourceManager->getShader(shaderNdx);
   2372 
   2373 		// Defined shader found
   2374 		if (shader->isDefined)
   2375 		{
   2376 			if (definedShaderNdx == -1)
   2377 				definedShaderNdx = shaderNdx;
   2378 			else if (m_random.getBool())
   2379 				definedShaderNdx = shaderNdx;
   2380 		}
   2381 
   2382 		// Vertex shader found
   2383 		if (shader->type == GL_VERTEX_SHADER)
   2384 		{
   2385 			if (vertexShaderNdx == -1)
   2386 				vertexShaderNdx = shaderNdx;
   2387 			else if (m_random.getBool())
   2388 				vertexShaderNdx = shaderNdx;
   2389 		}
   2390 
   2391 		// Fragmet shader found
   2392 		if (shader->type == GL_FRAGMENT_SHADER)
   2393 		{
   2394 			if (fragmentShaderNdx == -1)
   2395 				fragmentShaderNdx = shaderNdx;
   2396 			else if (m_random.getBool())
   2397 				fragmentShaderNdx = shaderNdx;
   2398 		}
   2399 	}
   2400 
   2401 	// Check what kind of programs we have
   2402 	for (int programNdx = 0; programNdx < m_threads[threadNdx]->context->resourceManager->getProgramCount(); programNdx++)
   2403 	{
   2404 		SharedPtr<GLES2ThreadTest::Program> program = m_threads[threadNdx]->context->resourceManager->getProgram(programNdx);
   2405 
   2406 		// Program that can be detached
   2407 		if (program->vertexShader || program->fragmentShader)
   2408 		{
   2409 			if (detachableProgramNdx == -1)
   2410 			{
   2411 				detachableProgramNdx = programNdx;
   2412 
   2413 				if (program->vertexShader)
   2414 					detachShaderType = GL_VERTEX_SHADER;
   2415 				else if (program->fragmentShader)
   2416 					detachShaderType = GL_FRAGMENT_SHADER;
   2417 				else
   2418 					DE_ASSERT(false);
   2419 			}
   2420 			else if (m_random.getBool())
   2421 			{
   2422 				detachableProgramNdx = programNdx;
   2423 
   2424 				if (program->vertexShader)
   2425 					detachShaderType = GL_VERTEX_SHADER;
   2426 				else if (program->fragmentShader)
   2427 					detachShaderType = GL_FRAGMENT_SHADER;
   2428 				else
   2429 					DE_ASSERT(false);
   2430 			}
   2431 		}
   2432 
   2433 		// Program that can be attached vertex shader
   2434 		if (!program->vertexShader)
   2435 		{
   2436 			if (unusedVertexAttachmentProgramNdx == -1)
   2437 				unusedVertexAttachmentProgramNdx = programNdx;
   2438 			else if (m_random.getBool())
   2439 				unusedVertexAttachmentProgramNdx = programNdx;
   2440 		}
   2441 
   2442 		// Program that can be attached fragment shader
   2443 		if (!program->fragmentShader)
   2444 		{
   2445 			if (unusedFragmentAttachmentProgramNdx == -1)
   2446 				unusedFragmentAttachmentProgramNdx = programNdx;
   2447 			else if (m_random.getBool())
   2448 				unusedFragmentAttachmentProgramNdx = programNdx;
   2449 		}
   2450 
   2451 		// Program that can be linked
   2452 		if (program->vertexShader && program->fragmentShader)
   2453 		{
   2454 			if (linkableProgramNdx == -1)
   2455 				linkableProgramNdx = programNdx;
   2456 			else if (m_random.getBool())
   2457 				linkableProgramNdx = programNdx;
   2458 		}
   2459 	}
   2460 
   2461 	// Has images
   2462 	if (resourceManager.getImageCount() > 0)
   2463 	{
   2464 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DESTROY_IMAGE]);
   2465 		operations.push_back(THREADOPERATIONID_DESTROY_IMAGE);
   2466 
   2467 		if (m_threads[threadNdx]->context->resourceManager->getTextureCount() > 0)
   2468 		{
   2469 			weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_TEXTURE_FROM_IMAGE]);
   2470 			operations.push_back(THREADOPERATIONID_TEXTURE_FROM_IMAGE);
   2471 		}
   2472 	}
   2473 
   2474 	// Has buffer
   2475 	if (destroyableBufferNdx != -1)
   2476 	{
   2477 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DESTROY_BUFFER]);
   2478 		operations.push_back(THREADOPERATIONID_DESTROY_BUFFER);
   2479 
   2480 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_BUFFER_DATA]);
   2481 		operations.push_back(THREADOPERATIONID_BUFFER_DATA);
   2482 	}
   2483 
   2484 	// Has buffer with defined data
   2485 	if (definedBufferNdx != -1)
   2486 	{
   2487 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_BUFFER_SUBDATA]);
   2488 		operations.push_back(THREADOPERATIONID_BUFFER_SUBDATA);
   2489 	}
   2490 
   2491 	// Has texture
   2492 	if (destroyableTextureNdx != -1)
   2493 	{
   2494 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DESTROY_TEXTURE]);
   2495 		operations.push_back(THREADOPERATIONID_DESTROY_TEXTURE);
   2496 
   2497 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_TEXIMAGE2D]);
   2498 		operations.push_back(THREADOPERATIONID_TEXIMAGE2D);
   2499 
   2500 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_COPYTEXIMAGE2D]);
   2501 		operations.push_back(THREADOPERATIONID_COPYTEXIMAGE2D);
   2502 	}
   2503 
   2504 	// Has texture with data
   2505 	if (definedTextureNdx != -1)
   2506 	{
   2507 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_TEXSUBIMAGE2D]);
   2508 		operations.push_back(THREADOPERATIONID_TEXSUBIMAGE2D);
   2509 
   2510 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_COPYTEXSUBIMAGE2D]);
   2511 		operations.push_back(THREADOPERATIONID_COPYTEXSUBIMAGE2D);
   2512 	}
   2513 
   2514 	// Has texture that can be used as EGLimage source
   2515 	if (nonSiblingTextureNdx != -1)
   2516 	{
   2517 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]);
   2518 		operations.push_back(THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE);
   2519 	}
   2520 
   2521 	// Has shader
   2522 	if (destroyableShaderNdx != -1)
   2523 	{
   2524 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DESTROY_SHADER]);
   2525 		operations.push_back(THREADOPERATIONID_DESTROY_SHADER);
   2526 
   2527 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_SHADER_SOURCE]);
   2528 		operations.push_back(THREADOPERATIONID_SHADER_SOURCE);
   2529 	}
   2530 
   2531 	// Has shader with defined source
   2532 	if (definedShaderNdx != -1)
   2533 	{
   2534 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_SHADER_COMPILE]);
   2535 		operations.push_back(THREADOPERATIONID_SHADER_COMPILE);
   2536 	}
   2537 
   2538 	// Has program
   2539 	if (destroyableProgramNdx != -1)
   2540 	{
   2541 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DESTROY_PROGRAM]);
   2542 		operations.push_back(THREADOPERATIONID_DESTROY_PROGRAM);
   2543 	}
   2544 
   2545 	// Has program that can be linked
   2546 	if (linkableProgramNdx != -1)
   2547 	{
   2548 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_LINK_PROGRAM]);
   2549 		operations.push_back(THREADOPERATIONID_LINK_PROGRAM);
   2550 	}
   2551 
   2552 	// has program with attachments
   2553 	if (detachableProgramNdx != -1)
   2554 	{
   2555 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DETACH_SHADER]);
   2556 		operations.push_back(THREADOPERATIONID_DETACH_SHADER);
   2557 	}
   2558 
   2559 	// Has program and shader pair that can be attached
   2560 	if (fragmentShaderNdx != -1 && unusedFragmentAttachmentProgramNdx != -1)
   2561 	{
   2562 		if (attachProgramNdx == -1)
   2563 		{
   2564 			DE_ASSERT(attachShaderNdx == -1);
   2565 			attachProgramNdx = unusedFragmentAttachmentProgramNdx;
   2566 			attachShaderNdx = fragmentShaderNdx;
   2567 
   2568 			weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_ATTACH_SHADER]);
   2569 			operations.push_back(THREADOPERATIONID_ATTACH_SHADER);
   2570 		}
   2571 		else if (m_random.getBool())
   2572 		{
   2573 			attachProgramNdx = unusedFragmentAttachmentProgramNdx;
   2574 			attachShaderNdx = fragmentShaderNdx;
   2575 		}
   2576 	}
   2577 
   2578 	if (vertexShaderNdx != -1 && unusedVertexAttachmentProgramNdx != -1)
   2579 	{
   2580 		if (attachProgramNdx == -1)
   2581 		{
   2582 			DE_ASSERT(attachShaderNdx == -1);
   2583 			attachProgramNdx = unusedVertexAttachmentProgramNdx;
   2584 			attachShaderNdx = vertexShaderNdx;
   2585 
   2586 			weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_ATTACH_SHADER]);
   2587 			operations.push_back(THREADOPERATIONID_ATTACH_SHADER);
   2588 		}
   2589 		else if (m_random.getBool())
   2590 		{
   2591 			attachProgramNdx = unusedVertexAttachmentProgramNdx;
   2592 			attachShaderNdx = vertexShaderNdx;
   2593 		}
   2594 	}
   2595 
   2596 	OperationId op = m_random.chooseWeighted<OperationId, std::vector<OperationId> ::iterator>(operations.begin(), operations.end(), weights.begin());
   2597 
   2598 	switch (op)
   2599 	{
   2600 		case THREADOPERATIONID_CREATE_BUFFER:
   2601 		{
   2602 			SharedPtr<GLES2ThreadTest::Buffer> buffer;
   2603 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateBuffer(buffer, m_config.useFenceSync, m_config.serverSync));
   2604 			m_threads[threadNdx]->context->resourceManager->addBuffer(buffer);
   2605 			break;
   2606 		}
   2607 
   2608 		case THREADOPERATIONID_DESTROY_BUFFER:
   2609 		{
   2610 			SharedPtr<GLES2ThreadTest::Buffer> buffer = m_threads[threadNdx]->context->resourceManager->popBuffer(destroyableBufferNdx);
   2611 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DeleteBuffer(buffer, m_config.useFenceSync, m_config.serverSync));
   2612 			break;
   2613 		}
   2614 
   2615 		case THREADOPERATIONID_BUFFER_DATA:
   2616 		{
   2617 			SharedPtr<GLES2ThreadTest::Buffer> buffer = m_threads[threadNdx]->context->resourceManager->popBuffer(destroyableBufferNdx);
   2618 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::BufferData(buffer, GL_ARRAY_BUFFER, 1024, GL_DYNAMIC_DRAW, m_config.useFenceSync, m_config.serverSync));
   2619 			m_threads[threadNdx]->context->resourceManager->addBuffer(buffer);
   2620 			break;
   2621 		}
   2622 
   2623 		case THREADOPERATIONID_BUFFER_SUBDATA:
   2624 		{
   2625 			SharedPtr<GLES2ThreadTest::Buffer> buffer = m_threads[threadNdx]->context->resourceManager->popBuffer(definedBufferNdx);
   2626 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::BufferSubData(buffer, GL_ARRAY_BUFFER, 1, 20, m_config.useFenceSync, m_config.serverSync));
   2627 			m_threads[threadNdx]->context->resourceManager->addBuffer(buffer);
   2628 			break;
   2629 		}
   2630 
   2631 		case THREADOPERATIONID_CREATE_TEXTURE:
   2632 		{
   2633 			SharedPtr<GLES2ThreadTest::Texture> texture;
   2634 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateTexture(texture, m_config.useFenceSync, m_config.serverSync));
   2635 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
   2636 			break;
   2637 		}
   2638 
   2639 		case THREADOPERATIONID_DESTROY_TEXTURE:
   2640 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DeleteTexture(m_threads[threadNdx]->context->resourceManager->popTexture(destroyableTextureNdx), m_config.useFenceSync, m_config.serverSync));
   2641 			break;
   2642 
   2643 		case THREADOPERATIONID_TEXIMAGE2D:
   2644 		{
   2645 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(destroyableTextureNdx);
   2646 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::TexImage2D(texture, 0, GL_RGBA, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
   2647 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
   2648 			break;
   2649 		}
   2650 
   2651 		case THREADOPERATIONID_TEXSUBIMAGE2D:
   2652 		{
   2653 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(definedTextureNdx);
   2654 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::TexSubImage2D(texture, 0, 30, 30, 50, 50, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
   2655 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
   2656 			break;
   2657 		}
   2658 
   2659 		case THREADOPERATIONID_COPYTEXIMAGE2D:
   2660 		{
   2661 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(destroyableTextureNdx);
   2662 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CopyTexImage2D(texture, 0, GL_RGBA, 20, 20, 300, 300, 0, m_config.useFenceSync, m_config.serverSync));
   2663 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
   2664 			break;
   2665 		}
   2666 
   2667 		case THREADOPERATIONID_COPYTEXSUBIMAGE2D:
   2668 		{
   2669 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(definedTextureNdx);
   2670 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CopyTexSubImage2D(texture, 0, 10, 10, 30, 30, 50, 50, m_config.useFenceSync, m_config.serverSync));
   2671 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
   2672 			break;
   2673 		}
   2674 
   2675 		case THREADOPERATIONID_CREATE_VERTEX_SHADER:
   2676 		{
   2677 			SharedPtr<GLES2ThreadTest::Shader> shader;
   2678 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateShader(GL_VERTEX_SHADER, shader, m_config.useFenceSync, m_config.serverSync));
   2679 			m_threads[threadNdx]->context->resourceManager->addShader(shader);
   2680 			break;
   2681 		}
   2682 
   2683 		case THREADOPERATIONID_CREATE_FRAGMENT_SHADER:
   2684 		{
   2685 			SharedPtr<GLES2ThreadTest::Shader> shader;
   2686 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateShader(GL_FRAGMENT_SHADER, shader, m_config.useFenceSync, m_config.serverSync));
   2687 			m_threads[threadNdx]->context->resourceManager->addShader(shader);
   2688 			break;
   2689 		}
   2690 
   2691 		case THREADOPERATIONID_DESTROY_SHADER:
   2692 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DeleteShader(m_threads[threadNdx]->context->resourceManager->popShader(destroyableShaderNdx), m_config.useFenceSync, m_config.serverSync));
   2693 			break;
   2694 
   2695 		case THREADOPERATIONID_SHADER_SOURCE:
   2696 		{
   2697 			const char* vertexShaderSource =
   2698 				"attribute mediump vec4 a_pos;\n"
   2699 				"varying mediump vec4 v_pos;\n"
   2700 				"void main (void)\n"
   2701 				"{\n"
   2702 				"\tv_pos = a_pos;\n"
   2703 				"\tgl_Position = a_pos;\n"
   2704 				"}\n";
   2705 
   2706 			const char* fragmentShaderSource =
   2707 				"varying mediump vec4 v_pos;\n"
   2708 				"void main (void)\n"
   2709 				"{\n"
   2710 				"\tgl_FragColor = v_pos;\n"
   2711 				"}\n";
   2712 			SharedPtr<GLES2ThreadTest::Shader> shader = m_threads[threadNdx]->context->resourceManager->popShader(destroyableShaderNdx);
   2713 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::ShaderSource(shader, (shader->type == GL_VERTEX_SHADER ? vertexShaderSource : fragmentShaderSource), m_config.useFenceSync, m_config.serverSync));
   2714 			m_threads[threadNdx]->context->resourceManager->addShader(shader);
   2715 			break;
   2716 		}
   2717 
   2718 		case THREADOPERATIONID_SHADER_COMPILE:
   2719 		{
   2720 			SharedPtr<GLES2ThreadTest::Shader> shader = m_threads[threadNdx]->context->resourceManager->popShader(definedShaderNdx);
   2721 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::ShaderCompile(shader, m_config.useFenceSync, m_config.serverSync));
   2722 			m_threads[threadNdx]->context->resourceManager->addShader(shader);
   2723 			break;
   2724 		}
   2725 
   2726 		case THREADOPERATIONID_CREATE_PROGRAM:
   2727 		{
   2728 			SharedPtr<GLES2ThreadTest::Program> program;
   2729 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateProgram(program, m_config.useFenceSync, m_config.serverSync));
   2730 			m_threads[threadNdx]->context->resourceManager->addProgram(program);
   2731 			break;
   2732 		}
   2733 
   2734 		case THREADOPERATIONID_DESTROY_PROGRAM:
   2735 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DeleteProgram(m_threads[threadNdx]->context->resourceManager->popProgram(destroyableProgramNdx), m_config.useFenceSync, m_config.serverSync));
   2736 			break;
   2737 
   2738 		case THREADOPERATIONID_ATTACH_SHADER:
   2739 		{
   2740 			SharedPtr<GLES2ThreadTest::Program>	program = m_threads[threadNdx]->context->resourceManager->popProgram(attachProgramNdx);
   2741 			SharedPtr<GLES2ThreadTest::Shader>	shader	= m_threads[threadNdx]->context->resourceManager->popShader(attachShaderNdx);
   2742 
   2743 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::AttachShader(program, shader, m_config.useFenceSync, m_config.serverSync));
   2744 
   2745 			m_threads[threadNdx]->context->resourceManager->addProgram(program);
   2746 			m_threads[threadNdx]->context->resourceManager->addShader(shader);
   2747 			break;
   2748 		}
   2749 
   2750 		case THREADOPERATIONID_DETACH_SHADER:
   2751 		{
   2752 			SharedPtr<GLES2ThreadTest::Program>	program = m_threads[threadNdx]->context->resourceManager->popProgram(detachableProgramNdx);
   2753 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DetachShader(program, detachShaderType, m_config.useFenceSync, m_config.serverSync));
   2754 			m_threads[threadNdx]->context->resourceManager->addProgram(program);
   2755 			break;
   2756 		}
   2757 
   2758 		case THREADOPERATIONID_LINK_PROGRAM:
   2759 		{
   2760 			SharedPtr<GLES2ThreadTest::Program>	program = m_threads[threadNdx]->context->resourceManager->popProgram(linkableProgramNdx);
   2761 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
   2762 			m_threads[threadNdx]->context->resourceManager->addProgram(program);
   2763 			break;
   2764 		}
   2765 
   2766 		case THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE:
   2767 		{
   2768 			SharedPtr<GLES2ThreadTest::EGLImage> image;
   2769 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(nonSiblingTextureNdx);
   2770 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateImageFromTexture(image, texture, m_config.useFenceSync, m_config.serverSync));
   2771 			// \note [mika] Can source be added back to resourceManager?
   2772 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
   2773 			resourceManager.addImage(image);
   2774 			break;
   2775 		}
   2776 
   2777 		case THREADOPERATIONID_DESTROY_IMAGE:
   2778 		{
   2779 			int imageNdx = m_random.getInt(0, resourceManager.getImageCount()-1);
   2780 			SharedPtr<GLES2ThreadTest::EGLImage> image = resourceManager.popImage(imageNdx);
   2781 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DestroyImage(image, m_config.useFenceSync, m_config.serverSync));
   2782 			break;
   2783 		}
   2784 
   2785 		case THREADOPERATIONID_TEXTURE_FROM_IMAGE:
   2786 		{
   2787 			int imageNdx = m_random.getInt(0, resourceManager.getImageCount()-1);
   2788 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(destroyableTextureNdx);
   2789 			SharedPtr<GLES2ThreadTest::EGLImage> image = resourceManager.popImage(imageNdx);
   2790 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DefineTextureFromImage(texture, image, m_config.useFenceSync, m_config.serverSync));
   2791 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
   2792 			resourceManager.addImage(image);
   2793 			break;
   2794 		}
   2795 
   2796 		default:
   2797 			DE_ASSERT(false);
   2798 	}
   2799 
   2800 	m_lastOperation = op;
   2801 }
   2802 
   2803 tcu::TestCase::IterateResult GLES2SharingRandomTest::iterate (void)
   2804 {
   2805 	if (!m_threadsStarted)
   2806 	{
   2807 		m_beginTimeUs = deGetMicroseconds();
   2808 
   2809 		// Execute threads
   2810 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   2811 			m_threads[threadNdx]->exec();
   2812 
   2813 		m_threadsStarted = true;
   2814 		m_threadsRunning = true;
   2815 	}
   2816 
   2817 	if (m_threadsRunning)
   2818 	{
   2819 		// Wait threads to finish
   2820 		int readyThreads = 0;
   2821 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   2822 		{
   2823 			if (m_threads[threadNdx]->getStatus() != tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING)
   2824 				readyThreads++;
   2825 		}
   2826 
   2827 		if (readyThreads == (int)m_threads.size())
   2828 		{
   2829 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   2830 				m_threads[threadNdx]->join();
   2831 
   2832 			m_executionReady	= true;
   2833 			m_requiresRestart	= false;
   2834 		}
   2835 
   2836 		if (deGetMicroseconds() - m_beginTimeUs > m_timeOutUs)
   2837 		{
   2838 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   2839 			{
   2840 				if (m_threads[threadNdx]->getStatus() != tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING)
   2841 				{
   2842 					if (m_threads[threadNdx]->isStarted())
   2843 						m_threads[threadNdx]->join();
   2844 				}
   2845 			}
   2846 			m_executionReady	= true;
   2847 			m_requiresRestart	= true;
   2848 			m_timeOutTimeUs		= deGetMicroseconds();
   2849 		}
   2850 		else
   2851 		{
   2852 			deSleep(m_sleepTimeMs);
   2853 		}
   2854 	}
   2855 
   2856 	if (m_executionReady)
   2857 	{
   2858 		std::vector<int> indices(m_threads.size(), 0);
   2859 		while (true)
   2860 		{
   2861 			int 		firstThread = -1;
   2862 
   2863 			// Find first thread with messages
   2864 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   2865 			{
   2866 				if (m_threads[threadNdx]->getMessageCount() > indices[threadNdx])
   2867 				{
   2868 					firstThread = threadNdx;
   2869 					break;
   2870 				}
   2871 			}
   2872 
   2873 			// No more messages
   2874 			if (firstThread == -1)
   2875 				break;
   2876 
   2877 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   2878 			{
   2879 				// No more messages in this thread
   2880 				if (m_threads[threadNdx]->getMessageCount() <= indices[threadNdx])
   2881 					continue;
   2882 
   2883 				if ((m_threads[threadNdx]->getMessage(indices[threadNdx]).getTime() - m_beginTimeUs) < (m_threads[firstThread]->getMessage(indices[firstThread]).getTime() - m_beginTimeUs))
   2884 					firstThread = threadNdx;
   2885 			}
   2886 
   2887 			deUint64	time	= m_threads[firstThread]->getMessage(indices[firstThread]).getTime();
   2888 			std::string	message	= m_threads[firstThread]->getMessage(indices[firstThread]).getMessage();
   2889 			m_log << tcu::TestLog::Message << "[" << (time - m_beginTimeUs) << "] (" << firstThread << ") " << message << tcu::TestLog::EndMessage;
   2890 			indices[firstThread]++;
   2891 		}
   2892 
   2893 		bool isOk = true;
   2894 		bool notSupported = false;
   2895 
   2896 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   2897 		{
   2898 			if (m_threads[threadNdx]->getStatus() == tcu::ThreadUtil::Thread::THREADSTATUS_FAILED)
   2899 				isOk = false;
   2900 			else if (m_threads[threadNdx]->getStatus() == tcu::ThreadUtil::Thread::THREADSTATUS_READY)
   2901 				isOk &= true;
   2902 			else if (m_threads[threadNdx]->getStatus() == tcu::ThreadUtil::Thread::THREADSTATUS_NOT_SUPPORTED)
   2903 				notSupported = true;
   2904 			else
   2905 			{
   2906 				isOk = false;
   2907 				DE_ASSERT(false);
   2908 			}
   2909 
   2910 		}
   2911 
   2912 		if (m_timeOutTimeUs != 0)
   2913 		{
   2914 			m_log << tcu::TestLog::Message << "[" << (m_timeOutTimeUs - m_beginTimeUs) << "] Execution timeout limit reached" << tcu::TestLog::EndMessage;
   2915 		}
   2916 
   2917 		if (notSupported)
   2918 			throw tcu::NotSupportedError("Thread threw tcu::NotSupportedError", "", __FILE__, __LINE__);
   2919 
   2920 		if (isOk)
   2921 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2922 		else
   2923 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2924 
   2925 		return STOP;
   2926 	}
   2927 
   2928 	return CONTINUE;
   2929 }
   2930 
   2931 class GLES2ThreadedSharingTest : public TestCase
   2932 {
   2933 public:
   2934 	struct TestConfig
   2935 	{
   2936 		enum ResourceType
   2937 		{
   2938 			RESOURCETYPE_BUFFER = 0,
   2939 			RESOURCETYPE_TEXTURE,
   2940 			RESOURCETYPE_VERTEX_SHADER,
   2941 			RESOURCETYPE_FRAGMENT_SHADER,
   2942 			RESOURCETYPE_PROGRAM,
   2943 			RESOURCETYPE_IMAGE
   2944 		};
   2945 
   2946 		ResourceType	resourceType;
   2947 		bool			singleContext;
   2948 		int				define;
   2949 		int				modify;
   2950 		bool			useFenceSync;
   2951 		bool			serverSync;
   2952 		bool			render;
   2953 	};
   2954 						GLES2ThreadedSharingTest	(EglTestContext& context, const TestConfig& config, const char* name, const char* description);
   2955 						~GLES2ThreadedSharingTest	(void);
   2956 
   2957 	void				init						(void);
   2958 	void				deinit						(void);
   2959 	IterateResult		iterate						(void);
   2960 
   2961 	void				addBufferOperations			(void);
   2962 	void				addTextureOperations		(void);
   2963 	void				addImageOperations			(void);
   2964 	void				addShaderOperations			(GLenum type);
   2965 	void				addProgramOperations		(void);
   2966 
   2967 private:
   2968 	TestConfig				m_config;
   2969 	tcu::TestLog&			m_log;
   2970 	int						m_seed;
   2971 	bool					m_threadsStarted;
   2972 	bool					m_threadsRunning;
   2973 	bool					m_executionReady;
   2974 	bool					m_requiresRestart;
   2975 	deUint64				m_beginTimeUs;
   2976 	deUint64				m_timeOutUs;
   2977 	deUint32				m_sleepTimeMs;
   2978 	deUint64				m_timeOutTimeUs;
   2979 
   2980 	std::vector<GLES2ThreadTest::EGLThread*>	m_threads;
   2981 
   2982 	EGLDisplay				m_eglDisplay;
   2983 	EGLConfig				m_eglConfig;
   2984 };
   2985 
   2986 GLES2ThreadedSharingTest::GLES2ThreadedSharingTest (EglTestContext& context, const TestConfig& config, const char* name, const char* description)
   2987 	: TestCase			(context, name, description)
   2988 	, m_config			(config)
   2989 	, m_log				(m_testCtx.getLog())
   2990 	, m_seed			(deStringHash(name))
   2991 	, m_threadsStarted	(false)
   2992 	, m_threadsRunning	(false)
   2993 	, m_executionReady	(false)
   2994 	, m_requiresRestart	(false)
   2995 	, m_beginTimeUs		(0)
   2996 	, m_timeOutUs		(10000000)	// 10 seconds
   2997 	, m_sleepTimeMs		(1)			// 1 milliseconds
   2998 	, m_timeOutTimeUs	(0)
   2999 	, m_eglDisplay		(EGL_NO_DISPLAY)
   3000 	, m_eglConfig		(0)
   3001 {
   3002 }
   3003 
   3004 GLES2ThreadedSharingTest::~GLES2ThreadedSharingTest (void)
   3005 {
   3006 	GLES2ThreadedSharingTest::deinit();
   3007 }
   3008 
   3009 void GLES2ThreadedSharingTest::init (void)
   3010 {
   3011 	tcu::egl::Display& display = m_eglTestCtx.getDisplay();
   3012 
   3013 	vector<EGLConfig>	configs;
   3014 
   3015 	EGLint attribList[] =
   3016 	{
   3017 		EGL_RENDERABLE_TYPE,	EGL_OPENGL_ES2_BIT,
   3018 		EGL_SURFACE_TYPE,		EGL_WINDOW_BIT,
   3019 		EGL_ALPHA_SIZE,			1,
   3020 		EGL_NONE
   3021 	};
   3022 
   3023 	display.chooseConfig(attribList, configs);
   3024 	m_eglDisplay	= display.getEGLDisplay();
   3025 	m_eglConfig 	= configs[0];
   3026 
   3027 	// Check extensions
   3028 	if (m_config.useFenceSync)
   3029 		requireEGLExtension(m_eglDisplay, "EGL_KHR_fence_sync");
   3030 
   3031 	if (m_config.serverSync)
   3032 		requireEGLExtension(m_eglDisplay, "EGL_KHR_wait_sync");
   3033 
   3034 	if (m_config.resourceType == TestConfig::RESOURCETYPE_IMAGE)
   3035 	{
   3036 		requireEGLExtension(m_eglDisplay, "EGL_KHR_image_base");
   3037 		requireEGLExtension(m_eglDisplay, "EGL_KHR_gl_texture_2D_image");
   3038 	}
   3039 
   3040 	// Create threads
   3041 	m_threads.push_back(new GLES2ThreadTest::EGLThread(deInt32Hash(m_seed)));
   3042 	m_threads.push_back(new GLES2ThreadTest::EGLThread(deInt32Hash(m_seed*200)));
   3043 
   3044 	SharedPtr<GLES2ThreadTest::GLES2Context> contex1;
   3045 	SharedPtr<GLES2ThreadTest::GLES2Context> contex2;
   3046 
   3047 	SharedPtr<GLES2ThreadTest::Surface> surface1;
   3048 	SharedPtr<GLES2ThreadTest::Surface> surface2;
   3049 
   3050 	// Create contexts
   3051 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateContext(m_eglDisplay, m_eglConfig, SharedPtr<GLES2ThreadTest::GLES2Context>(), contex1));
   3052 	m_threads[1]->addOperation(new GLES2ThreadTest::CreateContext(m_eglDisplay, m_eglConfig, contex1, contex2));
   3053 
   3054 	// Create surfaces
   3055 	m_threads[0]->addOperation(new GLES2ThreadTest::CreatePBufferSurface(m_eglDisplay, m_eglConfig, 400, 400, surface1));
   3056 	m_threads[1]->addOperation(new GLES2ThreadTest::CreatePBufferSurface(m_eglDisplay, m_eglConfig, 400, 400, surface2));
   3057 
   3058 	// Make current contexts
   3059 	m_threads[0]->addOperation(new GLES2ThreadTest::MakeCurrent(*m_threads[0], m_eglDisplay, surface1, contex1));
   3060 	m_threads[1]->addOperation(new GLES2ThreadTest::MakeCurrent(*m_threads[1], m_eglDisplay, surface2, contex2));
   3061 	// Operations to check fence sync support
   3062 	if (m_config.useFenceSync)
   3063 	{
   3064 		m_threads[0]->addOperation(new GLES2ThreadTest::InitGLExtension("GL_OES_EGL_sync"));
   3065 		m_threads[1]->addOperation(new GLES2ThreadTest::InitGLExtension("GL_OES_EGL_sync"));
   3066 	}
   3067 
   3068 
   3069 	switch (m_config.resourceType)
   3070 	{
   3071 		case TestConfig::RESOURCETYPE_BUFFER:
   3072 			addBufferOperations();
   3073 			break;
   3074 
   3075 		case TestConfig::RESOURCETYPE_TEXTURE:
   3076 			addTextureOperations();
   3077 			break;
   3078 
   3079 		case TestConfig::RESOURCETYPE_IMAGE:
   3080 			addImageOperations();
   3081 			break;
   3082 
   3083 		case TestConfig::RESOURCETYPE_VERTEX_SHADER:
   3084 			addShaderOperations(GL_VERTEX_SHADER);
   3085 			break;
   3086 
   3087 		case TestConfig::RESOURCETYPE_FRAGMENT_SHADER:
   3088 			addShaderOperations(GL_FRAGMENT_SHADER);
   3089 			break;
   3090 
   3091 		case TestConfig::RESOURCETYPE_PROGRAM:
   3092 			addProgramOperations();
   3093 			break;
   3094 
   3095 		default:
   3096 			DE_ASSERT(false);
   3097 	}
   3098 
   3099 	// Relaese contexts
   3100 	m_threads[0]->addOperation(new GLES2ThreadTest::MakeCurrent(*m_threads[0], m_eglDisplay, SharedPtr<GLES2ThreadTest::Surface>(), SharedPtr<GLES2ThreadTest::GLES2Context>()));
   3101 	m_threads[1]->addOperation(new GLES2ThreadTest::MakeCurrent(*m_threads[0], m_eglDisplay, SharedPtr<GLES2ThreadTest::Surface>(), SharedPtr<GLES2ThreadTest::GLES2Context>()));
   3102 
   3103 	// Destory context
   3104 	m_threads[0]->addOperation(new GLES2ThreadTest::DestroyContext(contex1));
   3105 	m_threads[1]->addOperation(new GLES2ThreadTest::DestroyContext(contex2));
   3106 
   3107 	// Destroy surfaces
   3108 	m_threads[0]->addOperation(new GLES2ThreadTest::DestroySurface(m_eglDisplay, surface1));
   3109 	m_threads[1]->addOperation(new GLES2ThreadTest::DestroySurface(m_eglDisplay, surface2));
   3110 }
   3111 
   3112 void GLES2ThreadedSharingTest::addBufferOperations (void)
   3113 {
   3114 	// Add operations for verify
   3115 	SharedPtr<GLES2ThreadTest::Shader>	vertexShader;
   3116 	SharedPtr<GLES2ThreadTest::Shader>	fragmentShader;
   3117 	SharedPtr<GLES2ThreadTest::Program>	program;
   3118 
   3119 	if (m_config.render)
   3120 	{
   3121 		const char* vertexShaderSource =
   3122 		"attribute highp vec2 a_pos;\n"
   3123 		"varying mediump vec2 v_pos;\n"
   3124 		"void main(void)\n"
   3125 		"{\n"
   3126 		"\tv_pos = a_pos;\n"
   3127 		"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
   3128 		"}\n";
   3129 
   3130 		const char* fragmentShaderSource =
   3131 		"varying mediump vec2 v_pos;\n"
   3132 		"void main(void)\n"
   3133 		"{\n"
   3134 		"\tgl_FragColor = vec4(v_pos, 0.5, 1.0);\n"
   3135 		"}\n";
   3136 
   3137 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_VERTEX_SHADER, vertexShader, m_config.useFenceSync, m_config.serverSync));
   3138 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(vertexShader, vertexShaderSource, m_config.useFenceSync, m_config.serverSync));
   3139 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(vertexShader, m_config.useFenceSync, m_config.serverSync));
   3140 
   3141 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_FRAGMENT_SHADER, fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3142 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(fragmentShader, fragmentShaderSource, m_config.useFenceSync, m_config.serverSync));
   3143 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3144 
   3145 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateProgram(program, m_config.useFenceSync, m_config.serverSync));
   3146 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3147 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, vertexShader, m_config.useFenceSync, m_config.serverSync));
   3148 
   3149 		m_threads[0]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
   3150 	}
   3151 
   3152 	SharedPtr<GLES2ThreadTest::Buffer> buffer;
   3153 
   3154 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateBuffer(buffer, m_config.useFenceSync, m_config.serverSync));
   3155 
   3156 	if (m_config.define)
   3157 	{
   3158 		if (m_config.modify || m_config.render)
   3159 			m_threads[0]->addOperation(new GLES2ThreadTest::BufferData(buffer, GL_ARRAY_BUFFER, 1024, GL_DYNAMIC_DRAW, m_config.useFenceSync, m_config.serverSync));
   3160 		else
   3161 			m_threads[1]->addOperation(new GLES2ThreadTest::BufferData(buffer, GL_ARRAY_BUFFER, 1024, GL_DYNAMIC_DRAW, m_config.useFenceSync, m_config.serverSync));
   3162 	}
   3163 
   3164 	if (m_config.modify)
   3165 	{
   3166 		if (m_config.render)
   3167 			m_threads[0]->addOperation(new GLES2ThreadTest::BufferSubData(buffer, GL_ARRAY_BUFFER, 17, 17, m_config.useFenceSync, m_config.serverSync));
   3168 		else
   3169 			m_threads[1]->addOperation(new GLES2ThreadTest::BufferSubData(buffer, GL_ARRAY_BUFFER, 17, 17, m_config.useFenceSync, m_config.serverSync));
   3170 	}
   3171 
   3172 	if (m_config.render)
   3173 	{
   3174 		m_threads[0]->addOperation(new GLES2ThreadTest::RenderBuffer(program, buffer, m_config.useFenceSync, m_config.serverSync));
   3175 		m_threads[1]->addOperation(new GLES2ThreadTest::RenderBuffer(program, buffer, m_config.useFenceSync, m_config.serverSync));
   3176 
   3177 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels1;
   3178 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels2;
   3179 
   3180 		m_threads[0]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels1, m_config.useFenceSync, m_config.serverSync));
   3181 		m_threads[1]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels2, m_config.useFenceSync, m_config.serverSync));
   3182 
   3183 		m_threads[0]->addOperation(new tcu::ThreadUtil::CompareData(pixels1, pixels2));
   3184 	}
   3185 
   3186 	if (m_config.modify || m_config.render)
   3187 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteBuffer(buffer, m_config.useFenceSync, m_config.serverSync));
   3188 	else
   3189 		m_threads[1]->addOperation(new GLES2ThreadTest::DeleteBuffer(buffer, m_config.useFenceSync, m_config.serverSync));
   3190 
   3191 	if (m_config.render)
   3192 	{
   3193 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(vertexShader, m_config.useFenceSync, m_config.serverSync));
   3194 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3195 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteProgram(program, m_config.useFenceSync, m_config.serverSync));
   3196 	}
   3197 }
   3198 
   3199 void GLES2ThreadedSharingTest::addTextureOperations (void)
   3200 {
   3201 	// Add operations for verify
   3202 	SharedPtr<GLES2ThreadTest::Shader>	vertexShader;
   3203 	SharedPtr<GLES2ThreadTest::Shader>	fragmentShader;
   3204 	SharedPtr<GLES2ThreadTest::Program>	program;
   3205 
   3206 	if (m_config.render)
   3207 	{
   3208 		const char* vertexShaderSource =
   3209 		"attribute highp vec2 a_pos;\n"
   3210 		"varying mediump vec2 v_pos;\n"
   3211 		"void main(void)\n"
   3212 		"{\n"
   3213 		"\tv_pos = a_pos;\n"
   3214 		"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
   3215 		"}\n";
   3216 
   3217 		const char* fragmentShaderSource =
   3218 		"varying mediump vec2 v_pos;\n"
   3219 		"uniform sampler2D u_sampler;\n"
   3220 		"void main(void)\n"
   3221 		"{\n"
   3222 		"\tgl_FragColor = texture2D(u_sampler, v_pos);\n"
   3223 		"}\n";
   3224 
   3225 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_VERTEX_SHADER, vertexShader, m_config.useFenceSync, m_config.serverSync));
   3226 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(vertexShader, vertexShaderSource, m_config.useFenceSync, m_config.serverSync));
   3227 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(vertexShader, m_config.useFenceSync, m_config.serverSync));
   3228 
   3229 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_FRAGMENT_SHADER, fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3230 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(fragmentShader, fragmentShaderSource, m_config.useFenceSync, m_config.serverSync));
   3231 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3232 
   3233 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateProgram(program, m_config.useFenceSync, m_config.serverSync));
   3234 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3235 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, vertexShader, m_config.useFenceSync, m_config.serverSync));
   3236 
   3237 		m_threads[0]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
   3238 	}
   3239 
   3240 	SharedPtr<GLES2ThreadTest::Texture> texture;
   3241 
   3242 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateTexture(texture, m_config.useFenceSync, m_config.serverSync));
   3243 
   3244 	if (m_config.define == 1)
   3245 	{
   3246 		if (m_config.modify || m_config.render)
   3247 			m_threads[0]->addOperation(new GLES2ThreadTest::TexImage2D(texture, 0, GL_RGBA, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
   3248 		else
   3249 			m_threads[1]->addOperation(new GLES2ThreadTest::TexImage2D(texture, 0, GL_RGBA, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
   3250 	}
   3251 
   3252 	if (m_config.define == 2)
   3253 	{
   3254 		if (m_config.modify || m_config.render)
   3255 			m_threads[0]->addOperation(new GLES2ThreadTest::CopyTexImage2D(texture, 0, GL_RGBA, 17, 17, 256, 256, 0, m_config.useFenceSync, m_config.serverSync));
   3256 		else
   3257 			m_threads[1]->addOperation(new GLES2ThreadTest::CopyTexImage2D(texture, 0, GL_RGBA, 17, 17, 256, 256, 0, m_config.useFenceSync, m_config.serverSync));
   3258 	}
   3259 
   3260 	if (m_config.modify == 1)
   3261 	{
   3262 		if (m_config.render)
   3263 			m_threads[0]->addOperation(new GLES2ThreadTest::TexSubImage2D(texture, 0, 17, 17, 29, 29, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
   3264 		else
   3265 			m_threads[1]->addOperation(new GLES2ThreadTest::TexSubImage2D(texture, 0, 17, 17, 29, 29, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
   3266 	}
   3267 
   3268 	if (m_config.modify == 2)
   3269 	{
   3270 		if (m_config.render)
   3271 			m_threads[0]->addOperation(new GLES2ThreadTest::CopyTexSubImage2D(texture, 0, 7, 7, 17, 17, 29, 29, m_config.useFenceSync, m_config.serverSync));
   3272 		else
   3273 			m_threads[1]->addOperation(new GLES2ThreadTest::CopyTexSubImage2D(texture, 0, 7, 7, 17, 17, 29, 29, m_config.useFenceSync, m_config.serverSync));
   3274 	}
   3275 
   3276 	if (m_config.render)
   3277 	{
   3278 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels1;
   3279 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels2;
   3280 
   3281 		m_threads[0]->addOperation(new GLES2ThreadTest::RenderTexture(program, texture, m_config.useFenceSync, m_config.serverSync));
   3282 		m_threads[1]->addOperation(new GLES2ThreadTest::RenderTexture(program, texture, m_config.useFenceSync, m_config.serverSync));
   3283 
   3284 		m_threads[0]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels1, m_config.useFenceSync, m_config.serverSync));
   3285 		m_threads[1]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels2, m_config.useFenceSync, m_config.serverSync));
   3286 
   3287 		m_threads[0]->addOperation(new tcu::ThreadUtil::CompareData(pixels1, pixels2));
   3288 	}
   3289 
   3290 	if (m_config.modify || m_config.render)
   3291 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteTexture(texture, m_config.useFenceSync, m_config.serverSync));
   3292 	else
   3293 		m_threads[1]->addOperation(new GLES2ThreadTest::DeleteTexture(texture, m_config.useFenceSync, m_config.serverSync));
   3294 
   3295 	if (m_config.render)
   3296 	{
   3297 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(vertexShader, m_config.useFenceSync, m_config.serverSync));
   3298 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3299 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteProgram(program, m_config.useFenceSync, m_config.serverSync));
   3300 	}
   3301 }
   3302 
   3303 void GLES2ThreadedSharingTest::addImageOperations (void)
   3304 {
   3305 	// Add operations for verify
   3306 	SharedPtr<GLES2ThreadTest::Shader>	vertexShader;
   3307 	SharedPtr<GLES2ThreadTest::Shader>	fragmentShader;
   3308 	SharedPtr<GLES2ThreadTest::Program>	program;
   3309 
   3310 	m_threads[0]->addOperation(new GLES2ThreadTest::InitGLExtension("GL_OES_EGL_image"));
   3311 	m_threads[1]->addOperation(new GLES2ThreadTest::InitGLExtension("GL_OES_EGL_image"));
   3312 
   3313 	if (m_config.render)
   3314 	{
   3315 		const char* vertexShaderSource =
   3316 		"attribute highp vec2 a_pos;\n"
   3317 		"varying mediump vec2 v_pos;\n"
   3318 		"void main(void)\n"
   3319 		"{\n"
   3320 		"\tv_pos = a_pos;\n"
   3321 		"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
   3322 		"}\n";
   3323 
   3324 		const char* fragmentShaderSource =
   3325 		"varying mediump vec2 v_pos;\n"
   3326 		"uniform sampler2D u_sampler;\n"
   3327 		"void main(void)\n"
   3328 		"{\n"
   3329 		"\tgl_FragColor = texture2D(u_sampler, v_pos);\n"
   3330 		"}\n";
   3331 
   3332 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_VERTEX_SHADER, vertexShader, m_config.useFenceSync, m_config.serverSync));
   3333 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(vertexShader, vertexShaderSource, m_config.useFenceSync, m_config.serverSync));
   3334 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(vertexShader, m_config.useFenceSync, m_config.serverSync));
   3335 
   3336 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_FRAGMENT_SHADER, fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3337 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(fragmentShader, fragmentShaderSource, m_config.useFenceSync, m_config.serverSync));
   3338 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3339 
   3340 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateProgram(program, m_config.useFenceSync, m_config.serverSync));
   3341 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3342 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, vertexShader, m_config.useFenceSync, m_config.serverSync));
   3343 
   3344 		m_threads[0]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
   3345 	}
   3346 
   3347 	SharedPtr<GLES2ThreadTest::Texture>		sourceTexture;
   3348 	SharedPtr<GLES2ThreadTest::Texture>		texture;
   3349 	SharedPtr<GLES2ThreadTest::EGLImage>	image;
   3350 
   3351 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateTexture(sourceTexture, m_config.useFenceSync, m_config.serverSync));
   3352 	m_threads[0]->addOperation(new GLES2ThreadTest::TexImage2D(sourceTexture, 0, GL_RGBA, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
   3353 
   3354 	if (m_config.define == 1)
   3355 	{
   3356 		if (m_config.modify || m_config.render)
   3357 			m_threads[0]->addOperation(new GLES2ThreadTest::CreateImageFromTexture(image, sourceTexture, m_config.useFenceSync, m_config.serverSync));
   3358 		else
   3359 			m_threads[1]->addOperation(new GLES2ThreadTest::CreateImageFromTexture(image, sourceTexture, m_config.useFenceSync, m_config.serverSync));
   3360 	}
   3361 
   3362 	if (m_config.define == 2)
   3363 	{
   3364 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateImageFromTexture(image, sourceTexture, m_config.useFenceSync, m_config.serverSync));
   3365 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateTexture(texture, m_config.useFenceSync, m_config.serverSync));
   3366 
   3367 		if (m_config.modify || m_config.render)
   3368 			m_threads[0]->addOperation(new GLES2ThreadTest::DefineTextureFromImage(texture, image, m_config.useFenceSync, m_config.serverSync));
   3369 		else
   3370 			m_threads[1]->addOperation(new GLES2ThreadTest::DefineTextureFromImage(texture, image, m_config.useFenceSync, m_config.serverSync));
   3371 	}
   3372 
   3373 	m_threads[0]->addOperation(new GLES2ThreadTest::DeleteTexture(sourceTexture, m_config.useFenceSync, m_config.serverSync));
   3374 
   3375 	if (m_config.modify == 1)
   3376 	{
   3377 		DE_ASSERT(m_config.define != 1);
   3378 
   3379 		if (m_config.render)
   3380 			m_threads[0]->addOperation(new GLES2ThreadTest::TexSubImage2D(texture, 0, 17, 17, 29, 29, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
   3381 		else
   3382 			m_threads[1]->addOperation(new GLES2ThreadTest::TexSubImage2D(texture, 0, 17, 17, 29, 29, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
   3383 	}
   3384 
   3385 	if (m_config.modify == 2)
   3386 	{
   3387 		DE_ASSERT(m_config.define != 1);
   3388 
   3389 		if (m_config.render)
   3390 			m_threads[0]->addOperation(new GLES2ThreadTest::CopyTexSubImage2D(texture, 0, 7, 7, 17, 17, 29, 29, m_config.useFenceSync, m_config.serverSync));
   3391 		else
   3392 			m_threads[1]->addOperation(new GLES2ThreadTest::CopyTexSubImage2D(texture, 0, 7, 7, 17, 17, 29, 29, m_config.useFenceSync, m_config.serverSync));
   3393 	}
   3394 
   3395 	if (m_config.modify == 3)
   3396 	{
   3397 		DE_ASSERT(m_config.define != 1);
   3398 
   3399 		if (m_config.render)
   3400 			m_threads[0]->addOperation(new GLES2ThreadTest::TexImage2D(texture, 0, GL_RGBA, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
   3401 		else
   3402 			m_threads[1]->addOperation(new GLES2ThreadTest::TexImage2D(texture, 0, GL_RGBA, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
   3403 	}
   3404 
   3405 	if (m_config.modify == 4)
   3406 	{
   3407 		DE_ASSERT(m_config.define != 1);
   3408 
   3409 		if (m_config.render)
   3410 			m_threads[0]->addOperation(new GLES2ThreadTest::CopyTexImage2D(texture, 0, GL_RGBA, 7, 7, 256, 256, 0, m_config.useFenceSync, m_config.serverSync));
   3411 		else
   3412 			m_threads[1]->addOperation(new GLES2ThreadTest::CopyTexImage2D(texture, 0, GL_RGBA, 7, 7, 256, 256, 0, m_config.useFenceSync, m_config.serverSync));
   3413 	}
   3414 
   3415 	if (m_config.render)
   3416 	{
   3417 		DE_ASSERT(m_config.define != 1);
   3418 
   3419 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels1;
   3420 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels2;
   3421 
   3422 		m_threads[0]->addOperation(new GLES2ThreadTest::RenderTexture(program, texture, m_config.useFenceSync, m_config.serverSync));
   3423 		m_threads[1]->addOperation(new GLES2ThreadTest::RenderTexture(program, texture, m_config.useFenceSync, m_config.serverSync));
   3424 
   3425 		m_threads[0]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels1, m_config.useFenceSync, m_config.serverSync));
   3426 		m_threads[1]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels2, m_config.useFenceSync, m_config.serverSync));
   3427 
   3428 		m_threads[0]->addOperation(new tcu::ThreadUtil::CompareData(pixels1, pixels2));
   3429 	}
   3430 
   3431 	if (texture)
   3432 	{
   3433 		if (m_config.modify || m_config.render)
   3434 			m_threads[0]->addOperation(new GLES2ThreadTest::DeleteTexture(texture, m_config.useFenceSync, m_config.serverSync));
   3435 		else
   3436 			m_threads[1]->addOperation(new GLES2ThreadTest::DeleteTexture(texture, m_config.useFenceSync, m_config.serverSync));
   3437 	}
   3438 
   3439 	if (m_config.modify || m_config.render)
   3440 		m_threads[0]->addOperation(new GLES2ThreadTest::DestroyImage(image, m_config.useFenceSync, m_config.serverSync));
   3441 	else
   3442 		m_threads[1]->addOperation(new GLES2ThreadTest::DestroyImage(image, m_config.useFenceSync, m_config.serverSync));
   3443 
   3444 	if (m_config.render)
   3445 	{
   3446 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(vertexShader, m_config.useFenceSync, m_config.serverSync));
   3447 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3448 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteProgram(program, m_config.useFenceSync, m_config.serverSync));
   3449 	}
   3450 }
   3451 
   3452 void GLES2ThreadedSharingTest::addShaderOperations (GLenum type)
   3453 {
   3454 	SharedPtr<GLES2ThreadTest::Shader> shader;
   3455 
   3456 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(type, shader, m_config.useFenceSync, m_config.serverSync));
   3457 
   3458 	if (m_config.define)
   3459 	{
   3460 		const char* vertexShaderSource =
   3461 		"attribute mediump vec4 a_pos;\n"
   3462 		"void main(void)\n"
   3463 		"{\n"
   3464 		"\tgl_Position = a_pos;\n"
   3465 		"}";
   3466 
   3467 		const char* fragmentShaderSource =
   3468 		"void main(void)\n"
   3469 		"{\n"
   3470 		"\tgl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
   3471 		"}";
   3472 
   3473 		if (m_config.modify || m_config.render)
   3474 			m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(shader, (type == GL_VERTEX_SHADER ? vertexShaderSource : fragmentShaderSource), m_config.useFenceSync, m_config.serverSync));
   3475 		else
   3476 			m_threads[1]->addOperation(new GLES2ThreadTest::ShaderSource(shader, (type == GL_VERTEX_SHADER ? vertexShaderSource : fragmentShaderSource), m_config.useFenceSync, m_config.serverSync));
   3477 	}
   3478 
   3479 	if (m_config.modify)
   3480 	{
   3481 		if (m_config.render)
   3482 			m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(shader, m_config.useFenceSync, m_config.serverSync));
   3483 		else
   3484 			m_threads[1]->addOperation(new GLES2ThreadTest::ShaderCompile(shader, m_config.useFenceSync, m_config.serverSync));
   3485 	}
   3486 
   3487 	DE_ASSERT(!m_config.render);
   3488 
   3489 	if (m_config.modify || m_config.render)
   3490 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(shader, m_config.useFenceSync, m_config.serverSync));
   3491 	else
   3492 		m_threads[1]->addOperation(new GLES2ThreadTest::DeleteShader(shader, m_config.useFenceSync, m_config.serverSync));
   3493 }
   3494 
   3495 void GLES2ThreadedSharingTest::addProgramOperations (void)
   3496 {
   3497 	// Add operations for verify
   3498 	SharedPtr<GLES2ThreadTest::Shader>	vertexShader;
   3499 	SharedPtr<GLES2ThreadTest::Shader>	fragmentShader;
   3500 
   3501 	if (m_config.define)
   3502 	{
   3503 		const char* vertexShaderSource =
   3504 		"attribute highp vec2 a_pos;\n"
   3505 		"varying mediump vec2 v_pos;\n"
   3506 		"void main(void)\n"
   3507 		"{\n"
   3508 		"\tv_pos = a_pos;\n"
   3509 		"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
   3510 		"}\n";
   3511 
   3512 		const char* fragmentShaderSource =
   3513 		"varying mediump vec2 v_pos;\n"
   3514 		"void main(void)\n"
   3515 		"{\n"
   3516 		"\tgl_FragColor = vec4(v_pos, 0.5, 1.0);\n"
   3517 		"}\n";
   3518 
   3519 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_VERTEX_SHADER, vertexShader, m_config.useFenceSync, m_config.serverSync));
   3520 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(vertexShader, vertexShaderSource, m_config.useFenceSync, m_config.serverSync));
   3521 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(vertexShader, m_config.useFenceSync, m_config.serverSync));
   3522 
   3523 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_FRAGMENT_SHADER, fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3524 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(fragmentShader, fragmentShaderSource, m_config.useFenceSync, m_config.serverSync));
   3525 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3526 	}
   3527 
   3528 	SharedPtr<GLES2ThreadTest::Program> program;
   3529 
   3530 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateProgram(program, m_config.useFenceSync, m_config.serverSync));
   3531 
   3532 	if (m_config.define)
   3533 	{
   3534 		// Attach shaders
   3535 		if (m_config.modify || m_config.render)
   3536 		{
   3537 			m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, vertexShader, m_config.useFenceSync, m_config.serverSync));
   3538 			m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3539 		}
   3540 		else
   3541 		{
   3542 			m_threads[1]->addOperation(new GLES2ThreadTest::AttachShader(program, vertexShader, m_config.useFenceSync, m_config.serverSync));
   3543 			m_threads[1]->addOperation(new GLES2ThreadTest::AttachShader(program, fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3544 		}
   3545 	}
   3546 
   3547 	if (m_config.modify == 1)
   3548 	{
   3549 		// Link program
   3550 		if (m_config.render)
   3551 			m_threads[0]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
   3552 		else
   3553 			m_threads[1]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
   3554 	}
   3555 
   3556 	if (m_config.modify == 2)
   3557 	{
   3558 		// Link program
   3559 		if (m_config.render)
   3560 		{
   3561 			m_threads[0]->addOperation(new GLES2ThreadTest::DetachShader(program, GL_VERTEX_SHADER, m_config.useFenceSync, m_config.serverSync));
   3562 			m_threads[0]->addOperation(new GLES2ThreadTest::DetachShader(program, GL_FRAGMENT_SHADER, m_config.useFenceSync, m_config.serverSync));
   3563 		}
   3564 		else
   3565 		{
   3566 			m_threads[1]->addOperation(new GLES2ThreadTest::DetachShader(program, GL_VERTEX_SHADER, m_config.useFenceSync, m_config.serverSync));
   3567 			m_threads[1]->addOperation(new GLES2ThreadTest::DetachShader(program, GL_FRAGMENT_SHADER, m_config.useFenceSync, m_config.serverSync));
   3568 		}
   3569 	}
   3570 
   3571 	if (m_config.render)
   3572 	{
   3573 		DE_ASSERT(false);
   3574 	}
   3575 
   3576 	if (m_config.modify || m_config.render)
   3577 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteProgram(program, m_config.useFenceSync, m_config.serverSync));
   3578 	else
   3579 		m_threads[1]->addOperation(new GLES2ThreadTest::DeleteProgram(program, m_config.useFenceSync, m_config.serverSync));
   3580 
   3581 	if (m_config.render)
   3582 	{
   3583 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(vertexShader, m_config.useFenceSync, m_config.serverSync));
   3584 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(fragmentShader, m_config.useFenceSync, m_config.serverSync));
   3585 	}
   3586 }
   3587 
   3588 void GLES2ThreadedSharingTest::deinit (void)
   3589 {
   3590 	for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   3591 		delete m_threads[threadNdx];
   3592 
   3593 	m_threads.clear();
   3594 
   3595 	TCU_CHECK(!m_requiresRestart);
   3596 }
   3597 
   3598 tcu::TestCase::IterateResult GLES2ThreadedSharingTest::iterate (void)
   3599 {
   3600 	if (!m_threadsStarted)
   3601 	{
   3602 		m_beginTimeUs = deGetMicroseconds();
   3603 
   3604 		// Execute threads
   3605 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   3606 			m_threads[threadNdx]->exec();
   3607 
   3608 		m_threadsStarted = true;
   3609 		m_threadsRunning = true;
   3610 	}
   3611 
   3612 	if (m_threadsRunning)
   3613 	{
   3614 		// Wait threads to finish
   3615 		int readyThreads = 0;
   3616 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   3617 		{
   3618 			if (m_threads[threadNdx]->getStatus() != tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING)
   3619 				readyThreads++;
   3620 		}
   3621 
   3622 		if (readyThreads == (int)m_threads.size())
   3623 		{
   3624 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   3625 				m_threads[threadNdx]->join();
   3626 
   3627 			m_executionReady	= true;
   3628 			m_requiresRestart	= false;
   3629 		}
   3630 
   3631 		if (deGetMicroseconds() - m_beginTimeUs > m_timeOutUs)
   3632 		{
   3633 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   3634 			{
   3635 				if (m_threads[threadNdx]->getStatus() != tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING)
   3636 					m_threads[threadNdx]->join();
   3637 			}
   3638 			m_executionReady	= true;
   3639 			m_requiresRestart	= true;
   3640 			m_timeOutTimeUs		= deGetMicroseconds();
   3641 		}
   3642 		else
   3643 		{
   3644 			deSleep(m_sleepTimeMs);
   3645 		}
   3646 	}
   3647 
   3648 	if (m_executionReady)
   3649 	{
   3650 		std::vector<int> indices(m_threads.size(), 0);
   3651 		while (true)
   3652 		{
   3653 			int firstThread = -1;
   3654 
   3655 			// Find first thread with messages
   3656 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   3657 			{
   3658 				if (m_threads[threadNdx]->getMessageCount() > indices[threadNdx])
   3659 				{
   3660 					firstThread = threadNdx;
   3661 					break;
   3662 				}
   3663 			}
   3664 
   3665 			// No more messages
   3666 			if (firstThread == -1)
   3667 				break;
   3668 
   3669 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   3670 			{
   3671 				// No more messages in this thread
   3672 				if (m_threads[threadNdx]->getMessageCount() <= indices[threadNdx])
   3673 					continue;
   3674 
   3675 				if ((m_threads[threadNdx]->getMessage(indices[threadNdx]).getTime() - m_beginTimeUs) < (m_threads[firstThread]->getMessage(indices[firstThread]).getTime() - m_beginTimeUs))
   3676 					firstThread = threadNdx;
   3677 			}
   3678 
   3679 			deUint64	time	= m_threads[firstThread]->getMessage(indices[firstThread]).getTime();
   3680 			std::string	message	= m_threads[firstThread]->getMessage(indices[firstThread]).getMessage();
   3681 			m_log << tcu::TestLog::Message << "[" << (time - m_beginTimeUs) << "] (" << firstThread << ") " << message << tcu::TestLog::EndMessage;
   3682 			indices[firstThread]++;
   3683 		}
   3684 
   3685 		bool isOk = true;
   3686 		bool notSupported = false;
   3687 
   3688 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
   3689 		{
   3690 			if (m_threads[threadNdx]->getStatus() == tcu::ThreadUtil::Thread::THREADSTATUS_FAILED)
   3691 				isOk = false;
   3692 			else if (m_threads[threadNdx]->getStatus() == tcu::ThreadUtil::Thread::THREADSTATUS_READY)
   3693 				isOk &= true;
   3694 			else if (m_threads[threadNdx]->getStatus() == tcu::ThreadUtil::Thread::THREADSTATUS_NOT_SUPPORTED)
   3695 				notSupported = true;
   3696 			else
   3697 			{
   3698 				isOk = false;
   3699 				DE_ASSERT(false);
   3700 			}
   3701 		}
   3702 
   3703 		if (m_timeOutTimeUs != 0)
   3704 		{
   3705 			m_log << tcu::TestLog::Message << "[" << (m_timeOutTimeUs - m_beginTimeUs) << "] Execution timeout limit reached" << tcu::TestLog::EndMessage;
   3706 		}
   3707 
   3708 		if (notSupported)
   3709 			throw tcu::NotSupportedError("Thread threw tcu::NotSupportedError", "", __FILE__, __LINE__);
   3710 
   3711 		if (isOk)
   3712 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   3713 		else
   3714 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   3715 
   3716 		return STOP;
   3717 	}
   3718 
   3719 	return CONTINUE;
   3720 }
   3721 
   3722 static void addSimpleTests (EglTestContext& ctx, tcu::TestCaseGroup* group, bool useSync, bool serverSync)
   3723 {
   3724 	{
   3725 		TestCaseGroup* bufferTests = new TestCaseGroup(ctx, "buffers", "Buffer management tests");
   3726 
   3727 		{
   3728 			GLES2ThreadedSharingTest::TestConfig config;
   3729 
   3730 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_BUFFER;
   3731 			config.useFenceSync = useSync;
   3732 			config.serverSync	= serverSync;
   3733 			config.define = 0;
   3734 			config.modify = 0;
   3735 			config.render = false;
   3736 			bufferTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "gen_delete", "Generate and delete buffer"));
   3737 		}
   3738 
   3739 		{
   3740 			GLES2ThreadedSharingTest::TestConfig config;
   3741 
   3742 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_BUFFER;
   3743 			config.useFenceSync = useSync;
   3744 			config.serverSync	= serverSync;
   3745 			config.define = 1;
   3746 			config.modify = 0;
   3747 			config.render = false;
   3748 			bufferTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "bufferdata", "Generate, set data and delete buffer"));
   3749 		}
   3750 
   3751 		{
   3752 			GLES2ThreadedSharingTest::TestConfig config;
   3753 
   3754 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_BUFFER;
   3755 			config.useFenceSync = useSync;
   3756 			config.serverSync	= serverSync;
   3757 			config.define = 1;
   3758 			config.modify = 1;
   3759 			config.render = false;
   3760 			bufferTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "buffersubdata", "Generate, set data, update data and delete buffer"));
   3761 		}
   3762 
   3763 		{
   3764 			GLES2ThreadedSharingTest::TestConfig config;
   3765 
   3766 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_BUFFER;
   3767 			config.useFenceSync = useSync;
   3768 			config.serverSync	= serverSync;
   3769 			config.define = 1;
   3770 			config.modify = 0;
   3771 			config.render = true;
   3772 			bufferTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "bufferdata_render", "Generate, set data, render and delete buffer"));
   3773 		}
   3774 
   3775 		{
   3776 			GLES2ThreadedSharingTest::TestConfig config;
   3777 
   3778 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_BUFFER;
   3779 			config.useFenceSync = useSync;
   3780 			config.serverSync	= serverSync;
   3781 			config.define = 1;
   3782 			config.modify = 1;
   3783 			config.render = true;
   3784 			bufferTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "buffersubdata_render", "Generate, set data, update data, render and delete buffer"));
   3785 		}
   3786 
   3787 		group->addChild(bufferTests);
   3788 	}
   3789 
   3790 	{
   3791 		TestCaseGroup* textureTests = new TestCaseGroup(ctx, "textures", "Texture management tests");
   3792 
   3793 		{
   3794 			GLES2ThreadedSharingTest::TestConfig config;
   3795 
   3796 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3797 			config.useFenceSync = useSync;
   3798 			config.serverSync	= serverSync;
   3799 			config.define = 0;
   3800 			config.modify = 0;
   3801 			config.render = false;
   3802 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "gen_delete", "Generate and delete texture"));
   3803 		}
   3804 
   3805 		{
   3806 			GLES2ThreadedSharingTest::TestConfig config;
   3807 
   3808 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3809 			config.useFenceSync = useSync;
   3810 			config.serverSync	= serverSync;
   3811 			config.define = 1;
   3812 			config.modify = 0;
   3813 			config.render = false;
   3814 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d", "Generate, set data and delete texture"));
   3815 		}
   3816 
   3817 		{
   3818 			GLES2ThreadedSharingTest::TestConfig config;
   3819 
   3820 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3821 			config.useFenceSync = useSync;
   3822 			config.serverSync	= serverSync;
   3823 			config.define = 1;
   3824 			config.modify = 1;
   3825 			config.render = false;
   3826 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_texsubimage2d", "Generate, set data, update data and delete texture"));
   3827 		}
   3828 
   3829 		{
   3830 			GLES2ThreadedSharingTest::TestConfig config;
   3831 
   3832 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3833 			config.useFenceSync = useSync;
   3834 			config.serverSync	= serverSync;
   3835 			config.define = 1;
   3836 			config.modify = 2;
   3837 			config.render = false;
   3838 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_copytexsubimage2d", "Generate, set data, update data and delete texture"));
   3839 		}
   3840 
   3841 		{
   3842 			GLES2ThreadedSharingTest::TestConfig config;
   3843 
   3844 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3845 			config.useFenceSync = useSync;
   3846 			config.serverSync	= serverSync;
   3847 			config.define = 1;
   3848 			config.modify = 0;
   3849 			config.render = true;
   3850 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_render", "Generate, set data, render and delete texture"));
   3851 		}
   3852 
   3853 		{
   3854 			GLES2ThreadedSharingTest::TestConfig config;
   3855 
   3856 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3857 			config.useFenceSync = useSync;
   3858 			config.serverSync	= serverSync;
   3859 			config.define = 1;
   3860 			config.modify = 1;
   3861 			config.render = true;
   3862 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_texsubimage2d_render", "Generate, set data, update data, render and delete texture"));
   3863 		}
   3864 
   3865 		{
   3866 			GLES2ThreadedSharingTest::TestConfig config;
   3867 
   3868 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3869 			config.useFenceSync = useSync;
   3870 			config.serverSync	= serverSync;
   3871 			config.define = 1;
   3872 			config.modify = 2;
   3873 			config.render = true;
   3874 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_copytexsubimage2d_render", "Generate, set data, update data, render and delete texture"));
   3875 		}
   3876 
   3877 		{
   3878 			GLES2ThreadedSharingTest::TestConfig config;
   3879 
   3880 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3881 			config.useFenceSync = useSync;
   3882 			config.serverSync	= serverSync;
   3883 			config.define = 2;
   3884 			config.modify = 0;
   3885 			config.render = false;
   3886 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d", "Generate, set data and delete texture"));
   3887 		}
   3888 
   3889 		{
   3890 			GLES2ThreadedSharingTest::TestConfig config;
   3891 
   3892 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3893 			config.useFenceSync = useSync;
   3894 			config.serverSync	= serverSync;
   3895 			config.define = 2;
   3896 			config.modify = 1;
   3897 			config.render = false;
   3898 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_texsubimage2d", "Generate, set data, update data and delete texture"));
   3899 		}
   3900 
   3901 		{
   3902 			GLES2ThreadedSharingTest::TestConfig config;
   3903 
   3904 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3905 			config.useFenceSync = useSync;
   3906 			config.serverSync	= serverSync;
   3907 			config.define = 2;
   3908 			config.modify = 2;
   3909 			config.render = false;
   3910 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_copytexsubimage2d", "Generate, set data, update data and delete texture"));
   3911 		}
   3912 
   3913 		{
   3914 			GLES2ThreadedSharingTest::TestConfig config;
   3915 
   3916 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3917 			config.useFenceSync = useSync;
   3918 			config.serverSync	= serverSync;
   3919 			config.define = 2;
   3920 			config.modify = 0;
   3921 			config.render = true;
   3922 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_render", "Generate, set data, render and delete texture"));
   3923 		}
   3924 
   3925 		{
   3926 			GLES2ThreadedSharingTest::TestConfig config;
   3927 
   3928 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3929 			config.useFenceSync = useSync;
   3930 			config.serverSync	= serverSync;
   3931 			config.define = 2;
   3932 			config.modify = 1;
   3933 			config.render = true;
   3934 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_texsubimage2d_render", "Generate, set data, update data, render and delete texture"));
   3935 		}
   3936 
   3937 		{
   3938 			GLES2ThreadedSharingTest::TestConfig config;
   3939 
   3940 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
   3941 			config.useFenceSync = useSync;
   3942 			config.serverSync	= serverSync;
   3943 			config.define = 2;
   3944 			config.modify = 2;
   3945 			config.render = true;
   3946 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_copytexsubimage2d_render", "Generate, set data, update data, render and delete texture"));
   3947 		}
   3948 
   3949 		group->addChild(textureTests);
   3950 	}
   3951 
   3952 	{
   3953 		TestCaseGroup* shaderTests = new TestCaseGroup(ctx, "shaders", "Shader management tests");
   3954 
   3955 		{
   3956 			GLES2ThreadedSharingTest::TestConfig config;
   3957 
   3958 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_VERTEX_SHADER;
   3959 			config.useFenceSync = useSync;
   3960 			config.serverSync	= serverSync;
   3961 			config.define = 0;
   3962 			config.modify = 0;
   3963 			config.render = false;
   3964 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "vtx_create_destroy", "Create and delete shader"));
   3965 		}
   3966 
   3967 		{
   3968 			GLES2ThreadedSharingTest::TestConfig config;
   3969 
   3970 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_VERTEX_SHADER;
   3971 			config.useFenceSync = useSync;
   3972 			config.serverSync	= serverSync;
   3973 			config.define = 1;
   3974 			config.modify = 0;
   3975 			config.render = false;
   3976 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "vtx_shadersource", "Create, set source and delete shader"));
   3977 		}
   3978 
   3979 		{
   3980 			GLES2ThreadedSharingTest::TestConfig config;
   3981 
   3982 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_VERTEX_SHADER;
   3983 			config.useFenceSync = useSync;
   3984 			config.serverSync	= serverSync;
   3985 			config.define = 1;
   3986 			config.modify = 1;
   3987 			config.render = false;
   3988 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "vtx_compile", "Create, set source, compile and delete shader"));
   3989 		}
   3990 
   3991 		{
   3992 			GLES2ThreadedSharingTest::TestConfig config;
   3993 
   3994 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_FRAGMENT_SHADER;
   3995 			config.useFenceSync = useSync;
   3996 			config.serverSync	= serverSync;
   3997 			config.define = 0;
   3998 			config.modify = 0;
   3999 			config.render = false;
   4000 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "frag_create_destroy", "Create and delete shader"));
   4001 		}
   4002 
   4003 		{
   4004 			GLES2ThreadedSharingTest::TestConfig config;
   4005 
   4006 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_FRAGMENT_SHADER;
   4007 			config.useFenceSync = useSync;
   4008 			config.serverSync	= serverSync;
   4009 			config.define = 1;
   4010 			config.modify = 0;
   4011 			config.render = false;
   4012 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "frag_shadersource", "Create, set source and delete shader"));
   4013 		}
   4014 
   4015 		{
   4016 			GLES2ThreadedSharingTest::TestConfig config;
   4017 
   4018 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_FRAGMENT_SHADER;
   4019 			config.useFenceSync = useSync;
   4020 			config.serverSync	= serverSync;
   4021 			config.define = 1;
   4022 			config.modify = 1;
   4023 			config.render = false;
   4024 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "frag_compile", "Create, set source, compile and delete shader"));
   4025 		}
   4026 
   4027 		group->addChild(shaderTests);
   4028 	}
   4029 
   4030 	{
   4031 		TestCaseGroup* programTests = new TestCaseGroup(ctx, "programs", "Program management tests");
   4032 
   4033 		{
   4034 			GLES2ThreadedSharingTest::TestConfig config;
   4035 
   4036 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_PROGRAM;
   4037 			config.useFenceSync = useSync;
   4038 			config.serverSync	= serverSync;
   4039 			config.define = 0;
   4040 			config.modify = 0;
   4041 			config.render = false;
   4042 			programTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "create_destroy", "Create and delete program"));
   4043 		}
   4044 
   4045 		{
   4046 			GLES2ThreadedSharingTest::TestConfig config;
   4047 
   4048 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_PROGRAM;
   4049 			config.useFenceSync = useSync;
   4050 			config.serverSync	= serverSync;
   4051 			config.define = 1;
   4052 			config.modify = 0;
   4053 			config.render = false;
   4054 			programTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "attach", "Create, attach shaders and delete program"));
   4055 		}
   4056 
   4057 		{
   4058 			GLES2ThreadedSharingTest::TestConfig config;
   4059 
   4060 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_PROGRAM;
   4061 			config.useFenceSync = useSync;
   4062 			config.serverSync	= serverSync;
   4063 			config.define = 1;
   4064 			config.modify = 1;
   4065 			config.render = false;
   4066 			programTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "link", "Create, attach shaders, link and delete program"));
   4067 		}
   4068 
   4069 		group->addChild(programTests);
   4070 	}
   4071 
   4072 	{
   4073 		TestCaseGroup* imageTests = new TestCaseGroup(ctx, "images", "Image management tests");
   4074 
   4075 		TestCaseGroup* textureSourceTests = new TestCaseGroup(ctx, "texture_source", "Image management tests with texture source.");
   4076 		{
   4077 			GLES2ThreadedSharingTest::TestConfig config;
   4078 
   4079 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
   4080 			config.useFenceSync = useSync;
   4081 			config.serverSync	= serverSync;
   4082 			config.define = 1;
   4083 			config.modify = 0;
   4084 			config.render = false;
   4085 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "create_destroy", "Create and destroy EGLImage."));
   4086 		}
   4087 
   4088 		{
   4089 			GLES2ThreadedSharingTest::TestConfig config;
   4090 
   4091 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
   4092 			config.useFenceSync = useSync;
   4093 			config.serverSync	= serverSync;
   4094 			config.define = 2;
   4095 			config.modify = 0;
   4096 			config.render = false;
   4097 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "create_texture", "Create texture from image."));
   4098 		}
   4099 
   4100 		{
   4101 			GLES2ThreadedSharingTest::TestConfig config;
   4102 
   4103 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
   4104 			config.useFenceSync = useSync;
   4105 			config.serverSync	= serverSync;
   4106 			config.define = 2;
   4107 			config.modify = 1;
   4108 			config.render = false;
   4109 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "texsubimage2d", "Modify texture created from image with glTexSubImage2D."));
   4110 		}
   4111 
   4112 		{
   4113 			GLES2ThreadedSharingTest::TestConfig config;
   4114 
   4115 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
   4116 			config.useFenceSync = useSync;
   4117 			config.serverSync	= serverSync;
   4118 			config.define = 2;
   4119 			config.modify = 2;
   4120 			config.render = false;
   4121 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copytexsubimage2d", "Modify texture created from image with glCopyTexSubImage2D."));
   4122 		}
   4123 
   4124 		{
   4125 			GLES2ThreadedSharingTest::TestConfig config;
   4126 
   4127 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
   4128 			config.useFenceSync = useSync;
   4129 			config.serverSync	= serverSync;
   4130 			config.define = 2;
   4131 			config.modify = 3;
   4132 			config.render = false;
   4133 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d", "Modify texture created from image with glTexImage2D."));
   4134 		}
   4135 
   4136 		{
   4137 			GLES2ThreadedSharingTest::TestConfig config;
   4138 
   4139 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
   4140 			config.useFenceSync = useSync;
   4141 			config.serverSync	= serverSync;
   4142 			config.define = 2;
   4143 			config.modify = 4;
   4144 			config.render = false;
   4145 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d", "Modify texture created from image with glCopyTexImage2D."));
   4146 		}
   4147 
   4148 		{
   4149 			GLES2ThreadedSharingTest::TestConfig config;
   4150 
   4151 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
   4152 			config.useFenceSync = useSync;
   4153 			config.serverSync	= serverSync;
   4154 			config.define = 2;
   4155 			config.modify = 0;
   4156 			config.render = true;
   4157 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "create_texture_render", "Create texture from image and render."));
   4158 		}
   4159 
   4160 		{
   4161 			GLES2ThreadedSharingTest::TestConfig config;
   4162 
   4163 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
   4164 			config.useFenceSync = useSync;
   4165 			config.serverSync	= serverSync;
   4166 			config.define = 2;
   4167 			config.modify = 1;
   4168 			config.render = true;
   4169 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "texsubimage2d_render", "Modify texture created from image and render."));
   4170 		}
   4171 
   4172 		{
   4173 			GLES2ThreadedSharingTest::TestConfig config;
   4174 
   4175 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
   4176 			config.useFenceSync = useSync;
   4177 			config.serverSync	= serverSync;
   4178 			config.define = 2;
   4179 			config.modify = 2;
   4180 			config.render = true;
   4181 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copytexsubimage2d_render", "Modify texture created from image and render."));
   4182 		}
   4183 
   4184 		{
   4185 			GLES2ThreadedSharingTest::TestConfig config;
   4186 
   4187 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
   4188 			config.useFenceSync = useSync;
   4189 			config.serverSync	= serverSync;
   4190 			config.define = 2;
   4191 			config.modify = 3;
   4192 			config.render = true;
   4193 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_render", "Modify texture created from image and render."));
   4194 		}
   4195 
   4196 		{
   4197 			GLES2ThreadedSharingTest::TestConfig config;
   4198 
   4199 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
   4200 			config.useFenceSync = useSync;
   4201 			config.serverSync	= serverSync;
   4202 			config.define = 2;
   4203 			config.modify = 4;
   4204 			config.render = true;
   4205 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_render", "Modify texture created from image and render."));
   4206 		}
   4207 
   4208 		imageTests->addChild(textureSourceTests);
   4209 
   4210 		group->addChild(imageTests);
   4211 	}
   4212 
   4213 }
   4214 
   4215 static void addRandomTests (EglTestContext& ctx, tcu::TestCaseGroup* group, bool useSync, bool serverSync)
   4216 {
   4217 	{
   4218 		TestCaseGroup* textureTests = new TestCaseGroup(ctx, "textures", "Texture management tests");
   4219 
   4220 		{
   4221 			TestCaseGroup* genTextureTests = new TestCaseGroup(ctx, "gen_delete", "Texture gen and delete tests");
   4222 
   4223 			for (int textureTestNdx = 0; textureTestNdx < 20; textureTestNdx++)
   4224 			{
   4225 				GLES2SharingRandomTest::TestConfig config;
   4226 				config.useFenceSync		= useSync;
   4227 				config.serverSync		= serverSync;
   4228 				config.threadCount		= 2 + textureTestNdx % 5;
   4229 				config.operationCount	= 30 + textureTestNdx;
   4230 
   4231 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]				= 1.0f;
   4232 
   4233 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.25f;
   4234 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.75f;
   4235 
   4236 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.5f;
   4237 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.5f;
   4238 
   4239 				std::string	name = de::toString(textureTestNdx);
   4240 				genTextureTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4241 			}
   4242 
   4243 			textureTests->addChild(genTextureTests);
   4244 		}
   4245 
   4246 		{
   4247 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "teximage2d", "Texture gen, delete and teximage2D tests");
   4248 
   4249 			for (int textureTestNdx = 0; textureTestNdx < 20; textureTestNdx++)
   4250 			{
   4251 				GLES2SharingRandomTest::TestConfig config;
   4252 				config.useFenceSync		= useSync;
   4253 				config.serverSync		= serverSync;
   4254 				config.threadCount		= 2 + textureTestNdx % 5;
   4255 				config.operationCount	= 40 + textureTestNdx;
   4256 
   4257 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]				= 1.0f;
   4258 
   4259 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.10f;
   4260 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.10f;
   4261 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]		= 0.80f;
   4262 
   4263 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.30f;
   4264 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.40f;
   4265 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]		= 0.30f;
   4266 
   4267 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]		= 0.40f;
   4268 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]		= 0.40f;
   4269 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]			= 0.20f;
   4270 
   4271 				std::string	name = de::toString(textureTestNdx);
   4272 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4273 			}
   4274 
   4275 			textureTests->addChild(texImage2DTests);
   4276 		}
   4277 
   4278 		{
   4279 			TestCaseGroup* texSubImage2DTests = new TestCaseGroup(ctx, "texsubimage2d", "Texture gen, delete, teximage2D and texsubimage2d tests");
   4280 
   4281 			for (int textureTestNdx = 0; textureTestNdx < 20; textureTestNdx++)
   4282 			{
   4283 				GLES2SharingRandomTest::TestConfig config;
   4284 				config.useFenceSync		= useSync;
   4285 				config.serverSync		= serverSync;
   4286 				config.threadCount		= 2 + textureTestNdx % 5;
   4287 				config.operationCount	= 50 + textureTestNdx;
   4288 
   4289 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]				= 1.0f;
   4290 
   4291 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.05f;
   4292 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.10f;
   4293 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]		= 0.80f;
   4294 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXSUBIMAGE2D]		= 0.05f;
   4295 
   4296 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.30f;
   4297 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.40f;
   4298 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]		= 0.20f;
   4299 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXSUBIMAGE2D]	= 0.10f;
   4300 
   4301 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]		= 0.20f;
   4302 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]		= 0.20f;
   4303 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]			= 0.10f;
   4304 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXSUBIMAGE2D]			= 0.50f;
   4305 
   4306 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.20f;
   4307 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]		= 0.25f;
   4308 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]			= 0.25f;
   4309 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_TEXSUBIMAGE2D]		= 0.30f;
   4310 
   4311 				std::string	name = de::toString(textureTestNdx);
   4312 				texSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4313 			}
   4314 
   4315 			textureTests->addChild(texSubImage2DTests);
   4316 		}
   4317 
   4318 		{
   4319 			TestCaseGroup* copyTexImage2DTests = new TestCaseGroup(ctx, "copyteximage2d", "Texture gen, delete and copyteximage2d tests");
   4320 
   4321 			for (int textureTestNdx = 0; textureTestNdx < 20; textureTestNdx++)
   4322 			{
   4323 				GLES2SharingRandomTest::TestConfig config;
   4324 				config.useFenceSync		= useSync;
   4325 				config.serverSync		= serverSync;
   4326 				config.threadCount		= 2 + textureTestNdx % 5;
   4327 				config.operationCount	= 40 + textureTestNdx;
   4328 
   4329 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]				= 1.0f;
   4330 
   4331 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.10f;
   4332 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.10f;
   4333 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_COPYTEXIMAGE2D]	= 0.80f;
   4334 
   4335 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.30f;
   4336 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.40f;
   4337 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_COPYTEXIMAGE2D]	= 0.30f;
   4338 
   4339 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.40f;
   4340 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]	= 0.40f;
   4341 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_COPYTEXIMAGE2D]	= 0.20f;
   4342 
   4343 
   4344 				std::string	name = de::toString(textureTestNdx);
   4345 				copyTexImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4346 			}
   4347 
   4348 			textureTests->addChild(copyTexImage2DTests);
   4349 		}
   4350 
   4351 		{
   4352 			TestCaseGroup* copyTexSubImage2DTests = new TestCaseGroup(ctx, "copytexsubimage2d", "Texture gen, delete, teximage2D and copytexsubimage2d tests");
   4353 
   4354 			for (int textureTestNdx = 0; textureTestNdx < 20; textureTestNdx++)
   4355 			{
   4356 				GLES2SharingRandomTest::TestConfig config;
   4357 				config.useFenceSync		= useSync;
   4358 				config.serverSync		= serverSync;
   4359 				config.threadCount		= 2 + textureTestNdx % 5;
   4360 				config.operationCount	= 50 + textureTestNdx;
   4361 
   4362 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]					= 1.0f;
   4363 
   4364 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]		= 0.05f;
   4365 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]		= 0.10f;
   4366 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]			= 0.80f;
   4367 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]		= 0.05f;
   4368 
   4369 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]		= 0.30f;
   4370 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]		= 0.40f;
   4371 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]			= 0.20f;
   4372 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]	= 0.10f;
   4373 
   4374 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.20f;
   4375 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]			= 0.20f;
   4376 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]				= 0.10f;
   4377 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_COPYTEXSUBIMAGE2D]			= 0.50f;
   4378 
   4379 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.20f;
   4380 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]		= 0.25f;
   4381 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]			= 0.25f;
   4382 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_COPYTEXSUBIMAGE2D]	= 0.30f;
   4383 
   4384 
   4385 				std::string	name = de::toString(textureTestNdx);
   4386 				copyTexSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4387 			}
   4388 
   4389 			textureTests->addChild(copyTexSubImage2DTests);
   4390 		}
   4391 
   4392 		group->addChild(textureTests);
   4393 
   4394 		TestCaseGroup* bufferTests = new TestCaseGroup(ctx, "buffers", "Buffer management tests");
   4395 
   4396 		{
   4397 			TestCaseGroup* genBufferTests = new TestCaseGroup(ctx, "gen_delete", "Buffer gen and delete tests");
   4398 
   4399 			for (int bufferTestNdx = 0; bufferTestNdx < 20; bufferTestNdx++)
   4400 			{
   4401 				GLES2SharingRandomTest::TestConfig config;
   4402 				config.useFenceSync		= useSync;
   4403 				config.serverSync		= serverSync;
   4404 				config.threadCount		= 2 + bufferTestNdx % 5;
   4405 				config.operationCount	= 30 + bufferTestNdx;
   4406 
   4407 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_BUFFER]				= 1.0f;
   4408 
   4409 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]		= 0.25f;
   4410 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.75f;
   4411 
   4412 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]	= 0.5f;
   4413 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.5f;
   4414 
   4415 				std::string	name = de::toString(bufferTestNdx);
   4416 				genBufferTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4417 			}
   4418 
   4419 			bufferTests->addChild(genBufferTests);
   4420 		}
   4421 
   4422 		{
   4423 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "bufferdata", "Buffer gen, delete and bufferdata tests");
   4424 
   4425 			for (int bufferTestNdx = 0; bufferTestNdx < 20; bufferTestNdx++)
   4426 			{
   4427 				GLES2SharingRandomTest::TestConfig config;
   4428 				config.useFenceSync		= useSync;
   4429 				config.serverSync		= serverSync;
   4430 				config.threadCount		= 2 + bufferTestNdx % 5;
   4431 				config.operationCount	= 40 + bufferTestNdx;
   4432 
   4433 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_BUFFER]				= 1.0f;
   4434 
   4435 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]		= 0.10f;
   4436 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.10f;
   4437 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_BUFFER_DATA]		= 0.80f;
   4438 
   4439 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]	= 0.30f;
   4440 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.40f;
   4441 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_BUFFER_DATA]		= 0.30f;
   4442 
   4443 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_DESTROY_BUFFER]		= 0.40f;
   4444 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_CREATE_BUFFER]		= 0.40f;
   4445 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_BUFFER_DATA]			= 0.20f;
   4446 
   4447 				std::string	name = de::toString(bufferTestNdx);
   4448 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4449 			}
   4450 
   4451 			bufferTests->addChild(texImage2DTests);
   4452 		}
   4453 
   4454 		{
   4455 			TestCaseGroup* texSubImage2DTests = new TestCaseGroup(ctx, "buffersubdata", "Buffer gen, delete, bufferdata and bufferdata tests");
   4456 
   4457 			for (int bufferTestNdx = 0; bufferTestNdx < 20; bufferTestNdx++)
   4458 			{
   4459 				GLES2SharingRandomTest::TestConfig config;
   4460 				config.useFenceSync		= useSync;
   4461 				config.serverSync		= serverSync;
   4462 				config.threadCount		= 2 + bufferTestNdx % 5;
   4463 				config.operationCount	= 50 + bufferTestNdx;
   4464 
   4465 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_BUFFER]				= 1.0f;
   4466 
   4467 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]		= 0.05f;
   4468 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.10f;
   4469 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_BUFFER_DATA]		= 0.80f;
   4470 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_BUFFER_SUBDATA]		= 0.05f;
   4471 
   4472 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]	= 0.30f;
   4473 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.40f;
   4474 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_BUFFER_DATA]		= 0.20f;
   4475 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_BUFFER_SUBDATA]	= 0.10f;
   4476 
   4477 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_DESTROY_BUFFER]		= 0.20f;
   4478 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_CREATE_BUFFER]		= 0.20f;
   4479 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_BUFFER_DATA]			= 0.10f;
   4480 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_BUFFER_SUBDATA]		= 0.50f;
   4481 
   4482 				config.probabilities[THREADOPERATIONID_BUFFER_SUBDATA][THREADOPERATIONID_DESTROY_BUFFER]	= 0.20f;
   4483 				config.probabilities[THREADOPERATIONID_BUFFER_SUBDATA][THREADOPERATIONID_CREATE_BUFFER]		= 0.25f;
   4484 				config.probabilities[THREADOPERATIONID_BUFFER_SUBDATA][THREADOPERATIONID_BUFFER_DATA]		= 0.25f;
   4485 				config.probabilities[THREADOPERATIONID_BUFFER_SUBDATA][THREADOPERATIONID_BUFFER_SUBDATA]	= 0.30f;
   4486 
   4487 				std::string	name = de::toString(bufferTestNdx);
   4488 				texSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4489 			}
   4490 
   4491 			bufferTests->addChild(texSubImage2DTests);
   4492 		}
   4493 
   4494 		group->addChild(bufferTests);
   4495 
   4496 		TestCaseGroup* shaderTests = new TestCaseGroup(ctx, "shaders", "Shader management tests");
   4497 
   4498 		{
   4499 			TestCaseGroup* createShaderTests = new TestCaseGroup(ctx, "create_destroy", "Shader create and destroy tests");
   4500 
   4501 			for (int shaderTestNdx = 0; shaderTestNdx < 20; shaderTestNdx++)
   4502 			{
   4503 				GLES2SharingRandomTest::TestConfig config;
   4504 				config.useFenceSync		= useSync;
   4505 				config.serverSync		= serverSync;
   4506 				config.threadCount		= 2 + shaderTestNdx % 5;
   4507 				config.operationCount	= 30 + shaderTestNdx;
   4508 
   4509 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_VERTEX_SHADER]						= 0.5f;
   4510 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]						= 0.5f;
   4511 
   4512 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_SHADER]				= 0.20f;
   4513 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.40f;
   4514 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]		= 0.40f;
   4515 
   4516 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_SHADER]			= 0.20f;
   4517 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.40f;
   4518 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]	= 0.40f;
   4519 
   4520 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_SHADER]					= 0.5f;
   4521 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.25f;
   4522 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.25f;
   4523 
   4524 				std::string	name = de::toString(shaderTestNdx);
   4525 				createShaderTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4526 			}
   4527 
   4528 			shaderTests->addChild(createShaderTests);
   4529 		}
   4530 
   4531 		{
   4532 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "source", "Shader create, destroy and source tests");
   4533 
   4534 			for (int shaderTestNdx = 0; shaderTestNdx < 20; shaderTestNdx++)
   4535 			{
   4536 				GLES2SharingRandomTest::TestConfig config;
   4537 				config.useFenceSync		= useSync;
   4538 				config.serverSync		= serverSync;
   4539 				config.threadCount		= 2 + shaderTestNdx % 5;
   4540 				config.operationCount	= 40 + shaderTestNdx;
   4541 
   4542 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_VERTEX_SHADER]						= 0.5f;
   4543 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]						= 0.5f;
   4544 
   4545 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_SHADER]				= 0.10f;
   4546 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.20f;
   4547 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]		= 0.20f;
   4548 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.50f;
   4549 
   4550 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_SHADER]			= 0.10f;
   4551 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.20f;
   4552 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]	= 0.20f;
   4553 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.50f;
   4554 
   4555 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_SHADER]					= 0.30f;
   4556 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.30f;
   4557 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.30f;
   4558 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
   4559 
   4560 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_SHADER]						= 0.20f;
   4561 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
   4562 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.20f;
   4563 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_SOURCE]						= 0.40f;
   4564 
   4565 				std::string	name = de::toString(shaderTestNdx);
   4566 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4567 			}
   4568 
   4569 			shaderTests->addChild(texImage2DTests);
   4570 		}
   4571 
   4572 		{
   4573 			TestCaseGroup* texSubImage2DTests = new TestCaseGroup(ctx, "compile", "Shader create, destroy, source and compile tests");
   4574 
   4575 			for (int shaderTestNdx = 0; shaderTestNdx < 20; shaderTestNdx++)
   4576 			{
   4577 				GLES2SharingRandomTest::TestConfig config;
   4578 				config.useFenceSync		= useSync;
   4579 				config.serverSync		= serverSync;
   4580 				config.threadCount		= 2 + shaderTestNdx % 5;
   4581 				config.operationCount	= 50 + shaderTestNdx;
   4582 
   4583 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_VERTEX_SHADER]						= 0.5f;
   4584 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]						= 0.5f;
   4585 
   4586 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_SHADER]				= 0.10f;
   4587 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.15f;
   4588 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]		= 0.15f;
   4589 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.50f;
   4590 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_COMPILE]				= 0.10f;
   4591 
   4592 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_SHADER]			= 0.10f;
   4593 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.15f;
   4594 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]	= 0.15f;
   4595 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.50f;
   4596 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_COMPILE]			= 0.10f;
   4597 
   4598 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_SHADER]					= 0.30f;
   4599 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.25f;
   4600 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.25f;
   4601 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
   4602 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_COMPILE]					= 0.10f;
   4603 
   4604 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_SHADER]						= 0.10f;
   4605 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.10f;
   4606 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.10f;
   4607 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_SOURCE]						= 0.20f;
   4608 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_COMPILE]						= 0.50f;
   4609 
   4610 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_DESTROY_SHADER]					= 0.15f;
   4611 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.15f;
   4612 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.15f;
   4613 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_SOURCE]						= 0.30f;
   4614 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_COMPILE]					= 0.30f;
   4615 
   4616 				std::string	name = de::toString(shaderTestNdx);
   4617 				texSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4618 			}
   4619 
   4620 			shaderTests->addChild(texSubImage2DTests);
   4621 		}
   4622 
   4623 		group->addChild(shaderTests);
   4624 
   4625 		TestCaseGroup* programTests = new TestCaseGroup(ctx, "programs", "Program management tests");
   4626 
   4627 		{
   4628 			TestCaseGroup* createProgramTests = new TestCaseGroup(ctx, "create_destroy", "Program create and destroy tests");
   4629 
   4630 			for (int programTestNdx = 0; programTestNdx < 20; programTestNdx++)
   4631 			{
   4632 				GLES2SharingRandomTest::TestConfig config;
   4633 				config.useFenceSync		= useSync;
   4634 				config.serverSync		= serverSync;
   4635 				config.threadCount		= 2 + programTestNdx % 5;
   4636 				config.operationCount	= 30 + programTestNdx;
   4637 
   4638 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_PROGRAM]				= 1.0f;
   4639 
   4640 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]	= 0.25f;
   4641 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]	= 0.75f;
   4642 
   4643 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]	= 0.5f;
   4644 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]	= 0.5f;
   4645 
   4646 				std::string	name = de::toString(programTestNdx);
   4647 				createProgramTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4648 			}
   4649 
   4650 			programTests->addChild(createProgramTests);
   4651 		}
   4652 
   4653 		{
   4654 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "attach_detach", "Program create, destroy, attach and detach tests");
   4655 
   4656 			for (int programTestNdx = 0; programTestNdx < 20; programTestNdx++)
   4657 			{
   4658 				GLES2SharingRandomTest::TestConfig config;
   4659 				config.useFenceSync		= useSync;
   4660 				config.serverSync		= serverSync;
   4661 				config.threadCount		= 2 + programTestNdx % 5;
   4662 				config.operationCount	= 60 + programTestNdx;
   4663 
   4664 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_VERTEX_SHADER]						= 0.35f;
   4665 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]						= 0.35f;
   4666 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_PROGRAM]								= 0.30f;
   4667 
   4668 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_SHADER]				= 0.10f;
   4669 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.10f;
   4670 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]		= 0.10f;
   4671 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.30f;
   4672 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_COMPILE]				= 0.10f;
   4673 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_PROGRAM]				= 0.10f;
   4674 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]				= 0.05f;
   4675 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_ATTACH_SHADER]				= 0.15f;
   4676 
   4677 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_SHADER]			= 0.10f;
   4678 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.10f;
   4679 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]	= 0.10f;
   4680 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.30f;
   4681 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_COMPILE]			= 0.10f;
   4682 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_PROGRAM]			= 0.10f;
   4683 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]			= 0.05f;
   4684 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_ATTACH_SHADER]				= 0.15f;
   4685 
   4686 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_SHADER]					= 0.20f;
   4687 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
   4688 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
   4689 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
   4690 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_COMPILE]					= 0.10f;
   4691 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_PROGRAM]					= 0.15f;
   4692 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
   4693 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_ATTACH_SHADER]						= 0.15f;
   4694 
   4695 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_SHADER]						= 0.10f;
   4696 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.10f;
   4697 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.10f;
   4698 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_SOURCE]						= 0.20f;
   4699 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_COMPILE]						= 0.50f;
   4700 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_PROGRAM]						= 0.10f;
   4701 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.10f;
   4702 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_ATTACH_SHADER]						= 0.25f;
   4703 
   4704 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_DESTROY_SHADER]					= 0.15f;
   4705 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.15f;
   4706 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.15f;
   4707 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_SOURCE]						= 0.30f;
   4708 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_COMPILE]					= 0.30f;
   4709 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_PROGRAM]					= 0.10f;
   4710 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.10f;
   4711 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_ATTACH_SHADER]						= 0.35f;
   4712 
   4713 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_DESTROY_SHADER]					= 0.10f;
   4714 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
   4715 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
   4716 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_SHADER_SOURCE]						= 0.05f;
   4717 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_SHADER_COMPILE]					= 0.05f;
   4718 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]					= 0.15f;
   4719 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.05f;
   4720 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_ATTACH_SHADER]						= 0.40f;
   4721 
   4722 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_DESTROY_SHADER]					= 0.20f;
   4723 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
   4724 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
   4725 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_SHADER_SOURCE]					= 0.10f;
   4726 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_SHADER_COMPILE]					= 0.10f;
   4727 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]					= 0.20f;
   4728 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
   4729 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_ATTACH_SHADER]					= 0.10f;
   4730 
   4731 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_DESTROY_SHADER]						= 0.20f;
   4732 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
   4733 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.20f;
   4734 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
   4735 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_SHADER_COMPILE]						= 0.10f;
   4736 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_PROGRAM]						= 0.15f;
   4737 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
   4738 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_ATTACH_SHADER]						= 0.30f;
   4739 
   4740 				std::string	name = de::toString(programTestNdx);
   4741 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4742 			}
   4743 
   4744 			programTests->addChild(texImage2DTests);
   4745 		}
   4746 
   4747 		{
   4748 			TestCaseGroup* texSubImage2DTests = new TestCaseGroup(ctx, "link", "Program create, destroy, attach and link tests");
   4749 
   4750 			for (int programTestNdx = 0; programTestNdx < 20; programTestNdx++)
   4751 			{
   4752 				GLES2SharingRandomTest::TestConfig config;
   4753 				config.useFenceSync		= useSync;
   4754 				config.serverSync		= serverSync;
   4755 				config.threadCount		= 2 + programTestNdx % 5;
   4756 				config.operationCount	= 70 + programTestNdx;
   4757 
   4758 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_VERTEX_SHADER]						= 0.35f;
   4759 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]						= 0.35f;
   4760 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_PROGRAM]								= 0.30f;
   4761 
   4762 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_SHADER]				= 0.10f;
   4763 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.10f;
   4764 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]		= 0.10f;
   4765 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.30f;
   4766 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_COMPILE]				= 0.10f;
   4767 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_PROGRAM]				= 0.10f;
   4768 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]				= 0.05f;
   4769 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_ATTACH_SHADER]				= 0.15f;
   4770 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_LINK_PROGRAM]				= 0.10f;
   4771 
   4772 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_SHADER]			= 0.10f;
   4773 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.10f;
   4774 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]	= 0.10f;
   4775 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.30f;
   4776 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_COMPILE]			= 0.10f;
   4777 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_PROGRAM]			= 0.10f;
   4778 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]			= 0.05f;
   4779 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_ATTACH_SHADER]				= 0.15f;
   4780 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_LINK_PROGRAM]				= 0.10f;
   4781 
   4782 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_SHADER]					= 0.20f;
   4783 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
   4784 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
   4785 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
   4786 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_COMPILE]					= 0.10f;
   4787 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_PROGRAM]					= 0.15f;
   4788 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
   4789 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_ATTACH_SHADER]						= 0.15f;
   4790 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_LINK_PROGRAM]						= 0.10f;
   4791 
   4792 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_SHADER]						= 0.10f;
   4793 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.10f;
   4794 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.10f;
   4795 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_SOURCE]						= 0.20f;
   4796 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_COMPILE]						= 0.50f;
   4797 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_PROGRAM]						= 0.10f;
   4798 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.10f;
   4799 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_ATTACH_SHADER]						= 0.25f;
   4800 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_LINK_PROGRAM]						= 0.20f;
   4801 
   4802 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_DESTROY_SHADER]					= 0.15f;
   4803 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.15f;
   4804 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.15f;
   4805 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_SOURCE]						= 0.30f;
   4806 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_COMPILE]					= 0.30f;
   4807 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_PROGRAM]					= 0.10f;
   4808 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.10f;
   4809 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_ATTACH_SHADER]						= 0.35f;
   4810 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_LINK_PROGRAM]						= 0.20f;
   4811 
   4812 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_DESTROY_SHADER]					= 0.10f;
   4813 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
   4814 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
   4815 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_SHADER_SOURCE]						= 0.05f;
   4816 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_SHADER_COMPILE]					= 0.05f;
   4817 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]					= 0.15f;
   4818 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.05f;
   4819 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_ATTACH_SHADER]						= 0.40f;
   4820 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_LINK_PROGRAM]						= 0.05f;
   4821 
   4822 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_DESTROY_SHADER]					= 0.20f;
   4823 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
   4824 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
   4825 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_SHADER_SOURCE]					= 0.10f;
   4826 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_SHADER_COMPILE]					= 0.10f;
   4827 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]					= 0.20f;
   4828 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
   4829 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_ATTACH_SHADER]					= 0.10f;
   4830 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_LINK_PROGRAM]						= 0.05f;
   4831 
   4832 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_DESTROY_SHADER]						= 0.20f;
   4833 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
   4834 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.20f;
   4835 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
   4836 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_SHADER_COMPILE]						= 0.10f;
   4837 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_PROGRAM]						= 0.15f;
   4838 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
   4839 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_ATTACH_SHADER]						= 0.30f;
   4840 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_LINK_PROGRAM]						= 0.30f;
   4841 
   4842 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_DESTROY_SHADER]						= 0.20f;
   4843 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
   4844 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.20f;
   4845 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
   4846 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_SHADER_COMPILE]						= 0.10f;
   4847 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]						= 0.20f;
   4848 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]						= 0.15f;
   4849 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_ATTACH_SHADER]						= 0.10f;
   4850 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_LINK_PROGRAM]						= 0.05f;
   4851 
   4852 				std::string	name = de::toString(programTestNdx);
   4853 				texSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4854 			}
   4855 
   4856 			programTests->addChild(texSubImage2DTests);
   4857 		}
   4858 
   4859 		group->addChild(programTests);
   4860 
   4861 		TestCaseGroup* imageTests = new TestCaseGroup(ctx, "images", "Image management tests");
   4862 
   4863 		{
   4864 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "create_destroy", "Image gen, delete and teximage2D tests");
   4865 
   4866 			for (int imageTestNdx = 0; imageTestNdx < 20; imageTestNdx++)
   4867 			{
   4868 				GLES2SharingRandomTest::TestConfig config;
   4869 				config.useFenceSync		= useSync;
   4870 				config.serverSync		= serverSync;
   4871 				config.threadCount		= 2 + imageTestNdx % 5;
   4872 				config.operationCount	= 70 + imageTestNdx;
   4873 				config.useImages		= true;
   4874 
   4875 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]									= 1.0f;
   4876 
   4877 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.10f;
   4878 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.15f;
   4879 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.40f;
   4880 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.35f;
   4881 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.30f;
   4882 
   4883 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.15f;
   4884 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.20f;
   4885 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.40f;
   4886 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.35f;
   4887 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.15f;
   4888 
   4889 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.25f;
   4890 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]				= 0.25f;
   4891 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]	= 0.40f;
   4892 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]				= 0.35f;
   4893 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]					= 0.15f;
   4894 
   4895 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
   4896 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
   4897 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.40f;
   4898 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.35f;
   4899 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
   4900 
   4901 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]							= 0.25f;
   4902 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
   4903 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]					= 0.40f;
   4904 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]								= 0.35f;
   4905 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
   4906 
   4907 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
   4908 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]					= 0.25f;
   4909 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.30f;
   4910 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.15f;
   4911 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXIMAGE2D]						= 0.15f;
   4912 
   4913 				std::string	name = de::toString(imageTestNdx);
   4914 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4915 			}
   4916 
   4917 			imageTests->addChild(texImage2DTests);
   4918 		}
   4919 
   4920 		{
   4921 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "teximage2d", "Image gen, delete and teximage2D tests");
   4922 
   4923 			for (int imageTestNdx = 0; imageTestNdx < 20; imageTestNdx++)
   4924 			{
   4925 				GLES2SharingRandomTest::TestConfig config;
   4926 				config.useFenceSync		= useSync;
   4927 				config.serverSync		= serverSync;
   4928 				config.threadCount		= 2 + imageTestNdx % 5;
   4929 				config.operationCount	= 70 + imageTestNdx;
   4930 				config.useImages		= true;
   4931 
   4932 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]									= 1.0f;
   4933 
   4934 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.10f;
   4935 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.15f;
   4936 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.20f;
   4937 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.15f;
   4938 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.30f;
   4939 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.20f;
   4940 
   4941 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.15f;
   4942 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.20f;
   4943 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.15f;
   4944 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.15f;
   4945 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.15f;
   4946 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
   4947 
   4948 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.25f;
   4949 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]				= 0.25f;
   4950 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]	= 0.25f;
   4951 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]				= 0.25f;
   4952 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]					= 0.15f;
   4953 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]			= 0.15f;
   4954 
   4955 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
   4956 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
   4957 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
   4958 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
   4959 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
   4960 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
   4961 
   4962 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]							= 0.25f;
   4963 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
   4964 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]					= 0.25f;
   4965 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]								= 0.25f;
   4966 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
   4967 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
   4968 
   4969 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
   4970 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]					= 0.25f;
   4971 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.25f;
   4972 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.25f;
   4973 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXIMAGE2D]						= 0.15f;
   4974 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]				= 0.15f;
   4975 
   4976 				std::string	name = de::toString(imageTestNdx);
   4977 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   4978 			}
   4979 
   4980 			imageTests->addChild(texImage2DTests);
   4981 		}
   4982 
   4983 		{
   4984 			TestCaseGroup* texSubImage2DTests = new TestCaseGroup(ctx, "texsubimage2d", "Image gen, delete, teximage2D and texsubimage2d tests");
   4985 
   4986 			for (int imageTestNdx = 0; imageTestNdx < 20; imageTestNdx++)
   4987 			{
   4988 				GLES2SharingRandomTest::TestConfig config;
   4989 				config.useFenceSync		= useSync;
   4990 				config.serverSync		= serverSync;
   4991 				config.threadCount		= 2 + imageTestNdx % 5;
   4992 				config.operationCount	= 70 + imageTestNdx;
   4993 				config.useImages		= true;
   4994 
   4995 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]									= 1.0f;
   4996 
   4997 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.10f;
   4998 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.15f;
   4999 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.20f;
   5000 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.15f;
   5001 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.30f;
   5002 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.20f;
   5003 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXSUBIMAGE2D]							= 0.10f;
   5004 
   5005 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.15f;
   5006 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.20f;
   5007 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.15f;
   5008 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.15f;
   5009 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.15f;
   5010 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
   5011 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXSUBIMAGE2D]						= 0.10f;
   5012 
   5013 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.25f;
   5014 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]				= 0.25f;
   5015 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]	= 0.25f;
   5016 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]				= 0.25f;
   5017 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]					= 0.15f;
   5018 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]			= 0.15f;
   5019 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXSUBIMAGE2D]				= 0.10f;
   5020 
   5021 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
   5022 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
   5023 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
   5024 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
   5025 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
   5026 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
   5027 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXSUBIMAGE2D]							= 0.10f;
   5028 
   5029 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]							= 0.25f;
   5030 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
   5031 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]					= 0.25f;
   5032 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]								= 0.25f;
   5033 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
   5034 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
   5035 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXSUBIMAGE2D]								= 0.10f;
   5036 
   5037 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
   5038 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]					= 0.25f;
   5039 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.25f;
   5040 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.25f;
   5041 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXIMAGE2D]						= 0.15f;
   5042 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]				= 0.15f;
   5043 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXSUBIMAGE2D]						= 0.10f;
   5044 
   5045 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
   5046 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
   5047 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
   5048 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
   5049 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
   5050 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
   5051 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_TEXSUBIMAGE2D]							= 0.10f;
   5052 
   5053 				std::string	name = de::toString(imageTestNdx);
   5054 				texSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   5055 			}
   5056 
   5057 			imageTests->addChild(texSubImage2DTests);
   5058 		}
   5059 
   5060 		{
   5061 			TestCaseGroup* copyTexImage2DTests = new TestCaseGroup(ctx, "copyteximage2d", "Image gen, delete and copyteximage2d tests");
   5062 
   5063 			for (int imageTestNdx = 0; imageTestNdx < 20; imageTestNdx++)
   5064 			{
   5065 				GLES2SharingRandomTest::TestConfig config;
   5066 				config.useFenceSync		= useSync;
   5067 				config.serverSync		= serverSync;
   5068 				config.threadCount		= 2 + imageTestNdx % 5;
   5069 				config.operationCount	= 70 + imageTestNdx;
   5070 				config.useImages		= true;
   5071 
   5072 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]									= 1.0f;
   5073 
   5074 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.10f;
   5075 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.15f;
   5076 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.20f;
   5077 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.15f;
   5078 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_COPYTEXIMAGE2D]						= 0.30f;
   5079 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.20f;
   5080 
   5081 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.15f;
   5082 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.20f;
   5083 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.15f;
   5084 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.15f;
   5085 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_COPYTEXIMAGE2D]						= 0.15f;
   5086 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
   5087 
   5088 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.25f;
   5089 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]				= 0.25f;
   5090 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]	= 0.25f;
   5091 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]				= 0.25f;
   5092 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_COPYTEXIMAGE2D]				= 0.15f;
   5093 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]			= 0.15f;
   5094 
   5095 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
   5096 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
   5097 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
   5098 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
   5099 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_COPYTEXIMAGE2D]							= 0.15f;
   5100 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
   5101 
   5102 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
   5103 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]						= 0.25f;
   5104 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
   5105 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
   5106 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_COPYTEXIMAGE2D]						= 0.15f;
   5107 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
   5108 
   5109 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
   5110 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]					= 0.25f;
   5111 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.25f;
   5112 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.25f;
   5113 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_COPYTEXIMAGE2D]					= 0.15f;
   5114 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]				= 0.15f;
   5115 
   5116 				std::string	name = de::toString(imageTestNdx);
   5117 				copyTexImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   5118 			}
   5119 
   5120 			imageTests->addChild(copyTexImage2DTests);
   5121 		}
   5122 
   5123 		{
   5124 			TestCaseGroup* copyTexSubImage2DTests = new TestCaseGroup(ctx, "copytexsubimage2d", "Image gen, delete, teximage2D and copytexsubimage2d tests");
   5125 
   5126 			for (int imageTestNdx = 0; imageTestNdx < 20; imageTestNdx++)
   5127 			{
   5128 				GLES2SharingRandomTest::TestConfig config;
   5129 				config.useFenceSync		= useSync;
   5130 				config.serverSync		= serverSync;
   5131 				config.threadCount		= 2 + imageTestNdx % 5;
   5132 				config.operationCount	= 70 + imageTestNdx;
   5133 				config.useImages		= true;
   5134 
   5135 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]									= 1.0f;
   5136 
   5137 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.10f;
   5138 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.15f;
   5139 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.20f;
   5140 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.15f;
   5141 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.30f;
   5142 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.20f;
   5143 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]						= 0.10f;
   5144 
   5145 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.15f;
   5146 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.20f;
   5147 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.15f;
   5148 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.15f;
   5149 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.15f;
   5150 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
   5151 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]					= 0.10f;
   5152 
   5153 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.25f;
   5154 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]				= 0.25f;
   5155 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]	= 0.25f;
   5156 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]				= 0.25f;
   5157 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]					= 0.15f;
   5158 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]			= 0.15f;
   5159 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]			= 0.10f;
   5160 
   5161 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
   5162 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
   5163 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
   5164 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
   5165 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
   5166 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
   5167 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]						= 0.10f;
   5168 
   5169 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]							= 0.25f;
   5170 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
   5171 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]					= 0.25f;
   5172 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]								= 0.25f;
   5173 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
   5174 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
   5175 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_COPYTEXSUBIMAGE2D]							= 0.10f;
   5176 
   5177 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
   5178 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]					= 0.25f;
   5179 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.25f;
   5180 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.25f;
   5181 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXIMAGE2D]						= 0.15f;
   5182 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]				= 0.15f;
   5183 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]					= 0.10f;
   5184 
   5185 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
   5186 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]						= 0.25f;
   5187 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.25f;
   5188 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]						= 0.25f;
   5189 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]							= 0.15f;
   5190 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
   5191 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_COPYTEXSUBIMAGE2D]					= 0.10f;
   5192 
   5193 
   5194 				std::string	name = de::toString(imageTestNdx);
   5195 				copyTexSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
   5196 			}
   5197 
   5198 			imageTests->addChild(copyTexSubImage2DTests);
   5199 		}
   5200 
   5201 		group->addChild(imageTests);
   5202 	}
   5203 }
   5204 
   5205 GLES2SharingThreadedTests::GLES2SharingThreadedTests (EglTestContext& eglTestCtx)
   5206 	: TestCaseGroup(eglTestCtx, "multithread", "EGL GLES2 sharing multithread tests")
   5207 {
   5208 }
   5209 
   5210 void GLES2SharingThreadedTests::init (void)
   5211 {
   5212 	tcu::TestCaseGroup* simpleTests = new TestCaseGroup(m_eglTestCtx, "simple", "Simple multithreaded tests");
   5213 	addSimpleTests(m_eglTestCtx, simpleTests, false, false);
   5214 	addChild(simpleTests);
   5215 
   5216 	TestCaseGroup* randomTests = new TestCaseGroup(m_eglTestCtx, "random", "Random tests");
   5217 	addRandomTests(m_eglTestCtx, randomTests, false, false);
   5218 	addChild(randomTests);
   5219 
   5220 	tcu::TestCaseGroup* simpleTestsSync = new TestCaseGroup(m_eglTestCtx, "simple_egl_sync", "Simple multithreaded tests with EGL_KHR_fence_sync");
   5221 	addSimpleTests(m_eglTestCtx, simpleTestsSync, true, false);
   5222 	addChild(simpleTestsSync);
   5223 
   5224 	TestCaseGroup* randomTestsSync = new TestCaseGroup(m_eglTestCtx, "random_egl_sync", "Random tests with EGL_KHR_fence_sync");
   5225 	addRandomTests(m_eglTestCtx, randomTestsSync, true, false);
   5226 	addChild(randomTestsSync);
   5227 
   5228 	tcu::TestCaseGroup* simpleTestsServerSync = new TestCaseGroup(m_eglTestCtx, "simple_egl_server_sync", "Simple multithreaded tests with EGL_KHR_fence_sync and EGL_KHR_wait_sync");
   5229 	addSimpleTests(m_eglTestCtx, simpleTestsServerSync, true, true);
   5230 	addChild(simpleTestsServerSync);
   5231 
   5232 	TestCaseGroup* randomTestsServerSync = new TestCaseGroup(m_eglTestCtx, "random_egl_server_sync", "Random tests with EGL_KHR_fence_sync and EGL_KHR_wait_sync");
   5233 	addRandomTests(m_eglTestCtx, randomTestsServerSync, true, true);
   5234 	addChild(randomTestsServerSync);
   5235 }
   5236 
   5237 } // egl
   5238 } // deqp
   5239