Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How can I tell when a ComputeShader.Dispatch() is complete?

Discussion in 'Scripting' started by Colt-Zero, Jun 24, 2016.

  1. Colt-Zero

    Colt-Zero

    Joined:
    Jun 24, 2016
    Posts:
    4
    The question I'm asking here is if there is a way to get some kind of callback from the Compute Shader when it finishes processing a kernel that I dispatched.

    It would be exceedingly useful since I know for a fact that if I call the ComputeBuffer.GetData() method too soon after dispatching a kernel, it will force a Pipeline stall until the Compute Shader is done with it's crap. And if I call it later, it would mean delaying further Dispatch calls more than needed. And I'm making something where I'm expecting a potentially several thousand calls to dispatch jobs to the GPU, and I want to do them as fast as possible.

    I'm currently basing my timing of when to call GetData() based on how much lag I'm seeing each time I do it, trying to find the right balance where I don't really get any significant lag, but still maximize the rate of Dispatches. But it's like freaking impossible, since Dispatch times can fluctuate quite a lot.

    If I could call ComputeBuffer.GetData() off the main thread, that would work as well, since I wouldn't have to worry about the Pipeline stall impacting the main game thread. But Unity says nope to that.
     
    SunnyChow likes this.
  2. TEBZ_22

    TEBZ_22

    Joined:
    Jan 28, 2014
    Posts:
    37
    Hi.
    I've been looking into the same thing, and it I can't find a good way at the moment to read if a Compute Shader is done or not.
    If someone have, pleas tell me !

    If anyone from Unity are listening, pleas make something like ComputeBuffer.AsynkGetData() that returns a boolean to indicate if data are available or not.

    And a ComputeShader.Done() would be nice to be able to chain Compute Shaders.

    /Thomas
     
    Last edited: Aug 1, 2016
  3. studentX

    studentX

    Joined:
    Jan 10, 2018
    Posts:
    1
    Has this been solved? I want to queue shaders to run one after the other (populating and consuming a buffer), and callbacks would be the intuitive way of doing it.
     
  4. AlexTuduran

    AlexTuduran

    Joined:
    Nov 26, 2016
    Posts:
    27
    Still nothing on this?
     
  5. idanbismut

    idanbismut

    Joined:
    Mar 24, 2021
    Posts:
    1
    I think that Create graphic fence (with flags of ComputeProcessing) and then Graphics.WaitOnGraphicsFence should provide some solution to problem.
    I'm facing similar issue, i'll update when I can confirm it works.
     
  6. DanielZeller

    DanielZeller

    Joined:
    Nov 18, 2014
    Posts:
    17
    Did this work? :)
     
  7. Yurijh

    Yurijh

    Joined:
    Nov 4, 2016
    Posts:
    15
    Any updates?
     
  8. Yurijh

    Yurijh

    Joined:
    Nov 4, 2016
    Posts:
    15
    I took your advice. After reading some documentation I've used the following solution:

    Code (CSharp):
    1. graphicsFence = Graphics.CreateGraphicsFence(GraphicsFenceType.CPUSynchronisation, SynchronisationStageFlags.ComputeProcessing);
    and then poll on
    Code (CSharp):
    1. graphicsFence.passed
    Anyway a callback would be great, do you guys know some alternative solution that involves callbacks?
     
  9. Epicsninja

    Epicsninja

    Joined:
    Aug 31, 2018
    Posts:
    2
    As far as I can tell, the next line of code isn't executed until Dispatch is finished.
     
  10. FM-Productions

    FM-Productions

    Joined:
    May 1, 2017
    Posts:
    72
    Pretty sure that's generally not true, during my tests while profiling, the Dispatch calls are really fast, but when calling GetData afterwards, that is when the CPU will stall and wait for completion (I suspect at least until the requested buffer has the required data written into it)

    As for the initial question: Seems like this method has been available since 2018.2: AsyncGPUCallback.Request.
    You can either pass a callback that is run when the requested work has been completed (= data has been written into the ComputeBuffer you passed), or you can store the result of the method as AsyncGPUReadbackRequest and periodically check whether the request has finished by accessing the "done" property. The request can also be forced to completion by calling WaitForCompletion, although I personally never used this option.