Commit bcb678a5 by Shahbaz Youssefi Committed by Angle LUCI CQ

Vulkan: Fix deferred clears vs 3D textures

Two bugs are fixed in this change. One is that framebuffer attachments to 3D textures should not attempt to defer clears. The clear staged for the 3D texture applies to all slices, not just the slice the framebuffer is attached to (and that would get cleared through deferred clears). Secondly, when clearing an attachment to a 3D texture, the clear must be applied immediately through a render pass loadOp to affect only the slice that's attached. This was already handled for layered framebuffers where the clear was applied immediately if the 3D texture render target had more layers than the framebuffer. The condition for this is generalized to check whether the 3D texture has more slices (regardless of whether the render target is layered or not). Test is based on one written by Austin Eng <enga@chromium.org> Bug: angleproject:5967 Change-Id: I43cf5fc24673323eda8390021641e2238be6e375 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2923785Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent 778a4ed9
...@@ -303,8 +303,10 @@ bool IsAnyAttachment3DWithoutAllLayers(const RenderTargetCache<RenderTargetVk> & ...@@ -303,8 +303,10 @@ bool IsAnyAttachment3DWithoutAllLayers(const RenderTargetCache<RenderTargetVk> &
{ {
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndexGL]; RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndexGL];
ASSERT(colorRenderTarget); ASSERT(colorRenderTarget);
if (colorRenderTarget->getLayerCount() > framebufferLayerCount &&
colorRenderTarget->getImageForRenderPass().getType() == VK_IMAGE_TYPE_3D) const vk::ImageHelper &image = colorRenderTarget->getImageForRenderPass();
if (image.getType() == VK_IMAGE_TYPE_3D && image.getExtents().depth > framebufferLayerCount)
{ {
return true; return true;
} }
......
...@@ -294,11 +294,15 @@ angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk, ...@@ -294,11 +294,15 @@ angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk,
ASSERT(mImage->valid() && (!isResolveImageOwnerOfData() || mResolveImage->valid())); ASSERT(mImage->valid() && (!isResolveImageOwnerOfData() || mResolveImage->valid()));
ASSERT(framebufferLayerCount != 0); ASSERT(framebufferLayerCount != 0);
// Note that the layer index for 3D textures is always zero according to Vulkan. // It's impossible to defer clears to slices of a 3D images, as the clear applies to all the
// slices, while deferred clears only clear a single slice (where the framebuffer is attached).
// Additionally, the layer index for 3D textures is always zero according to Vulkan.
uint32_t layerIndex = mLayerIndex; uint32_t layerIndex = mLayerIndex;
if (mImage->getType() == VK_IMAGE_TYPE_3D) if (mImage->getType() == VK_IMAGE_TYPE_3D)
{ {
layerIndex = 0; layerIndex = 0;
deferredClears = nullptr;
deferredClearIndex = 0;
} }
vk::ImageHelper *image = getOwnerOfData(); vk::ImageHelper *image = getOwnerOfData();
......
...@@ -2482,6 +2482,39 @@ TEST_P(ClearTest, DISABLED_ClearReachesWindow) ...@@ -2482,6 +2482,39 @@ TEST_P(ClearTest, DISABLED_ClearReachesWindow)
angle::Sleep(2000); angle::Sleep(2000);
} }
// Test that clearing slices of a 3D texture and reading them back works.
TEST_P(ClearTestES3, ClearAndReadPixels3DTexture)
{
constexpr uint32_t kWidth = 128;
constexpr uint32_t kHeight = 128;
constexpr uint32_t kDepth = 7;
GLTexture texture;
glBindTexture(GL_TEXTURE_3D, texture);
glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, kWidth, kHeight, kDepth);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
std::array<GLColor, kDepth> clearColors = {
GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow,
GLColor::cyan, GLColor::magenta, GLColor::white,
};
GLFramebuffer framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
for (uint32_t z = 0; z < kDepth; ++z)
{
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
glClearBufferfv(GL_COLOR, 0, clearColors[z].toNormalizedVector().data());
}
for (uint32_t z = 0; z < kDepth; ++z)
{
glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
EXPECT_PIXEL_COLOR_EQ(0, 0, clearColors[z]);
}
}
#ifdef Bool #ifdef Bool
// X11 craziness. // X11 craziness.
# undef Bool # undef Bool
......
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