naga-agal: Implement log, exp, pow, ddx, ddy, min, rsq, sge ops

This commit is contained in:
Mike Welsh 2023-04-06 11:47:54 -07:00 committed by Aaron Hill
parent 3be933d7c2
commit f97bb9c2f1
1 changed files with 83 additions and 2 deletions

View File

@ -7,8 +7,8 @@ use naga::{
}; };
use naga::{BinaryOperator, MathFunction}; use naga::{BinaryOperator, MathFunction};
use naga::{ use naga::{
Binding, Expression, Function, Handle, LocalVariable, Module, ScalarKind, Span, Statement, Binding, DerivativeAxis, Expression, Function, Handle, LocalVariable, Module, ScalarKind, Span,
Type, TypeInner, VectorSize, Statement, Type, TypeInner, VectorSize,
}; };
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
@ -1268,6 +1268,18 @@ impl<'a> NagaBuilder<'a> {
}); });
self.emit_dest_store(dest, div)?; self.emit_dest_store(dest, div)?;
} }
Opcode::Min => {
let source1 = self.emit_source_field_load(source1, true)?;
let source2 = self.emit_source_field_load(source2.assert_source_field(), true)?;
let max = self.evaluate_expr(Expression::Math {
fun: MathFunction::Min,
arg: source1,
arg1: Some(source2),
arg2: None,
arg3: None,
});
self.emit_dest_store(dest, max)?;
}
Opcode::Max => { Opcode::Max => {
let source1 = self.emit_source_field_load(source1, true)?; let source1 = self.emit_source_field_load(source1, true)?;
let source2 = self.emit_source_field_load(source2.assert_source_field(), true)?; let source2 = self.emit_source_field_load(source2.assert_source_field(), true)?;
@ -1315,6 +1327,17 @@ impl<'a> NagaBuilder<'a> {
}); });
self.emit_dest_store(dest, sqt)?; self.emit_dest_store(dest, sqt)?;
} }
Opcode::Rsq => {
let source = self.emit_source_field_load(source1, true)?;
let sqt = self.evaluate_expr(Expression::Math {
fun: MathFunction::InverseSqrt,
arg: source,
arg1: None,
arg2: None,
arg3: None,
});
self.emit_dest_store(dest, sqt)?;
}
Opcode::Crs => { Opcode::Crs => {
let source1 = let source1 =
self.emit_source_field_load_with_swizzle_out(source1, false, VectorSize::Tri)?; self.emit_source_field_load_with_swizzle_out(source1, false, VectorSize::Tri)?;
@ -1441,6 +1464,14 @@ impl<'a> NagaBuilder<'a> {
}); });
self.emit_dest_store(dest, neg)?; self.emit_dest_store(dest, neg)?;
} }
Opcode::Sge => {
let result = self.boolean_binary_op(
source1,
source2.assert_source_field(),
BinaryOperator::GreaterEqual,
)?;
self.emit_dest_store(dest, result)?;
}
Opcode::Slt => { Opcode::Slt => {
let result = self.boolean_binary_op( let result = self.boolean_binary_op(
source1, source1,
@ -1498,6 +1529,56 @@ impl<'a> NagaBuilder<'a> {
}); });
self.emit_dest_store(dest, abs)?; self.emit_dest_store(dest, abs)?;
} }
Opcode::Pow => {
let source1 = self.emit_source_field_load(source1, true)?;
let source2 = self.emit_source_field_load(source2.assert_source_field(), true)?;
let pow = self.evaluate_expr(Expression::Math {
fun: MathFunction::Pow,
arg: source1,
arg1: Some(source2),
arg2: None,
arg3: None,
});
self.emit_dest_store(dest, pow)?;
}
Opcode::Log => {
let source = self.emit_source_field_load(source1, true)?;
let log = self.evaluate_expr(Expression::Math {
fun: MathFunction::Log2,
arg: source,
arg1: None,
arg2: None,
arg3: None,
});
self.emit_dest_store(dest, log)?;
}
Opcode::Exp => {
let source = self.emit_source_field_load(source1, true)?;
let exp = self.evaluate_expr(Expression::Math {
fun: MathFunction::Exp2,
arg: source,
arg1: None,
arg2: None,
arg3: None,
});
self.emit_dest_store(dest, exp)?;
}
Opcode::Ddx => {
let source = self.emit_source_field_load(source1, true)?;
let derivative = self.evaluate_expr(Expression::Derivative {
axis: DerivativeAxis::X,
expr: source,
});
self.emit_dest_store(dest, derivative)?;
}
Opcode::Ddy => {
let source = self.emit_source_field_load(source1, true)?;
let derivative = self.evaluate_expr(Expression::Derivative {
axis: DerivativeAxis::Y,
expr: source,
});
self.emit_dest_store(dest, derivative)?;
}
_ => { _ => {
return Err(Error::Unimplemented(format!( return Err(Error::Unimplemented(format!(
"Unimplemented opcode: {opcode:?}", "Unimplemented opcode: {opcode:?}",