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