@@ -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.
0 commit comments