Vulkan: Implement masked depth & stencil clear
This commit also adds tests for clearing depth and stencil with
mask/scissor.
Bug: angleproject:2540
Change-Id: I30dd840afd6cdd4e3a38c50fcba4c8623513ceb0
Reviewed-on: https://chromium-review.googlesource.com/c/1307585
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index 8e91a53..39abce1 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -178,6 +178,9 @@
bool clearDepth = (depthAttachment && (mask & GL_DEPTH_BUFFER_BIT) != 0);
ASSERT(!clearDepth || depthAttachment->isAttached());
+ // If depth write is disabled, pretend that GL_DEPTH_BUFFER_BIT is not specified altogether.
+ clearDepth = clearDepth && contextVk->getGLState().getDepthStencilState().depthMask;
+
const gl::FramebufferAttachment *stencilAttachment = mState.getStencilAttachment();
bool clearStencil = (stencilAttachment && (mask & GL_STENCIL_BUFFER_BIT) != 0);
ASSERT(!clearStencil || stencilAttachment->isAttached());
@@ -203,8 +206,6 @@
if (clearDepth || clearStencil)
{
- // Masked stencil clears are currently not implemented.
- // TODO(jmadill): Masked stencil clear. http://anglebug.com/2540
ANGLE_TRY(clearWithClearAttachments(contextVk, false, clearDepth, clearStencil));
}
return angle::Result::Continue();
@@ -222,9 +223,6 @@
// With scissor test enabled, we clear very differently and we don't need to access
// the image inside each attachment we can just use clearCmdAttachments with our
// scissor region instead.
-
- // Masked stencil clears are currently not implemented.
- // TODO(jmadill): Masked stencil clear. http://anglebug.com/2540
ANGLE_TRY(clearWithClearAttachments(contextVk, clearColor, clearDepth, clearStencil));
return angle::Result::Continue();
}
@@ -234,9 +232,13 @@
{
ANGLE_TRY(mFramebuffer.recordCommands(contextVk, &commandBuffer));
- const VkClearDepthStencilValue &clearDepthStencilValue =
+ VkClearDepthStencilValue clearDepthStencilValue =
contextVk->getClearDepthStencilValue().depthStencil;
+ // Apply the stencil mask to the clear value.
+ clearDepthStencilValue.stencil &=
+ contextVk->getGLState().getDepthStencilState().stencilWritemask;
+
RenderTargetVk *renderTarget = mRenderTargetCache.getDepthStencil();
const angle::Format &format = renderTarget->getImageFormat().textureFormat();
const VkImageAspectFlags aspectFlags = vk::GetDepthStencilAspectFlags(format);
@@ -936,6 +938,16 @@
}
}
+ VkClearValue depthStencilClearValue = contextVk->getClearDepthStencilValue();
+
+ // Apply the stencil mask to the clear value. Stencil mask is generally respected through the
+ // respective pipeline state, but clear uses its own special function.
+ if (clearStencil)
+ {
+ depthStencilClearValue.depthStencil.stencil &=
+ contextVk->getGLState().getDepthStencilState().stencilWritemask;
+ }
+
if (clearDepth && clearStencil && mState.getDepthStencilAttachment() != nullptr)
{
// When we have a packed depth/stencil attachment we can do 1 clear for both when it
@@ -943,7 +955,7 @@
VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
clearAttachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
clearAttachment.colorAttachment = VK_ATTACHMENT_UNUSED;
- clearAttachment.clearValue = contextVk->getClearDepthStencilValue();
+ clearAttachment.clearValue = depthStencilClearValue;
++clearAttachmentIndex;
}
else
@@ -953,7 +965,7 @@
VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
clearAttachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
clearAttachment.colorAttachment = VK_ATTACHMENT_UNUSED;
- clearAttachment.clearValue = contextVk->getClearDepthStencilValue();
+ clearAttachment.clearValue = depthStencilClearValue;
++clearAttachmentIndex;
}
@@ -962,7 +974,7 @@
VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
clearAttachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
clearAttachment.colorAttachment = VK_ATTACHMENT_UNUSED;
- clearAttachment.clearValue = contextVk->getClearDepthStencilValue();
+ clearAttachment.clearValue = depthStencilClearValue;
++clearAttachmentIndex;
}
}