You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Make Scope and Semantics normal arguments rather than const generics #414
Subjectively, three u32s that need to be composed in a very particular way are quite ugly.
Consider changing API to use normal types for these arguments, so we can all enjoy autocomplete in IDE, better formatting and implement ability to combine semantics variants, like this:
let position_in_bucket = unsafe{atomic_i_add(
bucket_count,1,Scope::QueueFamily,Semantics::None,)};control_barrier(Scope::Workgroup,Scope::Workgroup,Semantics::WorkgroupMemory | Semantics::AcquireRelease,);
The result of Semantics::WorkgroupMemory | Semantics::AcquireRelease can be Semantics::Combined(u32) for example, with Debug implementation overridden to render human-readable set of enabled flags.
Alternatively, a builder pattern could be used for Semantics with const fn to have guarantees of sane composition in case some invariants fundamentally do not make sense.
At some point non-integer const generics will become available, but even then I see no benefit from const generics for this particular use case.
This is in interesting constraint. I believe it'll be possible to use const generics with arbitrary types in the future, but we're not there yet (or maybe codegen backend can opt-in into this experimental feature already given the narrow scope?).
I'm wondering if const {} can be exploited here somehow and/or #[inline(always)] (I'm just brainstorming here, but the intuition is that at some abstraction level arguments will become inlined constants). Or maybe special-case these functions for compiler somehow such that it is a normal argument, but compiler knows the arguments must be known at compile time. There are a few tricks of this nature in Rust standard library that are not directly implementable in normal Rust code.
Or maybe replace these functions with macros, such that it is possible to use normal types and have compile-time guarantees of type safety.
In fact there are so many const generics, that we can't reasonably assume users will correctly specify them. So the Image! macro exists to correctly specify them, and we have some common image types typedef'ed:
Activity
Firestar99 commentedon Oct 10, 2025
Scope and Memory Semantics args are impossible
Scope and Memory Semantics must be a constant and cannot be runtime dynamic args, see spec:
https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_validation_rules_for_shader_capabilities
Which forces us to use const generics and forward them to the
asm!block as constants:rust-gpu/crates/spirv-std/src/arch/barrier.rs
Lines 36 to 53 in 7e15027
I also tried replacing the
OpConstantwith ordinaryOpLoads, but that fails validation:So we're unfortunately tied to constants by the spec.
nazar-pc commentedon Oct 10, 2025
This is in interesting constraint. I believe it'll be possible to use const generics with arbitrary types in the future, but we're not there yet (or maybe codegen backend can opt-in into this experimental feature already given the narrow scope?).
I'm wondering if
const {}can be exploited here somehow and/or#[inline(always)](I'm just brainstorming here, but the intuition is that at some abstraction level arguments will become inlined constants). Or maybe special-case these functions for compiler somehow such that it is a normal argument, but compiler knows the arguments must be known at compile time. There are a few tricks of this nature in Rust standard library that are not directly implementable in normal Rust code.Or maybe replace these functions with macros, such that it is possible to use normal types and have compile-time guarantees of type safety.
Firestar99 commentedon Oct 10, 2025
Alternatives
Const generics with enums / ADT types
This would solve this issues at once, but it looks like rustc is still quite a ways off...
Wrapping functions
You've already mentioned them, they are probably the easiest way to wrap the const complexity
rust-gpu/crates/spirv-std/src/arch/barrier.rs
Lines 113 to 122 in 7e15027
Image! macro
Images are similarly full of const generics that are effectively enums:
rust-gpu/crates/spirv-std/src/image.rs
Lines 103 to 112 in adfe6b8
In fact there are so many const generics, that we can't reasonably assume users will correctly specify them. So the
Image!macro exists to correctly specify them, and we have some common image types typedef'ed:rust-gpu/crates/spirv-std/src/image.rs
Lines 30 to 35 in adfe6b8
Type wrapping
This is something I've used in my own engine with great success, and could be a model for rust-gpu as well?
macro_rules!asm!should hopefully also accept as a const:@eddyb @LegNeato @schell @nnethercote Design thoughts on where we should head to in the future?
adt_const_paramsfor intrinsics #607 as a duplicate of this issuenazar-pc commentedon Aug 4, 2026
Implemented
adt_const_paramsalternative in #635