Search Unity

Question Trying to debug problems when using Vulkan or DX12 (but fine with DX11)

Discussion in 'Shaders' started by trepan, Jul 20, 2022.

  1. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    So my game is using a custom SRP and a lot of Compute kernels. Under DX11 everything runs just fine, but I've been wanting to also support DX12 or Vulkan (or both) so that I can use the more modern diagnostic tools from NVidia/AMD to help with profiling. The problem is a switch to either alternative API was yielding GPU hangs...

    So I identified and worked around one issue on DX12, and I'm at a point where I can sort of run the game without seeing a hang, but I'm also not seeing my world rendering. I've tracked this down to what appears to be a case of a large compute buffer used to store the world representation being empty. ...In that all attempts to read from the buffer return 0 when I write trace data back to a debug buffer. (I've validated that the data was clearly non zero prior to me calling <cb>.SetData()).

    In RenderDoc, when I look at any of the vkCmdDispatch() commands where this buffer should be bound, they all show red, 'No Resource'. I'm not sure why that doesn't correlate with a run-time error (which I don't see any of), but I figure it can't be a coincidence that this is the one buffer giving those 'zero' reads. Other buffers of similar type show as correctly bound in RenderDoc and - as far as I can test - seem to be returning data. I believe NSight is also showing the buffer as unbound but I don't totally trust that I'm using the tool correctly here :)

    So what's the deal with my problem ComputeBuffer? It's a Buffer<uint>, declared as follows in C#:

    RaycastData = new ComputeBuffer(RAYCAST_DATA_SIZE_IN_INTS, sizeof(uint), ComputeBufferType.Default) { name = "RaycastData" };

    Most notable is that it's big, the biggest I'm using, at 1728Mb. Is that too big? Could DX11 be ok with this where the modern APIs aren't? ...I can't seem to find any definitive description of their limits to be certain, but I am dubious that size alone is the issue since I hacked it down to 30% size and still saw 'No Resource' in RenderDoc.

    Originally I was only binding the buffer to the shader kernel once, but I've tried doing so before each frame's Invoke with no change. What other causes could there be for an apparently unbound buffer?

    Maybe also worth mentioning, I'm seeing similar behavior (DX11 fine, others broken) on both Nvidia and AMD systems although I've been focusing most debugging on Nvidia.

    Any debugging tips and suggestions would be very welcome.

    Thanks!
     
  2. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    So from more experimentation (I created a dummy buffer alongside my real one and incrementally adjusted the size) it looks like on Vulkan at least, a ComputeBuffer larger than 512Mb silently fails. It will show up in RenderDoc as 'No Resource' but there's no hint of runtime warning or error which seems surprising and rather unhelpful :( I'm also shocked that I can use a 2Gb buffer under DX11 but only a quarter that for Vulkan?

    I know DX11 operates under a different model where a hardware driver implement features vs the client engine doing so. Does that explain this? ...That the DX11 driver is doing more sophisticated memory management than Unity has implemented here? ...And that the max buffer size is more down to what the client code (Unity) implements rather than being an API limit? I would love to have some confirmation of this before I have to rework a bunch of code based on supposition (again).

    As ever I'm left wondering how the heck a developer is supposed to know this stuff or where to ask 'intermediate' level Unity graphics questions that might attract a response.
     
  3. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    In case it ever helps anyone: I suspect that another difference between DX11 and Vulkan/DX12 is that on DX11 buffers are perhaps always initialized to zero automatically, whereas with Vulkan/DX12 I think that may be true in a standalone build but not in editor (or perhaps they're deliberately initialized to an uninitialized state?). ...Either way I fixed another issue by adding a missing initial buffer clear!
     
  4. trepan

    trepan

    Joined:
    Feb 11, 2011
    Posts:
    113
    Oh, and by splitting that large ComputeBuffer into three smaller ones (each <= 512Mb), that did fix the unbound buffer issues and got that system working.