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