Jump to content
  • Advertisement
VietNN

DX12 Set constant buffer for pixel shader only

Recommended Posts

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 :)

Edited by VietNN
correct grammar

Share this post


Link to post
Share on other sites
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.

Edited by GuyWithBeard
typo fix

Share this post


Link to post
Share on other sites

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.

Edited by VietNN

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!