-
Notifications
You must be signed in to change notification settings - Fork 54
Make the doc so that it explains Rust-GPU as something in itself, not by comparing to other GPU languages (like GLSL) #248
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
Comments
I want to extend this topic. I recently was trying to setup some very basic shaders and getting mesh rendering to work, but there were no relevant examples. For my background, I am decently familiar with shaders and memory binding from the gpu in general, but I couldn't seem to find any documentation on the basics. I read through all of the examples, and the shadertoys examples, trying to find out what I thought should be very simple:
After a bunch of trial and error this worked: use spirv_std::glam::{Vec3, Vec4};
use spirv_std::spirv;
#[allow(dead_code)]
#[spirv(fragment)]
pub fn main_fs(in_original_pos: Vec3, output: &mut Vec4) {
let mut mapped = (in_original_pos + 1.0) / 2.0;
mapped.z = 0.0;
*output = mapped.extend(1.0);
}
#[allow(dead_code)]
#[spirv(vertex)]
pub fn main_vs(
position: Vec3,
#[spirv(position, invariant)] pos: &mut Vec4,
out_original_pos: &mut Vec3,
) {
*pos = position.extend(1.0);
*out_original_pos = position;
} But I am left with questions. What is the magic behind picking How does it wire up the A lot of the basic information on how to use rust-gpu to make functinoal shaders is missing still. |
These are common early blockers, very understandably. This kind of stuff definitely should be upfront in documentation somewhere. I think a lot of this used to be documented on the
Here's some annotated vertex, fragment, and compute shader signatures #[spirv(vertex)]
pub fn raster_simple_vs(
// Builtin inputs
#[spirv(instance_index)] instance_index: u32,
#[spirv(vertex_index)] vid: u32,
// VS pipeline inputs, owned args in order of definition in signature
in_pos: Vec3, // position 0
// descriptors, i.e. buffers, images, etc
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)]
instance_transforms: &[InstanceTransform],
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)]
instance_constants: &[InstanceDynamicParameters],
#[spirv(storage_buffer, descriptor_set = 1, binding = 0)] meshes: &[GpuMeshDescriptor],
#[spirv(storage_buffer, descriptor_set = 1, binding = 1)] vertices: &mut [u32], // ByteAddressBuffer
#[spirv(uniform, descriptor_set = 2, binding = 0)] frame_constants: &FrameConstants,
#[spirv(storage_buffer, descriptor_set = 2, binding = 2)] materials_dyn: &[MeshMaterial],
// VS pipeline outputs, &mut args in order of definition in signature
out_color: &mut Vec3, // position 0
out_normal: &mut Vec3, // position 1
#[spirv(flat)] out_material_id: &mut u32, // etc
#[spirv(flat)] out_instance_index: &mut u32,
out_vs_pos: &mut Vec3,
out_prev_vs_pos: &mut Vec3,
out_uv: &mut Vec2,
// Builtin VS pipeline output
#[spirv(position, invariant)] builtin_pos: &mut Vec4,
) {
...
}
#[spirv(fragment)]
pub fn raster_simple_fs(
// FS pipeline inputs, these map *by order* to the outputs from the VS above
color: Vec3,
normal_ws: Vec3,
#[spirv(flat)] material_id: u32,
#[spirv(flat)] instance_index: u32,
vs_pos: Vec3,
prev_vs_pos: Vec3,
uv: Vec2,
// descriptors
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)]
instance_transforms: &[InstanceTransform],
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)]
instance_constants: &[InstanceDynamicParameters],
#[spirv(storage_buffer, descriptor_set = 1, binding = 0)] meshes: &[GpuMeshDescriptor],
#[spirv(storage_buffer, descriptor_set = 1, binding = 1)] vertices: &[u32], // ByteAddressBuffer
#[spirv(storage_buffer, descriptor_set = 2, binding = 2)] materials_dyn: &[MeshMaterial],
#[spirv(descriptor_set = 1, binding = 5)] bindless_textures: &RuntimeArray<
Image!(2D, type=f32, sampled=true),
>,
#[spirv(descriptor_set = 0, binding = 33)] sampler_llr: &Sampler,
#[spirv(descriptor_set = 0, binding = 32)] sampler_lnc: &Sampler,
#[spirv(uniform, descriptor_set = 2, binding = 0)] frame_constants: &FrameConstants,
// specialization constant inputs
#[spirv(spec_constant(id = 0, default = 0))] custom_shader: u32,
#[spirv(spec_constant(id = 1, default = 0))] use_alpha_masking: u32,
// builtin inputs
#[spirv(front_facing)] front_facing: bool,
// FS pipeline outputs, these correspond to a fragment write into a *bound render target*, *by order*
out_view_normal: &mut Vec4,
out_gbuffer: &mut Vec4,
out_velocity: &mut Vec4,
) {
...
}
#[spirv(compute(threads(256)))]
pub fn calc_adaptive_lum(
// no pipeline inputs/outputs here in a compute shader..
// descriptor inputs
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] inout_histogram: &mut [u32],
#[spirv(descriptor_set = 0, binding = 1)] prev_log2_lum_tex: &Image!(2D, type=f32, sampled=true),
#[spirv(descriptor_set = 0, binding = 2)] output_tex: &Image!(
2D,
format = rgba16f,
sampled = false
),
#[spirv(uniform, descriptor_set = 0, binding = 3)] constants: &AdaptiveConstants,
// buffers placed in workgroup local storage
#[spirv(workgroup)] shared_sum_buffer: &mut [f32; LUMINANCE_HISTOGRAM_BIN_COUNT],
#[spirv(workgroup)] shared_weight_sum_buffer: &mut [f32; LUMINANCE_HISTOGRAM_BIN_COUNT],
// builtin input
#[spirv(local_invocation_index)] idx: u32,
) {
...
} |
Fantastic, thanks so much. It's what I ended up discovering via reverse engineering but I wish I had this information to save some frustration at the start. This is good information which would be great to have in the repository with some shaders. |
I'll start of by saying that I am familiar with Rust, know a bit about how GPU work but have not programmed on GPU ever before, as that can explain some of the remarks I'm about to make.
My problem
I was reading through The Dev guide on writing shaders. I know there are other issues describing the fact that the doc is old / kinda obsolete, but I wanted to touch on something else.
The doc seems to make a lot of assumptions on previous knowledge of those reading said doc, this is apparent in multiple places:
In particular on this second point, this is nice for people that have knowledge of those other languages; but for people like me that do not have this knowledge, it does not suffice as an explanation. For example, when explaining the
flat
keyword:"The flat attribute corresponds to the flat keyword in glsl - in other words, the data is not interpolated across the triangle when invoking the fragment shader."
I can kinda understand what that means, but it's a bit succinct.
Some other keywords are explained less than this:
"The invariant attribute corresponds to the invariant keyword in glsl. It can only be applied to output variables."
This doesn't tell me much about what that is.
Now, I understand that this is very much a work in progress, and that for early adopters previous knowledge might be required to be able to get into it. However, on the website for rust-gpu, one of the first paragraphs states:
"There is no longer a need to learn a GPU-specific programming language. You can write both CPU and GPU code in Rust, leveraging your existing Rust knowledge and maintaining a consistent development experience"
With that goal in mind, i think it would be good to write the doc in a way that doesn't assume previous knowledge of other GPU languages. Of course, keeping the comparison with other GPU languages is a good thing, more information on that is not a bad thing.
Ideas
I have given a few examples, but I can provide the complete list of places I think could be improved if that is something the people working on this are interested in.
If this is more of a case of "it's too early for people without previous knowledge to start using", then feel free to close the issue, but I would very much like to try to use on my own projects (namely a ray tracer I wrote a year back and that i would like to use GPU on).
The text was updated successfully, but these errors were encountered: