1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program EGL Module
3 * ---------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief EGL image tests.
22 *//*--------------------------------------------------------------------*/
24 #include "teglImageFormatTests.hpp"
26 #include "deStringUtil.hpp"
27 #include "deSTLUtil.hpp"
29 #include "tcuTestLog.hpp"
30 #include "tcuSurface.hpp"
31 #include "tcuTexture.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuImageCompare.hpp"
34 #include "tcuCommandLine.hpp"
36 #include "egluNativeDisplay.hpp"
37 #include "egluNativeWindow.hpp"
38 #include "egluNativePixmap.hpp"
39 #include "egluConfigFilter.hpp"
40 #include "egluUnique.hpp"
41 #include "egluUtil.hpp"
43 #include "eglwLibrary.hpp"
44 #include "eglwEnums.hpp"
46 #include "gluCallLogWrapper.hpp"
47 #include "gluShaderProgram.hpp"
48 #include "gluStrUtil.hpp"
49 #include "gluTexture.hpp"
50 #include "gluPixelTransfer.hpp"
51 #include "gluObjectWrapper.hpp"
52 #include "gluTextureUtil.hpp"
54 #include "glwEnums.hpp"
55 #include "glwFunctions.hpp"
57 #include "teglImageUtil.hpp"
58 #include "teglAndroidUtil.hpp"
71 using glu::Framebuffer;
72 using glu::Renderbuffer;
75 using eglu::UniqueImage;
77 using tcu::ConstPixelBufferAccess;
90 glu::ProgramSources programSources (const string& vertexSource, const string& fragmentSource)
92 glu::ProgramSources sources;
94 sources << glu::VertexSource(vertexSource) << glu::FragmentSource(fragmentSource);
99 class Program : public glu::ShaderProgram
102 Program (const glw::Functions& gl, const char* vertexSource, const char* fragmentSource)
103 : glu::ShaderProgram(gl, programSources(vertexSource, fragmentSource)) {}
113 class IllegalRendererException : public std::exception
120 virtual ~Action (void) {}
121 virtual bool invoke (ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& refImg) const = 0;
122 virtual string getRequiredExtension (void) const = 0;
141 Operation (int apiIndex_, const Action& action_) : apiIndex(apiIndex_), action(&action_) {}
143 const Action* action;
146 vector<ApiContext> contexts;
147 vector<Operation> operations;
154 ImageApi (const Library& egl, int contextId, EGLDisplay display, EGLSurface surface);
155 virtual ~ImageApi (void) {}
158 const Library& m_egl;
160 EGLDisplay m_display;
161 EGLSurface m_surface;
164 ImageApi::ImageApi (const Library& egl, int contextId, EGLDisplay display, EGLSurface surface)
166 , m_contextId (contextId)
167 , m_display (display)
168 , m_surface (surface)
172 class GLES2ImageApi : public ImageApi, private glu::CallLogWrapper
175 class GLES2Action : public Action
178 bool invoke (ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
179 virtual bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const = 0;
182 class Create : public GLES2Action
185 Create (MovePtr<ImageSource> imgSource) : m_imgSource(imgSource) {}
186 string getRequiredExtension (void) const { return m_imgSource->getRequiredExtension(); }
187 bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
188 glw::GLenum getEffectiveFormat (void) const { return m_imgSource->getEffectiveFormat(); }
191 UniquePtr<ImageSource> m_imgSource;
194 class Render : public GLES2Action
197 virtual string getRequiredExtension (void) const { return "GL_OES_EGL_image"; }
200 class RenderTexture2D : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
201 class RenderTextureCubemap : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
202 class RenderReadPixelsRenderbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
203 class RenderDepthbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
204 class RenderStencilbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
205 class RenderTryAll : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
207 class RenderExternalTexture : public Render
210 bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override;
211 string getRequiredExtension (void) const override { return "GL_OES_EGL_image_external"; }
214 class RenderExternalTextureSamplerArray : public Render
217 bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override;
218 string getRequiredExtension (void) const override { return "GL_OES_EGL_image_external"; }
221 class Modify : public GLES2Action
224 string getRequiredExtension (void) const { return "GL_OES_EGL_image"; }
227 class ModifyTexSubImage : public Modify
230 ModifyTexSubImage (GLenum format, GLenum type) : m_format(format), m_type(type) {}
231 bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
232 GLenum getFormat (void) const { return m_format; }
233 GLenum getType (void) const { return m_type; }
240 class ModifyRenderbuffer : public Modify
243 bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
246 virtual void initializeRbo (GLES2ImageApi& api, GLuint rbo, tcu::Texture2D& ref) const = 0;
249 class ModifyRenderbufferClearColor : public ModifyRenderbuffer
252 ModifyRenderbufferClearColor (tcu::Vec4 color) : m_color(color) {}
255 void initializeRbo (GLES2ImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
260 class ModifyRenderbufferClearDepth : public ModifyRenderbuffer
263 ModifyRenderbufferClearDepth (GLfloat depth) : m_depth(depth) {}
266 void initializeRbo (GLES2ImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
271 class ModifyRenderbufferClearStencil : public ModifyRenderbuffer
274 ModifyRenderbufferClearStencil (GLint stencil) : m_stencil(stencil) {}
277 void initializeRbo (GLES2ImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
282 GLES2ImageApi (const Library& egl, const glw::Functions& gl, int contextId, tcu::TestLog& log, EGLDisplay display, EGLSurface surface, EGLConfig config);
283 ~GLES2ImageApi (void);
286 EGLContext m_context;
287 const glw::Functions& m_gl;
289 MovePtr<UniqueImage> createImage (const ImageSource& source, const ClientBuffer& buffer) const;
292 GLES2ImageApi::GLES2ImageApi (const Library& egl, const glw::Functions& gl, int contextId, tcu::TestLog& log, EGLDisplay display, EGLSurface surface, EGLConfig config)
293 : ImageApi (egl, contextId, display, surface)
294 , glu::CallLogWrapper (gl, log)
295 , m_context (DE_NULL)
298 const EGLint attriblist[] =
300 EGL_CONTEXT_CLIENT_VERSION, 2,
304 EGLint configId = -1;
305 EGLU_CHECK_CALL(m_egl, getConfigAttrib(m_display, config, EGL_CONFIG_ID, &configId));
306 getLog() << tcu::TestLog::Message << "Creating gles2 context with config id: " << configId << " context: " << m_contextId << tcu::TestLog::EndMessage;
307 egl.bindAPI(EGL_OPENGL_ES_API);
308 m_context = m_egl.createContext(m_display, config, EGL_NO_CONTEXT, attriblist);
309 EGLU_CHECK_MSG(m_egl, "Failed to create GLES2 context");
311 egl.makeCurrent(display, m_surface, m_surface, m_context);
312 EGLU_CHECK_MSG(m_egl, "Failed to make context current");
315 GLES2ImageApi::~GLES2ImageApi (void)
317 m_egl.makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
318 m_egl.destroyContext(m_display, m_context);
321 bool GLES2ImageApi::GLES2Action::invoke (ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const
323 GLES2ImageApi& gles2Api = dynamic_cast<GLES2ImageApi&>(api);
325 gles2Api.m_egl.makeCurrent(gles2Api.m_display, gles2Api.m_surface, gles2Api.m_surface, gles2Api.m_context);
326 return invokeGLES2(gles2Api, image, ref);
330 bool GLES2ImageApi::Create::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const
332 de::UniquePtr<ClientBuffer> buffer (m_imgSource->createBuffer(api.m_egl, api.m_gl, &ref));
334 GLU_CHECK_GLW_CALL(api.m_gl, finish());
336 image = api.createImage(*m_imgSource, *buffer);
340 MovePtr<UniqueImage> GLES2ImageApi::createImage (const ImageSource& source, const ClientBuffer& buffer) const
342 const EGLImageKHR image = source.createImage(m_egl, m_display, m_context, buffer.get());
343 return MovePtr<UniqueImage>(new UniqueImage(m_egl, m_display, image));
346 static void imageTargetTexture2D (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
348 gl.eglImageTargetTexture2DOES(GL_TEXTURE_2D, img);
350 const GLenum error = gl.getError();
352 if (error == GL_INVALID_OPERATION)
353 TCU_THROW(NotSupportedError, "Creating texture2D from EGLImage type not supported");
355 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
356 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
360 static void imageTargetExternalTexture (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
362 gl.eglImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, img);
364 const GLenum error = gl.getError();
366 if (error == GL_INVALID_OPERATION)
367 TCU_THROW(NotSupportedError, "Creating external texture from EGLImage type not supported");
369 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
370 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
374 static void imageTargetRenderbuffer (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
376 gl.eglImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, img);
378 const GLenum error = gl.getError();
380 if (error == GL_INVALID_OPERATION)
381 TCU_THROW(NotSupportedError, "Creating renderbuffer from EGLImage type not supported");
383 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetRenderbufferStorageOES()");
384 EGLU_CHECK_MSG(egl, "glEGLImageTargetRenderbufferStorageOES()");
388 static void framebufferRenderbuffer (const glw::Functions& gl, GLenum attachment, GLuint rbo)
390 GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rbo));
391 TCU_CHECK_AND_THROW(NotSupportedError,
392 gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
393 ("EGLImage as " + string(glu::getFramebufferAttachmentName(attachment)) + " not supported").c_str());
396 static const float squareTriangleCoords[] =
407 bool GLES2ImageApi::RenderTexture2D::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
409 const glw::Functions& gl = api.m_gl;
410 tcu::TestLog& log = api.getLog();
413 // Branch only taken in TryAll case
414 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
415 throw IllegalRendererException(); // Skip, GLES2 does not support sampling depth textures
416 if (reference.getFormat().order == tcu::TextureFormat::S)
417 throw IllegalRendererException(); // Skip, GLES2 does not support sampling stencil textures
419 gl.clearColor(0.0, 0.0, 0.0, 0.0);
420 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
421 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
422 gl.disable(GL_DEPTH_TEST);
424 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_2D in context: " << api.m_contextId << tcu::TestLog::EndMessage;
425 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
427 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
428 imageTargetTexture2D(api.m_egl, gl, **img);
430 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
431 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
432 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
433 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
435 const char* const vertexShader =
436 "attribute highp vec2 a_coord;\n"
437 "varying mediump vec2 v_texCoord;\n"
438 "void main(void) {\n"
439 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
440 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
443 const char* const fragmentShader =
444 "varying mediump vec2 v_texCoord;\n"
445 "uniform sampler2D u_sampler;\n"
446 "void main(void) {\n"
447 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
448 "\tgl_FragColor = vec4(texColor);\n"
451 Program program(gl, vertexShader, fragmentShader);
452 TCU_CHECK(program.isOk());
454 GLuint glProgram = program.getProgram();
455 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
457 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
458 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
460 GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
461 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
463 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
464 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
465 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
466 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
468 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
469 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
470 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, 0));
472 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
473 tcu::Surface screen (reference.getWidth(), reference.getHeight());
474 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
476 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
478 float threshold = 0.05f;
479 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
484 bool GLES2ImageApi::RenderExternalTexture::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
486 const glw::Functions& gl = api.m_gl;
487 tcu::TestLog& log = api.getLog();
490 // Branch only taken in TryAll case
491 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
492 throw IllegalRendererException(); // Skip, GLES2 does not support sampling depth textures
493 if (reference.getFormat().order == tcu::TextureFormat::S)
494 throw IllegalRendererException(); // Skip, GLES2 does not support sampling stencil textures
496 gl.clearColor(0.0, 0.0, 0.0, 0.0);
497 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
498 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
499 gl.disable(GL_DEPTH_TEST);
501 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_EXTERNAL_OES in context: " << api.m_contextId << tcu::TestLog::EndMessage;
502 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
504 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
505 imageTargetExternalTexture(api.m_egl, gl, **img);
507 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
508 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
509 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
510 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
512 const char* const vertexShader =
513 "attribute highp vec2 a_coord;\n"
514 "varying mediump vec2 v_texCoord;\n"
515 "void main(void) {\n"
516 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
517 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
520 const char* const fragmentShader =
521 "#extension GL_OES_EGL_image_external : require\n"
522 "varying mediump vec2 v_texCoord;\n"
523 "uniform samplerExternalOES u_sampler;\n"
524 "void main(void) {\n"
525 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
526 "\tgl_FragColor = vec4(texColor);\n"
529 Program program(gl, vertexShader, fragmentShader);
530 TCU_CHECK(program.isOk());
532 GLuint glProgram = program.getProgram();
533 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
535 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
536 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
538 GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
539 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
541 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
542 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
543 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
544 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
546 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
547 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
548 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
550 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
551 tcu::Surface screen (reference.getWidth(), reference.getHeight());
552 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
554 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
556 float threshold = 0.05f;
557 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
562 bool GLES2ImageApi::RenderExternalTextureSamplerArray::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
564 const glw::Functions& gl = api.m_gl;
565 tcu::TestLog& log = api.getLog();
568 // Branch only taken in TryAll case
569 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
570 throw IllegalRendererException(); // Skip, GLES2 does not support sampling depth textures
571 if (reference.getFormat().order == tcu::TextureFormat::S)
572 throw IllegalRendererException(); // Skip, GLES2 does not support sampling stencil textures
574 gl.clearColor(0.0, 0.0, 0.0, 0.0);
575 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
576 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
577 gl.disable(GL_DEPTH_TEST);
579 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_EXTERNAL_OES using sampler array in context: " << api.m_contextId << tcu::TestLog::EndMessage;
580 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
582 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
583 imageTargetExternalTexture(api.m_egl, gl, **img);
585 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
586 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
587 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
588 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
590 // Texture not associated with an external texture will return (0, 0, 0, 1) when sampled.
592 gl.genTextures(1, &emptyTex);
593 gl.activeTexture(GL_TEXTURE1);
594 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, emptyTex));
596 const char* const vertexShader =
597 "attribute highp vec2 a_coord;\n"
598 "varying mediump vec2 v_texCoord;\n"
599 "void main(void) {\n"
600 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
601 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
604 const char* const fragmentShader =
605 "#extension GL_OES_EGL_image_external : require\n"
606 "varying mediump vec2 v_texCoord;\n"
607 "uniform samplerExternalOES u_sampler[4];\n"
608 "void main(void) {\n"
609 "\tmediump vec4 texColor = texture2D(u_sampler[2], v_texCoord);\n"
610 "\t//These will sample (0, 0, 0, 1) and should not affect the results.\n"
611 "\ttexColor += texture2D(u_sampler[0], v_texCoord) - vec4(0, 0, 0, 1);\n"
612 "\ttexColor += texture2D(u_sampler[1], v_texCoord) - vec4(0, 0, 0, 1);\n"
613 "\ttexColor += texture2D(u_sampler[3], v_texCoord) - vec4(0, 0, 0, 1);\n"
614 "\tgl_FragColor = vec4(texColor);\n"
617 Program program(gl, vertexShader, fragmentShader);
618 TCU_CHECK(program.isOk());
620 GLuint glProgram = program.getProgram();
621 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
623 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
624 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
626 GLuint samplerLoc0 = gl.getUniformLocation(glProgram, "u_sampler[0]");
627 TCU_CHECK_MSG((int)samplerLoc0 != (int)-1, "Couldn't find uniform u_sampler[0]");
628 GLuint samplerLoc1 = gl.getUniformLocation(glProgram, "u_sampler[1]");
629 TCU_CHECK_MSG((int)samplerLoc1 != (int)-1, "Couldn't find uniform u_sampler[1]");
630 GLuint samplerLoc2 = gl.getUniformLocation(glProgram, "u_sampler[2]");
631 TCU_CHECK_MSG((int)samplerLoc2 != (int)-1, "Couldn't find uniform u_sampler[2]");
632 GLuint samplerLoc3 = gl.getUniformLocation(glProgram, "u_sampler[3]");
633 TCU_CHECK_MSG((int)samplerLoc3 != (int)-1, "Couldn't find uniform u_sampler[3]");
635 gl.activeTexture(GL_TEXTURE0);
636 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
637 // One sampler reads a gradient and others opaque black.
638 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc0, 1));
639 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc1, 1));
640 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc2, 0));
641 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc3, 1));
642 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
643 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
645 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
646 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
647 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
648 gl.activeTexture(GL_TEXTURE1);
649 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
650 gl.deleteTextures(1, &emptyTex);
651 gl.activeTexture(GL_TEXTURE0);
653 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
654 tcu::Surface screen (reference.getWidth(), reference.getHeight());
655 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
657 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
659 float threshold = 0.05f;
660 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
665 bool GLES2ImageApi::RenderDepthbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
667 const glw::Functions& gl = api.m_gl;
668 tcu::TestLog& log = api.getLog();
669 Framebuffer framebuffer (gl);
670 Renderbuffer renderbufferColor (gl);
671 Renderbuffer renderbufferDepth (gl);
672 const tcu::RGBA compareThreshold (32, 32, 32, 32); // layer colors are far apart, large thresholds are ok
674 // Branch only taken in TryAll case
675 if (reference.getFormat().order != tcu::TextureFormat::DS && reference.getFormat().order != tcu::TextureFormat::D)
676 throw IllegalRendererException(); // Skip, interpreting non-depth data as depth data is not meaningful
678 log << tcu::TestLog::Message << "Rendering with depth buffer" << tcu::TestLog::EndMessage;
680 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
682 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferColor));
683 GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight()));
684 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbufferColor);
686 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferDepth));
687 imageTargetRenderbuffer(api.m_egl, gl, **img);
688 framebufferRenderbuffer(gl, GL_DEPTH_ATTACHMENT, *renderbufferDepth);
689 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
691 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
694 const char* vertexShader =
695 "attribute highp vec2 a_coord;\n"
696 "uniform highp float u_depth;\n"
697 "void main(void) {\n"
698 "\tgl_Position = vec4(a_coord, u_depth, 1.0);\n"
701 const char* fragmentShader =
702 "uniform mediump vec4 u_color;\n"
703 "void main(void) {\n"
704 "\tgl_FragColor = u_color;\n"
707 Program program(gl, vertexShader, fragmentShader);
708 TCU_CHECK(program.isOk());
710 GLuint glProgram = program.getProgram();
711 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
713 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
714 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
716 GLuint colorLoc = gl.getUniformLocation(glProgram, "u_color");
717 TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color");
719 GLuint depthLoc = gl.getUniformLocation(glProgram, "u_depth");
720 TCU_CHECK_MSG((int)depthLoc != (int)-1, "Couldn't find uniform u_depth");
722 GLU_CHECK_GLW_CALL(gl, clearColor(0.5f, 1.0f, 0.5f, 1.0f));
723 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
725 tcu::Vec4 depthLevelColors[] = {
726 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
727 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
728 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
729 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
730 tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
732 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
733 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
734 tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f),
735 tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f),
736 tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)
739 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
740 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
742 GLU_CHECK_GLW_CALL(gl, enable(GL_DEPTH_TEST));
743 GLU_CHECK_GLW_CALL(gl, depthFunc(GL_LESS));
744 GLU_CHECK_GLW_CALL(gl, depthMask(GL_FALSE));
746 for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevelColors); level++)
748 const tcu::Vec4 color = depthLevelColors[level];
749 const float clipDepth = ((float)(level + 1) * 0.1f) * 2.0f - 1.0f; // depth in clip coords
751 GLU_CHECK_GLW_CALL(gl, uniform4f(colorLoc, color.x(), color.y(), color.z(), color.w()));
752 GLU_CHECK_GLW_CALL(gl, uniform1f(depthLoc, clipDepth));
753 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
756 GLU_CHECK_GLW_CALL(gl, depthMask(GL_TRUE));
757 GLU_CHECK_GLW_CALL(gl, disable(GL_DEPTH_TEST));
758 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
760 const ConstPixelBufferAccess& refAccess = reference.getLevel(0);
761 tcu::Surface screen (reference.getWidth(), reference.getHeight());
762 tcu::Surface referenceScreen (reference.getWidth(), reference.getHeight());
764 gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
766 for (int y = 0; y < reference.getHeight(); y++)
768 for (int x = 0; x < reference.getWidth(); x++)
770 tcu::Vec4 result = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f);
772 for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevelColors); level++)
774 if ((float)(level + 1) * 0.1f < refAccess.getPixDepth(x, y))
775 result = depthLevelColors[level];
778 referenceScreen.getAccess().setPixel(result, x, y);
782 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
783 GLU_CHECK_GLW_CALL(gl, finish());
785 return tcu::pixelThresholdCompare(log, "Depth buffer rendering result", "Result from rendering with depth buffer", referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT);
788 bool GLES2ImageApi::RenderStencilbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
790 // Branch only taken in TryAll case
791 if (reference.getFormat().order != tcu::TextureFormat::DS && reference.getFormat().order != tcu::TextureFormat::S)
792 throw IllegalRendererException(); // Skip, interpreting non-stencil data as stencil data is not meaningful
794 const glw::Functions& gl = api.m_gl;
795 tcu::TestLog& log = api.getLog();
796 Framebuffer framebuffer (gl);
797 Renderbuffer renderbufferColor (gl);
798 Renderbuffer renderbufferStencil (gl);
799 const tcu::RGBA compareThreshold (32, 32, 32, 32); // layer colors are far apart, large thresholds are ok
800 const deUint32 numStencilBits = tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(reference.getLevel(0).getFormat(), tcu::Sampler::MODE_STENCIL)).x();
801 const deUint32 maxStencil = deBitMask32(0, numStencilBits);
803 log << tcu::TestLog::Message << "Rendering with stencil buffer" << tcu::TestLog::EndMessage;
805 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
807 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferColor));
808 GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight()));
809 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbufferColor);
811 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferStencil));
812 imageTargetRenderbuffer(api.m_egl, gl, **img);
813 framebufferRenderbuffer(gl, GL_STENCIL_ATTACHMENT, *renderbufferStencil);
814 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
816 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
819 const char* vertexShader =
820 "attribute highp vec2 a_coord;\n"
821 "void main(void) {\n"
822 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
825 const char* fragmentShader =
826 "uniform mediump vec4 u_color;\n"
827 "void main(void) {\n"
828 "\tgl_FragColor = u_color;\n"
831 Program program(gl, vertexShader, fragmentShader);
832 TCU_CHECK(program.isOk());
834 GLuint glProgram = program.getProgram();
835 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
837 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
838 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
840 GLuint colorLoc = gl.getUniformLocation(glProgram, "u_color");
841 TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color");
843 GLU_CHECK_GLW_CALL(gl, clearColor(0.5f, 1.0f, 0.5f, 1.0f));
844 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
846 tcu::Vec4 stencilLevelColors[] = {
847 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
848 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
849 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
850 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
851 tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
853 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
854 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
855 tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f),
856 tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f),
857 tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)
860 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
861 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
863 GLU_CHECK_GLW_CALL(gl, enable(GL_STENCIL_TEST));
864 GLU_CHECK_GLW_CALL(gl, stencilOp(GL_KEEP, GL_KEEP, GL_KEEP));
866 for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++)
868 const tcu::Vec4 color = stencilLevelColors[level];
869 const int stencil = (int)(((float)(level + 1) * 0.1f) * (float)maxStencil);
871 GLU_CHECK_GLW_CALL(gl, stencilFunc(GL_LESS, stencil, 0xFFFFFFFFu));
872 GLU_CHECK_GLW_CALL(gl, uniform4f(colorLoc, color.x(), color.y(), color.z(), color.w()));
873 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
876 GLU_CHECK_GLW_CALL(gl, disable(GL_STENCIL_TEST));
877 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
879 const ConstPixelBufferAccess& refAccess = reference.getLevel(0);
880 tcu::Surface screen (reference.getWidth(), reference.getHeight());
881 tcu::Surface referenceScreen (reference.getWidth(), reference.getHeight());
883 gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
885 for (int y = 0; y < reference.getHeight(); y++)
886 for (int x = 0; x < reference.getWidth(); x++)
888 tcu::Vec4 result = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f);
890 for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++)
892 const int levelStencil = (int)(((float)(level + 1) * 0.1f) * (float)maxStencil);
893 if (levelStencil < refAccess.getPixStencil(x, y))
894 result = stencilLevelColors[level];
897 referenceScreen.getAccess().setPixel(result, x, y);
900 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
901 GLU_CHECK_GLW_CALL(gl, finish());
903 return tcu::pixelThresholdCompare(log, "StencilResult", "Result from rendering with stencil buffer", referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT);
906 bool GLES2ImageApi::RenderReadPixelsRenderbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
908 const glw::Functions& gl = api.m_gl;
909 const tcu::IVec4 bitDepth = tcu::getTextureFormatMantissaBitDepth(reference.getFormat());
910 const tcu::IVec4 threshold (2 * (tcu::IVec4(1) << (tcu::IVec4(8) - bitDepth)));
911 const tcu::RGBA threshold8 ((deUint8)(de::clamp(threshold[0], 0, 255)), (deUint8)(de::clamp(threshold[1], 0, 255)), (deUint8)(de::clamp(threshold[2], 0, 255)), (deUint8)(de::clamp(threshold[3], 0, 255)));
912 tcu::TestLog& log = api.getLog();
913 Framebuffer framebuffer (gl);
914 Renderbuffer renderbuffer (gl);
915 tcu::Surface screen (reference.getWidth(), reference.getHeight());
916 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
918 switch (glu::getInternalFormat(reference.getFormat()))
925 // Skip, not in the list of allowed render buffer formats for GLES2.
926 throw tcu::NotSupportedError("Image format not allowed for glReadPixels.");
930 log << tcu::TestLog::Message << "Reading with ReadPixels from renderbuffer" << tcu::TestLog::EndMessage;
932 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
933 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer));
934 imageTargetRenderbuffer(api.m_egl, gl, **img);
936 GLU_EXPECT_NO_ERROR(gl.getError(), "imageTargetRenderbuffer");
937 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbuffer);
938 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferRenderbuffer");
940 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
942 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
944 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
945 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
946 GLU_CHECK_GLW_CALL(gl, finish());
948 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
950 return tcu::pixelThresholdCompare(log, "Renderbuffer read", "Result from reading renderbuffer", refSurface, screen, threshold8, tcu::COMPARE_LOG_RESULT);
954 bool GLES2ImageApi::RenderTryAll::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
956 bool foundSupported = false;
957 tcu::TestLog& log = api.getLog();
958 GLES2ImageApi::RenderTexture2D renderTex2D;
959 GLES2ImageApi::RenderExternalTexture renderExternal;
960 GLES2ImageApi::RenderExternalTextureSamplerArray renderExternalSamplerArray;
961 GLES2ImageApi::RenderReadPixelsRenderbuffer renderReadPixels;
962 GLES2ImageApi::RenderDepthbuffer renderDepth;
963 GLES2ImageApi::RenderStencilbuffer renderStencil;
964 Action* actions[] = { &renderTex2D, &renderExternal, &renderExternalSamplerArray, &renderReadPixels, &renderDepth, &renderStencil };
966 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(actions); ++ndx)
970 if (!actions[ndx]->invoke(api, img, reference))
973 foundSupported = true;
975 catch (const tcu::NotSupportedError& error)
977 log << tcu::TestLog::Message << error.what() << tcu::TestLog::EndMessage;
979 catch (const IllegalRendererException&)
981 // not valid renderer
986 throw tcu::NotSupportedError("Rendering not supported", "", __FILE__, __LINE__);
991 bool GLES2ImageApi::ModifyTexSubImage::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
993 const glw::Functions& gl = api.m_gl;
994 tcu::TestLog& log = api.getLog();
995 glu::Texture srcTex (gl);
996 const int xOffset = 8;
997 const int yOffset = 16;
998 const int xSize = de::clamp(16, 0, reference.getWidth() - xOffset);
999 const int ySize = de::clamp(16, 0, reference.getHeight() - yOffset);
1000 tcu::Texture2D src (glu::mapGLTransferFormat(m_format, m_type), xSize, ySize);
1002 log << tcu::TestLog::Message << "Modifying EGLImage with gl.texSubImage2D" << tcu::TestLog::EndMessage;
1005 tcu::fillWithComponentGradients(src.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
1007 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
1008 imageTargetTexture2D(api.m_egl, gl, **img);
1009 GLU_CHECK_GLW_CALL(gl, texSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, src.getWidth(), src.getHeight(), m_format, m_type, src.getLevel(0).getDataPtr()));
1010 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, 0));
1011 GLU_CHECK_GLW_CALL(gl, finish());
1013 tcu::copy(tcu::getSubregion(reference.getLevel(0), xOffset, yOffset, 0, xSize, ySize, 1), src.getLevel(0));
1018 bool GLES2ImageApi::ModifyRenderbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
1020 const glw::Functions& gl = api.m_gl;
1021 tcu::TestLog& log = api.getLog();
1022 glu::Framebuffer framebuffer (gl);
1023 glu::Renderbuffer renderbuffer (gl);
1025 log << tcu::TestLog::Message << "Modifying EGLImage with glClear to renderbuffer" << tcu::TestLog::EndMessage;
1027 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
1028 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer));
1030 imageTargetRenderbuffer(api.m_egl, gl, **img);
1032 initializeRbo(api, *renderbuffer, reference);
1034 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1035 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
1037 GLU_CHECK_GLW_CALL(gl, finish());
1042 void GLES2ImageApi::ModifyRenderbufferClearColor::initializeRbo (GLES2ImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
1044 const glw::Functions& gl = api.m_gl;
1046 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, renderbuffer);
1048 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1049 GLU_CHECK_GLW_CALL(gl, clearColor(m_color.x(), m_color.y(), m_color.z(), m_color.w()));
1050 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
1052 tcu::clear(reference.getLevel(0), m_color);
1055 void GLES2ImageApi::ModifyRenderbufferClearDepth::initializeRbo (GLES2ImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
1057 const glw::Functions& gl = api.m_gl;
1059 framebufferRenderbuffer(gl, GL_DEPTH_ATTACHMENT, renderbuffer);
1061 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1062 GLU_CHECK_GLW_CALL(gl, clearDepthf(m_depth));
1063 GLU_CHECK_GLW_CALL(gl, clear(GL_DEPTH_BUFFER_BIT));
1065 tcu::clearDepth(reference.getLevel(0), m_depth);
1068 void GLES2ImageApi::ModifyRenderbufferClearStencil::initializeRbo (GLES2ImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
1070 const glw::Functions& gl = api.m_gl;
1072 framebufferRenderbuffer(gl, GL_STENCIL_ATTACHMENT, renderbuffer);
1074 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1075 GLU_CHECK_GLW_CALL(gl, clearStencil(m_stencil));
1076 GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT));
1078 tcu::clearStencil(reference.getLevel(0), m_stencil);
1081 class ImageFormatCase : public TestCase, private glu::CallLogWrapper
1084 ImageFormatCase (EglTestContext& eglTestCtx, const TestSpec& spec);
1085 ~ImageFormatCase (void);
1089 IterateResult iterate (void);
1090 void checkExtensions (void);
1093 EGLConfig getConfig (void);
1095 const TestSpec m_spec;
1097 vector<ImageApi*> m_apiContexts;
1099 EGLDisplay m_display;
1100 eglu::NativeWindow* m_window;
1101 EGLSurface m_surface;
1104 MovePtr<UniqueImage>m_img;
1105 tcu::Texture2D m_refImg;
1106 glw::Functions m_gl;
1109 EGLConfig ImageFormatCase::getConfig (void)
1111 const EGLint attribList[] =
1113 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
1114 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
1123 return eglu::chooseSingleConfig(m_eglTestCtx.getLibrary(), m_display, attribList);
1126 ImageFormatCase::ImageFormatCase (EglTestContext& eglTestCtx, const TestSpec& spec)
1127 : TestCase (eglTestCtx, spec.name.c_str(), spec.desc.c_str())
1128 , glu::CallLogWrapper (m_gl, eglTestCtx.getTestContext().getLog())
1130 , m_display (EGL_NO_DISPLAY)
1131 , m_window (DE_NULL)
1132 , m_surface (EGL_NO_SURFACE)
1135 , m_refImg (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1)
1139 ImageFormatCase::~ImageFormatCase (void)
1144 void ImageFormatCase::checkExtensions (void)
1146 const Library& egl = m_eglTestCtx.getLibrary();
1147 const EGLDisplay dpy = m_display;
1149 const vector<string> glExts = de::splitString((const char*) m_gl.getString(GL_EXTENSIONS));
1150 const vector<string> eglExts = eglu::getDisplayExtensions(egl, dpy);
1152 exts.insert(glExts.begin(), glExts.end());
1153 exts.insert(eglExts.begin(), eglExts.end());
1155 if (eglu::getVersion(egl, dpy) >= eglu::Version(1, 5))
1157 // EGL 1.5 has built-in support for EGLImage and GL sources
1158 exts.insert("EGL_KHR_image_base");
1159 exts.insert("EGL_KHR_gl_texture_2D_image");
1160 exts.insert("EGL_KHR_gl_texture_cubemap_image");
1161 exts.insert("EGL_KHR_gl_renderbuffer_image");
1164 if (!de::contains(exts, "EGL_KHR_image_base") && !de::contains(exts, "EGL_KHR_image"))
1166 getLog() << tcu::TestLog::Message
1167 << "EGL version is under 1.5 and neither EGL_KHR_image nor EGL_KHR_image_base is supported."
1168 << "One should be supported."
1169 << tcu::TestLog::EndMessage;
1170 TCU_THROW(NotSupportedError, "Extension not supported: EGL_KHR_image_base");
1173 for (int operationNdx = 0; operationNdx < (int)m_spec.operations.size(); operationNdx++)
1175 const TestSpec::Operation& op = m_spec.operations[operationNdx];
1176 const string ext = op.action->getRequiredExtension();
1178 if (!de::contains(exts, ext))
1179 TCU_THROW_EXPR(NotSupportedError, "Extension not supported", ext.c_str());
1183 void ImageFormatCase::init (void)
1185 const Library& egl = m_eglTestCtx.getLibrary();
1186 const eglu::NativeWindowFactory& windowFactory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
1190 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
1191 m_config = getConfig();
1192 m_window = windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL, eglu::WindowParams(480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine())));
1193 m_surface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_display, m_config, DE_NULL);
1196 const char* extensions[] = { "GL_OES_EGL_image" };
1197 m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2, 0), DE_LENGTH_OF_ARRAY(extensions), &extensions[0]);
1200 for (int contextNdx = 0; contextNdx < (int)m_spec.contexts.size(); contextNdx++)
1202 ImageApi* api = DE_NULL;
1203 switch (m_spec.contexts[contextNdx])
1205 case TestSpec::API_GLES2:
1207 api = new GLES2ImageApi(egl, m_gl, contextNdx, getLog(), m_display, m_surface, m_config);
1215 m_apiContexts.push_back(api);
1226 void ImageFormatCase::deinit (void)
1228 const Library& egl = m_eglTestCtx.getLibrary();
1232 for (int contexNdx = 0 ; contexNdx < (int)m_apiContexts.size(); contexNdx++)
1233 delete m_apiContexts[contexNdx];
1235 m_apiContexts.clear();
1237 if (m_surface != EGL_NO_SURFACE)
1239 egl.destroySurface(m_display, m_surface);
1240 m_surface = EGL_NO_SURFACE;
1246 if (m_display != EGL_NO_DISPLAY)
1248 egl.terminate(m_display);
1249 m_display = EGL_NO_DISPLAY;
1253 TestCase::IterateResult ImageFormatCase::iterate (void)
1255 const TestSpec::Operation& op = m_spec.operations[m_curIter++];
1256 ImageApi& api = *m_apiContexts[op.apiIndex];
1257 const bool isOk = op.action->invoke(api, m_img, m_refImg);
1259 if (isOk && m_curIter < (int)m_spec.operations.size())
1262 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1264 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1269 struct LabeledAction
1272 MovePtr<Action> action;
1275 // A simple vector mockup that we need because MovePtr isn't copy-constructible.
1276 struct LabeledActions
1278 LabeledActions (void) : m_numActions(0){}
1279 LabeledAction& operator[] (int ndx) { DE_ASSERT(0 <= ndx && ndx < m_numActions); return m_actions[ndx]; }
1280 void add (const string& label, MovePtr<Action> action);
1281 int size (void) const { return m_numActions; }
1283 LabeledAction m_actions[64];
1287 void LabeledActions::add (const string& label, MovePtr<Action> action)
1289 DE_ASSERT(m_numActions < DE_LENGTH_OF_ARRAY(m_actions));
1290 m_actions[m_numActions].label = label;
1291 m_actions[m_numActions].action = action;
1295 class ImageTests : public TestCaseGroup
1298 ImageTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1299 : TestCaseGroup(eglTestCtx, name.c_str(), desc.c_str()) {}
1301 void addCreateTexture (const string& name, EGLenum source, GLenum internalFormat, GLenum format, GLenum type);
1302 void addCreateRenderbuffer (const string& name, GLenum format);
1303 void addCreateAndroidNative (const string& name, GLenum format);
1304 void addCreateTexture2DActions (const string& prefix);
1305 void addCreateTextureCubemapActions (const string& suffix, GLenum internalFormat, GLenum format, GLenum type);
1306 void addCreateRenderbufferActions (void);
1307 void addCreateAndroidNativeActions (void);
1309 LabeledActions m_createActions;
1312 void ImageTests::addCreateTexture (const string& name, EGLenum source, GLenum internalFormat, GLenum format, GLenum type)
1314 m_createActions.add(name, MovePtr<Action>(new GLES2ImageApi::Create(createTextureImageSource(source, internalFormat, format, type))));
1317 void ImageTests::addCreateRenderbuffer (const string& name, GLenum format)
1319 m_createActions.add(name, MovePtr<Action>(new GLES2ImageApi::Create(createRenderbufferImageSource(format))));
1322 void ImageTests::addCreateAndroidNative (const string& name, GLenum format)
1324 m_createActions.add(name, MovePtr<Action>(new GLES2ImageApi::Create(createAndroidNativeImageSource(format))));
1327 void ImageTests::addCreateTexture2DActions (const string& prefix)
1329 addCreateTexture(prefix + "rgb8", EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1330 addCreateTexture(prefix + "rgb565", EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
1331 addCreateTexture(prefix + "rgba8", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1332 addCreateTexture(prefix + "rgb5_a1", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
1333 addCreateTexture(prefix + "rgba4", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
1336 void ImageTests::addCreateTextureCubemapActions (const string& suffix, GLenum internalFormat, GLenum format, GLenum type)
1338 addCreateTexture("cubemap_positive_x" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, internalFormat, format, type);
1339 addCreateTexture("cubemap_positive_y" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR, internalFormat, format, type);
1340 addCreateTexture("cubemap_positive_z" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR, internalFormat, format, type);
1341 addCreateTexture("cubemap_negative_x" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR, internalFormat, format, type);
1342 addCreateTexture("cubemap_negative_y" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR, internalFormat, format, type);
1343 addCreateTexture("cubemap_negative_z" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR, internalFormat, format, type);
1346 void ImageTests::addCreateRenderbufferActions (void)
1348 addCreateRenderbuffer("renderbuffer_rgba4", GL_RGBA4);
1349 addCreateRenderbuffer("renderbuffer_rgb5_a1", GL_RGB5_A1);
1350 addCreateRenderbuffer("renderbuffer_rgb565", GL_RGB565);
1351 addCreateRenderbuffer("renderbuffer_depth16", GL_DEPTH_COMPONENT16);
1352 addCreateRenderbuffer("renderbuffer_stencil", GL_STENCIL_INDEX8);
1355 void ImageTests::addCreateAndroidNativeActions (void)
1357 addCreateAndroidNative("android_native_rgba4", GL_RGBA4);
1358 addCreateAndroidNative("android_native_rgb5_a1", GL_RGB5_A1);
1359 addCreateAndroidNative("android_native_rgb565", GL_RGB565);
1360 addCreateAndroidNative("android_native_rgb8", GL_RGB8);
1361 addCreateAndroidNative("android_native_rgba8", GL_RGBA8);
1362 addCreateAndroidNative("android_native_d16", GL_DEPTH_COMPONENT16);
1363 addCreateAndroidNative("android_native_d24", GL_DEPTH_COMPONENT24);
1364 addCreateAndroidNative("android_native_d24s8", GL_DEPTH24_STENCIL8);
1365 addCreateAndroidNative("android_native_d32f", GL_DEPTH_COMPONENT32F);
1366 addCreateAndroidNative("android_native_d32fs8", GL_DEPTH32F_STENCIL8);
1367 addCreateAndroidNative("android_native_rgb10a2", GL_RGB10_A2);
1368 addCreateAndroidNative("android_native_rgba16f", GL_RGBA16F);
1369 addCreateAndroidNative("android_native_s8", GL_STENCIL_INDEX8);
1372 class RenderTests : public ImageTests
1375 RenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1376 : ImageTests (eglTestCtx, name, desc) {}
1378 void addRenderActions (void);
1379 LabeledActions m_renderActions;
1382 void RenderTests::addRenderActions (void)
1384 m_renderActions.add("texture", MovePtr<Action>(new GLES2ImageApi::RenderTexture2D()));
1385 m_renderActions.add("read_pixels", MovePtr<Action>(new GLES2ImageApi::RenderReadPixelsRenderbuffer()));
1386 m_renderActions.add("depth_buffer", MovePtr<Action>(new GLES2ImageApi::RenderDepthbuffer()));
1387 m_renderActions.add("stencil_buffer", MovePtr<Action>(new GLES2ImageApi::RenderStencilbuffer()));
1390 class SimpleCreationTests : public RenderTests
1393 SimpleCreationTests (EglTestContext& eglTestCtx, const string& name, const string& desc) : RenderTests(eglTestCtx, name, desc) {}
1397 bool isDepthFormat (GLenum format)
1412 case GL_DEPTH_COMPONENT16:
1413 case GL_DEPTH_COMPONENT24:
1414 case GL_DEPTH_COMPONENT32:
1415 case GL_DEPTH_COMPONENT32F:
1416 case GL_DEPTH24_STENCIL8:
1417 case GL_DEPTH32F_STENCIL8:
1420 case GL_STENCIL_INDEX8:
1429 bool isStencilFormat (GLenum format)
1444 case GL_DEPTH_COMPONENT16:
1445 case GL_DEPTH_COMPONENT24:
1446 case GL_DEPTH_COMPONENT32:
1447 case GL_DEPTH_COMPONENT32F:
1450 case GL_STENCIL_INDEX8:
1451 case GL_DEPTH24_STENCIL8:
1452 case GL_DEPTH32F_STENCIL8:
1461 bool isCompatibleCreateAndRenderActions (const Action& create, const Action& render)
1463 if (const GLES2ImageApi::Create* gles2Create = dynamic_cast<const GLES2ImageApi::Create*>(&create))
1465 const GLenum createFormat = gles2Create->getEffectiveFormat();
1467 if (dynamic_cast<const GLES2ImageApi::RenderTexture2D*>(&render))
1469 // GLES2 does not have depth or stencil textures
1470 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1474 if (dynamic_cast<const GLES2ImageApi::RenderReadPixelsRenderbuffer*>(&render))
1476 // GLES2 does not support readPixels for depth or stencil
1477 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1481 if (dynamic_cast<const GLES2ImageApi::RenderDepthbuffer*>(&render))
1483 // Copying non-depth data to depth renderbuffer and expecting meaningful
1484 // results just doesn't make any sense.
1485 if (!isDepthFormat(createFormat))
1489 if (dynamic_cast<const GLES2ImageApi::RenderStencilbuffer*>(&render))
1491 // Copying non-stencil data to stencil renderbuffer and expecting meaningful
1492 // results just doesn't make any sense.
1493 if (!isStencilFormat(createFormat))
1505 void SimpleCreationTests::init (void)
1507 addCreateTexture2DActions("texture_");
1508 addCreateTextureCubemapActions("_rgba", GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1509 addCreateTextureCubemapActions("_rgb", GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1510 addCreateRenderbufferActions();
1511 addCreateAndroidNativeActions();
1514 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
1516 const LabeledAction& createAction = m_createActions[createNdx];
1518 for (int renderNdx = 0; renderNdx < m_renderActions.size(); renderNdx++)
1520 const LabeledAction& renderAction = m_renderActions[renderNdx];
1523 if (!isCompatibleCreateAndRenderActions(*createAction.action, *renderAction.action))
1526 spec.name = std::string("gles2_") + createAction.label + "_" + renderAction.label;
1527 spec.desc = spec.name;
1528 spec.contexts.push_back(TestSpec::API_GLES2);
1529 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
1530 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
1532 addChild(new ImageFormatCase(m_eglTestCtx, spec));
1537 TestCaseGroup* createSimpleCreationTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1539 return new SimpleCreationTests(eglTestCtx, name, desc);
1542 bool isCompatibleFormats (GLenum createFormat, GLenum modifyFormat, GLenum modifyType)
1544 switch (modifyFormat)
1549 case GL_UNSIGNED_BYTE:
1550 return createFormat == GL_RGB
1551 || createFormat == GL_RGB8
1552 || createFormat == GL_RGB565
1553 || createFormat == GL_SRGB8;
1556 return createFormat == GL_RGB8_SNORM;
1558 case GL_UNSIGNED_SHORT_5_6_5:
1559 return createFormat == GL_RGB
1560 || createFormat == GL_RGB565;
1562 case GL_UNSIGNED_INT_10F_11F_11F_REV:
1563 return createFormat == GL_R11F_G11F_B10F;
1565 case GL_UNSIGNED_INT_5_9_9_9_REV:
1566 return createFormat == GL_RGB9_E5;
1569 return createFormat == GL_RGB16F
1570 || createFormat == GL_R11F_G11F_B10F
1571 || createFormat == GL_RGB9_E5;
1574 return createFormat == GL_RGB16F
1575 || createFormat == GL_RGB32F
1576 || createFormat == GL_R11F_G11F_B10F
1577 || createFormat == GL_RGB9_E5;
1580 DE_FATAL("Unknown modify type");
1587 case GL_UNSIGNED_BYTE:
1588 return createFormat == GL_RGBA8
1589 || createFormat == GL_RGB5_A1
1590 || createFormat == GL_RGBA4
1591 || createFormat == GL_SRGB8_ALPHA8
1592 || createFormat == GL_RGBA;
1594 case GL_UNSIGNED_SHORT_4_4_4_4:
1595 return createFormat == GL_RGBA4
1596 || createFormat == GL_RGBA;
1598 case GL_UNSIGNED_SHORT_5_5_5_1:
1599 return createFormat == GL_RGB5_A1
1600 || createFormat == GL_RGBA;
1602 case GL_UNSIGNED_INT_2_10_10_10_REV:
1603 return createFormat == GL_RGB10_A2
1604 || createFormat == GL_RGB5_A1;
1607 return createFormat == GL_RGBA16F;
1610 return createFormat == GL_RGBA16F
1611 || createFormat == GL_RGBA32F;
1614 DE_FATAL("Unknown modify type");
1619 DE_FATAL("Unknown modify format");
1624 bool isCompatibleCreateAndModifyActions (const Action& create, const Action& modify)
1626 if (const GLES2ImageApi::Create* gles2Create = dynamic_cast<const GLES2ImageApi::Create*>(&create))
1628 const GLenum createFormat = gles2Create->getEffectiveFormat();
1630 if (const GLES2ImageApi::ModifyTexSubImage* gles2TexSubImageModify = dynamic_cast<const GLES2ImageApi::ModifyTexSubImage*>(&modify))
1632 const GLenum modifyFormat = gles2TexSubImageModify->getFormat();
1633 const GLenum modifyType = gles2TexSubImageModify->getType();
1635 return isCompatibleFormats(createFormat, modifyFormat, modifyType);
1638 if (dynamic_cast<const GLES2ImageApi::ModifyRenderbufferClearColor*>(&modify))
1640 // reintepreting color as non-color is not meaningful
1641 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1645 if (dynamic_cast<const GLES2ImageApi::ModifyRenderbufferClearDepth*>(&modify))
1647 // reintepreting depth as non-depth is not meaningful
1648 if (!isDepthFormat(createFormat))
1652 if (dynamic_cast<const GLES2ImageApi::ModifyRenderbufferClearStencil*>(&modify))
1654 // reintepreting stencil as non-stencil is not meaningful
1655 if (!isStencilFormat(createFormat))
1667 class MultiContextRenderTests : public RenderTests
1670 MultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc);
1672 void addClearActions (void);
1674 LabeledActions m_clearActions;
1677 MultiContextRenderTests::MultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1678 : RenderTests (eglTestCtx, name, desc)
1682 void MultiContextRenderTests::addClearActions (void)
1684 m_clearActions.add("clear_color", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearColor(tcu::Vec4(0.8f, 0.2f, 0.9f, 1.0f))));
1685 m_clearActions.add("clear_depth", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearDepth(0.75f)));
1686 m_clearActions.add("clear_stencil", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearStencil(97)));
1689 void MultiContextRenderTests::init (void)
1691 addCreateTexture2DActions("texture_");
1692 addCreateTextureCubemapActions("_rgba8", GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1693 addCreateTextureCubemapActions("_rgb8", GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1694 addCreateRenderbufferActions();
1695 addCreateAndroidNativeActions();
1699 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
1700 for (int renderNdx = 0; renderNdx < m_renderActions.size(); renderNdx++)
1701 for (int clearNdx = 0; clearNdx < m_clearActions.size(); clearNdx++)
1703 const LabeledAction& createAction = m_createActions[createNdx];
1704 const LabeledAction& renderAction = m_renderActions[renderNdx];
1705 const LabeledAction& clearAction = m_clearActions[clearNdx];
1708 if (!isCompatibleCreateAndRenderActions(*createAction.action, *renderAction.action))
1710 if (!isCompatibleCreateAndModifyActions(*createAction.action, *clearAction.action))
1713 spec.name = std::string("gles2_") + createAction.label + "_" + renderAction.label;
1715 const GLES2ImageApi::Create* gles2Create = dynamic_cast<const GLES2ImageApi::Create*>(createAction.action.get());
1718 DE_FATAL("Dynamic casting to GLES2ImageApi::Create* failed");
1720 const GLenum createFormat = gles2Create->getEffectiveFormat();
1722 if (isDepthFormat(createFormat) && isStencilFormat(createFormat))
1724 // Combined depth and stencil format. Add the clear action label to avoid test
1726 spec.name += std::string("_") + clearAction.label;
1729 spec.desc = spec.name;
1731 spec.contexts.push_back(TestSpec::API_GLES2);
1732 spec.contexts.push_back(TestSpec::API_GLES2);
1734 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
1735 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
1736 spec.operations.push_back(TestSpec::Operation(0, *clearAction.action));
1737 spec.operations.push_back(TestSpec::Operation(1, *createAction.action));
1738 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
1739 spec.operations.push_back(TestSpec::Operation(1, *renderAction.action));
1741 addChild(new ImageFormatCase(m_eglTestCtx, spec));
1745 TestCaseGroup* createMultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1747 return new MultiContextRenderTests(eglTestCtx, name, desc);
1750 class ModifyTests : public ImageTests
1753 ModifyTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1754 : ImageTests(eglTestCtx, name, desc) {}
1759 void addModifyActions(void);
1761 LabeledActions m_modifyActions;
1762 GLES2ImageApi::RenderTryAll m_renderAction;
1765 void ModifyTests::addModifyActions (void)
1767 m_modifyActions.add("tex_subimage_rgb8", MovePtr<Action>(new GLES2ImageApi::ModifyTexSubImage(GL_RGB, GL_UNSIGNED_BYTE)));
1768 m_modifyActions.add("tex_subimage_rgb565", MovePtr<Action>(new GLES2ImageApi::ModifyTexSubImage(GL_RGB, GL_UNSIGNED_SHORT_5_6_5)));
1769 m_modifyActions.add("tex_subimage_rgba8", MovePtr<Action>(new GLES2ImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_BYTE)));
1770 m_modifyActions.add("tex_subimage_rgb5_a1", MovePtr<Action>(new GLES2ImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1)));
1771 m_modifyActions.add("tex_subimage_rgba4", MovePtr<Action>(new GLES2ImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4)));
1773 m_modifyActions.add("renderbuffer_clear_color", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearColor(tcu::Vec4(0.3f, 0.5f, 0.3f, 1.0f))));
1774 m_modifyActions.add("renderbuffer_clear_depth", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearDepth(0.7f)));
1775 m_modifyActions.add("renderbuffer_clear_stencil", MovePtr<Action>(new GLES2ImageApi::ModifyRenderbufferClearStencil(78)));
1778 void ModifyTests::init (void)
1780 addCreateTexture2DActions("tex_");
1781 addCreateRenderbufferActions();
1782 addCreateAndroidNativeActions();
1785 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
1787 LabeledAction& createAction = m_createActions[createNdx];
1789 for (int modifyNdx = 0; modifyNdx < m_modifyActions.size(); modifyNdx++)
1791 LabeledAction& modifyAction = m_modifyActions[modifyNdx];
1793 if (!isCompatibleCreateAndModifyActions(*createAction.action, *modifyAction.action))
1797 spec.name = createAction.label + "_" + modifyAction.label;
1798 spec.desc = "gles2_tex_sub_image";
1800 spec.contexts.push_back(TestSpec::API_GLES2);
1802 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
1803 spec.operations.push_back(TestSpec::Operation(0, m_renderAction));
1804 spec.operations.push_back(TestSpec::Operation(0, *modifyAction.action));
1805 spec.operations.push_back(TestSpec::Operation(0, m_renderAction));
1807 addChild(new ImageFormatCase(m_eglTestCtx, spec));
1812 TestCaseGroup* createModifyTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1814 return new ModifyTests(eglTestCtx, name, desc);