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