Commit 5559351c by Tim Van Patten Committed by Commit Bot

Vulkan: Correctly determine mip level in resolveColorWithCommand()

FramebufferVk::resolveColorWithCommand() is currently using the wrong mip level value by using the GL index value, rather than calculating the VK value from (index value - the base level). Bug: angleproject:4753 Test: FramebufferTest_ES31::MultisampleResolveIntoMipMapWithBlit() Change-Id: I8ddaeb21c4957b46880f5ef5f6a78242c04b4dcd Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2349951Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Tim Van Patten <timvp@google.com>
parent 5c8c6b42
...@@ -1229,10 +1229,12 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk, ...@@ -1229,10 +1229,12 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk,
&drawRenderTarget->getImageForWrite())); &drawRenderTarget->getImageForWrite()));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer)); ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
resolveRegion.dstSubresource.mipLevel = drawRenderTarget->getLevelIndex(); vk::ImageHelper &dstImage = drawRenderTarget->getImageForWrite();
uint32_t levelVK = drawRenderTarget->getLevelIndex() - dstImage.getBaseLevel();
resolveRegion.dstSubresource.mipLevel = levelVK;
resolveRegion.dstSubresource.baseArrayLayer = drawRenderTarget->getLayerIndex(); resolveRegion.dstSubresource.baseArrayLayer = drawRenderTarget->getLayerIndex();
srcImage->resolve(&drawRenderTarget->getImageForWrite(), resolveRegion, commandBuffer); srcImage->resolve(&dstImage, resolveRegion, commandBuffer);
} }
return angle::Result::Continue; return angle::Result::Continue;
......
...@@ -1129,6 +1129,62 @@ TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsTex) ...@@ -1129,6 +1129,62 @@ TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsTex)
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
} }
// Test resolving a multisampled texture into a mipmaped texture with blit
TEST_P(FramebufferTest_ES31, MultisampleResolveIntoMipMapWithBlit)
{
// FBO 1 is attached to a 64x64 texture
// FBO 2 attached to level 1 of a 128x128 texture
constexpr int kSize = 64;
glViewport(0, 0, kSize, kSize);
// Create the textures early and call glGenerateMipmap() so it doesn't break the render pass
// between the drawQuad() and glBlitFramebuffer(), so we can test the resolve with subpass path
// in the Vulkan back end.
GLTexture texture;
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture.get());
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
ASSERT_GL_NO_ERROR();
GLTexture resolveTexture;
glBindTexture(GL_TEXTURE_2D, resolveTexture);
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());
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.
GLFramebuffer resolveFBO;
glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 1);
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, 251, 0, 0, 255, 1.0); // Red
EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 251, 0, 255, 1.0); // Green
EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 251, 251, 0, 255, 1.0); // Yellow
}
// 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.
......
...@@ -644,6 +644,20 @@ void main() ...@@ -644,6 +644,20 @@ void main()
})"; })";
} }
// A shader that renders a simple gradient of red to green. Needs varying v_position.
const char *RedGreenGradient()
{
return R"(#version 310 es
precision highp float;
in vec4 v_position;
out vec4 my_FragColor;
void main()
{
my_FragColor = vec4(v_position.x, v_position.y, 0.0, 1.0);
})";
}
} // namespace fs } // namespace fs
} // namespace essl31_shaders } // namespace essl31_shaders
} // namespace angle } // namespace angle
...@@ -172,6 +172,9 @@ ANGLE_UTIL_EXPORT const char *Red(); ...@@ -172,6 +172,9 @@ ANGLE_UTIL_EXPORT const char *Red();
// A shader that fills with 100% opaque green. // A shader that fills with 100% opaque green.
ANGLE_UTIL_EXPORT const char *Green(); ANGLE_UTIL_EXPORT const char *Green();
// A shader that renders a simple gradient of red to green. Needs varying v_position.
ANGLE_UTIL_EXPORT const char *RedGreenGradient();
} // namespace fs } // namespace fs
} // namespace essl31_shaders } // namespace essl31_shaders
} // namespace angle } // namespace angle
......
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