"Multithreaded Rendering" vs "Graphics Jobs"

Unity built-in (legacy) renderer:
In the Player Settings you find the “Multithreaded Rendering” and “Graphics Jobs” options. The following text is copied from the documentation, but it sounds very similar to me:

It seems the difference is that Multithreaded Rendering runs on exactly one worker thread, where Graphics Jobs might run on multiple worker threads.

  • What are the pros and cons of each method? They must have different pros and cons, otherwise more than one option wouldn’t exist.
  • When would I use MTR over GJ for example?
  • The MTR and GJ options don’t seem to be exclusive, I can enable just one or both. Which option dominates when I enable both?
2 Likes

Hi!
The options are not mutually exclusive, you can enable both.

Multithreaded rendering: graphics API calls are moved from the main thread to a separate render thread.
Graphics jobs: multiple threads prepare commands for the thread that submits graphics API calls.

If you have both enabled, main thread schedules some work for worker threads, which prepare commands for the render thread, which in turn submits graphics API calls.

4 Likes

If I disable Multithreaded rendering and only enable Graphics jobs, will main thread offload all its works including something like Batch.DrawInstanced to Render Thread?

There will be no dedicated render thread in this setup.

Sounds like it won’t benefit to performance?

It depends on what your performance bottleneck is and on the target hardware. If any of those options would’ve been a clear performance benefit in all possible scenarios, there wouldn’t have been an checkbox :slight_smile:

Thanks for reply.

My scenario is I found Batch.DrawInstanced run on Main Thread will dispatch Batch.FillInstanceProperties to job worker threads but it will wait for it to finish the job. So the Batch.DrawInstanced will cost much on Main Thread.
I found enable Graphics jobs will dispatch some calls of Batch.DrawInstanced to Render Thread on Editor, but it has no effect on Android with OpenGLES 3.2, so I’m wondering if there is any way to make Render Thread or job worker thread also run some Batch.DrawInstanced to reduce the workload on Main Thread on Android with OpenGLES?

If you want to reduce the load on the main thread, you need to enable multithreaded rendering.

Yes, I always enable multithreaded rendering, but I found the Batch.DrawInstanced on MainThread will wait Batch.FillInstanceProperties which takes a lot of time on MainThread. I found Graphics jobs could move some works to Render Thread but it donesn’t take effect on Android with OpenGLES, so I want to know will Graphics jobs have effect on Android with OpenGLES?

Ah! Now I get your question :slight_smile:
No, OpenGL ES doesn’t support graphics jobs.
You can try enabling Vulkan.

1 Like

As @aleksandrk mentioned above, on Android you can target Vulkan in order to enable Native Graphics Jobs which aim to better utilize the CPU during rendering setup. You can read a bit more on the different ‘Rendering Thread Modes’ in the API docs: https://docs.unity3d.com/ScriptReference/Rendering.RenderingThreadingMode.html

Worth noting, we are now working on a new graphics jobs threading mode which aims to remove unnecessary synchronization between the main thread and graphics jobs threads at the beginning/end of frames. In addition, we are also working to provide official Graphics Jobs support in Editor. We are first targeting DX12, but support for other compatible graphics backends will follow shortly.

4 Likes

Good to know that it’s being worked on. Vulkan support would also be great since it’s cross platform by design (and has issues in 2021 on quest 2 which then could be included)

1 Like

Thanks! I’m already trying the vulkan!

Thanks for the explaination, seems there are some compatibale problem on my android device for Vulkan, I will digging more about it.

1 Like

If you don’t mind, can you please tell what kind of tasks/works these are?
Are these something like

  1. Uploading image/buffers data to gpu?
  2. Filling up data in MaterialPropertyBlock? (When populating data for GPU Instancing)
    etc…

Thanks!