Nabla
Nabla copied to clipboard
Port our shader library to HLSL2021 but retain access to all SPV extensions.
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.hlslheader 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