Vulkan: Fix resolve-with-subpass with non-zero read attachment
The draw framebuffer's color index was used to get the read buffer of
the source framebuffer.
Bug: b/159903491
Change-Id: I7a1626e6732367c14d46f1e1be4057998fdbf011
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2390440
Reviewed-by: Tim Van Patten <timvp@google.com>
Reviewed-by: Charlie Lao <cclao@google.com>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/tests/gl_tests/FramebufferTest.cpp b/src/tests/gl_tests/FramebufferTest.cpp
index d5cabce9..2945c5c 100644
--- a/src/tests/gl_tests/FramebufferTest.cpp
+++ b/src/tests/gl_tests/FramebufferTest.cpp
@@ -1175,10 +1175,6 @@
GLFramebuffer resolveFBO;
glBindTexture(GL_TEXTURE_2D, resolveTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
@@ -1242,10 +1238,6 @@
GLFramebuffer resolveFBO;
glBindTexture(GL_TEXTURE_2D, resolveTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
@@ -1292,10 +1284,6 @@
GLFramebuffer resolveFBO1;
glBindTexture(GL_TEXTURE_2D, resolveTexture1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
@@ -1313,10 +1301,6 @@
GLFramebuffer resolveFBO2;
glBindTexture(GL_TEXTURE_2D, resolveTexture2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO2);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture2, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
@@ -1352,10 +1336,6 @@
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
ASSERT_GL_NO_ERROR();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
GLFramebuffer msaaFBO;
glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
@@ -1386,7 +1366,7 @@
EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 251, 251, 0, 255, 1.0); // Yellow
}
-// Test resolving a multisampled texture with blit after drawing to mulitiple FBOs.
+// Test resolving a multisampled texture with blit after drawing to multiple FBOs.
TEST_P(FramebufferTest_ES31, MultipleTextureMultisampleResolveWithBlitMultipleResolves)
{
// Attach two MSAA textures to FBO1
@@ -1440,10 +1420,6 @@
GLFramebuffer resolveFBO1;
glBindTexture(GL_TEXTURE_2D, resolveTexture1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
@@ -1462,10 +1438,6 @@
GLFramebuffer resolveFBO2;
glBindTexture(GL_TEXTURE_2D, resolveTexture2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO2);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture2, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
@@ -1480,6 +1452,94 @@
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
+// Test resolving a multisampled texture with blit after drawing to multiple FBOs, with color
+// attachment 1 resolved first.
+TEST_P(FramebufferTest_ES31,
+ MultipleTextureMultisampleResolveWithBlitMultipleResolvesAttachment1First)
+{
+ // Attach two MSAA textures to FBO1
+ // Set read buffer 1
+ // Resolve into FBO2
+ // Set read buffer 0
+ // Resolve into FBO3
+
+ ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_draw_buffers"));
+
+ constexpr int kSize = 16;
+ glViewport(0, 0, kSize, kSize);
+
+ GLFramebuffer msaaFBO;
+ glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
+
+ GLTexture msaaTextureRed;
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTextureRed.get());
+ glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
+ ASSERT_GL_NO_ERROR();
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
+ msaaTextureRed.get(), 0);
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ GLTexture msaaTextureGreen;
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTextureGreen.get());
+ glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
+ ASSERT_GL_NO_ERROR();
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
+ msaaTextureGreen.get(), 0);
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ // Setup program to render red into attachment 0 and green into attachment 1.
+ const char *fs = R"(#extension GL_EXT_draw_buffers : enable
+precision highp float;
+void main()
+{
+ gl_FragData[0] = vec4(1.0, 0.0, 0.0, 1.0); // attachment 0: red
+ gl_FragData[1] = vec4(0.0, 1.0, 0.0, 1.0); // attachment 1: green
+})";
+ ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), fs);
+ glUseProgram(program);
+ constexpr GLenum kDrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
+ glDrawBuffers(2, kDrawBuffers);
+
+ drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
+ ASSERT_GL_NO_ERROR();
+
+ // Create another FBO to resolve the multisample buffer into.
+ GLTexture resolveTexture1;
+ GLFramebuffer resolveFBO1;
+ glBindTexture(GL_TEXTURE_2D, resolveTexture1);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO1);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 0);
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO1);
+ glReadBuffer(GL_COLOR_ATTACHMENT1); // Green
+ glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ ASSERT_GL_NO_ERROR();
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO1);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+
+ // Create another FBO to resolve the multisample buffer into.
+ GLTexture resolveTexture2;
+ GLFramebuffer resolveFBO2;
+ glBindTexture(GL_TEXTURE_2D, resolveTexture2);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO2);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture2, 0);
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO2);
+ glReadBuffer(GL_COLOR_ATTACHMENT0); // Red
+ glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ ASSERT_GL_NO_ERROR();
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO2);
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+}
+
// If there are no attachments, rendering will be limited to a rectangle having a lower left of
// (0, 0) and an upper right of(width, height), where width and height are the framebuffer
// object's default width and height.