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