Nuke arithmetic.rs (#666)

This commit is contained in:
Ashley Hauck 2021-06-15 09:43:13 +02:00 committed by GitHub
parent f7ac6a09e7
commit 04dfa80266
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 0 additions and 668 deletions

View File

@ -5,14 +5,12 @@
//! no additional safety checks beyond type-checking. //! no additional safety checks beyond type-checking.
use crate::{scalar::Scalar, vector::Vector}; use crate::{scalar::Scalar, vector::Vector};
mod arithmetic;
mod barrier; mod barrier;
mod demote_to_helper_invocation_ext; mod demote_to_helper_invocation_ext;
mod derivative; mod derivative;
mod primitive; mod primitive;
mod ray_tracing; mod ray_tracing;
pub use arithmetic::*;
pub use barrier::*; pub use barrier::*;
pub use demote_to_helper_invocation_ext::*; pub use demote_to_helper_invocation_ext::*;
pub use derivative::*; pub use derivative::*;

View File

@ -1,502 +0,0 @@
// The new preferred style is still to use `unsafe` blocks in `unsafe` functions
// but the compiler/clippy hasn't caught up to that style yet, so we just
// disable the lint.
#![allow(unused_unsafe)]
use crate::{
float::Float,
integer::{Integer, SignedInteger, UnsignedInteger},
vector::Vector,
};
/// Signed-integer subtract of `operand` from zero. Results are computed
/// per component.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpSNegate")]
#[inline]
pub fn s_negate_vector<S, V, const N: usize>(operand: V) -> V
where
S: SignedInteger,
V: Vector<S, N>,
{
let mut result = V::default();
unsafe {
asm! {
"%operand = OpLoad typeof*{operand} {operand}",
"%result = OpSNegate typeof*{operand} %operand",
"OpStore {result} %result",
operand = in(reg) &operand,
result = in(reg) &mut result,
}
}
result
}
/// Floating-point subtract of `operand` from zero. Results are computed
/// per component.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpFNegate")]
#[inline]
pub fn f_negate_vector<F, V, const N: usize>(operand: V) -> V
where
F: Float,
V: Vector<F, N>,
{
let mut result = V::default();
unsafe {
asm! {
"%operand = OpLoad typeof*{operand} {operand}",
"%result = OpFNegate typeof*{operand} %operand",
"OpStore {result} %result",
operand = in(reg) &operand,
result = in(reg) &mut result,
}
}
result
}
/// Integer addition of `x` and `y`. Results are computed per component.
///
/// # Safety
/// The resulting value is undefined if the computation would result
/// in overflow.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpIAdd")]
#[inline]
pub unsafe fn i_add_vector<I, V, const LEN: usize>(x: V, y: V) -> V
where
I: Integer,
V: Vector<I, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpIAdd typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Floating-point addition of `x` and `y`. Results are computed per component.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpFAdd")]
#[inline]
pub fn f_add_vector<F, V, const LEN: usize>(x: V, y: V) -> V
where
F: Float,
V: Vector<F, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpFAdd typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Signed-integer subtract of `x` from `y`. Results are computed per component.
///
/// # Safety
/// The resulting value is undefined if the computation would result
/// in underflow.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpISub")]
#[inline]
pub fn i_sub_vector<I, V, const LEN: usize>(x: V, y: V) -> V
where
I: Integer,
V: Vector<I, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpISub typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Floating-point subtract of `x` from `y`. Results are computed per component.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpFSub")]
#[inline]
pub fn f_sub_vector<F, V, const LEN: usize>(x: V, y: V) -> V
where
F: Float,
V: Vector<F, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpFSub typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Integer multiplication of `x` and `y`. Results are computed per component.
///
/// # Safety
/// The resulting value is undefined if the computation would result
/// in underflow.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpIMul")]
#[inline]
pub fn i_mul_vector<I, V, const LEN: usize>(x: V, y: V) -> V
where
I: Integer,
V: Vector<I, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpIMul typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Floating-point multiplication of `x` and `y`. Results are computed
/// per component.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpFMul")]
#[inline]
pub fn f_mul_vector<F, V, const LEN: usize>(x: V, y: V) -> V
where
F: Float,
V: Vector<F, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpFMul typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Unsigned-integer division of `x` from `y`. Results are computed
/// per component.
///
/// # Safety
/// The resulting value is undefined if any component of `y` is `0`.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpUDiv")]
#[inline]
pub unsafe fn u_div_vector<I, V, const LEN: usize>(x: V, y: V) -> V
where
I: UnsignedInteger,
V: Vector<I, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpUDiv typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Signed-integer division of `x` from `y`. Results are computed
/// per component.
///
/// # Safety
/// The resulting value is undefined if any component of `y` is `0`, or if a
/// component of `y` is `-1` and the dividing component of `x` is
/// minimum representable value for its type, causing signed overflow.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpSDiv")]
#[inline]
pub unsafe fn s_div_vector<I, V, const LEN: usize>(x: V, y: V) -> V
where
I: SignedInteger,
V: Vector<I, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpSDiv typeof*{y} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Floating-point division of `x` from `y`. Results are computed
/// per component.
///
/// # Safety
/// The resulting value is undefined if any component of `y` is `0.0`.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpFDiv")]
#[inline]
pub fn f_div_vector<F, V, const LEN: usize>(x: V, y: V) -> V
where
F: Float,
V: Vector<F, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpFDiv typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Unsigned modulo operation of `x` modulo `y`. Results are computed
/// per component.
///
/// # Safety
/// The resulting value is undefined if `y` is `0`.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpUMod")]
#[inline]
pub fn u_mod_vector<I, V, const LEN: usize>(x: V, y: V) -> V
where
I: UnsignedInteger,
V: Vector<I, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpUMod typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Signed-integer remainder operation for getting the remainder from `x / y`
/// whose sign matches the sign of `x`.
///
/// # Safety
/// Behavior is undefined if `y` is 0, or if `y` is -1 and `x` is the minimum
/// representable value for the type, causing signed overflow.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpSRem")]
#[inline]
pub fn s_rem_vector<I, V, const LEN: usize>(x: V, y: V) -> V
where
I: SignedInteger,
V: Vector<I, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpSRem typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Signed-integer modulo operation from `x` modulo `y`, whose sign matches the
/// sign of `y`. Results are computed per component.
///
/// # Safety
/// Behavior is undefined if `y` is 0, or if `y` is -1 and `x` is the minimum
/// representable value for the type, causing signed overflow.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpSMod")]
#[inline]
pub fn s_mod_vector<I, V, const LEN: usize>(x: V, y: V) -> V
where
I: SignedInteger,
V: Vector<I, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpSMod typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Floating-point remainder operation for getting the remainder from `x / y`
/// whose sign matches the sign of `x`. Results are computed per component.
///
/// # Safety
/// Behavior is undefined if `y` is 0, or if `y` is -1 and `x` is the minimum
/// representable value for the type, causing signed overflow.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpFRem")]
#[inline]
pub fn f_rem_vector<F, V, const LEN: usize>(x: V, y: V) -> V
where
F: Float,
V: Vector<F, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpFRem typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Floating-point modulo operation from `x` modulo `y`, whose sign matches the
/// sign of `y`. Results are computed per component.
///
/// # Safety
/// Behavior is undefined if `y` is 0, or if `y` is -1 and `x` is the minimum
/// representable value for the type, causing signed overflow.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpFMod")]
#[inline]
pub fn f_mod_vector<F, V, const LEN: usize>(x: V, y: V) -> V
where
F: Float,
V: Vector<F, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%x = OpLoad typeof*{x} {x}",
"%y = OpLoad typeof*{y} {y}",
"%result = OpFMod typeof*{x} %x %y",
"OpStore {result} %result",
x = in(reg) &x,
y = in(reg) &y,
result = in(reg) &mut result,
}
}
result
}
/// Scale a floating-point `vector` by `scalar`. Each component of `vector` is
/// multiplied by `scalar`.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpVectorTimesScalar")]
#[inline]
pub fn vector_times_scalar<F, V, const LEN: usize>(vector: V, scalar: F) -> V
where
F: Float,
V: Vector<F, LEN>,
{
let mut result = V::default();
unsafe {
asm! {
"%vector = OpLoad typeof*{vector} {vector}",
"%scalar = OpLoad typeof*{scalar} {scalar}",
"%result = OpVectorTimesScalar typeof*{vector} %vector %scalar",
"OpStore {result} %result",
vector = in(reg) &vector,
scalar = in(reg) &scalar,
result = in(reg) &mut result,
}
}
result
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = 5.0;
let y = 2.0;
let vx = glam::Vec2::new(2.0, 5.0);
let vy = glam::Vec2::new(5.0, 2.0);
assert!(spirv_std::arch::f_add_vector(vx, vy) == glam::Vec2::new(7.0, 7.0));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = 10.0;
let y = 2.0;
let vx = glam::Vec2::new(10.0, 10.0);
let vy = glam::Vec2::new(2.0, 2.0);
assert!(spirv_std::arch::f_div_vector(vx, vy) == glam::Vec2::new(5.0, 5.0));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = 10.0;
let y = 2.0;
let vx = glam::Vec2::new(10.0, 10.0);
let vy = glam::Vec2::new(2.0, 2.0);
assert!(spirv_std::arch::f_mod_vector(vx, vy) == glam::Vec2::new(0.0, 0.0));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = 5.0;
let y = 2.0;
let vx = glam::Vec2::new(5.0, 2.0);
let vy = glam::Vec2::new(2.0, 5.0);
assert!(spirv_std::arch::f_mul_vector(vx, vy) == glam::Vec2::new(10.0, 10.0));
}

View File

@ -1,8 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let operand: f32 = -5.0;
let vector = glam::Vec2::new(-5.0, -0.0);
assert!(spirv_std::arch::f_negate_vector(vector) == glam::Vec2::new(5.0, 0.0));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = -10.0;
let y = -2.0;
let vx = glam::Vec2::new(-10.0, -10.0);
let vy = glam::Vec2::new(-2.0, -2.0);
assert!(spirv_std::arch::f_mod_vector(vx, vy) == glam::Vec2::new(-0.0, -0.0));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = 5.0;
let y = 5.0;
let vx = glam::Vec2::new(5.0, 7.0);
let vy = glam::Vec2::new(5.0, 7.0);
assert!(spirv_std::arch::f_sub_vector(vx, vy) == glam::Vec2::new(0.0, 0.0));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = 5;
let y = 2;
let vx = glam::IVec2::new(2, 5);
let vy = glam::IVec2::new(5, 2);
assert!(unsafe { spirv_std::arch::i_add_vector(vx, vy) } == glam::IVec2::new(7, 7));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = 5;
let y = 2;
let vx = glam::IVec2::new(5, 2);
let vy = glam::IVec2::new(2, 5);
assert!(spirv_std::arch::i_mul_vector(vx, vy) == glam::IVec2::new(10, 10));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = 5;
let y = 5;
let vx = glam::IVec2::new(5, 7);
let vy = glam::IVec2::new(5, 7);
assert!(spirv_std::arch::i_sub_vector(vx, vy) == glam::IVec2::new(0, 0));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = 10;
let y = 2;
let vx = glam::IVec2::new(10, 10);
let vy = glam::IVec2::new(2, 2);
assert!(unsafe { spirv_std::arch::s_div_vector(vx, vy) } == glam::IVec2::new(5, 5));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = 10;
let y = 2;
let vx = glam::IVec2::new(10, 10);
let vy = glam::IVec2::new(2, 2);
assert!(spirv_std::arch::s_mod_vector(vx, vy) == glam::IVec2::new(0, 0));
}

View File

@ -1,8 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let operand: i32 = -5;
let vector = glam::IVec2::new(-5, -0);
assert!(spirv_std::arch::s_negate_vector(vector) == glam::IVec2::new(5, 0));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x = -10;
let y = -2;
let vx = glam::IVec2::new(-10, -10);
let vy = glam::IVec2::new(-2, -2);
assert!(spirv_std::arch::s_rem_vector(vx, vy) == glam::IVec2::new(-0, -0));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x: u32 = 10;
let y = 2;
let vx = glam::UVec2::new(10, 10);
let vy = glam::UVec2::new(2, 2);
assert!(unsafe { spirv_std::arch::u_div_vector(vx, vy) } == glam::UVec2::new(5, 5));
}

View File

@ -1,10 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let x: u32 = 10;
let y = 2;
let vx = glam::UVec2::new(10, 10);
let vy = glam::UVec2::new(2, 2);
assert!(spirv_std::arch::u_mod_vector(vx, vy) == glam::UVec2::new(0, 0));
}

View File

@ -1,8 +0,0 @@
// build-pass
#[spirv(fragment)]
pub fn main() {
let vector = glam::Vec2::new(10.0, 10.0);
let scalar = 2.0;
assert!(spirv_std::arch::vector_times_scalar(vector, scalar) == glam::Vec2::new(20.0, 20.0));
}