Search Unity

What rules exist around BathRendererGroup, Compute/Graphics Buffers, and instance data?

Discussion in 'Graphics for ECS' started by DreamingImLatios, Aug 10, 2021.

  1. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    I know there's a new version of BatchRendererGroup coming, and maybe that will change the answer to this question, or maybe it is orthogonal.

    So I want to run a Compute Shader only on instances that pass culling. However, it seems currently HR V2 uploads all instance data and compute buffers (skinning) prior to culling. I recognize that culling happens in multiple stages for multiple cameras. That's fine if I have to incrementally update the compute buffer and run additional compute shader passes with a different range of the buffer. So I guess my questions are:
    • Is updating the instance data buffers safe during culling?
    • Is updating a Compute Buffer safe during culling?
    • Is dispatching a Compute Shader safe during culling?
    • Is there some other SRP hook where I could be doing this uploading and/or Compute Shader dispatch instead after knowing the culling results?
     
    Lukas_Kastern likes this.
  2. JussiKnuuttila

    JussiKnuuttila

    Unity Technologies

    Joined:
    Jun 7, 2019
    Posts:
    351
    The BatchRendererGroup main culling callback should be in the main thread, so I think in principle it should be possible to graphics operations there, including compute shader dispatches.

    At least one thing to be careful about is that there can be multiple culling callbacks during a frame (for example, main viewport and shadow maps), and during the second callback the results of the first can already be partially or completely drawn, so modifying instance data buffers that are already being used could potentially cause problems.
     
    DreamingImLatios likes this.
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    It has been a while, but I wanted to follow up and state that so far this is working surprisingly well!

    I have been dispatching a compute shader from the culling callback for a while now. But this weekend I got the entire material property updates migrated over. I keep track of which entities have been rendered in a frame and only change values for new entities which are passing a culling callback for the first time. This gives me a last-moment opportunity to set an offset into a buffer populated by a compute shader on an entity. I also have to preserve old buffers for a few frames when resizing to a new one, but overall, VRAM usage is way down!