Rendering Task System

Started by
1 comment, last by AxeGuywithanAxe 7 years, 4 months ago

Hey all, so I am currently in the process of adding a task system to my rendering engine. As of now I have been using a single render thread. In my current system , when what I call a "RenderResource" needs to be created, i.e have it's gfx specific resource created. it sends a job to the render thread for it to be initialized. I am currently relying on the sequential nature of a single thread to make sure that resources aren't used before they are initialized, and resources aren't destroyed while they are being used. I.e a resource that is initialized in Frame0, will always be initialized prior to a world that is being rendered in Frame0 because sending jobs to the render thread is part of "game logic" , and sending a job to render the world isn't sent until after game logic is done. A secondary issue is creating resources during a frame. When I use a single thread that owns the device, If i need a resource I can create it immediately, and that extends towards creating precompiled shaders, pooled render targets, and etc. In a task based system, that becomes more difficult. A Job running on thread C may need to create a pooled render target that it will bind to the command list that it's currently compiling, or thread D may be using a shader that is being used for the first time, so it has to make a call to the gfx device create the shader, which may make a call to a global "shader cache" to return a shader if it already exists", and the complexity keeps growing. This is also without taking into account that certain APIs don't support multithreaded resource creation. It seems that resource management becomes drastically more complex when you move command list creation to other threads.

Advertisement

Having parallel running threads, one for AIs, another running animations, another running player control, another running rendering, … makes things needlessly complex (as you determined already), because they all need to be synchronized. A better way is to have the tasks still in sequence (because many if not all of them need to have a stable result state of previous tasks), and to parallelize just within the tasks. If you really want to go the other way of concurrency, you probably need to multi-buffer each task's state and to synchronize on them in the producer/consumer manner.

For GPU resource allocation, an AFAIK common approach is to allocate them in advance, and reuse what is available at the time.

Just my 2 Cents on a complex topic, of course.

Actually as of now I have a game thread , a rendering thread, and the rest of the available threads are used as worker threads. What I have been doing is sending messages to the rendering thread when I need to render something, but what I'm currently trying to do is remove the rendering thread , possibly change it to a "submission" thread, and do all of my rendering logic in a job based manner.

This is what Bungie, Frostbite, and Naughty Dog do, while Unreal and Unity use a render thread approach. As of right now, my rendering thread is responsible for visibility detection, mesh batching, and command list generation. Visibility Detection is an easy thing to pull off the rendering thread, but it becomes more difficult when I have to work with resources that can only be created on one thread, in certain APIs. This will occur in the command list, and mesh batching stage. It may be determined that I can instance a set of meshes, which will require me to generate an instancing buffer, something that has to be done on the render thread, or during command list generation, I may need to create a shader that hasn't been used yet, which will require me to call the CreateXXXShader function on the render thread. From my point of view, it feels like rendering logic needs to have a dedicated orchestration thread, because every time you need to create a resource during the frame, you need to sync to the thread that is capable of creating resources.

This topic is closed to new replies.

Advertisement