Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 77e3d0a

Browse files
cclaoCommit Bot
authored andcommitted
Vulkan: Defer the depthStencil buffer layout change to endRenderPass
Depth stencil layout may change while we build the render pass, depending on the read/write access been made. Right now we are always inserting a layout change barrier at the start of render pass. Later on when the read/write property changes, we insert another layout change barrier. Similarly, we maintain the attachmentOps and RenderPassDesc::mPackedColorAttachmentRangeAndDSAccess as we changes read/write access. This makes code quite commplicated. This CL moves mReadOnlyDepthStencilMode from FramebufferVK to CommandBufferHelper object and we only maintain that boolean while we updating the read/write access. Then at the end of render pass or when depthStencil image is deleted, we update attachmentOps and mRenderPassDesc and layout transition all at once and only done once. This simplifies the read only depth stencil mode implementation a lot. Bug: b/168953278 Change-Id: Ie263b4526c82a9858e5d1f141ea58f499187a3ca Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2432075 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Tim Van Patten <timvp@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>
1 parent f074d61 commit 77e3d0a

File tree

9 files changed

+173
-162
lines changed

9 files changed

+173
-162
lines changed

src/libANGLE/renderer/vulkan/ContextVk.cpp

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4042,16 +4042,15 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context)
40424042

40434043
if (hasStartedRenderPass())
40444044
{
4045-
if (!mDrawFramebuffer->isReadOnlyDepthMode())
4045+
if (!mRenderPassCommands->isReadOnlyDepthMode())
40464046
{
40474047
// To enter depth feedback loop, we must flush and start a new renderpass.
40484048
// Otherwise it will stick with writable layout and cause validation error.
40494049
ANGLE_TRY(flushCommandsAndEndRenderPass());
40504050
}
40514051
else
40524052
{
4053-
ANGLE_TRY(mDrawFramebuffer->updateRenderPassReadOnlyDepthMode(
4054-
this, mRenderPassCommands));
4053+
mDrawFramebuffer->updateRenderPassReadOnlyDepthMode(this, mRenderPassCommands);
40554054
}
40564055
}
40574056

@@ -4573,13 +4572,6 @@ angle::Result ContextVk::onImageRead(VkImageAspectFlags aspectFlags,
45734572
ASSERT(!image->isReleasedToExternal());
45744573
ASSERT(image->getImageSerial().valid());
45754574

4576-
// Layout transitions for images used in the render pass are handled especially. This function
4577-
// is only called when the image is used outside the render pass. As such, if the image is used
4578-
// inside the render pass, its layout is necessarily different from imageLayout, and thus a
4579-
// layout transition is necessary (and the render pass has to break).
4580-
ASSERT(image->isReadBarrierNecessary(imageLayout) ||
4581-
!(mRenderPassCommands->started() && mRenderPassCommands->usesImageInRenderPass(*image)));
4582-
45834575
// Note that different read methods are not compatible. A shader read uses a different layout
45844576
// than a transfer read. So we cannot support simultaneous read usage as easily as for Buffers.
45854577
// TODO: Don't close the render pass if the image was only used read-only in the render pass.
@@ -4636,22 +4628,18 @@ angle::Result ContextVk::startRenderPass(gl::Rectangle renderArea,
46364628
{
46374629
mGraphicsDirtyBits |= mNewGraphicsCommandBufferDirtyBits;
46384630

4639-
// We always start renderpass with proper depth stencil read only mode based on the current
4640-
// depth stencil state.
4641-
const gl::DepthStencilState &dsState = mState.getDepthStencilState();
4642-
vk::ResourceAccess depthAccess = GetDepthAccess(dsState);
4643-
vk::ResourceAccess stencilAccess = GetStencilAccess(dsState);
4644-
bool readOnlyDepthMode =
4645-
depthAccess != vk::ResourceAccess::Write && stencilAccess != vk::ResourceAccess::Write;
4646-
4647-
ANGLE_TRY(mDrawFramebuffer->startNewRenderPass(this, readOnlyDepthMode, renderArea,
4648-
&mRenderPassCommandBuffer));
4631+
ANGLE_TRY(mDrawFramebuffer->startNewRenderPass(this, renderArea, &mRenderPassCommandBuffer));
46494632

46504633
ANGLE_TRY(resumeOcclusionQueryIfActive());
46514634

4635+
const gl::DepthStencilState &dsState = mState.getDepthStencilState();
4636+
vk::ResourceAccess depthAccess = GetDepthAccess(dsState);
4637+
vk::ResourceAccess stencilAccess = GetStencilAccess(dsState);
46524638
mRenderPassCommands->onDepthAccess(depthAccess);
46534639
mRenderPassCommands->onStencilAccess(stencilAccess);
46544640

4641+
mDrawFramebuffer->updateRenderPassReadOnlyDepthMode(this, mRenderPassCommands);
4642+
46554643
if (commandBufferOut)
46564644
{
46574645
*commandBufferOut = mRenderPassCommandBuffer;
@@ -5088,8 +5076,7 @@ angle::Result ContextVk::updateRenderPassDepthStencilAccess()
50885076
mDrawFramebuffer->restoreDepthStencilDefinedContents();
50895077
}
50905078

5091-
ANGLE_TRY(
5092-
mDrawFramebuffer->updateRenderPassReadOnlyDepthMode(this, mRenderPassCommands));
5079+
mDrawFramebuffer->updateRenderPassReadOnlyDepthMode(this, mRenderPassCommands);
50935080
}
50945081
}
50955082

src/libANGLE/renderer/vulkan/ContextVk.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,12 @@ class ContextVk : public ContextImpl, public vk::Context
553553
vk::AliasingMode::Allowed, image);
554554
}
555555

556+
void onDepthStencilDraw(vk::ImageHelper *image, vk::ImageHelper *resolveImage)
557+
{
558+
ASSERT(mRenderPassCommands->started());
559+
mRenderPassCommands->depthStencilImagesDraw(&mResourceUseList, image, resolveImage);
560+
}
561+
556562
void onImageHelperRelease(const vk::ImageHelper *image)
557563
{
558564
if (mRenderPassCommands->started())

src/libANGLE/renderer/vulkan/FramebufferVk.cpp

Lines changed: 11 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,6 @@ FramebufferVk::FramebufferVk(RendererVk *renderer,
309309
mBackbuffer(backbuffer),
310310
mFramebuffer(nullptr),
311311
mActiveColorComponents(0),
312-
mReadOnlyDepthStencilMode(false),
313312
mReadOnlyDepthFeedbackLoopMode(false)
314313
{
315314
mReadPixelBuffer.init(renderer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, kReadPixelsBufferAlignment,
@@ -1749,9 +1748,6 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
17491748
return angle::Result::Continue;
17501749
}
17511750

1752-
// Default to writable depth on any Framebuffer change.
1753-
mReadOnlyDepthStencilMode = false;
1754-
17551751
// The FBO's new attachment may have changed the renderable area
17561752
const gl::State &glState = context->getState();
17571753
ANGLE_TRY(contextVk->updateScissor(glState));
@@ -1819,12 +1815,9 @@ void FramebufferVk::updateRenderPassDesc()
18191815
RenderTargetVk *depthStencilRenderTarget = getDepthStencilRenderTarget();
18201816
if (depthStencilRenderTarget)
18211817
{
1822-
vk::ResourceAccess dsAccess =
1823-
mReadOnlyDepthStencilMode ? vk::ResourceAccess::ReadOnly : vk::ResourceAccess::Write;
1824-
18251818
mRenderPassDesc.packDepthStencilAttachment(
18261819
depthStencilRenderTarget->getImageForRenderPass().getFormat().intendedFormatID,
1827-
dsAccess);
1820+
vk::ResourceAccess::Write);
18281821

18291822
// Add the resolve attachment, if any.
18301823
if (depthStencilRenderTarget->hasResolveAttachment())
@@ -2154,7 +2147,7 @@ angle::Result FramebufferVk::clearWithLoadOp(ContextVk *contextVk,
21542147
clearValue.depthStencil = clearDepthStencilValue;
21552148
commands.updateRenderPassDepthStencilClear(dsAspectFlags, clearValue);
21562149
// If we were in depth read only mode, we must change to write mode
2157-
ANGLE_TRY(updateRenderPassReadOnlyDepthMode(contextVk, &commands));
2150+
updateRenderPassReadOnlyDepthMode(contextVk, &commands);
21582151
}
21592152
}
21602153
else
@@ -2237,7 +2230,7 @@ angle::Result FramebufferVk::clearWithCommand(
22372230
attachments.emplace_back(VkClearAttachment{dsAspectFlags, 0, dsClearValue});
22382231
// Because we may have changed the depth stencil access mode, update read only depth mode
22392232
// now.
2240-
ANGLE_TRY(updateRenderPassReadOnlyDepthMode(contextVk, renderpassCommands));
2233+
updateRenderPassReadOnlyDepthMode(contextVk, renderpassCommands);
22412234
}
22422235

22432236
VkClearRect rect = {};
@@ -2260,7 +2253,6 @@ angle::Result FramebufferVk::getSamplePosition(const gl::Context *context,
22602253
}
22612254

22622255
angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
2263-
bool readOnlyDepthMode,
22642256
const gl::Rectangle &renderArea,
22652257
vk::CommandBuffer **commandBufferOut)
22662258
{
@@ -2466,22 +2458,6 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
24662458
renderPassAttachmentOps.setOps(depthStencilAttachmentIndex, depthLoadOp, depthStoreOp);
24672459
renderPassAttachmentOps.setStencilOps(depthStencilAttachmentIndex, stencilLoadOp,
24682460
stencilStoreOp);
2469-
2470-
// We can only start the renderpass in read only mode if it is requested to be read only and
2471-
// we are not doing clear.
2472-
bool depthStencilReadOnly =
2473-
readOnlyDepthMode && !depthStencilRenderTarget->hasResolveAttachment() &&
2474-
renderPassAttachmentOps[depthStencilAttachmentIndex].loadOp !=
2475-
VK_ATTACHMENT_LOAD_OP_CLEAR &&
2476-
renderPassAttachmentOps[depthStencilAttachmentIndex].stencilLoadOp !=
2477-
VK_ATTACHMENT_LOAD_OP_CLEAR;
2478-
setReadOnlyDepthMode(depthStencilReadOnly);
2479-
2480-
vk::ImageLayout dsLayout = mReadOnlyDepthStencilMode
2481-
? vk::ImageLayout::DepthStencilReadOnly
2482-
: vk::ImageLayout::DepthStencilAttachment;
2483-
2484-
renderPassAttachmentOps.setLayouts(depthStencilAttachmentIndex, dsLayout, dsLayout);
24852461
}
24862462

24872463
// If render pass description is changed, the previous render pass desc is no longer compatible.
@@ -2524,7 +2500,8 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
25242500
// tracking content valid very loosely here that as long as it is attached, it assumes will
25252501
// have valid content. The only time it has undefined content is between swap and
25262502
// startNewRenderPass
2527-
depthStencilRenderTarget->onDepthStencilDraw(contextVk, mReadOnlyDepthStencilMode);
2503+
// The actual layout determination will be deferred until endRenderPass time
2504+
depthStencilRenderTarget->onDepthStencilDraw(contextVk);
25282505
}
25292506

25302507
if (unresolveColorMask.any() || unresolveDepth || unresolveStencil)
@@ -2663,50 +2640,19 @@ angle::Result FramebufferVk::flushDeferredClears(ContextVk *contextVk,
26632640
return contextVk->startRenderPass(renderArea, nullptr);
26642641
}
26652642

2666-
void FramebufferVk::setReadOnlyDepthMode(bool readOnlyDepthEnabled)
2667-
{
2668-
if (mReadOnlyDepthStencilMode != readOnlyDepthEnabled)
2669-
{
2670-
mReadOnlyDepthStencilMode = readOnlyDepthEnabled;
2671-
2672-
ASSERT(getDepthStencilRenderTarget());
2673-
vk::ResourceAccess dsAccess =
2674-
isReadOnlyDepthMode() ? vk::ResourceAccess::ReadOnly : vk::ResourceAccess::Write;
2675-
ASSERT(mRenderPassDesc.hasDepthStencilAttachment());
2676-
mRenderPassDesc.updateDepthStencilAccess(dsAccess);
2677-
}
2678-
}
2679-
2680-
angle::Result FramebufferVk::updateRenderPassReadOnlyDepthMode(ContextVk *contextVk,
2681-
vk::CommandBufferHelper *renderPass)
2643+
void FramebufferVk::updateRenderPassReadOnlyDepthMode(ContextVk *contextVk,
2644+
vk::CommandBufferHelper *renderPass)
26822645
{
2683-
ASSERT(getDepthStencilRenderTarget());
2684-
2685-
bool readOnlyDepthStencil =
2686-
!getDepthStencilRenderTarget()->hasResolveAttachment() &&
2646+
bool readOnlyDepthStencilMode =
2647+
getDepthStencilRenderTarget() && !getDepthStencilRenderTarget()->hasResolveAttachment() &&
26872648
(mReadOnlyDepthFeedbackLoopMode || !renderPass->hasDepthStencilWriteOrClear());
2688-
if (readOnlyDepthStencil == mReadOnlyDepthStencilMode)
2689-
{
2690-
return angle::Result::Continue;
2691-
}
26922649

26932650
// If readOnlyDepthStencil is false, we are switching out of read only mode due to depth write.
26942651
// We must not be in the read only feedback loop mode because the logic in
26952652
// ContextVk::updateRenderPassDepthStencilAccess() should ensure we end the previous renderpass
26962653
// and a new renderpass will start with feedback loop disabled.
2697-
ASSERT(readOnlyDepthStencil || !mReadOnlyDepthFeedbackLoopMode);
2698-
2699-
setReadOnlyDepthMode(readOnlyDepthStencil);
2700-
2701-
// When we toggle read/write mode, we must insert a layout transition.
2702-
getDepthStencilRenderTarget()->onDepthStencilDraw(contextVk, readOnlyDepthStencil);
2654+
ASSERT(readOnlyDepthStencilMode || !mReadOnlyDepthFeedbackLoopMode);
27032655

2704-
vk::Framebuffer *currentFramebuffer = nullptr;
2705-
ANGLE_TRY(getFramebuffer(contextVk, &currentFramebuffer, nullptr));
2706-
2707-
renderPass->updateStartedRenderPassWithDepthMode(*currentFramebuffer, mRenderPassDesc,
2708-
readOnlyDepthStencil);
2709-
2710-
return angle::Result::Continue;
2656+
renderPass->updateStartedRenderPassWithDepthMode(readOnlyDepthStencilMode);
27112657
}
27122658
} // namespace rx

src/libANGLE/renderer/vulkan/FramebufferVk.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ class FramebufferVk : public FramebufferImpl
116116
RenderTargetVk *getColorReadRenderTarget() const;
117117

118118
angle::Result startNewRenderPass(ContextVk *contextVk,
119-
bool readOnlyDepthMode,
120119
const gl::Rectangle &renderArea,
121120
vk::CommandBuffer **commandBufferOut);
122121
void restoreDepthStencilDefinedContents();
@@ -130,17 +129,15 @@ class FramebufferVk : public FramebufferImpl
130129
vk::Framebuffer **framebufferOut,
131130
const vk::ImageView *resolveImageViewIn);
132131

133-
bool isReadOnlyDepthMode() const { return mReadOnlyDepthStencilMode; }
134-
135132
bool hasDeferredClears() const { return !mDeferredClears.empty(); }
136133
angle::Result flushDeferredClears(ContextVk *contextVk, const gl::Rectangle &renderArea);
137134
void setReadOnlyDepthFeedbackLoopMode(bool readOnlyDepthFeedbackModeEnabled)
138135
{
139136
mReadOnlyDepthFeedbackLoopMode = readOnlyDepthFeedbackModeEnabled;
140137
}
141138
bool isReadOnlyDepthFeedbackLoopMode() const { return mReadOnlyDepthFeedbackLoopMode; }
142-
angle::Result updateRenderPassReadOnlyDepthMode(ContextVk *contextVk,
143-
vk::CommandBufferHelper *renderPass);
139+
void updateRenderPassReadOnlyDepthMode(ContextVk *contextVk,
140+
vk::CommandBufferHelper *renderPass);
144141

145142
private:
146143
FramebufferVk(RendererVk *renderer,
@@ -232,8 +229,6 @@ class FramebufferVk : public FramebufferImpl
232229
vk::ImageViewSubresourceSerial resolveImageViewSerial);
233230
void removeColorResolveAttachment(uint32_t colorIndexGL);
234231

235-
void setReadOnlyDepthMode(bool readOnlyDepthEnabled);
236-
237232
WindowSurfaceVk *mBackbuffer;
238233

239234
vk::RenderPassDesc mRenderPassDesc;
@@ -257,8 +252,6 @@ class FramebufferVk : public FramebufferImpl
257252

258253
vk::ClearValuesArray mDeferredClears;
259254

260-
// True if depth stencil buffer is read only.
261-
bool mReadOnlyDepthStencilMode;
262255
// Tracks if we are in depth feedback loop. Depth read only feedback loop is a special kind of
263256
// depth stencil read only mode. When we are in feedback loop, we must flush renderpass to exit
264257
// the loop instead of update the layout.

src/libANGLE/renderer/vulkan/RenderTargetVk.cpp

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -107,29 +107,12 @@ void RenderTargetVk::onColorDraw(ContextVk *contextVk)
107107
mContentDefined = true;
108108
}
109109

110-
void RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk, bool isReadOnly)
110+
void RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk)
111111
{
112112
const angle::Format &format = mImage->getFormat().actualImageFormat();
113113
ASSERT(format.hasDepthOrStencilBits());
114-
VkImageAspectFlags aspectFlags = vk::GetDepthStencilAspectFlags(format);
115-
116-
if (isReadOnly)
117-
{
118-
ASSERT(!mResolveImage);
119-
contextVk->onImageRenderPassRead(aspectFlags, vk::ImageLayout::DepthStencilReadOnly,
120-
mImage);
121-
}
122-
else
123-
{
124-
contextVk->onImageRenderPassWrite(aspectFlags, vk::ImageLayout::DepthStencilAttachment,
125-
mImage);
126-
if (mResolveImage)
127-
{
128-
contextVk->onImageRenderPassWrite(
129-
aspectFlags, vk::ImageLayout::DepthStencilResolveAttachment, mResolveImage);
130-
}
131-
}
132114

115+
contextVk->onDepthStencilDraw(mImage, mResolveImage);
133116
retainImageViews(contextVk);
134117

135118
mContentDefined = true;

src/libANGLE/renderer/vulkan/RenderTargetVk.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
6767

6868
// Note: RenderTargets should be called in order, with the depth/stencil onRender last.
6969
void onColorDraw(ContextVk *contextVk);
70-
void onDepthStencilDraw(ContextVk *contextVk, bool isReadOnly);
70+
void onDepthStencilDraw(ContextVk *contextVk);
7171

7272
vk::ImageHelper &getImageForRenderPass();
7373
const vk::ImageHelper &getImageForRenderPass() const;

src/libANGLE/renderer/vulkan/UtilsVk.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
14131413

14141414
// We may have changed depth stencil access mode, so update read only depth stencil mode
14151415
// here.
1416-
ANGLE_TRY(framebuffer->updateRenderPassReadOnlyDepthMode(contextVk, renderpassCommands));
1416+
framebuffer->updateRenderPassReadOnlyDepthMode(contextVk, renderpassCommands);
14171417
}
14181418

14191419
ImageClearShaderParams shaderParams;
@@ -1666,7 +1666,7 @@ angle::Result UtilsVk::blitResolveImpl(ContextVk *contextVk,
16661666
pipelineDesc.setScissor(gl_vk::GetRect(params.blitArea));
16671667

16681668
vk::CommandBuffer *commandBuffer;
1669-
ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, false, params.blitArea, &commandBuffer));
1669+
ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, params.blitArea, &commandBuffer));
16701670
contextVk->onImageRenderPassRead(src->getAspectFlags(), vk::ImageLayout::FragmentShaderReadOnly,
16711671
src);
16721672

0 commit comments

Comments
 (0)