Vulkan: Fix resolve with different formats
vkCmdResolveImage and subpass resolve attachments cannot be used if the
source and destination formats aren't identical per Vulkan spec:
vkCmdResolveImage:
> srcImage and dstImage must have been created with the same image
> format
VkSubpassDescription:
> each resolve attachment that is not VK_ATTACHMENT_UNUSED must have the
> same VkFormat as its corresponding color attachment
Bug: chromium:1123524
Change-Id: Iaf7182dbcad0420483ac2c23d0acf8c109688565
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2390781
Reviewed-by: Tim Van Patten <timvp@google.com>
Reviewed-by: Nicolas Capens <capn@chromium.org>
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 2945c5c..e46e005 100644
--- a/src/tests/gl_tests/FramebufferTest.cpp
+++ b/src/tests/gl_tests/FramebufferTest.cpp
@@ -1191,6 +1191,52 @@
EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 239, 239, 0, 255, 1.0); // Yellow
}
+// Test resolving a multisampled texture with blit to a different format
+TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitDifferentFormats)
+{
+ ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"));
+
+ constexpr int kSize = 16;
+ glViewport(0, 0, kSize, kSize);
+
+ GLFramebuffer msaaFBO;
+ glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
+
+ GLTexture texture;
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture.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,
+ texture.get(), 0);
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
+ essl31_shaders::fs::RedGreenGradient());
+ drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
+ ASSERT_GL_NO_ERROR();
+
+ // Create another FBO to resolve the multisample buffer into.
+ GLTexture resolveTexture;
+ GLFramebuffer resolveFBO;
+ glBindTexture(GL_TEXTURE_2D, resolveTexture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA8_EXT, kSize, kSize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
+ nullptr);
+ glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
+ ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
+ glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ ASSERT_GL_NO_ERROR();
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
+ EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0); // Black
+ EXPECT_PIXEL_NEAR(kSize - 1, 1, 239, 0, 0, 255, 1.0); // Red
+ EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 239, 0, 255, 1.0); // Green
+ EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 239, 239, 0, 255, 1.0); // Yellow
+}
+
// Test resolving a multisampled texture with blit after drawing to mulitiple FBOs.
TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitMultipleFBOs)
{