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(); }
191 bool isYUVFormatImage (void) const { return m_imgSource->isYUVFormatImage(); }
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"; }
230 class RenderYUVTexture : public Render
233 bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const override;
234 string getRequiredExtension (void) const override { return "GL_EXT_YUV_target"; }
236 class Modify : public GLESAction
239 string getRequiredExtension (void) const { return "GL_OES_EGL_image"; }
242 class ModifyTexSubImage : public Modify
245 ModifyTexSubImage (GLenum format, GLenum type) : m_format(format), m_type(type) {}
246 bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
247 GLenum getFormat (void) const { return m_format; }
248 GLenum getType (void) const { return m_type; }
255 class ModifyRenderbuffer : public Modify
258 bool invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const;
261 virtual void initializeRbo (GLESImageApi& api, GLuint rbo, tcu::Texture2D& ref) const = 0;
264 class ModifyRenderbufferClearColor : public ModifyRenderbuffer
267 ModifyRenderbufferClearColor (tcu::Vec4 color) : m_color(color) {}
270 void initializeRbo (GLESImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
275 class ModifyRenderbufferClearDepth : public ModifyRenderbuffer
278 ModifyRenderbufferClearDepth (GLfloat depth) : m_depth(depth) {}
281 void initializeRbo (GLESImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
286 class ModifyRenderbufferClearStencil : public ModifyRenderbuffer
289 ModifyRenderbufferClearStencil (GLint stencil) : m_stencil(stencil) {}
292 void initializeRbo (GLESImageApi& api, GLuint rbo, tcu::Texture2D& ref) const;
297 GLESImageApi (const Library& egl, const glw::Functions& gl, int contextId, tcu::TestLog& log, EGLDisplay display, EGLSurface surface, EGLConfig config, EGLint apiVersion);
298 ~GLESImageApi (void);
301 EGLContext m_context;
302 const glw::Functions& m_gl;
304 MovePtr<UniqueImage> createImage (const ImageSource& source, const ClientBuffer& buffer) const;
307 GLESImageApi::GLESImageApi (const Library& egl, const glw::Functions& gl, int contextId, tcu::TestLog& log, EGLDisplay display, EGLSurface surface, EGLConfig config, EGLint apiVersion)
308 : ImageApi (egl, contextId, display, surface)
309 , glu::CallLogWrapper (gl, log)
310 , m_context (DE_NULL)
313 const EGLint attriblist[] =
315 EGL_CONTEXT_CLIENT_VERSION, apiVersion,
319 EGLint configId = -1;
320 EGLU_CHECK_CALL(m_egl, getConfigAttrib(m_display, config, EGL_CONFIG_ID, &configId));
321 getLog() << tcu::TestLog::Message << "Creating gles" << apiVersion << " context with config id: " << configId << " context: " << m_contextId << tcu::TestLog::EndMessage;
322 egl.bindAPI(EGL_OPENGL_ES_API);
323 m_context = m_egl.createContext(m_display, config, EGL_NO_CONTEXT, attriblist);
324 EGLU_CHECK_MSG(m_egl, "Failed to create GLES context");
326 egl.makeCurrent(display, m_surface, m_surface, m_context);
327 EGLU_CHECK_MSG(m_egl, "Failed to make context current");
330 GLESImageApi::~GLESImageApi (void)
332 m_egl.makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
333 m_egl.destroyContext(m_display, m_context);
336 bool GLESImageApi::GLESAction::invoke (ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const
338 GLESImageApi& glesApi = dynamic_cast<GLESImageApi&>(api);
340 glesApi.m_egl.makeCurrent(glesApi.m_display, glesApi.m_surface, glesApi.m_surface, glesApi.m_context);
341 return invokeGLES(glesApi, image, ref);
344 bool GLESImageApi::Create::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const
346 de::UniquePtr<ClientBuffer> buffer (m_imgSource->createBuffer(api.m_egl, api.m_gl, &ref));
348 GLU_CHECK_GLW_CALL(api.m_gl, finish());
350 image = api.createImage(*m_imgSource, *buffer);
354 MovePtr<UniqueImage> GLESImageApi::createImage (const ImageSource& source, const ClientBuffer& buffer) const
356 const EGLImageKHR image = source.createImage(m_egl, m_display, m_context, buffer.get());
357 return MovePtr<UniqueImage>(new UniqueImage(m_egl, m_display, image));
360 static void imageTargetTexture2D (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
362 gl.eglImageTargetTexture2DOES(GL_TEXTURE_2D, img);
364 const GLenum error = gl.getError();
366 if (error == GL_INVALID_OPERATION)
367 TCU_THROW(NotSupportedError, "Creating texture2D from EGLImage type not supported");
369 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
370 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
374 static void imageTargetExternalTexture (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
376 gl.eglImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, img);
378 const GLenum error = gl.getError();
380 if (error == GL_INVALID_OPERATION)
381 TCU_THROW(NotSupportedError, "Creating external texture from EGLImage type not supported");
383 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
384 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
388 static void imageTargetTexture2DArray (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
390 gl.eglImageTargetTexture2DOES(GL_TEXTURE_2D_ARRAY, img);
392 const GLenum error = gl.getError();
394 if (error == GL_INVALID_OPERATION)
395 TCU_THROW(NotSupportedError, "Creating texture2D array from EGLImage type not supported");
397 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetTexture2DOES()");
398 EGLU_CHECK_MSG(egl, "glEGLImageTargetTexture2DOES()");
402 static void imageTargetRenderbuffer (const Library& egl, const glw::Functions& gl, GLeglImageOES img)
404 gl.eglImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, img);
406 const GLenum error = gl.getError();
408 if (error == GL_INVALID_OPERATION)
409 TCU_THROW(NotSupportedError, "Creating renderbuffer from EGLImage type not supported");
411 GLU_EXPECT_NO_ERROR(error, "glEGLImageTargetRenderbufferStorageOES()");
412 EGLU_CHECK_MSG(egl, "glEGLImageTargetRenderbufferStorageOES()");
416 static void framebufferRenderbuffer (const glw::Functions& gl, GLenum attachment, GLuint rbo)
418 GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rbo));
419 TCU_CHECK_AND_THROW(NotSupportedError,
420 gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
421 ("EGLImage as " + string(glu::getFramebufferAttachmentName(attachment)) + " not supported").c_str());
424 static set<string> getSupportedExtensions (tcu::TestLog& log, const Library& egl, const EGLDisplay dpy, const glw::Functions gl)
427 const vector<string> glExts = de::splitString((const char*) gl.getString(GL_EXTENSIONS));
428 const vector<string> eglExts = eglu::getDisplayExtensions(egl, dpy);
430 exts.insert(glExts.begin(), glExts.end());
431 exts.insert(eglExts.begin(), eglExts.end());
433 if (eglu::getVersion(egl, dpy) >= eglu::Version(1, 5))
435 // EGL 1.5 has built-in support for EGLImage and GL sources
436 exts.insert("EGL_KHR_image_base");
437 exts.insert("EGL_KHR_gl_texture_2D_image");
438 exts.insert("EGL_KHR_gl_texture_cubemap_image");
439 exts.insert("EGL_KHR_gl_renderbuffer_image");
442 if (!de::contains(exts, "EGL_KHR_image_base") && !de::contains(exts, "EGL_KHR_image"))
444 log << tcu::TestLog::Message
445 << "EGL version is under 1.5 and neither EGL_KHR_image nor EGL_KHR_image_base is supported."
446 << "One should be supported."
447 << tcu::TestLog::EndMessage;
448 TCU_THROW(NotSupportedError, "Extension not supported: EGL_KHR_image_base");
454 static const float squareTriangleCoords[] =
465 bool GLESImageApi::RenderTexture2D::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
467 const glw::Functions& gl = api.m_gl;
468 tcu::TestLog& log = api.getLog();
471 // Branch only taken in TryAll case
472 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
473 throw IllegalRendererException(); // Skip, GLES does not support sampling depth textures
474 if (reference.getFormat().order == tcu::TextureFormat::S)
475 throw IllegalRendererException(); // Skip, GLES does not support sampling stencil textures
477 gl.clearColor(0.0, 0.0, 0.0, 0.0);
478 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
479 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
480 gl.disable(GL_DEPTH_TEST);
482 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_2D in context: " << api.m_contextId << tcu::TestLog::EndMessage;
483 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
485 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
486 imageTargetTexture2D(api.m_egl, gl, **img);
488 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
489 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
490 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
491 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
493 const char* const vertexShader =
494 "attribute highp vec2 a_coord;\n"
495 "varying mediump vec2 v_texCoord;\n"
496 "void main(void) {\n"
497 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
498 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
501 const char* const fragmentShader =
502 "varying mediump vec2 v_texCoord;\n"
503 "uniform sampler2D u_sampler;\n"
504 "void main(void) {\n"
505 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
506 "\tgl_FragColor = vec4(texColor);\n"
509 Program program(gl, vertexShader, fragmentShader);
510 TCU_CHECK(program.isOk());
512 GLuint glProgram = program.getProgram();
513 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
515 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
516 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
518 GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
519 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
521 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
522 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
523 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
524 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
526 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
527 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
528 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, 0));
530 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
531 tcu::Surface screen (reference.getWidth(), reference.getHeight());
532 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
534 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
536 float threshold = 0.05f;
537 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
542 // Renders using a single layer from a texture array.
543 bool GLESImageApi::RenderTexture2DArray::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
545 const glw::Functions& gl = api.m_gl;
546 tcu::TestLog& log = api.getLog();
549 gl.clearColor(0.0, 0.0, 0.0, 0.0);
550 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
551 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
552 gl.disable(GL_DEPTH_TEST);
554 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_2D_ARRAY in context: " << api.m_contextId << tcu::TestLog::EndMessage;
555 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
557 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D_ARRAY, *srcTex));
558 imageTargetTexture2DArray(api.m_egl, gl, **img);
560 glu::TransferFormat transferFormat = glu::getTransferFormat(reference.getFormat());
561 // Initializes layer 1.
562 GLU_CHECK_GLW_CALL(gl, texSubImage3D(GL_TEXTURE_2D_ARRAY,
566 1, // Z offset (layer)
567 reference.getWidth(), // Width
568 reference.getHeight(), // Height
570 transferFormat.format, // Format
571 transferFormat.dataType, // Type
572 reference.getLevel(0).getDataPtr())); // Pixel data
575 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
576 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
577 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
578 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
580 const char* const vertexShader =
582 "precision highp int;\n"
583 "precision highp float;\n"
584 "layout(location = 0) in vec2 pos_in;\n"
585 "layout(location = 0) out vec2 texcoord_out;\n"
588 " gl_Position = vec4(pos_in, -0.1, 1.0);\n"
589 " texcoord_out = vec2((pos_in.x + 1.0) * 0.5, (pos_in.y + 1.0) * 0.5);\n"
592 const char* const fragmentShader =
594 "precision highp int;\n"
595 "precision highp float;\n"
596 "layout(location = 0) in vec2 texcoords_in;\n"
597 "layout(location = 0) out vec4 color_out;\n"
598 "uniform layout(binding=0) highp sampler2DArray tex_sampler;\n"
602 " color_out = texture(tex_sampler, vec3(texcoords_in, 1));\n"
605 Program program(gl, vertexShader, fragmentShader);
609 log << tcu::TestLog::Message << "Shader build failed.\n"
610 << "Vertex: " << program.getShaderInfo(glu::SHADERTYPE_VERTEX).infoLog << "\n"
611 << vertexShader << "\n"
612 << "Fragment: " << program.getShaderInfo(glu::SHADERTYPE_FRAGMENT).infoLog << "\n"
613 << fragmentShader << "\n"
614 << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
617 TCU_CHECK(program.isOk());
619 GLuint glProgram = program.getProgram();
620 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
622 GLuint coordLoc = gl.getAttribLocation(glProgram, "pos_in");
623 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute pos_in");
625 GLuint samplerLoc = gl.getUniformLocation(glProgram, "tex_sampler");
626 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform tex_sampler");
628 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D_ARRAY, *srcTex));
629 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
630 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
631 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
633 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
634 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
636 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
637 tcu::Surface screen (reference.getWidth(), reference.getHeight());
638 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
640 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
642 float threshold = 0.05f;
643 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
648 bool GLESImageApi::RenderExternalTexture::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
650 const glw::Functions& gl = api.m_gl;
651 tcu::TestLog& log = api.getLog();
654 // Branch only taken in TryAll case
655 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
656 throw IllegalRendererException(); // Skip, GLES2 does not support sampling depth textures
657 if (reference.getFormat().order == tcu::TextureFormat::S)
658 throw IllegalRendererException(); // Skip, GLES2 does not support sampling stencil textures
660 gl.clearColor(0.0, 0.0, 0.0, 0.0);
661 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
662 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
663 gl.disable(GL_DEPTH_TEST);
665 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_EXTERNAL_OES in context: " << api.m_contextId << tcu::TestLog::EndMessage;
666 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
668 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
669 imageTargetExternalTexture(api.m_egl, gl, **img);
671 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
672 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
673 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
674 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
676 const char* const vertexShader =
677 "attribute highp vec2 a_coord;\n"
678 "varying mediump vec2 v_texCoord;\n"
679 "void main(void) {\n"
680 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
681 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
684 const char* const fragmentShader =
685 "#extension GL_OES_EGL_image_external : require\n"
686 "varying mediump vec2 v_texCoord;\n"
687 "uniform samplerExternalOES u_sampler;\n"
688 "void main(void) {\n"
689 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
690 "\tgl_FragColor = vec4(texColor);\n"
693 Program program(gl, vertexShader, fragmentShader);
694 TCU_CHECK(program.isOk());
696 GLuint glProgram = program.getProgram();
697 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
699 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
700 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
702 GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
703 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
705 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
706 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
707 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
708 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
710 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
711 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
712 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
714 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
715 tcu::Surface screen (reference.getWidth(), reference.getHeight());
716 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
718 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
720 float threshold = 0.05f;
721 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
726 bool GLESImageApi::RenderYUVTexture::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
728 const glw::Functions& gl = api.m_gl;
729 tcu::TestLog& log = api.getLog();
732 DE_ASSERT(reference.isYUVTextureUsed());
734 gl.clearColor(0.0, 0.0, 0.0, 0.0);
735 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
736 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
737 gl.disable(GL_DEPTH_TEST);
739 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_EXTERNAL_OES in context: " << api.m_contextId << tcu::TestLog::EndMessage;
740 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
741 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
742 imageTargetExternalTexture(api.m_egl, gl, **img);
744 /* init YUV texture with glClear, clear color value in YUV color space */
745 glu::Framebuffer fbo(gl);
746 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *fbo));
747 GLU_CHECK_GLW_CALL(gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES,*srcTex, 0));
748 const tcu::Vec4 colorValues[] =
750 tcu::Vec4(0.9f, 0.5f, 0.65f, 1.0f),
751 tcu::Vec4(0.5f, 0.7f, 0.65f, 1.0f),
752 tcu::Vec4(0.2f, 0.5f, 0.65f, 1.0f),
753 tcu::Vec4(0.3f, 0.1f, 0.5f, 1.0f),
754 tcu::Vec4(0.8f, 0.2f, 0.3f, 1.0f),
755 tcu::Vec4(0.9f, 0.4f, 0.8f, 1.0f),
757 tcu::clear(reference.getLevel(0), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
758 GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST));
759 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorValues); ++ndx)
761 const tcu::IVec2 size = tcu::IVec2((int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) * ((float)reference.getWidth() / float(DE_LENGTH_OF_ARRAY(colorValues)))),
762 (int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) * ((float)reference.getHeight() / float(DE_LENGTH_OF_ARRAY(colorValues)))));
764 if (size.x() == 0 || size.y() == 0)
766 GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y()));
768 GLU_CHECK_GLW_CALL(gl, clearColor(colorValues[ndx].x(), colorValues[ndx].y(), colorValues[ndx].z(), colorValues[ndx].w()));
769 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
770 GLU_CHECK_GLW_CALL(gl, finish());
772 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)tmp));
773 tcu::clear(tcu::getSubregion(reference.getLevel(0), 0, 0, size.x(), size.y()), tcu::Vec4(tmp[0]/(255.0f), tmp[1]/(255.0f), tmp[2]/(255.0f), tmp[3]/(255.0f)));
775 GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST));
776 GLU_CHECK_GLW_CALL(gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, 0, 0));
777 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
778 GLU_CHECK_GLW_CALL(gl, finish());
781 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
782 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
783 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
784 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
786 const char* const vertexShader =
787 "attribute highp vec2 a_coord;\n"
788 "varying mediump vec2 v_texCoord;\n"
789 "void main(void) {\n"
790 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
791 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
794 const char* const fragmentShader =
795 "#extension GL_OES_EGL_image_external : require\n"
796 "varying mediump vec2 v_texCoord;\n"
797 "uniform samplerExternalOES u_sampler;\n"
798 "void main(void) {\n"
799 "\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
800 "\tgl_FragColor = vec4(texColor);\n"
803 Program program(gl, vertexShader, fragmentShader);
804 TCU_CHECK(program.isOk());
806 GLuint glProgram = program.getProgram();
807 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
809 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
810 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
812 GLuint samplerLoc = gl.getUniformLocation(glProgram, "u_sampler");
813 TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
815 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
816 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc, 0));
817 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
818 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
820 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
821 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
822 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
824 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
825 tcu::Surface screen (reference.getWidth(), reference.getHeight());
826 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
828 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
830 float threshold = 0.05f;
831 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
836 bool GLESImageApi::RenderExternalTextureSamplerArray::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
838 const glw::Functions& gl = api.m_gl;
839 tcu::TestLog& log = api.getLog();
842 // Branch only taken in TryAll case
843 if (reference.getFormat().order == tcu::TextureFormat::DS || reference.getFormat().order == tcu::TextureFormat::D)
844 throw IllegalRendererException(); // Skip, GLES2 does not support sampling depth textures
845 if (reference.getFormat().order == tcu::TextureFormat::S)
846 throw IllegalRendererException(); // Skip, GLES2 does not support sampling stencil textures
848 gl.clearColor(0.0, 0.0, 0.0, 0.0);
849 gl.viewport(0, 0, reference.getWidth(), reference.getHeight());
850 gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
851 gl.disable(GL_DEPTH_TEST);
853 log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_EXTERNAL_OES using sampler array in context: " << api.m_contextId << tcu::TestLog::EndMessage;
854 TCU_CHECK(**img != EGL_NO_IMAGE_KHR);
856 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
857 imageTargetExternalTexture(api.m_egl, gl, **img);
859 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
860 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
861 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
862 GLU_CHECK_GLW_CALL(gl, texParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
864 // Texture not associated with an external texture will return (0, 0, 0, 1) when sampled.
866 gl.genTextures(1, &emptyTex);
867 gl.activeTexture(GL_TEXTURE1);
868 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, emptyTex));
870 const char* const vertexShader =
871 "attribute highp vec2 a_coord;\n"
872 "varying mediump vec2 v_texCoord;\n"
873 "void main(void) {\n"
874 "\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
875 "\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
878 const char* const fragmentShader =
879 "#extension GL_OES_EGL_image_external : require\n"
880 "varying mediump vec2 v_texCoord;\n"
881 "uniform samplerExternalOES u_sampler[4];\n"
882 "void main(void) {\n"
883 "\tmediump vec4 texColor = texture2D(u_sampler[2], v_texCoord);\n"
884 "\t//These will sample (0, 0, 0, 1) and should not affect the results.\n"
885 "\ttexColor += texture2D(u_sampler[0], v_texCoord) - vec4(0, 0, 0, 1);\n"
886 "\ttexColor += texture2D(u_sampler[1], v_texCoord) - vec4(0, 0, 0, 1);\n"
887 "\ttexColor += texture2D(u_sampler[3], v_texCoord) - vec4(0, 0, 0, 1);\n"
888 "\tgl_FragColor = vec4(texColor);\n"
891 Program program(gl, vertexShader, fragmentShader);
892 TCU_CHECK(program.isOk());
894 GLuint glProgram = program.getProgram();
895 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
897 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
898 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
900 GLuint samplerLoc0 = gl.getUniformLocation(glProgram, "u_sampler[0]");
901 TCU_CHECK_MSG((int)samplerLoc0 != (int)-1, "Couldn't find uniform u_sampler[0]");
902 GLuint samplerLoc1 = gl.getUniformLocation(glProgram, "u_sampler[1]");
903 TCU_CHECK_MSG((int)samplerLoc1 != (int)-1, "Couldn't find uniform u_sampler[1]");
904 GLuint samplerLoc2 = gl.getUniformLocation(glProgram, "u_sampler[2]");
905 TCU_CHECK_MSG((int)samplerLoc2 != (int)-1, "Couldn't find uniform u_sampler[2]");
906 GLuint samplerLoc3 = gl.getUniformLocation(glProgram, "u_sampler[3]");
907 TCU_CHECK_MSG((int)samplerLoc3 != (int)-1, "Couldn't find uniform u_sampler[3]");
909 gl.activeTexture(GL_TEXTURE0);
910 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, *srcTex));
911 // One sampler reads a gradient and others opaque black.
912 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc0, 1));
913 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc1, 1));
914 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc2, 0));
915 GLU_CHECK_GLW_CALL(gl, uniform1i(samplerLoc3, 1));
916 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
917 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
919 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
920 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
921 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
922 gl.activeTexture(GL_TEXTURE1);
923 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
924 gl.deleteTextures(1, &emptyTex);
925 gl.activeTexture(GL_TEXTURE0);
927 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
928 tcu::Surface screen (reference.getWidth(), reference.getHeight());
929 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
931 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
933 float threshold = 0.05f;
934 bool match = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refSurface, screen, threshold, tcu::COMPARE_LOG_RESULT);
939 bool GLESImageApi::RenderDepthbuffer::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
941 const glw::Functions& gl = api.m_gl;
942 tcu::TestLog& log = api.getLog();
943 Framebuffer framebuffer (gl);
944 Renderbuffer renderbufferColor (gl);
945 Renderbuffer renderbufferDepth (gl);
946 const tcu::RGBA compareThreshold (32, 32, 32, 32); // layer colors are far apart, large thresholds are ok
948 // Branch only taken in TryAll case
949 if (reference.getFormat().order != tcu::TextureFormat::DS && reference.getFormat().order != tcu::TextureFormat::D)
950 throw IllegalRendererException(); // Skip, interpreting non-depth data as depth data is not meaningful
952 log << tcu::TestLog::Message << "Rendering with depth buffer" << tcu::TestLog::EndMessage;
954 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
956 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferColor));
957 GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight()));
958 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbufferColor);
960 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferDepth));
961 imageTargetRenderbuffer(api.m_egl, gl, **img);
962 framebufferRenderbuffer(gl, GL_DEPTH_ATTACHMENT, *renderbufferDepth);
963 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
965 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
968 const char* vertexShader =
969 "attribute highp vec2 a_coord;\n"
970 "uniform highp float u_depth;\n"
971 "void main(void) {\n"
972 "\tgl_Position = vec4(a_coord, u_depth, 1.0);\n"
975 const char* fragmentShader =
976 "uniform mediump vec4 u_color;\n"
977 "void main(void) {\n"
978 "\tgl_FragColor = u_color;\n"
981 Program program(gl, vertexShader, fragmentShader);
982 TCU_CHECK(program.isOk());
984 GLuint glProgram = program.getProgram();
985 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
987 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
988 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
990 GLuint colorLoc = gl.getUniformLocation(glProgram, "u_color");
991 TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color");
993 GLuint depthLoc = gl.getUniformLocation(glProgram, "u_depth");
994 TCU_CHECK_MSG((int)depthLoc != (int)-1, "Couldn't find uniform u_depth");
996 GLU_CHECK_GLW_CALL(gl, clearColor(0.5f, 1.0f, 0.5f, 1.0f));
997 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
999 tcu::Vec4 depthLevelColors[] = {
1000 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
1001 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
1002 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
1003 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
1004 tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
1006 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
1007 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
1008 tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f),
1009 tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f),
1010 tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)
1013 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
1014 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
1016 GLU_CHECK_GLW_CALL(gl, enable(GL_DEPTH_TEST));
1017 GLU_CHECK_GLW_CALL(gl, depthFunc(GL_LESS));
1018 GLU_CHECK_GLW_CALL(gl, depthMask(GL_FALSE));
1020 for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevelColors); level++)
1022 const tcu::Vec4 color = depthLevelColors[level];
1023 const float clipDepth = ((float)(level + 1) * 0.1f) * 2.0f - 1.0f; // depth in clip coords
1025 GLU_CHECK_GLW_CALL(gl, uniform4f(colorLoc, color.x(), color.y(), color.z(), color.w()));
1026 GLU_CHECK_GLW_CALL(gl, uniform1f(depthLoc, clipDepth));
1027 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
1030 GLU_CHECK_GLW_CALL(gl, depthMask(GL_TRUE));
1031 GLU_CHECK_GLW_CALL(gl, disable(GL_DEPTH_TEST));
1032 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
1034 const ConstPixelBufferAccess& refAccess = reference.getLevel(0);
1035 tcu::Surface screen (reference.getWidth(), reference.getHeight());
1036 tcu::Surface referenceScreen (reference.getWidth(), reference.getHeight());
1038 gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
1040 for (int y = 0; y < reference.getHeight(); y++)
1042 for (int x = 0; x < reference.getWidth(); x++)
1044 tcu::Vec4 result = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f);
1046 for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevelColors); level++)
1048 if ((float)(level + 1) * 0.1f < refAccess.getPixDepth(x, y))
1049 result = depthLevelColors[level];
1052 referenceScreen.getAccess().setPixel(result, x, y);
1056 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1057 GLU_CHECK_GLW_CALL(gl, finish());
1059 return tcu::pixelThresholdCompare(log, "Depth buffer rendering result", "Result from rendering with depth buffer", referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT);
1062 bool GLESImageApi::RenderStencilbuffer::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
1064 // Branch only taken in TryAll case
1065 if (reference.getFormat().order != tcu::TextureFormat::DS && reference.getFormat().order != tcu::TextureFormat::S)
1066 throw IllegalRendererException(); // Skip, interpreting non-stencil data as stencil data is not meaningful
1068 const glw::Functions& gl = api.m_gl;
1069 tcu::TestLog& log = api.getLog();
1070 Framebuffer framebuffer (gl);
1071 Renderbuffer renderbufferColor (gl);
1072 Renderbuffer renderbufferStencil (gl);
1073 const tcu::RGBA compareThreshold (32, 32, 32, 32); // layer colors are far apart, large thresholds are ok
1074 const deUint32 numStencilBits = tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(reference.getLevel(0).getFormat(), tcu::Sampler::MODE_STENCIL)).x();
1075 const deUint32 maxStencil = deBitMask32(0, numStencilBits);
1077 log << tcu::TestLog::Message << "Rendering with stencil buffer" << tcu::TestLog::EndMessage;
1079 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
1081 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferColor));
1082 GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight()));
1083 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbufferColor);
1085 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferStencil));
1086 imageTargetRenderbuffer(api.m_egl, gl, **img);
1087 framebufferRenderbuffer(gl, GL_STENCIL_ATTACHMENT, *renderbufferStencil);
1088 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
1090 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1093 const char* vertexShader =
1094 "attribute highp vec2 a_coord;\n"
1095 "void main(void) {\n"
1096 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
1099 const char* fragmentShader =
1100 "uniform mediump vec4 u_color;\n"
1101 "void main(void) {\n"
1102 "\tgl_FragColor = u_color;\n"
1105 Program program(gl, vertexShader, fragmentShader);
1106 TCU_CHECK(program.isOk());
1108 GLuint glProgram = program.getProgram();
1109 GLU_CHECK_GLW_CALL(gl, useProgram(glProgram));
1111 GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord");
1112 TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
1114 GLuint colorLoc = gl.getUniformLocation(glProgram, "u_color");
1115 TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color");
1117 GLU_CHECK_GLW_CALL(gl, clearColor(0.5f, 1.0f, 0.5f, 1.0f));
1118 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
1120 tcu::Vec4 stencilLevelColors[] = {
1121 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
1122 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
1123 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
1124 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
1125 tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
1127 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
1128 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
1129 tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f),
1130 tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f),
1131 tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)
1134 GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc));
1135 GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords));
1137 GLU_CHECK_GLW_CALL(gl, enable(GL_STENCIL_TEST));
1138 GLU_CHECK_GLW_CALL(gl, stencilOp(GL_KEEP, GL_KEEP, GL_KEEP));
1140 for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++)
1142 const tcu::Vec4 color = stencilLevelColors[level];
1143 const int stencil = (int)(((float)(level + 1) * 0.1f) * (float)maxStencil);
1145 GLU_CHECK_GLW_CALL(gl, stencilFunc(GL_LESS, stencil, 0xFFFFFFFFu));
1146 GLU_CHECK_GLW_CALL(gl, uniform4f(colorLoc, color.x(), color.y(), color.z(), color.w()));
1147 GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6));
1150 GLU_CHECK_GLW_CALL(gl, disable(GL_STENCIL_TEST));
1151 GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc));
1153 const ConstPixelBufferAccess& refAccess = reference.getLevel(0);
1154 tcu::Surface screen (reference.getWidth(), reference.getHeight());
1155 tcu::Surface referenceScreen (reference.getWidth(), reference.getHeight());
1157 gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
1159 for (int y = 0; y < reference.getHeight(); y++)
1160 for (int x = 0; x < reference.getWidth(); x++)
1162 tcu::Vec4 result = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f);
1164 for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++)
1166 const int levelStencil = (int)(((float)(level + 1) * 0.1f) * (float)maxStencil);
1167 if (levelStencil < refAccess.getPixStencil(x, y))
1168 result = stencilLevelColors[level];
1171 referenceScreen.getAccess().setPixel(result, x, y);
1174 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1175 GLU_CHECK_GLW_CALL(gl, finish());
1177 return tcu::pixelThresholdCompare(log, "StencilResult", "Result from rendering with stencil buffer", referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT);
1180 bool GLESImageApi::RenderReadPixelsRenderbuffer::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
1182 switch (glu::getInternalFormat(reference.getFormat()))
1189 // Skip, not in the list of allowed render buffer formats for GLES.
1190 throw tcu::NotSupportedError("Image format not allowed for glReadPixels.");
1193 const glw::Functions& gl = api.m_gl;
1194 const tcu::IVec4 bitDepth = tcu::getTextureFormatMantissaBitDepth(reference.getFormat());
1195 const tcu::IVec4 threshold (2 * (tcu::IVec4(1) << (tcu::IVec4(8) - bitDepth)));
1196 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)));
1197 tcu::TestLog& log = api.getLog();
1198 Framebuffer framebuffer (gl);
1199 Renderbuffer renderbuffer (gl);
1200 tcu::Surface screen (reference.getWidth(), reference.getHeight());
1201 tcu::Surface refSurface (reference.getWidth(), reference.getHeight());
1203 log << tcu::TestLog::Message << "Reading with ReadPixels from renderbuffer" << tcu::TestLog::EndMessage;
1205 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
1206 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer));
1207 imageTargetRenderbuffer(api.m_egl, gl, **img);
1209 GLU_EXPECT_NO_ERROR(gl.getError(), "imageTargetRenderbuffer");
1210 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbuffer);
1211 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferRenderbuffer");
1213 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1215 GLU_CHECK_GLW_CALL(gl, readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()));
1217 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1218 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
1219 GLU_CHECK_GLW_CALL(gl, finish());
1221 tcu::copy(refSurface.getAccess(), reference.getLevel(0));
1223 return tcu::pixelThresholdCompare(log, "Renderbuffer read", "Result from reading renderbuffer", refSurface, screen, threshold8, tcu::COMPARE_LOG_RESULT);
1227 bool GLESImageApi::RenderTryAll::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
1229 bool foundSupported = false;
1230 tcu::TestLog& log = api.getLog();
1231 GLESImageApi::RenderTexture2D renderTex2D;
1232 GLESImageApi::RenderExternalTexture renderExternal;
1233 GLESImageApi::RenderExternalTextureSamplerArray renderExternalSamplerArray;
1234 GLESImageApi::RenderReadPixelsRenderbuffer renderReadPixels;
1235 GLESImageApi::RenderDepthbuffer renderDepth;
1236 GLESImageApi::RenderStencilbuffer renderStencil;
1237 Action* actions[] = { &renderTex2D, &renderExternal, &renderExternalSamplerArray, &renderReadPixels, &renderDepth, &renderStencil };
1238 set<string> exts = getSupportedExtensions(log, api.m_egl, api.m_display, api.m_gl);
1240 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(actions); ++ndx)
1244 const string ext = actions[ndx]->getRequiredExtension();
1246 if (!de::contains(exts, ext))
1247 TCU_THROW_EXPR(NotSupportedError, "Extension not supported", ext.c_str());
1249 if (!actions[ndx]->invoke(api, img, reference))
1252 foundSupported = true;
1254 catch (const tcu::NotSupportedError& error)
1256 log << tcu::TestLog::Message << error.what() << tcu::TestLog::EndMessage;
1258 catch (const IllegalRendererException&)
1260 // not valid renderer
1264 if (!foundSupported)
1265 throw tcu::NotSupportedError("Rendering not supported", "", __FILE__, __LINE__);
1270 bool GLESImageApi::ModifyTexSubImage::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
1272 const glw::Functions& gl = api.m_gl;
1273 tcu::TestLog& log = api.getLog();
1274 glu::Texture srcTex (gl);
1275 const int xOffset = 8;
1276 const int yOffset = 16;
1277 const int xSize = de::clamp(16, 0, reference.getWidth() - xOffset);
1278 const int ySize = de::clamp(16, 0, reference.getHeight() - yOffset);
1279 tcu::Texture2D src (glu::mapGLTransferFormat(m_format, m_type), xSize, ySize);
1281 log << tcu::TestLog::Message << "Modifying EGLImage with gl.texSubImage2D" << tcu::TestLog::EndMessage;
1284 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));
1286 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, *srcTex));
1287 imageTargetTexture2D(api.m_egl, gl, **img);
1288 GLU_CHECK_GLW_CALL(gl, texSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, src.getWidth(), src.getHeight(), m_format, m_type, src.getLevel(0).getDataPtr()));
1289 GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, 0));
1290 GLU_CHECK_GLW_CALL(gl, finish());
1292 tcu::copy(tcu::getSubregion(reference.getLevel(0), xOffset, yOffset, 0, xSize, ySize, 1), src.getLevel(0));
1297 bool GLESImageApi::ModifyRenderbuffer::invokeGLES (GLESImageApi& api, MovePtr<UniqueImage>& img, tcu::Texture2D& reference) const
1299 const glw::Functions& gl = api.m_gl;
1300 tcu::TestLog& log = api.getLog();
1301 glu::Framebuffer framebuffer (gl);
1302 glu::Renderbuffer renderbuffer (gl);
1304 log << tcu::TestLog::Message << "Modifying EGLImage with glClear to renderbuffer" << tcu::TestLog::EndMessage;
1306 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer));
1307 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer));
1309 imageTargetRenderbuffer(api.m_egl, gl, **img);
1311 initializeRbo(api, *renderbuffer, reference);
1313 GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
1314 GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0));
1316 GLU_CHECK_GLW_CALL(gl, finish());
1321 void GLESImageApi::ModifyRenderbufferClearColor::initializeRbo (GLESImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
1323 const glw::Functions& gl = api.m_gl;
1325 framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, renderbuffer);
1327 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1328 GLU_CHECK_GLW_CALL(gl, clearColor(m_color.x(), m_color.y(), m_color.z(), m_color.w()));
1329 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
1331 tcu::clear(reference.getLevel(0), m_color);
1334 void GLESImageApi::ModifyRenderbufferClearDepth::initializeRbo (GLESImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
1336 const glw::Functions& gl = api.m_gl;
1338 framebufferRenderbuffer(gl, GL_DEPTH_ATTACHMENT, renderbuffer);
1340 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1341 GLU_CHECK_GLW_CALL(gl, clearDepthf(m_depth));
1342 GLU_CHECK_GLW_CALL(gl, clear(GL_DEPTH_BUFFER_BIT));
1344 tcu::clearDepth(reference.getLevel(0), m_depth);
1347 void GLESImageApi::ModifyRenderbufferClearStencil::initializeRbo (GLESImageApi& api, GLuint renderbuffer, tcu::Texture2D& reference) const
1349 const glw::Functions& gl = api.m_gl;
1351 framebufferRenderbuffer(gl, GL_STENCIL_ATTACHMENT, renderbuffer);
1353 GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight()));
1354 GLU_CHECK_GLW_CALL(gl, clearStencil(m_stencil));
1355 GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT));
1357 tcu::clearStencil(reference.getLevel(0), m_stencil);
1360 class ImageFormatCase : public TestCase, private glu::CallLogWrapper
1363 ImageFormatCase (EglTestContext& eglTestCtx, const TestSpec& spec);
1364 ~ImageFormatCase (void);
1368 IterateResult iterate (void);
1369 void checkExtensions (void);
1372 EGLConfig getConfig (void);
1374 const TestSpec m_spec;
1376 vector<ImageApi*> m_apiContexts;
1378 EGLDisplay m_display;
1379 eglu::NativeWindow* m_window;
1380 EGLSurface m_surface;
1383 MovePtr<UniqueImage> m_img;
1384 tcu::Texture2D m_refImg;
1385 glw::Functions m_gl;
1388 EGLConfig ImageFormatCase::getConfig (void)
1390 const GLint glesApi = m_spec.contexts[0] == TestSpec::API_GLES3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
1391 const EGLint attribList[] =
1393 EGL_RENDERABLE_TYPE, glesApi,
1394 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
1403 return eglu::chooseSingleConfig(m_eglTestCtx.getLibrary(), m_display, attribList);
1406 ImageFormatCase::ImageFormatCase (EglTestContext& eglTestCtx, const TestSpec& spec)
1407 : TestCase (eglTestCtx, spec.name.c_str(), spec.desc.c_str())
1408 , glu::CallLogWrapper (m_gl, eglTestCtx.getTestContext().getLog())
1410 , m_display (EGL_NO_DISPLAY)
1411 , m_window (DE_NULL)
1412 , m_surface (EGL_NO_SURFACE)
1415 , m_refImg (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1)
1419 ImageFormatCase::~ImageFormatCase (void)
1424 void ImageFormatCase::checkExtensions (void)
1426 set<string> exts = getSupportedExtensions(getLog(), m_eglTestCtx.getLibrary(), m_display, m_gl);
1428 for (int operationNdx = 0; operationNdx < (int)m_spec.operations.size(); operationNdx++)
1430 const TestSpec::Operation& op = m_spec.operations[operationNdx];
1431 const string ext = op.action->getRequiredExtension();
1433 if (!de::contains(exts, ext))
1434 TCU_THROW_EXPR(NotSupportedError, "Extension not supported", ext.c_str());
1438 void ImageFormatCase::init (void)
1440 const Library& egl = m_eglTestCtx.getLibrary();
1441 const eglu::NativeWindowFactory& windowFactory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
1445 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
1447 // GLES3 requires either EGL 1.5 or EGL_KHR_create_context extension.
1448 if (m_spec.contexts[0] == TestSpec::API_GLES3 && eglu::getVersion(egl, m_display) < eglu::Version(1, 5))
1451 const vector<string> eglExts = eglu::getDisplayExtensions(egl, m_display);
1452 exts.insert(eglExts.begin(), eglExts.end());
1454 if (!de::contains(exts, "EGL_KHR_create_context"))
1456 getLog() << tcu::TestLog::Message
1457 << "EGL version is under 1.5 and the test is using OpenGL ES 3.2."
1458 << "This requires EGL_KHR_create_context extension."
1459 << tcu::TestLog::EndMessage;
1460 TCU_THROW(NotSupportedError, "Extension not supported: EGL_KHR_create_context");
1464 m_config = getConfig();
1465 m_window = windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL, eglu::WindowParams(480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine())));
1466 m_surface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_display, m_config, DE_NULL);
1469 const char* extensions[] = { "GL_OES_EGL_image" };
1473 if (m_spec.contexts[0] == TestSpec::API_GLES3)
1478 m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(major, minor), DE_LENGTH_OF_ARRAY(extensions), &extensions[0]);
1481 for (int contextNdx = 0; contextNdx < (int)m_spec.contexts.size(); contextNdx++)
1483 ImageApi* api = DE_NULL;
1484 switch (m_spec.contexts[contextNdx])
1486 case TestSpec::API_GLES2:
1488 api = new GLESImageApi(egl, m_gl, contextNdx, getLog(), m_display, m_surface, m_config, 2);
1492 case TestSpec::API_GLES3:
1494 api = new GLESImageApi(egl, m_gl, contextNdx, getLog(), m_display, m_surface, m_config, 3);
1502 m_apiContexts.push_back(api);
1513 void ImageFormatCase::deinit (void)
1515 const Library& egl = m_eglTestCtx.getLibrary();
1519 for (int contexNdx = 0 ; contexNdx < (int)m_apiContexts.size(); contexNdx++)
1520 delete m_apiContexts[contexNdx];
1522 m_apiContexts.clear();
1524 if (m_surface != EGL_NO_SURFACE)
1526 egl.destroySurface(m_display, m_surface);
1527 m_surface = EGL_NO_SURFACE;
1533 if (m_display != EGL_NO_DISPLAY)
1535 egl.terminate(m_display);
1536 m_display = EGL_NO_DISPLAY;
1540 TestCase::IterateResult ImageFormatCase::iterate (void)
1542 const TestSpec::Operation& op = m_spec.operations[m_curIter++];
1543 ImageApi& api = *m_apiContexts[op.apiIndex];
1544 const bool isOk = op.action->invoke(api, m_img, m_refImg);
1546 if (isOk && m_curIter < (int)m_spec.operations.size())
1549 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1551 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1556 struct LabeledAction
1559 MovePtr<Action> action;
1562 // A simple vector mockup that we need because MovePtr isn't copy-constructible.
1563 struct LabeledActions
1565 LabeledActions (void) : m_numActions(0){}
1566 LabeledAction& operator[] (int ndx) { DE_ASSERT(0 <= ndx && ndx < m_numActions); return m_actions[ndx]; }
1567 void add (const string& label, MovePtr<Action> action);
1568 int size (void) const { return m_numActions; }
1570 LabeledAction m_actions[64];
1574 void LabeledActions::add (const string& label, MovePtr<Action> action)
1576 DE_ASSERT(m_numActions < DE_LENGTH_OF_ARRAY(m_actions));
1577 m_actions[m_numActions].label = label;
1578 m_actions[m_numActions].action = action;
1582 class ImageTests : public TestCaseGroup
1585 ImageTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1586 : TestCaseGroup(eglTestCtx, name.c_str(), desc.c_str()) {}
1588 void addCreateTexture (const string& name, EGLenum source, GLenum internalFormat, GLenum format, GLenum type);
1589 void addCreateRenderbuffer (const string& name, GLenum format);
1590 void addCreateAndroidNative (const string& name, GLenum format, bool isYUV);
1591 void addCreateAndroidNativeArray (const string& name, GLenum format, deUint32 numLayers);
1592 void addCreateTexture2DActions (const string& prefix);
1593 void addCreateTextureCubemapActions (const string& suffix, GLenum internalFormat, GLenum format, GLenum type);
1594 void addCreateRenderbufferActions (void);
1595 void addCreateAndroidNativeActions (void);
1597 LabeledActions m_createActions;
1600 void ImageTests::addCreateTexture (const string& name, EGLenum source, GLenum internalFormat, GLenum format, GLenum type)
1602 m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createTextureImageSource(source, internalFormat, format, type))));
1605 void ImageTests::addCreateRenderbuffer (const string& name, GLenum format)
1607 m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createRenderbufferImageSource(format))));
1610 void ImageTests::addCreateAndroidNative (const string& name, GLenum format, bool isYUV = false)
1612 m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createAndroidNativeImageSource(format, 1u, isYUV))));
1615 void ImageTests::addCreateAndroidNativeArray (const string& name, GLenum format, deUint32 numLayers)
1617 m_createActions.add(name, MovePtr<Action>(new GLESImageApi::Create(createAndroidNativeImageSource(format, numLayers, false), numLayers)));
1620 void ImageTests::addCreateTexture2DActions (const string& prefix)
1622 addCreateTexture(prefix + "rgb8", EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1623 addCreateTexture(prefix + "rgb565", EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
1624 addCreateTexture(prefix + "rgba8", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1625 addCreateTexture(prefix + "rgb5_a1", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
1626 addCreateTexture(prefix + "rgba4", EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
1629 void ImageTests::addCreateTextureCubemapActions (const string& suffix, GLenum internalFormat, GLenum format, GLenum type)
1631 addCreateTexture("cubemap_positive_x" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, internalFormat, format, type);
1632 addCreateTexture("cubemap_positive_y" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR, internalFormat, format, type);
1633 addCreateTexture("cubemap_positive_z" + suffix, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR, internalFormat, format, type);
1634 addCreateTexture("cubemap_negative_x" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR, internalFormat, format, type);
1635 addCreateTexture("cubemap_negative_y" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR, internalFormat, format, type);
1636 addCreateTexture("cubemap_negative_z" + suffix, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR, internalFormat, format, type);
1639 void ImageTests::addCreateRenderbufferActions (void)
1641 addCreateRenderbuffer("renderbuffer_rgba4", GL_RGBA4);
1642 addCreateRenderbuffer("renderbuffer_rgb5_a1", GL_RGB5_A1);
1643 addCreateRenderbuffer("renderbuffer_rgb565", GL_RGB565);
1644 addCreateRenderbuffer("renderbuffer_depth16", GL_DEPTH_COMPONENT16);
1645 addCreateRenderbuffer("renderbuffer_stencil", GL_STENCIL_INDEX8);
1648 void ImageTests::addCreateAndroidNativeActions (void)
1650 addCreateAndroidNative("android_native_rgba4", GL_RGBA4);
1651 addCreateAndroidNative("android_native_rgb5_a1", GL_RGB5_A1);
1652 addCreateAndroidNative("android_native_rgb565", GL_RGB565);
1653 addCreateAndroidNative("android_native_rgb8", GL_RGB8);
1654 addCreateAndroidNative("android_native_rgba8", GL_RGBA8);
1655 addCreateAndroidNative("android_native_d16", GL_DEPTH_COMPONENT16);
1656 addCreateAndroidNative("android_native_d24", GL_DEPTH_COMPONENT24);
1657 addCreateAndroidNative("android_native_d24s8", GL_DEPTH24_STENCIL8);
1658 addCreateAndroidNative("android_native_d32f", GL_DEPTH_COMPONENT32F);
1659 addCreateAndroidNative("android_native_d32fs8", GL_DEPTH32F_STENCIL8);
1660 addCreateAndroidNative("android_native_rgb10a2", GL_RGB10_A2);
1661 addCreateAndroidNative("android_native_rgba16f", GL_RGBA16F);
1662 addCreateAndroidNative("android_native_s8", GL_STENCIL_INDEX8);
1663 addCreateAndroidNative("android_native_yuv420", GL_RGBA8, true);
1665 addCreateAndroidNativeArray("android_native_array_rgba4", GL_RGBA4, 4u);
1666 addCreateAndroidNativeArray("android_native_array_rgb5_a1", GL_RGB5_A1, 4u);
1667 addCreateAndroidNativeArray("android_native_array_rgb565", GL_RGB565, 4u);
1668 addCreateAndroidNativeArray("android_native_array_rgb8", GL_RGB8, 4u);
1669 addCreateAndroidNativeArray("android_native_array_rgba8", GL_RGBA8, 4u);
1672 class RenderTests : public ImageTests
1675 RenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1676 : ImageTests (eglTestCtx, name, desc) {}
1678 void addRenderActions (void);
1679 LabeledActions m_renderActions;
1682 void RenderTests::addRenderActions (void)
1684 m_renderActions.add("texture", MovePtr<Action>(new GLESImageApi::RenderTexture2D()));
1685 m_renderActions.add("texture_array", MovePtr<Action>(new GLESImageApi::RenderTexture2DArray()));
1686 m_renderActions.add("read_pixels", MovePtr<Action>(new GLESImageApi::RenderReadPixelsRenderbuffer()));
1687 m_renderActions.add("depth_buffer", MovePtr<Action>(new GLESImageApi::RenderDepthbuffer()));
1688 m_renderActions.add("stencil_buffer", MovePtr<Action>(new GLESImageApi::RenderStencilbuffer()));
1689 m_renderActions.add("yuv_texture", MovePtr<Action>(new GLESImageApi::RenderYUVTexture()));
1692 class SimpleCreationTests : public RenderTests
1695 SimpleCreationTests (EglTestContext& eglTestCtx, const string& name, const string& desc) : RenderTests(eglTestCtx, name, desc) {}
1699 bool isDepthFormat (GLenum format)
1714 case GL_DEPTH_COMPONENT16:
1715 case GL_DEPTH_COMPONENT24:
1716 case GL_DEPTH_COMPONENT32:
1717 case GL_DEPTH_COMPONENT32F:
1718 case GL_DEPTH24_STENCIL8:
1719 case GL_DEPTH32F_STENCIL8:
1722 case GL_STENCIL_INDEX8:
1731 bool isStencilFormat (GLenum format)
1746 case GL_DEPTH_COMPONENT16:
1747 case GL_DEPTH_COMPONENT24:
1748 case GL_DEPTH_COMPONENT32:
1749 case GL_DEPTH_COMPONENT32F:
1752 case GL_STENCIL_INDEX8:
1753 case GL_DEPTH24_STENCIL8:
1754 case GL_DEPTH32F_STENCIL8:
1763 bool isCompatibleCreateAndRenderActions (const Action& create, const Action& render)
1765 if (const GLESImageApi::Create* glesCreate = dynamic_cast<const GLESImageApi::Create*>(&create))
1767 bool yuvFormatTest = glesCreate->isYUVFormatImage();
1768 // this path only for none-yuv format tests
1771 const GLenum createFormat = glesCreate->getEffectiveFormat();
1773 if (dynamic_cast<const GLESImageApi::RenderTexture2DArray*>(&render))
1775 // Makes sense only for texture arrays.
1776 if (glesCreate->getNumLayers() <= 1u)
1779 else if (glesCreate->getNumLayers() != 1u)
1781 // Skip other render actions for texture arrays.
1785 if (dynamic_cast<const GLESImageApi::RenderTexture2D*>(&render))
1787 // GLES does not have depth or stencil textures
1788 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1792 if (dynamic_cast<const GLESImageApi::RenderReadPixelsRenderbuffer*>(&render))
1794 // GLES does not support readPixels for depth or stencil.
1795 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1799 if (dynamic_cast<const GLESImageApi::RenderDepthbuffer*>(&render))
1801 // Copying non-depth data to depth renderbuffer and expecting meaningful
1802 // results just doesn't make any sense.
1803 if (!isDepthFormat(createFormat))
1807 if (dynamic_cast<const GLESImageApi::RenderStencilbuffer*>(&render))
1809 // Copying non-stencil data to stencil renderbuffer and expecting meaningful
1810 // results just doesn't make any sense.
1811 if (!isStencilFormat(createFormat))
1815 if (dynamic_cast<const GLESImageApi::RenderYUVTexture*>(&render))
1817 // In yuv path rendering with non-yuv format native buffer and expecting meaningful
1818 // results just doesn't make any sense
1824 else if (dynamic_cast<const GLESImageApi::RenderYUVTexture*>(&render))
1835 void SimpleCreationTests::init (void)
1837 addCreateTexture2DActions("texture_");
1838 addCreateTextureCubemapActions("_rgba", GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1839 addCreateTextureCubemapActions("_rgb", GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
1840 addCreateRenderbufferActions();
1841 addCreateAndroidNativeActions();
1844 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
1846 const LabeledAction& createAction = m_createActions[createNdx];
1848 for (int renderNdx = 0; renderNdx < m_renderActions.size(); renderNdx++)
1850 const LabeledAction& renderAction = m_renderActions[renderNdx];
1853 if (!isCompatibleCreateAndRenderActions(*createAction.action, *renderAction.action))
1856 if (dynamic_cast<const GLESImageApi::RenderTexture2DArray*>(renderAction.action.get()) ||
1857 dynamic_cast<const GLESImageApi::RenderYUVTexture*>(renderAction.action.get()))
1859 // Texture array tests require GLES3.
1860 spec.name = std::string("gles3_") + createAction.label + "_" + renderAction.label;
1861 spec.contexts.push_back(TestSpec::API_GLES3);
1865 spec.name = std::string("gles2_") + createAction.label + "_" + renderAction.label;
1866 spec.contexts.push_back(TestSpec::API_GLES2);
1869 spec.desc = spec.name;
1870 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
1871 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
1873 addChild(new ImageFormatCase(m_eglTestCtx, spec));
1878 TestCaseGroup* createSimpleCreationTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
1880 return new SimpleCreationTests(eglTestCtx, name, desc);
1883 bool isCompatibleFormats (GLenum createFormat, GLenum modifyFormat, GLenum modifyType)
1885 switch (modifyFormat)
1890 case GL_UNSIGNED_BYTE:
1891 return createFormat == GL_RGB
1892 || createFormat == GL_RGB8
1893 || createFormat == GL_RGB565
1894 || createFormat == GL_SRGB8;
1897 return createFormat == GL_RGB8_SNORM;
1899 case GL_UNSIGNED_SHORT_5_6_5:
1900 return createFormat == GL_RGB
1901 || createFormat == GL_RGB565;
1903 case GL_UNSIGNED_INT_10F_11F_11F_REV:
1904 return createFormat == GL_R11F_G11F_B10F;
1906 case GL_UNSIGNED_INT_5_9_9_9_REV:
1907 return createFormat == GL_RGB9_E5;
1910 return createFormat == GL_RGB16F
1911 || createFormat == GL_R11F_G11F_B10F
1912 || createFormat == GL_RGB9_E5;
1915 return createFormat == GL_RGB16F
1916 || createFormat == GL_RGB32F
1917 || createFormat == GL_R11F_G11F_B10F
1918 || createFormat == GL_RGB9_E5;
1921 DE_FATAL("Unknown modify type");
1928 case GL_UNSIGNED_BYTE:
1929 return createFormat == GL_RGBA8
1930 || createFormat == GL_RGB5_A1
1931 || createFormat == GL_RGBA4
1932 || createFormat == GL_SRGB8_ALPHA8
1933 || createFormat == GL_RGBA;
1935 case GL_UNSIGNED_SHORT_4_4_4_4:
1936 return createFormat == GL_RGBA4
1937 || createFormat == GL_RGBA;
1939 case GL_UNSIGNED_SHORT_5_5_5_1:
1940 return createFormat == GL_RGB5_A1
1941 || createFormat == GL_RGBA;
1943 case GL_UNSIGNED_INT_2_10_10_10_REV:
1944 return createFormat == GL_RGB10_A2
1945 || createFormat == GL_RGB5_A1;
1948 return createFormat == GL_RGBA16F;
1951 return createFormat == GL_RGBA16F
1952 || createFormat == GL_RGBA32F;
1955 DE_FATAL("Unknown modify type");
1960 DE_FATAL("Unknown modify format");
1965 bool isCompatibleCreateAndModifyActions (const Action& create, const Action& modify)
1967 if (const GLESImageApi::Create* glesCreate = dynamic_cast<const GLESImageApi::Create*>(&create))
1969 // No modify tests for texture arrays.
1970 if (glesCreate->getNumLayers() > 1u)
1972 // No modify tests for yuv format image.
1973 if (glesCreate->isYUVFormatImage())
1976 const GLenum createFormat = glesCreate->getEffectiveFormat();
1978 if (const GLESImageApi::ModifyTexSubImage* glesTexSubImageModify = dynamic_cast<const GLESImageApi::ModifyTexSubImage*>(&modify))
1980 const GLenum modifyFormat = glesTexSubImageModify->getFormat();
1981 const GLenum modifyType = glesTexSubImageModify->getType();
1983 return isCompatibleFormats(createFormat, modifyFormat, modifyType);
1986 if (dynamic_cast<const GLESImageApi::ModifyRenderbufferClearColor*>(&modify))
1988 // reintepreting color as non-color is not meaningful
1989 if (isDepthFormat(createFormat) || isStencilFormat(createFormat))
1993 if (dynamic_cast<const GLESImageApi::ModifyRenderbufferClearDepth*>(&modify))
1995 // reintepreting depth as non-depth is not meaningful
1996 if (!isDepthFormat(createFormat))
2000 if (dynamic_cast<const GLESImageApi::ModifyRenderbufferClearStencil*>(&modify))
2002 // reintepreting stencil as non-stencil is not meaningful
2003 if (!isStencilFormat(createFormat))
2015 class MultiContextRenderTests : public RenderTests
2018 MultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc);
2020 void addClearActions (void);
2022 LabeledActions m_clearActions;
2025 MultiContextRenderTests::MultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
2026 : RenderTests (eglTestCtx, name, desc)
2030 void MultiContextRenderTests::addClearActions (void)
2032 m_clearActions.add("clear_color", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearColor(tcu::Vec4(0.8f, 0.2f, 0.9f, 1.0f))));
2033 m_clearActions.add("clear_depth", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearDepth(0.75f)));
2034 m_clearActions.add("clear_stencil", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearStencil(97)));
2037 void MultiContextRenderTests::init (void)
2039 addCreateTexture2DActions("texture_");
2040 addCreateTextureCubemapActions("_rgba8", GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
2041 addCreateTextureCubemapActions("_rgb8", GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
2042 addCreateRenderbufferActions();
2043 addCreateAndroidNativeActions();
2047 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
2048 for (int renderNdx = 0; renderNdx < m_renderActions.size(); renderNdx++)
2049 for (int clearNdx = 0; clearNdx < m_clearActions.size(); clearNdx++)
2051 const LabeledAction& createAction = m_createActions[createNdx];
2052 const LabeledAction& renderAction = m_renderActions[renderNdx];
2053 const LabeledAction& clearAction = m_clearActions[clearNdx];
2056 if (!isCompatibleCreateAndRenderActions(*createAction.action, *renderAction.action))
2058 if (!isCompatibleCreateAndModifyActions(*createAction.action, *clearAction.action))
2061 spec.name = std::string("gles2_") + createAction.label + "_" + renderAction.label;
2063 const GLESImageApi::Create* glesCreate = dynamic_cast<const GLESImageApi::Create*>(createAction.action.get());
2066 DE_FATAL("Dynamic casting to GLESImageApi::Create* failed");
2068 const GLenum createFormat = glesCreate->getEffectiveFormat();
2070 if (isDepthFormat(createFormat) && isStencilFormat(createFormat))
2072 // Combined depth and stencil format. Add the clear action label to avoid test
2074 spec.name += std::string("_") + clearAction.label;
2077 spec.desc = spec.name;
2079 spec.contexts.push_back(TestSpec::API_GLES2);
2080 spec.contexts.push_back(TestSpec::API_GLES2);
2082 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
2083 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
2084 spec.operations.push_back(TestSpec::Operation(0, *clearAction.action));
2085 spec.operations.push_back(TestSpec::Operation(1, *createAction.action));
2086 spec.operations.push_back(TestSpec::Operation(0, *renderAction.action));
2087 spec.operations.push_back(TestSpec::Operation(1, *renderAction.action));
2089 addChild(new ImageFormatCase(m_eglTestCtx, spec));
2093 TestCaseGroup* createMultiContextRenderTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
2095 return new MultiContextRenderTests(eglTestCtx, name, desc);
2098 class ModifyTests : public ImageTests
2101 ModifyTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
2102 : ImageTests(eglTestCtx, name, desc) {}
2107 void addModifyActions(void);
2109 LabeledActions m_modifyActions;
2110 GLESImageApi::RenderTryAll m_renderAction;
2113 void ModifyTests::addModifyActions (void)
2115 m_modifyActions.add("tex_subimage_rgb8", MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGB, GL_UNSIGNED_BYTE)));
2116 m_modifyActions.add("tex_subimage_rgb565", MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGB, GL_UNSIGNED_SHORT_5_6_5)));
2117 m_modifyActions.add("tex_subimage_rgba8", MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_BYTE)));
2118 m_modifyActions.add("tex_subimage_rgb5_a1", MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1)));
2119 m_modifyActions.add("tex_subimage_rgba4", MovePtr<Action>(new GLESImageApi::ModifyTexSubImage(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4)));
2121 m_modifyActions.add("renderbuffer_clear_color", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearColor(tcu::Vec4(0.3f, 0.5f, 0.3f, 1.0f))));
2122 m_modifyActions.add("renderbuffer_clear_depth", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearDepth(0.7f)));
2123 m_modifyActions.add("renderbuffer_clear_stencil", MovePtr<Action>(new GLESImageApi::ModifyRenderbufferClearStencil(78)));
2126 void ModifyTests::init (void)
2128 addCreateTexture2DActions("tex_");
2129 addCreateRenderbufferActions();
2130 addCreateAndroidNativeActions();
2133 for (int createNdx = 0; createNdx < m_createActions.size(); createNdx++)
2135 LabeledAction& createAction = m_createActions[createNdx];
2137 for (int modifyNdx = 0; modifyNdx < m_modifyActions.size(); modifyNdx++)
2139 LabeledAction& modifyAction = m_modifyActions[modifyNdx];
2141 if (!isCompatibleCreateAndModifyActions(*createAction.action, *modifyAction.action))
2145 spec.name = createAction.label + "_" + modifyAction.label;
2146 spec.desc = "gles2_tex_sub_image";
2148 spec.contexts.push_back(TestSpec::API_GLES2);
2150 spec.operations.push_back(TestSpec::Operation(0, *createAction.action));
2151 spec.operations.push_back(TestSpec::Operation(0, m_renderAction));
2152 spec.operations.push_back(TestSpec::Operation(0, *modifyAction.action));
2153 spec.operations.push_back(TestSpec::Operation(0, m_renderAction));
2155 addChild(new ImageFormatCase(m_eglTestCtx, spec));
2160 TestCaseGroup* createModifyTests (EglTestContext& eglTestCtx, const string& name, const string& desc)
2162 return new ModifyTests(eglTestCtx, name, desc);