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