Commit a61e273a by Jamie Madill Committed by Commit Bot

Vulkan: Fix store ops with linear command recording.

DiscardFramebuffer was being ignored in the new linear path. Fix this by using the correct APIs. Also cleans up some of the access to the "RenderPassCommandBuffer" struct in ContextVk. Add a new accessor that returns the RenderPass without a flush that ensures it is only called when a RenderPass is already started. Bug: angleproject:4029 Change-Id: Ibd199f3a371c0f91b448a0b34c8752dc8b76c284 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2057329Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent b4357d46
......@@ -2204,6 +2204,9 @@ angle::Result ContextVk::clearWithRenderPassOp(
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue)
{
// Validate cache variable is in sync.
ASSERT(mDrawFramebuffer == vk::GetImpl(mState.getDrawFramebuffer()));
ASSERT(!commandGraphEnabled());
// Start a new render pass if:
//
......@@ -2213,12 +2216,11 @@ angle::Result ContextVk::clearWithRenderPassOp(
// - the current render area doesn't match the clear area. We need the render area to be
// exactly as specified by the scissor for the loadOp to clear only that area. See
// ContextVk::updateScissor for more information.
vk::FramebufferHelper *framebuffer = mDrawFramebuffer->getFramebuffer();
if (!framebuffer->valid() || !framebuffer->renderPassStartedButEmpty() ||
framebuffer->getRenderPassRenderArea() != clearArea)
if (!mRenderPassCommands.started() ||
(mRenderPassCommands.started() && !mRenderPassCommands.empty()) ||
mRenderPassCommands.getRenderArea() != clearArea)
{
mGraphicsDirtyBits |= mNewGraphicsCommandBufferDirtyBits;
ANGLE_TRY(mDrawFramebuffer->startNewRenderPass(this, clearArea, &mRenderPassCommandBuffer));
}
else
......@@ -2269,14 +2271,14 @@ angle::Result ContextVk::clearWithRenderPassOp(
{
if (clearDepth)
{
getRenderPassCommandBuffer().clearRenderPassDepthAttachment(
attachmentIndexVk, clearDepthStencilValue.depth);
mRenderPassCommands.clearRenderPassDepthAttachment(attachmentIndexVk,
clearDepthStencilValue.depth);
}
if (clearStencil)
{
getRenderPassCommandBuffer().clearRenderPassStencilAttachment(
attachmentIndexVk, clearDepthStencilValue.stencil);
mRenderPassCommands.clearRenderPassStencilAttachment(attachmentIndexVk,
clearDepthStencilValue.stencil);
}
}
......@@ -4072,22 +4074,20 @@ angle::Result ContextVk::onImageWrite(VkImageAspectFlags aspectFlags,
return angle::Result::Continue;
}
void ContextVk::beginRenderPass(const vk::Framebuffer &framebuffer,
const gl::Rectangle &renderArea,
const vk::RenderPassDesc &renderPassDesc,
const vk::AttachmentOpsArray &renderPassAttachmentOps,
const std::vector<VkClearValue> &clearValues,
vk::CommandBuffer **commandBufferOut)
angle::Result ContextVk::beginRenderPass(const vk::Framebuffer &framebuffer,
const gl::Rectangle &renderArea,
const vk::RenderPassDesc &renderPassDesc,
const vk::AttachmentOpsArray &renderPassAttachmentOps,
const std::vector<VkClearValue> &clearValues,
vk::CommandBuffer **commandBufferOut)
{
ASSERT(!commandGraphEnabled());
if (!mOutsideRenderPassCommands.empty())
{
mOutsideRenderPassCommands.flushToPrimary(&mPrimaryCommands);
}
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
mRenderPassCommands.beginRenderPass(framebuffer, renderArea, renderPassDesc,
renderPassAttachmentOps, clearValues, commandBufferOut);
return angle::Result::Continue;
}
angle::Result ContextVk::endRenderPass()
......
......@@ -204,7 +204,8 @@ class RenderPassCommandBuffer final : public CommandBufferHelper
angle::Result flushToPrimary(ContextVk *contextVk, vk::PrimaryCommandBuffer *primary);
bool empty() const { return !mRenderPassStarted; }
bool empty() const { return !started() && mCommandBuffer.empty(); }
bool started() const { return mRenderPassStarted; }
void reset();
uint32_t getAndResetCounter()
......@@ -602,16 +603,18 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
return angle::Result::Continue;
}
void beginRenderPass(const vk::Framebuffer &framebuffer,
const gl::Rectangle &renderArea,
const vk::RenderPassDesc &renderPassDesc,
const vk::AttachmentOpsArray &renderPassAttachmentOps,
const std::vector<VkClearValue> &clearValues,
vk::CommandBuffer **commandBufferOut);
angle::Result beginRenderPass(const vk::Framebuffer &framebuffer,
const gl::Rectangle &renderArea,
const vk::RenderPassDesc &renderPassDesc,
const vk::AttachmentOpsArray &renderPassAttachmentOps,
const std::vector<VkClearValue> &clearValues,
vk::CommandBuffer **commandBufferOut);
RenderPassCommandBuffer &getRenderPassCommandBuffer()
bool hasStartedRenderPass() const { return !mRenderPassCommands.empty(); }
RenderPassCommandBuffer &getStartedRenderPassCommands()
{
mOutsideRenderPassCommands.flushToPrimary(&mPrimaryCommands);
ASSERT(hasStartedRenderPass());
return mRenderPassCommands;
}
......
......@@ -164,9 +164,22 @@ angle::Result FramebufferVk::invalidate(const gl::Context *context,
ContextVk *contextVk = vk::GetImpl(context);
mFramebuffer.onResourceAccess(&contextVk->getResourceUseList());
if (mFramebuffer.valid() && mFramebuffer.hasStartedRenderPass())
if (mFramebuffer.valid())
{
invalidateImpl(contextVk, count, attachments);
if (contextVk->commandGraphEnabled())
{
if (mFramebuffer.hasStartedRenderPass())
{
ANGLE_TRY(invalidateImpl(contextVk, count, attachments));
}
}
else
{
if (contextVk->hasStartedRenderPass())
{
ANGLE_TRY(invalidateImpl(contextVk, count, attachments));
}
}
}
return angle::Result::Continue;
......@@ -182,10 +195,24 @@ angle::Result FramebufferVk::invalidateSub(const gl::Context *context,
// RenderPass' storeOp cannot be made conditional to a specific region, so we only apply this
// hint if the requested area encompasses the render area.
if (mFramebuffer.valid() && mFramebuffer.hasStartedRenderPass() &&
area.encloses(mFramebuffer.getRenderPassRenderArea()))
if (mFramebuffer.valid())
{
invalidateImpl(contextVk, count, attachments);
if (contextVk->commandGraphEnabled())
{
if (mFramebuffer.hasStartedRenderPass() &&
area.encloses(mFramebuffer.getRenderPassRenderArea()))
{
ANGLE_TRY(invalidateImpl(contextVk, count, attachments));
}
}
else
{
if (contextVk->hasStartedRenderPass() &&
area.encloses(contextVk->getStartedRenderPassCommands().getRenderArea()))
{
ANGLE_TRY(invalidateImpl(contextVk, count, attachments));
}
}
}
return angle::Result::Continue;
......@@ -983,9 +1010,11 @@ angle::Result FramebufferVk::updateColorAttachment(const gl::Context *context, s
return angle::Result::Continue;
}
void FramebufferVk::invalidateImpl(ContextVk *contextVk, size_t count, const GLenum *attachments)
angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
size_t count,
const GLenum *attachments)
{
ASSERT(mFramebuffer.hasStartedRenderPass());
ASSERT(contextVk->hasStartedRenderPass());
gl::DrawBufferMask invalidateColorBuffers;
bool invalidateDepthBuffer = false;
......@@ -1025,7 +1054,15 @@ void FramebufferVk::invalidateImpl(ContextVk *contextVk, size_t count, const GLe
{
if (invalidateColorBuffers.test(colorIndexGL))
{
mFramebuffer.invalidateRenderPassColorAttachment(attachmentIndexVk);
if (contextVk->commandGraphEnabled())
{
mFramebuffer.invalidateRenderPassColorAttachment(attachmentIndexVk);
}
else
{
contextVk->getStartedRenderPassCommands().invalidateRenderPassColorAttachment(
attachmentIndexVk);
}
}
++attachmentIndexVk;
}
......@@ -1035,12 +1072,28 @@ void FramebufferVk::invalidateImpl(ContextVk *contextVk, size_t count, const GLe
{
if (invalidateDepthBuffer)
{
mFramebuffer.invalidateRenderPassDepthAttachment(attachmentIndexVk);
if (contextVk->commandGraphEnabled())
{
mFramebuffer.invalidateRenderPassDepthAttachment(attachmentIndexVk);
}
else
{
contextVk->getStartedRenderPassCommands().invalidateRenderPassDepthAttachment(
attachmentIndexVk);
}
}
if (invalidateStencilBuffer)
{
mFramebuffer.invalidateRenderPassStencilAttachment(attachmentIndexVk);
if (contextVk->commandGraphEnabled())
{
mFramebuffer.invalidateRenderPassStencilAttachment(attachmentIndexVk);
}
else
{
contextVk->getStartedRenderPassCommands().invalidateRenderPassStencilAttachment(
attachmentIndexVk);
}
}
}
......@@ -1057,7 +1110,16 @@ void FramebufferVk::invalidateImpl(ContextVk *contextVk, size_t count, const GLe
// this pattern, this optimization may not be necessary if no application does this. It is
// expected that an application would invalidate() when it's done with the framebuffer, so the
// render pass would have closed either way.
mFramebuffer.finishCurrentCommands(contextVk);
if (contextVk->commandGraphEnabled())
{
mFramebuffer.finishCurrentCommands(contextVk);
}
else
{
ANGLE_TRY(contextVk->endRenderPass());
}
return angle::Result::Continue;
}
angle::Result FramebufferVk::syncState(const gl::Context *context,
......@@ -1290,15 +1352,7 @@ angle::Result FramebufferVk::clearWithRenderPassOp(
SetEmulatedAlphaValue(renderTarget->getImageFormat(), &value);
}
if (contextVk->commandGraphEnabled())
{
mFramebuffer.clearRenderPassColorAttachment(attachmentIndexVk, value);
}
else
{
contextVk->getRenderPassCommandBuffer().clearRenderPassColorAttachment(
attachmentIndexVk, value);
}
mFramebuffer.clearRenderPassColorAttachment(attachmentIndexVk, value);
}
++attachmentIndexVk;
}
......@@ -1309,30 +1363,14 @@ angle::Result FramebufferVk::clearWithRenderPassOp(
{
if (clearDepth)
{
if (contextVk->commandGraphEnabled())
{
mFramebuffer.clearRenderPassDepthAttachment(attachmentIndexVk,
clearDepthStencilValue.depth);
}
else
{
contextVk->getRenderPassCommandBuffer().clearRenderPassDepthAttachment(
attachmentIndexVk, clearDepthStencilValue.depth);
}
mFramebuffer.clearRenderPassDepthAttachment(attachmentIndexVk,
clearDepthStencilValue.depth);
}
if (clearStencil)
{
if (contextVk->commandGraphEnabled())
{
mFramebuffer.clearRenderPassStencilAttachment(attachmentIndexVk,
clearDepthStencilValue.stencil);
}
else
{
contextVk->getRenderPassCommandBuffer().clearRenderPassStencilAttachment(
attachmentIndexVk, clearDepthStencilValue.stencil);
}
mFramebuffer.clearRenderPassStencilAttachment(attachmentIndexVk,
clearDepthStencilValue.stencil);
}
}
......@@ -1413,7 +1451,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&writeCommands));
ANGLE_TRY(contextVk->endRenderPass());
}
// Initialize RenderPass info.
......@@ -1451,10 +1489,9 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
}
else
{
contextVk->beginRenderPass(*framebuffer, renderArea, mRenderPassDesc,
renderPassAttachmentOps, attachmentClearValues,
commandBufferOut);
return angle::Result::Continue;
return contextVk->beginRenderPass(*framebuffer, renderArea, mRenderPassDesc,
renderPassAttachmentOps, attachmentClearValues,
commandBufferOut);
}
}
......
......@@ -178,7 +178,7 @@ class FramebufferVk : public FramebufferImpl
void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a);
void updateRenderPassDesc();
angle::Result updateColorAttachment(const gl::Context *context, size_t colorIndex);
void invalidateImpl(ContextVk *contextVk, size_t count, const GLenum *attachments);
angle::Result invalidateImpl(ContextVk *contextVk, size_t count, const GLenum *attachments);
WindowSurfaceVk *mBackbuffer;
......
......@@ -58,11 +58,11 @@ angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer)
{
ASSERT(commandBuffer->valid());
ASSERT(!mImage->getFormat().actualImageFormat().hasDepthOrStencilBits());
if (contextVk->commandGraphEnabled())
{
ASSERT(commandBuffer->valid());
mImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorAttachment,
commandBuffer);
......@@ -84,7 +84,6 @@ angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer)
{
ASSERT(commandBuffer->valid());
ASSERT(mImage->getFormat().actualImageFormat().hasDepthOrStencilBits());
const angle::Format &format = mImage->getFormat().actualImageFormat();
......@@ -92,6 +91,7 @@ angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk,
if (contextVk->commandGraphEnabled())
{
ASSERT(commandBuffer->valid());
mImage->changeLayout(aspectFlags, vk::ImageLayout::DepthStencilAttachment, commandBuffer);
// Set up dependencies between the RT resource and the Framebuffer.
......
......@@ -1261,8 +1261,9 @@ angle::Result UtilsVk::startRenderPass(ContextVk *contextVk,
}
else
{
contextVk->beginRenderPass(framebuffer, renderArea, renderPassDesc, renderPassAttachmentOps,
clearValues, commandBufferOut);
ANGLE_TRY(contextVk->beginRenderPass(framebuffer, renderArea, renderPassDesc,
renderPassAttachmentOps, clearValues,
commandBufferOut));
}
contextVk->addGarbage(&framebuffer);
......
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