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