Gfx: [RFC][ll] SPIR-V as the shader API solution

Created on 15 Jul 2017  路  7Comments  路  Source: gfx-rs/gfx

Currently, providing platform-specific shaders is the weakest part of the abstraction. It's also error-prone and maintenance heavy. This RFC is different from #71 for being focused on low-level side.

We could have a single unified API in Factory to receive SPIRV binary. This would work in line with #1226, and we can use SPIRV-cross to generate the backend-specific shader binaries from it. As a follow-up, we may develop a library for generating such SPIRV from Rust sources.

At the same time, the backend Factory structs can have special methods for constructing shader modules from platform-specific shader representation. I.e. GL backends may create shaders from GLSL files. This would allow supporting the existing applications that only care about GL.

We must be careful in respecting platform specifics and patching SPIRV accordingly before passing it down the toolchain:

  • All: Y coordinate for target/texture going up/down
  • GL: depth is in range -1 to 1 (see #971)
  • Metal: shift vertex buffer indices to avoid conflicts with indirect argument buffers (see #1372)
DirectX-12 Metal average hal infrastructure ready for work api discussion strategic

Most helpful comment

We kind should provide both:

  • SPIR-V is essential for our vulkan portability goal, therefore we need to provide some way to handle these for all backends
  • Language specific shaders would be nice to give developers more control when they need it, which could be caused by corner cases of the SPIR-V translation (e.g for older GL backends). Might also give a bit of extra performance as we remove the additional translation step from SPIR-V -> backend specific shader format.
  • Rust frontend would be terrific for the library itself. More in concerning the higher layers (render) to provide additional security for users by sharing the shader interface with the host program.

All 7 comments

As awesome as this would be I assume we will be blocked here by SPIRV-Cross as it's not production ready enough afaik (even though already quite good!).
An offline pipeline could be a valueable first step here to check the generated output and provide manual fixes or complete shaders.

@msiglreith I think we reached the stage where we can start playing with SPIRV and get something working, then actually spread our wings and contribute to SPIRV-cross with fixes we need. AFAIK, that's what MoltenVK did, and SPIRV->MTL is used in production, so we have a good start.

It would be quite neat to generate shader binaries directly from SPIR-V, in order make the loading faster on those backends. FXC seems to be fairly well researched (https://github.com/google/rspirv/issues/17), and DXIL has an open-source compiler. MTL, however, doesn't appear to be open or reverse-engineered.

I'm in favor of the SPIR-V to DXBC/DXIL approach. It involves less steps (no need to invoke the whole HLSL front end in the middle) and is more efficient.

I think it might be better/easier to translate glsl/msl/hlsl directly from Rust (or another high level language). SPIR-V can have multiple entry points, subpasses, push constants. I am not sure how much effort it would be to translate SPIR-V into a higher level language.

But translating a high level language into a high level shader language probably is also terrible, I am not sure how good the optimizers in the drivers are. I can only shiver if I imagine to translate Rusts iterators into GLSL without any optimizations.

Then there is the other approach of translating from an IR like Mir or llvm-ir etc. At least you could get offline optimizations that way but it is definitely a bit more involved.

There is also https://github.com/LunarG/LunarGLASS but I am not quite sure what the point is. There is no plan for a SPIR-V backend. (But it has a SPIR-V fronted so it might be able to convert to GLSL/HLSL)

I know that spirv-cross currently is a bit lacking and so is the optimizer but they probably will improve over time.

I currently also work on a mir -> SPIR-V backend and if everything works out I think creating a backend for other languages should not be much work. Although I have to admit that I am progressing much slower than I anticipated.

We kind should provide both:

  • SPIR-V is essential for our vulkan portability goal, therefore we need to provide some way to handle these for all backends
  • Language specific shaders would be nice to give developers more control when they need it, which could be caused by corner cases of the SPIR-V translation (e.g for older GL backends). Might also give a bit of extra performance as we remove the additional translation step from SPIR-V -> backend specific shader format.
  • Rust frontend would be terrific for the library itself. More in concerning the higher layers (render) to provide additional security for users by sharing the shader interface with the host program.

This has actually been implemented, see #1546 and #1576 馃帀

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mjadczak picture mjadczak  路  4Comments

Bastacyclop picture Bastacyclop  路  3Comments

grovesNL picture grovesNL  路  3Comments

InMath picture InMath  路  5Comments

kvark picture kvark  路  3Comments