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