Commit 61fa0878 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Invalidate/restore depth/stencil separately.

Depth/stencil content defined is already tracked separately in the ImageHelper. This change exposes this tracking from RenderTargetVk. Bug: b/167275320 Bug: angleproject:4836 Change-Id: Ie6520e7a4ab557eb233c60c6ab0d4a8f8f098bf6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2462039 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarIan Elliott <ianelliott@google.com>
parent 87f3f4b5
...@@ -2568,6 +2568,7 @@ void ContextVk::optimizeRenderPassForPresent(VkFramebuffer framebufferHandle) ...@@ -2568,6 +2568,7 @@ void ContextVk::optimizeRenderPassForPresent(VkFramebuffer framebufferHandle)
mRenderPassCommands->invalidateRenderPassDepthAttachment(dsState); mRenderPassCommands->invalidateRenderPassDepthAttachment(dsState);
// Mark content as invalid so that we will not load them in next renderpass // Mark content as invalid so that we will not load them in next renderpass
depthStencilRenderTarget->invalidateEntireContent(this); depthStencilRenderTarget->invalidateEntireContent(this);
depthStencilRenderTarget->invalidateEntireStencilContent(this);
} }
// Use finalLayout instead of extra barrier for layout change to present // Use finalLayout instead of extra barrier for layout change to present
...@@ -5131,12 +5132,12 @@ angle::Result ContextVk::updateRenderPassDepthStencilAccess() ...@@ -5131,12 +5132,12 @@ angle::Result ContextVk::updateRenderPassDepthStencilAccess()
if (mRenderPassCommands->onDepthAccess(depthAccess)) if (mRenderPassCommands->onDepthAccess(depthAccess))
{ {
// The attachment is no longer invalidated, so set mContentDefined to true // The attachment is no longer invalidated, so set mContentDefined to true
mDrawFramebuffer->restoreDepthStencilDefinedContents(); mDrawFramebuffer->restoreDepthDefinedContents();
} }
if (mRenderPassCommands->onStencilAccess(stencilAccess)) if (mRenderPassCommands->onStencilAccess(stencilAccess))
{ {
// The attachment is no longer invalidated, so set mContentDefined to true // The attachment is no longer invalidated, so set mContentDefined to true
mDrawFramebuffer->restoreDepthStencilDefinedContents(); mDrawFramebuffer->restoreStencilDefinedContents();
} }
mDrawFramebuffer->updateRenderPassReadOnlyDepthMode(this, mRenderPassCommands); mDrawFramebuffer->updateRenderPassReadOnlyDepthMode(this, mRenderPassCommands);
......
...@@ -1522,12 +1522,18 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk, ...@@ -1522,12 +1522,18 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
} }
} }
// If we have a depth / stencil render target AND we invalidate both we'll mark it as // If we have a depth / stencil render target, invalidate its aspects.
// invalid. Maybe in the future add separate depth & stencil invalid flags. if (depthStencilRenderTarget)
if (depthStencilRenderTarget && invalidateDepthBuffer && invalidateStencilBuffer) {
if (invalidateDepthBuffer)
{ {
depthStencilRenderTarget->invalidateEntireContent(contextVk); depthStencilRenderTarget->invalidateEntireContent(contextVk);
} }
if (invalidateStencilBuffer)
{
depthStencilRenderTarget->invalidateEntireStencilContent(contextVk);
}
}
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -2207,7 +2213,7 @@ angle::Result FramebufferVk::clearWithCommand( ...@@ -2207,7 +2213,7 @@ angle::Result FramebufferVk::clearWithCommand(
if (renderpassCommands->onDepthAccess(vk::ResourceAccess::Write)) if (renderpassCommands->onDepthAccess(vk::ResourceAccess::Write))
{ {
// The attachment is no longer invalidated, so set mContentDefined to true // The attachment is no longer invalidated, so set mContentDefined to true
restoreDepthStencilDefinedContents(); restoreDepthDefinedContents();
} }
} }
...@@ -2219,7 +2225,7 @@ angle::Result FramebufferVk::clearWithCommand( ...@@ -2219,7 +2225,7 @@ angle::Result FramebufferVk::clearWithCommand(
if (renderpassCommands->onStencilAccess(vk::ResourceAccess::Write)) if (renderpassCommands->onStencilAccess(vk::ResourceAccess::Write))
{ {
// The attachment is no longer invalidated, so set mContentDefined to true // The attachment is no longer invalidated, so set mContentDefined to true
restoreDepthStencilDefinedContents(); restoreStencilDefinedContents();
} }
} }
...@@ -2360,6 +2366,10 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ...@@ -2360,6 +2366,10 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
depthStencilRenderTarget->isEntirelyTransient()) depthStencilRenderTarget->isEntirelyTransient())
{ {
depthLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; depthLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
}
if (!depthStencilRenderTarget->hasDefinedStencilContent() ||
depthStencilRenderTarget->isEntirelyTransient())
{
stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
} }
...@@ -2494,7 +2504,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ...@@ -2494,7 +2504,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
if (depthStencilRenderTarget) if (depthStencilRenderTarget)
{ {
// This must be called after hasDefinedContent() since it will set content to valid. We are // This must be called after hasDefined*Content() since it will set content to valid. We are
// tracking content valid very loosely here that as long as it is attached, it assumes will // tracking content valid very loosely here that as long as it is attached, it assumes will
// have valid content. The only time it has undefined content is between swap and // have valid content. The only time it has undefined content is between swap and
// startNewRenderPass // startNewRenderPass
...@@ -2519,7 +2529,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ...@@ -2519,7 +2529,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
return angle::Result::Continue; return angle::Result::Continue;
} }
void FramebufferVk::restoreDepthStencilDefinedContents() void FramebufferVk::restoreDepthDefinedContents()
{ {
// If the depthStencilRenderTarget does not have "defined content" (i.e. meaning that a future // If the depthStencilRenderTarget does not have "defined content" (i.e. meaning that a future
// render pass should use a loadOp of DONT_CARE), we should restore it (i.e. so that a future // render pass should use a loadOp of DONT_CARE), we should restore it (i.e. so that a future
...@@ -2531,6 +2541,16 @@ void FramebufferVk::restoreDepthStencilDefinedContents() ...@@ -2531,6 +2541,16 @@ void FramebufferVk::restoreDepthStencilDefinedContents()
} }
} }
void FramebufferVk::restoreStencilDefinedContents()
{
// Similar to restoreDepthDefinedContents, but for the stencil aspect.
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget)
{
depthStencilRenderTarget->restoreEntireStencilContent();
}
}
void FramebufferVk::updateActiveColorMasks(size_t colorIndexGL, bool r, bool g, bool b, bool a) void FramebufferVk::updateActiveColorMasks(size_t colorIndexGL, bool r, bool g, bool b, bool a)
{ {
gl::BlendStateExt::ColorMaskStorage::SetValueIndexed( gl::BlendStateExt::ColorMaskStorage::SetValueIndexed(
......
...@@ -118,7 +118,8 @@ class FramebufferVk : public FramebufferImpl ...@@ -118,7 +118,8 @@ class FramebufferVk : public FramebufferImpl
angle::Result startNewRenderPass(ContextVk *contextVk, angle::Result startNewRenderPass(ContextVk *contextVk,
const gl::Rectangle &renderArea, const gl::Rectangle &renderArea,
vk::CommandBuffer **commandBufferOut); vk::CommandBuffer **commandBufferOut);
void restoreDepthStencilDefinedContents(); void restoreDepthDefinedContents();
void restoreStencilDefinedContents();
RenderTargetVk *getFirstRenderTarget() const; RenderTargetVk *getFirstRenderTarget() const;
GLint getSamples() const; GLint getSamples() const;
......
...@@ -278,31 +278,37 @@ void RenderTargetVk::retainImageViews(ContextVk *contextVk) const ...@@ -278,31 +278,37 @@ void RenderTargetVk::retainImageViews(ContextVk *contextVk) const
bool RenderTargetVk::hasDefinedContent() const bool RenderTargetVk::hasDefinedContent() const
{ {
vk::ImageHelper *image = getOwnerOfData(); vk::ImageHelper *image = getOwnerOfData();
// TODO: separate depth and stencil defined content. https://issuetracker.google.com/167275320 return image->hasSubresourceDefinedContent(mLevelIndexGL, mLayerIndex);
return image->hasSubresourceDefinedContent(mLevelIndexGL, mLayerIndex) || }
image->hasSubresourceDefinedStencilContent(mLevelIndexGL, mLayerIndex);
bool RenderTargetVk::hasDefinedStencilContent() const
{
vk::ImageHelper *image = getOwnerOfData();
return image->hasSubresourceDefinedStencilContent(mLevelIndexGL, mLayerIndex);
} }
void RenderTargetVk::invalidateEntireContent(ContextVk *contextVk) void RenderTargetVk::invalidateEntireContent(ContextVk *contextVk)
{ {
vk::ImageHelper *image = getOwnerOfData(); vk::ImageHelper *image = getOwnerOfData();
// TODO: separate depth and stencil defined content. https://issuetracker.google.com/167275320
image->invalidateSubresourceContent(contextVk, mLevelIndexGL, mLayerIndex); image->invalidateSubresourceContent(contextVk, mLevelIndexGL, mLayerIndex);
if ((image->getAspectFlags() & VK_IMAGE_ASPECT_STENCIL_BIT) != 0) }
{
void RenderTargetVk::invalidateEntireStencilContent(ContextVk *contextVk)
{
vk::ImageHelper *image = getOwnerOfData();
image->invalidateSubresourceStencilContent(contextVk, mLevelIndexGL, mLayerIndex); image->invalidateSubresourceStencilContent(contextVk, mLevelIndexGL, mLayerIndex);
}
} }
void RenderTargetVk::restoreEntireContent() void RenderTargetVk::restoreEntireContent()
{ {
vk::ImageHelper *image = getOwnerOfData(); vk::ImageHelper *image = getOwnerOfData();
// TODO: separate depth and stencil defined content. https://issuetracker.google.com/167275320
image->restoreSubresourceContent(mLevelIndexGL, mLayerIndex); image->restoreSubresourceContent(mLevelIndexGL, mLayerIndex);
if ((image->getAspectFlags() & VK_IMAGE_ASPECT_STENCIL_BIT) != 0) }
{
void RenderTargetVk::restoreEntireStencilContent()
{
vk::ImageHelper *image = getOwnerOfData();
image->restoreSubresourceStencilContent(mLevelIndexGL, mLayerIndex); image->restoreSubresourceStencilContent(mLevelIndexGL, mLayerIndex);
}
} }
gl::ImageIndex RenderTargetVk::getImageIndex() const gl::ImageIndex RenderTargetVk::getImageIndex() const
......
...@@ -109,10 +109,13 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget ...@@ -109,10 +109,13 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
void retainImageViews(ContextVk *contextVk) const; void retainImageViews(ContextVk *contextVk) const;
bool hasDefinedContent() const; bool hasDefinedContent() const;
bool hasDefinedStencilContent() const;
// Mark content as undefined so that certain optimizations are possible such as using DONT_CARE // Mark content as undefined so that certain optimizations are possible such as using DONT_CARE
// as loadOp of the render target in the next renderpass. // as loadOp of the render target in the next renderpass.
void invalidateEntireContent(ContextVk *contextVk); void invalidateEntireContent(ContextVk *contextVk);
void invalidateEntireStencilContent(ContextVk *contextVk);
void restoreEntireContent(); void restoreEntireContent();
void restoreEntireStencilContent();
// See the description of mTransience for details of how the following two can interact. // See the description of mTransience for details of how the following two can interact.
bool hasResolveAttachment() const { return mResolveImage != nullptr && !isEntirelyTransient(); } bool hasResolveAttachment() const { return mResolveImage != nullptr && !isEntirelyTransient(); }
...@@ -141,7 +144,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget ...@@ -141,7 +144,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
// implement GL_EXT_multisampled_render_to_texture, so while the rendering is done on mImage // implement GL_EXT_multisampled_render_to_texture, so while the rendering is done on mImage
// during the renderpass, the resolved image is the one that actually holds the data. This // during the renderpass, the resolved image is the one that actually holds the data. This
// means that data uploads and blit are done on this image, copies are done out of this image // means that data uploads and blit are done on this image, copies are done out of this image
// etc. This means that if there is no clear, and hasDefinedContent(), the contents of // etc. This means that if there is no clear, and hasDefined*Content(), the contents of
// mResolveImage must be copied to mImage since the loadOp of the attachment must be set to // mResolveImage must be copied to mImage since the loadOp of the attachment must be set to
// LOAD. // LOAD.
vk::ImageHelper *mResolveImage; vk::ImageHelper *mResolveImage;
......
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