Skip to content

Commit c10a6c0

Browse files
authored
Add vector_insert_dynamic (#411)
* Add vector_insert_dynamic and copy_object * Update arch.rs * Update basic.rs * Update arch.rs * Update spirv_type_constraints.rs
1 parent 2f9d4d8 commit c10a6c0

File tree

5 files changed

+54
-6
lines changed

5 files changed

+54
-6
lines changed

crates/rustc_codegen_spirv/src/builder/spirv_asm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> {
461461
) -> Option<Word> {
462462
use crate::spirv_type_constraints::{instruction_signatures, InstSig, TyListPat, TyPat};
463463

464+
#[derive(Debug)]
464465
struct Mismatch;
465466

466467
/// Recursively match `ty` against `pat`, returning one of:

crates/rustc_codegen_spirv/src/spirv_type_constraints.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
use rspirv::spirv::Op;
2323

2424
/// Pattern for a SPIR-V type, dynamic representation (see module-level docs).
25-
#[derive(PartialEq, Eq)]
25+
#[derive(Debug, PartialEq, Eq)]
2626
pub enum TyPat<'a> {
2727
/// Unconstrained type.
2828
Any,
@@ -97,7 +97,7 @@ impl TyPat<'_> {
9797
///
9898
/// "Type lists" are used for `OpTypeStruct` fields, `OpTypeFunction` parameters,
9999
/// and operand types of instructions signatures.
100-
#[derive(PartialEq, Eq)]
100+
#[derive(Debug, PartialEq, Eq)]
101101
pub enum TyListPat<'a> {
102102
/// Unconstrained type list (any length, and the types can freely vary).
103103
Any,
@@ -126,7 +126,7 @@ impl TyListPat<'_> {
126126
}
127127

128128
/// Instruction "signature", dynamic representation (see module-level docs).
129-
#[derive(Copy, Clone)]
129+
#[derive(Copy, Clone, Debug)]
130130
pub struct InstSig<'a> {
131131
/// Patterns for the complete list of types of the instruction's value operands.
132132
pub inputs: &'a TyListPat<'a>,
@@ -371,8 +371,11 @@ pub fn instruction_signatures(op: Op) -> Option<&'static [InstSig<'static>]> {
371371
// 3.37.12. Composite Instructions
372372
Op::VectorExtractDynamic => sig! { (Vector(T), _) -> T },
373373
Op::VectorInsertDynamic => sig! {
374-
// FIXME(eddyb) missing equality constraint between input and output vectors.
375-
(Vector(T), T, _) -> Vector(T)
374+
// FIXME(eddyb) was `(Vector(T), T, _) -> Vector(T)` but that was
375+
// missing an equality constraint between input and output vectors;
376+
// we should use `(Vector(T, N), T, _) -> Vector(T, N)`, or constrain
377+
// input and output vectors to have the same type some other way.
378+
(T, _, _) -> T
376379
},
377380
Op::VectorShuffle => sig! { (Vector(T), Vector(T)) -> Vector(T) },
378381
Op::CompositeConstruct => sig! {

crates/spirv-builder/src/test/basic.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,20 @@ pub fn main() {
383383
"#);
384384
}
385385

386+
#[test]
387+
fn vector_insert_dynamic() {
388+
val(r#"
389+
#[allow(unused_attributes)]
390+
#[spirv(fragment)]
391+
pub fn main() {
392+
let vector = glam::Vec2::new(1.0, 2.0);
393+
let expected = glam::Vec2::new(1.0, 3.0);
394+
let new_vector = unsafe { spirv_std::arch::vector_insert_dynamic(vector, 1, 3.0) };
395+
assert!(new_vector == expected);
396+
}
397+
"#);
398+
}
399+
386400
#[test]
387401
fn mat3_vec3_multiply() {
388402
val(r#"

crates/spirv-std/src/arch.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,33 @@ pub unsafe fn vector_extract_dynamic<T: Scalar, V: Vector<T>>(vector: V, index:
2727

2828
result
2929
}
30+
31+
/// Make a copy of a vector, with a single, variably selected,
32+
/// component modified.
33+
///
34+
/// # Safety
35+
/// Behavior is undefined if `index`’s value is greater than or equal to the
36+
/// number of components in `vector`.
37+
#[spirv_std_macros::gpu_only]
38+
#[doc(alias = "OpVectorInsertDynamic")]
39+
#[inline]
40+
pub unsafe fn vector_insert_dynamic<T: Scalar, V: Vector<T>>(
41+
vector: V,
42+
index: usize,
43+
element: T,
44+
) -> V {
45+
let mut result = V::default();
46+
47+
asm! {
48+
"%vector = OpLoad _ {vector}",
49+
"%element = OpLoad _ {element}",
50+
"%new_vector = OpVectorInsertDynamic _ %vector %element {index}",
51+
"OpStore {result} %new_vector",
52+
vector = in(reg) &vector,
53+
index = in(reg) index,
54+
element = in(reg) &element,
55+
result = in(reg) &mut result,
56+
}
57+
58+
result
59+
}

crates/spirv-std/src/vector.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/// Abstract trait representing a SPIR-V vector type.
2-
pub trait Vector<T: crate::scalar::Scalar>: crate::sealed::Sealed {}
2+
pub trait Vector<T: crate::scalar::Scalar>: crate::sealed::Sealed + Default {}
33

44
impl Vector<bool> for glam::BVec2 {}
55
impl Vector<bool> for glam::BVec3 {}

0 commit comments

Comments
 (0)