Add missing EGLimage stencil image verifier.
- Add stencil buffer verifier.
- Avoid adding new tests to mustpass.
Bug: 20638016
Change-Id: I8dbeb51b8dfb4392b3fa4216772308ec9e450cb4
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_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_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 @@
class RenderTextureCubemap : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
class RenderReadPixelsRenderbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
class RenderDepthbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
+ class RenderStencilbuffer : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
class RenderTryAll : public Render { public: bool invokeGLES2 (GLES2ImageApi& api, MovePtr<UniqueImage>& image, tcu::Texture2D& ref) const; };
class Modify : public GLES2Action
@@ -539,6 +540,7 @@
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 @@
}
}
- 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<UniqueImage>& 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<UniqueImage>& img, tcu::Texture2D& reference) const
{
const glw::Functions& gl = api.m_gl;
@@ -617,7 +736,8 @@
GLES2ImageApi::RenderTexture2D renderTex2D;
GLES2ImageApi::RenderReadPixelsRenderbuffer renderReadPixels;
GLES2ImageApi::RenderDepthbuffer renderDepth;
- Action* actions[] = { &renderTex2D, &renderReadPixels, &renderDepth };
+ GLES2ImageApi::RenderStencilbuffer renderStencil;
+ Action* actions[] = { &renderTex2D, &renderReadPixels, &renderDepth, &renderStencil };
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(actions); ++ndx)
{
@@ -1024,9 +1144,10 @@
void RenderTests::addRenderActions (void)
{
- m_renderActions.add("texture", MovePtr<Action>(new GLES2ImageApi::RenderTexture2D()));
- m_renderActions.add("read_pixels", MovePtr<Action>(new GLES2ImageApi::RenderReadPixelsRenderbuffer()));
- m_renderActions.add("depth_buffer", MovePtr<Action>(new GLES2ImageApi::RenderDepthbuffer()));
+ m_renderActions.add("texture", MovePtr<Action>(new GLES2ImageApi::RenderTexture2D()));
+ m_renderActions.add("read_pixels", MovePtr<Action>(new GLES2ImageApi::RenderReadPixelsRenderbuffer()));
+ m_renderActions.add("depth_buffer", MovePtr<Action>(new GLES2ImageApi::RenderDepthbuffer()));
+ m_renderActions.add("stencil_buffer", MovePtr<Action>(new GLES2ImageApi::RenderStencilbuffer()));
}
class SimpleCreationTests : public RenderTests
@@ -1114,6 +1235,14 @@
return false;
}
+ if (dynamic_cast<const GLES2ImageApi::RenderStencilbuffer*>(&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 @@
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 @@
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 @@
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));