-
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? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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: