Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upFind a solution for shader language support #71
Comments
cmr
added
the
question
label
Jul 5, 2014
This comment has been minimized.
This comment has been minimized.
|
One idea is to just query for the backend in use and have the user themselves supply a shader per API. |
This comment has been minimized.
This comment has been minimized.
|
Another is to use a single shader language and translate to whatever the backend needs. HLSL might be a mature choice here. (Valve has a tool available but I'm not sure how quality it is, and it only supports Shader Model 3.) |
This comment has been minimized.
This comment has been minimized.
|
Another is to make our own shading language, but that just sounds like a bad idea. |
This comment has been minimized.
This comment has been minimized.
|
A HM typed concatenative language! jk. |
This comment has been minimized.
This comment has been minimized.
|
I'm currently toying around with a "umbrella" struct for providing the source of the same logical shader in different languages. Nothing fancy, something like this: pub enum DeviceShader {
StaticBytes(&'static [u8]),
OwnedBytes(Vec<u8>),
NotProvided
}
pub struct ShaderSource {
pub glsl_120: DeviceShader,
pub glsl_150: DeviceShader,
hlsl_sm_3: DeviceShader
...
}
...
static VERTEX_SRC: ShaderSource = shaders! {
GLSL_120: b"
#version 120
attribute vec2 a_Pos;
varying vec4 v_Color;
void main() {
v_Color = vec4(a_Pos+0.5, 1.0, 1.0);
gl_Position = vec4(a_Pos, 0.0, 1.0);
}
"
GLSL_150: b"
#version 150 core
in vec2 a_Pos;
out vec4 v_Color;
void main() {
v_Color = vec4(a_Pos+0.5, 0.0, 1.0);
gl_Position = vec4(a_Pos, 0.0, 1.0);
}
"
};That should at least make it possible to hack some legacy compatibility into the libs without giving up on the newer shader versions at all. |
This comment has been minimized.
This comment has been minimized.
|
#72 gets us some of the way there. |
This comment has been minimized.
This comment has been minimized.
|
Found a good link for that: Cross Platform Shaders in 2014 |
kvark
added
T-discussion
and removed
T-question
labels
Jul 16, 2014
This comment has been minimized.
This comment has been minimized.
|
I think what we have today is as good as we are going to get. Anything else can be built on top of it, externally, and possibly merged back in. |
cmr
closed this
Aug 22, 2014
cmr
added
the
newcolumn1
label
Aug 22, 2014
This comment has been minimized.
This comment has been minimized.
|
Shaders become one of the major usability bottleneck of gfx-rs. Let's continue this discussion, even if the code for it will end up in a separate library. |
kvark
reopened this
Feb 2, 2015
kvark
added
difficulty: hard
and removed
difficulty: average
labels
Feb 2, 2015
This comment has been minimized.
This comment has been minimized.
|
This might be worth looking at: https://github.com/kmcallister/glassful |
This comment has been minimized.
This comment has been minimized.
|
Something to also think about is whether we want to support recompiling of shaders at runtime. |
This comment has been minimized.
This comment has been minimized.
kmcallister
commented
Feb 3, 2015
|
I would very much like that feature. |
This comment has been minimized.
This comment has been minimized.
|
Inspired by Glassful and @csherratt's example code from Reddit, I tried to develop it further. Here is an example of what I'd like to use (very roughly): /// uniforms
struct MyParams {
color: vec4,
}
/// vertex buffer 1
struct MyBuf1 {
pos: vec2,
}
/// vertex buffer 2
struct MyBuf2 {
tc: vec2,
}
let technique = glassful! {
struct Varying {
tc: vec2,
}
// @Position is a special vertex output, not sure if we can make it more sound
fn vertex(_params: MyParams, buf1: MyBuf1, buf2: MyBuf2) -> (@Position, Varying) {
(vec4(buf1.pos, 0.0, 1.0), Varying { tc: buf2.tc })
}
fn fragment(params: MyParams, _var: Varying) -> vec4 {
params.color
}
static pass0 = pass(vertex, fragment);
};
...
let program = device.link_program(&technique.pass0).unwrap();The implementation doesn't seem trivial. Here are the biggest problems that I see:
Any ideas, feedback, suggestions - please let me know. |
This comment has been minimized.
This comment has been minimized.
ghost
commented
Feb 8, 2015
|
I have been playing around with this a bit in rusterize. I'm not sure we even need @position, we could just require the vertex sharer to fill slot 0 of the tuple with the position. If it is not a // Placing a variable in a Flat<T> makes the compiler place a flat property around it for the fragment shader
fn vertex(_params: MyParams, buf1: MyBuf1, buf2: MyBuf2) -> (vec4, Flat<vec4>) {
(vec4(buf1.pos, 0.0, 1.0), buf2)
}
fn fragment(params: MyParams, (position, color): (vec4, vec4)) -> vec4 {
color
}This can be a bit hairy of you add to many varying: // Placing a variable in a Flat<T> makes the compiler place a flat property around it for the fragment shader
fn vertex(_params: MyParams, buf1: MyBuf1, buf2: MyBuf2) -> (vec4, vec3, vec2) {
(vec4(buf1.pos, 0.0, 1.0), buf1.normal, buf1.texture)
}
fn fragment(params: MyParams, (position, normal, color): (vec4, vec3, vec2)) -> vec4 {
color
}The strategy I have for I don't image traits are going to be a nice way to actually implement this for |
This comment has been minimized.
This comment has been minimized.
|
@csherratt so your vertex output position is implicit. We can't extend this approach to other special inputs/outputs, because many of them are optional (like. |
This comment has been minimized.
This comment has been minimized.
ghost
commented
Feb 9, 2015
|
There are quite a few you are right: https://www.opengl.org/wiki/Built-in_Variable_%28GLSL%29 The idea of using custom types for these works well in my mind. If you add one to the tuple, output struct we can easily find it. I guess for input it would not be much harder, but we do lose a bit of the input struct is the output struct. |
kvark
added
the
value: strategic
label
Feb 14, 2015
This comment has been minimized.
This comment has been minimized.
|
Something from g-truck about SPIR-V: http://www.g-truc.net/post-0714.html |
This comment has been minimized.
This comment has been minimized.
|
I so really want Vulcan/SPIR-V now!!! |
This comment has been minimized.
This comment has been minimized.
|
Note that SPIR-V specification is available, so while we are not able to test anything, we could start writing a translator. |
This comment has been minimized.
This comment has been minimized.
|
Current state of the SPIR-V ecosystem:
With the upcoming Vulkan backend a SPIR-V based shader compilation pipeline (e.g. GLSL -> SPIR-V -> backend(+ metadata)) might be interesting. |
This comment has been minimized.
This comment has been minimized.
|
bgfx has a solution using a C preprocessor to generate HLSL and GLSL (and thus SPIR-V) from a GLSL-like language -- it might be worth looking into. See https://bkaradzic.github.io/bgfx/tools.html#shader-compiler-shaderc |
This comment has been minimized.
This comment has been minimized.
|
This initiative on 3d portability from the Khronos Group can be interesting: |
This comment has been minimized.
This comment has been minimized.
|
I've found an SPIR-V 1.1 implementation in rust: https://github.com/google/rspirv This would allow to easily create some macros to write shaders in rust that generate SPIR-V, and from there to the final shader language. For that last step, there is already an experimental tool: Update: Include the cross tool |
This comment has been minimized.
This comment has been minimized.
|
Experience from inspirv-rust: The goal of this project is/was to generate SPIR-V binaries from Rust via MIR. What worked: example
Issues:
Future possibilities: |
This comment has been minimized.
This comment has been minimized.
FWIW we want to fix these problems and ship a Cretonne backend within a year, hopefully. It'd be nice to have more discussions and organization on these issues, but we (the Rust compiler team) have been spread thin for a while and it's showing. |
This comment has been minimized.
This comment has been minimized.
|
@eddyb Thanks for chiming in! |
This comment has been minimized.
This comment has been minimized.
|
For structured CFG, the Relooper algorithm emscripten uses (used?) is probably a good starting point - not sure if SPIR-V is better than JS at this but at least it's still a CFG. |
This comment has been minimized.
This comment has been minimized.
|
triaged: still important to provide a nice shading language that would compile to SPIR-V, likely as a separate library. |
This comment has been minimized.
This comment has been minimized.
|
The ecosystem issue has been raised in rust-gamedev/wg#23 |
cmr commentedJul 5, 2014
Different graphics APIs have their own shading languages or ideas for what a shading language should be. In our quest to support multiple backend APIs, we need a way to unify these.