Commit 03c18fbd by Charlie Lao Committed by Commit Bot

Vulkan: Skip load if depth/stencil value are undefined

EGL1.5 spec says depth/stencil data are undefined after swap. This CL will track the depth/stencil data and mark it as undefined and skip the load if it is undefined. Bug: b/153885625 Change-Id: Ifb3d88d442da547fa78c1eae091cbae08a20d0ab Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2148179Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>
parent 764d572b
......@@ -2389,6 +2389,8 @@ void ContextVk::optimizeRenderPassForPresent(VkFramebuffer framebufferHandle)
// Change depthstencil attachment storeOp to DONT_CARE
mRenderPassCommands.invalidateRenderPassStencilAttachment(depthStencilAttachmentIndexVk);
mRenderPassCommands.invalidateRenderPassDepthAttachment(depthStencilAttachmentIndexVk);
// Mark content as invalid so that we will not load them in next renderpass
depthStencilRenderTarget->invalidateContent();
}
// Use finalLayout instead of extra barrier for layout change to present
......
......@@ -1357,20 +1357,34 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
ANGLE_TRY(colorRenderTarget->onColorDraw(contextVk));
renderPassAttachmentOps.initWithLoadStore(attachmentClearValues.size(),
vk::ImageLayout::ColorAttachment,
vk::ImageLayout::ColorAttachment);
renderPassAttachmentOps.initWithStore(
attachmentClearValues.size(), VK_ATTACHMENT_LOAD_OP_LOAD,
vk::ImageLayout::ColorAttachment, vk::ImageLayout::ColorAttachment);
attachmentClearValues.emplace_back(kUninitializedClearValue);
}
RenderTargetVk *depthStencilRenderTarget = getDepthStencilRenderTarget();
if (depthStencilRenderTarget)
{
VkAttachmentLoadOp loadOp;
if (depthStencilRenderTarget->hasDefinedContent())
{
loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
}
else
{
loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
}
renderPassAttachmentOps.initWithStore(attachmentClearValues.size(), loadOp,
vk::ImageLayout::DepthStencilAttachment,
vk::ImageLayout::DepthStencilAttachment);
// This must be called after hasDefinedContent() 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
// have valid content. The only time it has undefined content is between swap and
// startNewRenderPass
ANGLE_TRY(depthStencilRenderTarget->onDepthStencilDraw(contextVk));
renderPassAttachmentOps.initWithLoadStore(attachmentClearValues.size(),
vk::ImageLayout::DepthStencilAttachment,
vk::ImageLayout::DepthStencilAttachment);
attachmentClearValues.emplace_back(kUninitializedClearValue);
}
......
......@@ -17,9 +17,11 @@
namespace rx
{
RenderTargetVk::RenderTargetVk()
: mImage(nullptr), mImageViews(nullptr), mLevelIndex(0), mLayerIndex(0)
{}
{
reset();
}
RenderTargetVk::~RenderTargetVk() {}
......@@ -27,12 +29,10 @@ RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
: mImage(other.mImage),
mImageViews(other.mImageViews),
mLevelIndex(other.mLevelIndex),
mLayerIndex(other.mLayerIndex)
mLayerIndex(other.mLayerIndex),
mContentDefined(other.mContentDefined)
{
other.mImage = nullptr;
other.mImageViews = nullptr;
other.mLevelIndex = 0;
other.mLayerIndex = 0;
other.reset();
}
void RenderTargetVk::init(vk::ImageHelper *image,
......@@ -44,14 +44,18 @@ void RenderTargetVk::init(vk::ImageHelper *image,
mImageViews = imageViews;
mLevelIndex = levelIndex;
mLayerIndex = layerIndex;
// We are being conservative here since our targeted optimization is to skip surfaceVK's depth
// buffer load after swap call.
mContentDefined = true;
}
void RenderTargetVk::reset()
{
mImage = nullptr;
mImageViews = nullptr;
mLevelIndex = 0;
mLayerIndex = 0;
mImage = nullptr;
mImageViews = nullptr;
mLevelIndex = 0;
mLayerIndex = 0;
mContentDefined = false;
}
vk::AttachmentSerial RenderTargetVk::getAssignSerial(ContextVk *contextVk)
......@@ -74,6 +78,7 @@ angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk)
contextVk->onRenderPassImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorAttachment,
mImage);
mContentDefined = true;
retainImageViews(contextVk);
return angle::Result::Continue;
......@@ -87,6 +92,7 @@ angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk)
VkImageAspectFlags aspectFlags = vk::GetDepthStencilAspectFlags(format);
contextVk->onRenderPassImageWrite(aspectFlags, vk::ImageLayout::DepthStencilAttachment, mImage);
mContentDefined = true;
retainImageViews(contextVk);
return angle::Result::Continue;
......
......@@ -77,11 +77,18 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
void retainImageViews(ContextVk *contextVk) const;
bool hasDefinedContent() const { return mContentDefined; }
// mark content as undefined so that certain optimizations are possible
void invalidateContent() { mContentDefined = false; }
private:
vk::ImageHelper *mImage;
vk::ImageViewHelper *mImageViews;
uint32_t mLevelIndex;
uint32_t mLayerIndex;
// Right now we are only tracking depth/stencil buffer. We could expand it to cover color
// buffers if needed in future.
bool mContentDefined;
};
// A vector of rendertargets
......
......@@ -1189,8 +1189,9 @@ angle::Result UtilsVk::startRenderPass(ContextVk *contextVk,
std::vector<VkClearValue> clearValues = {{}};
ASSERT(clearValues.size() == 1);
renderPassAttachmentOps.initWithLoadStore(0, vk::ImageLayout::ColorAttachment,
vk::ImageLayout::ColorAttachment);
renderPassAttachmentOps.initWithStore(0, VK_ATTACHMENT_LOAD_OP_LOAD,
vk::ImageLayout::ColorAttachment,
vk::ImageLayout::ColorAttachment);
ANGLE_TRY(contextVk->flushAndBeginRenderPass(framebuffer, renderArea, renderPassDesc,
renderPassAttachmentOps, clearValues,
......
......@@ -1456,16 +1456,17 @@ void AttachmentOpsArray::initDummyOp(size_t index,
SetBitField(ops.stencilStoreOp, VK_ATTACHMENT_STORE_OP_DONT_CARE);
}
void AttachmentOpsArray::initWithLoadStore(size_t index,
ImageLayout initialLayout,
ImageLayout finalLayout)
void AttachmentOpsArray::initWithStore(size_t index,
VkAttachmentLoadOp loadOp,
ImageLayout initialLayout,
ImageLayout finalLayout)
{
PackedAttachmentOpsDesc &ops = mOps[index];
SetBitField(ops.initialLayout, initialLayout);
SetBitField(ops.finalLayout, finalLayout);
SetBitField(ops.loadOp, VK_ATTACHMENT_LOAD_OP_LOAD);
SetBitField(ops.stencilLoadOp, VK_ATTACHMENT_LOAD_OP_LOAD);
SetBitField(ops.loadOp, loadOp);
SetBitField(ops.stencilLoadOp, loadOp);
SetBitField(ops.storeOp, VK_ATTACHMENT_STORE_OP_STORE);
SetBitField(ops.stencilStoreOp, VK_ATTACHMENT_STORE_OP_STORE);
}
......
......@@ -154,8 +154,11 @@ class AttachmentOpsArray final
// Initializes an attachment op with whatever values. Used for compatible RenderPass checks.
void initDummyOp(size_t index, ImageLayout initialLayout, ImageLayout finalLayout);
// Initialize an attachment op with all load and store operations.
void initWithLoadStore(size_t index, ImageLayout initialLayout, ImageLayout finalLayout);
// Initialize an attachment op with store operations.
void initWithStore(size_t index,
VkAttachmentLoadOp loadOp,
ImageLayout initialLayout,
ImageLayout finalLayout);
size_t hash() const;
......
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