Commit f8070feb by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Use depthClamp to clear depth where available

This will avoid breaking render pass if clearing depth in clearWithDraw. Bug: angleproject:4836 Change-Id: I50242d1115efc91059923143f6ae5fd25fb3d36f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2462717 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent dd4b6445
...@@ -2019,7 +2019,9 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk, ...@@ -2019,7 +2019,9 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
const VkClearColorValue &clearColorValue, const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue) const VkClearDepthStencilValue &clearDepthStencilValue)
{ {
if (clearDepth) RendererVk *renderer = contextVk->getRenderer();
if (clearDepth && !renderer->getPhysicalDeviceFeatures().depthClamp)
{ {
VkClearValue clearValue; VkClearValue clearValue;
clearValue.depthStencil = clearDepthStencilValue; clearValue.depthStencil = clearDepthStencilValue;
...@@ -2031,15 +2033,18 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk, ...@@ -2031,15 +2033,18 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
// Force start a new render pass for the depth clear to take effect. // Force start a new render pass for the depth clear to take effect.
// UtilsVk::clearFramebuffer may not start a new render pass if there's one already started. // UtilsVk::clearFramebuffer may not start a new render pass if there's one already started.
ANGLE_TRY(flushDeferredClears(contextVk, clearArea)); ANGLE_TRY(flushDeferredClears(contextVk, clearArea));
clearDepth = false;
} }
UtilsVk::ClearFramebufferParameters params = {}; UtilsVk::ClearFramebufferParameters params = {};
params.clearArea = clearArea; params.clearArea = clearArea;
params.colorClearValue = clearColorValue; params.colorClearValue = clearColorValue;
params.stencilClearValue = static_cast<uint8_t>(clearDepthStencilValue.stencil); params.depthStencilClearValue = clearDepthStencilValue;
params.stencilMask = stencilMask; params.stencilMask = stencilMask;
params.clearColor = true; params.clearColor = true;
params.clearDepth = clearDepth;
params.clearStencil = clearStencil; params.clearStencil = clearStencil;
const auto &colorRenderTargets = mRenderTargetCache.getColors(); const auto &colorRenderTargets = mRenderTargetCache.getColors();
...@@ -2060,12 +2065,13 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk, ...@@ -2060,12 +2065,13 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
ANGLE_TRY(contextVk->getUtils().clearFramebuffer(contextVk, this, params)); ANGLE_TRY(contextVk->getUtils().clearFramebuffer(contextVk, this, params));
// Clear stencil only once! // Clear depth/stencil only once!
params.clearDepth = false;
params.clearStencil = false; params.clearStencil = false;
} }
// If there was no color clear, clear stencil alone. // If there was no color clear, clear depth/stencil alone.
if (params.clearStencil) if (params.clearDepth || params.clearStencil)
{ {
params.clearColor = false; params.clearColor = false;
ANGLE_TRY(contextVk->getUtils().clearFramebuffer(contextVk, this, params)); ANGLE_TRY(contextVk->getUtils().clearFramebuffer(contextVk, this, params));
......
...@@ -1336,6 +1336,8 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF ...@@ -1336,6 +1336,8 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
enabledFeatures.features.shaderClipDistance = mPhysicalDeviceFeatures.shaderClipDistance; enabledFeatures.features.shaderClipDistance = mPhysicalDeviceFeatures.shaderClipDistance;
// Used to support OES_sample_shading // Used to support OES_sample_shading
enabledFeatures.features.sampleRateShading = mPhysicalDeviceFeatures.sampleRateShading; enabledFeatures.features.sampleRateShading = mPhysicalDeviceFeatures.sampleRateShading;
// Used to support depth clears through draw calls.
enabledFeatures.features.depthClamp = mPhysicalDeviceFeatures.depthClamp;
if (!vk::CommandBuffer::ExecutesInline()) if (!vk::CommandBuffer::ExecutesInline())
{ {
......
...@@ -1402,14 +1402,21 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk, ...@@ -1402,14 +1402,21 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
ANGLE_TRY(contextVk->startRenderPass(scissoredRenderArea, &commandBuffer)); ANGLE_TRY(contextVk->startRenderPass(scissoredRenderArea, &commandBuffer));
} }
if (params.clearStencil) if (params.clearStencil || params.clearDepth)
{ {
vk::CommandBufferHelper *renderpassCommands; vk::CommandBufferHelper *renderpassCommands;
renderpassCommands = &contextVk->getStartedRenderPassCommands(); renderpassCommands = &contextVk->getStartedRenderPassCommands();
// Because clear is not affected by stencil test, we have to explicitly mark stencil write // Because clear is not affected by depth/stencil test, we have to explicitly mark
// here. // depth/stencil write here.
renderpassCommands->onStencilAccess(vk::ResourceAccess::Write); if (params.clearDepth)
{
renderpassCommands->onDepthAccess(vk::ResourceAccess::Write);
}
if (params.clearStencil)
{
renderpassCommands->onStencilAccess(vk::ResourceAccess::Write);
}
// We may have changed depth stencil access mode, so update read only depth stencil mode // We may have changed depth stencil access mode, so update read only depth stencil mode
// here. // here.
...@@ -1433,11 +1440,25 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk, ...@@ -1433,11 +1440,25 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
// used. // used.
pipelineDesc.setSubpass(contextVk->getCurrentSubpassIndex()); pipelineDesc.setSubpass(contextVk->getCurrentSubpassIndex());
// Clear depth by enabling depth clamping and setting the viewport depth range to the clear
// value.
if (params.clearDepth)
{
// This path requires the depthClamp Vulkan feature.
ASSERT(contextVk->getRenderer()->getPhysicalDeviceFeatures().depthClamp);
pipelineDesc.setDepthTestEnabled(true);
pipelineDesc.setDepthWriteEnabled(true);
pipelineDesc.setDepthFunc(VK_COMPARE_OP_ALWAYS);
pipelineDesc.setDepthClampEnabled(true);
}
// Clear stencil by enabling stencil write with the right mask. // Clear stencil by enabling stencil write with the right mask.
if (params.clearStencil) if (params.clearStencil)
{ {
const uint8_t compareMask = 0xFF; const uint8_t compareMask = 0xFF;
const uint8_t clearStencilValue = params.stencilClearValue; const uint8_t clearStencilValue =
static_cast<uint8_t>(params.depthStencilClearValue.stencil);
pipelineDesc.setStencilTestEnabled(true); pipelineDesc.setStencilTestEnabled(true);
pipelineDesc.setStencilFrontFuncs(clearStencilValue, VK_COMPARE_OP_ALWAYS, compareMask); pipelineDesc.setStencilFrontFuncs(clearStencilValue, VK_COMPARE_OP_ALWAYS, compareMask);
...@@ -1453,8 +1474,11 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk, ...@@ -1453,8 +1474,11 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
VkViewport viewport; VkViewport viewport;
gl::Rectangle completeRenderArea = framebuffer->getRotatedCompleteRenderArea(contextVk); gl::Rectangle completeRenderArea = framebuffer->getRotatedCompleteRenderArea(contextVk);
bool invertViewport = contextVk->isViewportFlipEnabledForDrawFBO(); bool invertViewport = contextVk->isViewportFlipEnabledForDrawFBO();
gl_vk::GetViewport(completeRenderArea, 0.0f, 1.0f, invertViewport, completeRenderArea.height, // Set depth range to clear value. If clearing depth, the vertex shader depth output is clamped
&viewport); // to this value, thus clearing the depth buffer to the desired clear value.
const float clearDepthValue = params.depthStencilClearValue.depth;
gl_vk::GetViewport(completeRenderArea, clearDepthValue, clearDepthValue, invertViewport,
completeRenderArea.height, &viewport);
pipelineDesc.setViewport(viewport); pipelineDesc.setViewport(viewport);
pipelineDesc.setScissor(gl_vk::GetRect(params.clearArea)); pipelineDesc.setScissor(gl_vk::GetRect(params.clearArea));
...@@ -2576,13 +2600,14 @@ angle::Result UtilsVk::allocateDescriptorSet(ContextVk *contextVk, ...@@ -2576,13 +2600,14 @@ angle::Result UtilsVk::allocateDescriptorSet(ContextVk *contextVk,
UtilsVk::ClearFramebufferParameters::ClearFramebufferParameters() UtilsVk::ClearFramebufferParameters::ClearFramebufferParameters()
: clearColor(false), : clearColor(false),
clearDepth(false),
clearStencil(false), clearStencil(false),
stencilMask(0), stencilMask(0),
colorMaskFlags(0), colorMaskFlags(0),
colorAttachmentIndexGL(0), colorAttachmentIndexGL(0),
colorFormat(nullptr), colorFormat(nullptr),
colorClearValue{}, colorClearValue{},
stencilClearValue(0) depthStencilClearValue{}
{} {}
} // namespace rx } // namespace rx
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
// resolve on depth/stencil images. // resolve on depth/stencil images.
// - Generate mipmap: Used by TextureVk::generateMipmapsWithCompute(). // - Generate mipmap: Used by TextureVk::generateMipmapsWithCompute().
// - Overlay Cull/Draw: Used by OverlayVk to efficiently draw a UI for debugging. // - Overlay Cull/Draw: Used by OverlayVk to efficiently draw a UI for debugging.
// - Mipmap generation: Not yet implemented // - Mipmap generation: Used by TextureVk to generate mipmaps more efficiently in compute.
// //
#ifndef LIBANGLE_RENDERER_VULKAN_UTILSVK_H_ #ifndef LIBANGLE_RENDERER_VULKAN_UTILSVK_H_
...@@ -95,8 +95,10 @@ class UtilsVk : angle::NonCopyable ...@@ -95,8 +95,10 @@ class UtilsVk : angle::NonCopyable
gl::Rectangle clearArea; gl::Rectangle clearArea;
// Note that depth clear is never needed to be done with a draw call. // Note that depth clear is only possible if the depthClamp Vulkan feature is supported. If
// needs be, this can be emulated by exporting depth from shaders/src/ImageClear.frag.
bool clearColor; bool clearColor;
bool clearDepth;
bool clearStencil; bool clearStencil;
uint8_t stencilMask; uint8_t stencilMask;
...@@ -105,7 +107,7 @@ class UtilsVk : angle::NonCopyable ...@@ -105,7 +107,7 @@ class UtilsVk : angle::NonCopyable
const angle::Format *colorFormat; const angle::Format *colorFormat;
VkClearColorValue colorClearValue; VkClearColorValue colorClearValue;
uint8_t stencilClearValue; VkClearDepthStencilValue depthStencilClearValue;
}; };
struct BlitResolveParameters struct BlitResolveParameters
......
...@@ -2178,6 +2178,11 @@ void GraphicsPipelineDesc::setDepthFunc(VkCompareOp op) ...@@ -2178,6 +2178,11 @@ void GraphicsPipelineDesc::setDepthFunc(VkCompareOp op)
SetBitField(mDepthStencilStateInfo.depthCompareOp, op); SetBitField(mDepthStencilStateInfo.depthCompareOp, op);
} }
void GraphicsPipelineDesc::setDepthClampEnabled(bool enabled)
{
mRasterizationAndMultisampleStateInfo.bits.depthClampEnable = enabled;
}
void GraphicsPipelineDesc::setStencilTestEnabled(bool enabled) void GraphicsPipelineDesc::setStencilTestEnabled(bool enabled)
{ {
mDepthStencilStateInfo.enable.stencilTest = enabled; mDepthStencilStateInfo.enable.stencilTest = enabled;
......
...@@ -623,6 +623,7 @@ class GraphicsPipelineDesc final ...@@ -623,6 +623,7 @@ class GraphicsPipelineDesc final
void setDepthTestEnabled(bool enabled); void setDepthTestEnabled(bool enabled);
void setDepthWriteEnabled(bool enabled); void setDepthWriteEnabled(bool enabled);
void setDepthFunc(VkCompareOp op); void setDepthFunc(VkCompareOp op);
void setDepthClampEnabled(bool enabled);
void setStencilTestEnabled(bool enabled); void setStencilTestEnabled(bool enabled);
void setStencilFrontFuncs(uint8_t reference, VkCompareOp compareOp, uint8_t compareMask); void setStencilFrontFuncs(uint8_t reference, VkCompareOp compareOp, uint8_t compareMask);
void setStencilBackFuncs(uint8_t reference, VkCompareOp compareOp, uint8_t compareMask); void setStencilBackFuncs(uint8_t reference, VkCompareOp compareOp, uint8_t compareMask);
......
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