Multi-threaded rendering of D3D / OpenGL / whatever

I read a lot about multithreaded rendering. People offered all kinds of strange and wonderful schemes for delivering work to a GPU with threads in order to speed up their frame rate and get more material, but I have a little conceptual problem with all this, and I thought I launched his guru to see what you think.

As far as I know, the main unit of concurrency on the GPU is Warp. That is, it is at the pixel level, and not higher at the geometry representation level. Therefore, given that the concurrency block on the GPU is a deformation, the driver must be tightly locked with mutexes to prevent multiple threads overlapping messages. If so, I don’t see the advantage of coding for D3D or OpenGL primitives with multiple threads.

Of course, the most efficient way to use your GPU in a multi-threaded scenario is at a higher abstract level, where do you get batches of work together before sending it? I mean, rather than accidentally moving teams from multiple threads, I would think that one block accepts work from several threads, but with a little intelligence inside it, to make sure everything is ordered for better performance before sending it to the visualizer , there will be much greater gains if you want to work with multiple threads.

So where is the support for D3D / OpenGL multithreaded rendering in the real API?

Help me with my confusion!

+6
source share
2 answers

Your question comes from a misunderstanding of the difference between "make your renderers multithreaded" and "multithreaded rendering."

A renderer, or rather a "rendering system," does more than just issue API commands. He must mix the memory. You may need to dynamically load textures into graphic memory and output it from it. He may have to read the data after some rendering process. And so on.

To make multithreading a visualization tool, this means: that the rendering system uses multiple threads. These can be streaming graph graph management tasks, such as building a list of objects for rendering (rejection, BSP, portals, etc.). This can be a stream dedicated to managing texture storage, which swaps textures as needed and unloads them, loading them from disk, etc. This may be the case with the D3D11 command lists, where you create a series of rendering commands in parallel with other tasks.

The rendering process, the presentation of the actual API rendering commands, is not a stream process. Usually you have one thread that is responsible for the main glDraw* or ::DrawIndexedPrimitive work. Lists of D3D11 commands allow you to create sequences of these commands, but they are not executed in parallel with other rendering commands. This is the rendering stream and the main context that is responsible for the actual release of the list of commands; a list of commands is here to make this list more stream-friendly.

+8
source

In Direct3D 11, you usually create deferred contexts to which you make callbacks from your workflows. When the work is completed and you are ready to render, you will create a list of commands from each pending context and execute it in the immediate (front thread) context. This allows you to compose drawing calls in multiple threads, while maintaining the correct ordering of drawing calls, etc.

+1
source

Source: https://habr.com/ru/post/946012/


All Articles