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