Commit d705f18f by Jamie Madill Committed by Commit Bot

Vulkan: Add immediate scissored clears.

This allows us to avoid using draw commands with pipelines for scissored clears. This prevents some tests from generating large numbers of VkPipelines. Bug: angleproject:4517 Bug: angleproject:4617 Change-Id: Id4a44000078098a60aa89233cfef30b75727d108 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2194473 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 69e46942
......@@ -275,7 +275,7 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context,
// there's a depth mask, depth clearing is already disabled.
bool maskedClearColor =
clearColor && (mActiveColorComponents & colorMaskFlags) != mActiveColorComponents;
bool maskedClearStencil = stencilMask != 0xFF;
bool maskedClearStencil = clearStencil && stencilMask != 0xFF;
bool clearColorWithRenderPassLoadOp = clearColor && !maskedClearColor && !scissoredClear;
bool clearDepthWithRenderPassLoadOp = clearDepth && !scissoredClear;
......@@ -325,6 +325,13 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context,
}
}
if (scissoredClear && !maskedClearColor && !maskedClearStencil)
{
return clearImmediatelyWithRenderPassOp(contextVk, scissoredRenderArea, clearColorBuffers,
clearDepth, clearStencil, clearColorValue,
clearDepthStencilValue);
}
// The most costly clear mode is when we need to mask out specific color channels or stencil
// bits. This can only be done with a draw call.
return clearWithDraw(contextVk, scissoredRenderArea, clearColorBuffers, clearDepth,
......@@ -1370,6 +1377,40 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe
return angle::Result::Continue;
}
angle::Result FramebufferVk::clearImmediatelyWithRenderPassOp(
ContextVk *contextVk,
const gl::Rectangle &clearArea,
gl::DrawBufferMask clearColorBuffers,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue)
{
for (size_t colorIndexGL : clearColorBuffers)
{
VkClearValue clearValue = getCorrectedColorClearValue(colorIndexGL, clearColorValue);
mDeferredClears.store(static_cast<uint32_t>(colorIndexGL), VK_IMAGE_ASPECT_COLOR_BIT,
clearValue);
}
if (clearDepth)
{
VkClearValue clearValue;
clearValue.depthStencil = clearDepthStencilValue;
mDeferredClears.store(vk::kClearValueDepthIndex, VK_IMAGE_ASPECT_DEPTH_BIT, clearValue);
}
if (clearStencil)
{
VkClearValue clearValue;
clearValue.depthStencil = clearDepthStencilValue;
mDeferredClears.store(vk::kClearValueStencilIndex, VK_IMAGE_ASPECT_STENCIL_BIT, clearValue);
}
// Ensure the clear happens immediately.
return flushDeferredClears(contextVk, clearArea);
}
angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
const gl::Rectangle &clearArea,
gl::DrawBufferMask clearColorBuffers,
......@@ -1386,11 +1427,8 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
clearValue.depthStencil = clearDepthStencilValue;
mDeferredClears.store(vk::kClearValueDepthIndex, VK_IMAGE_ASPECT_DEPTH_BIT, clearValue);
// Ensure the clear happens immediately.
if (clearColorBuffers.none() && !clearStencil)
{
return flushDeferredClears(contextVk, clearArea);
}
// Scissored-only clears are handled in clearImmediatelyWithRenderPassOp.
ASSERT(clearColorBuffers.any() || clearStencil);
}
UtilsVk::ClearFramebufferParameters params = {};
......@@ -1432,6 +1470,40 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
return angle::Result::Continue;
}
VkClearValue FramebufferVk::getCorrectedColorClearValue(size_t colorIndexGL,
const VkClearColorValue &clearColor) const
{
VkClearValue clearValue;
clearValue.color = clearColor;
if (!mEmulatedAlphaAttachmentMask[colorIndexGL])
{
return clearValue;
}
// If the render target doesn't have alpha, but its emulated format has it, clear the alpha
// to 1.
RenderTargetVk *renderTarget = getColorDrawRenderTarget(colorIndexGL);
const vk::Format &format = renderTarget->getImageFormat();
if (format.vkFormatIsInt)
{
if (format.vkFormatIsUnsigned)
{
clearValue.color.uint32[3] = kEmulatedAlphaValue;
}
else
{
clearValue.color.int32[3] = kEmulatedAlphaValue;
}
}
else
{
clearValue.color.float32[3] = kEmulatedAlphaValue;
}
return clearValue;
}
void FramebufferVk::clearWithRenderPassOp(gl::DrawBufferMask clearColorBuffers,
bool clearDepth,
bool clearStencil,
......@@ -1443,33 +1515,8 @@ void FramebufferVk::clearWithRenderPassOp(gl::DrawBufferMask clearColorBuffers,
{
ASSERT(mState.getEnabledDrawBuffers().test(colorIndexGL));
RenderTargetVk *renderTarget = getColorDrawRenderTarget(colorIndexGL);
VkClearValue clearValue;
clearValue.color = clearColorValue;
// If the render target doesn't have alpha, but its emulated format has it, clear the
// alpha to 1.
if (mEmulatedAlphaAttachmentMask[colorIndexGL])
{
const vk::Format &format = renderTarget->getImageFormat();
if (format.vkFormatIsInt)
{
if (format.vkFormatIsUnsigned)
{
clearValue.color.uint32[3] = kEmulatedAlphaValue;
}
else
{
clearValue.color.int32[3] = kEmulatedAlphaValue;
}
}
else
{
clearValue.color.float32[3] = kEmulatedAlphaValue;
}
}
gl::ImageIndex imageIndex = renderTarget->getImageIndex();
VkClearValue clearValue = getCorrectedColorClearValue(colorIndexGL, clearColorValue);
gl::ImageIndex imageIndex = renderTarget->getImageIndex();
renderTarget->getImage().stageClear(imageIndex, VK_IMAGE_ASPECT_COLOR_BIT, clearValue);
}
......
......@@ -157,6 +157,16 @@ class FramebufferVk : public FramebufferImpl
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue);
angle::Result clearImmediatelyWithRenderPassOp(
ContextVk *contextVk,
const gl::Rectangle &clearArea,
gl::DrawBufferMask clearColorBuffers,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue);
angle::Result clearWithDraw(ContextVk *contextVk,
const gl::Rectangle &clearArea,
gl::DrawBufferMask clearColorBuffers,
......@@ -186,6 +196,8 @@ class FramebufferVk : public FramebufferImpl
VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const;
angle::Result flushDeferredClears(ContextVk *contextVk, const gl::Rectangle &renderArea);
VkClearValue getCorrectedColorClearValue(size_t colorIndexGL,
const VkClearColorValue &clearColor) const;
WindowSurfaceVk *mBackbuffer;
......
......@@ -701,8 +701,9 @@ void ClearValuesArray::store(uint32_t index,
// We do this double if to handle the packed depth-stencil case.
if ((aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT) != 0)
{
// Special case for stencil.
ASSERT(index == kClearValueDepthIndex);
// Ensure for packed DS we're writing to the depth index.
ASSERT(index == kClearValueDepthIndex ||
(index == kClearValueStencilIndex && aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT));
mValues[kClearValueStencilIndex] = clearValue;
mEnabled.set(kClearValueStencilIndex);
}
......
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