Dxvk: HLSL to SPIRV descriptor set

Created on 21 Dec 2017  路  2Comments  路  Source: doitsujin/dxvk

Hi,
Excellent work tho, how do you plan to map the hlsl register into vulkan descriptor set?
Or you plan to have one unique descriptor set for shader?

question

Most helpful comment

Assuming that I understand your question correctly: Shader resource binding is already implemented. Here's how it works:

Step 1 - Descriptor set layout

For each shader, a list of resource slots that are used by the shader is stored. So if a vertex shader uses constant buffer c0, that information will be remembered. When a given set of shaders is used for rendering for the first time, this information will be used to create a descriptor set layout.

Let's assume you render your scene with a vertex shader which uses constant buffer c0, and a pixel shader which uses sampler s0, texture t0 and its own constant buffer c0. Bindings in the descriptor set layout are tightly packed, and each resource has its own binding, so you'll end up with:

  • Binding 0 -> c0 (Vertex shader) with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
  • Binding 1 -> c0 (Pixel shader) with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
  • Binding 2 -> s0 (Pixel shader) with type VK_DESCRIPTOR_TYPE_SAMPLER
  • Binding 3 -> t0 (Pixel shader) with type VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE

Again, this binding mapping is stored. The descriptor set layout will be used to create a pipeline layout, there are no additional descriptor set layouts.

Step 2 - Descriptor set allocation

There is a descriptor set allocator tied to the command buffer, which automatically creates descriptor pools when needed. The descriptor pools don't really care about the pipeline layout, they just have a fixed number of descriptors of each type, and are created in a way that descriptor sets cannot be freed individually.

Each time a draw call is executed, if a new resource has been bound or if the shader pipeline itself has changed, a new descriptor set is created and immediately updated with vkUpdateDescriptorSets, using the resources that are currently bound to the D3D context.

Now in reality, there's another level of indirection because all D3D stuff goes through an intermediate layer first (which does all the heavy lifting), but the explanation is still valid since a pixel shader's c0 is statically assigned to resource slot 12 in the backend and so on. Here's the relevant pieces of code:

src/dxvk/dxvk_descriptor.cpp
src/dxvk/dxvk_pipelayout.cpp
src/dxvk/dxvk-context.cpp
src/dxvk/dxvk-cmdlist.cpp

All 2 comments

Assuming that I understand your question correctly: Shader resource binding is already implemented. Here's how it works:

Step 1 - Descriptor set layout

For each shader, a list of resource slots that are used by the shader is stored. So if a vertex shader uses constant buffer c0, that information will be remembered. When a given set of shaders is used for rendering for the first time, this information will be used to create a descriptor set layout.

Let's assume you render your scene with a vertex shader which uses constant buffer c0, and a pixel shader which uses sampler s0, texture t0 and its own constant buffer c0. Bindings in the descriptor set layout are tightly packed, and each resource has its own binding, so you'll end up with:

  • Binding 0 -> c0 (Vertex shader) with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
  • Binding 1 -> c0 (Pixel shader) with type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
  • Binding 2 -> s0 (Pixel shader) with type VK_DESCRIPTOR_TYPE_SAMPLER
  • Binding 3 -> t0 (Pixel shader) with type VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE

Again, this binding mapping is stored. The descriptor set layout will be used to create a pipeline layout, there are no additional descriptor set layouts.

Step 2 - Descriptor set allocation

There is a descriptor set allocator tied to the command buffer, which automatically creates descriptor pools when needed. The descriptor pools don't really care about the pipeline layout, they just have a fixed number of descriptors of each type, and are created in a way that descriptor sets cannot be freed individually.

Each time a draw call is executed, if a new resource has been bound or if the shader pipeline itself has changed, a new descriptor set is created and immediately updated with vkUpdateDescriptorSets, using the resources that are currently bound to the D3D context.

Now in reality, there's another level of indirection because all D3D stuff goes through an intermediate layer first (which does all the heavy lifting), but the explanation is still valid since a pixel shader's c0 is statically assigned to resource slot 12 in the backend and so on. Here's the relevant pieces of code:

src/dxvk/dxvk_descriptor.cpp
src/dxvk/dxvk_pipelayout.cpp
src/dxvk/dxvk-context.cpp
src/dxvk/dxvk-cmdlist.cpp

Thanks for the answer, thus means you have only one unique descriptor set, my question was about multiple descriptor set introduced in vulkan but one set works as well.

Thanks

Was this page helpful?
0 / 5 - 0 ratings