From b0dff9c6bdd4eb723a0fad1e9d139430e2542202 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jarkko=20P=C3=B6yry?= Date: Wed, 6 May 2015 13:24:00 -0700 Subject: [PATCH] Add missing EGLimage stencil image verifier. - Add stencil buffer verifier. - Avoid adding new tests to mustpass. Bug: 20638016 Change-Id: I8dbeb51b8dfb4392b3fa4216772308ec9e450cb4 --- android/cts/master/src/egl-failures.txt | 2 + modules/egl/teglImageFormatTests.cpp | 139 ++++++++++++++++++++++++++++++-- modules/egl/teglImageUtil.cpp | 8 +- 3 files changed, 142 insertions(+), 7 deletions(-) diff --git a/android/cts/master/src/egl-failures.txt b/android/cts/master/src/egl-failures.txt index fc62579..b9004ee 100644 --- a/android/cts/master/src/egl-failures.txt +++ b/android/cts/master/src/egl-failures.txt @@ -447,6 +447,7 @@ dEQP-EGL.functional.image.create.gles2_renderbuffer_rgb5_a1_read_pixels dEQP-EGL.functional.image.create.gles2_renderbuffer_rgb5_a1_texture dEQP-EGL.functional.image.create.gles2_renderbuffer_rgba4_read_pixels dEQP-EGL.functional.image.create.gles2_renderbuffer_rgba4_texture +dEQP-EGL.functional.image.create.gles2_renderbuffer_stencil_stencil_buffer dEQP-EGL.functional.image.create.gles2_texture_rgba4_read_pixels dEQP-EGL.functional.image.create.gles2_texture_rgba4_texture dEQP-EGL.functional.image.create.gles2_texture_rgba5_a1_read_pixels @@ -511,6 +512,7 @@ dEQP-EGL.functional.image.render_multiple_contexts.gles2_renderbuffer_rgb5_a1_re dEQP-EGL.functional.image.render_multiple_contexts.gles2_renderbuffer_rgb5_a1_texture dEQP-EGL.functional.image.render_multiple_contexts.gles2_renderbuffer_rgba4_read_pixels dEQP-EGL.functional.image.render_multiple_contexts.gles2_renderbuffer_rgba4_texture +dEQP-EGL.functional.image.render_multiple_contexts.gles2_renderbuffer_stencil_stencil_buffer dEQP-EGL.functional.image.render_multiple_contexts.gles2_texture_rgba4_read_pixels dEQP-EGL.functional.image.render_multiple_contexts.gles2_texture_rgba4_texture dEQP-EGL.functional.image.render_multiple_contexts.gles2_texture_rgba5_a1_read_pixels diff --git a/modules/egl/teglImageFormatTests.cpp b/modules/egl/teglImageFormatTests.cpp index d40dc09..1974e85 100644 --- a/modules/egl/teglImageFormatTests.cpp +++ b/modules/egl/teglImageFormatTests.cpp @@ -201,6 +201,7 @@ public: class RenderTextureCubemap : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr& image, tcu::Texture2D& ref) const; }; class RenderReadPixelsRenderbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr& image, tcu::Texture2D& ref) const; }; class RenderDepthbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr& image, tcu::Texture2D& ref) const; }; + class RenderStencilbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr& image, tcu::Texture2D& ref) const; }; class RenderTryAll : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr& image, tcu::Texture2D& ref) const; }; class Modify : public GLES2Action @@ -539,6 +540,7 @@ bool GLES2ImageApi::RenderDepthbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr< GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6)); } + GLU_CHECK_GLW_CALL(gl, depthMask(GL_TRUE)); GLU_CHECK_GLW_CALL(gl, disable(GL_DEPTH_TEST)); GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc)); @@ -564,13 +566,130 @@ bool GLES2ImageApi::RenderDepthbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr< } } - GLU_CHECK_GLW_CALL(gl, depthMask(GL_TRUE)); GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0)); GLU_CHECK_GLW_CALL(gl, finish()); return tcu::pixelThresholdCompare(log, "Depth buffer rendering result", "Result from rendering with depth buffer", referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT); } +bool GLES2ImageApi::RenderStencilbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr& img, tcu::Texture2D& reference) const +{ + // Branch only taken in TryAll case + if (reference.getFormat().order != tcu::TextureFormat::DS && reference.getFormat().order != tcu::TextureFormat::S) + throw IllegalRendererException(); // Skip, interpreting non-stencil data as stencil data is not meaningful + + const glw::Functions& gl = api.m_gl; + tcu::TestLog& log = api.getLog(); + Framebuffer framebuffer (gl); + Renderbuffer renderbufferColor (gl); + Renderbuffer renderbufferStencil (gl); + const tcu::RGBA compareThreshold (32, 32, 32, 32); // layer colors are far apart, large thresholds are ok + const deUint32 numStencilBits = tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(reference.getLevel(0).getFormat(), tcu::Sampler::MODE_STENCIL)).x(); + const deUint32 maxStencil = deBitMask32(0, numStencilBits); + + log << tcu::TestLog::Message << "Rendering with stencil buffer" << tcu::TestLog::EndMessage; + + GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, *framebuffer)); + + GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferColor)); + GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight())); + framebufferRenderbuffer(gl, GL_COLOR_ATTACHMENT0, *renderbufferColor); + + GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, *renderbufferStencil)); + imageTargetRenderbuffer(api.m_egl, gl, **img); + framebufferRenderbuffer(gl, GL_STENCIL_ATTACHMENT, *renderbufferStencil); + GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, 0)); + + GLU_CHECK_GLW_CALL(gl, viewport(0, 0, reference.getWidth(), reference.getHeight())); + + // Render + const char* vertexShader = + "attribute highp vec2 a_coord;\n" + "void main(void) {\n" + "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n" + "}\n"; + + const char* fragmentShader = + "uniform mediump vec4 u_color;\n" + "void main(void) {\n" + "\tgl_FragColor = u_color;\n" + "}"; + + Program program(gl, vertexShader, fragmentShader); + TCU_CHECK(program.isOk()); + + GLuint glProgram = program.getProgram(); + GLU_CHECK_GLW_CALL(gl, useProgram(glProgram)); + + GLuint coordLoc = gl.getAttribLocation(glProgram, "a_coord"); + TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord"); + + GLuint colorLoc = gl.getUniformLocation(glProgram, "u_color"); + TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color"); + + GLU_CHECK_GLW_CALL(gl, clearColor(0.5f, 1.0f, 0.5f, 1.0f)); + GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT)); + + tcu::Vec4 stencilLevelColors[] = { + tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), + tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), + tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), + tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), + tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f), + + tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), + tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), + tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f), + tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f), + tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f) + }; + + GLU_CHECK_GLW_CALL(gl, enableVertexAttribArray(coordLoc)); + GLU_CHECK_GLW_CALL(gl, vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, squareTriangleCoords)); + + GLU_CHECK_GLW_CALL(gl, enable(GL_STENCIL_TEST)); + GLU_CHECK_GLW_CALL(gl, stencilOp(GL_KEEP, GL_KEEP, GL_KEEP)); + + for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++) + { + const tcu::Vec4 color = stencilLevelColors[level]; + const int stencil = (int)(((level + 1) * 0.1f) * maxStencil); + + GLU_CHECK_GLW_CALL(gl, stencilFunc(GL_LESS, stencil, 0xFFFFFFFFu)); + GLU_CHECK_GLW_CALL(gl, uniform4f(colorLoc, color.x(), color.y(), color.z(), color.w())); + GLU_CHECK_GLW_CALL(gl, drawArrays(GL_TRIANGLES, 0, 6)); + } + + GLU_CHECK_GLW_CALL(gl, disable(GL_STENCIL_TEST)); + GLU_CHECK_GLW_CALL(gl, disableVertexAttribArray(coordLoc)); + + const ConstPixelBufferAccess& refAccess = reference.getLevel(0); + tcu::Surface screen (reference.getWidth(), reference.getHeight()); + tcu::Surface referenceScreen (reference.getWidth(), reference.getHeight()); + + gl.readPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr()); + + for (int y = 0; y < reference.getHeight(); y++) + for (int x = 0; x < reference.getWidth(); x++) + { + tcu::Vec4 result = tcu::Vec4(0.5f, 1.0f, 0.5f, 1.0f); + + for (int level = 0; level < DE_LENGTH_OF_ARRAY(stencilLevelColors); level++) + { + const int levelStencil = (int)(((level + 1) * 0.1f) * maxStencil); + if (levelStencil < refAccess.getPixStencil(x, y)) + result = stencilLevelColors[level]; + } + + referenceScreen.getAccess().setPixel(result, x, y); + } + + GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, 0)); + GLU_CHECK_GLW_CALL(gl, finish()); + + return tcu::pixelThresholdCompare(log, "StencilResult", "Result from rendering with stencil buffer", referenceScreen, screen, compareThreshold, tcu::COMPARE_LOG_RESULT); +} + bool GLES2ImageApi::RenderReadPixelsRenderbuffer::invokeGLES2 (GLES2ImageApi& api, MovePtr& img, tcu::Texture2D& reference) const { const glw::Functions& gl = api.m_gl; @@ -617,7 +736,8 @@ bool GLES2ImageApi::RenderTryAll::invokeGLES2 (GLES2ImageApi& api, MovePtr(new GLES2ImageApi::RenderTexture2D())); - m_renderActions.add("read_pixels", MovePtr(new GLES2ImageApi::RenderReadPixelsRenderbuffer())); - m_renderActions.add("depth_buffer", MovePtr(new GLES2ImageApi::RenderDepthbuffer())); + m_renderActions.add("texture", MovePtr(new GLES2ImageApi::RenderTexture2D())); + m_renderActions.add("read_pixels", MovePtr(new GLES2ImageApi::RenderReadPixelsRenderbuffer())); + m_renderActions.add("depth_buffer", MovePtr(new GLES2ImageApi::RenderDepthbuffer())); + m_renderActions.add("stencil_buffer", MovePtr(new GLES2ImageApi::RenderStencilbuffer())); } class SimpleCreationTests : public RenderTests @@ -1114,6 +1235,14 @@ bool isCompatibleCreateAndRenderActions (const Action& create, const Action& ren return false; } + if (dynamic_cast(&render)) + { + // Copying non-stencil data to stencil renderbuffer and expecting meaningful + // results just doesn't make any sense. + if (!isStencilFormat(createFormat)) + return false; + } + return true; } else diff --git a/modules/egl/teglImageUtil.cpp b/modules/egl/teglImageUtil.cpp index 9f47f5a..825361e 100644 --- a/modules/egl/teglImageUtil.cpp +++ b/modules/egl/teglImageUtil.cpp @@ -330,6 +330,9 @@ void initializeStencilRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref) 0x0F0CFDC7u, }; + const deUint32 numStencilBits = tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(ref.getLevel(0).getFormat(), tcu::Sampler::MODE_STENCIL)).x(); + const deUint32 stencilMask = deBitMask32(0, numStencilBits); + GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo)); GLU_CHECK_GLW_CALL(gl, clearStencil(0)); @@ -340,6 +343,7 @@ void initializeStencilRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref) GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST)); for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilValues); ++ndx) { + const deUint32 stencil = stencilValues[ndx] & stencilMask; const tcu::IVec2 size = tcu::IVec2((int)((DE_LENGTH_OF_ARRAY(stencilValues) - ndx) * (ref.getWidth() / float(DE_LENGTH_OF_ARRAY(stencilValues)))), (int)((DE_LENGTH_OF_ARRAY(stencilValues) - ndx) * (ref.getHeight() / float(DE_LENGTH_OF_ARRAY(stencilValues) + 4)))); // not symmetric @@ -347,10 +351,10 @@ void initializeStencilRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref) break; GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y())); - GLU_CHECK_GLW_CALL(gl, clearStencil(stencilValues[ndx])); + GLU_CHECK_GLW_CALL(gl, clearStencil(stencil)); GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT)); - tcu::clearStencil(tcu::getSubregion(ref.getLevel(0), 0, 0, size.x(), size.y()), stencilValues[ndx]); + tcu::clearStencil(tcu::getSubregion(ref.getLevel(0), 0, 0, size.x(), size.y()), stencil); } GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST)); -- 2.7.4