Investigate spirv_to_dxil Library
HLSL Compilation Problem
HLSL compilation to DXBC/DXIL is quite a pain right now. We have two main options in HLSL compiler and they both have significant downsides.
FXC (aka D3DCompiler)
Pros:
- Built into windows
Con:
- Extremely slow (500ms - 10s happen regularly)
- Only generates DXBC (limited to SM 5.1)
- Buggy and unmaintained
DXC (aka DXCompiler)
Pros:
- Compiles directly to DXIL SM 6.0+
- Faster than FXC
- Maintained
Cons:
- Requires external DLL to be shipped to users - showstopper for a lot of rust projects.
- Includes LLVM, large code size (17MB uncompressed) - showstopper for FF
Of these, the cons of DXC are show stoppers for many people while FXC's tradeoffs are bad, but tolerable.
spirv_to_dxil
I was recently pointed to the work of spirv-to-dxil. This is a standalone library that's part of mesa which exposes a single function that transpiles spirv directly to dxil. https://gitlab.freedesktop.org/mesa/mesa/-/tree/main/src/microsoft/spirv_to_dxil
I have yet to run it, but I am optimistic that it could at least partially help our shader compilation woes, at least short to medium term. Some pros, cons, and things to be investigated as I see them.
Pros:
- With some minimal modification of the spirv-backend we should be able to integrate it.
- Does not require a DLL.
- Supports SM 6.6+.
- It's somebody else's code, we can file bugs against them.
- Part of GLon12
Pros (needing investigation):
- Significantly faster than HLSL path.
- Smaller code size
Cons:
- It's somebody else's code. Firefox cannot accept this path.
- Build process uses meson. While the output is just a regular library you can link with, it's integrated with the rest of mesa's build system, and depends on NIR. Ideally we want the build experience for the user to involve no external tools, so we might need to do some massaging/preprocessing to get this to build with just
cc. - Giant pile of C, which requires building.
DXIL naga backend
If we can get a fully functioning DXIL naga backend, this would be the most ideal situation, but it is a significant amount of work which will take a long time to get fully operational. There is reasonable reason to think that DXIL does not need to be optimized as vendor compilers will happily do further optimization paths, similarly to how our spirv-backend does not optimize and we've experienced no major issues.
Plan
We should investigate this option as a native-only option, feature flagging it out for firefox like we do DXC right now. If the investigation proves that it does what it says on the tin, and we see success, we should enable it for default windows workflows.
Firefox can't incorporate this code into our code base. The cost and risk of bringing this in makes FXC preferable for us for the time being.
In the long term, Naga could grow a DXIL backend, and that would be fine for Firefox.
Updated the above plan and pros/cons to reflect recent discussion. Aiming for this potentially being the default native-only solution.
Not sure if this is useful or not anymore, but I've recently updated my Rust bindings to spirv-to-dxil to build with just cc.
We're not really pursuing it actively anymore due to some priority changes, but I'm very glad this exists, especially building without meson!
https://devblogs.microsoft.com/directx/directx-adopting-spir-v/ Since microsoft is going on another path, what is the status of this issue?
We're still interested in having it, and the spirv backend changes needed to support this are even more needed now.
With #6574 landed this can probably be closed?
DXC is still quite slow (just monumentally faster), so this would still benefit some people and there are still concerns about code size with DXC, just no longer for Firefox as they are shipping it more. I think the biggest issue here would needing to implement the various binding polyfills on the spirv backend too