Skip to content

Commit

Permalink
Operators
Browse files Browse the repository at this point in the history
  • Loading branch information
nanoqsh committed Jan 3, 2024
1 parent 48091ab commit 875348f
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 22 deletions.
9 changes: 8 additions & 1 deletion dunge/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ pub struct Context(Arc<State>);

impl Context {
pub async fn new() -> Result<Self, Error> {
let instance = wgpu::Instance::default();
use wgpu::{Backends, Instance, InstanceDescriptor};

let desc = InstanceDescriptor {
backends: Backends::PRIMARY,
..Default::default()
};

let instance = Instance::new(desc);
let state = State::new(&instance).await?;
Ok(Self(Arc::new(state)))
}
Expand Down
2 changes: 1 addition & 1 deletion dunge/tests/triangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn render() -> Result<(), Error> {
const THIRD: f32 = consts::TAU / 3.;

let triangle = |Index(index): Index| {
let [x, y] = sl::share(sl::f32(index) * THIRD);
let [x, y] = sl::thunk(sl::f32(index) * THIRD);
Out {
place: sl::vec4(sl::cos(x), sl::sin(y), 0., 1.),
color: Vec4::new(1., 0., 0., 1.),
Expand Down
109 changes: 89 additions & 20 deletions dunge_shader/src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,50 +125,121 @@ const fn ret<A, T>(a: A) -> Ret<A, T> {
Ret { a, t: PhantomData }
}

impl<A> ops::Add<Ret<A, Self>> for f32 {
type Output = Ret<Binary<Self, Ret<A, Self>>, Self>;

fn add(self, b: Ret<A, Self>) -> Self::Output {
ret(Binary {
a: self,
b,
op: Op::Add,
})
}
}

impl<A> ops::Add<f32> for Ret<A, f32> {
type Output = Ret<Binary<Self, f32>, f32>;

fn add(self, b: f32) -> Self::Output {
ret(Binary {
a: self,
b,
op: Op::Add,
})
}
}

impl<A> ops::Sub<Ret<A, Self>> for f32 {
type Output = Ret<Binary<Self, Ret<A, Self>>, Self>;

fn sub(self, b: Ret<A, Self>) -> Self::Output {
ret(Binary {
a: self,
b,
op: Op::Sub,
})
}
}

impl<A> ops::Sub<f32> for Ret<A, f32> {
type Output = Ret<Binary<Self, f32>, f32>;

fn sub(self, b: f32) -> Self::Output {
ret(Binary {
a: self,
b,
op: Op::Sub,
})
}
}

impl<A> ops::Mul<Ret<A, Self>> for f32 {
type Output = Ret<Mul<Self, Ret<A, Self>>, Self>;
type Output = Ret<Binary<Self, Ret<A, Self>>, Self>;

fn mul(self, b: Ret<A, Self>) -> Self::Output {
ret(Mul { a: self, b })
ret(Binary {
a: self,
b,
op: Op::Mul,
})
}
}

impl<A> ops::Mul<f32> for Ret<A, f32> {
type Output = Ret<Mul<Self, f32>, f32>;
type Output = Ret<Binary<Self, f32>, f32>;

fn mul(self, b: f32) -> Self::Output {
ret(Mul { a: self, b })
ret(Binary {
a: self,
b,
op: Op::Mul,
})
}
}

impl<A, O> ops::Mul<f32> for Ret<A, O>
where
O: types::Vector,
{
type Output = Ret<Mul<Self, f32>, O>;
type Output = Ret<Binary<Self, f32>, O>;

fn mul(self, b: f32) -> Self::Output {
ret(Mul { a: self, b })
ret(Binary {
a: self,
b,
op: Op::Mul,
})
}
}

impl<A, O> ops::Mul<Ret<A, O>> for f32
where
O: types::Vector,
{
type Output = Ret<Mul<Self, Ret<A, O>>, O>;
type Output = Ret<Binary<Self, Ret<A, O>>, O>;

fn mul(self, b: Ret<A, O>) -> Self::Output {
ret(Mul { a: self, b })
ret(Binary {
a: self,
b,
op: Op::Mul,
})
}
}

pub struct Mul<A, B> {
enum Op {
Add,
Sub,
Mul,
}

pub struct Binary<A, B> {
a: A,
b: B,
op: Op,
}

impl<A, B, O, E> Eval<E> for Ret<Mul<A, B>, O>
impl<A, B, O, E> Eval<E> for Ret<Binary<A, B>, O>
where
A: Eval<E>,
B: Eval<E>,
Expand All @@ -179,7 +250,7 @@ where
fn eval(self, en: &mut E) -> Expr {
let x = self.a.a.eval(en);
let y = self.a.b.eval(en);
en.get().binary(Op::Mul, x, y)
en.get().binary(self.a.op, x, y)
}
}

Expand Down Expand Up @@ -445,22 +516,22 @@ where
}
}

pub fn share<A, E, const N: usize>(a: A) -> [Ret<Share<A>, A::Out>; N]
pub fn thunk<A, E, const N: usize>(a: A) -> [Ret<Thunk<A>, A::Out>; N]
where
A: Eval<E>,
{
let state = State::Eval(a);
let inner = Rc::new(Cell::new(state));
array::from_fn(|_| ret(Share(Rc::clone(&inner))))
array::from_fn(|_| ret(Thunk(Rc::clone(&inner))))
}

pub struct Share<A>(Rc<Cell<State<A>>>);
pub struct Thunk<A>(Rc<Cell<State<A>>>);

impl<A, O, E> Eval<E> for Ret<Share<A>, O>
impl<A, O, E> Eval<E> for Ret<Thunk<A>, O>
where
A: Eval<E>,
{
type Out = A::Out;
type Out = O;

fn eval(self, en: &mut E) -> Expr {
match self.a.0.replace(State::None) {
Expand Down Expand Up @@ -931,10 +1002,6 @@ impl Argument {
}
}

enum Op {
Mul,
}

type Args<'a> = dyn Iterator<Item = Argument> + 'a;

pub struct Entry {
Expand Down Expand Up @@ -999,6 +1066,8 @@ impl Entry {

fn binary(&mut self, op: Op, a: Expr, b: Expr) -> Expr {
let op = match op {
Op::Add => BinaryOperator::Add,
Op::Sub => BinaryOperator::Subtract,
Op::Mul => BinaryOperator::Multiply,
};

Expand Down

0 comments on commit 875348f

Please sign in to comment.