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;
142 Operation (int apiIndex_, const Action& action_) : apiIndex(apiIndex_), action(&action_) {}
144 const Action* action;
147 vector<ApiContext> contexts;
148 vector<Operation> operations;
155 ImageApi (const Library& egl, int contextId, EGLDisplay display, EGLSurface surface);
156 virtual ~ImageApi (void) {}
159 const Library& m_egl;
161 EGLDisplay m_display;
162 EGLSurface m_surface;
165 ImageApi::ImageApi (const Library& egl, int contextId, EGLDisplay display, EGLSurface surface)
167 , m_contextId (contextId)
168 , m_display (display)
169 , m_surface (surface)
173 class GLESImageApi : public ImageApi, private glu::CallLogWrapper
176 class GLESAction : public Action
179 bool invoke (ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
180 virtual bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const = 0;
183 class Create : public GLESAction
186 Create (MovePtr<ImageSource> imgSource, deUint32 numLayers = 1u) : m_imgSource(imgSource), m_numLayers(numLayers) {}
187 string getRequiredExtension (void) const { return m_imgSource->getRequiredExtension(); }
188 bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
189 deUint32 getNumLayers (void) const { return m_numLayers; }
190 glw::GLenum getEffectiveFormat (void) const { return m_imgSource->getEffectiveFormat(); }
193 UniquePtr<ImageSource> m_imgSource;
194 deUint32 m_numLayers;
197 class Render : public GLESAction
200 virtual string getRequiredExtension (void) const { return "GL_OES_EGL_image"; }
203 class RenderTexture2D : public Render { public: bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override; };
204 class RenderTextureCubemap : public Render { public: bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override; };
205 class RenderReadPixelsRenderbuffer : public Render { public: bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override; };
206 class RenderDepthbuffer : public Render { public: bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override; };
207 class RenderStencilbuffer : public Render { public: bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override; };
208 class RenderTryAll : public Render { public: bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override; };
210 class RenderTexture2DArray : public Render
213 bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override;
214 string getRequiredExtension (void) const override { return "GL_EXT_EGL_image_array"; }
217 class RenderExternalTexture : public Render
220 bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override;
221 string getRequiredExtension (void) const override { return "GL_OES_EGL_image_external"; }
224 class RenderExternalTextureSamplerArray : public Render
227 bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override;
228 string getRequiredExtension (void) const override { return "GL_OES_EGL_image_external"; }
231 class Modify : public GLESAction
234 string getRequiredExtension (void) const { return "GL_OES_EGL_image"; }
237 class ModifyTexSubImage : public Modify
240 ModifyTexSubImage (GLenum format, GLenum type) : m_format(format), m_type(type) {}
241 bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
242 GLenum getFormat (void) const { return m_format; }
243 GLenum getType (void) const { return m_type; }
250 class ModifyRenderbuffer : public Modify
253 bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
256 virtual void initializeRbo (GLESImageApi& api, GLuint rbo, tcu::Texture2D& ref) const = 0;
259 class ModifyRenderbufferClearColor : public ModifyRenderbuffer
262 ModifyRenderbufferClearColor (tcu::Vec4 color) : m_color(color) {}
265 void initializeRbo (GLESImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
270 class ModifyRenderbufferClearDepth : public ModifyRenderbuffer
273 ModifyRenderbufferClearDepth (GLfloat depth) : m_depth(depth) {}
276 void initializeRbo (GLESImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
281 class ModifyRenderbufferClearStencil : public ModifyRenderbuffer
284 ModifyRenderbufferClearStencil (GLint stencil) : m_stencil(stencil) {}
287 void initializeRbo (GLESImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
292 GLESImageApi (const Library& egl, const glw::Functions& gl, int contextId, tcu::TestLog& log, EGLDisplay display, EGLSurface surface, EGLConfig config, EGLint apiVersion);
293 ~GLESImageApi (void);
296 EGLContext m_context;
297 const glw::Functions& m_gl;
299 MovePtr<UniqueImage> createImage (const ImageSource& source, const ClientBuffer& buffer) const;
302 GLESImageApi::GLESImageApi (const Library& egl, const glw::Functions& gl, int contextId, tcu::TestLog& log, EGLDisplay display, EGLSurface surface, EGLConfig config, EGLint apiVersion)
303 : ImageApi (egl, contextId, display, surface)
304 , glu::CallLogWrapper (gl, log)
305 , m_context (DE_NULL)
308 const EGLint attriblist[] =
310 EGL_CONTEXT_CLIENT_VERSION, apiVersion,
314 EGLint configId = -1;
315 EGLU_CHECK_CALL(m_egl, getConfigAttrib(m_display, config, EGL_CONFIG_ID, &configId));
316 getLog() << tcu::TestLog::Message << "Creating gles" << apiVersion << " context with config id: " << configId << " context: " << m_contextId << tcu::TestLog::EndMessage;
317 egl.bindAPI(EGL_OPENGL_ES_API);
318 m_context = m_egl.createContext(m_display, config, EGL_NO_CONTEXT, attriblist);
319 EGLU_CHECK_MSG(m_egl, "Failed to create GLES context");
321 egl.makeCurrent(display, m_surface, m_surface, m_context);
322 EGLU_CHECK_MSG(m_egl, "Failed to make context current");
325 GLESImageApi::~GLESImageApi (void)
327 m_egl.makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
328 m_egl.destroyContext(m_display, m_context);
331 bool GLESImageApi::GLESAction::invoke (ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const
333 GLESImageApi& glesApi = dynamic_cast<GLESImageApi&>(api);
335 glesApi.m_egl.makeCurrent(glesApi.m_display, glesApi.m_surface, glesApi.m_surface, glesApi.m_context);
336 return invokeGLES(glesApi, image, ref);
339 bool GLESImageApi::Create::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const
341 de::UniquePtr<ClientBuffer> buffer (m_imgSource->createBuffer(api.m_egl, api.m_gl, &ref));
343 GLU_CHECK_GLW_CALL(api.m_gl, finish());
345 image = api.createImage(*m_imgSource, *buffer);
349 MovePtr<UniqueImage> GLESImageApi::createImage (const ImageSource& source, const ClientBuffer& buffer) const
351 const EGLImageKHR image = source.createImage(m_egl, m_display, m_context, buffer.get());
352 return MovePtr<UniqueImage>(new UniqueImage(m_egl, m_display, image));
355 static void imageTargetTexture2D (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
357 gl.eglImageTargetTexture2DOES(GL_TEXTURE_2D, img);
359 const GLenum error = gl.getError();
361 if (error == GL_INVALID_OPERATION)
362 TCU_THROW(NotSupportedError, "Creating texture2D from EGLImage type not supported");
364 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
365 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
369 static void imageTargetExternalTexture (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
371 gl.eglImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, img);
373 const GLenum error = gl.getError();
375 if (error == GL_INVALID_OPERATION)
376 TCU_THROW(NotSupportedError, "Creating external texture from EGLImage type not supported");
378 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
379 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
383 static void imageTargetTexture2DArray (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
385 gl.eglImageTargetTexture2DOES(GL_TEXTURE_2D_ARRAY, img);
387 const GLenum error = gl.getError();
389 if (error == GL_INVALID_OPERATION)
390 TCU_THROW(NotSupportedError, "Creating texture2D array from EGLImage type not supported");
392 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
393 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
397 static void imageTargetRenderbuffer (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
399 gl.eglImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, img);
401 const GLenum error = gl.getError();
403 if (error == GL_INVALID_OPERATION)
404 TCU_THROW(NotSupportedError, "Creating renderbuffer from EGLImage type not supported");
406 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetRenderbufferStorageOES()");
407 EGLU_CHECK_MSG(egl, "glEGLImageTargetRenderbufferStorageOES()");
411 static void framebufferRenderbuffer (const glw::Functions& gl, GLenum attachment, GLuint rbo)
413 GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rbo));
414 TCU_CHECK_AND_THROW(NotSupportedError,
415 gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
416 ("EGLImage as " + string(glu::getFramebufferAttachmentName(attachment)) + " not supported").c_str());
419 static const float squareTriangleCoords[] =
430 bool GLESImageApi::RenderTexture2D::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
432 const glw::Functions& gl = api.m_gl;
433 tcu::TestLog& log = api.getLog();
436 // Branch only taken in TryAll case
437 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
438 throw IllegalRendererException(); // Skip, GLES does not support sampling depth textures
439 if (reference.getFormat().order == tcu::TextureFormat::S)
440 throw IllegalRendererException(); // Skip, GLES does not support sampling stencil textures
442 gl.clearColor(0.0, 0.0, 0.0, 0.0);
443 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
444 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
445 gl.disable(GL_DEPTH_TEST);
447 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_2D in context: " << api.m_contextId << tcu::TestLog::EndMessage;
448 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
450 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
451 imageTargetTexture2D(api.m_egl, gl, **img);
453 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
454 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
455 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
456 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
458 const char* const vertexShader =
459 "attribute highp vec2 a_coord;\n"
460 "varying mediump vec2 v_texCoord;\n"
461 "void main(void) {\n"
462 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
463 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
466 const char* const fragmentShader =
467 "varying mediump vec2 v_texCoord;\n"
468 "uniform sampler2D u_sampler;\n"
469 "void main(void) {\n"
470 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
471 "\tgl_FragColor = vec4(texColor);\n"
474 Program program(gl, vertexShader, fragmentShader);
475 TCU_CHECK(program.isOk());
477 GLuint glProgram = program.getProgram();
478 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
480 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
481 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
483 GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
484 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
486 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
487 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
488 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
489 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
491 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
492 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
493 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, 0));
495 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
496 tcu::Surface screen (reference.getWidth(), reference.getHeight());
497 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
499 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
501 float threshold = 0.05f;
502 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
507 // Renders using a single layer from a texture array.
508 bool GLESImageApi::RenderTexture2DArray::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
510 const glw::Functions& gl = api.m_gl;
511 tcu::TestLog& log = api.getLog();
514 gl.clearColor(0.0, 0.0, 0.0, 0.0);
515 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
516 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
517 gl.disable(GL_DEPTH_TEST);
519 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_2D_ARRAY in context: " << api.m_contextId << tcu::TestLog::EndMessage;
520 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
522 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D_ARRAY, *srcTex));
523 imageTargetTexture2DArray(api.m_egl, gl, **img);
525 glu::TransferFormat transferFormat = glu::getTransferFormat(reference.getFormat());
526 // Initializes layer 1.
527 GLU_CHECK_GLW_CALL(gl, texSubImage3D(GL_TEXTURE_2D_ARRAY,
531 1, // Z offset (layer)
532 reference.getWidth(), // Width
533 reference.getHeight(), // Height
535 transferFormat.format, // Format
536 transferFormat.dataType, // Type
537 reference.getLevel(0).getDataPtr())); // Pixel data
540 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
541 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
542 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
543 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
545 const char* const vertexShader =
547 "precision highp int;\n"
548 "precision highp float;\n"
549 "layout(location = 0) in vec2 pos_in;\n"
550 "layout(location = 0) out vec2 texcoord_out;\n"
553 " gl_Position = vec4(pos_in, -0.1, 1.0);\n"
554 " texcoord_out = vec2((pos_in.x + 1.0) * 0.5, (pos_in.y + 1.0) * 0.5);\n"
557 const char* const fragmentShader =
559 "precision highp int;\n"
560 "precision highp float;\n"
561 "layout(location = 0) in vec2 texcoords_in;\n"
562 "layout(location = 0) out vec4 color_out;\n"
563 "uniform layout(binding=0) highp sampler2DArray tex_sampler;\n"
567 " color_out = texture(tex_sampler, vec3(texcoords_in, 1));\n"
570 Program program(gl, vertexShader, fragmentShader);
574 log << tcu::TestLog::Message << "Shader build failed.\n"
575 << "Vertex: " << program.getShaderInfo(glu::SHADERTYPE_VERTEX).infoLog << "\n"
576 << vertexShader << "\n"
577 << "Fragment: " << program.getShaderInfo(glu::SHADERTYPE_FRAGMENT).infoLog << "\n"
578 << fragmentShader << "\n"
579 << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
582 TCU_CHECK(program.isOk());
584 GLuint glProgram = program.getProgram();
585 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
587 GLuint coordLoc = gl.getAttribLocation(glProgram, "pos_in");
588 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute pos_in");
590 GLuint samplerLoc = gl.getUniformLocation(glProgram, "tex_sampler");
591 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform tex_sampler");
593 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D_ARRAY, *srcTex));
594 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
595 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
596 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
598 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
599 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
601 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
602 tcu::Surface screen (reference.getWidth(), reference.getHeight());
603 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
605 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
607 float threshold = 0.05f;
608 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
613 bool GLESImageApi::RenderExternalTexture::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
615 const glw::Functions& gl = api.m_gl;
616 tcu::TestLog& log = api.getLog();
619 // Branch only taken in TryAll case
620 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
621 throw IllegalRendererException(); // Skip, GLES2 does not support sampling depth textures
622 if (reference.getFormat().order == tcu::TextureFormat::S)
623 throw IllegalRendererException(); // Skip, GLES2 does not support sampling stencil textures
625 gl.clearColor(0.0, 0.0, 0.0, 0.0);
626 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
627 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
628 gl.disable(GL_DEPTH_TEST);
630 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_EXTERNAL_OES in context: " << api.m_contextId << tcu::TestLog::EndMessage;
631 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
633 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
634 imageTargetExternalTexture(api.m_egl, gl, **img);
636 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
637 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
638 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
639 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
641 const char* const vertexShader =
642 "attribute highp vec2 a_coord;\n"
643 "varying mediump vec2 v_texCoord;\n"
644 "void main(void) {\n"
645 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
646 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
649 const char* const fragmentShader =
650 "#extension GL_OES_EGL_image_external : require\n"
651 "varying mediump vec2 v_texCoord;\n"
652 "uniform samplerExternalOES u_sampler;\n"
653 "void main(void) {\n"
654 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
655 "\tgl_FragColor = vec4(texColor);\n"
658 Program program(gl, vertexShader, fragmentShader);
659 TCU_CHECK(program.isOk());
661 GLuint glProgram = program.getProgram();
662 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
664 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
665 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
667 GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
668 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
670 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
671 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
672 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
673 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
675 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
676 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
677 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
679 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
680 tcu::Surface screen (reference.getWidth(), reference.getHeight());
681 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
683 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
685 float threshold = 0.05f;
686 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
691 bool GLESImageApi::RenderExternalTextureSamplerArray::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
693 const glw::Functions& gl = api.m_gl;
694 tcu::TestLog& log = api.getLog();
697 // Branch only taken in TryAll case
698 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
699 throw IllegalRendererException(); // Skip, GLES2 does not support sampling depth textures
700 if (reference.getFormat().order == tcu::TextureFormat::S)
701 throw IllegalRendererException(); // Skip, GLES2 does not support sampling stencil textures
703 gl.clearColor(0.0, 0.0, 0.0, 0.0);
704 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
705 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
706 gl.disable(GL_DEPTH_TEST);
708 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_EXTERNAL_OES using sampler array in context: " << api.m_contextId << tcu::TestLog::EndMessage;
709 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
711 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
712 imageTargetExternalTexture(api.m_egl, gl, **img);
714 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
715 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
716 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
717 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
719 // Texture not associated with an external texture will return (0, 0, 0, 1) when sampled.
721 gl.genTextures(1, &emptyTex);
722 gl.activeTexture(GL_TEXTURE1);
723 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, emptyTex));
725 const char* const vertexShader =
726 "attribute highp vec2 a_coord;\n"
727 "varying mediump vec2 v_texCoord;\n"
728 "void main(void) {\n"
729 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
730 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
733 const char* const fragmentShader =
734 "#extension GL_OES_EGL_image_external : require\n"
735 "varying mediump vec2 v_texCoord;\n"
736 "uniform samplerExternalOES u_sampler[4];\n"
737 "void main(void) {\n"
738 "\tmediump vec4 texColor = texture2D(u_sampler[2], v_texCoord);\n"
739 "\t//These will sample (0, 0, 0, 1) and should not affect the results.\n"
740 "\ttexColor += texture2D(u_sampler[0], v_texCoord) - vec4(0, 0, 0, 1);\n"
741 "\ttexColor += texture2D(u_sampler[1], v_texCoord) - vec4(0, 0, 0, 1);\n"
742 "\ttexColor += texture2D(u_sampler[3], v_texCoord) - vec4(0, 0, 0, 1);\n"
743 "\tgl_FragColor = vec4(texColor);\n"
746 Program program(gl, vertexShader, fragmentShader);
747 TCU_CHECK(program.isOk());
749 GLuint glProgram = program.getProgram();
750 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
752 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
753 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
755 GLuint samplerLoc0 = gl.getUniformLocation(glProgram, "u_sampler[0]");
756 TCU_CHECK_MSG((int)samplerLoc0 != (int)-1, "Couldn't find uniform u_sampler[0]");
757 GLuint samplerLoc1 = gl.getUniformLocation(glProgram, "u_sampler[1]");
758 TCU_CHECK_MSG((int)samplerLoc1 != (int)-1, "Couldn't find uniform u_sampler[1]");
759 GLuint samplerLoc2 = gl.getUniformLocation(glProgram, "u_sampler[2]");
760 TCU_CHECK_MSG((int)samplerLoc2 != (int)-1, "Couldn't find uniform u_sampler[2]");
761 GLuint samplerLoc3 = gl.getUniformLocation(glProgram, "u_sampler[3]");
762 TCU_CHECK_MSG((int)samplerLoc3 != (int)-1, "Couldn't find uniform u_sampler[3]");
764 gl.activeTexture(GL_TEXTURE0);
765 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
766 // One sampler reads a gradient and others opaque black.
767 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc0, 1));
768 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc1, 1));
769 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc2, 0));
770 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc3, 1));
771 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
772 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
774 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
775 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
776 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
777 gl.activeTexture(GL_TEXTURE1);
778 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
779 gl.deleteTextures(1, &emptyTex);
780 gl.activeTexture(GL_TEXTURE0);
782 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
783 tcu::Surface screen (reference.getWidth(), reference.getHeight());
784 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
786 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
788 float threshold = 0.05f;
789 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
794 bool GLESImageApi::RenderDepthbuffer::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
796 const glw::Functions& gl = api.m_gl;
797 tcu::TestLog& log = api.getLog();
798 Framebuffer framebuffer (gl);
799 Renderbuffer renderbufferColor (gl);
800 Renderbuffer renderbufferDepth (gl);
801 const tcu::RGBA compareThreshold (32, 32, 32, 32); // layer colors are far apart, large thresholds are ok
803 // Branch only taken in TryAll case
804 if (reference.getFormat().order != tcu::TextureFormat::DS && reference.getFormat().order != tcu::TextureFormat::D)
805 throw IllegalRendererException(); // Skip, interpreting non-depth data as depth data is not meaningful
807 log << tcu::TestLog::Message << "Rendering with depth buffer" << tcu::TestLog::EndMessage;
809 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
811 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferColor));
812 GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight()));
813 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbufferColor);
815 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferDepth));
816 imageTargetRenderbuffer(api.m_egl, gl, **img);
817 framebufferRenderbuffer(gl, GL_DEPTH_ATTACHMENT, *renderbufferDepth);
818 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
820 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
823 const char* vertexShader =
824 "attribute highp vec2 a_coord;\n"
825 "uniform highp float u_depth;\n"
826 "void main(void) {\n"
827 "\tgl_Position = vec4(a_coord, u_depth, 1.0);\n"
830 const char* fragmentShader =
831 "uniform mediump vec4 u_color;\n"
832 "void main(void) {\n"
833 "\tgl_FragColor = u_color;\n"
836 Program program(gl, vertexShader, fragmentShader);
837 TCU_CHECK(program.isOk());
839 GLuint glProgram = program.getProgram();
840 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
842 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
843 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
845 GLuint colorLoc = gl.getUniformLocation(glProgram, "u_color");
846 TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color");
848 GLuint depthLoc = gl.getUniformLocation(glProgram, "u_depth");
849 TCU_CHECK_MSG((int)depthLoc != (int)-1, "Couldn't find uniform u_depth");
851 GLU_CHECK_GLW_CALL(gl, clearColor(0.5f, 1.0f, 0.5f, 1.0f));
852 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
854 tcu::Vec4 depthLevelColors[] = {
855 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
856 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
857 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
858 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
859 tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
861 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
862 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
863 tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f),
864 tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f),
865 tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)
868 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
869 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
871 GLU_CHECK_GLW_CALL(gl, enable(GL_DEPTH_TEST));
872 GLU_CHECK_GLW_CALL(gl, depthFunc(GL_LESS));
873 GLU_CHECK_GLW_CALL(gl, depthMask(GL_FALSE));
875 for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevelColors); level++)
877 const tcu::Vec4 color = depthLevelColors[level];
878 const float clipDepth = ((float)(level + 1) * 0.1f) * 2.0f - 1.0f; // depth in clip coords
880 GLU_CHECK_GLW_CALL(gl, uniform4f(colorLoc, color.x(), color.y(), color.z(), color.w()));
881 GLU_CHECK_GLW_CALL(gl, uniform1f(depthLoc, clipDepth));
882 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
885 GLU_CHECK_GLW_CALL(gl, depthMask(GL_TRUE));
886 GLU_CHECK_GLW_CALL(gl, disable(GL_DEPTH_TEST));
887 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
889 const ConstPixelBufferAccess& refAccess = reference.getLevel(0);
890 tcu::Surface screen (reference.getWidth(), reference.getHeight());
891 tcu::Surface referenceScreen (reference.getWidth(), reference.getHeight());
893 gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
895 for (int y = 0; y < reference.getHeight(); y++)
897 for (int x = 0; x < reference.getWidth(); x++)
899 tcu::Vec4 result = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f);
901 for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevelColors); level++)
903 if ((float)(level + 1) * 0.1f < refAccess.getPixDepth(x, y))
904 result = depthLevelColors[level];
907 referenceScreen.getAccess().setPixel(result, x, y);
911 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
912 GLU_CHECK_GLW_CALL(gl, finish());
914 return tcu::pixelThresholdCompare(log, "Depth buffer rendering result", "Result from rendering with depth buffer", referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT);
917 bool GLESImageApi::RenderStencilbuffer::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
919 // Branch only taken in TryAll case
920 if (reference.getFormat().order != tcu::TextureFormat::DS && reference.getFormat().order != tcu::TextureFormat::S)
921 throw IllegalRendererException(); // Skip, interpreting non-stencil data as stencil data is not meaningful
923 const glw::Functions& gl = api.m_gl;
924 tcu::TestLog& log = api.getLog();
925 Framebuffer framebuffer (gl);
926 Renderbuffer renderbufferColor (gl);
927 Renderbuffer renderbufferStencil (gl);
928 const tcu::RGBA compareThreshold (32, 32, 32, 32); // layer colors are far apart, large thresholds are ok
929 const deUint32 numStencilBits = tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(reference.getLevel(0).getFormat(), tcu::Sampler::MODE_STENCIL)).x();
930 const deUint32 maxStencil = deBitMask32(0, numStencilBits);
932 log << tcu::TestLog::Message << "Rendering with stencil buffer" << tcu::TestLog::EndMessage;
934 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
936 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferColor));
937 GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight()));
938 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbufferColor);
940 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferStencil));
941 imageTargetRenderbuffer(api.m_egl, gl, **img);
942 framebufferRenderbuffer(gl, GL_STENCIL_ATTACHMENT, *renderbufferStencil);
943 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
945 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
948 const char* vertexShader =
949 "attribute highp vec2 a_coord;\n"
950 "void main(void) {\n"
951 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
954 const char* fragmentShader =
955 "uniform mediump vec4 u_color;\n"
956 "void main(void) {\n"
957 "\tgl_FragColor = u_color;\n"
960 Program program(gl, vertexShader, fragmentShader);
961 TCU_CHECK(program.isOk());
963 GLuint glProgram = program.getProgram();
964 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
966 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
967 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
969 GLuint colorLoc = gl.getUniformLocation(glProgram, "u_color");
970 TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color");
972 GLU_CHECK_GLW_CALL(gl, clearColor(0.5f, 1.0f, 0.5f, 1.0f));
973 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
975 tcu::Vec4 stencilLevelColors[] = {
976 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
977 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
978 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
979 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
980 tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
982 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
983 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
984 tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f),
985 tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f),
986 tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)
989 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
990 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
992 GLU_CHECK_GLW_CALL(gl, enable(GL_STENCIL_TEST));
993 GLU_CHECK_GLW_CALL(gl, stencilOp(GL_KEEP, GL_KEEP, GL_KEEP));
995 for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++)
997 const tcu::Vec4 color = stencilLevelColors[level];
998 const int stencil = (int)(((float)(level + 1) * 0.1f) * (float)maxStencil);
1000 GLU_CHECK_GLW_CALL(gl, stencilFunc(GL_LESS, stencil, 0xFFFFFFFFu));
1001 GLU_CHECK_GLW_CALL(gl, uniform4f(colorLoc, color.x(), color.y(), color.z(), color.w()));
1002 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
1005 GLU_CHECK_GLW_CALL(gl, disable(GL_STENCIL_TEST));
1006 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
1008 const ConstPixelBufferAccess& refAccess = reference.getLevel(0);
1009 tcu::Surface screen (reference.getWidth(), reference.getHeight());
1010 tcu::Surface referenceScreen (reference.getWidth(), reference.getHeight());
1012 gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
1014 for (int y = 0; y < reference.getHeight(); y++)
1015 for (int x = 0; x < reference.getWidth(); x++)
1017 tcu::Vec4 result = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f);
1019 for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++)
1021 const int levelStencil = (int)(((float)(level + 1) * 0.1f) * (float)maxStencil);
1022 if (levelStencil < refAccess.getPixStencil(x, y))
1023 result = stencilLevelColors[level];
1026 referenceScreen.getAccess().setPixel(result, x, y);
1029 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1030 GLU_CHECK_GLW_CALL(gl, finish());
1032 return tcu::pixelThresholdCompare(log, "StencilResult", "Result from rendering with stencil buffer", referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT);
1035 bool GLESImageApi::RenderReadPixelsRenderbuffer::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
1037 switch (glu::getInternalFormat(reference.getFormat()))
1044 // Skip, not in the list of allowed render buffer formats for GLES.
1045 throw tcu::NotSupportedError("Image format not allowed for glReadPixels.");
1049 const glw::Functions& gl = api.m_gl;
1050 const tcu::IVec4 bitDepth = tcu::getTextureFormatMantissaBitDepth(reference.getFormat());
1051 const tcu::IVec4 threshold (2 * (tcu::IVec4(1) << (tcu::IVec4(8) - bitDepth)));
1052 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)));
1053 tcu::TestLog& log = api.getLog();
1054 Framebuffer framebuffer (gl);
1055 Renderbuffer renderbuffer (gl);
1056 tcu::Surface screen (reference.getWidth(), reference.getHeight());
1057 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
1059 log << tcu::TestLog::Message << "Reading with ReadPixels from renderbuffer" << tcu::TestLog::EndMessage;
1061 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
1062 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer));
1063 imageTargetRenderbuffer(api.m_egl, gl, **img);
1065 GLU_EXPECT_NO_ERROR(gl.getError(), "imageTargetRenderbuffer");
1066 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbuffer);
1067 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferRenderbuffer");
1069 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1071 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
1073 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1074 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
1075 GLU_CHECK_GLW_CALL(gl, finish());
1077 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
1079 return tcu::pixelThresholdCompare(log, "Renderbuffer read", "Result from reading renderbuffer", refSurface, screen, threshold8, tcu::COMPARE_LOG_RESULT);
1083 bool GLESImageApi::RenderTryAll::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
1085 bool foundSupported = false;
1086 tcu::TestLog& log = api.getLog();
1087 GLESImageApi::RenderTexture2D renderTex2D;
1088 GLESImageApi::RenderExternalTexture renderExternal;
1089 GLESImageApi::RenderExternalTextureSamplerArray renderExternalSamplerArray;
1090 GLESImageApi::RenderReadPixelsRenderbuffer renderReadPixels;
1091 GLESImageApi::RenderDepthbuffer renderDepth;
1092 GLESImageApi::RenderStencilbuffer renderStencil;
1093 Action* actions[] = { &renderTex2D, &renderExternal, &renderExternalSamplerArray, &renderReadPixels, &renderDepth, &renderStencil };
1095 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(actions); ++ndx)
1099 if (!actions[ndx]->invoke(api, img, reference))
1102 foundSupported = true;
1104 catch (const tcu::NotSupportedError& error)
1106 log << tcu::TestLog::Message << error.what() << tcu::TestLog::EndMessage;
1108 catch (const IllegalRendererException&)
1110 // not valid renderer
1114 if (!foundSupported)
1115 throw tcu::NotSupportedError("Rendering not supported", "", __FILE__, __LINE__);
1120 bool GLESImageApi::ModifyTexSubImage::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
1122 const glw::Functions& gl = api.m_gl;
1123 tcu::TestLog& log = api.getLog();
1124 glu::Texture srcTex (gl);
1125 const int xOffset = 8;
1126 const int yOffset = 16;
1127 const int xSize = de::clamp(16, 0, reference.getWidth() - xOffset);
1128 const int ySize = de::clamp(16, 0, reference.getHeight() - yOffset);
1129 tcu::Texture2D src (glu::mapGLTransferFormat(m_format, m_type), xSize, ySize);
1131 log << tcu::TestLog::Message << "Modifying EGLImage with gl.texSubImage2D" << tcu::TestLog::EndMessage;
1134 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));
1136 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
1137 imageTargetTexture2D(api.m_egl, gl, **img);
1138 GLU_CHECK_GLW_CALL(gl, texSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, src.getWidth(), src.getHeight(), m_format, m_type, src.getLevel(0).getDataPtr()));
1139 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, 0));
1140 GLU_CHECK_GLW_CALL(gl, finish());
1142 tcu::copy(tcu::getSubregion(reference.getLevel(0), xOffset, yOffset, 0, xSize, ySize, 1), src.getLevel(0));
1147 bool GLESImageApi::ModifyRenderbuffer::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
1149 const glw::Functions& gl = api.m_gl;
1150 tcu::TestLog& log = api.getLog();
1151 glu::Framebuffer framebuffer (gl);
1152 glu::Renderbuffer renderbuffer (gl);
1154 log << tcu::TestLog::Message << "Modifying EGLImage with glClear to renderbuffer" << tcu::TestLog::EndMessage;
1156 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
1157 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer));
1159 imageTargetRenderbuffer(api.m_egl, gl, **img);
1161 initializeRbo(api, *renderbuffer, reference);
1163 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1164 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
1166 GLU_CHECK_GLW_CALL(gl, finish());
1171 void GLESImageApi::ModifyRenderbufferClearColor::initializeRbo (GLESImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
1173 const glw::Functions& gl = api.m_gl;
1175 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, renderbuffer);
1177 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1178 GLU_CHECK_GLW_CALL(gl, clearColor(m_color.x(), m_color.y(), m_color.z(), m_color.w()));
1179 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
1181 tcu::clear(reference.getLevel(0), m_color);
1184 void GLESImageApi::ModifyRenderbufferClearDepth::initializeRbo (GLESImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
1186 const glw::Functions& gl = api.m_gl;
1188 framebufferRenderbuffer(gl, GL_DEPTH_ATTACHMENT, renderbuffer);
1190 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1191 GLU_CHECK_GLW_CALL(gl, clearDepthf(m_depth));
1192 GLU_CHECK_GLW_CALL(gl, clear(GL_DEPTH_BUFFER_BIT));
1194 tcu::clearDepth(reference.getLevel(0), m_depth);
1197 void GLESImageApi::ModifyRenderbufferClearStencil::initializeRbo (GLESImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
1199 const glw::Functions& gl = api.m_gl;
1201 framebufferRenderbuffer(gl, GL_STENCIL_ATTACHMENT, renderbuffer);
1203 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1204 GLU_CHECK_GLW_CALL(gl, clearStencil(m_stencil));
1205 GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT));
1207 tcu::clearStencil(reference.getLevel(0), m_stencil);
1210 class ImageFormatCase : public TestCase, private glu::CallLogWrapper
1213 ImageFormatCase (EglTestContext& eglTestCtx, const TestSpec& spec);
1214 ~ImageFormatCase (void);
1218 IterateResult iterate (void);
1219 void checkExtensions (void);
1222 EGLConfig getConfig (void);
1224 const TestSpec m_spec;
1226 vector<ImageApi*> m_apiContexts;
1228 EGLDisplay m_display;
1229 eglu::NativeWindow* m_window;
1230 EGLSurface m_surface;
1233 MovePtr<UniqueImage> m_img;
1234 tcu::Texture2D m_refImg;
1235 glw::Functions m_gl;
1238 EGLConfig ImageFormatCase::getConfig (void)
1240 const GLint glesApi = m_spec.contexts[0] == TestSpec::API_GLES3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
1241 const EGLint attribList[] =
1243 EGL_RENDERABLE_TYPE, glesApi,
1244 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
1253 return eglu::chooseSingleConfig(m_eglTestCtx.getLibrary(), m_display, attribList);
1256 ImageFormatCase::ImageFormatCase (EglTestContext& eglTestCtx, const TestSpec& spec)
1257 : TestCase (eglTestCtx, spec.name.c_str(), spec.desc.c_str())
1258 , glu::CallLogWrapper (m_gl, eglTestCtx.getTestContext().getLog())
1260 , m_display (EGL_NO_DISPLAY)
1261 , m_window (DE_NULL)
1262 , m_surface (EGL_NO_SURFACE)
1265 , m_refImg (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1)
1269 ImageFormatCase::~ImageFormatCase (void)
1274 void ImageFormatCase::checkExtensions (void)
1276 const Library& egl = m_eglTestCtx.getLibrary();
1277 const EGLDisplay dpy = m_display;
1279 const vector<string> glExts = de::splitString((const char*) m_gl.getString(GL_EXTENSIONS));
1280 const vector<string> eglExts = eglu::getDisplayExtensions(egl, dpy);
1282 exts.insert(glExts.begin(), glExts.end());
1283 exts.insert(eglExts.begin(), eglExts.end());
1285 if (eglu::getVersion(egl, dpy) >= eglu::Version(1, 5))
1287 // EGL 1.5 has built-in support for EGLImage and GL sources
1288 exts.insert("EGL_KHR_image_base");
1289 exts.insert("EGL_KHR_gl_texture_2D_image");
1290 exts.insert("EGL_KHR_gl_texture_cubemap_image");
1291 exts.insert("EGL_KHR_gl_renderbuffer_image");
1294 if (!de::contains(exts, "EGL_KHR_image_base") && !de::contains(exts, "EGL_KHR_image"))
1296 getLog() << tcu::TestLog::Message
1297 << "EGL version is under 1.5 and neither EGL_KHR_image nor EGL_KHR_image_base is supported."
1298 << "One should be supported."
1299 << tcu::TestLog::EndMessage;
1300 TCU_THROW(NotSupportedError, "Extension not supported: EGL_KHR_image_base");
1303 for (int operationNdx = 0; operationNdx < (int)m_spec.operations.size(); operationNdx++)
1305 const TestSpec::Operation& op = m_spec.operations[operationNdx];
1306 const string ext = op.action->getRequiredExtension();
1308 if (!de::contains(exts, ext))
1309 TCU_THROW_EXPR(NotSupportedError, "Extension not supported", ext.c_str());
1313 void ImageFormatCase::init (void)
1315 const Library& egl = m_eglTestCtx.getLibrary();
1316 const eglu::NativeWindowFactory& windowFactory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
1320 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
1321 m_config = getConfig();
1322 m_window = windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL, eglu::WindowParams(480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine())));
1323 m_surface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_display, m_config, DE_NULL);
1326 const char* extensions[] = { "GL_OES_EGL_image" };
1330 if (m_spec.contexts[0] == TestSpec::API_GLES3)
1335 m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(major, minor), DE_LENGTH_OF_ARRAY(extensions), &extensions[0]);
1338 for (int contextNdx = 0; contextNdx < (int)m_spec.contexts.size(); contextNdx++)
1340 ImageApi* api = DE_NULL;
1341 switch (m_spec.contexts[contextNdx])
1343 case TestSpec::API_GLES2:
1345 api = new GLESImageApi(egl, m_gl, contextNdx, getLog(), m_display, m_surface, m_config, 2);
1349 case TestSpec::API_GLES3:
1351 api = new GLESImageApi(egl, m_gl, contextNdx, getLog(), m_display, m_surface, m_config, 3);
1359 m_apiContexts.push_back(api);
1370 void ImageFormatCase::deinit (void)
1372 const Library& egl = m_eglTestCtx.getLibrary();
1376 for (int contexNdx = 0 ; contexNdx < (int)m_apiContexts.size(); contexNdx++)
1377 delete m_apiContexts[contexNdx];
1379 m_apiContexts.clear();
1381 if (m_surface != EGL_NO_SURFACE)
1383 egl.destroySurface(m_display, m_surface);
1384 m_surface = EGL_NO_SURFACE;
1390 if (m_display != EGL_NO_DISPLAY)
1392 egl.terminate(m_display);
1393 m_display = EGL_NO_DISPLAY;
1397 TestCase::IterateResult ImageFormatCase::iterate (void)
1399 const TestSpec::Operation& op = m_spec.operations[m_curIter++];
1400 ImageApi& api = *m_apiContexts[op.apiIndex];
1401 const bool isOk = op.action->invoke(api, m_img, m_refImg);
1403 if (isOk && m_curIter < (int)m_spec.operations.size())
1406 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1408 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1413 struct LabeledAction
1416 MovePtr<Action> action;
1419 // A simple vector mockup that we need because MovePtr isn't copy-constructible.
1420 struct LabeledActions
1422 LabeledActions (void) : m_numActions(0){}
1423 LabeledAction& operator[] (int ndx) { DE_ASSERT(0 <= ndx && ndx < m_numActions); return m_actions[ndx]; }
1424 void add (const string& label, MovePtr<Action> action);
1425 int size (void) const { return m_numActions; }
1427 LabeledAction m_actions[64];
1431 void LabeledActions::add (const string& label, MovePtr<Action> action)
1433 DE_ASSERT(m_numActions < DE_LENGTH_OF_ARRAY(m_actions));
1434 m_actions[m_numActions].label = label;
1435 m_actions[m_numActions].action = action;
1439 class ImageTests : public TestCaseGroup
1442 ImageTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1443 : TestCaseGroup(eglTestCtx, name.c_str(), desc.c_str()) {}
1445 void addCreateTexture (const string& name, EGLenum source, GLenum internalFormat, GLenum format, GLenum type);
1446 void addCreateRenderbuffer (const string& name, GLenum format);
1447 void addCreateAndroidNative (const string& name, GLenum format);
1448 void addCreateAndroidNativeArray (const string& name, GLenum format, deUint32 numLayers);
1449 void addCreateTexture2DActions (const string& prefix);
1450 void addCreateTextureCubemapActions (const string& suffix, GLenum internalFormat, GLenum format, GLenum type);
1451 void addCreateRenderbufferActions (void);
1452 void addCreateAndroidNativeActions (void);
1454 LabeledActions m_createActions;
1457 void ImageTests::addCreateTexture (const string& name, EGLenum source, GLenum internalFormat, GLenum format, GLenum type)
1459 m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createTextureImageSource(source, internalFormat, format, type))));
1462 void ImageTests::addCreateRenderbuffer (const string& name, GLenum format)
1464 m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createRenderbufferImageSource(format))));
1467 void ImageTests::addCreateAndroidNative (const string& name, GLenum format)
1469 m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createAndroidNativeImageSource(format, 1u))));
1472 void ImageTests::addCreateAndroidNativeArray (const string& name, GLenum format, deUint32 numLayers)
1474 m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createAndroidNativeImageSource(format, numLayers), numLayers)));
1477 void ImageTests::addCreateTexture2DActions (const string& prefix)
1479 addCreateTexture(prefix + "rgb8", EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1480 addCreateTexture(prefix + "rgb565", EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
1481 addCreateTexture(prefix + "rgba8", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1482 addCreateTexture(prefix + "rgb5_a1", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
1483 addCreateTexture(prefix + "rgba4", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
1486 void ImageTests::addCreateTextureCubemapActions (const string& suffix, GLenum internalFormat, GLenum format, GLenum type)
1488 addCreateTexture("cubemap_positive_x" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, internalFormat, format, type);
1489 addCreateTexture("cubemap_positive_y" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR, internalFormat, format, type);
1490 addCreateTexture("cubemap_positive_z" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR, internalFormat, format, type);
1491 addCreateTexture("cubemap_negative_x" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR, internalFormat, format, type);
1492 addCreateTexture("cubemap_negative_y" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR, internalFormat, format, type);
1493 addCreateTexture("cubemap_negative_z" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR, internalFormat, format, type);
1496 void ImageTests::addCreateRenderbufferActions (void)
1498 addCreateRenderbuffer("renderbuffer_rgba4", GL_RGBA4);
1499 addCreateRenderbuffer("renderbuffer_rgb5_a1", GL_RGB5_A1);
1500 addCreateRenderbuffer("renderbuffer_rgb565", GL_RGB565);
1501 addCreateRenderbuffer("renderbuffer_depth16", GL_DEPTH_COMPONENT16);
1502 addCreateRenderbuffer("renderbuffer_stencil", GL_STENCIL_INDEX8);
1505 void ImageTests::addCreateAndroidNativeActions (void)
1507 addCreateAndroidNative("android_native_rgba4", GL_RGBA4);
1508 addCreateAndroidNative("android_native_rgb5_a1", GL_RGB5_A1);
1509 addCreateAndroidNative("android_native_rgb565", GL_RGB565);
1510 addCreateAndroidNative("android_native_rgb8", GL_RGB8);
1511 addCreateAndroidNative("android_native_rgba8", GL_RGBA8);
1512 addCreateAndroidNative("android_native_d16", GL_DEPTH_COMPONENT16);
1513 addCreateAndroidNative("android_native_d24", GL_DEPTH_COMPONENT24);
1514 addCreateAndroidNative("android_native_d24s8", GL_DEPTH24_STENCIL8);
1515 addCreateAndroidNative("android_native_d32f", GL_DEPTH_COMPONENT32F);
1516 addCreateAndroidNative("android_native_d32fs8", GL_DEPTH32F_STENCIL8);
1517 addCreateAndroidNative("android_native_rgb10a2", GL_RGB10_A2);
1518 addCreateAndroidNative("android_native_rgba16f", GL_RGBA16F);
1519 addCreateAndroidNative("android_native_s8", GL_STENCIL_INDEX8);
1521 addCreateAndroidNativeArray("android_native_array_rgba4", GL_RGBA4, 4u);
1522 addCreateAndroidNativeArray("android_native_array_rgb5_a1", GL_RGB5_A1, 4u);
1523 addCreateAndroidNativeArray("android_native_array_rgb565", GL_RGB565, 4u);
1524 addCreateAndroidNativeArray("android_native_array_rgb8", GL_RGB8, 4u);
1525 addCreateAndroidNativeArray("android_native_array_rgba8", GL_RGBA8, 4u);
1528 class RenderTests : public ImageTests
1531 RenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1532 : ImageTests (eglTestCtx, name, desc) {}
1534 void addRenderActions (void);
1535 LabeledActions m_renderActions;
1538 void RenderTests::addRenderActions (void)
1540 m_renderActions.add("texture", MovePtr<Action>(new GLESImageApi::RenderTexture2D()));
1541 m_renderActions.add("texture_array", MovePtr<Action>(new GLESImageApi::RenderTexture2DArray()));
1542 m_renderActions.add("read_pixels", MovePtr<Action>(new GLESImageApi::RenderReadPixelsRenderbuffer()));
1543 m_renderActions.add("depth_buffer", MovePtr<Action>(new GLESImageApi::RenderDepthbuffer()));
1544 m_renderActions.add("stencil_buffer", MovePtr<Action>(new GLESImageApi::RenderStencilbuffer()));
1547 class SimpleCreationTests : public RenderTests
1550 SimpleCreationTests (EglTestContext& eglTestCtx, const string& name, const string& desc) : RenderTests(eglTestCtx, name, desc) {}
1554 bool isDepthFormat (GLenum format)
1569 case GL_DEPTH_COMPONENT16:
1570 case GL_DEPTH_COMPONENT24:
1571 case GL_DEPTH_COMPONENT32:
1572 case GL_DEPTH_COMPONENT32F:
1573 case GL_DEPTH24_STENCIL8:
1574 case GL_DEPTH32F_STENCIL8:
1577 case GL_STENCIL_INDEX8:
1586 bool isStencilFormat (GLenum format)
1601 case GL_DEPTH_COMPONENT16:
1602 case GL_DEPTH_COMPONENT24:
1603 case GL_DEPTH_COMPONENT32:
1604 case GL_DEPTH_COMPONENT32F:
1607 case GL_STENCIL_INDEX8:
1608 case GL_DEPTH24_STENCIL8:
1609 case GL_DEPTH32F_STENCIL8:
1618 bool isCompatibleCreateAndRenderActions (const Action& create, const Action& render)
1620 if (const GLESImageApi::Create* glesCreate = dynamic_cast<const GLESImageApi::Create*>(&create))
1622 const GLenum createFormat = glesCreate->getEffectiveFormat();
1624 if (dynamic_cast<const GLESImageApi::RenderTexture2DArray*>(&render))
1626 // Makes sense only for texture arrays.
1627 if (glesCreate->getNumLayers() <= 1u)
1630 else if (glesCreate->getNumLayers() != 1u)
1632 // Skip other render actions for texture arrays.
1636 if (dynamic_cast<const GLESImageApi::RenderTexture2D*>(&render))
1638 // GLES does not have depth or stencil textures
1639 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1643 if (dynamic_cast<const GLESImageApi::RenderReadPixelsRenderbuffer*>(&render))
1645 // GLES does not support readPixels for depth or stencil.
1646 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1650 if (dynamic_cast<const GLESImageApi::RenderDepthbuffer*>(&render))
1652 // Copying non-depth data to depth renderbuffer and expecting meaningful
1653 // results just doesn't make any sense.
1654 if (!isDepthFormat(createFormat))
1658 if (dynamic_cast<const GLESImageApi::RenderStencilbuffer*>(&render))
1660 // Copying non-stencil data to stencil renderbuffer and expecting meaningful
1661 // results just doesn't make any sense.
1662 if (!isStencilFormat(createFormat))
1674 void SimpleCreationTests::init (void)
1676 addCreateTexture2DActions("texture_");
1677 addCreateTextureCubemapActions("_rgba", GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1678 addCreateTextureCubemapActions("_rgb", GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1679 addCreateRenderbufferActions();
1680 addCreateAndroidNativeActions();
1683 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
1685 const LabeledAction& createAction = m_createActions[createNdx];
1687 for (int renderNdx = 0; renderNdx < m_renderActions.size(); renderNdx++)
1689 const LabeledAction& renderAction = m_renderActions[renderNdx];
1692 if (!isCompatibleCreateAndRenderActions(*createAction.action, *renderAction.action))
1695 if (dynamic_cast<const GLESImageApi::RenderTexture2DArray*>(renderAction.action.get()))
1697 // Texture array tests require GLES3.
1698 spec.name = std::string("gles3_") + createAction.label + "_" + renderAction.label;
1699 spec.contexts.push_back(TestSpec::API_GLES3);
1703 spec.name = std::string("gles2_") + createAction.label + "_" + renderAction.label;
1704 spec.contexts.push_back(TestSpec::API_GLES2);
1707 spec.desc = spec.name;
1708 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
1709 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
1711 addChild(new ImageFormatCase(m_eglTestCtx, spec));
1716 TestCaseGroup* createSimpleCreationTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1718 return new SimpleCreationTests(eglTestCtx, name, desc);
1721 bool isCompatibleFormats (GLenum createFormat, GLenum modifyFormat, GLenum modifyType)
1723 switch (modifyFormat)
1728 case GL_UNSIGNED_BYTE:
1729 return createFormat == GL_RGB
1730 || createFormat == GL_RGB8
1731 || createFormat == GL_RGB565
1732 || createFormat == GL_SRGB8;
1735 return createFormat == GL_RGB8_SNORM;
1737 case GL_UNSIGNED_SHORT_5_6_5:
1738 return createFormat == GL_RGB
1739 || createFormat == GL_RGB565;
1741 case GL_UNSIGNED_INT_10F_11F_11F_REV:
1742 return createFormat == GL_R11F_G11F_B10F;
1744 case GL_UNSIGNED_INT_5_9_9_9_REV:
1745 return createFormat == GL_RGB9_E5;
1748 return createFormat == GL_RGB16F
1749 || createFormat == GL_R11F_G11F_B10F
1750 || createFormat == GL_RGB9_E5;
1753 return createFormat == GL_RGB16F
1754 || createFormat == GL_RGB32F
1755 || createFormat == GL_R11F_G11F_B10F
1756 || createFormat == GL_RGB9_E5;
1759 DE_FATAL("Unknown modify type");
1766 case GL_UNSIGNED_BYTE:
1767 return createFormat == GL_RGBA8
1768 || createFormat == GL_RGB5_A1
1769 || createFormat == GL_RGBA4
1770 || createFormat == GL_SRGB8_ALPHA8
1771 || createFormat == GL_RGBA;
1773 case GL_UNSIGNED_SHORT_4_4_4_4:
1774 return createFormat == GL_RGBA4
1775 || createFormat == GL_RGBA;
1777 case GL_UNSIGNED_SHORT_5_5_5_1:
1778 return createFormat == GL_RGB5_A1
1779 || createFormat == GL_RGBA;
1781 case GL_UNSIGNED_INT_2_10_10_10_REV:
1782 return createFormat == GL_RGB10_A2
1783 || createFormat == GL_RGB5_A1;
1786 return createFormat == GL_RGBA16F;
1789 return createFormat == GL_RGBA16F
1790 || createFormat == GL_RGBA32F;
1793 DE_FATAL("Unknown modify type");
1798 DE_FATAL("Unknown modify format");
1803 bool isCompatibleCreateAndModifyActions (const Action& create, const Action& modify)
1805 if (const GLESImageApi::Create* glesCreate = dynamic_cast<const GLESImageApi::Create*>(&create))
1807 // No modify tests for texture arrays.
1808 if (glesCreate->getNumLayers() > 1u)
1811 const GLenum createFormat = glesCreate->getEffectiveFormat();
1813 if (const GLESImageApi::ModifyTexSubImage* glesTexSubImageModify = dynamic_cast<const GLESImageApi::ModifyTexSubImage*>(&modify))
1815 const GLenum modifyFormat = glesTexSubImageModify->getFormat();
1816 const GLenum modifyType = glesTexSubImageModify->getType();
1818 return isCompatibleFormats(createFormat, modifyFormat, modifyType);
1821 if (dynamic_cast<const GLESImageApi::ModifyRenderbufferClearColor*>(&modify))
1823 // reintepreting color as non-color is not meaningful
1824 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1828 if (dynamic_cast<const GLESImageApi::ModifyRenderbufferClearDepth*>(&modify))
1830 // reintepreting depth as non-depth is not meaningful
1831 if (!isDepthFormat(createFormat))
1835 if (dynamic_cast<const GLESImageApi::ModifyRenderbufferClearStencil*>(&modify))
1837 // reintepreting stencil as non-stencil is not meaningful
1838 if (!isStencilFormat(createFormat))
1850 class MultiContextRenderTests : public RenderTests
1853 MultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc);
1855 void addClearActions (void);
1857 LabeledActions m_clearActions;
1860 MultiContextRenderTests::MultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1861 : RenderTests (eglTestCtx, name, desc)
1865 void MultiContextRenderTests::addClearActions (void)
1867 m_clearActions.add("clear_color", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearColor(tcu::Vec4(0.8f, 0.2f, 0.9f, 1.0f))));
1868 m_clearActions.add("clear_depth", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearDepth(0.75f)));
1869 m_clearActions.add("clear_stencil", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearStencil(97)));
1872 void MultiContextRenderTests::init (void)
1874 addCreateTexture2DActions("texture_");
1875 addCreateTextureCubemapActions("_rgba8", GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1876 addCreateTextureCubemapActions("_rgb8", GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1877 addCreateRenderbufferActions();
1878 addCreateAndroidNativeActions();
1882 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
1883 for (int renderNdx = 0; renderNdx < m_renderActions.size(); renderNdx++)
1884 for (int clearNdx = 0; clearNdx < m_clearActions.size(); clearNdx++)
1886 const LabeledAction& createAction = m_createActions[createNdx];
1887 const LabeledAction& renderAction = m_renderActions[renderNdx];
1888 const LabeledAction& clearAction = m_clearActions[clearNdx];
1891 if (!isCompatibleCreateAndRenderActions(*createAction.action, *renderAction.action))
1893 if (!isCompatibleCreateAndModifyActions(*createAction.action, *clearAction.action))
1896 spec.name = std::string("gles2_") + createAction.label + "_" + renderAction.label;
1898 const GLESImageApi::Create* glesCreate = dynamic_cast<const GLESImageApi::Create*>(createAction.action.get());
1901 DE_FATAL("Dynamic casting to GLESImageApi::Create* failed");
1903 const GLenum createFormat = glesCreate->getEffectiveFormat();
1905 if (isDepthFormat(createFormat) && isStencilFormat(createFormat))
1907 // Combined depth and stencil format. Add the clear action label to avoid test
1909 spec.name += std::string("_") + clearAction.label;
1912 spec.desc = spec.name;
1914 spec.contexts.push_back(TestSpec::API_GLES2);
1915 spec.contexts.push_back(TestSpec::API_GLES2);
1917 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
1918 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
1919 spec.operations.push_back(TestSpec::Operation(0, *clearAction.action));
1920 spec.operations.push_back(TestSpec::Operation(1, *createAction.action));
1921 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
1922 spec.operations.push_back(TestSpec::Operation(1, *renderAction.action));
1924 addChild(new ImageFormatCase(m_eglTestCtx, spec));
1928 TestCaseGroup* createMultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1930 return new MultiContextRenderTests(eglTestCtx, name, desc);
1933 class ModifyTests : public ImageTests
1936 ModifyTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1937 : ImageTests(eglTestCtx, name, desc) {}
1942 void addModifyActions(void);
1944 LabeledActions m_modifyActions;
1945 GLESImageApi::RenderTryAll m_renderAction;
1948 void ModifyTests::addModifyActions (void)
1950 m_modifyActions.add("tex_subimage_rgb8", MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGB, GL_UNSIGNED_BYTE)));
1951 m_modifyActions.add("tex_subimage_rgb565", MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGB, GL_UNSIGNED_SHORT_5_6_5)));
1952 m_modifyActions.add("tex_subimage_rgba8", MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_BYTE)));
1953 m_modifyActions.add("tex_subimage_rgb5_a1", MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1)));
1954 m_modifyActions.add("tex_subimage_rgba4", MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4)));
1956 m_modifyActions.add("renderbuffer_clear_color", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearColor(tcu::Vec4(0.3f, 0.5f, 0.3f, 1.0f))));
1957 m_modifyActions.add("renderbuffer_clear_depth", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearDepth(0.7f)));
1958 m_modifyActions.add("renderbuffer_clear_stencil", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearStencil(78)));
1961 void ModifyTests::init (void)
1963 addCreateTexture2DActions("tex_");
1964 addCreateRenderbufferActions();
1965 addCreateAndroidNativeActions();
1968 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
1970 LabeledAction& createAction = m_createActions[createNdx];
1972 for (int modifyNdx = 0; modifyNdx < m_modifyActions.size(); modifyNdx++)
1974 LabeledAction& modifyAction = m_modifyActions[modifyNdx];
1976 if (!isCompatibleCreateAndModifyActions(*createAction.action, *modifyAction.action))
1980 spec.name = createAction.label + "_" + modifyAction.label;
1981 spec.desc = "gles2_tex_sub_image";
1983 spec.contexts.push_back(TestSpec::API_GLES2);
1985 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
1986 spec.operations.push_back(TestSpec::Operation(0, m_renderAction));
1987 spec.operations.push_back(TestSpec::Operation(0, *modifyAction.action));
1988 spec.operations.push_back(TestSpec::Operation(0, m_renderAction));
1990 addChild(new ImageFormatCase(m_eglTestCtx, spec));
1995 TestCaseGroup* createModifyTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1997 return new ModifyTests(eglTestCtx, name, desc);