Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Javelin post #30

Merged
merged 1 commit into from
Jul 14, 2019
Merged

Javelin post #30

merged 1 commit into from
Jul 14, 2019

Conversation

kvark
Copy link
Member

@kvark kvark commented Jul 8, 2019


We are moving gfx-rs project forward, while having fun with it, thanks to the power provided by Rust language. We are building rich abstractions, which expand beyond gfx-hal API itself - into the internal layers of the backends, structured to be modular and maintainable. We are building high-performance graphics and compute infrastructure that deeply interacts with OS and drivers, thanks to the Rust's FFI capabilities and the lack of runtime. All of that, while dedicating only a bit of time and attention from the developers, who mostly do it as a side project. Rust allows us to move forward confidently and quickly, experiment with features as well as land the production code.

But gfx-rs is not all written in Rust. There is one complex and important component we rely on that is written in a mixture of C and C++: [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross). It's a shader translation library developed by [@TheMaister](https://github.com/HansKristian-Work) and a few Khronos members, although not an official Khronos product. We use it to generate platform-specific shaders from SPIR-V sources. It has a test suite, and it's Metal backend is mostly developed and used by MoltenVK.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its Metal backend

@Lokathor
Copy link

Lokathor commented Jul 8, 2019

SPIRV-Cross may be the "last bastion of C++ code in gfx-rs" but as far as I recall there's still not a pure rust way to make SPIRV from shader source text, right?

Will Javelin allow translating source text into SPIRV as well? Your post isn't clear on this point.

@kvark
Copy link
Member Author

kvark commented Jul 8, 2019

@Lokathor

there's still not a pure rust way to make SPIRV from shader source text, right?

There is no single SPIR-V source text, unless you mean the textual form (slide 38), which nobody uses.

Some people generate SPIR-V from GLSL, most use HLSL as the source. Rust ecosystem also dips the toes in the direct SPIRV generation with rlsl. We can't cover all of them here, and we don't think it makes sense to even try covering that part in scope of Javelin. It's an important path to get right, but it's not essential for gfx-rs to operate (since it only knows and cares about SPIR-V).

I'll make the article more clear about this (thank you for noticing this!)

@Lokathor
Copy link

Lokathor commented Jul 8, 2019

Right, I mean GLSL -> SPIRV or HLSL -> SPIRV or any other human readable form to SPIRV.

I don't think that gfx-rs needs to cover every format, but I think that it needs to cover at least one format. Otherwise, a person cannot legitimately say that you can use just gfx-rs to display things, because you have no way (without reaching outside of gfx-rs) to actually get SPIRV code to send to the GPU.

@kvark
Copy link
Member Author

kvark commented Jul 8, 2019

@Lokathor I think you have a valid point, but I'm not sure about the best way to address it. Do you suggest to include Something -> SPIRV in scope for the project? I'd very much prefer to not fix the target on GLSL or HLSL and instead keep exploring.

@Lokathor
Copy link

Lokathor commented Jul 8, 2019

I don't know enough to say what the best shader situation would be. I started graphics with OpenGL, so then when I did learn-gfx-hal I also naturally used GLSL for the basic shaders I needed there.

Someone smarter than me will have to pick a first target for supporting a pure-rust FOO->SPIRV compiler. GLSL, HLSL, RLSL, or even some fourth option. Keeping in mind that it wouldn't be a total lock in, just a first selection and that probably other compilers for the other formats would follow.

@antiagainst
Copy link

Thanks for the interest in rspirv! It's thrilling to see that it can help to remove the last C++ code component in gfx-rs! I'm happy to facilitate the procedure. :)

I'm not familiar with gfx-rs per-se but I think HLSL is the front-end language chosen by the industry. Developing a compiler for HLSL to SPIR-V in Rust is a non-trivial task given that HLSL is a C++-ish language. Designing another Rust DSL for shading language might be even daunting. I think they are both significant enough to merit their own project. But this is just my two cents. :)

@Lokathor
Copy link

Lokathor commented Jul 8, 2019

I think that if we have a reliable, pure-rust "SourceLang -> SPIRV -> NativeLang" pipeline it doesn't really matter that much which language is the textual source language. They're basically doing the same pure math ops since they're all fairly plain languages running on the same GPU, it's just syntactic differences.

If we setup an HLSL compiler to start and then say "Sorry that you can't use GLSL with this, here's a 30 minute tutorial to get you up to speed on how to use HLSL instead, and here's some cross compilers so that you can easily translate your old GLSL to HLSL as you move forward." then that's a fine situation that doesn't really leave anyone stuck.

Copy link
Contributor

@fu5ha fu5ha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice :) I just have some gramatical/sentence flow things

title: Javelin project
---

We are moving gfx-rs project forward, while having fun with it, thanks to the power provided by Rust language. We are building rich abstractions, which expand beyon gfx-hal API itself - into the internal layers of the backends, structured to be modular and maintainable. We are building high-performance graphics and compute infrastructure that deeply interacts with OS and drivers, thanks to the Rust's FFI capabilities and the lack of runtime. All of that, while dedicating only a bit of time and attention from the developers, who mostly do it as a side project. Rust allows us to move forward confidently and quickly, experiment with features as well as land the production code.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are having fun moving the gfx-rs project forward thanks to the power provided by the Rust language.

We are building rich abstractions which expand beyond the gfx-hal API itself and into the internal layers of the backends, structured to be modular and maintainable.

We do all of this while requiring only a portion of our developers' time and attention, who work on gfx-rs mostly as a side project.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you think the other sentences there are best to be removed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, just only had comments on those ones :)


SPIRV-Cross shows up quite a bit in our performance profiles (e.g. on Dota2). It is also written in a way (arguably!) that makes weak guarantees about what the state of the translator is at any point. And while it moves fast (in terms of contributions), it defines for us today what we can and what we can not do in terms of using advanced backend features, e.g. tessellation, argument buffers, etc. It complicates our [build process](https://github.com/gfx-rs/gfx/issues/2520), becoming a pain point for developers and users alike.

We think the time has come for us [to attack](https://github.com/gfx-rs/gfx/issues/2269) that last bastion of C++ code in gfx-rs. That is what [Javelin](https://github.com/gfx-rs/javelin) project is about: "A SPIR that flies above the garden walls". It's a very complex piece of software to be written, that we haven't made much progress yet. However, we feel that Rust, once again, is the best tool for the job of shader translation: it's about parsing, working with bytes and data structures, with an ability to do unit and fuzzy testing, and no external dependencies.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is what the Javelin project is about...

It's a very complex piece of software and we have not made much progress on it yet.


We think the time has come for us [to attack](https://github.com/gfx-rs/gfx/issues/2269) that last bastion of C++ code in gfx-rs. That is what [Javelin](https://github.com/gfx-rs/javelin) project is about: "A SPIR that flies above the garden walls". It's a very complex piece of software to be written, that we haven't made much progress yet. However, we feel that Rust, once again, is the best tool for the job of shader translation: it's about parsing, working with bytes and data structures, with an ability to do unit and fuzzy testing, and no external dependencies.

This post is meant to communicate our vision and plans for this future development. Note that here we are only talking about the path of shader translation from SPIR-V to anything, we don't plan to have GLSL->SPIR-V in scope. The key points of advantage that we hope to get by implementing Javelin are:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The key advantages we hope to gain by implementing Javelin are:

@grovesNL
Copy link
Contributor

grovesNL commented Jul 9, 2019

@Lokathor I don't think gfx needs to take much of a stance on HLSL/GLSL/RLSL -> SPIR-V compilation at the moment, besides agreeing that it would be nice to have some fully Rust tooling in that space. gfx-hal (like Vulkan) just accepts SPIR-V and it isn't impacted by the choice of source language used.

For example, somebody could contribute to the SPIR-V backend for the existing glsl crate or contribute to RLSL if they would like to help.

---


We are having fun moving the gfx-rs project forward thanks to the power provided by the Rust language. We are building rich abstractions which expand beyond the gfx-hal API itself and into the internal layers of the backends, structured to be modular and maintainable. We are building high-performance graphics and compute infrastructure that deeply interacts with OS and drivers, thanks to the Rust's FFI capabilities and the lack of runtime. We do all of this while requiring only a portion of our developers' time and attention, who work on gfx-rs mostly as a side project. Rust allows us to move forward confidently and quickly, experiment with features as well as land the production code.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as land the production code

Maybe "land production-quality code"


But gfx-rs is not all written in Rust. There is one complex and important component we rely on that is written in a mixture of C and C++: [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross). It's a shader translation library developed by [@TheMaister](https://github.com/HansKristian-Work) and a few Khronos members, although not an official Khronos product. We use it to generate platform-specific shaders from SPIR-V sources. It has a test suite, and its Metal backend is mostly developed and used by MoltenVK.

SPIRV-Cross shows up quite a bit in our performance profiles (e.g. on Dota2). It is also written in a way (arguably!) that makes weak guarantees about what the state of the translator is at any point. And while it moves fast (in terms of contributions), it defines for us today what we can and what we can not do in terms of using advanced backend features, e.g. tessellation, argument buffers, etc. It complicates our [build process](https://github.com/gfx-rs/gfx/issues/2520), becoming a pain point for developers and users alike.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also mention how we have to have a separate Emscripten build to generate wasm for SPIRV-Cross, separate from the rest of the Rust code (which does not use Emscripten)

3. Make it easier to maintain and identify issues in the shader translation
4. Start working on SPIR-V validation and sanitization for safety and WebGPU
5. Unlimit our progress with advanced backend features:
- explore direct translation to LLVM, MSL, and DXIL (all of those are LLVM-IR variations)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be AIR instead of MSL


We think the time has come for us [to attack](https://github.com/gfx-rs/gfx/issues/2269) that last bastion of C++ code in gfx-rs. That is what the [Javelin](https://github.com/gfx-rs/javelin) project is about: "A SPIR that flies above the garden walls". It's a very complex piece of software and we have not made much progress on it yet. However, we feel that Rust, once again, is the best tool for the job of shader translation: it's about parsing, working with bytes and data structures, with an ability to do unit and fuzzy testing, and no external dependencies.

This post is meant to communicate our vision and plans for this future development. Note that here we are only talking about the path of shader translation from SPIR-V to anything, we don't plan to have GLSL->SPIR-V in scope. The key advantages we hope to gain by implementing Javelin are:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could clarify it a bit more

SPIR-V to anything (for example, translating SPIR-V to HLSL, MSL, or GLSL)


But gfx-rs is not all written in Rust. There is one complex and important component we rely on that is written in a mixture of C and C++: [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross). It's a shader translation library developed by [@TheMaister](https://github.com/HansKristian-Work) and a few Khronos members, although not an official Khronos product. We use it to generate platform-specific shaders from SPIR-V sources. It has a test suite, and its Metal backend is mostly developed and used by MoltenVK.

SPIRV-Cross shows up quite a bit in our performance profiles (e.g. on Dota2). It is also written in a way (arguably!) that makes weak guarantees about what the state of the translator is at any point. And while it moves fast (in terms of contributions), it defines for us today what we can and what we can not do in terms of using advanced backend features, e.g. tessellation, argument buffers, etc. It complicates our [build process](https://github.com/gfx-rs/gfx/issues/2520), becoming a pain point for developers and users alike.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could rephrase

It is also written in a way (arguably!) that makes weak guarantees about what the state of the translator is at any point.

to talk about how we'd prefer to work with immutable Rust data structures representing the compiler state directly instead of going through the Rust <-> C ABI <-> C++

- explore direct translation to LLVM, MSL, and DXIL (all of those are LLVM-IR variations)
- get Metal argument buffers and tessellation in a way that works best for us

In terms of implementation, the first step is getting the proper tools to work with SPIR-V. We are currently looking into building the proper structured representation in [rspirv](https://github.com/google/rspirv). Once this is done, we'd start experimenting with simple shader outputs in the backends behind an optional feature. We are also planning to have a web playground to be able to convert the shaders online and investigate issues. The path forward is hard, and we would appreciate any help!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

building the proper structured representation in rspirv

to

building a proper structured representation for SPIR-V in rspirv

- explore direct translation to LLVM, MSL, and DXIL (all of those are LLVM-IR variations)
- get Metal argument buffers and tessellation in a way that works best for us

In terms of implementation, the first step is getting the proper tools to work with SPIR-V. We are currently looking into building the proper structured representation in [rspirv](https://github.com/google/rspirv). Once this is done, we'd start experimenting with simple shader outputs in the backends behind an optional feature. We are also planning to have a web playground to be able to convert the shaders online and investigate issues. The path forward is hard, and we would appreciate any help!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably clarify how a shader playground would relate to the existing efforts of http://shader-playground.timjones.io/

@Lokathor
Copy link

Lokathor commented Jul 9, 2019

@grovesNL As I said in the Discord but I'll repeat here for others reading this thread: I absolutely do not care about the difference between GLSL/HLSL/anything-else. What I care about is that there is some way to produce the SPIRV that gets fed in to Javelin. If you're relying on a C/C++ tool for the start of the process, that entire process relies on C/C++. So Javelin doesn't really remove the last bit of C++ from the gfx-rs ecosystem.

The only reason that I talked about HLSL is because Antiagainst said that HLSL is used the most. That's fine if that's the first language that can be compiled to SPIRV, because basically all shader languages are the same anyway. The choice is unimportant compared to the fact that we can compile anything at all to SPIRV.

@kvark
Copy link
Member Author

kvark commented Jul 9, 2019

@Lokathor It's not nearly as black and white as you are painting it. Generation of SPIRV can be done with Rust code ("rlsl" and "glsl" crates), could be done using external tools, which don't have to be a part of the build process. At the very least, it could be done in a specially crafted environment that isn't required for the rest of the code. Consider the following scenarios:

A: I built a library on gfx-rs that relies on SPIR-Cross. Every single user of that library, on every platform, now has to be able to build SPIRV-Cross for their environment.

B: I built a library on gfx-rs that relies on Javelin. I grabbed some SPIRV shaders from the internet, maybe generated them with playground, or locally on one specific machine. I included them in the library - bam! no clients need to have any specific build environment.


There are many ways to generate SPIR-V. We do care about them. Technically, providing the trusted and idiomatic solutions for the ecosystem would be in scope for the gfx-rs organization. But it would not be in scope for this particular project - Javelin.

@Lokathor
Copy link

Lokathor commented Jul 9, 2019

I understand everything you're saying, and I really fully understand that SPIRV can come from many locations and that some programs need to generate SPIRV at runtime and that most only need to generate it all compile time. I get all of that. I've used gfx-hal before. But everything I'm saying is just a strong, emotional reaction to the particular phrasing being used in the blog post:

We think the time has come for us to attack that last bastion of C++ code in gfx-rs. That is what the Javelin project is about:

Because SPIRV-cross isn't the last bastion of C++ for as long as there isn't a pure rust path at the start of the "ShaderText->SPIRV->Platform" pipeline.

  • I looked at the rlsl crate the other day, it specifically says it's not ready for use, it doesn't accept contributions, and it's not on crates.io.
  • The glsl crate is at least on crates.io but self rates as "passively maintained" and the documentation is totally unclear how you turn GLSL into SPIRV, if you can even actually do that at all (I actually don't think it can so that).

In my experience with trying to on-board beginners into gfx-hal, I've never once had any of them think twice about spirv_cross being a dependency. It's so seamless they don't even know it's in there. But I've had nearly every single one of them look at shaderc and its wild build process and super long build times and comment on how that is the most annoying and problematic step in the entire build.

Thank you everyone for your time.

@kvark kvark changed the title Create 2019-07-09-javelin.md Javelin post Jul 11, 2019
@kvark kvark merged commit b5783d5 into master Jul 14, 2019
@kvark kvark deleted the kvark-javelin branch July 14, 2019 03:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants