DirectXShaderCompiler icon indicating copy to clipboard operation
DirectXShaderCompiler copied to clipboard

[SPIR-V][Feature Request][SM6.6] ResourceDescriptorHeap support/emulation

Open jeremyong-az opened this issue 3 years ago • 5 comments

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

jeremyong-az avatar Feb 12 '22 06:02 jeremyong-az

Relevant discussion: https://github.com/KhronosGroup/Vulkan-Docs/issues/871

jeremyong-az avatar Feb 12 '22 07:02 jeremyong-az

Thank you for reporting this issue. Ok .. we need some investigation for this topic. We will take a look.

jaebaek avatar Feb 15 '22 16:02 jaebaek

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.

jeremyong-az avatar Feb 15 '22 16:02 jeremyong-az

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.

hsiversson avatar Aug 18 '22 11:08 hsiversson

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.

ghost avatar Nov 29 '22 03:11 ghost