DirectXShaderCompiler
DirectXShaderCompiler copied to clipboard
[SPIR-V][Feature Request][SM6.6] ResourceDescriptorHeap support/emulation
Currently, attempting to assign a value indexed from ResourceDescriptorHeap
results in a ICE (segfault) if -spirv
is passed.
I'm writing this issue as sort of a placeholder to describe how this could be at least emulated in SPIR-V, at least until more direct support is available.
Consider a barebones shader like so:
[numthreads(32, 1, 1)]
void CSMain()
{
Texture2D t = ResourceDescriptorHeap[0];
}
This shader fails to compile if -spirv -E CSMain
are passed to dxc
. However, one way this could be emulated is by creating "shadow" bindings for every resource type in a distinct space when -spirv
is set. e.g. the compiler could transform the snippet above to:
[vk::binding(1000)]
Texture2D<float> __texture2d_float[];
[vk::binding(1000)]
Texture2D<float2> __texture2d_float2[];
[vk::binding(1000)]
Texture2D<float3> __texture2d_float3[];
// etc. for every resource type present in the shader. The set/binding for these emitted arrays can be set with a
// command line argument but defaults to some high number
// The float and float2 texture types here are just illustrative.
[numthreads(32, 1, 1)]
void CSMain()
{
Texture2D t = __texture2d_float2[0];
}
In the above transformation, the user could still write ResourceDescriptorHeap
without thinking about which aliased descriptor array matched the resource type. The compiler does the following work:
- Analyzes which types are present in the shader
- Silently emits a binding at a deterministic set/binding slot corresponding to that type
- Mutates
ResourceDescriptorHeap
to reference the correctly typed descriptor array
To use the shader, the user is responsible for creating the descriptor set that binds the descriptors themselves. However, the user is still able to access all resource types in a single unified heap (and more importantly, author shaders that work with both DX12 + vulkan using the same binding style).
Relevant discussion: https://github.com/KhronosGroup/Vulkan-Docs/issues/871
Thank you for reporting this issue. Ok .. we need some investigation for this topic. We will take a look.
Thanks, one edit I would make to my proposal above is that the binding scheme be changed to have a deterministic mapping between set/binding to resource type.
For example:
- Bit 0: RW vs non-RW variant
- Bits 1-2: Dimensionality (1D, 2D, 3D)
- Bits 3-x: Resource base type (e.g. ByteAddressBuffer, Texture2D, etc.)
The binding number could be computed as above so that the user can be free to bind the descriptor sets that are needed and simply leave the remaining bindings unmapped.
For samplers, we could use a different set from the resource descriptor types.
Thank you for reporting this issue. Ok .. we need some investigation for this topic. We will take a look.
@jaebaek Just curious, was there ever any progress made on this topic? Not having the ResourceDescriptorHeap available for SPIR-V is pretty much a showstopper for applications built with true bindless architecture, wanting to target Vulkan using DXC. You'd have to build large workarounds or manage additional root signatures and descriptors otherwise.
I have bit another proposal, but for HLSL. We have mutable descriptor type, and descriptor buffers, so we can try to add decorators to bind these HLSL names with set=N
. And we have same binding point, same set, needs only to just casting.