Advertisement

Dx11 Multiple render targets

Started by July 03, 2018 03:05 PM
3 comments, last by Jman2 6 years, 7 months ago

Hello,

I have been trying to set up multiple render target views in a traditional oop style architecture (as opposed to DOD), DX11 forces binding of RenderTargets as an array with the depth view as well. This is annoying when it comes to binding multiple buffers when you have objects such as DX11Rendertarget2D which stores an ID3D11RenderTargetView*, if it worked like everything else did in the sense that it used slots such that you can do:
SetRenderTarget(slot, RenderTarget);

,Then it would be a lot better as you could set the slots you want and set the depth buffer or leave it as the default one by passing null such is the way of a state-full API.

Any input on how others have managed there RenderTargets would be appreciated, storing an array of ID3D11RenderTargetView*[8] doesn't seem like a good idea due to ownership and ref counting.

Thanks.

Different platforms' APIs handle this differently. In Vulkan, for example, you must also set all colour attachments for a whole pass in advance. D3D12 is simular to D3D11 and D3D10 in this regard. On PS4, for example, the API allows for setting the RTVs individually.

I think the Vulkan way is the best because it gives the driver all the info very soon.

From a GPU perspective, it just wants to see the RT descriptor (MEMORY ADDRESS, width, height, format, tiling, mip, etc) and will gladly render into it. That means that the GPU commands (at least on AMD GCN) are indeed able to exchange individual RTs and Depth Stencil, however I don't think this is safe or useful at high level. Go the Vulkan way, it scales back to everything.

Advertisement

I agree with pcmaster: if you're going to try to have your own abstractions over D3D (or other API's), you're best off if you structure your engine's "internal" API in a way that requires you to specify all render targets simultaneously. That you way you can map that to any backends that your engine supports.

In our engine we have something we call a "render target state", which handles setting render targets + depth targets, optionally clearing them, and also specifying the necessary barriers (or low-level sync operations for consoles) that are necessary for using those render targets and potentially reading from them afterwards. This setup initially came from working with the Vita, which has a mobile GPU that requires you to be rather explicit about your render target usage due to the way that tile-based deferred rendering (TBDR) works. But it turned out to have worked out well for modern consoles and PC graphics API's.

Yeah, I just made the user pass in a vector of Rener targets and  grab the count. It's split into setRenderTarget and setRenderTargets if you pass nullptr to the singular one it Debra all to null accept [0] which gets default or the main target.

Either way it turns out the solution for both Oop and dod will be the same just one with handles. I'm doing both eventually.

This topic is closed to new replies.

Advertisement