Commit 543a3962 by Shahbaz Youssefi Committed by Commit Bot

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/+/2390440Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent 6b2639b0
...@@ -387,13 +387,11 @@ const FramebufferAttachment *FramebufferState::getAttachment(const Context *cont ...@@ -387,13 +387,11 @@ const FramebufferAttachment *FramebufferState::getAttachment(const Context *cont
} }
} }
size_t FramebufferState::getReadIndex() const uint32_t FramebufferState::getReadIndex() const
{ {
ASSERT(mReadBufferState == GL_BACK || ASSERT(mReadBufferState == GL_BACK ||
(mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15)); (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15));
size_t readIndex = (mReadBufferState == GL_BACK uint32_t readIndex = mReadBufferState == GL_BACK ? 0 : mReadBufferState - GL_COLOR_ATTACHMENT0;
? 0
: static_cast<size_t>(mReadBufferState - GL_COLOR_ATTACHMENT0));
ASSERT(readIndex < mColorAttachments.size()); ASSERT(readIndex < mColorAttachments.size());
return readIndex; return readIndex;
} }
...@@ -405,7 +403,7 @@ const FramebufferAttachment *FramebufferState::getReadAttachment() const ...@@ -405,7 +403,7 @@ const FramebufferAttachment *FramebufferState::getReadAttachment() const
return nullptr; return nullptr;
} }
size_t readIndex = getReadIndex(); uint32_t readIndex = getReadIndex();
const gl::FramebufferAttachment &framebufferAttachment = const gl::FramebufferAttachment &framebufferAttachment =
isDefault() ? mDefaultFramebufferReadAttachment : mColorAttachments[readIndex]; isDefault() ? mDefaultFramebufferReadAttachment : mColorAttachments[readIndex];
......
...@@ -58,7 +58,7 @@ class FramebufferState final : angle::NonCopyable ...@@ -58,7 +58,7 @@ class FramebufferState final : angle::NonCopyable
~FramebufferState(); ~FramebufferState();
const std::string &getLabel() const; const std::string &getLabel() const;
size_t getReadIndex() const; uint32_t getReadIndex() const;
const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const; const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const;
const FramebufferAttachment *getReadAttachment() const; const FramebufferAttachment *getReadAttachment() const;
......
...@@ -1230,28 +1230,29 @@ angle::Result FramebufferVk::resolveColorWithSubpass(ContextVk *contextVk, ...@@ -1230,28 +1230,29 @@ angle::Result FramebufferVk::resolveColorWithSubpass(ContextVk *contextVk,
// render pass subpass. Due to this, we currently only support using resolve attachments when // render pass subpass. Due to this, we currently only support using resolve attachments when
// there is a single draw attachment enabled. // there is a single draw attachment enabled.
ASSERT(mState.getEnabledDrawBuffers().count() == 1); ASSERT(mState.getEnabledDrawBuffers().count() == 1);
uint32_t colorIndexGL = static_cast<uint32_t>(*mState.getEnabledDrawBuffers().begin()); uint32_t drawColorIndexGL = static_cast<uint32_t>(*mState.getEnabledDrawBuffers().begin());
const gl::State &glState = contextVk->getState(); const gl::State &glState = contextVk->getState();
const gl::Framebuffer *srcFramebuffer = glState.getReadFramebuffer(); const gl::Framebuffer *srcFramebuffer = glState.getReadFramebuffer();
FramebufferVk *srcFramebufferVk = vk::GetImpl(srcFramebuffer); FramebufferVk *srcFramebufferVk = vk::GetImpl(srcFramebuffer);
uint32_t readColorIndexGL = srcFramebuffer->getState().getReadIndex();
// Use the draw FBO's color attachments as resolve attachments in the read FBO. // Use the draw FBO's color attachments as resolve attachments in the read FBO.
// - Assign the draw FBO's color attachment Serial to the read FBO's resolve attachment // - Assign the draw FBO's color attachment Serial to the read FBO's resolve attachment
// - Deactivate the source Framebuffer, since the description changed // - Deactivate the source Framebuffer, since the description changed
// - Update the renderpass description to indicate there's a resolve attachment // - Update the renderpass description to indicate there's a resolve attachment
vk::ImageViewSubresourceSerial resolveImageViewSerial = vk::ImageViewSubresourceSerial resolveImageViewSerial =
mCurrentFramebufferDesc.getColorImageViewSerial(colorIndexGL); mCurrentFramebufferDesc.getColorImageViewSerial(drawColorIndexGL);
ASSERT(resolveImageViewSerial.imageViewSerial.valid()); ASSERT(resolveImageViewSerial.imageViewSerial.valid());
srcFramebufferVk->updateColorResolveAttachment(colorIndexGL, resolveImageViewSerial); srcFramebufferVk->updateColorResolveAttachment(readColorIndexGL, resolveImageViewSerial);
// Since tha source FBO was updated with a resolve attachment it didn't have when the render // Since the source FBO was updated with a resolve attachment it didn't have when the render
// pass was started, we need to: // pass was started, we need to:
// 1. Get the new framebuffer // 1. Get the new framebuffer
// - The draw framebuffer's ImageView will be used as the resolve attachment, so pass it along // - The draw framebuffer's ImageView will be used as the resolve attachment, so pass it along
// in case vkCreateFramebuffer() needs to be called to create a new vkFramebuffer with the new // in case vkCreateFramebuffer() needs to be called to create a new vkFramebuffer with the new
// resolve attachment. // resolve attachment.
RenderTargetVk *drawRenderTarget = mRenderTargetCache.getColors()[colorIndexGL]; RenderTargetVk *drawRenderTarget = mRenderTargetCache.getColors()[drawColorIndexGL];
const vk::ImageView *resolveImageView = nullptr; const vk::ImageView *resolveImageView = nullptr;
ANGLE_TRY(drawRenderTarget->getImageView(contextVk, &resolveImageView)); ANGLE_TRY(drawRenderTarget->getImageView(contextVk, &resolveImageView));
vk::Framebuffer *newSrcFramebuffer = nullptr; vk::Framebuffer *newSrcFramebuffer = nullptr;
......
...@@ -1175,10 +1175,6 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlit) ...@@ -1175,10 +1175,6 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlit)
GLFramebuffer resolveFBO; GLFramebuffer resolveFBO;
glBindTexture(GL_TEXTURE_2D, resolveTexture); glBindTexture(GL_TEXTURE_2D, resolveTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); 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); glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
...@@ -1242,10 +1238,6 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitMultipleFBOs) ...@@ -1242,10 +1238,6 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitMultipleFBOs)
GLFramebuffer resolveFBO; GLFramebuffer resolveFBO;
glBindTexture(GL_TEXTURE_2D, resolveTexture); glBindTexture(GL_TEXTURE_2D, resolveTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); 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); glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
...@@ -1292,10 +1284,6 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitMultipleResolves) ...@@ -1292,10 +1284,6 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitMultipleResolves)
GLFramebuffer resolveFBO1; GLFramebuffer resolveFBO1;
glBindTexture(GL_TEXTURE_2D, resolveTexture1); glBindTexture(GL_TEXTURE_2D, resolveTexture1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); 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); glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
...@@ -1313,10 +1301,6 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitMultipleResolves) ...@@ -1313,10 +1301,6 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitMultipleResolves)
GLFramebuffer resolveFBO2; GLFramebuffer resolveFBO2;
glBindTexture(GL_TEXTURE_2D, resolveTexture2); glBindTexture(GL_TEXTURE_2D, resolveTexture2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); 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); glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO2);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture2, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture2, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
...@@ -1352,10 +1336,6 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveIntoMipMapWithBlit) ...@@ -1352,10 +1336,6 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveIntoMipMapWithBlit)
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); 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); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
ASSERT_GL_NO_ERROR(); 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; GLFramebuffer msaaFBO;
glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get()); glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
...@@ -1386,7 +1366,7 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveIntoMipMapWithBlit) ...@@ -1386,7 +1366,7 @@ TEST_P(FramebufferTest_ES31, MultisampleResolveIntoMipMapWithBlit)
EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 251, 251, 0, 255, 1.0); // Yellow 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) TEST_P(FramebufferTest_ES31, MultipleTextureMultisampleResolveWithBlitMultipleResolves)
{ {
// Attach two MSAA textures to FBO1 // Attach two MSAA textures to FBO1
...@@ -1440,10 +1420,6 @@ void main() ...@@ -1440,10 +1420,6 @@ void main()
GLFramebuffer resolveFBO1; GLFramebuffer resolveFBO1;
glBindTexture(GL_TEXTURE_2D, resolveTexture1); glBindTexture(GL_TEXTURE_2D, resolveTexture1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); 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); glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
...@@ -1462,10 +1438,6 @@ void main() ...@@ -1462,10 +1438,6 @@ void main()
GLFramebuffer resolveFBO2; GLFramebuffer resolveFBO2;
glBindTexture(GL_TEXTURE_2D, resolveTexture2); glBindTexture(GL_TEXTURE_2D, resolveTexture2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); 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); glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO2);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture2, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture2, 0);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
...@@ -1480,6 +1452,94 @@ void main() ...@@ -1480,6 +1452,94 @@ void main()
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); 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 // 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 // (0, 0) and an upper right of(width, height), where width and height are the framebuffer
// object's default width and height. // object's default width and height.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment