Job Based Rendering

Started by
5 comments, last by Ameise 7 years, 9 months ago

Hey guys, so I was reading up on different architectures for rendering, and I've decided to go for a job based approach with a thread dedicated to submit. I have the game side figured out when it comes to jobifying it, but I seem to be having a difficult time with rendering data. My main difficulty is the fact that some apis don't support asynchronous resource creation. The method I'm using now is similar to Bungies method , whether they have multiple phases. Phase one is the update phase, where game side data is extracted for any object visible in any view, and using a frame approach, I allocate memory , i.e skinning data , and perform certain computations. During the "prepare" phase, any object that requires gpu data to be written / resources to be created, are called on the thread that owns the context, while others are allowed to be called on any of the other threads. This is an approach that works fairly well, but was wondering if anyone had a list of apis that support async resource creation, besides D3D , and if it's honestly a non issue when I start moving to other platforms. I know that valve uses per thread pools, I'm guessing that at the beginning of the frame they unlock a large vertex buffer and send it to each thread for use, and that shouldn't be hard to implement, anyway thanks!

Advertisement

I am not sure how this approach fits in with your design, but it may spark some new ideas.

http://etodd.io/2016/01/12/poor-mans-threading-architecture/

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

What platforms are you targeting? PC and game consoles have got you covered. I'm not experienced with threaded resource creation on mobile, so I'm not sure there.

D3D11/12 is fine and Vulkan is fine. I assume metal is fine. OpenGL (do you really have a linux port?) also supports it, but in a very roundabout way. You've got to make a second GL context, and follow some very strict rules about which GL functions you ever call on the secondary context. You can use a mutex to share this second context among your threads. If you implement it right, the drivers will actually make use of their DMA controllers ("Copy queue" in d3d12 terms) and do fancy async uploads of your resource data. Sorry, I've forgotten where to find the info on how to do this properly though.

On D3D9, I actually just emulate free-threaded resource creation. I return a texture/buffer object back to the user immediately, but copy all the creation arguments (including initial pixel data) into a queue for the main/submit thread to execute later.

However... resource *creation* should be done ahead of time, not as part of the main rendering loop. You should only be updating data within resources that have already been created. Do you have a link to this method that you're copying?

Thank you both Hodgman and Glass_Knife. I will look at the link. To Hodgman, I have a resource system that is done before time, the issue is more with dynamic resources like particle data and dynamic instancing. I have a pool of VertexBuffers/IndexBuffers/Instancing(structured buffers) for per frame data. The issue is that if the pools become maxed out during a frame on another thread , I can't just create a new buffer to be used by the particle system etc. In a render thread method, I could just instantly create the new resource. As of right now I am targeting PC and hopefully consoles at some point, but since you said I don't have to worry about their resource creation operations, I should be fine on that front. The method I'm basing it off of is on GDC Free Vault http://www.gdcvault.com/play/1021926/Destiny-s-Multithreaded-Rendering. They go over their multiphase approach, but since Destiny is on Consoles only they don't have to worry much about OpenGL's context issue. I guess my issue is resolved.

I am not sure how this approach fits in with your design, but it may spark some new ideas.

http://etodd.io/2016/01/12/poor-mans-threading-architecture/

Doesn't that architecture only allow for two primary threads?

I am not sure how this approach fits in with your design, but it may spark some new ideas.

http://etodd.io/2016/01/12/poor-mans-threading-architecture/

Doesn't that architecture only allow for two primary threads?

In the example, there are two update loops in different threads: game loop and physics loop. I don't see why you couldn't have more.

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

I am not sure how this approach fits in with your design, but it may spark some new ideas.

http://etodd.io/2016/01/12/poor-mans-threading-architecture/

Doesn't that architecture only allow for two primary threads?

In the example, there are two update loops in different threads: game loop and physics loop. I don't see why you couldn't have more.

Why not just implement a simple job graph at that point? They're not particularly difficult to write.

In that particular architecture, the more threads you have trying to communicate like that, the deeper the pipeline becomes, so you end up with more latency.

This topic is closed to new replies.

Advertisement