Skip to content

Commit

Permalink
Add vector_insert_dynamic (#411)
Browse files Browse the repository at this point in the history
* Add vector_insert_dynamic and copy_object

* Update arch.rs

* Update basic.rs

* Update arch.rs

* Update spirv_type_constraints.rs
  • Loading branch information
XAMPPRocky authored Feb 11, 2021
1 parent 2f9d4d8 commit c10a6c0
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 6 deletions.
1 change: 1 addition & 0 deletions crates/rustc_codegen_spirv/src/builder/spirv_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> {
) -> Option<Word> {
use crate::spirv_type_constraints::{instruction_signatures, InstSig, TyListPat, TyPat};

#[derive(Debug)]
struct Mismatch;

/// Recursively match `ty` against `pat`, returning one of:
Expand Down
13 changes: 8 additions & 5 deletions crates/rustc_codegen_spirv/src/spirv_type_constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
use rspirv::spirv::Op;

/// Pattern for a SPIR-V type, dynamic representation (see module-level docs).
#[derive(PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
pub enum TyPat<'a> {
/// Unconstrained type.
Any,
Expand Down Expand Up @@ -97,7 +97,7 @@ impl TyPat<'_> {
///
/// "Type lists" are used for `OpTypeStruct` fields, `OpTypeFunction` parameters,
/// and operand types of instructions signatures.
#[derive(PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
pub enum TyListPat<'a> {
/// Unconstrained type list (any length, and the types can freely vary).
Any,
Expand Down Expand Up @@ -126,7 +126,7 @@ impl TyListPat<'_> {
}

/// Instruction "signature", dynamic representation (see module-level docs).
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub struct InstSig<'a> {
/// Patterns for the complete list of types of the instruction's value operands.
pub inputs: &'a TyListPat<'a>,
Expand Down Expand Up @@ -371,8 +371,11 @@ pub fn instruction_signatures(op: Op) -> Option<&'static [InstSig<'static>]> {
// 3.37.12. Composite Instructions
Op::VectorExtractDynamic => sig! { (Vector(T), _) -> T },
Op::VectorInsertDynamic => sig! {
// FIXME(eddyb) missing equality constraint between input and output vectors.
(Vector(T), T, _) -> Vector(T)
// FIXME(eddyb) was `(Vector(T), T, _) -> Vector(T)` but that was
// missing an equality constraint between input and output vectors;
// we should use `(Vector(T, N), T, _) -> Vector(T, N)`, or constrain
// input and output vectors to have the same type some other way.
(T, _, _) -> T
},
Op::VectorShuffle => sig! { (Vector(T), Vector(T)) -> Vector(T) },
Op::CompositeConstruct => sig! {
Expand Down
14 changes: 14 additions & 0 deletions crates/spirv-builder/src/test/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,20 @@ pub fn main() {
"#);
}

#[test]
fn vector_insert_dynamic() {
val(r#"
#[allow(unused_attributes)]
#[spirv(fragment)]
pub fn main() {
let vector = glam::Vec2::new(1.0, 2.0);
let expected = glam::Vec2::new(1.0, 3.0);
let new_vector = unsafe { spirv_std::arch::vector_insert_dynamic(vector, 1, 3.0) };
assert!(new_vector == expected);
}
"#);
}

#[test]
fn mat3_vec3_multiply() {
val(r#"
Expand Down
30 changes: 30 additions & 0 deletions crates/spirv-std/src/arch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,33 @@ pub unsafe fn vector_extract_dynamic<T: Scalar, V: Vector<T>>(vector: V, index:

result
}

/// Make a copy of a vector, with a single, variably selected,
/// component modified.
///
/// # Safety
/// Behavior is undefined if `index`’s value is greater than or equal to the
/// number of components in `vector`.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpVectorInsertDynamic")]
#[inline]
pub unsafe fn vector_insert_dynamic<T: Scalar, V: Vector<T>>(
vector: V,
index: usize,
element: T,
) -> V {
let mut result = V::default();

asm! {
"%vector = OpLoad _ {vector}",
"%element = OpLoad _ {element}",
"%new_vector = OpVectorInsertDynamic _ %vector %element {index}",
"OpStore {result} %new_vector",
vector = in(reg) &vector,
index = in(reg) index,
element = in(reg) &element,
result = in(reg) &mut result,
}

result
}
2 changes: 1 addition & 1 deletion crates/spirv-std/src/vector.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// Abstract trait representing a SPIR-V vector type.
pub trait Vector<T: crate::scalar::Scalar>: crate::sealed::Sealed {}
pub trait Vector<T: crate::scalar::Scalar>: crate::sealed::Sealed + Default {}

impl Vector<bool> for glam::BVec2 {}
impl Vector<bool> for glam::BVec3 {}
Expand Down

0 comments on commit c10a6c0

Please sign in to comment.