• 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 	{
2220 		int threadNdx  = 0;
2221 
2222 		// Destroy images
2223 		// \note Android reference counts EGLDisplays so we can't trust the eglTerminate() to clean up resources
2224 		while (resourceManager.getImageCount() > 0)
2225 		{
2226 			const SharedPtr<GLES2ThreadTest::EGLImage> image = resourceManager.popImage(0);
2227 
2228 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DestroyImage(image, m_config.useFenceSync, m_config.serverSync));
2229 
2230 			threadNdx = (threadNdx + 1) % m_config.threadCount;
2231 		}
2232 	}
2233 
2234 	// Release contexts
2235 	for (int threadNdx = 0; threadNdx < m_config.threadCount; threadNdx++)
2236 	{
2237 		SharedPtr<GLES2ThreadTest::GLES2Context>	context = m_threads[threadNdx]->context;
2238 		SharedPtr<GLES2ThreadTest::Surface>			surface = m_threads[threadNdx]->surface;
2239 
2240 		m_threads[threadNdx]->addOperation(new GLES2ThreadTest::MakeCurrent(*m_threads[threadNdx], m_eglDisplay, SharedPtr<GLES2ThreadTest::Surface>(), SharedPtr<GLES2ThreadTest::GLES2Context>()));
2241 
2242 		resourceManager.addSurface(surface);
2243 		resourceManager.addContext(context);
2244 	}
2245 
2246 	// Destroy contexts
2247 	for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
2248 		m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DestroyContext(resourceManager.popContext(0)));
2249 
2250 	// Destroy surfaces
2251 	for (int threadNdx = 0; threadNdx < m_config.threadCount; threadNdx++)
2252 		m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DestroySurface(m_eglDisplay, resourceManager.popSurface(0)));
2253 }
2254 
deinit(void)2255 void GLES2SharingRandomTest::deinit (void)
2256 {
2257 	for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
2258 	{
2259 		delete m_threads[threadNdx];
2260 		m_threads[threadNdx] = DE_NULL;
2261 	}
2262 
2263 	m_threads.clear();
2264 
2265 	if (m_eglDisplay != EGL_NO_DISPLAY)
2266 	{
2267 		m_eglTestCtx.getLibrary().terminate(m_eglDisplay);
2268 		m_eglDisplay = EGL_NO_DISPLAY;
2269 	}
2270 
2271 	TCU_CHECK(!m_requiresRestart);
2272 }
2273 
addRandomOperation(GLES2ThreadTest::EGLResourceManager & resourceManager)2274 void GLES2SharingRandomTest::addRandomOperation (GLES2ThreadTest::EGLResourceManager& resourceManager)
2275 {
2276 	int threadNdx	= m_random.getUint32() % (deUint32)m_threads.size();
2277 
2278 	std::vector<OperationId>	operations;
2279 	std::vector<float>			weights;
2280 
2281 	operations.push_back(THREADOPERATIONID_CREATE_BUFFER);
2282 	weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_BUFFER]);
2283 
2284 	operations.push_back(THREADOPERATIONID_CREATE_TEXTURE);
2285 	weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_TEXTURE]);
2286 
2287 	operations.push_back(THREADOPERATIONID_CREATE_VERTEX_SHADER);
2288 	weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_VERTEX_SHADER]);
2289 
2290 	operations.push_back(THREADOPERATIONID_CREATE_FRAGMENT_SHADER);
2291 	weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]);
2292 
2293 	operations.push_back(THREADOPERATIONID_CREATE_PROGRAM);
2294 	weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_PROGRAM]);
2295 
2296 	int destroyableBufferNdx				= -1;
2297 	int destroyableTextureNdx				= -1;
2298 	int destroyableShaderNdx				= -1;
2299 	int destroyableProgramNdx				= -1;
2300 
2301 	int vertexShaderNdx						= -1;
2302 	int fragmentShaderNdx					= -1;
2303 
2304 	int definedTextureNdx					= -1;
2305 
2306 	int definedBufferNdx					= -1;
2307 
2308 	int definedShaderNdx					= -1;
2309 
2310 	int detachableProgramNdx				= -1;
2311 	GLenum detachShaderType					= GL_VERTEX_SHADER;
2312 
2313 	int unusedVertexAttachmentProgramNdx	= -1;
2314 	int unusedFragmentAttachmentProgramNdx	= -1;
2315 
2316 	int linkableProgramNdx					= -1;
2317 
2318 	int attachProgramNdx					= -1;
2319 	int attachShaderNdx						= -1;
2320 
2321 	int nonSiblingTextureNdx				= -1;
2322 
2323 	if (m_threads[threadNdx]->context->resourceManager->getBufferCount() > 0)
2324 		destroyableBufferNdx = m_random.getUint32() % m_threads[threadNdx]->context->resourceManager->getBufferCount();
2325 
2326 	if (m_threads[threadNdx]->context->resourceManager->getTextureCount() > 0)
2327 		destroyableTextureNdx = m_random.getUint32() % m_threads[threadNdx]->context->resourceManager->getTextureCount();
2328 
2329 	if (m_threads[threadNdx]->context->resourceManager->getShaderCount() > 0)
2330 		destroyableShaderNdx = m_random.getUint32() % m_threads[threadNdx]->context->resourceManager->getShaderCount();
2331 
2332 	if (m_threads[threadNdx]->context->resourceManager->getProgramCount() > 0)
2333 		destroyableProgramNdx = m_random.getUint32() % m_threads[threadNdx]->context->resourceManager->getProgramCount();
2334 
2335 	// Check what kind of buffers we have
2336 	for (int bufferNdx = 0; bufferNdx < m_threads[threadNdx]->context->resourceManager->getBufferCount(); bufferNdx++)
2337 	{
2338 		SharedPtr<GLES2ThreadTest::Buffer> buffer = m_threads[threadNdx]->context->resourceManager->getBuffer(bufferNdx);
2339 
2340 		if (buffer->isDefined)
2341 		{
2342 			if (definedBufferNdx == -1)
2343 				definedBufferNdx = bufferNdx;
2344 			else if (m_random.getBool())
2345 				definedBufferNdx = bufferNdx;
2346 		}
2347 	}
2348 
2349 	// Check what kind of textures we have
2350 	for (int textureNdx = 0; textureNdx < m_threads[threadNdx]->context->resourceManager->getTextureCount(); textureNdx++)
2351 	{
2352 		SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->getTexture(textureNdx);
2353 
2354 		if (texture->isDefined)
2355 		{
2356 			if (definedTextureNdx == -1)
2357 				definedTextureNdx = textureNdx;
2358 			else if (m_random.getBool())
2359 				definedTextureNdx = textureNdx;
2360 
2361 			if (!texture->sourceImage)
2362 			{
2363 				if (nonSiblingTextureNdx == -1)
2364 					nonSiblingTextureNdx = textureNdx;
2365 				else if (m_random.getBool())
2366 					nonSiblingTextureNdx = textureNdx;
2367 			}
2368 		}
2369 
2370 	}
2371 
2372 	// Check what kind of shaders we have
2373 	for (int shaderNdx = 0; shaderNdx < m_threads[threadNdx]->context->resourceManager->getShaderCount(); shaderNdx++)
2374 	{
2375 		SharedPtr<GLES2ThreadTest::Shader> shader = m_threads[threadNdx]->context->resourceManager->getShader(shaderNdx);
2376 
2377 		// Defined shader found
2378 		if (shader->isDefined)
2379 		{
2380 			if (definedShaderNdx == -1)
2381 				definedShaderNdx = shaderNdx;
2382 			else if (m_random.getBool())
2383 				definedShaderNdx = shaderNdx;
2384 		}
2385 
2386 		// Vertex shader found
2387 		if (shader->type == GL_VERTEX_SHADER)
2388 		{
2389 			if (vertexShaderNdx == -1)
2390 				vertexShaderNdx = shaderNdx;
2391 			else if (m_random.getBool())
2392 				vertexShaderNdx = shaderNdx;
2393 		}
2394 
2395 		// Fragmet shader found
2396 		if (shader->type == GL_FRAGMENT_SHADER)
2397 		{
2398 			if (fragmentShaderNdx == -1)
2399 				fragmentShaderNdx = shaderNdx;
2400 			else if (m_random.getBool())
2401 				fragmentShaderNdx = shaderNdx;
2402 		}
2403 	}
2404 
2405 	// Check what kind of programs we have
2406 	for (int programNdx = 0; programNdx < m_threads[threadNdx]->context->resourceManager->getProgramCount(); programNdx++)
2407 	{
2408 		SharedPtr<GLES2ThreadTest::Program> program = m_threads[threadNdx]->context->resourceManager->getProgram(programNdx);
2409 
2410 		// Program that can be detached
2411 		if (program->vertexShader || program->fragmentShader)
2412 		{
2413 			if (detachableProgramNdx == -1)
2414 			{
2415 				detachableProgramNdx = programNdx;
2416 
2417 				if (program->vertexShader)
2418 					detachShaderType = GL_VERTEX_SHADER;
2419 				else if (program->fragmentShader)
2420 					detachShaderType = GL_FRAGMENT_SHADER;
2421 				else
2422 					DE_ASSERT(false);
2423 			}
2424 			else if (m_random.getBool())
2425 			{
2426 				detachableProgramNdx = programNdx;
2427 
2428 				if (program->vertexShader)
2429 					detachShaderType = GL_VERTEX_SHADER;
2430 				else if (program->fragmentShader)
2431 					detachShaderType = GL_FRAGMENT_SHADER;
2432 				else
2433 					DE_ASSERT(false);
2434 			}
2435 		}
2436 
2437 		// Program that can be attached vertex shader
2438 		if (!program->vertexShader)
2439 		{
2440 			if (unusedVertexAttachmentProgramNdx == -1)
2441 				unusedVertexAttachmentProgramNdx = programNdx;
2442 			else if (m_random.getBool())
2443 				unusedVertexAttachmentProgramNdx = programNdx;
2444 		}
2445 
2446 		// Program that can be attached fragment shader
2447 		if (!program->fragmentShader)
2448 		{
2449 			if (unusedFragmentAttachmentProgramNdx == -1)
2450 				unusedFragmentAttachmentProgramNdx = programNdx;
2451 			else if (m_random.getBool())
2452 				unusedFragmentAttachmentProgramNdx = programNdx;
2453 		}
2454 
2455 		// Program that can be linked
2456 		if (program->vertexShader && program->fragmentShader)
2457 		{
2458 			if (linkableProgramNdx == -1)
2459 				linkableProgramNdx = programNdx;
2460 			else if (m_random.getBool())
2461 				linkableProgramNdx = programNdx;
2462 		}
2463 	}
2464 
2465 	// Has images
2466 	if (resourceManager.getImageCount() > 0)
2467 	{
2468 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DESTROY_IMAGE]);
2469 		operations.push_back(THREADOPERATIONID_DESTROY_IMAGE);
2470 
2471 		if (m_threads[threadNdx]->context->resourceManager->getTextureCount() > 0)
2472 		{
2473 			weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_TEXTURE_FROM_IMAGE]);
2474 			operations.push_back(THREADOPERATIONID_TEXTURE_FROM_IMAGE);
2475 		}
2476 	}
2477 
2478 	// Has buffer
2479 	if (destroyableBufferNdx != -1)
2480 	{
2481 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DESTROY_BUFFER]);
2482 		operations.push_back(THREADOPERATIONID_DESTROY_BUFFER);
2483 
2484 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_BUFFER_DATA]);
2485 		operations.push_back(THREADOPERATIONID_BUFFER_DATA);
2486 	}
2487 
2488 	// Has buffer with defined data
2489 	if (definedBufferNdx != -1)
2490 	{
2491 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_BUFFER_SUBDATA]);
2492 		operations.push_back(THREADOPERATIONID_BUFFER_SUBDATA);
2493 	}
2494 
2495 	// Has texture
2496 	if (destroyableTextureNdx != -1)
2497 	{
2498 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DESTROY_TEXTURE]);
2499 		operations.push_back(THREADOPERATIONID_DESTROY_TEXTURE);
2500 
2501 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_TEXIMAGE2D]);
2502 		operations.push_back(THREADOPERATIONID_TEXIMAGE2D);
2503 
2504 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_COPYTEXIMAGE2D]);
2505 		operations.push_back(THREADOPERATIONID_COPYTEXIMAGE2D);
2506 	}
2507 
2508 	// Has texture with data
2509 	if (definedTextureNdx != -1)
2510 	{
2511 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_TEXSUBIMAGE2D]);
2512 		operations.push_back(THREADOPERATIONID_TEXSUBIMAGE2D);
2513 
2514 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_COPYTEXSUBIMAGE2D]);
2515 		operations.push_back(THREADOPERATIONID_COPYTEXSUBIMAGE2D);
2516 	}
2517 
2518 	// Has texture that can be used as EGLimage source
2519 	if (nonSiblingTextureNdx != -1)
2520 	{
2521 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]);
2522 		operations.push_back(THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE);
2523 	}
2524 
2525 	// Has shader
2526 	if (destroyableShaderNdx != -1)
2527 	{
2528 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DESTROY_SHADER]);
2529 		operations.push_back(THREADOPERATIONID_DESTROY_SHADER);
2530 
2531 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_SHADER_SOURCE]);
2532 		operations.push_back(THREADOPERATIONID_SHADER_SOURCE);
2533 	}
2534 
2535 	// Has shader with defined source
2536 	if (definedShaderNdx != -1)
2537 	{
2538 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_SHADER_COMPILE]);
2539 		operations.push_back(THREADOPERATIONID_SHADER_COMPILE);
2540 	}
2541 
2542 	// Has program
2543 	if (destroyableProgramNdx != -1)
2544 	{
2545 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DESTROY_PROGRAM]);
2546 		operations.push_back(THREADOPERATIONID_DESTROY_PROGRAM);
2547 	}
2548 
2549 	// Has program that can be linked
2550 	if (linkableProgramNdx != -1)
2551 	{
2552 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_LINK_PROGRAM]);
2553 		operations.push_back(THREADOPERATIONID_LINK_PROGRAM);
2554 	}
2555 
2556 	// has program with attachments
2557 	if (detachableProgramNdx != -1)
2558 	{
2559 		weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_DETACH_SHADER]);
2560 		operations.push_back(THREADOPERATIONID_DETACH_SHADER);
2561 	}
2562 
2563 	// Has program and shader pair that can be attached
2564 	if (fragmentShaderNdx != -1 && unusedFragmentAttachmentProgramNdx != -1)
2565 	{
2566 		if (attachProgramNdx == -1)
2567 		{
2568 			DE_ASSERT(attachShaderNdx == -1);
2569 			attachProgramNdx = unusedFragmentAttachmentProgramNdx;
2570 			attachShaderNdx = fragmentShaderNdx;
2571 
2572 			weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_ATTACH_SHADER]);
2573 			operations.push_back(THREADOPERATIONID_ATTACH_SHADER);
2574 		}
2575 		else if (m_random.getBool())
2576 		{
2577 			attachProgramNdx = unusedFragmentAttachmentProgramNdx;
2578 			attachShaderNdx = fragmentShaderNdx;
2579 		}
2580 	}
2581 
2582 	if (vertexShaderNdx != -1 && unusedVertexAttachmentProgramNdx != -1)
2583 	{
2584 		if (attachProgramNdx == -1)
2585 		{
2586 			DE_ASSERT(attachShaderNdx == -1);
2587 			attachProgramNdx = unusedVertexAttachmentProgramNdx;
2588 			attachShaderNdx = vertexShaderNdx;
2589 
2590 			weights.push_back(m_config.probabilities[m_lastOperation][THREADOPERATIONID_ATTACH_SHADER]);
2591 			operations.push_back(THREADOPERATIONID_ATTACH_SHADER);
2592 		}
2593 		else if (m_random.getBool())
2594 		{
2595 			attachProgramNdx = unusedVertexAttachmentProgramNdx;
2596 			attachShaderNdx = vertexShaderNdx;
2597 		}
2598 	}
2599 
2600 	OperationId op = m_random.chooseWeighted<OperationId, std::vector<OperationId> ::iterator>(operations.begin(), operations.end(), weights.begin());
2601 
2602 	switch (op)
2603 	{
2604 		case THREADOPERATIONID_CREATE_BUFFER:
2605 		{
2606 			SharedPtr<GLES2ThreadTest::Buffer> buffer;
2607 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateBuffer(buffer, m_config.useFenceSync, m_config.serverSync));
2608 			m_threads[threadNdx]->context->resourceManager->addBuffer(buffer);
2609 			break;
2610 		}
2611 
2612 		case THREADOPERATIONID_DESTROY_BUFFER:
2613 		{
2614 			SharedPtr<GLES2ThreadTest::Buffer> buffer = m_threads[threadNdx]->context->resourceManager->popBuffer(destroyableBufferNdx);
2615 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DeleteBuffer(buffer, m_config.useFenceSync, m_config.serverSync));
2616 			break;
2617 		}
2618 
2619 		case THREADOPERATIONID_BUFFER_DATA:
2620 		{
2621 			SharedPtr<GLES2ThreadTest::Buffer> buffer = m_threads[threadNdx]->context->resourceManager->popBuffer(destroyableBufferNdx);
2622 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::BufferData(buffer, GL_ARRAY_BUFFER, 1024, GL_DYNAMIC_DRAW, m_config.useFenceSync, m_config.serverSync));
2623 			m_threads[threadNdx]->context->resourceManager->addBuffer(buffer);
2624 			break;
2625 		}
2626 
2627 		case THREADOPERATIONID_BUFFER_SUBDATA:
2628 		{
2629 			SharedPtr<GLES2ThreadTest::Buffer> buffer = m_threads[threadNdx]->context->resourceManager->popBuffer(definedBufferNdx);
2630 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::BufferSubData(buffer, GL_ARRAY_BUFFER, 1, 20, m_config.useFenceSync, m_config.serverSync));
2631 			m_threads[threadNdx]->context->resourceManager->addBuffer(buffer);
2632 			break;
2633 		}
2634 
2635 		case THREADOPERATIONID_CREATE_TEXTURE:
2636 		{
2637 			SharedPtr<GLES2ThreadTest::Texture> texture;
2638 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateTexture(texture, m_config.useFenceSync, m_config.serverSync));
2639 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
2640 			break;
2641 		}
2642 
2643 		case THREADOPERATIONID_DESTROY_TEXTURE:
2644 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DeleteTexture(m_threads[threadNdx]->context->resourceManager->popTexture(destroyableTextureNdx), m_config.useFenceSync, m_config.serverSync));
2645 			break;
2646 
2647 		case THREADOPERATIONID_TEXIMAGE2D:
2648 		{
2649 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(destroyableTextureNdx);
2650 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::TexImage2D(texture, 0, GL_RGBA, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
2651 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
2652 			break;
2653 		}
2654 
2655 		case THREADOPERATIONID_TEXSUBIMAGE2D:
2656 		{
2657 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(definedTextureNdx);
2658 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::TexSubImage2D(texture, 0, 30, 30, 50, 50, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
2659 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
2660 			break;
2661 		}
2662 
2663 		case THREADOPERATIONID_COPYTEXIMAGE2D:
2664 		{
2665 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(destroyableTextureNdx);
2666 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CopyTexImage2D(texture, 0, GL_RGBA, 20, 20, 300, 300, 0, m_config.useFenceSync, m_config.serverSync));
2667 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
2668 			break;
2669 		}
2670 
2671 		case THREADOPERATIONID_COPYTEXSUBIMAGE2D:
2672 		{
2673 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(definedTextureNdx);
2674 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CopyTexSubImage2D(texture, 0, 10, 10, 30, 30, 50, 50, m_config.useFenceSync, m_config.serverSync));
2675 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
2676 			break;
2677 		}
2678 
2679 		case THREADOPERATIONID_CREATE_VERTEX_SHADER:
2680 		{
2681 			SharedPtr<GLES2ThreadTest::Shader> shader;
2682 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateShader(GL_VERTEX_SHADER, shader, m_config.useFenceSync, m_config.serverSync));
2683 			m_threads[threadNdx]->context->resourceManager->addShader(shader);
2684 			break;
2685 		}
2686 
2687 		case THREADOPERATIONID_CREATE_FRAGMENT_SHADER:
2688 		{
2689 			SharedPtr<GLES2ThreadTest::Shader> shader;
2690 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateShader(GL_FRAGMENT_SHADER, shader, m_config.useFenceSync, m_config.serverSync));
2691 			m_threads[threadNdx]->context->resourceManager->addShader(shader);
2692 			break;
2693 		}
2694 
2695 		case THREADOPERATIONID_DESTROY_SHADER:
2696 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DeleteShader(m_threads[threadNdx]->context->resourceManager->popShader(destroyableShaderNdx), m_config.useFenceSync, m_config.serverSync));
2697 			break;
2698 
2699 		case THREADOPERATIONID_SHADER_SOURCE:
2700 		{
2701 			const char* vertexShaderSource =
2702 				"attribute mediump vec4 a_pos;\n"
2703 				"varying mediump vec4 v_pos;\n"
2704 				"void main (void)\n"
2705 				"{\n"
2706 				"\tv_pos = a_pos;\n"
2707 				"\tgl_Position = a_pos;\n"
2708 				"}\n";
2709 
2710 			const char* fragmentShaderSource =
2711 				"varying mediump vec4 v_pos;\n"
2712 				"void main (void)\n"
2713 				"{\n"
2714 				"\tgl_FragColor = v_pos;\n"
2715 				"}\n";
2716 			SharedPtr<GLES2ThreadTest::Shader> shader = m_threads[threadNdx]->context->resourceManager->popShader(destroyableShaderNdx);
2717 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::ShaderSource(shader, (shader->type == GL_VERTEX_SHADER ? vertexShaderSource : fragmentShaderSource), m_config.useFenceSync, m_config.serverSync));
2718 			m_threads[threadNdx]->context->resourceManager->addShader(shader);
2719 			break;
2720 		}
2721 
2722 		case THREADOPERATIONID_SHADER_COMPILE:
2723 		{
2724 			SharedPtr<GLES2ThreadTest::Shader> shader = m_threads[threadNdx]->context->resourceManager->popShader(definedShaderNdx);
2725 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::ShaderCompile(shader, m_config.useFenceSync, m_config.serverSync));
2726 			m_threads[threadNdx]->context->resourceManager->addShader(shader);
2727 			break;
2728 		}
2729 
2730 		case THREADOPERATIONID_CREATE_PROGRAM:
2731 		{
2732 			SharedPtr<GLES2ThreadTest::Program> program;
2733 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateProgram(program, m_config.useFenceSync, m_config.serverSync));
2734 			m_threads[threadNdx]->context->resourceManager->addProgram(program);
2735 			break;
2736 		}
2737 
2738 		case THREADOPERATIONID_DESTROY_PROGRAM:
2739 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DeleteProgram(m_threads[threadNdx]->context->resourceManager->popProgram(destroyableProgramNdx), m_config.useFenceSync, m_config.serverSync));
2740 			break;
2741 
2742 		case THREADOPERATIONID_ATTACH_SHADER:
2743 		{
2744 			SharedPtr<GLES2ThreadTest::Program>	program = m_threads[threadNdx]->context->resourceManager->popProgram(attachProgramNdx);
2745 			SharedPtr<GLES2ThreadTest::Shader>	shader	= m_threads[threadNdx]->context->resourceManager->popShader(attachShaderNdx);
2746 
2747 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::AttachShader(program, shader, m_config.useFenceSync, m_config.serverSync));
2748 
2749 			m_threads[threadNdx]->context->resourceManager->addProgram(program);
2750 			m_threads[threadNdx]->context->resourceManager->addShader(shader);
2751 			break;
2752 		}
2753 
2754 		case THREADOPERATIONID_DETACH_SHADER:
2755 		{
2756 			SharedPtr<GLES2ThreadTest::Program>	program = m_threads[threadNdx]->context->resourceManager->popProgram(detachableProgramNdx);
2757 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DetachShader(program, detachShaderType, m_config.useFenceSync, m_config.serverSync));
2758 			m_threads[threadNdx]->context->resourceManager->addProgram(program);
2759 			break;
2760 		}
2761 
2762 		case THREADOPERATIONID_LINK_PROGRAM:
2763 		{
2764 			SharedPtr<GLES2ThreadTest::Program>	program = m_threads[threadNdx]->context->resourceManager->popProgram(linkableProgramNdx);
2765 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
2766 			m_threads[threadNdx]->context->resourceManager->addProgram(program);
2767 			break;
2768 		}
2769 
2770 		case THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE:
2771 		{
2772 			SharedPtr<GLES2ThreadTest::EGLImage> image;
2773 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(nonSiblingTextureNdx);
2774 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::CreateImageFromTexture(image, texture, m_config.useFenceSync, m_config.serverSync));
2775 			// \note [mika] Can source be added back to resourceManager?
2776 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
2777 			resourceManager.addImage(image);
2778 			break;
2779 		}
2780 
2781 		case THREADOPERATIONID_DESTROY_IMAGE:
2782 		{
2783 			int imageNdx = m_random.getInt(0, resourceManager.getImageCount()-1);
2784 			SharedPtr<GLES2ThreadTest::EGLImage> image = resourceManager.popImage(imageNdx);
2785 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DestroyImage(image, m_config.useFenceSync, m_config.serverSync));
2786 			break;
2787 		}
2788 
2789 		case THREADOPERATIONID_TEXTURE_FROM_IMAGE:
2790 		{
2791 			int imageNdx = m_random.getInt(0, resourceManager.getImageCount()-1);
2792 			SharedPtr<GLES2ThreadTest::Texture> texture = m_threads[threadNdx]->context->resourceManager->popTexture(destroyableTextureNdx);
2793 			SharedPtr<GLES2ThreadTest::EGLImage> image = resourceManager.popImage(imageNdx);
2794 			m_threads[threadNdx]->addOperation(new GLES2ThreadTest::DefineTextureFromImage(texture, image, m_config.useFenceSync, m_config.serverSync));
2795 			m_threads[threadNdx]->context->resourceManager->addTexture(texture);
2796 			resourceManager.addImage(image);
2797 			break;
2798 		}
2799 
2800 		default:
2801 			DE_ASSERT(false);
2802 	}
2803 
2804 	m_lastOperation = op;
2805 }
2806 
iterate(void)2807 tcu::TestCase::IterateResult GLES2SharingRandomTest::iterate (void)
2808 {
2809 	if (!m_threadsStarted)
2810 	{
2811 		m_beginTimeUs = deGetMicroseconds();
2812 
2813 		// Execute threads
2814 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
2815 			m_threads[threadNdx]->exec();
2816 
2817 		m_threadsStarted = true;
2818 		m_threadsRunning = true;
2819 	}
2820 
2821 	if (m_threadsRunning)
2822 	{
2823 		// Wait threads to finish
2824 		int readyThreads = 0;
2825 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
2826 		{
2827 			const tcu::ThreadUtil::Thread::ThreadStatus status = m_threads[threadNdx]->getStatus();
2828 
2829 			if (status != tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING && status != tcu::ThreadUtil::Thread::THREADSTATUS_NOT_STARTED)
2830 				readyThreads++;
2831 		}
2832 
2833 		if (readyThreads == (int)m_threads.size())
2834 		{
2835 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
2836 				m_threads[threadNdx]->join();
2837 
2838 			m_executionReady	= true;
2839 			m_requiresRestart	= false;
2840 		}
2841 
2842 		if (deGetMicroseconds() - m_beginTimeUs > m_timeOutUs)
2843 		{
2844 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
2845 			{
2846 				if (m_threads[threadNdx]->getStatus() != tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING)
2847 				{
2848 					if (m_threads[threadNdx]->isStarted())
2849 						m_threads[threadNdx]->join();
2850 				}
2851 			}
2852 			m_executionReady	= true;
2853 			m_requiresRestart	= true;
2854 			m_timeOutTimeUs		= deGetMicroseconds();
2855 		}
2856 		else
2857 		{
2858 			deSleep(m_sleepTimeMs);
2859 		}
2860 	}
2861 
2862 	if (m_executionReady)
2863 	{
2864 		std::vector<int> indices(m_threads.size(), 0);
2865 
2866 		if (m_timeOutTimeUs != 0)
2867 			m_log << tcu::TestLog::Message << "Execution timeout limit reached. Trying to get per thread logs. This is potentially dangerous." << tcu::TestLog::EndMessage;
2868 
2869 		while (true)
2870 		{
2871 			int			firstThread = -1;
2872 
2873 			// Find first thread with messages
2874 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
2875 			{
2876 				if (m_threads[threadNdx]->getMessageCount() > indices[threadNdx])
2877 				{
2878 					firstThread = threadNdx;
2879 					break;
2880 				}
2881 			}
2882 
2883 			// No more messages
2884 			if (firstThread == -1)
2885 				break;
2886 
2887 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
2888 			{
2889 				// No more messages in this thread
2890 				if (m_threads[threadNdx]->getMessageCount() <= indices[threadNdx])
2891 					continue;
2892 
2893 				if ((m_threads[threadNdx]->getMessage(indices[threadNdx]).getTime() - m_beginTimeUs) < (m_threads[firstThread]->getMessage(indices[firstThread]).getTime() - m_beginTimeUs))
2894 					firstThread = threadNdx;
2895 			}
2896 
2897 			tcu::ThreadUtil::Message message = m_threads[firstThread]->getMessage(indices[firstThread]);
2898 
2899 			m_log << tcu::TestLog::Message << "[" << (message.getTime() - m_beginTimeUs) << "] (" << firstThread << ") " << message.getMessage() << tcu::TestLog::EndMessage;
2900 			indices[firstThread]++;
2901 		}
2902 
2903 		if (m_timeOutTimeUs != 0)
2904 			m_log << tcu::TestLog::Message << "[" << (m_timeOutTimeUs - m_beginTimeUs) << "] Execution timeout limit reached" << tcu::TestLog::EndMessage;
2905 
2906 		bool isOk = true;
2907 		bool notSupported = false;
2908 
2909 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
2910 		{
2911 			const tcu::ThreadUtil::Thread::ThreadStatus status = m_threads[threadNdx]->getStatus();
2912 
2913 			switch (status)
2914 			{
2915 				case tcu::ThreadUtil::Thread::THREADSTATUS_FAILED:
2916 				case tcu::ThreadUtil::Thread::THREADSTATUS_INIT_FAILED:
2917 				case tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING:
2918 					isOk = false;
2919 					break;
2920 
2921 				case tcu::ThreadUtil::Thread::THREADSTATUS_NOT_SUPPORTED:
2922 					notSupported = true;
2923 					break;
2924 
2925 				case tcu::ThreadUtil::Thread::THREADSTATUS_READY:
2926 					// Nothing
2927 					break;
2928 
2929 				default:
2930 					DE_ASSERT(false);
2931 					isOk = false;
2932 			};
2933 		}
2934 
2935 		if (notSupported)
2936 			throw tcu::NotSupportedError("Thread threw tcu::NotSupportedError", "", __FILE__, __LINE__);
2937 
2938 		if (isOk)
2939 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2940 		else
2941 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2942 
2943 		return STOP;
2944 	}
2945 
2946 	return CONTINUE;
2947 }
2948 
2949 class GLES2ThreadedSharingTest : public TestCase
2950 {
2951 public:
2952 	struct TestConfig
2953 	{
2954 		enum ResourceType
2955 		{
2956 			RESOURCETYPE_BUFFER = 0,
2957 			RESOURCETYPE_TEXTURE,
2958 			RESOURCETYPE_VERTEX_SHADER,
2959 			RESOURCETYPE_FRAGMENT_SHADER,
2960 			RESOURCETYPE_PROGRAM,
2961 			RESOURCETYPE_IMAGE
2962 		};
2963 
2964 		ResourceType	resourceType;
2965 		bool			singleContext;
2966 		int				define;
2967 		int				modify;
2968 		bool			useFenceSync;
2969 		bool			serverSync;
2970 		bool			render;
2971 	};
2972 						GLES2ThreadedSharingTest	(EglTestContext& context, const TestConfig& config, const char* name, const char* description);
2973 						~GLES2ThreadedSharingTest	(void);
2974 
2975 	void				init						(void);
2976 	void				deinit						(void);
2977 	IterateResult		iterate						(void);
2978 
2979 	void				addBufferOperations			(void);
2980 	void				addTextureOperations		(void);
2981 	void				addImageOperations			(void);
2982 	void				addShaderOperations			(GLenum type);
2983 	void				addProgramOperations		(void);
2984 
2985 private:
2986 	TestConfig				m_config;
2987 	tcu::TestLog&			m_log;
2988 	int						m_seed;
2989 	bool					m_threadsStarted;
2990 	bool					m_threadsRunning;
2991 	bool					m_executionReady;
2992 	bool					m_requiresRestart;
2993 	deUint64				m_beginTimeUs;
2994 	deUint64				m_timeOutUs;
2995 	deUint32				m_sleepTimeMs;
2996 	deUint64				m_timeOutTimeUs;
2997 
2998 	std::vector<GLES2ThreadTest::EGLThread*>	m_threads;
2999 
3000 	EGLDisplay				m_eglDisplay;
3001 	EGLConfig				m_eglConfig;
3002 	glw::Functions			m_gl;
3003 };
3004 
GLES2ThreadedSharingTest(EglTestContext & context,const TestConfig & config,const char * name,const char * description)3005 GLES2ThreadedSharingTest::GLES2ThreadedSharingTest (EglTestContext& context, const TestConfig& config, const char* name, const char* description)
3006 	: TestCase			(context, name, description)
3007 	, m_config			(config)
3008 	, m_log				(m_testCtx.getLog())
3009 	, m_seed			(deStringHash(name))
3010 	, m_threadsStarted	(false)
3011 	, m_threadsRunning	(false)
3012 	, m_executionReady	(false)
3013 	, m_requiresRestart	(false)
3014 	, m_beginTimeUs		(0)
3015 	, m_timeOutUs		(10000000)	// 10 seconds
3016 	, m_sleepTimeMs		(1)			// 1 milliseconds
3017 	, m_timeOutTimeUs	(0)
3018 	, m_eglDisplay		(EGL_NO_DISPLAY)
3019 	, m_eglConfig		(0)
3020 {
3021 }
3022 
~GLES2ThreadedSharingTest(void)3023 GLES2ThreadedSharingTest::~GLES2ThreadedSharingTest (void)
3024 {
3025 	GLES2ThreadedSharingTest::deinit();
3026 }
3027 
init(void)3028 void GLES2ThreadedSharingTest::init (void)
3029 {
3030 	const Library& egl = m_eglTestCtx.getLibrary();
3031 
3032 	const EGLint attribList[] =
3033 	{
3034 		EGL_RENDERABLE_TYPE,	EGL_OPENGL_ES2_BIT,
3035 		EGL_SURFACE_TYPE,		EGL_WINDOW_BIT,
3036 		EGL_ALPHA_SIZE,			1,
3037 		EGL_NONE
3038 	};
3039 
3040 	m_eglDisplay	= eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
3041 	m_eglConfig		= eglu::chooseSingleConfig(egl, m_eglDisplay, attribList);
3042 
3043 	m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2,0));
3044 
3045 	// Check extensions
3046 	if (m_config.useFenceSync)
3047 		requireEGLExtension(egl, m_eglDisplay, "EGL_KHR_fence_sync");
3048 
3049 	if (m_config.serverSync)
3050 		requireEGLExtension(egl, m_eglDisplay, "EGL_KHR_wait_sync");
3051 
3052 	if (m_config.resourceType == TestConfig::RESOURCETYPE_IMAGE)
3053 	{
3054 		requireEGLExtension(egl, m_eglDisplay, "EGL_KHR_image_base");
3055 		requireEGLExtension(egl, m_eglDisplay, "EGL_KHR_gl_texture_2D_image");
3056 	}
3057 
3058 	// Create threads
3059 	m_threads.push_back(new GLES2ThreadTest::EGLThread(egl, m_gl, deInt32Hash(m_seed)));
3060 	m_threads.push_back(new GLES2ThreadTest::EGLThread(egl, m_gl, deInt32Hash(m_seed*200)));
3061 
3062 	SharedPtr<GLES2ThreadTest::GLES2Context> contex1;
3063 	SharedPtr<GLES2ThreadTest::GLES2Context> contex2;
3064 
3065 	SharedPtr<GLES2ThreadTest::Surface> surface1;
3066 	SharedPtr<GLES2ThreadTest::Surface> surface2;
3067 
3068 	// Create contexts
3069 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateContext(m_eglDisplay, m_eglConfig, SharedPtr<GLES2ThreadTest::GLES2Context>(), contex1));
3070 	m_threads[1]->addOperation(new GLES2ThreadTest::CreateContext(m_eglDisplay, m_eglConfig, contex1, contex2));
3071 
3072 	// Create surfaces
3073 	m_threads[0]->addOperation(new GLES2ThreadTest::CreatePBufferSurface(m_eglDisplay, m_eglConfig, 400, 400, surface1));
3074 	m_threads[1]->addOperation(new GLES2ThreadTest::CreatePBufferSurface(m_eglDisplay, m_eglConfig, 400, 400, surface2));
3075 
3076 	// Make current contexts
3077 	m_threads[0]->addOperation(new GLES2ThreadTest::MakeCurrent(*m_threads[0], m_eglDisplay, surface1, contex1));
3078 	m_threads[1]->addOperation(new GLES2ThreadTest::MakeCurrent(*m_threads[1], m_eglDisplay, surface2, contex2));
3079 	// Operations to check fence sync support
3080 	if (m_config.useFenceSync)
3081 	{
3082 		m_threads[0]->addOperation(new GLES2ThreadTest::InitGLExtension("GL_OES_EGL_sync"));
3083 		m_threads[1]->addOperation(new GLES2ThreadTest::InitGLExtension("GL_OES_EGL_sync"));
3084 	}
3085 
3086 
3087 	switch (m_config.resourceType)
3088 	{
3089 		case TestConfig::RESOURCETYPE_BUFFER:
3090 			addBufferOperations();
3091 			break;
3092 
3093 		case TestConfig::RESOURCETYPE_TEXTURE:
3094 			addTextureOperations();
3095 			break;
3096 
3097 		case TestConfig::RESOURCETYPE_IMAGE:
3098 			addImageOperations();
3099 			break;
3100 
3101 		case TestConfig::RESOURCETYPE_VERTEX_SHADER:
3102 			addShaderOperations(GL_VERTEX_SHADER);
3103 			break;
3104 
3105 		case TestConfig::RESOURCETYPE_FRAGMENT_SHADER:
3106 			addShaderOperations(GL_FRAGMENT_SHADER);
3107 			break;
3108 
3109 		case TestConfig::RESOURCETYPE_PROGRAM:
3110 			addProgramOperations();
3111 			break;
3112 
3113 		default:
3114 			DE_ASSERT(false);
3115 	}
3116 
3117 	// Relaese contexts
3118 	m_threads[0]->addOperation(new GLES2ThreadTest::MakeCurrent(*m_threads[0], m_eglDisplay, SharedPtr<GLES2ThreadTest::Surface>(), SharedPtr<GLES2ThreadTest::GLES2Context>()));
3119 	m_threads[1]->addOperation(new GLES2ThreadTest::MakeCurrent(*m_threads[0], m_eglDisplay, SharedPtr<GLES2ThreadTest::Surface>(), SharedPtr<GLES2ThreadTest::GLES2Context>()));
3120 
3121 	// Destory context
3122 	m_threads[0]->addOperation(new GLES2ThreadTest::DestroyContext(contex1));
3123 	m_threads[1]->addOperation(new GLES2ThreadTest::DestroyContext(contex2));
3124 
3125 	// Destroy surfaces
3126 	m_threads[0]->addOperation(new GLES2ThreadTest::DestroySurface(m_eglDisplay, surface1));
3127 	m_threads[1]->addOperation(new GLES2ThreadTest::DestroySurface(m_eglDisplay, surface2));
3128 }
3129 
addBufferOperations(void)3130 void GLES2ThreadedSharingTest::addBufferOperations (void)
3131 {
3132 	// Add operations for verify
3133 	SharedPtr<GLES2ThreadTest::Shader>	vertexShader;
3134 	SharedPtr<GLES2ThreadTest::Shader>	fragmentShader;
3135 	SharedPtr<GLES2ThreadTest::Program>	program;
3136 
3137 	if (m_config.render)
3138 	{
3139 		const char* vertexShaderSource =
3140 		"attribute highp vec2 a_pos;\n"
3141 		"varying mediump vec2 v_pos;\n"
3142 		"void main(void)\n"
3143 		"{\n"
3144 		"\tv_pos = a_pos;\n"
3145 		"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
3146 		"}\n";
3147 
3148 		const char* fragmentShaderSource =
3149 		"varying mediump vec2 v_pos;\n"
3150 		"void main(void)\n"
3151 		"{\n"
3152 		"\tgl_FragColor = vec4(v_pos, 0.5, 1.0);\n"
3153 		"}\n";
3154 
3155 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_VERTEX_SHADER, vertexShader, m_config.useFenceSync, m_config.serverSync));
3156 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(vertexShader, vertexShaderSource, m_config.useFenceSync, m_config.serverSync));
3157 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(vertexShader, m_config.useFenceSync, m_config.serverSync));
3158 
3159 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_FRAGMENT_SHADER, fragmentShader, m_config.useFenceSync, m_config.serverSync));
3160 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(fragmentShader, fragmentShaderSource, m_config.useFenceSync, m_config.serverSync));
3161 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(fragmentShader, m_config.useFenceSync, m_config.serverSync));
3162 
3163 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateProgram(program, m_config.useFenceSync, m_config.serverSync));
3164 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, fragmentShader, m_config.useFenceSync, m_config.serverSync));
3165 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, vertexShader, m_config.useFenceSync, m_config.serverSync));
3166 
3167 		m_threads[0]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
3168 	}
3169 
3170 	SharedPtr<GLES2ThreadTest::Buffer> buffer;
3171 
3172 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateBuffer(buffer, m_config.useFenceSync, m_config.serverSync));
3173 
3174 	if (m_config.define)
3175 	{
3176 		if (m_config.modify || m_config.render)
3177 			m_threads[0]->addOperation(new GLES2ThreadTest::BufferData(buffer, GL_ARRAY_BUFFER, 1024, GL_DYNAMIC_DRAW, m_config.useFenceSync, m_config.serverSync));
3178 		else
3179 			m_threads[1]->addOperation(new GLES2ThreadTest::BufferData(buffer, GL_ARRAY_BUFFER, 1024, GL_DYNAMIC_DRAW, m_config.useFenceSync, m_config.serverSync));
3180 	}
3181 
3182 	if (m_config.modify)
3183 	{
3184 		if (m_config.render)
3185 			m_threads[0]->addOperation(new GLES2ThreadTest::BufferSubData(buffer, GL_ARRAY_BUFFER, 17, 17, m_config.useFenceSync, m_config.serverSync));
3186 		else
3187 			m_threads[1]->addOperation(new GLES2ThreadTest::BufferSubData(buffer, GL_ARRAY_BUFFER, 17, 17, m_config.useFenceSync, m_config.serverSync));
3188 	}
3189 
3190 	if (m_config.render)
3191 	{
3192 		m_threads[0]->addOperation(new GLES2ThreadTest::RenderBuffer(program, buffer, m_config.useFenceSync, m_config.serverSync));
3193 		m_threads[1]->addOperation(new GLES2ThreadTest::RenderBuffer(program, buffer, m_config.useFenceSync, m_config.serverSync));
3194 
3195 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels1;
3196 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels2;
3197 
3198 		m_threads[0]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels1, m_config.useFenceSync, m_config.serverSync));
3199 		m_threads[1]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels2, m_config.useFenceSync, m_config.serverSync));
3200 
3201 		m_threads[0]->addOperation(new tcu::ThreadUtil::CompareData(pixels1, pixels2));
3202 	}
3203 
3204 	if (m_config.modify || m_config.render)
3205 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteBuffer(buffer, m_config.useFenceSync, m_config.serverSync));
3206 	else
3207 		m_threads[1]->addOperation(new GLES2ThreadTest::DeleteBuffer(buffer, m_config.useFenceSync, m_config.serverSync));
3208 
3209 	if (m_config.render)
3210 	{
3211 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(vertexShader, m_config.useFenceSync, m_config.serverSync));
3212 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(fragmentShader, m_config.useFenceSync, m_config.serverSync));
3213 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteProgram(program, m_config.useFenceSync, m_config.serverSync));
3214 	}
3215 }
3216 
addTextureOperations(void)3217 void GLES2ThreadedSharingTest::addTextureOperations (void)
3218 {
3219 	// Add operations for verify
3220 	SharedPtr<GLES2ThreadTest::Shader>	vertexShader;
3221 	SharedPtr<GLES2ThreadTest::Shader>	fragmentShader;
3222 	SharedPtr<GLES2ThreadTest::Program>	program;
3223 
3224 	if (m_config.render)
3225 	{
3226 		const char* vertexShaderSource =
3227 		"attribute highp vec2 a_pos;\n"
3228 		"varying mediump vec2 v_pos;\n"
3229 		"void main(void)\n"
3230 		"{\n"
3231 		"\tv_pos = a_pos;\n"
3232 		"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
3233 		"}\n";
3234 
3235 		const char* fragmentShaderSource =
3236 		"varying mediump vec2 v_pos;\n"
3237 		"uniform sampler2D u_sampler;\n"
3238 		"void main(void)\n"
3239 		"{\n"
3240 		"\tgl_FragColor = texture2D(u_sampler, v_pos);\n"
3241 		"}\n";
3242 
3243 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_VERTEX_SHADER, vertexShader, m_config.useFenceSync, m_config.serverSync));
3244 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(vertexShader, vertexShaderSource, m_config.useFenceSync, m_config.serverSync));
3245 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(vertexShader, m_config.useFenceSync, m_config.serverSync));
3246 
3247 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_FRAGMENT_SHADER, fragmentShader, m_config.useFenceSync, m_config.serverSync));
3248 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(fragmentShader, fragmentShaderSource, m_config.useFenceSync, m_config.serverSync));
3249 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(fragmentShader, m_config.useFenceSync, m_config.serverSync));
3250 
3251 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateProgram(program, m_config.useFenceSync, m_config.serverSync));
3252 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, fragmentShader, m_config.useFenceSync, m_config.serverSync));
3253 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, vertexShader, m_config.useFenceSync, m_config.serverSync));
3254 
3255 		m_threads[0]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
3256 	}
3257 
3258 	SharedPtr<GLES2ThreadTest::Texture> texture;
3259 
3260 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateTexture(texture, m_config.useFenceSync, m_config.serverSync));
3261 
3262 	if (m_config.define == 1)
3263 	{
3264 		if (m_config.modify || m_config.render)
3265 			m_threads[0]->addOperation(new GLES2ThreadTest::TexImage2D(texture, 0, GL_RGBA, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
3266 		else
3267 			m_threads[1]->addOperation(new GLES2ThreadTest::TexImage2D(texture, 0, GL_RGBA, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
3268 	}
3269 
3270 	if (m_config.define == 2)
3271 	{
3272 		if (m_config.modify || m_config.render)
3273 			m_threads[0]->addOperation(new GLES2ThreadTest::CopyTexImage2D(texture, 0, GL_RGBA, 17, 17, 256, 256, 0, m_config.useFenceSync, m_config.serverSync));
3274 		else
3275 			m_threads[1]->addOperation(new GLES2ThreadTest::CopyTexImage2D(texture, 0, GL_RGBA, 17, 17, 256, 256, 0, m_config.useFenceSync, m_config.serverSync));
3276 	}
3277 
3278 	if (m_config.modify == 1)
3279 	{
3280 		if (m_config.render)
3281 			m_threads[0]->addOperation(new GLES2ThreadTest::TexSubImage2D(texture, 0, 17, 17, 29, 29, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
3282 		else
3283 			m_threads[1]->addOperation(new GLES2ThreadTest::TexSubImage2D(texture, 0, 17, 17, 29, 29, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
3284 	}
3285 
3286 	if (m_config.modify == 2)
3287 	{
3288 		if (m_config.render)
3289 			m_threads[0]->addOperation(new GLES2ThreadTest::CopyTexSubImage2D(texture, 0, 7, 7, 17, 17, 29, 29, m_config.useFenceSync, m_config.serverSync));
3290 		else
3291 			m_threads[1]->addOperation(new GLES2ThreadTest::CopyTexSubImage2D(texture, 0, 7, 7, 17, 17, 29, 29, m_config.useFenceSync, m_config.serverSync));
3292 	}
3293 
3294 	if (m_config.render)
3295 	{
3296 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels1;
3297 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels2;
3298 
3299 		m_threads[0]->addOperation(new GLES2ThreadTest::RenderTexture(program, texture, m_config.useFenceSync, m_config.serverSync));
3300 		m_threads[1]->addOperation(new GLES2ThreadTest::RenderTexture(program, texture, m_config.useFenceSync, m_config.serverSync));
3301 
3302 		m_threads[0]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels1, m_config.useFenceSync, m_config.serverSync));
3303 		m_threads[1]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels2, m_config.useFenceSync, m_config.serverSync));
3304 
3305 		m_threads[0]->addOperation(new tcu::ThreadUtil::CompareData(pixels1, pixels2));
3306 	}
3307 
3308 	if (m_config.modify || m_config.render)
3309 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteTexture(texture, m_config.useFenceSync, m_config.serverSync));
3310 	else
3311 		m_threads[1]->addOperation(new GLES2ThreadTest::DeleteTexture(texture, m_config.useFenceSync, m_config.serverSync));
3312 
3313 	if (m_config.render)
3314 	{
3315 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(vertexShader, m_config.useFenceSync, m_config.serverSync));
3316 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(fragmentShader, m_config.useFenceSync, m_config.serverSync));
3317 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteProgram(program, m_config.useFenceSync, m_config.serverSync));
3318 	}
3319 }
3320 
addImageOperations(void)3321 void GLES2ThreadedSharingTest::addImageOperations (void)
3322 {
3323 	// Add operations for verify
3324 	SharedPtr<GLES2ThreadTest::Shader>	vertexShader;
3325 	SharedPtr<GLES2ThreadTest::Shader>	fragmentShader;
3326 	SharedPtr<GLES2ThreadTest::Program>	program;
3327 
3328 	m_threads[0]->addOperation(new GLES2ThreadTest::InitGLExtension("GL_OES_EGL_image"));
3329 	m_threads[1]->addOperation(new GLES2ThreadTest::InitGLExtension("GL_OES_EGL_image"));
3330 
3331 	if (m_config.render)
3332 	{
3333 		const char* vertexShaderSource =
3334 		"attribute highp vec2 a_pos;\n"
3335 		"varying mediump vec2 v_pos;\n"
3336 		"void main(void)\n"
3337 		"{\n"
3338 		"\tv_pos = a_pos;\n"
3339 		"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
3340 		"}\n";
3341 
3342 		const char* fragmentShaderSource =
3343 		"varying mediump vec2 v_pos;\n"
3344 		"uniform sampler2D u_sampler;\n"
3345 		"void main(void)\n"
3346 		"{\n"
3347 		"\tgl_FragColor = texture2D(u_sampler, v_pos);\n"
3348 		"}\n";
3349 
3350 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_VERTEX_SHADER, vertexShader, m_config.useFenceSync, m_config.serverSync));
3351 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(vertexShader, vertexShaderSource, m_config.useFenceSync, m_config.serverSync));
3352 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(vertexShader, m_config.useFenceSync, m_config.serverSync));
3353 
3354 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_FRAGMENT_SHADER, fragmentShader, m_config.useFenceSync, m_config.serverSync));
3355 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(fragmentShader, fragmentShaderSource, m_config.useFenceSync, m_config.serverSync));
3356 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(fragmentShader, m_config.useFenceSync, m_config.serverSync));
3357 
3358 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateProgram(program, m_config.useFenceSync, m_config.serverSync));
3359 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, fragmentShader, m_config.useFenceSync, m_config.serverSync));
3360 		m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, vertexShader, m_config.useFenceSync, m_config.serverSync));
3361 
3362 		m_threads[0]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
3363 	}
3364 
3365 	SharedPtr<GLES2ThreadTest::Texture>		sourceTexture;
3366 	SharedPtr<GLES2ThreadTest::Texture>		texture;
3367 	SharedPtr<GLES2ThreadTest::EGLImage>	image;
3368 
3369 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateTexture(sourceTexture, m_config.useFenceSync, m_config.serverSync));
3370 	m_threads[0]->addOperation(new GLES2ThreadTest::TexImage2D(sourceTexture, 0, GL_RGBA, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
3371 
3372 	if (m_config.define == 1)
3373 	{
3374 		if (m_config.modify || m_config.render)
3375 			m_threads[0]->addOperation(new GLES2ThreadTest::CreateImageFromTexture(image, sourceTexture, m_config.useFenceSync, m_config.serverSync));
3376 		else
3377 			m_threads[1]->addOperation(new GLES2ThreadTest::CreateImageFromTexture(image, sourceTexture, m_config.useFenceSync, m_config.serverSync));
3378 	}
3379 
3380 	if (m_config.define == 2)
3381 	{
3382 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateImageFromTexture(image, sourceTexture, m_config.useFenceSync, m_config.serverSync));
3383 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateTexture(texture, m_config.useFenceSync, m_config.serverSync));
3384 
3385 		if (m_config.modify || m_config.render)
3386 			m_threads[0]->addOperation(new GLES2ThreadTest::DefineTextureFromImage(texture, image, m_config.useFenceSync, m_config.serverSync));
3387 		else
3388 			m_threads[1]->addOperation(new GLES2ThreadTest::DefineTextureFromImage(texture, image, m_config.useFenceSync, m_config.serverSync));
3389 	}
3390 
3391 	m_threads[0]->addOperation(new GLES2ThreadTest::DeleteTexture(sourceTexture, m_config.useFenceSync, m_config.serverSync));
3392 
3393 	if (m_config.modify == 1)
3394 	{
3395 		DE_ASSERT(m_config.define != 1);
3396 
3397 		if (m_config.render)
3398 			m_threads[0]->addOperation(new GLES2ThreadTest::TexSubImage2D(texture, 0, 17, 17, 29, 29, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
3399 		else
3400 			m_threads[1]->addOperation(new GLES2ThreadTest::TexSubImage2D(texture, 0, 17, 17, 29, 29, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
3401 	}
3402 
3403 	if (m_config.modify == 2)
3404 	{
3405 		DE_ASSERT(m_config.define != 1);
3406 
3407 		if (m_config.render)
3408 			m_threads[0]->addOperation(new GLES2ThreadTest::CopyTexSubImage2D(texture, 0, 7, 7, 17, 17, 29, 29, m_config.useFenceSync, m_config.serverSync));
3409 		else
3410 			m_threads[1]->addOperation(new GLES2ThreadTest::CopyTexSubImage2D(texture, 0, 7, 7, 17, 17, 29, 29, m_config.useFenceSync, m_config.serverSync));
3411 	}
3412 
3413 	if (m_config.modify == 3)
3414 	{
3415 		DE_ASSERT(m_config.define != 1);
3416 
3417 		if (m_config.render)
3418 			m_threads[0]->addOperation(new GLES2ThreadTest::TexImage2D(texture, 0, GL_RGBA, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
3419 		else
3420 			m_threads[1]->addOperation(new GLES2ThreadTest::TexImage2D(texture, 0, GL_RGBA, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, m_config.useFenceSync, m_config.serverSync));
3421 	}
3422 
3423 	if (m_config.modify == 4)
3424 	{
3425 		DE_ASSERT(m_config.define != 1);
3426 
3427 		if (m_config.render)
3428 			m_threads[0]->addOperation(new GLES2ThreadTest::CopyTexImage2D(texture, 0, GL_RGBA, 7, 7, 256, 256, 0, m_config.useFenceSync, m_config.serverSync));
3429 		else
3430 			m_threads[1]->addOperation(new GLES2ThreadTest::CopyTexImage2D(texture, 0, GL_RGBA, 7, 7, 256, 256, 0, m_config.useFenceSync, m_config.serverSync));
3431 	}
3432 
3433 	if (m_config.render)
3434 	{
3435 		DE_ASSERT(m_config.define != 1);
3436 
3437 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels1;
3438 		SharedPtr<tcu::ThreadUtil::DataBlock> pixels2;
3439 
3440 		m_threads[0]->addOperation(new GLES2ThreadTest::RenderTexture(program, texture, m_config.useFenceSync, m_config.serverSync));
3441 		m_threads[1]->addOperation(new GLES2ThreadTest::RenderTexture(program, texture, m_config.useFenceSync, m_config.serverSync));
3442 
3443 		m_threads[0]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels1, m_config.useFenceSync, m_config.serverSync));
3444 		m_threads[1]->addOperation(new GLES2ThreadTest::ReadPixels(0, 0, 400, 400, GL_RGBA, GL_UNSIGNED_BYTE, pixels2, m_config.useFenceSync, m_config.serverSync));
3445 
3446 		m_threads[0]->addOperation(new tcu::ThreadUtil::CompareData(pixels1, pixels2));
3447 	}
3448 
3449 	if (texture)
3450 	{
3451 		if (m_config.modify || m_config.render)
3452 			m_threads[0]->addOperation(new GLES2ThreadTest::DeleteTexture(texture, m_config.useFenceSync, m_config.serverSync));
3453 		else
3454 			m_threads[1]->addOperation(new GLES2ThreadTest::DeleteTexture(texture, m_config.useFenceSync, m_config.serverSync));
3455 	}
3456 
3457 	if (m_config.modify || m_config.render)
3458 		m_threads[0]->addOperation(new GLES2ThreadTest::DestroyImage(image, m_config.useFenceSync, m_config.serverSync));
3459 	else
3460 		m_threads[1]->addOperation(new GLES2ThreadTest::DestroyImage(image, m_config.useFenceSync, m_config.serverSync));
3461 
3462 	if (m_config.render)
3463 	{
3464 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(vertexShader, m_config.useFenceSync, m_config.serverSync));
3465 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(fragmentShader, m_config.useFenceSync, m_config.serverSync));
3466 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteProgram(program, m_config.useFenceSync, m_config.serverSync));
3467 	}
3468 }
3469 
addShaderOperations(GLenum type)3470 void GLES2ThreadedSharingTest::addShaderOperations (GLenum type)
3471 {
3472 	SharedPtr<GLES2ThreadTest::Shader> shader;
3473 
3474 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(type, shader, m_config.useFenceSync, m_config.serverSync));
3475 
3476 	if (m_config.define)
3477 	{
3478 		const char* vertexShaderSource =
3479 		"attribute mediump vec4 a_pos;\n"
3480 		"void main(void)\n"
3481 		"{\n"
3482 		"\tgl_Position = a_pos;\n"
3483 		"}";
3484 
3485 		const char* fragmentShaderSource =
3486 		"void main(void)\n"
3487 		"{\n"
3488 		"\tgl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
3489 		"}";
3490 
3491 		if (m_config.modify || m_config.render)
3492 			m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(shader, (type == GL_VERTEX_SHADER ? vertexShaderSource : fragmentShaderSource), m_config.useFenceSync, m_config.serverSync));
3493 		else
3494 			m_threads[1]->addOperation(new GLES2ThreadTest::ShaderSource(shader, (type == GL_VERTEX_SHADER ? vertexShaderSource : fragmentShaderSource), m_config.useFenceSync, m_config.serverSync));
3495 	}
3496 
3497 	if (m_config.modify)
3498 	{
3499 		if (m_config.render)
3500 			m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(shader, m_config.useFenceSync, m_config.serverSync));
3501 		else
3502 			m_threads[1]->addOperation(new GLES2ThreadTest::ShaderCompile(shader, m_config.useFenceSync, m_config.serverSync));
3503 	}
3504 
3505 	DE_ASSERT(!m_config.render);
3506 
3507 	if (m_config.modify || m_config.render)
3508 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(shader, m_config.useFenceSync, m_config.serverSync));
3509 	else
3510 		m_threads[1]->addOperation(new GLES2ThreadTest::DeleteShader(shader, m_config.useFenceSync, m_config.serverSync));
3511 }
3512 
addProgramOperations(void)3513 void GLES2ThreadedSharingTest::addProgramOperations (void)
3514 {
3515 	// Add operations for verify
3516 	SharedPtr<GLES2ThreadTest::Shader>	vertexShader;
3517 	SharedPtr<GLES2ThreadTest::Shader>	fragmentShader;
3518 
3519 	if (m_config.define)
3520 	{
3521 		const char* vertexShaderSource =
3522 		"attribute highp vec2 a_pos;\n"
3523 		"varying mediump vec2 v_pos;\n"
3524 		"void main(void)\n"
3525 		"{\n"
3526 		"\tv_pos = a_pos;\n"
3527 		"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
3528 		"}\n";
3529 
3530 		const char* fragmentShaderSource =
3531 		"varying mediump vec2 v_pos;\n"
3532 		"void main(void)\n"
3533 		"{\n"
3534 		"\tgl_FragColor = vec4(v_pos, 0.5, 1.0);\n"
3535 		"}\n";
3536 
3537 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_VERTEX_SHADER, vertexShader, m_config.useFenceSync, m_config.serverSync));
3538 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(vertexShader, vertexShaderSource, m_config.useFenceSync, m_config.serverSync));
3539 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(vertexShader, m_config.useFenceSync, m_config.serverSync));
3540 
3541 		m_threads[0]->addOperation(new GLES2ThreadTest::CreateShader(GL_FRAGMENT_SHADER, fragmentShader, m_config.useFenceSync, m_config.serverSync));
3542 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderSource(fragmentShader, fragmentShaderSource, m_config.useFenceSync, m_config.serverSync));
3543 		m_threads[0]->addOperation(new GLES2ThreadTest::ShaderCompile(fragmentShader, m_config.useFenceSync, m_config.serverSync));
3544 	}
3545 
3546 	SharedPtr<GLES2ThreadTest::Program> program;
3547 
3548 	m_threads[0]->addOperation(new GLES2ThreadTest::CreateProgram(program, m_config.useFenceSync, m_config.serverSync));
3549 
3550 	if (m_config.define)
3551 	{
3552 		// Attach shaders
3553 		if (m_config.modify || m_config.render)
3554 		{
3555 			m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, vertexShader, m_config.useFenceSync, m_config.serverSync));
3556 			m_threads[0]->addOperation(new GLES2ThreadTest::AttachShader(program, fragmentShader, m_config.useFenceSync, m_config.serverSync));
3557 		}
3558 		else
3559 		{
3560 			m_threads[1]->addOperation(new GLES2ThreadTest::AttachShader(program, vertexShader, m_config.useFenceSync, m_config.serverSync));
3561 			m_threads[1]->addOperation(new GLES2ThreadTest::AttachShader(program, fragmentShader, m_config.useFenceSync, m_config.serverSync));
3562 		}
3563 	}
3564 
3565 	if (m_config.modify == 1)
3566 	{
3567 		// Link program
3568 		if (m_config.render)
3569 			m_threads[0]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
3570 		else
3571 			m_threads[1]->addOperation(new GLES2ThreadTest::LinkProgram(program, m_config.useFenceSync, m_config.serverSync));
3572 	}
3573 
3574 	if (m_config.modify == 2)
3575 	{
3576 		// Link program
3577 		if (m_config.render)
3578 		{
3579 			m_threads[0]->addOperation(new GLES2ThreadTest::DetachShader(program, GL_VERTEX_SHADER, m_config.useFenceSync, m_config.serverSync));
3580 			m_threads[0]->addOperation(new GLES2ThreadTest::DetachShader(program, GL_FRAGMENT_SHADER, m_config.useFenceSync, m_config.serverSync));
3581 		}
3582 		else
3583 		{
3584 			m_threads[1]->addOperation(new GLES2ThreadTest::DetachShader(program, GL_VERTEX_SHADER, m_config.useFenceSync, m_config.serverSync));
3585 			m_threads[1]->addOperation(new GLES2ThreadTest::DetachShader(program, GL_FRAGMENT_SHADER, m_config.useFenceSync, m_config.serverSync));
3586 		}
3587 	}
3588 
3589 	if (m_config.render)
3590 	{
3591 		DE_ASSERT(false);
3592 	}
3593 
3594 	if (m_config.modify || m_config.render)
3595 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteProgram(program, m_config.useFenceSync, m_config.serverSync));
3596 	else
3597 		m_threads[1]->addOperation(new GLES2ThreadTest::DeleteProgram(program, m_config.useFenceSync, m_config.serverSync));
3598 
3599 	if (m_config.render)
3600 	{
3601 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(vertexShader, m_config.useFenceSync, m_config.serverSync));
3602 		m_threads[0]->addOperation(new GLES2ThreadTest::DeleteShader(fragmentShader, m_config.useFenceSync, m_config.serverSync));
3603 	}
3604 }
3605 
deinit(void)3606 void GLES2ThreadedSharingTest::deinit (void)
3607 {
3608 	for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
3609 	{
3610 		delete m_threads[threadNdx];
3611 		m_threads[threadNdx] = DE_NULL;
3612 	}
3613 
3614 	m_threads.clear();
3615 
3616 	if (m_eglDisplay != EGL_NO_DISPLAY)
3617 	{
3618 		m_eglTestCtx.getLibrary().terminate(m_eglDisplay);
3619 		m_eglDisplay = EGL_NO_DISPLAY;
3620 	}
3621 
3622 	TCU_CHECK(!m_requiresRestart);
3623 }
3624 
iterate(void)3625 tcu::TestCase::IterateResult GLES2ThreadedSharingTest::iterate (void)
3626 {
3627 	if (!m_threadsStarted)
3628 	{
3629 		m_beginTimeUs = deGetMicroseconds();
3630 
3631 		// Execute threads
3632 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
3633 			m_threads[threadNdx]->exec();
3634 
3635 		m_threadsStarted = true;
3636 		m_threadsRunning = true;
3637 	}
3638 
3639 	if (m_threadsRunning)
3640 	{
3641 		// Wait threads to finish
3642 		int readyThreads = 0;
3643 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
3644 		{
3645 			const tcu::ThreadUtil::Thread::ThreadStatus status = m_threads[threadNdx]->getStatus();
3646 
3647 			if (status != tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING && status != tcu::ThreadUtil::Thread::THREADSTATUS_NOT_STARTED)
3648 				readyThreads++;
3649 		}
3650 
3651 		if (readyThreads == (int)m_threads.size())
3652 		{
3653 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
3654 				m_threads[threadNdx]->join();
3655 
3656 			m_executionReady	= true;
3657 			m_requiresRestart	= false;
3658 		}
3659 
3660 		if (deGetMicroseconds() - m_beginTimeUs > m_timeOutUs)
3661 		{
3662 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
3663 			{
3664 				if (m_threads[threadNdx]->getStatus() != tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING)
3665 					m_threads[threadNdx]->join();
3666 			}
3667 			m_executionReady	= true;
3668 			m_requiresRestart	= true;
3669 			m_timeOutTimeUs		= deGetMicroseconds();
3670 		}
3671 		else
3672 		{
3673 			deSleep(m_sleepTimeMs);
3674 		}
3675 	}
3676 
3677 	if (m_executionReady)
3678 	{
3679 		std::vector<int> indices(m_threads.size(), 0);
3680 
3681 		if (m_timeOutTimeUs != 0)
3682 			m_log << tcu::TestLog::Message << "Execution timeout limit reached. Trying to get per thread logs. This is potentially dangerous." << tcu::TestLog::EndMessage;
3683 
3684 		while (true)
3685 		{
3686 			int			firstThread = -1;
3687 
3688 			// Find first thread with messages
3689 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
3690 			{
3691 				if (m_threads[threadNdx]->getMessageCount() > indices[threadNdx])
3692 				{
3693 					firstThread = threadNdx;
3694 					break;
3695 				}
3696 			}
3697 
3698 			// No more messages
3699 			if (firstThread == -1)
3700 				break;
3701 
3702 			for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
3703 			{
3704 				// No more messages in this thread
3705 				if (m_threads[threadNdx]->getMessageCount() <= indices[threadNdx])
3706 					continue;
3707 
3708 				if ((m_threads[threadNdx]->getMessage(indices[threadNdx]).getTime() - m_beginTimeUs) < (m_threads[firstThread]->getMessage(indices[firstThread]).getTime() - m_beginTimeUs))
3709 					firstThread = threadNdx;
3710 			}
3711 
3712 			tcu::ThreadUtil::Message message = m_threads[firstThread]->getMessage(indices[firstThread]);
3713 
3714 			m_log << tcu::TestLog::Message << "[" << (message.getTime() - m_beginTimeUs) << "] (" << firstThread << ") " << message.getMessage() << tcu::TestLog::EndMessage;
3715 			indices[firstThread]++;
3716 		}
3717 
3718 		if (m_timeOutTimeUs != 0)
3719 			m_log << tcu::TestLog::Message << "[" << (m_timeOutTimeUs - m_beginTimeUs) << "] Execution timeout limit reached" << tcu::TestLog::EndMessage;
3720 
3721 		bool isOk = true;
3722 		bool notSupported = false;
3723 
3724 		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
3725 		{
3726 			const tcu::ThreadUtil::Thread::ThreadStatus status = m_threads[threadNdx]->getStatus();
3727 
3728 			switch (status)
3729 			{
3730 				case tcu::ThreadUtil::Thread::THREADSTATUS_FAILED:
3731 				case tcu::ThreadUtil::Thread::THREADSTATUS_INIT_FAILED:
3732 				case tcu::ThreadUtil::Thread::THREADSTATUS_RUNNING:
3733 					isOk = false;
3734 					break;
3735 
3736 				case tcu::ThreadUtil::Thread::THREADSTATUS_NOT_SUPPORTED:
3737 					notSupported = true;
3738 					break;
3739 
3740 				case tcu::ThreadUtil::Thread::THREADSTATUS_READY:
3741 					// Nothing
3742 					break;
3743 
3744 				default:
3745 					DE_ASSERT(false);
3746 					isOk = false;
3747 			};
3748 		}
3749 
3750 		if (notSupported)
3751 			throw tcu::NotSupportedError("Thread threw tcu::NotSupportedError", "", __FILE__, __LINE__);
3752 
3753 		if (isOk)
3754 			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3755 		else
3756 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3757 
3758 		return STOP;
3759 	}
3760 
3761 	return CONTINUE;
3762 }
3763 
addSimpleTests(EglTestContext & ctx,tcu::TestCaseGroup * group,bool useSync,bool serverSync)3764 static void addSimpleTests (EglTestContext& ctx, tcu::TestCaseGroup* group, bool useSync, bool serverSync)
3765 {
3766 	{
3767 		TestCaseGroup* bufferTests = new TestCaseGroup(ctx, "buffers", "Buffer management tests");
3768 
3769 		{
3770 			GLES2ThreadedSharingTest::TestConfig config;
3771 
3772 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_BUFFER;
3773 			config.useFenceSync = useSync;
3774 			config.serverSync	= serverSync;
3775 			config.define = 0;
3776 			config.modify = 0;
3777 			config.render = false;
3778 			bufferTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "gen_delete", "Generate and delete buffer"));
3779 		}
3780 
3781 		{
3782 			GLES2ThreadedSharingTest::TestConfig config;
3783 
3784 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_BUFFER;
3785 			config.useFenceSync = useSync;
3786 			config.serverSync	= serverSync;
3787 			config.define = 1;
3788 			config.modify = 0;
3789 			config.render = false;
3790 			bufferTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "bufferdata", "Generate, set data and delete buffer"));
3791 		}
3792 
3793 		{
3794 			GLES2ThreadedSharingTest::TestConfig config;
3795 
3796 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_BUFFER;
3797 			config.useFenceSync = useSync;
3798 			config.serverSync	= serverSync;
3799 			config.define = 1;
3800 			config.modify = 1;
3801 			config.render = false;
3802 			bufferTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "buffersubdata", "Generate, set data, update data and delete buffer"));
3803 		}
3804 
3805 		{
3806 			GLES2ThreadedSharingTest::TestConfig config;
3807 
3808 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_BUFFER;
3809 			config.useFenceSync = useSync;
3810 			config.serverSync	= serverSync;
3811 			config.define = 1;
3812 			config.modify = 0;
3813 			config.render = true;
3814 			bufferTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "bufferdata_render", "Generate, set data, render and delete buffer"));
3815 		}
3816 
3817 		{
3818 			GLES2ThreadedSharingTest::TestConfig config;
3819 
3820 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_BUFFER;
3821 			config.useFenceSync = useSync;
3822 			config.serverSync	= serverSync;
3823 			config.define = 1;
3824 			config.modify = 1;
3825 			config.render = true;
3826 			bufferTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "buffersubdata_render", "Generate, set data, update data, render and delete buffer"));
3827 		}
3828 
3829 		group->addChild(bufferTests);
3830 	}
3831 
3832 	{
3833 		TestCaseGroup* textureTests = new TestCaseGroup(ctx, "textures", "Texture management tests");
3834 
3835 		{
3836 			GLES2ThreadedSharingTest::TestConfig config;
3837 
3838 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3839 			config.useFenceSync = useSync;
3840 			config.serverSync	= serverSync;
3841 			config.define = 0;
3842 			config.modify = 0;
3843 			config.render = false;
3844 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "gen_delete", "Generate and delete texture"));
3845 		}
3846 
3847 		{
3848 			GLES2ThreadedSharingTest::TestConfig config;
3849 
3850 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3851 			config.useFenceSync = useSync;
3852 			config.serverSync	= serverSync;
3853 			config.define = 1;
3854 			config.modify = 0;
3855 			config.render = false;
3856 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d", "Generate, set data and delete texture"));
3857 		}
3858 
3859 		{
3860 			GLES2ThreadedSharingTest::TestConfig config;
3861 
3862 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3863 			config.useFenceSync = useSync;
3864 			config.serverSync	= serverSync;
3865 			config.define = 1;
3866 			config.modify = 1;
3867 			config.render = false;
3868 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_texsubimage2d", "Generate, set data, update data and delete texture"));
3869 		}
3870 
3871 		{
3872 			GLES2ThreadedSharingTest::TestConfig config;
3873 
3874 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3875 			config.useFenceSync = useSync;
3876 			config.serverSync	= serverSync;
3877 			config.define = 1;
3878 			config.modify = 2;
3879 			config.render = false;
3880 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_copytexsubimage2d", "Generate, set data, update data and delete texture"));
3881 		}
3882 
3883 		{
3884 			GLES2ThreadedSharingTest::TestConfig config;
3885 
3886 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3887 			config.useFenceSync = useSync;
3888 			config.serverSync	= serverSync;
3889 			config.define = 1;
3890 			config.modify = 0;
3891 			config.render = true;
3892 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_render", "Generate, set data, render and delete texture"));
3893 		}
3894 
3895 		{
3896 			GLES2ThreadedSharingTest::TestConfig config;
3897 
3898 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3899 			config.useFenceSync = useSync;
3900 			config.serverSync	= serverSync;
3901 			config.define = 1;
3902 			config.modify = 1;
3903 			config.render = true;
3904 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_texsubimage2d_render", "Generate, set data, update data, render and delete texture"));
3905 		}
3906 
3907 		{
3908 			GLES2ThreadedSharingTest::TestConfig config;
3909 
3910 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3911 			config.useFenceSync = useSync;
3912 			config.serverSync	= serverSync;
3913 			config.define = 1;
3914 			config.modify = 2;
3915 			config.render = true;
3916 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_copytexsubimage2d_render", "Generate, set data, update data, render and delete texture"));
3917 		}
3918 
3919 		{
3920 			GLES2ThreadedSharingTest::TestConfig config;
3921 
3922 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3923 			config.useFenceSync = useSync;
3924 			config.serverSync	= serverSync;
3925 			config.define = 2;
3926 			config.modify = 0;
3927 			config.render = false;
3928 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d", "Generate, set data and delete texture"));
3929 		}
3930 
3931 		{
3932 			GLES2ThreadedSharingTest::TestConfig config;
3933 
3934 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3935 			config.useFenceSync = useSync;
3936 			config.serverSync	= serverSync;
3937 			config.define = 2;
3938 			config.modify = 1;
3939 			config.render = false;
3940 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_texsubimage2d", "Generate, set data, update data and delete texture"));
3941 		}
3942 
3943 		{
3944 			GLES2ThreadedSharingTest::TestConfig config;
3945 
3946 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3947 			config.useFenceSync = useSync;
3948 			config.serverSync	= serverSync;
3949 			config.define = 2;
3950 			config.modify = 2;
3951 			config.render = false;
3952 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_copytexsubimage2d", "Generate, set data, update data and delete texture"));
3953 		}
3954 
3955 		{
3956 			GLES2ThreadedSharingTest::TestConfig config;
3957 
3958 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3959 			config.useFenceSync = useSync;
3960 			config.serverSync	= serverSync;
3961 			config.define = 2;
3962 			config.modify = 0;
3963 			config.render = true;
3964 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_render", "Generate, set data, render and delete texture"));
3965 		}
3966 
3967 		{
3968 			GLES2ThreadedSharingTest::TestConfig config;
3969 
3970 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3971 			config.useFenceSync = useSync;
3972 			config.serverSync	= serverSync;
3973 			config.define = 2;
3974 			config.modify = 1;
3975 			config.render = true;
3976 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_texsubimage2d_render", "Generate, set data, update data, render and delete texture"));
3977 		}
3978 
3979 		{
3980 			GLES2ThreadedSharingTest::TestConfig config;
3981 
3982 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_TEXTURE;
3983 			config.useFenceSync = useSync;
3984 			config.serverSync	= serverSync;
3985 			config.define = 2;
3986 			config.modify = 2;
3987 			config.render = true;
3988 			textureTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_copytexsubimage2d_render", "Generate, set data, update data, render and delete texture"));
3989 		}
3990 
3991 		group->addChild(textureTests);
3992 	}
3993 
3994 	{
3995 		TestCaseGroup* shaderTests = new TestCaseGroup(ctx, "shaders", "Shader management tests");
3996 
3997 		{
3998 			GLES2ThreadedSharingTest::TestConfig config;
3999 
4000 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_VERTEX_SHADER;
4001 			config.useFenceSync = useSync;
4002 			config.serverSync	= serverSync;
4003 			config.define = 0;
4004 			config.modify = 0;
4005 			config.render = false;
4006 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "vtx_create_destroy", "Create and delete shader"));
4007 		}
4008 
4009 		{
4010 			GLES2ThreadedSharingTest::TestConfig config;
4011 
4012 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_VERTEX_SHADER;
4013 			config.useFenceSync = useSync;
4014 			config.serverSync	= serverSync;
4015 			config.define = 1;
4016 			config.modify = 0;
4017 			config.render = false;
4018 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "vtx_shadersource", "Create, set source and delete shader"));
4019 		}
4020 
4021 		{
4022 			GLES2ThreadedSharingTest::TestConfig config;
4023 
4024 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_VERTEX_SHADER;
4025 			config.useFenceSync = useSync;
4026 			config.serverSync	= serverSync;
4027 			config.define = 1;
4028 			config.modify = 1;
4029 			config.render = false;
4030 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "vtx_compile", "Create, set source, compile and delete shader"));
4031 		}
4032 
4033 		{
4034 			GLES2ThreadedSharingTest::TestConfig config;
4035 
4036 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_FRAGMENT_SHADER;
4037 			config.useFenceSync = useSync;
4038 			config.serverSync	= serverSync;
4039 			config.define = 0;
4040 			config.modify = 0;
4041 			config.render = false;
4042 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "frag_create_destroy", "Create and delete shader"));
4043 		}
4044 
4045 		{
4046 			GLES2ThreadedSharingTest::TestConfig config;
4047 
4048 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_FRAGMENT_SHADER;
4049 			config.useFenceSync = useSync;
4050 			config.serverSync	= serverSync;
4051 			config.define = 1;
4052 			config.modify = 0;
4053 			config.render = false;
4054 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "frag_shadersource", "Create, set source and delete shader"));
4055 		}
4056 
4057 		{
4058 			GLES2ThreadedSharingTest::TestConfig config;
4059 
4060 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_FRAGMENT_SHADER;
4061 			config.useFenceSync = useSync;
4062 			config.serverSync	= serverSync;
4063 			config.define = 1;
4064 			config.modify = 1;
4065 			config.render = false;
4066 			shaderTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "frag_compile", "Create, set source, compile and delete shader"));
4067 		}
4068 
4069 		group->addChild(shaderTests);
4070 	}
4071 
4072 	{
4073 		TestCaseGroup* programTests = new TestCaseGroup(ctx, "programs", "Program management tests");
4074 
4075 		{
4076 			GLES2ThreadedSharingTest::TestConfig config;
4077 
4078 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_PROGRAM;
4079 			config.useFenceSync = useSync;
4080 			config.serverSync	= serverSync;
4081 			config.define = 0;
4082 			config.modify = 0;
4083 			config.render = false;
4084 			programTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "create_destroy", "Create and delete program"));
4085 		}
4086 
4087 		{
4088 			GLES2ThreadedSharingTest::TestConfig config;
4089 
4090 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_PROGRAM;
4091 			config.useFenceSync = useSync;
4092 			config.serverSync	= serverSync;
4093 			config.define = 1;
4094 			config.modify = 0;
4095 			config.render = false;
4096 			programTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "attach", "Create, attach shaders and delete program"));
4097 		}
4098 
4099 		{
4100 			GLES2ThreadedSharingTest::TestConfig config;
4101 
4102 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_PROGRAM;
4103 			config.useFenceSync = useSync;
4104 			config.serverSync	= serverSync;
4105 			config.define = 1;
4106 			config.modify = 1;
4107 			config.render = false;
4108 			programTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "link", "Create, attach shaders, link and delete program"));
4109 		}
4110 
4111 		group->addChild(programTests);
4112 	}
4113 
4114 	{
4115 		TestCaseGroup* imageTests = new TestCaseGroup(ctx, "images", "Image management tests");
4116 
4117 		TestCaseGroup* textureSourceTests = new TestCaseGroup(ctx, "texture_source", "Image management tests with texture source.");
4118 		{
4119 			GLES2ThreadedSharingTest::TestConfig config;
4120 
4121 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
4122 			config.useFenceSync = useSync;
4123 			config.serverSync	= serverSync;
4124 			config.define = 1;
4125 			config.modify = 0;
4126 			config.render = false;
4127 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "create_destroy", "Create and destroy EGLImage."));
4128 		}
4129 
4130 		{
4131 			GLES2ThreadedSharingTest::TestConfig config;
4132 
4133 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
4134 			config.useFenceSync = useSync;
4135 			config.serverSync	= serverSync;
4136 			config.define = 2;
4137 			config.modify = 0;
4138 			config.render = false;
4139 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "create_texture", "Create texture from image."));
4140 		}
4141 
4142 		{
4143 			GLES2ThreadedSharingTest::TestConfig config;
4144 
4145 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
4146 			config.useFenceSync = useSync;
4147 			config.serverSync	= serverSync;
4148 			config.define = 2;
4149 			config.modify = 1;
4150 			config.render = false;
4151 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "texsubimage2d", "Modify texture created from image with glTexSubImage2D."));
4152 		}
4153 
4154 		{
4155 			GLES2ThreadedSharingTest::TestConfig config;
4156 
4157 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
4158 			config.useFenceSync = useSync;
4159 			config.serverSync	= serverSync;
4160 			config.define = 2;
4161 			config.modify = 2;
4162 			config.render = false;
4163 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copytexsubimage2d", "Modify texture created from image with glCopyTexSubImage2D."));
4164 		}
4165 
4166 		{
4167 			GLES2ThreadedSharingTest::TestConfig config;
4168 
4169 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
4170 			config.useFenceSync = useSync;
4171 			config.serverSync	= serverSync;
4172 			config.define = 2;
4173 			config.modify = 3;
4174 			config.render = false;
4175 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d", "Modify texture created from image with glTexImage2D."));
4176 		}
4177 
4178 		{
4179 			GLES2ThreadedSharingTest::TestConfig config;
4180 
4181 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
4182 			config.useFenceSync = useSync;
4183 			config.serverSync	= serverSync;
4184 			config.define = 2;
4185 			config.modify = 4;
4186 			config.render = false;
4187 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d", "Modify texture created from image with glCopyTexImage2D."));
4188 		}
4189 
4190 		{
4191 			GLES2ThreadedSharingTest::TestConfig config;
4192 
4193 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
4194 			config.useFenceSync = useSync;
4195 			config.serverSync	= serverSync;
4196 			config.define = 2;
4197 			config.modify = 0;
4198 			config.render = true;
4199 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "create_texture_render", "Create texture from image and render."));
4200 		}
4201 
4202 		{
4203 			GLES2ThreadedSharingTest::TestConfig config;
4204 
4205 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
4206 			config.useFenceSync = useSync;
4207 			config.serverSync	= serverSync;
4208 			config.define = 2;
4209 			config.modify = 1;
4210 			config.render = true;
4211 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "texsubimage2d_render", "Modify texture created from image and render."));
4212 		}
4213 
4214 		{
4215 			GLES2ThreadedSharingTest::TestConfig config;
4216 
4217 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
4218 			config.useFenceSync = useSync;
4219 			config.serverSync	= serverSync;
4220 			config.define = 2;
4221 			config.modify = 2;
4222 			config.render = true;
4223 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copytexsubimage2d_render", "Modify texture created from image and render."));
4224 		}
4225 
4226 		{
4227 			GLES2ThreadedSharingTest::TestConfig config;
4228 
4229 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
4230 			config.useFenceSync = useSync;
4231 			config.serverSync	= serverSync;
4232 			config.define = 2;
4233 			config.modify = 3;
4234 			config.render = true;
4235 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "teximage2d_render", "Modify texture created from image and render."));
4236 		}
4237 
4238 		{
4239 			GLES2ThreadedSharingTest::TestConfig config;
4240 
4241 			config.resourceType = GLES2ThreadedSharingTest::TestConfig::RESOURCETYPE_IMAGE;
4242 			config.useFenceSync = useSync;
4243 			config.serverSync	= serverSync;
4244 			config.define = 2;
4245 			config.modify = 4;
4246 			config.render = true;
4247 			textureSourceTests->addChild(new GLES2ThreadedSharingTest(ctx, config, "copyteximage2d_render", "Modify texture created from image and render."));
4248 		}
4249 
4250 		imageTests->addChild(textureSourceTests);
4251 
4252 		group->addChild(imageTests);
4253 	}
4254 
4255 }
4256 
addRandomTests(EglTestContext & ctx,tcu::TestCaseGroup * group,bool useSync,bool serverSync)4257 static void addRandomTests (EglTestContext& ctx, tcu::TestCaseGroup* group, bool useSync, bool serverSync)
4258 {
4259 	{
4260 		TestCaseGroup* textureTests = new TestCaseGroup(ctx, "textures", "Texture management tests");
4261 
4262 		{
4263 			TestCaseGroup* genTextureTests = new TestCaseGroup(ctx, "gen_delete", "Texture gen and delete tests");
4264 
4265 			for (int textureTestNdx = 0; textureTestNdx < 20; textureTestNdx++)
4266 			{
4267 				GLES2SharingRandomTest::TestConfig config;
4268 				config.useFenceSync		= useSync;
4269 				config.serverSync		= serverSync;
4270 				config.threadCount		= 2 + textureTestNdx % 5;
4271 				config.operationCount	= 30 + textureTestNdx;
4272 
4273 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]				= 1.0f;
4274 
4275 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.25f;
4276 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.75f;
4277 
4278 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.5f;
4279 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.5f;
4280 
4281 				std::string	name = de::toString(textureTestNdx);
4282 				genTextureTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4283 			}
4284 
4285 			textureTests->addChild(genTextureTests);
4286 		}
4287 
4288 		{
4289 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "teximage2d", "Texture gen, delete and teximage2D tests");
4290 
4291 			for (int textureTestNdx = 0; textureTestNdx < 20; textureTestNdx++)
4292 			{
4293 				GLES2SharingRandomTest::TestConfig config;
4294 				config.useFenceSync		= useSync;
4295 				config.serverSync		= serverSync;
4296 				config.threadCount		= 2 + textureTestNdx % 5;
4297 				config.operationCount	= 40 + textureTestNdx;
4298 
4299 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]				= 1.0f;
4300 
4301 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.10f;
4302 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.10f;
4303 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]		= 0.80f;
4304 
4305 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.30f;
4306 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.40f;
4307 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]		= 0.30f;
4308 
4309 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]		= 0.40f;
4310 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]		= 0.40f;
4311 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]			= 0.20f;
4312 
4313 				std::string	name = de::toString(textureTestNdx);
4314 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4315 			}
4316 
4317 			textureTests->addChild(texImage2DTests);
4318 		}
4319 
4320 		{
4321 			TestCaseGroup* texSubImage2DTests = new TestCaseGroup(ctx, "texsubimage2d", "Texture gen, delete, teximage2D and texsubimage2d tests");
4322 
4323 			for (int textureTestNdx = 0; textureTestNdx < 20; textureTestNdx++)
4324 			{
4325 				GLES2SharingRandomTest::TestConfig config;
4326 				config.useFenceSync		= useSync;
4327 				config.serverSync		= serverSync;
4328 				config.threadCount		= 2 + textureTestNdx % 5;
4329 				config.operationCount	= 50 + textureTestNdx;
4330 
4331 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]				= 1.0f;
4332 
4333 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.05f;
4334 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.10f;
4335 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]		= 0.80f;
4336 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXSUBIMAGE2D]		= 0.05f;
4337 
4338 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.30f;
4339 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.40f;
4340 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]		= 0.20f;
4341 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXSUBIMAGE2D]	= 0.10f;
4342 
4343 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]		= 0.20f;
4344 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]		= 0.20f;
4345 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]			= 0.10f;
4346 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXSUBIMAGE2D]			= 0.50f;
4347 
4348 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.20f;
4349 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]		= 0.25f;
4350 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]			= 0.25f;
4351 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_TEXSUBIMAGE2D]		= 0.30f;
4352 
4353 				std::string	name = de::toString(textureTestNdx);
4354 				texSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4355 			}
4356 
4357 			textureTests->addChild(texSubImage2DTests);
4358 		}
4359 
4360 		{
4361 			TestCaseGroup* copyTexImage2DTests = new TestCaseGroup(ctx, "copyteximage2d", "Texture gen, delete and copyteximage2d tests");
4362 
4363 			for (int textureTestNdx = 0; textureTestNdx < 20; textureTestNdx++)
4364 			{
4365 				GLES2SharingRandomTest::TestConfig config;
4366 				config.useFenceSync		= useSync;
4367 				config.serverSync		= serverSync;
4368 				config.threadCount		= 2 + textureTestNdx % 5;
4369 				config.operationCount	= 40 + textureTestNdx;
4370 
4371 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]				= 1.0f;
4372 
4373 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.10f;
4374 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.10f;
4375 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_COPYTEXIMAGE2D]	= 0.80f;
4376 
4377 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.30f;
4378 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]	= 0.40f;
4379 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_COPYTEXIMAGE2D]	= 0.30f;
4380 
4381 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.40f;
4382 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]	= 0.40f;
4383 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_COPYTEXIMAGE2D]	= 0.20f;
4384 
4385 
4386 				std::string	name = de::toString(textureTestNdx);
4387 				copyTexImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4388 			}
4389 
4390 			textureTests->addChild(copyTexImage2DTests);
4391 		}
4392 
4393 		{
4394 			TestCaseGroup* copyTexSubImage2DTests = new TestCaseGroup(ctx, "copytexsubimage2d", "Texture gen, delete, teximage2D and copytexsubimage2d tests");
4395 
4396 			for (int textureTestNdx = 0; textureTestNdx < 20; textureTestNdx++)
4397 			{
4398 				GLES2SharingRandomTest::TestConfig config;
4399 				config.useFenceSync		= useSync;
4400 				config.serverSync		= serverSync;
4401 				config.threadCount		= 2 + textureTestNdx % 5;
4402 				config.operationCount	= 50 + textureTestNdx;
4403 
4404 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]					= 1.0f;
4405 
4406 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]		= 0.05f;
4407 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]		= 0.10f;
4408 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]			= 0.80f;
4409 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]		= 0.05f;
4410 
4411 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]		= 0.30f;
4412 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]		= 0.40f;
4413 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]			= 0.20f;
4414 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]	= 0.10f;
4415 
4416 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.20f;
4417 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]			= 0.20f;
4418 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]				= 0.10f;
4419 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_COPYTEXSUBIMAGE2D]			= 0.50f;
4420 
4421 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]	= 0.20f;
4422 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]		= 0.25f;
4423 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]			= 0.25f;
4424 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_COPYTEXSUBIMAGE2D]	= 0.30f;
4425 
4426 
4427 				std::string	name = de::toString(textureTestNdx);
4428 				copyTexSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4429 			}
4430 
4431 			textureTests->addChild(copyTexSubImage2DTests);
4432 		}
4433 
4434 		group->addChild(textureTests);
4435 
4436 		TestCaseGroup* bufferTests = new TestCaseGroup(ctx, "buffers", "Buffer management tests");
4437 
4438 		{
4439 			TestCaseGroup* genBufferTests = new TestCaseGroup(ctx, "gen_delete", "Buffer gen and delete tests");
4440 
4441 			for (int bufferTestNdx = 0; bufferTestNdx < 20; bufferTestNdx++)
4442 			{
4443 				GLES2SharingRandomTest::TestConfig config;
4444 				config.useFenceSync		= useSync;
4445 				config.serverSync		= serverSync;
4446 				config.threadCount		= 2 + bufferTestNdx % 5;
4447 				config.operationCount	= 30 + bufferTestNdx;
4448 
4449 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_BUFFER]				= 1.0f;
4450 
4451 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]		= 0.25f;
4452 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.75f;
4453 
4454 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]	= 0.5f;
4455 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.5f;
4456 
4457 				std::string	name = de::toString(bufferTestNdx);
4458 				genBufferTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4459 			}
4460 
4461 			bufferTests->addChild(genBufferTests);
4462 		}
4463 
4464 		{
4465 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "bufferdata", "Buffer gen, delete and bufferdata tests");
4466 
4467 			for (int bufferTestNdx = 0; bufferTestNdx < 20; bufferTestNdx++)
4468 			{
4469 				GLES2SharingRandomTest::TestConfig config;
4470 				config.useFenceSync		= useSync;
4471 				config.serverSync		= serverSync;
4472 				config.threadCount		= 2 + bufferTestNdx % 5;
4473 				config.operationCount	= 40 + bufferTestNdx;
4474 
4475 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_BUFFER]				= 1.0f;
4476 
4477 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]		= 0.10f;
4478 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.10f;
4479 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_BUFFER_DATA]		= 0.80f;
4480 
4481 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]	= 0.30f;
4482 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.40f;
4483 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_BUFFER_DATA]		= 0.30f;
4484 
4485 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_DESTROY_BUFFER]		= 0.40f;
4486 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_CREATE_BUFFER]		= 0.40f;
4487 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_BUFFER_DATA]			= 0.20f;
4488 
4489 				std::string	name = de::toString(bufferTestNdx);
4490 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4491 			}
4492 
4493 			bufferTests->addChild(texImage2DTests);
4494 		}
4495 
4496 		{
4497 			TestCaseGroup* texSubImage2DTests = new TestCaseGroup(ctx, "buffersubdata", "Buffer gen, delete, bufferdata and bufferdata tests");
4498 
4499 			for (int bufferTestNdx = 0; bufferTestNdx < 20; bufferTestNdx++)
4500 			{
4501 				GLES2SharingRandomTest::TestConfig config;
4502 				config.useFenceSync		= useSync;
4503 				config.serverSync		= serverSync;
4504 				config.threadCount		= 2 + bufferTestNdx % 5;
4505 				config.operationCount	= 50 + bufferTestNdx;
4506 
4507 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_BUFFER]				= 1.0f;
4508 
4509 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]		= 0.05f;
4510 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.10f;
4511 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_BUFFER_DATA]		= 0.80f;
4512 				config.probabilities[THREADOPERATIONID_CREATE_BUFFER][THREADOPERATIONID_BUFFER_SUBDATA]		= 0.05f;
4513 
4514 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_DESTROY_BUFFER]	= 0.30f;
4515 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_CREATE_BUFFER]		= 0.40f;
4516 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_BUFFER_DATA]		= 0.20f;
4517 				config.probabilities[THREADOPERATIONID_DESTROY_BUFFER][THREADOPERATIONID_BUFFER_SUBDATA]	= 0.10f;
4518 
4519 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_DESTROY_BUFFER]		= 0.20f;
4520 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_CREATE_BUFFER]		= 0.20f;
4521 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_BUFFER_DATA]			= 0.10f;
4522 				config.probabilities[THREADOPERATIONID_BUFFER_DATA][THREADOPERATIONID_BUFFER_SUBDATA]		= 0.50f;
4523 
4524 				config.probabilities[THREADOPERATIONID_BUFFER_SUBDATA][THREADOPERATIONID_DESTROY_BUFFER]	= 0.20f;
4525 				config.probabilities[THREADOPERATIONID_BUFFER_SUBDATA][THREADOPERATIONID_CREATE_BUFFER]		= 0.25f;
4526 				config.probabilities[THREADOPERATIONID_BUFFER_SUBDATA][THREADOPERATIONID_BUFFER_DATA]		= 0.25f;
4527 				config.probabilities[THREADOPERATIONID_BUFFER_SUBDATA][THREADOPERATIONID_BUFFER_SUBDATA]	= 0.30f;
4528 
4529 				std::string	name = de::toString(bufferTestNdx);
4530 				texSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4531 			}
4532 
4533 			bufferTests->addChild(texSubImage2DTests);
4534 		}
4535 
4536 		group->addChild(bufferTests);
4537 
4538 		TestCaseGroup* shaderTests = new TestCaseGroup(ctx, "shaders", "Shader management tests");
4539 
4540 		{
4541 			TestCaseGroup* createShaderTests = new TestCaseGroup(ctx, "create_destroy", "Shader create and destroy tests");
4542 
4543 			for (int shaderTestNdx = 0; shaderTestNdx < 20; shaderTestNdx++)
4544 			{
4545 				GLES2SharingRandomTest::TestConfig config;
4546 				config.useFenceSync		= useSync;
4547 				config.serverSync		= serverSync;
4548 				config.threadCount		= 2 + shaderTestNdx % 5;
4549 				config.operationCount	= 30 + shaderTestNdx;
4550 
4551 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_VERTEX_SHADER]						= 0.5f;
4552 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]						= 0.5f;
4553 
4554 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_SHADER]				= 0.20f;
4555 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.40f;
4556 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]		= 0.40f;
4557 
4558 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_SHADER]			= 0.20f;
4559 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.40f;
4560 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]	= 0.40f;
4561 
4562 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_SHADER]					= 0.5f;
4563 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.25f;
4564 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.25f;
4565 
4566 				std::string	name = de::toString(shaderTestNdx);
4567 				createShaderTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4568 			}
4569 
4570 			shaderTests->addChild(createShaderTests);
4571 		}
4572 
4573 		{
4574 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "source", "Shader create, destroy and source tests");
4575 
4576 			for (int shaderTestNdx = 0; shaderTestNdx < 20; shaderTestNdx++)
4577 			{
4578 				GLES2SharingRandomTest::TestConfig config;
4579 				config.useFenceSync		= useSync;
4580 				config.serverSync		= serverSync;
4581 				config.threadCount		= 2 + shaderTestNdx % 5;
4582 				config.operationCount	= 40 + shaderTestNdx;
4583 
4584 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_VERTEX_SHADER]						= 0.5f;
4585 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]						= 0.5f;
4586 
4587 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_SHADER]				= 0.10f;
4588 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.20f;
4589 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]		= 0.20f;
4590 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.50f;
4591 
4592 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_SHADER]			= 0.10f;
4593 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.20f;
4594 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]	= 0.20f;
4595 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.50f;
4596 
4597 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_SHADER]					= 0.30f;
4598 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.30f;
4599 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.30f;
4600 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
4601 
4602 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_SHADER]						= 0.20f;
4603 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
4604 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.20f;
4605 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_SOURCE]						= 0.40f;
4606 
4607 				std::string	name = de::toString(shaderTestNdx);
4608 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4609 			}
4610 
4611 			shaderTests->addChild(texImage2DTests);
4612 		}
4613 
4614 		{
4615 			TestCaseGroup* texSubImage2DTests = new TestCaseGroup(ctx, "compile", "Shader create, destroy, source and compile tests");
4616 
4617 			for (int shaderTestNdx = 0; shaderTestNdx < 20; shaderTestNdx++)
4618 			{
4619 				GLES2SharingRandomTest::TestConfig config;
4620 				config.useFenceSync		= useSync;
4621 				config.serverSync		= serverSync;
4622 				config.threadCount		= 2 + shaderTestNdx % 5;
4623 				config.operationCount	= 50 + shaderTestNdx;
4624 
4625 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_VERTEX_SHADER]						= 0.5f;
4626 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]						= 0.5f;
4627 
4628 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_SHADER]				= 0.10f;
4629 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.15f;
4630 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]		= 0.15f;
4631 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.50f;
4632 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_COMPILE]				= 0.10f;
4633 
4634 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_SHADER]			= 0.10f;
4635 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.15f;
4636 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]	= 0.15f;
4637 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.50f;
4638 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_COMPILE]			= 0.10f;
4639 
4640 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_SHADER]					= 0.30f;
4641 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.25f;
4642 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.25f;
4643 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
4644 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_COMPILE]					= 0.10f;
4645 
4646 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_SHADER]						= 0.10f;
4647 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.10f;
4648 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.10f;
4649 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_SOURCE]						= 0.20f;
4650 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_COMPILE]						= 0.50f;
4651 
4652 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_DESTROY_SHADER]					= 0.15f;
4653 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.15f;
4654 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.15f;
4655 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_SOURCE]						= 0.30f;
4656 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_COMPILE]					= 0.30f;
4657 
4658 				std::string	name = de::toString(shaderTestNdx);
4659 				texSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4660 			}
4661 
4662 			shaderTests->addChild(texSubImage2DTests);
4663 		}
4664 
4665 		group->addChild(shaderTests);
4666 
4667 		TestCaseGroup* programTests = new TestCaseGroup(ctx, "programs", "Program management tests");
4668 
4669 		{
4670 			TestCaseGroup* createProgramTests = new TestCaseGroup(ctx, "create_destroy", "Program create and destroy tests");
4671 
4672 			for (int programTestNdx = 0; programTestNdx < 20; programTestNdx++)
4673 			{
4674 				GLES2SharingRandomTest::TestConfig config;
4675 				config.useFenceSync		= useSync;
4676 				config.serverSync		= serverSync;
4677 				config.threadCount		= 2 + programTestNdx % 5;
4678 				config.operationCount	= 30 + programTestNdx;
4679 
4680 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_PROGRAM]				= 1.0f;
4681 
4682 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]	= 0.25f;
4683 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]	= 0.75f;
4684 
4685 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]	= 0.5f;
4686 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]	= 0.5f;
4687 
4688 				std::string	name = de::toString(programTestNdx);
4689 				createProgramTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4690 			}
4691 
4692 			programTests->addChild(createProgramTests);
4693 		}
4694 
4695 		{
4696 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "attach_detach", "Program create, destroy, attach and detach tests");
4697 
4698 			for (int programTestNdx = 0; programTestNdx < 20; programTestNdx++)
4699 			{
4700 				GLES2SharingRandomTest::TestConfig config;
4701 				config.useFenceSync		= useSync;
4702 				config.serverSync		= serverSync;
4703 				config.threadCount		= 2 + programTestNdx % 5;
4704 				config.operationCount	= 60 + programTestNdx;
4705 
4706 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_VERTEX_SHADER]						= 0.35f;
4707 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]						= 0.35f;
4708 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_PROGRAM]								= 0.30f;
4709 
4710 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_SHADER]				= 0.10f;
4711 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.10f;
4712 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]		= 0.10f;
4713 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.30f;
4714 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_COMPILE]				= 0.10f;
4715 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_PROGRAM]				= 0.10f;
4716 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]				= 0.05f;
4717 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_ATTACH_SHADER]				= 0.15f;
4718 
4719 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_SHADER]			= 0.10f;
4720 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.10f;
4721 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]	= 0.10f;
4722 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.30f;
4723 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_COMPILE]			= 0.10f;
4724 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_PROGRAM]			= 0.10f;
4725 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]			= 0.05f;
4726 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_ATTACH_SHADER]				= 0.15f;
4727 
4728 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_SHADER]					= 0.20f;
4729 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
4730 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
4731 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
4732 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_COMPILE]					= 0.10f;
4733 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_PROGRAM]					= 0.15f;
4734 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
4735 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_ATTACH_SHADER]						= 0.15f;
4736 
4737 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_SHADER]						= 0.10f;
4738 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.10f;
4739 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.10f;
4740 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_SOURCE]						= 0.20f;
4741 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_COMPILE]						= 0.50f;
4742 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_PROGRAM]						= 0.10f;
4743 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.10f;
4744 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_ATTACH_SHADER]						= 0.25f;
4745 
4746 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_DESTROY_SHADER]					= 0.15f;
4747 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.15f;
4748 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.15f;
4749 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_SOURCE]						= 0.30f;
4750 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_COMPILE]					= 0.30f;
4751 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_PROGRAM]					= 0.10f;
4752 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.10f;
4753 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_ATTACH_SHADER]						= 0.35f;
4754 
4755 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_DESTROY_SHADER]					= 0.10f;
4756 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
4757 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
4758 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_SHADER_SOURCE]						= 0.05f;
4759 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_SHADER_COMPILE]					= 0.05f;
4760 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]					= 0.15f;
4761 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.05f;
4762 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_ATTACH_SHADER]						= 0.40f;
4763 
4764 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_DESTROY_SHADER]					= 0.20f;
4765 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
4766 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
4767 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_SHADER_SOURCE]					= 0.10f;
4768 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_SHADER_COMPILE]					= 0.10f;
4769 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]					= 0.20f;
4770 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
4771 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_ATTACH_SHADER]					= 0.10f;
4772 
4773 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_DESTROY_SHADER]						= 0.20f;
4774 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
4775 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.20f;
4776 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
4777 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_SHADER_COMPILE]						= 0.10f;
4778 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_PROGRAM]						= 0.15f;
4779 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
4780 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_ATTACH_SHADER]						= 0.30f;
4781 
4782 				std::string	name = de::toString(programTestNdx);
4783 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4784 			}
4785 
4786 			programTests->addChild(texImage2DTests);
4787 		}
4788 
4789 		{
4790 			TestCaseGroup* texSubImage2DTests = new TestCaseGroup(ctx, "link", "Program create, destroy, attach and link tests");
4791 
4792 			for (int programTestNdx = 0; programTestNdx < 20; programTestNdx++)
4793 			{
4794 				GLES2SharingRandomTest::TestConfig config;
4795 				config.useFenceSync		= useSync;
4796 				config.serverSync		= serverSync;
4797 				config.threadCount		= 2 + programTestNdx % 5;
4798 				config.operationCount	= 70 + programTestNdx;
4799 
4800 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_VERTEX_SHADER]						= 0.35f;
4801 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]						= 0.35f;
4802 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_PROGRAM]								= 0.30f;
4803 
4804 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_SHADER]				= 0.10f;
4805 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.10f;
4806 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]		= 0.10f;
4807 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.30f;
4808 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_SHADER_COMPILE]				= 0.10f;
4809 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_CREATE_PROGRAM]				= 0.10f;
4810 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]				= 0.05f;
4811 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_ATTACH_SHADER]				= 0.15f;
4812 				config.probabilities[THREADOPERATIONID_CREATE_VERTEX_SHADER][THREADOPERATIONID_LINK_PROGRAM]				= 0.10f;
4813 
4814 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_SHADER]			= 0.10f;
4815 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]		= 0.10f;
4816 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]	= 0.10f;
4817 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_SOURCE]				= 0.30f;
4818 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_SHADER_COMPILE]			= 0.10f;
4819 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_CREATE_PROGRAM]			= 0.10f;
4820 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]			= 0.05f;
4821 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_ATTACH_SHADER]				= 0.15f;
4822 				config.probabilities[THREADOPERATIONID_CREATE_FRAGMENT_SHADER][THREADOPERATIONID_LINK_PROGRAM]				= 0.10f;
4823 
4824 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_SHADER]					= 0.20f;
4825 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
4826 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
4827 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
4828 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_SHADER_COMPILE]					= 0.10f;
4829 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_CREATE_PROGRAM]					= 0.15f;
4830 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
4831 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_ATTACH_SHADER]						= 0.15f;
4832 				config.probabilities[THREADOPERATIONID_DESTROY_SHADER][THREADOPERATIONID_LINK_PROGRAM]						= 0.10f;
4833 
4834 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_SHADER]						= 0.10f;
4835 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.10f;
4836 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.10f;
4837 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_SOURCE]						= 0.20f;
4838 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_SHADER_COMPILE]						= 0.50f;
4839 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_CREATE_PROGRAM]						= 0.10f;
4840 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.10f;
4841 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_ATTACH_SHADER]						= 0.25f;
4842 				config.probabilities[THREADOPERATIONID_SHADER_SOURCE][THREADOPERATIONID_LINK_PROGRAM]						= 0.20f;
4843 
4844 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_DESTROY_SHADER]					= 0.15f;
4845 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.15f;
4846 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.15f;
4847 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_SOURCE]						= 0.30f;
4848 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_SHADER_COMPILE]					= 0.30f;
4849 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_CREATE_PROGRAM]					= 0.10f;
4850 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.10f;
4851 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_ATTACH_SHADER]						= 0.35f;
4852 				config.probabilities[THREADOPERATIONID_SHADER_COMPILE][THREADOPERATIONID_LINK_PROGRAM]						= 0.20f;
4853 
4854 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_DESTROY_SHADER]					= 0.10f;
4855 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
4856 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
4857 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_SHADER_SOURCE]						= 0.05f;
4858 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_SHADER_COMPILE]					= 0.05f;
4859 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]					= 0.15f;
4860 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.05f;
4861 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_ATTACH_SHADER]						= 0.40f;
4862 				config.probabilities[THREADOPERATIONID_CREATE_PROGRAM][THREADOPERATIONID_LINK_PROGRAM]						= 0.05f;
4863 
4864 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_DESTROY_SHADER]					= 0.20f;
4865 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
4866 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]			= 0.20f;
4867 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_SHADER_SOURCE]					= 0.10f;
4868 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_SHADER_COMPILE]					= 0.10f;
4869 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]					= 0.20f;
4870 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
4871 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_ATTACH_SHADER]					= 0.10f;
4872 				config.probabilities[THREADOPERATIONID_DESTROY_PROGRAM][THREADOPERATIONID_LINK_PROGRAM]						= 0.05f;
4873 
4874 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_DESTROY_SHADER]						= 0.20f;
4875 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
4876 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.20f;
4877 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
4878 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_SHADER_COMPILE]						= 0.10f;
4879 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_CREATE_PROGRAM]						= 0.15f;
4880 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_DESTROY_PROGRAM]					= 0.15f;
4881 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_ATTACH_SHADER]						= 0.30f;
4882 				config.probabilities[THREADOPERATIONID_ATTACH_SHADER][THREADOPERATIONID_LINK_PROGRAM]						= 0.30f;
4883 
4884 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_DESTROY_SHADER]						= 0.20f;
4885 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_CREATE_VERTEX_SHADER]				= 0.20f;
4886 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_CREATE_FRAGMENT_SHADER]				= 0.20f;
4887 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_SHADER_SOURCE]						= 0.10f;
4888 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_SHADER_COMPILE]						= 0.10f;
4889 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_CREATE_PROGRAM]						= 0.20f;
4890 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_DESTROY_PROGRAM]						= 0.15f;
4891 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_ATTACH_SHADER]						= 0.10f;
4892 				config.probabilities[THREADOPERATIONID_LINK_PROGRAM][THREADOPERATIONID_LINK_PROGRAM]						= 0.05f;
4893 
4894 				std::string	name = de::toString(programTestNdx);
4895 				texSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4896 			}
4897 
4898 			programTests->addChild(texSubImage2DTests);
4899 		}
4900 
4901 		group->addChild(programTests);
4902 
4903 		TestCaseGroup* imageTests = new TestCaseGroup(ctx, "images", "Image management tests");
4904 
4905 		{
4906 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "create_destroy", "Image gen, delete and teximage2D tests");
4907 
4908 			for (int imageTestNdx = 0; imageTestNdx < 20; imageTestNdx++)
4909 			{
4910 				GLES2SharingRandomTest::TestConfig config;
4911 				config.useFenceSync		= useSync;
4912 				config.serverSync		= serverSync;
4913 				config.threadCount		= 2 + imageTestNdx % 5;
4914 				config.operationCount	= 70 + imageTestNdx;
4915 				config.useImages		= true;
4916 
4917 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]									= 1.0f;
4918 
4919 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.10f;
4920 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.15f;
4921 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.40f;
4922 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.35f;
4923 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.30f;
4924 
4925 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.15f;
4926 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.20f;
4927 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.40f;
4928 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.35f;
4929 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.15f;
4930 
4931 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.25f;
4932 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]				= 0.25f;
4933 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]	= 0.40f;
4934 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]				= 0.35f;
4935 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]					= 0.15f;
4936 
4937 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
4938 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
4939 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.40f;
4940 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.35f;
4941 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
4942 
4943 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]							= 0.25f;
4944 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
4945 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]					= 0.40f;
4946 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]								= 0.35f;
4947 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
4948 
4949 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
4950 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]					= 0.25f;
4951 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.30f;
4952 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.15f;
4953 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXIMAGE2D]						= 0.15f;
4954 
4955 				std::string	name = de::toString(imageTestNdx);
4956 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
4957 			}
4958 
4959 			imageTests->addChild(texImage2DTests);
4960 		}
4961 
4962 		{
4963 			TestCaseGroup* texImage2DTests = new TestCaseGroup(ctx, "teximage2d", "Image gen, delete and teximage2D tests");
4964 
4965 			for (int imageTestNdx = 0; imageTestNdx < 20; imageTestNdx++)
4966 			{
4967 				GLES2SharingRandomTest::TestConfig config;
4968 				config.useFenceSync		= useSync;
4969 				config.serverSync		= serverSync;
4970 				config.threadCount		= 2 + imageTestNdx % 5;
4971 				config.operationCount	= 70 + imageTestNdx;
4972 				config.useImages		= true;
4973 
4974 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]									= 1.0f;
4975 
4976 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.10f;
4977 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.15f;
4978 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.20f;
4979 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.15f;
4980 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.30f;
4981 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.20f;
4982 
4983 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.15f;
4984 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.20f;
4985 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.15f;
4986 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.15f;
4987 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.15f;
4988 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
4989 
4990 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.25f;
4991 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]				= 0.25f;
4992 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]	= 0.25f;
4993 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]				= 0.25f;
4994 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]					= 0.15f;
4995 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]			= 0.15f;
4996 
4997 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
4998 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
4999 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
5000 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
5001 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
5002 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
5003 
5004 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]							= 0.25f;
5005 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
5006 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]					= 0.25f;
5007 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]								= 0.25f;
5008 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
5009 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
5010 
5011 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
5012 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]					= 0.25f;
5013 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.25f;
5014 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.25f;
5015 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXIMAGE2D]						= 0.15f;
5016 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]				= 0.15f;
5017 
5018 				std::string	name = de::toString(imageTestNdx);
5019 				texImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
5020 			}
5021 
5022 			imageTests->addChild(texImage2DTests);
5023 		}
5024 
5025 		{
5026 			TestCaseGroup* texSubImage2DTests = new TestCaseGroup(ctx, "texsubimage2d", "Image gen, delete, teximage2D and texsubimage2d tests");
5027 
5028 			for (int imageTestNdx = 0; imageTestNdx < 20; imageTestNdx++)
5029 			{
5030 				GLES2SharingRandomTest::TestConfig config;
5031 				config.useFenceSync		= useSync;
5032 				config.serverSync		= serverSync;
5033 				config.threadCount		= 2 + imageTestNdx % 5;
5034 				config.operationCount	= 70 + imageTestNdx;
5035 				config.useImages		= true;
5036 
5037 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]									= 1.0f;
5038 
5039 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.10f;
5040 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.15f;
5041 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.20f;
5042 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.15f;
5043 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.30f;
5044 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.20f;
5045 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXSUBIMAGE2D]							= 0.10f;
5046 
5047 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.15f;
5048 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.20f;
5049 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.15f;
5050 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.15f;
5051 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.15f;
5052 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
5053 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXSUBIMAGE2D]						= 0.10f;
5054 
5055 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.25f;
5056 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]				= 0.25f;
5057 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]	= 0.25f;
5058 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]				= 0.25f;
5059 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]					= 0.15f;
5060 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]			= 0.15f;
5061 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXSUBIMAGE2D]				= 0.10f;
5062 
5063 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
5064 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
5065 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
5066 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
5067 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
5068 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
5069 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXSUBIMAGE2D]							= 0.10f;
5070 
5071 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]							= 0.25f;
5072 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
5073 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]					= 0.25f;
5074 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]								= 0.25f;
5075 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
5076 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
5077 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXSUBIMAGE2D]								= 0.10f;
5078 
5079 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
5080 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]					= 0.25f;
5081 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.25f;
5082 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.25f;
5083 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXIMAGE2D]						= 0.15f;
5084 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]				= 0.15f;
5085 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXSUBIMAGE2D]						= 0.10f;
5086 
5087 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
5088 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
5089 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
5090 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
5091 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
5092 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
5093 				config.probabilities[THREADOPERATIONID_TEXSUBIMAGE2D][THREADOPERATIONID_TEXSUBIMAGE2D]							= 0.10f;
5094 
5095 				std::string	name = de::toString(imageTestNdx);
5096 				texSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
5097 			}
5098 
5099 			imageTests->addChild(texSubImage2DTests);
5100 		}
5101 
5102 		{
5103 			TestCaseGroup* copyTexImage2DTests = new TestCaseGroup(ctx, "copyteximage2d", "Image gen, delete and copyteximage2d tests");
5104 
5105 			for (int imageTestNdx = 0; imageTestNdx < 20; imageTestNdx++)
5106 			{
5107 				GLES2SharingRandomTest::TestConfig config;
5108 				config.useFenceSync		= useSync;
5109 				config.serverSync		= serverSync;
5110 				config.threadCount		= 2 + imageTestNdx % 5;
5111 				config.operationCount	= 70 + imageTestNdx;
5112 				config.useImages		= true;
5113 
5114 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]									= 1.0f;
5115 
5116 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.10f;
5117 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.15f;
5118 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.20f;
5119 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.15f;
5120 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_COPYTEXIMAGE2D]						= 0.30f;
5121 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.20f;
5122 
5123 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.15f;
5124 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.20f;
5125 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.15f;
5126 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.15f;
5127 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_COPYTEXIMAGE2D]						= 0.15f;
5128 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
5129 
5130 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.25f;
5131 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]				= 0.25f;
5132 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]	= 0.25f;
5133 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]				= 0.25f;
5134 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_COPYTEXIMAGE2D]				= 0.15f;
5135 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]			= 0.15f;
5136 
5137 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
5138 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
5139 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
5140 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
5141 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_COPYTEXIMAGE2D]							= 0.15f;
5142 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
5143 
5144 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
5145 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]						= 0.25f;
5146 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
5147 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
5148 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_COPYTEXIMAGE2D]						= 0.15f;
5149 				config.probabilities[THREADOPERATIONID_COPYTEXIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
5150 
5151 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
5152 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]					= 0.25f;
5153 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.25f;
5154 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.25f;
5155 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_COPYTEXIMAGE2D]					= 0.15f;
5156 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]				= 0.15f;
5157 
5158 				std::string	name = de::toString(imageTestNdx);
5159 				copyTexImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
5160 			}
5161 
5162 			imageTests->addChild(copyTexImage2DTests);
5163 		}
5164 
5165 		{
5166 			TestCaseGroup* copyTexSubImage2DTests = new TestCaseGroup(ctx, "copytexsubimage2d", "Image gen, delete, teximage2D and copytexsubimage2d tests");
5167 
5168 			for (int imageTestNdx = 0; imageTestNdx < 20; imageTestNdx++)
5169 			{
5170 				GLES2SharingRandomTest::TestConfig config;
5171 				config.useFenceSync		= useSync;
5172 				config.serverSync		= serverSync;
5173 				config.threadCount		= 2 + imageTestNdx % 5;
5174 				config.operationCount	= 70 + imageTestNdx;
5175 				config.useImages		= true;
5176 
5177 				config.probabilities[THREADOPERATIONID_NONE][THREADOPERATIONID_CREATE_TEXTURE]									= 1.0f;
5178 
5179 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.10f;
5180 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.15f;
5181 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.20f;
5182 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.15f;
5183 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.30f;
5184 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.20f;
5185 				config.probabilities[THREADOPERATIONID_CREATE_TEXTURE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]						= 0.10f;
5186 
5187 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.15f;
5188 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]						= 0.20f;
5189 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.15f;
5190 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.15f;
5191 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]							= 0.15f;
5192 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
5193 				config.probabilities[THREADOPERATIONID_DESTROY_TEXTURE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]					= 0.10f;
5194 
5195 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_TEXTURE]			= 0.25f;
5196 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_TEXTURE]				= 0.25f;
5197 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]	= 0.25f;
5198 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_DESTROY_IMAGE]				= 0.25f;
5199 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXIMAGE2D]					= 0.15f;
5200 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]			= 0.15f;
5201 				config.probabilities[THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]			= 0.10f;
5202 
5203 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]						= 0.25f;
5204 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
5205 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]				= 0.25f;
5206 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]							= 0.25f;
5207 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
5208 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
5209 				config.probabilities[THREADOPERATIONID_DESTROY_IMAGE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]						= 0.10f;
5210 
5211 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]							= 0.25f;
5212 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]							= 0.25f;
5213 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]					= 0.25f;
5214 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]								= 0.25f;
5215 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]								= 0.15f;
5216 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]						= 0.15f;
5217 				config.probabilities[THREADOPERATIONID_TEXIMAGE2D][THREADOPERATIONID_COPYTEXSUBIMAGE2D]							= 0.10f;
5218 
5219 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
5220 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_TEXTURE]					= 0.25f;
5221 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.25f;
5222 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_DESTROY_IMAGE]						= 0.25f;
5223 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXIMAGE2D]						= 0.15f;
5224 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_TEXTURE_FROM_IMAGE]				= 0.15f;
5225 				config.probabilities[THREADOPERATIONID_TEXTURE_FROM_IMAGE][THREADOPERATIONID_COPYTEXSUBIMAGE2D]					= 0.10f;
5226 
5227 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_TEXTURE]					= 0.25f;
5228 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_CREATE_TEXTURE]						= 0.25f;
5229 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_CREATE_IMAGE_FROM_TEXTURE]			= 0.25f;
5230 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_DESTROY_IMAGE]						= 0.25f;
5231 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_TEXIMAGE2D]							= 0.15f;
5232 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_TEXTURE_FROM_IMAGE]					= 0.15f;
5233 				config.probabilities[THREADOPERATIONID_COPYTEXSUBIMAGE2D][THREADOPERATIONID_COPYTEXSUBIMAGE2D]					= 0.10f;
5234 
5235 
5236 				std::string	name = de::toString(imageTestNdx);
5237 				copyTexSubImage2DTests->addChild(new GLES2SharingRandomTest(ctx, config, name.c_str(), name.c_str()));
5238 			}
5239 
5240 			imageTests->addChild(copyTexSubImage2DTests);
5241 		}
5242 
5243 		group->addChild(imageTests);
5244 	}
5245 }
5246 
GLES2SharingThreadedTests(EglTestContext & eglTestCtx)5247 GLES2SharingThreadedTests::GLES2SharingThreadedTests (EglTestContext& eglTestCtx)
5248 	: TestCaseGroup(eglTestCtx, "multithread", "EGL GLES2 sharing multithread tests")
5249 {
5250 }
5251 
init(void)5252 void GLES2SharingThreadedTests::init (void)
5253 {
5254 	tcu::TestCaseGroup* simpleTests = new TestCaseGroup(m_eglTestCtx, "simple", "Simple multithreaded tests");
5255 	addSimpleTests(m_eglTestCtx, simpleTests, false, false);
5256 	addChild(simpleTests);
5257 
5258 	TestCaseGroup* randomTests = new TestCaseGroup(m_eglTestCtx, "random", "Random tests");
5259 	addRandomTests(m_eglTestCtx, randomTests, false, false);
5260 	addChild(randomTests);
5261 
5262 	tcu::TestCaseGroup* simpleTestsSync = new TestCaseGroup(m_eglTestCtx, "simple_egl_sync", "Simple multithreaded tests with EGL_KHR_fence_sync");
5263 	addSimpleTests(m_eglTestCtx, simpleTestsSync, true, false);
5264 	addChild(simpleTestsSync);
5265 
5266 	TestCaseGroup* randomTestsSync = new TestCaseGroup(m_eglTestCtx, "random_egl_sync", "Random tests with EGL_KHR_fence_sync");
5267 	addRandomTests(m_eglTestCtx, randomTestsSync, true, false);
5268 	addChild(randomTestsSync);
5269 
5270 	tcu::TestCaseGroup* simpleTestsServerSync = new TestCaseGroup(m_eglTestCtx, "simple_egl_server_sync", "Simple multithreaded tests with EGL_KHR_fence_sync and EGL_KHR_wait_sync");
5271 	addSimpleTests(m_eglTestCtx, simpleTestsServerSync, true, true);
5272 	addChild(simpleTestsServerSync);
5273 
5274 	TestCaseGroup* randomTestsServerSync = new TestCaseGroup(m_eglTestCtx, "random_egl_server_sync", "Random tests with EGL_KHR_fence_sync and EGL_KHR_wait_sync");
5275 	addRandomTests(m_eglTestCtx, randomTestsServerSync, true, true);
5276 	addChild(randomTestsServerSync);
5277 }
5278 
5279 } // egl
5280 } // deqp
5281