Skip to content

Commit 8d87969

Browse files
ShabbyXAngle LUCI CQ
authored andcommitted
Vulkan: Fix robust resource init vs invalidate
If robust resource init is enabled, invalidate should not leave the contents of the image undefined. With this change, after the framebuffer is invalidated, the render pass store op is still STORE_OP_DONT_CARE so that it would be efficient, but a robust init clear is restaged in the image. In the next render pass, or on read-back, the content is cleared again automatically. Bug: chromium:492153658 Change-Id: I84089b955c44be1569ed1d71ab406d3df681590f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/7697282 Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com> Reviewed-by: Charlie Lao <cclao@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
1 parent 2b53114 commit 8d87969

File tree

8 files changed

+373
-14
lines changed

8 files changed

+373
-14
lines changed

src/libANGLE/renderer/vulkan/FramebufferVk.cpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,10 @@ angle::Result FramebufferVk::invalidateSub(const gl::Context *context,
554554
// glCopyTex[Sub]Image, shader storage image, etc).
555555
restageDeferredClears(contextVk);
556556

557-
if (contextVk->hasActiveRenderPass() &&
557+
// If robust resource initialization is enabled, do not invalidate sub-regions of the
558+
// framebuffer. This is because otherwise the contents of that region becomes undefined and
559+
// ANGLE doesn't clear it back to black.
560+
if (!contextVk->isRobustResourceInitEnabled() && contextVk->hasActiveRenderPass() &&
558561
rotatedInvalidateArea.encloses(contextVk->getStartedRenderPassCommands().getRenderArea()))
559562
{
560563
// Because the render pass's render area is within the invalidated area, it is fine for
@@ -566,7 +569,10 @@ angle::Result FramebufferVk::invalidateSub(const gl::Context *context,
566569
{
567570
ANGLE_VK_PERF_WARNING(
568571
contextVk, GL_DEBUG_SEVERITY_LOW,
569-
"InvalidateSubFramebuffer ignored due to area not covering the render area");
572+
contextVk->isRobustResourceInitEnabled()
573+
? "InvalidateSubFramebuffer ignored due to area not covering the entire "
574+
"framebuffer while robust resource initialization is enabled"
575+
: "InvalidateSubFramebuffer ignored due to area not covering the render area");
570576
}
571577

572578
return angle::Result::Continue;
@@ -2282,7 +2288,6 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
22822288
mDeferredClears.reset(vk::kUnpackedStencilIndex);
22832289
}
22842290
}
2285-
22862291
// Limit invalidateColorBuffers to enabled draw buffers
22872292
invalidateColorBuffers &= mState.getEnabledDrawBuffers();
22882293
for (size_t colorIndexGL : invalidateColorBuffers)
@@ -2298,6 +2303,12 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
22982303

22992304
// If not a partial invalidate, mark the contents of the invalidated attachments as undefined,
23002305
// so their loadOp can be set to DONT_CARE in the following render pass.
2306+
2307+
// If robust resource initialization is enabled, restage clears on the invalidated resources.
2308+
// This way, STORE_OP_DONT_CARE can be used, but the application can still not observe garbage
2309+
// data in the image.
2310+
const bool isRobustResourceInitEnabled = contextVk->isRobustResourceInitEnabled();
2311+
ASSERT(!(isRobustResourceInitEnabled && isSubInvalidate));
23012312
if (!isSubInvalidate)
23022313
{
23032314
for (size_t colorIndexGL : invalidateColorBuffers)
@@ -2311,6 +2322,13 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
23112322
{
23122323
invalidateColorBuffers.reset(colorIndexGL);
23132324
}
2325+
else if (isRobustResourceInitEnabled)
2326+
{
2327+
gl::ImageIndex imageIndex = colorRenderTarget->getImageIndexForClear(
2328+
mCurrentFramebufferDesc.getLayerCount());
2329+
colorRenderTarget->getImageForWrite().stageRobustResourceClear(
2330+
imageIndex, VK_IMAGE_ASPECT_COLOR_BIT);
2331+
}
23142332
}
23152333

23162334
// If we have a depth / stencil render target, invalidate its aspects.
@@ -2336,6 +2354,26 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
23362354
invalidateStencilBuffer = false;
23372355
}
23382356
}
2357+
2358+
if (isRobustResourceInitEnabled)
2359+
{
2360+
VkImageAspectFlags dsAspectFlags = 0;
2361+
if (invalidateDepthBuffer)
2362+
{
2363+
dsAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
2364+
}
2365+
if (invalidateStencilBuffer)
2366+
{
2367+
dsAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
2368+
}
2369+
if (dsAspectFlags)
2370+
{
2371+
gl::ImageIndex imageIndex = depthStencilRenderTarget->getImageIndexForClear(
2372+
mCurrentFramebufferDesc.getLayerCount());
2373+
depthStencilRenderTarget->getImageForWrite().stageRobustResourceClear(
2374+
imageIndex, dsAspectFlags);
2375+
}
2376+
}
23392377
}
23402378
}
23412379

@@ -2347,7 +2385,10 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
23472385
// to invalidate the D/S of FBO 2 since it would be the currently active renderpass.
23482386
if (contextVk->hasStartedRenderPassWithQueueSerial(mLastRenderPassQueueSerial))
23492387
{
2350-
bool closeRenderPass = false;
2388+
// When robust-resource init is enabled, a clear is stashed in the image after invalidating
2389+
// it. The render pass is closed for the same reason as with images with emulated alpha
2390+
// channel as described below.
2391+
bool closeRenderPass = isRobustResourceInitEnabled;
23512392

23522393
// Mark the invalidated attachments in the render pass for loadOp and storeOp determination
23532394
// at its end.

src/libANGLE/renderer/vulkan/RenderbufferVk.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ angle::Result RenderbufferVk::initializeContents(const gl::Context *context,
287287
const gl::ImageIndex &imageIndex)
288288
{
289289
// Note: stageSubresourceRobustClear only uses the intended format to count channels.
290-
mImage->stageRobustResourceClear(imageIndex);
290+
mImage->stageRobustResourceClear(imageIndex, mImage->getAspectFlags());
291291
return mImage->flushAllStagedUpdates(vk::GetImpl(context));
292292
}
293293

src/libANGLE/renderer/vulkan/SurfaceVk.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -850,14 +850,15 @@ angle::Result OffscreenSurfaceVk::initializeContents(const gl::Context *context,
850850
{
851851
case GL_BACK:
852852
ASSERT(mColorAttachment.image.valid());
853-
mColorAttachment.image.stageRobustResourceClear(imageIndex);
853+
mColorAttachment.image.stageRobustResourceClear(imageIndex, VK_IMAGE_ASPECT_COLOR_BIT);
854854
ANGLE_TRY(mColorAttachment.image.flushAllStagedUpdates(contextVk));
855855
break;
856856

857857
case GL_DEPTH:
858858
case GL_STENCIL:
859859
ASSERT(mDepthStencilAttachment.image.valid());
860-
mDepthStencilAttachment.image.stageRobustResourceClear(imageIndex);
860+
mDepthStencilAttachment.image.stageRobustResourceClear(
861+
imageIndex, mDepthStencilAttachment.image.getAspectFlags());
861862
ANGLE_TRY(mDepthStencilAttachment.image.flushAllStagedUpdates(contextVk));
862863
break;
863864

@@ -3606,14 +3607,15 @@ angle::Result WindowSurfaceVk::initializeContents(const gl::Context *context,
36063607
vk::ImageHelper *image =
36073608
hasAncillaryColor() ? &mAncillaryColorImage
36083609
: mSwapchainImages[mCurrentSwapchainImageIndex].image.get();
3609-
image->stageRobustResourceClear(imageIndex);
3610+
image->stageRobustResourceClear(imageIndex, VK_IMAGE_ASPECT_COLOR_BIT);
36103611
ANGLE_TRY(image->flushAllStagedUpdates(contextVk));
36113612
break;
36123613
}
36133614
case GL_DEPTH:
36143615
case GL_STENCIL:
36153616
ASSERT(mDepthStencilImage.valid());
3616-
mDepthStencilImage.stageRobustResourceClear(gl::ImageIndex::Make2D(0));
3617+
mDepthStencilImage.stageRobustResourceClear(gl::ImageIndex::Make2D(0),
3618+
mDepthStencilImage.getAspectFlags());
36173619
ANGLE_TRY(mDepthStencilImage.flushAllStagedUpdates(contextVk));
36183620
break;
36193621
default:

src/libANGLE/renderer/vulkan/vk_helpers.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9548,10 +9548,9 @@ void ImageHelper::stageClear(const gl::ImageIndex &index,
95489548
appendSubresourceUpdate(updateLevelGL, SubresourceUpdate(aspectFlags, clearValue, index));
95499549
}
95509550

9551-
void ImageHelper::stageRobustResourceClear(const gl::ImageIndex &index)
9551+
void ImageHelper::stageRobustResourceClear(const gl::ImageIndex &index,
9552+
const VkImageAspectFlags aspectFlags)
95529553
{
9553-
const VkImageAspectFlags aspectFlags = getAspectFlags();
9554-
95559554
ASSERT(mActualFormatID != angle::FormatID::NONE);
95569555
VkClearValue clearValue = GetRobustResourceClearValue(getIntendedFormat(), getActualFormat());
95579556

src/libANGLE/renderer/vulkan/vk_helpers.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2595,7 +2595,8 @@ class ImageHelper final : public Resource, public angle::Subject
25952595
const gl::Extents &glExtents,
25962596
const angle::Format &intendedFormat,
25972597
const angle::Format &imageFormat);
2598-
void stageRobustResourceClear(const gl::ImageIndex &index);
2598+
void stageRobustResourceClear(const gl::ImageIndex &index,
2599+
const VkImageAspectFlags aspectFlags);
25992600

26002601
angle::Result stageResourceClearWithFormat(ContextVk *contextVk,
26012602
const gl::ImageIndex &index,

src/libANGLE/renderer/vulkan/vk_renderer.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,18 @@ constexpr vk::SkippedSyncvalMessage kSkippedSyncvalMessagesWithMSRTTEmulation[]
765765
"old_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL",
766766
"new_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL",
767767
}},
768+
// Unknown whether ANGLE or syncval bug. See http://anglebug.com/495832130
769+
{"SYNC-HAZARD-WRITE-AFTER-WRITE",
770+
false,
771+
{
772+
"message_type = ImageSubresourceRangeError",
773+
"access = VK_PIPELINE_STAGE_2_CLEAR_BIT(VK_ACCESS_2_TRANSFER_WRITE_BIT)",
774+
"prior_access = "
775+
"VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_"
776+
"BIT)",
777+
"command = vkCmdClearDepthStencilImage",
778+
"prior_command = vkCmdNextSubpass",
779+
}},
768780
};
769781

770782
enum class DebugMessageReport

src/tests/angle_end2end_tests_expectations.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@
278278
42266866 NVIDIA OPENGL : GLSLTest_ES3.LargeInterfaceBlockNestedArray/* = SKIP
279279
42266866 NVIDIA GLES : GLSLTest_ES3.LargeInterfaceBlockArray/* = SKIP
280280
42266866 NVIDIA GLES : GLSLTest_ES3.LargeInterfaceBlockNestedArray/* = SKIP
281+
496616811 NVIDIA OPENGL : RobustResourceInitTestES3.DrawThenInvalidateThenVerifyDepthStencil/* = SKIP
282+
496616811 NVIDIA GLES : RobustResourceInitTestES3.DrawThenInvalidateThenVerifyDepthStencil/* = SKIP
281283
// Nvidia sees same matrix type with different layouts as different types
282284
42262474 NVIDIA OPENGL : GLSLTest_ES31.TernaryOnStructsInDifferentBlockStorages/* = SKIP
283285
42262474 NVIDIA OPENGL : GLSLTest_ES31.TernaryOnMatricesInDifferentBlockStorages/* = SKIP
@@ -475,6 +477,7 @@
475477
42266214 MAC APPLE METAL : Texture2DTest.ManySupersedingTextureUpdates/* = SKIP
476478
494392011 MAC METAL : MipmapTestES3.MismatchingLevelFormats/* = SKIP
477479
494341324 MAC OPENGL : MipmapTestES3.MismatchingLevelFormats/* = SKIP
480+
496604559 MAC METAL : RobustResourceInitTestES3.DrawThenInvalidateThenVerifyDepthStencil/* = SKIP
478481

479482
// The workaround is not intended to be enabled in this configuration so
480483
// skip it as the failure is likely a driver bug.
@@ -549,9 +552,11 @@
549552
448658631 WIN D3D11 : GLSLTestLoops.ForContinueInSwitchComplex/* = SKIP
550553
448658631 WIN D3D11 : GLSLTest_ES3.SwitchConstantFold/* = SKIP
551554
448658631 WIN D3D11 : GLSLTest_ES3.SwitchConstantFoldWithVariables/* = SKIP
552-
553555
494938700 WIN D3D11 : CopyTexImageTest.CopyTexImageFromTexture3D/* = SKIP
554556
494938700 WIN D3D11 : CopyTexImageTest.CopyTexSubImageFromTexture3D/* = SKIP
557+
496259841 WIN D3D11 : RobustResourceInitTestES3.InvalidateThenReadBack/* = SKIP
558+
496259841 WIN D3D11 : RobustResourceInitTestES3.DrawThenInvalidateThenReadBack/* = SKIP
559+
496259841 WIN D3D11 : RobustResourceInitTestES3.DrawThenInvalidateThenVerifyDepthStencil/* = SKIP
555560

556561
// Android
557562
42264624 ANDROID GLES : GLSLTest_ES3.InitGlobalComplexConstant/* = SKIP

0 commit comments

Comments
 (0)