Merge vk-gl-cts/vulkan-cts-1.3.4 into vk-gl-cts/vulkan-cts-1.3.5
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglGLES2SharingTests.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 tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglGLES2SharingTests.hpp"
25
26 #include "teglGLES2SharingThreadedTests.hpp"
27
28 #include "egluNativeWindow.hpp"
29 #include "egluUtil.hpp"
30 #include "egluUnique.hpp"
31
32 #include "eglwLibrary.hpp"
33 #include "eglwEnums.hpp"
34
35 #include "tcuCommandLine.hpp"
36 #include "tcuImageCompare.hpp"
37 #include "tcuSurface.hpp"
38 #include "tcuTestLog.hpp"
39 #include "tcuTexture.hpp"
40 #include "tcuTextureUtil.hpp"
41
42 #include "deUniquePtr.hpp"
43 #include "deRandom.hpp"
44
45 #include "deMath.h"
46 #include "deMemory.h"
47 #include "deString.h"
48
49 #include "gluDefs.hpp"
50 #include "gluShaderProgram.hpp"
51
52 #include "glwFunctions.hpp"
53 #include "glwEnums.hpp"
54
55 #include <memory>
56 #include <sstream>
57 #include <vector>
58
59 using std::vector;
60
61 namespace deqp
62 {
63 namespace egl
64 {
65
66 using namespace glw;
67 using namespace eglw;
68
69 class GLES2SharingTest : public TestCase
70 {
71 public:
72         enum ResourceType
73         {
74                 BUFFER = 0,
75                 TEXTURE,
76                 RENDERBUFFER,
77                 SHADER_PROGRAM
78         };
79
80         struct TestSpec
81         {
82                 ResourceType    type;
83                 bool                    destroyContextBFirst;
84                 bool                    useResource;
85                 bool                    destroyOnContexB;
86                 bool                    initializeData;
87                 bool                    renderOnContexA;
88                 bool                    renderOnContexB;
89                 bool                    verifyOnContexA;
90                 bool                    verifyOnContexB;
91         };
92
93                                         GLES2SharingTest        (EglTestContext& eglTestCtx, const char* name , const char* desc, const TestSpec& spec);
94
95         void                    init                            (void);
96
97         IterateResult   iterate                         (void);
98
99 private:
100         TestSpec                m_spec;
101
102         EGLContext              createContext           (EGLDisplay display, EGLContext share, EGLConfig config);
103         void                    makeCurrent                     (EGLDisplay display, EGLContext context, EGLSurface surface);
104
105 protected:
106         de::Random              m_random;
107         tcu::TestLog&   m_log;
108         glw::Functions  m_gl;
109
110         virtual void    createResource          (void)  { DE_ASSERT(false); }
111         virtual void    destroyResource         (void)  { DE_ASSERT(false); }
112         virtual void    renderResource          (tcu::Surface* screen, tcu::Surface* reference) { DE_UNREF(screen); DE_UNREF(reference); DE_ASSERT(false); }
113 };
114
115 GLES2SharingTest::GLES2SharingTest (EglTestContext& eglTestCtx, const char* name , const char* desc, const TestSpec& spec)
116         : TestCase      (eglTestCtx, name, desc)
117         , m_spec        (spec)
118         , m_random      (deStringHash(name))
119         , m_log         (eglTestCtx.getTestContext().getLog())
120 {
121 }
122
123 void GLES2SharingTest::init (void)
124 {
125         m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2,0));
126 }
127
128 EGLContext GLES2SharingTest::createContext (EGLDisplay display, EGLContext share, EGLConfig config)
129 {
130         const Library& egl = m_eglTestCtx.getLibrary();
131         EGLContext context = EGL_NO_CONTEXT;
132         const EGLint attriblist[] =
133         {
134                 EGL_CONTEXT_CLIENT_VERSION, 2,
135                 EGL_NONE
136         };
137
138         EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API));
139
140         context = egl.createContext(display, config, share, attriblist);
141         EGLU_CHECK_MSG(egl, "Failed to create GLES2 context");
142         TCU_CHECK(context != EGL_NO_CONTEXT);
143
144         return context;
145 }
146
147 void GLES2SharingTest::makeCurrent (EGLDisplay display, EGLContext context, EGLSurface surface)
148 {
149         const Library& egl = m_eglTestCtx.getLibrary();
150         EGLU_CHECK_CALL(egl, makeCurrent(display, surface, surface, context));
151 }
152
153 TestCase::IterateResult GLES2SharingTest::iterate (void)
154 {
155         const Library&                                          egl                             = m_eglTestCtx.getLibrary();
156         tcu::TestLog&                                           log                             = m_testCtx.getLog();
157         eglu::UniqueDisplay                                     display                 (egl, eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay()));
158         const eglu::NativeWindowFactory&        windowFactory   = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
159         EGLConfig                                                       config;
160         bool                                                            isOk                    = true;
161         EGLContext                                                      contextA                = EGL_NO_CONTEXT;
162         EGLContext                                                      contextB                = EGL_NO_CONTEXT;
163
164         {
165                 const EGLint attribList[] =
166                 {
167                         EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
168                         EGL_SURFACE_TYPE,               EGL_WINDOW_BIT,
169                         EGL_ALPHA_SIZE,                 1,
170                         EGL_NONE
171                 };
172
173                 config = eglu::chooseSingleConfig(egl, *display, attribList);
174         }
175
176         try
177         {
178                 de::UniquePtr<eglu::NativeWindow>       window  (windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), *display, config, DE_NULL, eglu::WindowParams(480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
179                 eglu::UniqueSurface                                     surface (egl, *display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, *display, config, DE_NULL));
180
181                 m_log << tcu::TestLog::Message << "Create context A (share_context = EGL_NO_CONTEXT)" << tcu::TestLog::EndMessage;
182                 contextA = createContext(*display, EGL_NO_CONTEXT, config);
183
184                 m_log << tcu::TestLog::Message << "Create context B (share_context = context A)" << tcu::TestLog::EndMessage;
185                 contextB = createContext(*display, contextA, config);
186
187                 if (m_spec.useResource)
188                 {
189                         m_log << tcu::TestLog::Message << "Make current context A" << tcu::TestLog::EndMessage;
190                         makeCurrent(*display, contextA, *surface);
191                         m_log << tcu::TestLog::Message << "Creating resource" << tcu::TestLog::EndMessage;
192                         createResource();
193
194                         int             width   = 240;
195                         int             height  = 240;
196
197                         if (m_spec.renderOnContexA)
198                         {
199                                 m_log << tcu::TestLog::Message << "Render resource" << tcu::TestLog::EndMessage;
200                                 if (m_spec.verifyOnContexA)
201                                 {
202                                         tcu::Surface screen     (width, height);
203                                         tcu::Surface ref        (width, height);
204                                         renderResource(&screen, &ref);
205
206                                         if (!fuzzyCompare(log, "Rendered image", "Rendering result comparision", ref, screen, 0.05f, tcu::COMPARE_LOG_RESULT))
207                                                 isOk = false;
208                                 }
209                                 else
210                                 {
211                                         renderResource(DE_NULL, DE_NULL);
212                                 }
213                         }
214
215                         if (m_spec.renderOnContexB)
216                         {
217                                 m_log << tcu::TestLog::Message << "Make current context B" << tcu::TestLog::EndMessage;
218                                 makeCurrent(*display, contextB, *surface);
219                                 m_log << tcu::TestLog::Message << "Render resource" << tcu::TestLog::EndMessage;
220                                 if (m_spec.verifyOnContexB)
221                                 {
222                                         tcu::Surface screen     (width, height);
223                                         tcu::Surface ref        (width, height);
224                                         renderResource(&screen, &ref);
225
226                                         if (!fuzzyCompare(log, "Rendered image", "Rendering result comparision", ref, screen, 0.05f, tcu::COMPARE_LOG_RESULT))
227                                                 isOk = false;
228                                 }
229                                 else
230                                 {
231                                         renderResource(DE_NULL, DE_NULL);
232                                 }
233                         }
234
235                         if (m_spec.destroyOnContexB)
236                         {
237                                 m_log << tcu::TestLog::Message << "Make current context B" << tcu::TestLog::EndMessage;
238                                 makeCurrent(*display, contextB, *surface);
239                                 m_log << tcu::TestLog::Message << "Destroy resource" << tcu::TestLog::EndMessage;
240                                 destroyResource();
241                         }
242                         else
243                         {
244                                 m_log << tcu::TestLog::Message << "Make current context A" << tcu::TestLog::EndMessage;
245                                 makeCurrent(*display, contextA, *surface);
246                                 m_log << tcu::TestLog::Message << "Destroy resource" << tcu::TestLog::EndMessage;
247                                 destroyResource();
248                         }
249                 }
250
251                 makeCurrent(*display, EGL_NO_CONTEXT, EGL_NO_SURFACE);
252
253                 if (m_spec.destroyContextBFirst)
254                 {
255                         m_log << tcu::TestLog::Message << "Destroy context B" << tcu::TestLog::EndMessage;
256                         egl.destroyContext(*display, contextB);
257                         contextB = EGL_NO_CONTEXT;
258
259                         m_log << tcu::TestLog::Message << "Destroy context A" << tcu::TestLog::EndMessage;
260                         egl.destroyContext(*display, contextA);
261                         contextA = EGL_NO_CONTEXT;
262                 }
263                 else
264                 {
265                         m_log << tcu::TestLog::Message << "Destroy context A" << tcu::TestLog::EndMessage;
266                         egl.destroyContext(*display, contextA);
267                         contextA = EGL_NO_CONTEXT;
268
269                         m_log << tcu::TestLog::Message << "Destroy context B" << tcu::TestLog::EndMessage;
270                         egl.destroyContext(*display, contextB);
271                         contextB = EGL_NO_CONTEXT;
272                 }
273
274                 EGLU_CHECK(egl);
275         }
276         catch (...)
277         {
278                 egl.makeCurrent(*display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
279                 if (contextA != EGL_NO_CONTEXT)
280                         egl.destroyContext(*display, contextA);
281                 if (contextB != EGL_NO_CONTEXT)
282                         egl.destroyContext(*display, contextB);
283                 throw;
284         }
285
286         if (isOk)
287                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
288         else
289                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
290
291         return STOP;
292 }
293
294 class GLES2BufferSharingTest : public GLES2SharingTest
295 {
296 public:
297                                                         GLES2BufferSharingTest  (EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec);
298
299 private:
300         GLuint                                  m_glBuffer;
301         std::vector<GLubyte>    m_buffer;
302
303         virtual void    createResource          (void);
304         virtual void    destroyResource         (void);
305         virtual void    renderResource          (tcu::Surface* screen, tcu::Surface* reference);
306
307 };
308
309 GLES2BufferSharingTest::GLES2BufferSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec)
310         : GLES2SharingTest      (eglTestCtx, name, desc, spec)
311         , m_glBuffer            (0)
312 {
313 }
314
315 void GLES2BufferSharingTest::createResource (void)
316 {
317         int                                             size    = 16*16*4;
318
319         m_buffer.reserve(size);
320
321         for (int i = 0; i < size; i++)
322                 m_buffer.push_back((GLubyte)m_random.getInt(0, 255));
323
324         GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_glBuffer));
325         GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_glBuffer));
326         GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (GLsizei)(m_buffer.size() * sizeof(GLubyte)), &(m_buffer[0]), GL_DYNAMIC_DRAW));
327         GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, 0));
328 }
329
330 void GLES2BufferSharingTest::destroyResource (void)
331 {
332         GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_glBuffer));
333         m_buffer.clear();
334 }
335
336 void GLES2BufferSharingTest::renderResource (tcu::Surface* screen, tcu::Surface* reference)
337 {
338         DE_ASSERT((screen && reference) || (!screen && !reference));
339
340         const char* vertexShader = ""
341         "attribute mediump vec2 a_pos;\n"
342         "attribute mediump float a_color;\n"
343         "varying mediump float v_color;\n"
344         "void main(void)\n"
345         "{\n"
346         "\tv_color = a_color;\n"
347         "\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
348         "}\n";
349
350         const char* fragmentShader = ""
351         "varying mediump float v_color;\n"
352         "void main(void)\n"
353         "{\n"
354         "\tgl_FragColor = vec4(v_color, v_color, v_color, 1.0);\n"
355         "}\n";
356
357         glu::ShaderProgram program(m_gl, glu::makeVtxFragSources(vertexShader, fragmentShader));
358
359         if (!program.isOk())
360                 TCU_FAIL("Failed to compile shader program");
361
362         std::vector<deUint16>   indices;
363         std::vector<float>              coords;
364
365         DE_ASSERT(m_buffer.size() % 4 == 0);
366
367         for (int i = 0; i < (int)m_buffer.size() / 4; i++)
368         {
369                 indices.push_back((deUint16)(i*4));
370                 indices.push_back((deUint16)(i*4 + 1));
371                 indices.push_back((deUint16)(i*4 + 2));
372                 indices.push_back((deUint16)(i*4 + 2));
373                 indices.push_back((deUint16)(i*4 + 3));
374                 indices.push_back((deUint16)(i*4));
375
376                 coords.push_back(0.125f * (float)(i % 16) - 1.0f);
377                 coords.push_back(0.125f * (float)((int)((float)i / 16.0f)) - 1.0f);
378
379                 coords.push_back(0.125f * (float)(i % 16) - 1.0f);
380                 coords.push_back(0.125f * (float)((int)((float)i / 16.0f) + 1) - 1.0f);
381
382                 coords.push_back(0.125f * (float)((i % 16) + 1) - 1.0f);
383                 coords.push_back(0.125f * (float)((int)((float)i / 16.0f) + 1) - 1.0f);
384
385                 coords.push_back(0.125f * (float)((i % 16) + 1) - 1.0f);
386                 coords.push_back(0.125f * (float)((int)((float)i / 16.0f)) - 1.0f);
387         }
388
389         int width = 240;
390         int height = 240;
391
392         if (screen)
393         {
394                 width = screen->getWidth();
395                 height = screen->getHeight();
396         }
397
398         GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, width, height));
399
400         GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 0.0f, 0.0f, 1.0f));
401         GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
402
403         GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
404
405         GLuint gridLocation = m_gl.getAttribLocation(program.getProgram(), "a_pos");
406         GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
407         TCU_CHECK(gridLocation != (GLuint)-1);
408
409         GLuint colorLocation = m_gl.getAttribLocation(program.getProgram(), "a_color");
410         GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
411         TCU_CHECK(colorLocation != (GLuint)-1);
412
413         GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(colorLocation));
414         GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(gridLocation));
415
416         GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_glBuffer));
417         GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(colorLocation, 1, GL_UNSIGNED_BYTE, GL_TRUE, 0, DE_NULL));
418         GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, 0));
419
420         GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(gridLocation, 2, GL_FLOAT, GL_FALSE, 0, &(coords[0])));
421
422         GLU_CHECK_GLW_CALL(m_gl, drawElements(GL_TRIANGLES, (GLsizei)indices.size(), GL_UNSIGNED_SHORT, &(indices[0])));
423         GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(colorLocation));
424         GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(gridLocation));
425
426         GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
427
428         if (screen)
429         {
430                 tcu::clear(reference->getAccess(), tcu::IVec4(0xff, 0, 0, 0xff));
431                 m_gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
432                 for (int i = 0; i < (int)m_buffer.size() / 4; i++)
433                 {
434                         float fx1 = 0.125f * (float)(i % 16) - 1.0f;
435                         float fy1 = 0.125f * (float)((int)((float)i / 16.0f)) - 1.0f;
436                         float fx2 = 0.125f * (float)((i % 16) + 1) - 1.0f;
437                         float fy2 = 0.125f * (float)((int)((float)i / 16.0f) + 1) - 1.0f;
438
439                         int ox = deRoundFloatToInt32((float)width       / 2.0f);
440                         int oy = deRoundFloatToInt32((float)height      / 2.0f);
441                         int x1 = deRoundFloatToInt32(((float)width       * fx1 / 2.0f) + (float)ox);
442                         int y1 = deRoundFloatToInt32(((float)height      * fy1 / 2.0f) + (float)oy);
443                         int x2 = deRoundFloatToInt32(((float)width       * fx2 / 2.0f) + (float)ox);
444                         int y2 = deRoundFloatToInt32(((float)height      * fy2 / 2.0f) + (float)oy);
445
446                         for (int x = x1; x < x2; x++)
447                         {
448                                 for (int y = y1; y < y2; y++)
449                                 {
450                                         float           xf              = ((float)(x-x1) + 0.5f) / (float)(x2 - x1);
451                                         float           yf              = ((float)(y-y1) + 0.5f) / (float)(y2 - y1);
452                                         bool            tri             = yf >= xf;
453                                         deUint8         a               = m_buffer[i*4 + (tri ? 1 : 3)];
454                                         deUint8         b               = m_buffer[i*4 + (tri ? 2 : 0)];
455                                         deUint8         c               = m_buffer[i*4 + (tri ? 0 : 2)];
456                                         float           s               = tri ? xf : 1.0f-xf;
457                                         float           t               = tri ? 1.0f-yf : yf;
458                                         float           val             = (float)a + (float)(b-a)*s + (float)(c-a)*t;
459
460                                         reference->setPixel(x, y, tcu::RGBA((deUint8)val, (deUint8)val, (deUint8)val, 255));
461                                 }
462                         }
463                 }
464         }
465 }
466
467 class GLES2TextureSharingTest : public GLES2SharingTest
468 {
469 public:
470                                                         GLES2TextureSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec, bool asColorAttachment);
471
472 private:
473         GLuint                                  m_glTexture;
474         tcu::Texture2D                  m_texture;
475         bool                                    m_glTextureAsColorAttachment;
476
477         virtual void    createResource          (void);
478         virtual void    destroyResource         (void);
479         virtual void    renderResource          (tcu::Surface* screen, tcu::Surface* reference);
480
481 };
482
483 GLES2TextureSharingTest::GLES2TextureSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec,  bool asColorAttachment)
484         : GLES2SharingTest      (eglTestCtx, name, desc, spec)
485         , m_glTexture           (0)
486         , m_texture                     (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1)
487         , m_glTextureAsColorAttachment(asColorAttachment)
488 {
489 }
490
491 void GLES2TextureSharingTest::createResource (void)
492 {
493         int width       = 128;
494         int     height  = 128;
495         m_texture = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), width, height);
496         m_texture.allocLevel(0);
497
498         tcu::fillWithComponentGradients(m_texture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
499         GLU_CHECK_GLW_CALL(m_gl, genTextures(1, &m_glTexture));
500         GLU_CHECK_GLW_CALL(m_gl, bindTexture(GL_TEXTURE_2D, m_glTexture));
501         GLU_CHECK_GLW_CALL(m_gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
502         GLU_CHECK_GLW_CALL(m_gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
503         GLU_CHECK_GLW_CALL(m_gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
504         GLU_CHECK_GLW_CALL(m_gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
505         GLU_CHECK_GLW_CALL(m_gl, texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_texture.getLevel(0).getDataPtr()));
506         GLU_CHECK_GLW_CALL(m_gl, bindTexture(GL_TEXTURE_2D, 0));
507 }
508
509 void GLES2TextureSharingTest::destroyResource (void)
510 {
511         GLU_CHECK_GLW_CALL(m_gl, deleteTextures(1, &m_glTexture));
512 }
513
514 void GLES2TextureSharingTest::renderResource (tcu::Surface* screen, tcu::Surface* reference)
515 {
516         DE_ASSERT((screen && reference) || (!screen && !reference));
517
518         const char* vertexShader = ""
519         "attribute mediump vec2 a_pos;\n"
520         "attribute mediump vec2 a_texCorod;\n"
521         "varying mediump vec2 v_texCoord;\n"
522         "void main(void)\n"
523         "{\n"
524         "\tv_texCoord = a_texCorod;\n"
525         "\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
526         "}\n";
527
528         const char* fragmentShader = ""
529         "varying mediump vec2 v_texCoord;\n"
530         "uniform sampler2D u_sampler;\n"
531         "void main(void)\n"
532         "{\n"
533         "\tgl_FragColor = texture2D(u_sampler, v_texCoord);\n"
534         "}\n";
535
536         glu::ShaderProgram program(m_gl, glu::makeVtxFragSources(vertexShader, fragmentShader));
537
538         if (!program.isOk())
539                 TCU_FAIL("Failed to compile shader program");
540
541         int width = 240;
542         int height = 240;
543
544         if (screen)
545         {
546                 width = screen->getWidth();
547                 height = screen->getHeight();
548         }
549
550         static const GLfloat coords[] = {
551                 -1.0f, -1.0f,
552                  1.0f, -1.0f,
553                  1.0f,  1.0f,
554                 -1.0f,  1.0f
555         };
556
557         static const GLfloat texCoords[] = {
558                 0.0f, 0.0f,
559                 1.0f, 0.0f,
560                 1.0f, 1.0f,
561                 0.0f, 1.0f
562         };
563
564         static const GLushort indices[] = {
565                 0, 1, 2,
566                 2, 3, 0
567         };
568
569         GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, width, height));
570
571         GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 0.0f, 0.0f, 1.0f));
572         GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
573
574         GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
575
576         GLuint coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_pos");
577         GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
578         TCU_CHECK(coordLocation != (GLuint)-1);
579
580         GLuint texCoordLocation = m_gl.getAttribLocation(program.getProgram(), "a_texCorod");
581         GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
582         TCU_CHECK(texCoordLocation != (GLuint)-1);
583
584
585         GLuint samplerLocation = m_gl.getUniformLocation(program.getProgram(), "u_sampler");
586         GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()");
587         TCU_CHECK(samplerLocation != (GLuint)-1);
588
589         GLU_CHECK_GLW_CALL(m_gl, activeTexture(GL_TEXTURE0));
590         GLU_CHECK_GLW_CALL(m_gl, bindTexture(GL_TEXTURE_2D, m_glTexture));
591
592         GLU_CHECK_GLW_CALL(m_gl, uniform1i(samplerLocation, 0));
593         if(!m_glTextureAsColorAttachment)
594         {
595
596                 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(texCoordLocation));
597                 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
598
599                 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
600                 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
601
602                 GLU_CHECK_GLW_CALL(m_gl, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
603                 GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(coordLocation));
604                 GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(texCoordLocation));
605
606                 GLU_CHECK_GLW_CALL(m_gl, bindTexture(GL_TEXTURE_2D, 0));
607                 GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
608
609                 if (screen)
610                 {
611                         m_gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
612
613                         for (int x = 0; x < width; x++)
614                         {
615                                 for (int y = 0; y < height; y++)
616                                 {
617                                         float t = ((float)x / ((float)width - 1.0f));
618                                         float s = ((float)y / ((float)height - 1.0f));
619                                         float lod = 0.0f;
620
621                                         tcu::Vec4 color = m_texture.sample(tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR), t, s, lod);
622
623                                         int r = deClamp32((int)(255.0f * color.x()), 0, 255);
624                                         int g = deClamp32((int)(255.0f * color.y()), 0, 255);
625                                         int b = deClamp32((int)(255.0f * color.z()), 0, 255);
626                                         int a = deClamp32((int)(255.0f * color.w()), 0, 255);
627
628                                         reference->setPixel(x, y, tcu::RGBA(r, g, b, a));
629                                 }
630                         }
631                 }
632         }
633         else
634         {
635                 DE_ASSERT(m_glTextureAsColorAttachment);
636
637                 for(int i=0; i < 2; i++)
638                 {
639                         /* Draw left half of rectangle */
640                         {
641                                 GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f };
642                                 GLfloat texcoords[] = {0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 1.0f, 0.0f, 1.0f};
643                                 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(texCoordLocation));
644                                 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
645
646                                 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
647                                 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
648                                 GLU_CHECK_GLW_CALL(m_gl, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
649
650                         }
651                         /* Bind the m_glTexture as user fbo color attachments */
652                         {
653                                 GLuint fbo = 0;
654                                 GLU_CHECK_GLW_CALL(m_gl, bindTexture(GL_TEXTURE_2D, m_glTexture));
655                                 GLU_CHECK_GLW_CALL(m_gl, genFramebuffers(1, &fbo));
656                                 GLU_CHECK_GLW_CALL(m_gl, bindFramebuffer(GL_FRAMEBUFFER, fbo));
657                                 GLU_CHECK_GLW_CALL(m_gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_glTexture, 0));
658                                 GLU_CHECK_GLW_CALL(m_gl, checkFramebufferStatus(GL_FRAMEBUFFER));
659                                 GLubyte data[] = { 0, 0, 0, 0 };
660                                 m_gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
661                                 GLU_CHECK_GLW_CALL(m_gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
662                                 GLU_CHECK_GLW_CALL(m_gl, deleteFramebuffers(1, &fbo));
663                         }
664                         /* Draw right half of rectangle */
665                         {
666                                 GLfloat vertices[] = { 0.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f};
667                                 GLfloat texcoords[] = {0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f, 1.0f};
668                                 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(texCoordLocation));
669                                 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
670
671                                 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
672                                 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
673                                 GLU_CHECK_GLW_CALL(m_gl, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
674                         }
675
676                         if(0 == i)
677                         {
678                                 /* Get the reference data */
679                                 m_gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, reference->getAccess().getDataPtr());
680                         }
681                         else
682                         {
683                                 m_gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
684                         }
685                 }
686         }
687
688 }
689
690 class GLES2ProgramSharingTest : public GLES2SharingTest
691 {
692 public:
693                                                 GLES2ProgramSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec);
694
695 private:
696         glu::ShaderProgram*     m_program;
697
698         virtual void            createResource                  (void);
699         virtual void            destroyResource                 (void);
700         virtual void            renderResource                  (tcu::Surface* screen, tcu::Surface* reference);
701
702 };
703
704 GLES2ProgramSharingTest::GLES2ProgramSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec)
705         : GLES2SharingTest      (eglTestCtx, name, desc, spec)
706         , m_program                     (DE_NULL)
707 {
708 }
709
710 void GLES2ProgramSharingTest::createResource (void)
711 {
712         const char* vertexShader = ""
713         "attribute mediump vec2 a_pos;\n"
714         "attribute mediump vec4 a_color;\n"
715         "varying mediump vec4 v_color;\n"
716         "void main(void)\n"
717         "{\n"
718         "\tv_color = a_color;\n"
719         "\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
720         "}\n";
721
722         const char* fragmentShader = ""
723         "varying mediump vec4 v_color;\n"
724         "void main(void)\n"
725         "{\n"
726         "\tgl_FragColor = v_color;\n"
727         "}\n";
728
729         m_program = new glu::ShaderProgram(m_gl, glu::makeVtxFragSources(vertexShader, fragmentShader));
730
731         if (!m_program->isOk())
732                 TCU_FAIL("Failed to compile shader program");
733 }
734
735 void GLES2ProgramSharingTest::destroyResource (void)
736 {
737         delete m_program;
738 }
739
740 void GLES2ProgramSharingTest::renderResource (tcu::Surface* screen, tcu::Surface* reference)
741 {
742         DE_ASSERT((screen && reference) || (!screen && !reference));
743
744         int width = 240;
745         int height = 240;
746
747         if (screen)
748         {
749                 width = screen->getWidth();
750                 height = screen->getHeight();
751         }
752
753         static const GLfloat coords[] = {
754                 -0.9f, -0.9f,
755                  0.9f, -0.9f,
756                  0.9f,  0.9f,
757                 -0.9f,  0.9f
758         };
759
760         static const GLfloat colors [] = {
761                 0.0f, 0.0f, 0.0f, 1.0f,
762                 1.0f, 0.0f, 0.0f, 1.0f,
763                 0.0f, 1.0f, 0.0f, 1.0f,
764                 0.0f, 0.0f, 1.0f, 1.0f
765         };
766
767         static const GLushort indices[] = {
768                 0, 1, 2,
769                 2, 3, 0
770         };
771
772         GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, width, height));
773
774         GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 0.0f, 0.0f, 1.0f));
775         GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
776
777         GLU_CHECK_GLW_CALL(m_gl, useProgram(m_program->getProgram()));
778
779         GLuint coordLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_pos");
780         GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
781         TCU_CHECK(coordLocation != (GLuint)-1);
782
783         GLuint colorLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_color");
784         GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
785         TCU_CHECK(colorLocation != (GLuint)-1);
786
787         GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(colorLocation));
788         GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
789
790         GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, colors));
791         GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
792
793         GLU_CHECK_GLW_CALL(m_gl, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
794         GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(coordLocation));
795         GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(colorLocation));
796         GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
797
798         if (screen)
799         {
800                 m_gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
801
802                 tcu::clear(reference->getAccess(), tcu::IVec4(0xff, 0, 0, 0xff));
803
804                 int x1 = (int)(((float)width/2.0f)  * (-0.9f) + ((float)width/2.0f));
805                 int x2 = (int)(((float)width/2.0f)  *   0.9f  + ((float)width/2.0f));
806                 int y1 = (int)(((float)height/2.0f) * (-0.9f) + ((float)height/2.0f));
807                 int y2 = (int)(((float)height/2.0f) *   0.9f  + ((float)height/2.0f));
808
809                 for (int x = x1; x <= x2; x++)
810                 {
811                         for (int y = y1; y <= y2; y++)
812                         {
813                                 float t = ((float)(x-x1) / (float)(x2-x1));
814                                 float s = ((float)(y-y1) / (float)(y2-y1));
815                                 bool isUpper = t > s;
816
817                                 tcu::Vec4 a(colors[0],          colors[1],              colors[2],              colors[3]);
818                                 tcu::Vec4 b(colors[4 + 0],      colors[4 + 1],  colors[4 + 2],  colors[4 + 3]);
819                                 tcu::Vec4 c(colors[8 + 0],      colors[8 + 1],  colors[8 + 2],  colors[8 + 3]);
820                                 tcu::Vec4 d(colors[12 + 0],     colors[12 + 1], colors[12 + 2], colors[12 + 3]);
821
822
823                                 tcu::Vec4 color;
824
825                                 if (isUpper)
826                                         color = a * (1.0f - t)  + b * (t - s) + s * c;
827                                 else
828                                         color = a * (1.0f - s)  + d * (s - t) + t * c;
829
830                                 int red         = deClamp32((int)(255.0f * color.x()), 0, 255);
831                                 int green       = deClamp32((int)(255.0f * color.y()), 0, 255);
832                                 int blue        = deClamp32((int)(255.0f * color.z()), 0, 255);
833                                 int alpha       = deClamp32((int)(255.0f * color.w()), 0, 255);
834
835                                 reference->setPixel(x, y, tcu::RGBA(red, green, blue, alpha));
836                         }
837                 }
838         }
839 }
840
841 class GLES2ShaderSharingTest : public GLES2SharingTest
842 {
843 public:
844                                         GLES2ShaderSharingTest  (EglTestContext& eglTestCtx, const char* name, const char* desc, GLenum shaderType, const GLES2SharingTest::TestSpec& spec);
845
846 private:
847         GLuint                  m_shader;
848         GLenum                  m_shaderType;
849
850         virtual void    createResource          (void);
851         virtual void    destroyResource         (void);
852         virtual void    renderResource          (tcu::Surface* screen, tcu::Surface* reference);
853
854 };
855
856 GLES2ShaderSharingTest::GLES2ShaderSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, GLenum shaderType, const GLES2SharingTest::TestSpec& spec)
857         : GLES2SharingTest      (eglTestCtx, name, desc, spec)
858         , m_shader                      (0)
859         , m_shaderType          (shaderType)
860 {
861 }
862
863 void GLES2ShaderSharingTest::createResource (void)
864 {
865         const char* vertexShader = ""
866         "attribute mediump vec2 a_pos;\n"
867         "attribute mediump vec4 a_color;\n"
868         "varying mediump vec4 v_color;\n"
869         "void main(void)\n"
870         "{\n"
871         "\tv_color = a_color;\n"
872         "\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
873         "}\n";
874
875         const char* fragmentShader = ""
876         "varying mediump vec4 v_color;\n"
877         "void main(void)\n"
878         "{\n"
879         "\tgl_FragColor = v_color;\n"
880         "}\n";
881
882
883         m_shader = m_gl.createShader(m_shaderType);
884         GLU_CHECK_GLW_MSG(m_gl, "glCreateShader()");
885
886         switch (m_shaderType)
887         {
888                 case GL_VERTEX_SHADER:
889                         GLU_CHECK_GLW_CALL(m_gl, shaderSource(m_shader, 1, &vertexShader, DE_NULL));
890                         break;
891
892                 case GL_FRAGMENT_SHADER:
893                         GLU_CHECK_GLW_CALL(m_gl, shaderSource(m_shader, 1, &fragmentShader, DE_NULL));
894                         break;
895
896                 default:
897                         DE_ASSERT(false);
898         }
899
900         GLU_CHECK_GLW_CALL(m_gl, compileShader(m_shader));
901
902         GLint status = 0;
903         GLU_CHECK_GLW_CALL(m_gl, getShaderiv(m_shader, GL_COMPILE_STATUS, &status));
904
905         if (!status)
906         {
907                 char buffer[256];
908                 GLU_CHECK_GLW_CALL(m_gl, getShaderInfoLog(m_shader, 256, DE_NULL, buffer));
909
910                 m_log << tcu::TestLog::Message << "Failed to compile shader" << tcu::TestLog::EndMessage;
911
912                 switch (m_shaderType)
913                 {
914                         case GL_VERTEX_SHADER:
915                                 m_log << tcu::TestLog::Message << vertexShader << tcu::TestLog::EndMessage;
916                                 break;
917
918                         case GL_FRAGMENT_SHADER:
919                                 m_log << tcu::TestLog::Message << fragmentShader << tcu::TestLog::EndMessage;
920                                 break;
921
922                         default:
923                                 DE_ASSERT(false);
924                 }
925
926                 m_log << tcu::TestLog::Message << buffer << tcu::TestLog::EndMessage;
927                 TCU_FAIL("Failed to compile shader");
928         }
929 }
930
931 void GLES2ShaderSharingTest::destroyResource (void)
932 {
933         GLU_CHECK_GLW_CALL(m_gl, deleteShader(m_shader));
934 }
935
936 void GLES2ShaderSharingTest::renderResource (tcu::Surface* screen, tcu::Surface* reference)
937 {
938         DE_ASSERT((screen && reference) || (!screen && !reference));
939
940         int width = 240;
941         int height = 240;
942
943         const char* vertexShader = ""
944         "attribute mediump vec2 a_pos;\n"
945         "attribute mediump vec4 a_color;\n"
946         "varying mediump vec4 v_color;\n"
947         "void main(void)\n"
948         "{\n"
949         "\tv_color = a_color;\n"
950         "\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
951         "}\n";
952
953         const char* fragmentShader = ""
954         "varying mediump vec4 v_color;\n"
955         "void main(void)\n"
956         "{\n"
957         "\tgl_FragColor = v_color;\n"
958         "}\n";
959
960
961         GLuint otherShader = (GLuint)-1;
962
963         switch (m_shaderType)
964         {
965                 case GL_VERTEX_SHADER:
966                         otherShader = m_gl.createShader(GL_FRAGMENT_SHADER);
967                         GLU_CHECK_GLW_MSG(m_gl, "glCreateShader()");
968                         GLU_CHECK_GLW_CALL(m_gl, shaderSource(otherShader, 1, &fragmentShader, DE_NULL));
969                         break;
970
971                 case GL_FRAGMENT_SHADER:
972                         otherShader = m_gl.createShader(GL_VERTEX_SHADER);
973                         GLU_CHECK_GLW_MSG(m_gl, "glCreateShader()");
974                         GLU_CHECK_GLW_CALL(m_gl, shaderSource(otherShader, 1, &vertexShader, DE_NULL));
975                         break;
976
977                 default:
978                         DE_ASSERT(false);
979         }
980
981         GLU_CHECK_GLW_CALL(m_gl, compileShader(otherShader));
982
983         GLint status = 0;
984         GLU_CHECK_GLW_CALL(m_gl, getShaderiv(otherShader, GL_COMPILE_STATUS, &status));
985
986         if (!status)
987         {
988                 char buffer[256];
989                 GLU_CHECK_GLW_CALL(m_gl, getShaderInfoLog(otherShader, 256, DE_NULL, buffer));
990
991                 m_log << tcu::TestLog::Message << "Failed to compile shader" << tcu::TestLog::EndMessage;
992
993                 switch (m_shaderType)
994                 {
995                         case GL_FRAGMENT_SHADER:
996                                 m_log << tcu::TestLog::Message << vertexShader << tcu::TestLog::EndMessage;
997                                 break;
998
999                         case GL_VERTEX_SHADER:
1000                                 m_log << tcu::TestLog::Message << fragmentShader << tcu::TestLog::EndMessage;
1001                                 break;
1002
1003                         default:
1004                                 DE_ASSERT(false);
1005                 }
1006
1007                 m_log << tcu::TestLog::Message << buffer << tcu::TestLog::EndMessage;
1008                 TCU_FAIL("Failed to compile shader");
1009         }
1010
1011         GLuint program = m_gl.createProgram();
1012         GLU_CHECK_GLW_MSG(m_gl, "glCreateProgram()");
1013
1014         GLU_CHECK_GLW_CALL(m_gl, attachShader(program, m_shader));
1015         GLU_CHECK_GLW_CALL(m_gl, attachShader(program, otherShader));
1016
1017         GLU_CHECK_GLW_CALL(m_gl, linkProgram(program));
1018         GLU_CHECK_GLW_CALL(m_gl, deleteShader(otherShader));
1019
1020         status = 0;
1021         GLU_CHECK_GLW_CALL(m_gl, getProgramiv(program, GL_LINK_STATUS, &status));
1022
1023         if (!status)
1024         {
1025                 char buffer[256];
1026                 GLU_CHECK_GLW_CALL(m_gl, getProgramInfoLog(program, 256, DE_NULL, buffer));
1027
1028                 m_log << tcu::TestLog::Message << "Failed to link program" << tcu::TestLog::EndMessage;
1029
1030                 m_log << tcu::TestLog::Message << vertexShader << tcu::TestLog::EndMessage;
1031                 m_log << tcu::TestLog::Message << fragmentShader << tcu::TestLog::EndMessage;
1032                 m_log << tcu::TestLog::Message << buffer << tcu::TestLog::EndMessage;
1033                 TCU_FAIL("Failed to link program");
1034         }
1035
1036         if (screen)
1037         {
1038                 width = screen->getWidth();
1039                 height = screen->getHeight();
1040         }
1041
1042         static const GLfloat coords[] = {
1043                 -0.9f, -0.9f,
1044                  0.9f, -0.9f,
1045                  0.9f,  0.9f,
1046                 -0.9f,  0.9f
1047         };
1048
1049         static const GLfloat colors [] = {
1050                 0.0f, 0.0f, 0.0f, 1.0f,
1051                 1.0f, 0.0f, 0.0f, 1.0f,
1052                 0.0f, 1.0f, 0.0f, 1.0f,
1053                 0.0f, 0.0f, 1.0f, 1.0f
1054         };
1055
1056         static const GLushort indices[] = {
1057                 0, 1, 2,
1058                 2, 3, 0
1059         };
1060
1061         GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, width, height));
1062
1063         GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 0.0f, 0.0f, 1.0f));
1064         GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
1065
1066         GLU_CHECK_GLW_CALL(m_gl, useProgram(program));
1067
1068         GLuint coordLocation = m_gl.getAttribLocation(program, "a_pos");
1069         GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
1070         TCU_CHECK(coordLocation != (GLuint)-1);
1071
1072         GLuint colorLocation = m_gl.getAttribLocation(program, "a_color");
1073         GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
1074         TCU_CHECK(colorLocation != (GLuint)-1);
1075
1076         GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(colorLocation));
1077         GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
1078
1079         GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, colors));
1080         GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
1081
1082         GLU_CHECK_GLW_CALL(m_gl, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
1083         GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(coordLocation));
1084         GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(colorLocation));
1085         GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
1086
1087         if (screen)
1088         {
1089                 m_gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
1090
1091                 tcu::clear(reference->getAccess(), tcu::IVec4(0xff, 0, 0, 0xff));
1092
1093                 int x1 = (int)(((float)width/2.0f)  * (-0.9f) + ((float)width/2.0f));
1094                 int x2 = (int)(((float)width/2.0f)  *   0.9f  + ((float)width/2.0f));
1095                 int y1 = (int)(((float)height/2.0f) * (-0.9f) + ((float)height/2.0f));
1096                 int y2 = (int)(((float)height/2.0f) *   0.9f  + ((float)height/2.0f));
1097
1098                 for (int x = x1; x <= x2; x++)
1099                 {
1100                         for (int y = y1; y <= y2; y++)
1101                         {
1102                                 float t = ((float)(x-x1) / (float)(x2-x1));
1103                                 float s = ((float)(y-y1) / (float)(y2-y1));
1104                                 bool isUpper = t > s;
1105
1106                                 tcu::Vec4 a(colors[0],          colors[1],              colors[2],              colors[3]);
1107                                 tcu::Vec4 b(colors[4 + 0],      colors[4 + 1],  colors[4 + 2],  colors[4 + 3]);
1108                                 tcu::Vec4 c(colors[8 + 0],      colors[8 + 1],  colors[8 + 2],  colors[8 + 3]);
1109                                 tcu::Vec4 d(colors[12 + 0],     colors[12 + 1], colors[12 + 2], colors[12 + 3]);
1110
1111
1112                                 tcu::Vec4 color;
1113
1114                                 if (isUpper)
1115                                         color = a * (1.0f - t)  + b * (t - s) + s * c;
1116                                 else
1117                                         color = a * (1.0f - s)  + d * (s - t) + t * c;
1118
1119                                 int red         = deClamp32((int)(255.0f * color.x()), 0, 255);
1120                                 int green       = deClamp32((int)(255.0f * color.y()), 0, 255);
1121                                 int blue        = deClamp32((int)(255.0f * color.z()), 0, 255);
1122                                 int alpha       = deClamp32((int)(255.0f * color.w()), 0, 255);
1123
1124                                 reference->setPixel(x, y, tcu::RGBA(red, green, blue, alpha));
1125                         }
1126                 }
1127         }
1128 }
1129
1130 SharingTests::SharingTests (EglTestContext& eglTestCtx)
1131         : TestCaseGroup (eglTestCtx, "sharing", "Sharing test cases")
1132 {
1133 }
1134
1135 void SharingTests::init (void)
1136 {
1137         TestCaseGroup* gles2 = new TestCaseGroup(m_eglTestCtx, "gles2", "OpenGL ES 2 sharing test");
1138
1139         TestCaseGroup* context = new TestCaseGroup(m_eglTestCtx, "context", "Context creation and destruction tests");
1140
1141         {
1142                 GLES2SharingTest::TestSpec spec;
1143                 spec.destroyContextBFirst       = false;
1144                 spec.useResource                        = false;
1145                 spec.destroyOnContexB           = false;
1146                 spec.initializeData                     = true;
1147                 spec.renderOnContexA            = true;
1148                 spec.renderOnContexB            = true;
1149                 spec.verifyOnContexA            = true;
1150                 spec.verifyOnContexB            = true;
1151
1152                 context->addChild(new GLES2SharingTest(m_eglTestCtx, "create_destroy", "Simple context creation and destruction", spec));
1153         }
1154         {
1155                 GLES2SharingTest::TestSpec spec;
1156                 spec.destroyContextBFirst       = true;
1157                 spec.useResource                        = false;
1158                 spec.destroyOnContexB           = false;
1159                 spec.initializeData                     = false;
1160                 spec.renderOnContexA            = false;
1161                 spec.renderOnContexB            = false;
1162                 spec.verifyOnContexA            = false;
1163                 spec.verifyOnContexB            = false;
1164
1165                 context->addChild(new GLES2SharingTest(m_eglTestCtx, "create_destroy_mixed", "Simple context creation and destruction test with different destruction order", spec));
1166         }
1167
1168         gles2->addChild(context);
1169
1170         TestCaseGroup* buffer = new TestCaseGroup(m_eglTestCtx, "buffer", "Buffer creation, destruction and rendering test");
1171
1172         {
1173                 GLES2SharingTest::TestSpec spec;
1174                 spec.destroyContextBFirst       = false;
1175                 spec.useResource                        = true;
1176                 spec.destroyOnContexB           = false;
1177                 spec.initializeData                     = true;
1178                 spec.renderOnContexA            = false;
1179                 spec.renderOnContexB            = false;
1180                 spec.verifyOnContexA            = false;
1181                 spec.verifyOnContexB            = false;
1182
1183                 buffer->addChild(new GLES2BufferSharingTest(m_eglTestCtx, "create_delete", "Create and delete on shared context", spec));
1184         }
1185         {
1186                 GLES2SharingTest::TestSpec spec;
1187                 spec.destroyContextBFirst       = false;
1188                 spec.useResource                        = true;
1189                 spec.destroyOnContexB           = true;
1190                 spec.initializeData                     = true;
1191                 spec.renderOnContexA            = false;
1192                 spec.renderOnContexB            = false;
1193                 spec.verifyOnContexA            = false;
1194                 spec.verifyOnContexB            = false;
1195
1196                 buffer->addChild(new GLES2BufferSharingTest(m_eglTestCtx, "create_delete_mixed", "Create and delet on different contexts", spec));
1197         }
1198         {
1199                 GLES2SharingTest::TestSpec spec;
1200                 spec.destroyContextBFirst       = false;
1201                 spec.useResource                        = true;
1202                 spec.destroyOnContexB           = false;
1203                 spec.initializeData                     = true;
1204                 spec.renderOnContexA            = true;
1205                 spec.renderOnContexB            = true;
1206                 spec.verifyOnContexA            = true;
1207                 spec.verifyOnContexB            = true;
1208
1209                 buffer->addChild(new GLES2BufferSharingTest(m_eglTestCtx, "render", "Create, rendering on two different contexts and delete", spec));
1210         }
1211
1212         gles2->addChild(buffer);
1213
1214         TestCaseGroup* texture = new TestCaseGroup(m_eglTestCtx, "texture", "Texture creation, destruction and rendering tests");
1215
1216         {
1217                 GLES2SharingTest::TestSpec spec;
1218                 spec.destroyContextBFirst       = false;
1219                 spec.useResource                        = true;
1220                 spec.destroyOnContexB           = false;
1221                 spec.initializeData                     = true;
1222                 spec.renderOnContexA            = false;
1223                 spec.renderOnContexB            = false;
1224                 spec.verifyOnContexA            = false;
1225                 spec.verifyOnContexB            = false;
1226
1227                 texture->addChild(new GLES2TextureSharingTest(m_eglTestCtx, "create_delete", "Create and delete on shared context", spec, false));
1228         }
1229         {
1230                 GLES2SharingTest::TestSpec spec;
1231                 spec.destroyContextBFirst       = false;
1232                 spec.useResource                        = true;
1233                 spec.destroyOnContexB           = true;
1234                 spec.initializeData                     = true;
1235                 spec.renderOnContexA            = false;
1236                 spec.renderOnContexB            = false;
1237                 spec.verifyOnContexA            = false;
1238                 spec.verifyOnContexB            = false;
1239
1240                 texture->addChild(new GLES2TextureSharingTest(m_eglTestCtx, "create_delete_mixed", "Create and delete on different contexts", spec, false));
1241         }
1242         {
1243                 GLES2SharingTest::TestSpec spec;
1244                 spec.destroyContextBFirst       = false;
1245                 spec.useResource                        = true;
1246                 spec.destroyOnContexB           = false;
1247                 spec.initializeData                     = true;
1248                 spec.renderOnContexA            = true;
1249                 spec.renderOnContexB            = true;
1250                 spec.verifyOnContexA            = true;
1251                 spec.verifyOnContexB            = true;
1252
1253                 texture->addChild(new GLES2TextureSharingTest(m_eglTestCtx,"render", "Create, render in two contexts and delete" , spec, false));
1254         }
1255         {
1256                 GLES2SharingTest::TestSpec spec;
1257                 spec.destroyContextBFirst       = false;
1258                 spec.useResource                        = true;
1259                 spec.destroyOnContexB           = false;
1260                 spec.initializeData                     = true;
1261                 spec.renderOnContexA            = true;
1262                 spec.renderOnContexB            = false;
1263                 spec.verifyOnContexA            = true;
1264                 spec.verifyOnContexB            = false;
1265
1266                 texture->addChild(new GLES2TextureSharingTest(m_eglTestCtx, "render_sample_mixed", "sampling, read pixels in different fbo", spec, true));
1267         }
1268         gles2->addChild(texture);
1269
1270         TestCaseGroup* program = new TestCaseGroup(m_eglTestCtx, "program", "Program creation, destruction and rendering test");
1271
1272         {
1273                 GLES2SharingTest::TestSpec spec;
1274                 spec.destroyContextBFirst       = false;
1275                 spec.useResource                        = true;
1276                 spec.destroyOnContexB           = false;
1277                 spec.initializeData                     = true;
1278                 spec.renderOnContexA            = false;
1279                 spec.renderOnContexB            = false;
1280                 spec.verifyOnContexA            = false;
1281                 spec.verifyOnContexB            = false;
1282
1283                 program->addChild(new GLES2ProgramSharingTest(m_eglTestCtx, "create_delete", "Create and delete on shared context", spec));
1284         }
1285         {
1286                 GLES2SharingTest::TestSpec spec;
1287                 spec.destroyContextBFirst       = false;
1288                 spec.useResource                        = true;
1289                 spec.destroyOnContexB           = true;
1290                 spec.initializeData                     = true;
1291                 spec.renderOnContexA            = false;
1292                 spec.renderOnContexB            = false;
1293                 spec.verifyOnContexA            = false;
1294                 spec.verifyOnContexB            = false;
1295
1296                 program->addChild(new GLES2ProgramSharingTest(m_eglTestCtx, "create_delete_mixed", "Create and delete on different contexts", spec));
1297         }
1298         {
1299                 GLES2SharingTest::TestSpec spec;
1300                 spec.destroyContextBFirst       = false;
1301                 spec.useResource                        = true;
1302                 spec.destroyOnContexB           = false;
1303                 spec.initializeData                     = true;
1304                 spec.renderOnContexA            = true;
1305                 spec.renderOnContexB            = true;
1306                 spec.verifyOnContexA            = true;
1307                 spec.verifyOnContexB            = true;
1308
1309                 program->addChild(new GLES2ProgramSharingTest(m_eglTestCtx, "render", "Create, render in two contexts and delete", spec));
1310         }
1311
1312         gles2->addChild(program);
1313
1314         TestCaseGroup* shader = new TestCaseGroup(m_eglTestCtx, "shader", "Shader creation, destruction and rendering test");
1315
1316         {
1317                 GLES2SharingTest::TestSpec spec;
1318                 spec.destroyContextBFirst       = false;
1319                 spec.useResource                        = true;
1320                 spec.destroyOnContexB           = false;
1321                 spec.initializeData                     = true;
1322                 spec.renderOnContexA            = false;
1323                 spec.renderOnContexB            = false;
1324                 spec.verifyOnContexA            = false;
1325                 spec.verifyOnContexB            = false;
1326
1327                 shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_vert", "Create and delete on shared context", GL_VERTEX_SHADER, spec));
1328         }
1329         {
1330                 GLES2SharingTest::TestSpec spec;
1331                 spec.destroyContextBFirst       = false;
1332                 spec.useResource                        = true;
1333                 spec.destroyOnContexB           = true;
1334                 spec.initializeData                     = true;
1335                 spec.renderOnContexA            = false;
1336                 spec.renderOnContexB            = false;
1337                 spec.verifyOnContexA            = false;
1338                 spec.verifyOnContexB            = false;
1339
1340                 shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_mixed_vert", "Create and delete on different contexts", GL_VERTEX_SHADER, spec));
1341         }
1342         {
1343                 GLES2SharingTest::TestSpec spec;
1344                 spec.destroyContextBFirst       = false;
1345                 spec.useResource                        = true;
1346                 spec.destroyOnContexB           = false;
1347                 spec.initializeData                     = true;
1348                 spec.renderOnContexA            = true;
1349                 spec.renderOnContexB            = true;
1350                 spec.verifyOnContexA            = true;
1351                 spec.verifyOnContexB            = true;
1352
1353                 shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "render_vert", "Create, render on two contexts and delete", GL_VERTEX_SHADER, spec));
1354         }
1355         {
1356                 GLES2SharingTest::TestSpec spec;
1357                 spec.destroyContextBFirst       = false;
1358                 spec.useResource                        = true;
1359                 spec.destroyOnContexB           = false;
1360                 spec.initializeData                     = true;
1361                 spec.renderOnContexA            = false;
1362                 spec.renderOnContexB            = false;
1363                 spec.verifyOnContexA            = false;
1364                 spec.verifyOnContexB            = false;
1365
1366                 shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_frag", "Create and delete on shared context", GL_FRAGMENT_SHADER, spec));
1367         }
1368         {
1369                 GLES2SharingTest::TestSpec spec;
1370                 spec.destroyContextBFirst       = false;
1371                 spec.useResource                        = true;
1372                 spec.destroyOnContexB           = true;
1373                 spec.initializeData                     = true;
1374                 spec.renderOnContexA            = false;
1375                 spec.renderOnContexB            = false;
1376                 spec.verifyOnContexA            = false;
1377                 spec.verifyOnContexB            = false;
1378
1379                 shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_mixed_frag", "Create and delete on different contexts", GL_FRAGMENT_SHADER, spec));
1380         }
1381         {
1382                 GLES2SharingTest::TestSpec spec;
1383                 spec.destroyContextBFirst       = false;
1384                 spec.useResource                        = true;
1385                 spec.destroyOnContexB           = false;
1386                 spec.initializeData                     = true;
1387                 spec.renderOnContexA            = true;
1388                 spec.renderOnContexB            = true;
1389                 spec.verifyOnContexA            = true;
1390                 spec.verifyOnContexB            = true;
1391
1392                 shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "render_frag", "Create, render on two contexts and delete", GL_FRAGMENT_SHADER, spec));
1393         }
1394
1395
1396         gles2->addChild(shader);
1397
1398
1399         gles2->addChild(new GLES2SharingThreadedTests(m_eglTestCtx));
1400
1401         addChild(gles2);
1402 }
1403
1404 } // egl
1405 } // deqp