Set constant buffer for pixel shader only

Started by
7 comments, last by VietNN 6 years, 5 months ago

Hi everyone,

I porting a project from DX11 to DX12.

- In Dx11,we can set the constant buffer for each shader by using : VSSetConstantBuffer, PSSetConstantBuffer. But in Dx12 I am using SetGraphicsRootConstantBufferView, as I know it will set constant buffer for both VS and PS, am I right?

- For example, my project is using 5 constant buffers: A,B,C,D,E. The VS use 3 const buffer A,B,C and PS use A, D,E

- So how to port it to DX12 correctly ? SetGraphicsRootConstantBufferView(0 -> 4, A -> E) seems ok, but would PS know how to match D E in right position?

Thank you :)

Advertisement

Not sure it works with SetGraphicsRootConstantBufferView() but if you are using descriptor tables CD3DX12_ROOT_PARAMETER has a method InitAsDescriptorTable() which takes a D3D12_SHADER_VISIBILITY parameter where you specify which shaders get access to the table.

Thank you GuyWithBeard, I will try using descriptor tables :)

Hi, I have tried using descriptor tables  for const buffer but it seems like fps is dropped. Not sure if I did not implement correctly or else, need time to investigate...

But I want to know if we can use SetGraphicsRootConstantBufferView for vertex or pixel shader separately. Or doing things like using SetGraphicsRootConstantBufferView but not need to modify shader.

The descriptor table adds one level of indirection compared to binding the view to the command list directly, so there is a little bit of extra overhead. It should be pretty much negligible but if you are seeing worse performance then I guess not.

AFAIK SetGraphicsRootConstantBufferView() does not allow you to set the shader visibility explicitly, which raises the question; which stages can access the resource? I don't know myself, but some samples I have seen verify that the resource is created with both D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE and D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE which suggests it is visible in all stages.

Finally, do note that SetGraphicsRootShaderResourceView() does not support binding textures to the shaders, so for those you will need descriptor heaps and tables anyway.

7 hours ago, VietNN said:

- In Dx11,we can set the constant buffer for each shader by using : VSSetConstantBuffer, PSSetConstantBuffer. But in Dx12 I am using SetGraphicsRootConstantBufferView, as I know it will set constant buffer for both VS and PS, am I right?

- For example, my project is using 5 constant buffers: A,B,C,D,E. The VS use 3 const buffer A,B,C and PS use A, D,E

- So how to port it to DX12 correctly ? SetGraphicsRootConstantBufferView(0 -> 4, A -> E) seems ok, but would PS know how to match D E in right position?

The root signature is what controls visibility and register assignment in D3D12.  In your specific case for constant buffers, the D3D12_ROOT_DESCRIPTOR contains a ShaderRegister variable for you to fill out that will match what you type in your shader code as cbuffer MyCB: register(b#).  For example, if you set ShaderRegister to 5, then you would declare cbuffer MyCB: register(b5).

The D3D12_ROOT_PARAMETER (of which the root descriptor is a unioned member of) has a ShaderVisibility member that controls which stages of the pipeline the parameter is visible to.  You can either set the visibility to ALL, or to individual stages and use duplicate (with different stage) entries in the root signature.  See here:  https://msdn.microsoft.com/en-us/library/windows/desktop/dn913202(v=vs.85).aspx#visibility

In your case, you can give your shared constant buffers ALL visibility and set them once using SetGraphicsRootConstantBufferView, or you can give your shared constant buffers duplicate entries with specific visibilities (VERTEX and PIXEL) and set them each with separate calls to SetGraphicsRootConstantBufferView.  The link above mentions this, but some hardware handles ALL differently and is less efficient than setting individual stages, while other hardware will have no extra cost for setting ALL.

Keep in mind general best practices for root signatures when deciding on a route - keep the root signature as small as possible, with items that change more frequently towards the beginning.  Root constant descriptors take 2 DWORDS each, so can start to grow your root signature quickly if you're not mindful.

More documentation that you might find helpful:

https://msdn.microsoft.com/en-us/library/windows/desktop/dn859357(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/windows/desktop/dn986747(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/windows/desktop/dn879476(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/windows/desktop/dn879482(v=vs.85).aspx

 

Ah, make perfect sense that you can set the visibility through the RootSig. Excellent description!

Thank you WFP, your comment is so helpful :)

 

This topic is closed to new replies.

Advertisement