What is EndGraphicsJobAfterScriptUpdate?

I’m profiling my game and can’t find any documentation about the marker PreLateUpdate.EndGraphicsJobAfterScriptUpdate, which takes multiple milliseconds in my situation. What does it represent?

I can only gather that it’s part of the core player loop, but I can’t find what it represents in the order of execution of events (there’s nothing like it between Update and LateUpdate).

I’m thinking it might mean that, because I’m using graphics jobs, it represents the time where the last frame hasn’t finished dispatching all the graphics jobs to the GPU, probably because the loop is GPU bound. Is that it?

But if that’s the case, why does that need to happen before LateUpdate, rather than just before rendering the next frame (which could help compact the frame’s CPU/GPU offsets)?

Ultimately, how can I reduce / optimize it?

This spot in the player loop is first of all, just a spot to hook code into. It’s subsamples tell you what it does.

And what it does in your case is indeed syncing on the rendering jobs, which are not running in the Render thread and not on the GPU but spread out across the worker threads, so you’ll need to scroll a bit more to see those.

If you turn on flow visualization (via the 3 dot button at the top left hand corner of the Timeline view) and select those subsamples, it might (not sure if it was implemented to emit flow events) draw lines to those jobs.

So: you are Rendering bound, which is the CPU side of the graphics calculations, not the GPU. You can optimize that with lowering the amount of commands that need to be prepared and sent to the GPU, as well as reducing the load those calculations (like culling) have to make, or move some of that load to the GPU via Unity’s different rendering features. Which ones exactly depend on what the details are of what your Render thread and graphics jobs are most busy with, but experiment and profile.

Thanks for the quick & detailed reply Martin!

A few follow-up questions:

  • Are there features in 2020.3 that could be toggled to move some of these Rendering calculations to the GPU?
  • Are there any tips for optimizing culling in particular? (Short of reimplementing it myself in larger chunks before the camera renders)

As a curiosity, I’d reiterate on of my original questions:

Why does that need to happen before LateUpdate, rather than just before rendering the next frame
(which could help compact the frame’s CPU/GPU offsets)?

Thanks in advance!

tbh, no idea, I’m not a rendering engineer or working on that system. You could start your build with the command line option “-gfx-jobs-sync=after-script-update” to change the graphics jobs sync point, or by adding this line to the boot.config file. The other options for that are “end-of-frame” (though that seems to have caused issues before) “wait-for-present” and the default “after-script-update”

Is that even your issue? taking a closer look at all those green samples in your screesnhot above, culling is not among these. Just a lot of time spend issuing draw orders for opaque geometry, updating depth textures and rendering shadowmaps. So I’d look into reducing that.

And then there is whatever the Graphics jobs are doing but those are not in the screenshot.

You might want to look into this ebook for pointers on what to do to optimize this.