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