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