Nabla icon indicating copy to clipboard operation
Nabla copied to clipboard

Port our shader library to HLSL2021 but retain access to all SPV extensions.

Open devshgraphicsprogramming opened this issue 3 years ago • 1 comments

Description

We want to reduce the unholy and ungodly Preprocessor Macro usage,

Description of the related problem

GLSL is ugly and verbose, we want to use HLSL2021 whenever we can for easier C++ and Shader code sharing (structs, namespaces, templates, methods, etc).

While at the same time retaining full access to all SPIR-V extensions and opcodes.

Solution proposal

A = Link SPIR-V modules produced from HLSL2021 with entry point GLSL

Compile certain collections of HLSL2021 headers to SPIR-V modules with DXC, then use SPIR-V Cross (or write our own tool) to generate the correct GLSL API headers (so that any dependent GLSL can be compiled).

Ensure that the autogenerated GLSL is produces the same SPIR-V as the source it was autogenerated from.

Failure Points:

  • inability to compile HLSL2021 without an entry point or shader stage agnostically
  • inability to use SPIRV-Cross to produce GLSL struct and function forward declarations without a complete and valid shader
  • SPIRV-Tools Linker not working at all

B = Use HLSL2021 for the entire engine library

The question remains, how to obtain access to every SPV functionality?

B.i Use the SPIR-V Tools linker

Wrap extra SPV functionality not supported by DXC inside functions, hand-write the SPV for the functions and the HLSL foward declaration in a header spv_instrinsics.hlsl.

Then, always:

  • include the spv_instrinsics.hlsl header before compiling anything with DXC
  • use SPIR-V Tools linker to link the instrinsic's SPV module

B.ii Fork DXC, implement every SPV feature we use

Painful, and free work for Microsoft.

Additional context

A

Its best if we adopt a "primary binary" + "linked libraries approach" due to limitations: https://github.com/KhronosGroup/SPIRV-Tools/issues/4224

For example it would be wise to validate that the SPIR-V libraries don't contain any descriptor declarations, etc.

Seems like this would be the solution https://github.com/microsoft/DirectXShaderCompiler/issues/3919

A

Was impossible anyway

B

We're going with a variant of this, DXC not SPIR-V linking, SPIR-V intrinsics are good enough

https://therealmjp.github.io/posts/dxil-linking/

Example 62 CAD, uses Fragment Shader Interlock, a great demonstration of how to use inline SPIR-v