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, ...@@ -275,7 +275,7 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context,
// there's a depth mask, depth clearing is already disabled. // there's a depth mask, depth clearing is already disabled.
bool maskedClearColor = bool maskedClearColor =
clearColor && (mActiveColorComponents & colorMaskFlags) != mActiveColorComponents; clearColor && (mActiveColorComponents & colorMaskFlags) != mActiveColorComponents;
bool maskedClearStencil = stencilMask != 0xFF; bool maskedClearStencil = clearStencil && stencilMask != 0xFF;
bool clearColorWithRenderPassLoadOp = clearColor && !maskedClearColor && !scissoredClear; bool clearColorWithRenderPassLoadOp = clearColor && !maskedClearColor && !scissoredClear;
bool clearDepthWithRenderPassLoadOp = clearDepth && !scissoredClear; bool clearDepthWithRenderPassLoadOp = clearDepth && !scissoredClear;
...@@ -325,6 +325,13 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context, ...@@ -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 // 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. // bits. This can only be done with a draw call.
return clearWithDraw(contextVk, scissoredRenderArea, clearColorBuffers, clearDepth, return clearWithDraw(contextVk, scissoredRenderArea, clearColorBuffers, clearDepth,
...@@ -1370,6 +1377,40 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe ...@@ -1370,6 +1377,40 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe
return angle::Result::Continue; 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, angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
const gl::Rectangle &clearArea, const gl::Rectangle &clearArea,
gl::DrawBufferMask clearColorBuffers, gl::DrawBufferMask clearColorBuffers,
...@@ -1386,11 +1427,8 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk, ...@@ -1386,11 +1427,8 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
clearValue.depthStencil = clearDepthStencilValue; clearValue.depthStencil = clearDepthStencilValue;
mDeferredClears.store(vk::kClearValueDepthIndex, VK_IMAGE_ASPECT_DEPTH_BIT, clearValue); mDeferredClears.store(vk::kClearValueDepthIndex, VK_IMAGE_ASPECT_DEPTH_BIT, clearValue);
// Ensure the clear happens immediately. // Scissored-only clears are handled in clearImmediatelyWithRenderPassOp.
if (clearColorBuffers.none() && !clearStencil) ASSERT(clearColorBuffers.any() || clearStencil);
{
return flushDeferredClears(contextVk, clearArea);
}
} }
UtilsVk::ClearFramebufferParameters params = {}; UtilsVk::ClearFramebufferParameters params = {};
...@@ -1432,6 +1470,40 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk, ...@@ -1432,6 +1470,40 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
return angle::Result::Continue; 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, void FramebufferVk::clearWithRenderPassOp(gl::DrawBufferMask clearColorBuffers,
bool clearDepth, bool clearDepth,
bool clearStencil, bool clearStencil,
...@@ -1443,33 +1515,8 @@ void FramebufferVk::clearWithRenderPassOp(gl::DrawBufferMask clearColorBuffers, ...@@ -1443,33 +1515,8 @@ void FramebufferVk::clearWithRenderPassOp(gl::DrawBufferMask clearColorBuffers,
{ {
ASSERT(mState.getEnabledDrawBuffers().test(colorIndexGL)); ASSERT(mState.getEnabledDrawBuffers().test(colorIndexGL));
RenderTargetVk *renderTarget = getColorDrawRenderTarget(colorIndexGL); RenderTargetVk *renderTarget = getColorDrawRenderTarget(colorIndexGL);
VkClearValue clearValue = getCorrectedColorClearValue(colorIndexGL, clearColorValue);
VkClearValue clearValue; gl::ImageIndex imageIndex = renderTarget->getImageIndex();
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();
renderTarget->getImage().stageClear(imageIndex, VK_IMAGE_ASPECT_COLOR_BIT, clearValue); renderTarget->getImage().stageClear(imageIndex, VK_IMAGE_ASPECT_COLOR_BIT, clearValue);
} }
......
...@@ -157,6 +157,16 @@ class FramebufferVk : public FramebufferImpl ...@@ -157,6 +157,16 @@ class FramebufferVk : public FramebufferImpl
bool clearStencil, bool clearStencil,
const VkClearColorValue &clearColorValue, const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue); 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, angle::Result clearWithDraw(ContextVk *contextVk,
const gl::Rectangle &clearArea, const gl::Rectangle &clearArea,
gl::DrawBufferMask clearColorBuffers, gl::DrawBufferMask clearColorBuffers,
...@@ -186,6 +196,8 @@ class FramebufferVk : public FramebufferImpl ...@@ -186,6 +196,8 @@ class FramebufferVk : public FramebufferImpl
VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const; VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const;
angle::Result flushDeferredClears(ContextVk *contextVk, const gl::Rectangle &renderArea); angle::Result flushDeferredClears(ContextVk *contextVk, const gl::Rectangle &renderArea);
VkClearValue getCorrectedColorClearValue(size_t colorIndexGL,
const VkClearColorValue &clearColor) const;
WindowSurfaceVk *mBackbuffer; WindowSurfaceVk *mBackbuffer;
......
...@@ -701,8 +701,9 @@ void ClearValuesArray::store(uint32_t index, ...@@ -701,8 +701,9 @@ void ClearValuesArray::store(uint32_t index,
// We do this double if to handle the packed depth-stencil case. // We do this double if to handle the packed depth-stencil case.
if ((aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT) != 0) if ((aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT) != 0)
{ {
// Special case for stencil. // Ensure for packed DS we're writing to the depth index.
ASSERT(index == kClearValueDepthIndex); ASSERT(index == kClearValueDepthIndex ||
(index == kClearValueStencilIndex && aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT));
mValues[kClearValueStencilIndex] = clearValue; mValues[kClearValueStencilIndex] = clearValue;
mEnabled.set(kClearValueStencilIndex); 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