renderdoc icon indicating copy to clipboard operation
renderdoc copied to clipboard

Input attachments shown with LOAD DONT CARE despite loadOp=LOAD

Open ShabbyX opened this issue 5 years ago • 1 comments

Description

Take the following framebuffer:

  • Attachment 0 MSAA loadOp=DONT_CARE, storeOp= DONT_CARE

  • Attachment 1 loadOp=LOAD, storeOp=STORE

  • Subpass 0:

    • Color Attachment 0: Attachment 0
    • Input Attachment 0: Attachment 1
  • Subpass 1:

    • Color Attachment 0: Attachment 0
    • Resolve Attachment 0: Attachment 1

In Subpass 0, there's a draw call that initializes the MSAA attachment from the input attachment (which is the same as the resolve attachment used in Subpass 1). There's an appropriate subpass dependency in between the two.

Looking at RenderDoc on said draw call, it shows the contents of Attachment 1 as LOAD DONT CARE, even though loadOp for this attachment is LOAD and the contents are valid.

Steps to reproduce

Take the following capture file: https://drive.google.com/file/d/1KuahchxMsZ-KDMSCji3YtMTuCUUuvkyR/view

In the above capture, there's a similar scenario to the above (except there are two pairs of attachments, 2 color and 2 input/resolve).

Observe at EID 21 (after first render pass) that Color Attachment 363 is valid (and red). Click on EID 26 (first subpass of second render pass), and in Texture Viewer look at Inputs. Observe that both inputs (including Color Attachment 363) show LOAD DONT CARE. Expected behavior is to see colors resolved to these attachments in the first render pass.

Environment

  • RenderDoc version: b1c12ce1a
  • Operating System: Linux (Ubuntu 20.04)
  • Graphics API: Vulkan
  • cmake arguments: -DCMAKE_BUILD_TYPE=Release -Bbuild -H. -DENABLE_GLES=OFF -DENABLE_GL=OFF
  • GPU: NVIDIA GTX 970, driver 440.100

ShabbyX avatar Sep 09 '20 09:09 ShabbyX

This looks to be caused by a bad interaction between renderdoc's replay and the renderpass (legally) having a self dependency where it outputs to one of its own inputs.

RenderDoc isn't deliberately filling the attachment with LOAD_DONT_CARE, but when it tries to break the renderpass apart to display a draw from part way through the first subpass, the LOAD_DONT_CARE hasn't yet been overwritten and still gets resolved out as an accidental byproduct of the partial renderpass. That then becomes the input when the draw itself is replayed, leading to the incorrect inputs. If you had two draws in the first subpass for example, the second one would see the resolved input from the first one even though the resolve hasn't happened yet.

The same thing causes the more benign behaviour that a renderpass without this kind of self dependency will show the resolve target as 'partially updated' when selecting a draw mid-way through a renderpass, because the resolve action still takes place even when inspecting part-way through a renderpass.

I'll need to find a way to patch up the renderpass to not perform resolve actions when it's being broken apart like this, so this will probably take a little while to fix.

baldurk avatar Sep 09 '20 10:09 baldurk

so this will probably take a little while to fix.

Quite the understatement...

I have legitimately been thinking about this every few months since it was opened. The fix I've put in is certainly not complete or ideal, it simply disables the discard patterns (which would still be useful if they functioned) and only in the case like this which is easily detectable via input attachments. It's not a general fix because if the read happened via a plain sampled texture the code would still be valid but would break in the same way.

That said I've been thinking about this for over 2 years and I have not figured out a solution I would be happy implementing, any really robust solution would be far too much maintenance burden and potential bug surface for a pathological case like this. I am guessing with the fakey MSAA extension that was added since this bug you're not even doing this yourself anymore (though I may be wrong).

It's not great and I was hoping for a better fix, but realistically if it's not been fixed by now it's never going to be, so it was either this imperfect fix or nothing at all and either way there's no point in leaving an issue open if I never plan to address it.

baldurk avatar Jan 12 '23 18:01 baldurk

Wow, I didn't even remember this myself! You're right, with the MSRTSS extension I don't do this anymore. In fact, we basically never need multipass render passes.

We do however use single-subpass render passes with a self-dependency where the attachments are simultaneously both color and input attachments (emulating GL's framebuffer fetch). I recall that doesn't work well with RenderDoc either, but your change might have fixed that use case too.

ShabbyX avatar Jan 12 '23 21:01 ShabbyX