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