D3D11: Implement multisampled stencil resolve.
This implements a fairly slow path with readback for stencil blits,
and depth/stencil resolve. In a subsequent patch I'll implement the
depth blits.
BUG=angleproject:1246
Change-Id: I04151d1f49ca404d858172dff8286608eae29864
Reviewed-on: https://chromium-review.googlesource.com/359955
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
index 4180765..6f8ab65 100644
--- a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
+++ b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
@@ -6,6 +6,8 @@
#include "test_utils/ANGLETest.h"
+#include "test_utils/gl_raii.h"
+
using namespace angle;
class BlitFramebufferANGLETest : public ANGLETest
@@ -891,8 +893,96 @@
// TODO(geofflang): Fix the dependence on glBlitFramebufferANGLE without checks and assuming the
// default framebuffer is BGRA to enable the GL and GLES backends. (http://anglebug.com/1289)
+class BlitFramebufferTest : public ANGLETest
+{
+ protected:
+ BlitFramebufferTest()
+ {
+ setWindowWidth(256);
+ setWindowHeight(256);
+ setConfigRedBits(8);
+ setConfigGreenBits(8);
+ setConfigBlueBits(8);
+ setConfigAlphaBits(8);
+ setConfigDepthBits(24);
+ setConfigStencilBits(8);
+ }
+};
+
+// Test resolving a multisampled stencil buffer.
+TEST_P(BlitFramebufferTest, MultisampleStencil)
+{
+ GLRenderbuffer renderbuf;
+ glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, 256, 256);
+
+ const std::string &vertex =
+ "#version 300 es\n"
+ "in vec2 position;\n"
+ "void main() {\n"
+ " gl_Position = vec4(position, 0.0, 1.0);\n"
+ "}";
+ const std::string &fragment =
+ "#version 300 es\n"
+ "out mediump vec4 red;\n"
+ "void main() {\n"
+ " red = vec4(1.0, 0.0, 0.0, 1.0);\n"
+ "}";
+
+ ANGLE_GL_PROGRAM(drawRed, vertex, fragment);
+
+ GLFramebuffer framebuffer;
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
+ renderbuf.get());
+
+ ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ // fill the stencil buffer with 0x1
+ glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
+ glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+ glEnable(GL_STENCIL_TEST);
+ drawQuad(drawRed.get(), "position", 0.5f);
+
+ GLTexture destColorbuf;
+ glBindTexture(GL_TEXTURE_2D, destColorbuf.get());
+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
+
+ GLRenderbuffer destRenderbuf;
+ glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 256, 256);
+
+ GLFramebuffer resolved;
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved.get());
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ destColorbuf.get(), 0);
+ glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
+ destRenderbuf.get());
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
+ glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, resolved.get());
+
+ ASSERT_GL_NO_ERROR();
+
+ // Clear to green
+ glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+
+ // Draw red if the stencil is 0x1, which should be true after the blit/resolve.
+ glStencilFunc(GL_EQUAL, 0x1, 0xFF);
+ drawQuad(drawRed.get(), "position", 0.5f);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+
+ ASSERT_GL_NO_ERROR();
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(BlitFramebufferANGLETest,
ES2_D3D9(),
ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE),
ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE));
+
+ANGLE_INSTANTIATE_TEST(BlitFramebufferTest, ES3_D3D11());
\ No newline at end of file