🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

[D3D12, Vulkan, Metal] Triple buffer everything? I saw Depth Stencil Buffer is never for example.

Started by
5 comments, last by Alundra 2 years, 2 months ago

Hello!
In D3D12 you need to manage the triple buffering entirely yourself.
Maybe it was always the case but the GPU was just waiting for you wasting performance.
But is it needed to triple buffering everyting?
Like for example I never saw the depth stencil buffer triple buffered, is it fine?
Is it needed to triple buffering anything that can change from this 3 frames or it's fine to not?
For example render target for deferred rendering and post process will change all the time.
Thanks!

Advertisement

In my experience yes, you need to double or triple (depending on how many buffers you want to support) buffer most things. This somewhat depends on your usage. If you are doing a general interface, it gets kind of tricky.

As an example I support mesh generation and destruction on the fly, to support LOD. I do this in a separate thread from the rendering thread. Even if I am supposedly done with a mesh (i.e. it will never be rendered again), it might still be being rendered in a previous frame so I can't simply delete it. I even tried to optimize the deletion somewhat, as I wanted to take the deallocation out of the main render thread, so I have something called a mesh graveyard that runs in a separate thread. Of course you don't need to take everything that far.

You have similar issues with entries in descriptor tables and also constant buffers. You have some options too. You can allocate separate buffers for each frame or you can use different parts of the same buffer. The same goes with descriptor tables. I settled on the system I have now but it took me months to really wrap my head around things and I'm still working on it.

Double buffering is one way to handle having a consumer (such as the GPU) that reads data while a producer (such as the CPU) writes to it. It's not the only way to do it, but it's perhaps the simplest. The classic case of this is having the CPU fill out a constant buffer: you can't have the CPU write to some memory while the GPU is reading to it since the GPU is running a frame behind, so you double buffer the constant buffer so that the CPU and GPU are actually accessing different memory. You may see the same pattern come up when running multiple threads on a CPU as well.

You do not need this when the write and read are happening sequentially on the same processor. This covers that “render target for deferred rendering” case you brough up: the GPU will write to it first, you'll hit a barrier, then the GPU read from it. There's no need to double buffer since the read and write can't happen at the same time.

So to answer your question: no, you don't need to do it for everything. Typically you will do for resources that are CPU-writable and GPU-readable, or vice versa.

So now that explains why depth stencil buffer is not needed to be n-buffered, thanks!
So yes, the classical render target for the frame is not needed to be n-buffered too (bloom, ssao, …).
So the main thing that needs to be n-buffered is the swapchain buffer with command allocator and graphics command list, texture and vertex/index/constant/structured buffers that are dynamically changed on the CPU each frame.
So we can also say that differently, all that got uploaded from CPU to GPU for each frame needs to be n-buffered but if it's a data on the GPU that is executed it does not need to be n-buffered.

Yes that summary is accurate. The only other common case where things need to be N-buffered is if you are reading back data from the GPU to CPU, for example when reading query results.

Makes sense, otherwise the buffer does not correspond to the actual frame.
I guess there is an exception for example with Font Atlas where you do not care of the texture for any frame and you just want it updated any time to use the texcoord in it and have the text properly drawn.

This topic is closed to new replies.

Advertisement