mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[spirv] fix binary operators, support more extensions
This commit is contained in:
committed by
Dzmitry Malyshau
parent
462c82fb71
commit
b5d99e133b
@@ -411,6 +411,31 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_expr_unary_op(
|
||||
&mut self,
|
||||
expressions: &mut Arena<crate::Expression>,
|
||||
op: crate::UnaryOperator,
|
||||
) -> Result<(), Error> {
|
||||
let result_type_id = self.next()?;
|
||||
let result_id = self.next()?;
|
||||
let p_id = self.next()?;
|
||||
|
||||
let p_lexp = self.lookup_expression.lookup(p_id)?;
|
||||
|
||||
let expr = crate::Expression::Unary {
|
||||
op,
|
||||
expr: p_lexp.handle,
|
||||
};
|
||||
self.lookup_expression.insert(
|
||||
result_id,
|
||||
LookupExpression {
|
||||
handle: expressions.append(expr),
|
||||
type_id: result_type_id,
|
||||
},
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_expr_binary_op(
|
||||
&mut self,
|
||||
expressions: &mut Arena<crate::Expression>,
|
||||
@@ -703,53 +728,37 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
});
|
||||
}
|
||||
// Arithmetic Instructions +, -, *, /, %
|
||||
_ if inst.op >= Op::IAdd && inst.op <= Op::FMod => {
|
||||
Op::SNegate | Op::FNegate => {
|
||||
inst.expect(4)?;
|
||||
self.parse_expr_unary_op(expressions, crate::UnaryOperator::Negate)?;
|
||||
}
|
||||
Op::IAdd | Op::FAdd => {
|
||||
inst.expect(5)?;
|
||||
self.parse_expr_binary_op(expressions, crate::BinaryOperator::Add)?;
|
||||
}
|
||||
Op::ISub | Op::FSub => {
|
||||
inst.expect(5)?;
|
||||
self.parse_expr_binary_op(expressions, crate::BinaryOperator::Subtract)?;
|
||||
}
|
||||
Op::VectorTimesScalar => {
|
||||
Op::IMul | Op::FMul => {
|
||||
inst.expect(5)?;
|
||||
let result_type_id = self.next()?;
|
||||
let result_id = self.next()?;
|
||||
let vector_id = self.next()?;
|
||||
let scalar_id = self.next()?;
|
||||
|
||||
let vector_lexp = self.lookup_expression.lookup(vector_id)?;
|
||||
let scalar_lexp = self.lookup_expression.lookup(scalar_id)?;
|
||||
|
||||
let expr = crate::Expression::Binary {
|
||||
op: crate::BinaryOperator::Multiply,
|
||||
left: vector_lexp.handle,
|
||||
right: scalar_lexp.handle,
|
||||
};
|
||||
self.lookup_expression.insert(
|
||||
result_id,
|
||||
LookupExpression {
|
||||
handle: expressions.append(expr),
|
||||
type_id: result_type_id,
|
||||
},
|
||||
);
|
||||
self.parse_expr_binary_op(expressions, crate::BinaryOperator::Multiply)?;
|
||||
}
|
||||
Op::MatrixTimesVector => {
|
||||
Op::SDiv | Op::UDiv | Op::FDiv => {
|
||||
inst.expect(5)?;
|
||||
let result_type_id = self.next()?;
|
||||
let result_id = self.next()?;
|
||||
let matrix_id = self.next()?;
|
||||
let vector_id = self.next()?;
|
||||
let matrix_lexp = self.lookup_expression.lookup(matrix_id)?;
|
||||
let vector_lexp = self.lookup_expression.lookup(vector_id)?;
|
||||
let expr = crate::Expression::Binary {
|
||||
op: crate::BinaryOperator::Multiply,
|
||||
left: matrix_lexp.handle,
|
||||
right: vector_lexp.handle,
|
||||
};
|
||||
self.lookup_expression.insert(
|
||||
result_id,
|
||||
LookupExpression {
|
||||
handle: expressions.append(expr),
|
||||
type_id: result_type_id,
|
||||
},
|
||||
);
|
||||
self.parse_expr_binary_op(expressions, crate::BinaryOperator::Divide)?;
|
||||
}
|
||||
Op::UMod | Op::FMod | Op::SRem | Op::FRem => {
|
||||
inst.expect(5)?;
|
||||
self.parse_expr_binary_op(expressions, crate::BinaryOperator::Modulo)?;
|
||||
}
|
||||
Op::VectorTimesScalar
|
||||
| Op::VectorTimesMatrix
|
||||
| Op::MatrixTimesScalar
|
||||
| Op::MatrixTimesVector
|
||||
| Op::MatrixTimesMatrix => {
|
||||
inst.expect(5)?;
|
||||
self.parse_expr_binary_op(expressions, crate::BinaryOperator::Multiply)?;
|
||||
}
|
||||
Op::Transpose => {
|
||||
inst.expect(4)?;
|
||||
@@ -772,9 +781,9 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
let result_id = self.next()?;
|
||||
let left_id = self.next()?;
|
||||
let right_id = self.next()?;
|
||||
let left_expr = self.lookup_expression.lookup(left_id)?;
|
||||
let right_expr = self.lookup_expression.lookup(right_id)?;
|
||||
let expr = crate::Expression::DotProduct(left_expr.handle, right_expr.handle);
|
||||
let left_lexp = self.lookup_expression.lookup(left_id)?;
|
||||
let right_lexp = self.lookup_expression.lookup(right_id)?;
|
||||
let expr = crate::Expression::DotProduct(left_lexp.handle, right_lexp.handle);
|
||||
self.lookup_expression.insert(
|
||||
result_id,
|
||||
LookupExpression {
|
||||
@@ -1015,7 +1024,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
let result_id = self.next()?;
|
||||
let value_id = self.next()?;
|
||||
|
||||
let value_expr = self.lookup_expression.lookup(value_id)?;
|
||||
let value_lexp = self.lookup_expression.lookup(value_id)?;
|
||||
let ty_lookup = self.lookup_type.lookup(result_type_id)?;
|
||||
let kind = match type_arena[ty_lookup.handle].inner {
|
||||
crate::TypeInner::Scalar { kind, .. }
|
||||
@@ -1023,7 +1032,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
_ => return Err(Error::InvalidAsType(ty_lookup.handle)),
|
||||
};
|
||||
|
||||
let expr = crate::Expression::As(value_expr.handle, kind);
|
||||
let expr = crate::Expression::As(value_lexp.handle, kind);
|
||||
self.lookup_expression.insert(
|
||||
result_id,
|
||||
LookupExpression {
|
||||
@@ -1069,8 +1078,40 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
}
|
||||
let inst_id = self.next()?;
|
||||
let name = match spirv::GLOp::from_u32(inst_id) {
|
||||
Some(spirv::GLOp::Atan2) => {
|
||||
Some(spirv::GLOp::FAbs) | Some(spirv::GLOp::SAbs) => {
|
||||
inst.expect(base_wc + 1)?;
|
||||
"abs"
|
||||
}
|
||||
Some(spirv::GLOp::FSign) | Some(spirv::GLOp::SSign) => {
|
||||
inst.expect(base_wc + 1)?;
|
||||
"sign"
|
||||
}
|
||||
Some(spirv::GLOp::Floor) => {
|
||||
inst.expect(base_wc + 1)?;
|
||||
"floor"
|
||||
}
|
||||
Some(spirv::GLOp::Ceil) => {
|
||||
inst.expect(base_wc + 1)?;
|
||||
"ceil"
|
||||
}
|
||||
Some(spirv::GLOp::Fract) => {
|
||||
inst.expect(base_wc + 1)?;
|
||||
"fract"
|
||||
}
|
||||
Some(spirv::GLOp::Sin) => {
|
||||
inst.expect(base_wc + 1)?;
|
||||
"sin"
|
||||
}
|
||||
Some(spirv::GLOp::Cos) => {
|
||||
inst.expect(base_wc + 1)?;
|
||||
"cos"
|
||||
}
|
||||
Some(spirv::GLOp::Tan) => {
|
||||
inst.expect(base_wc + 1)?;
|
||||
"tan"
|
||||
}
|
||||
Some(spirv::GLOp::Atan2) => {
|
||||
inst.expect(base_wc + 2)?;
|
||||
"atan2"
|
||||
}
|
||||
Some(spirv::GLOp::Pow) => {
|
||||
@@ -1085,6 +1126,10 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
inst.expect(base_wc + 3)?;
|
||||
"mix"
|
||||
}
|
||||
Some(spirv::GLOp::Step) => {
|
||||
inst.expect(base_wc + 2)?;
|
||||
"step"
|
||||
}
|
||||
Some(spirv::GLOp::SmoothStep) => {
|
||||
inst.expect(base_wc + 3)?;
|
||||
"smoothstep"
|
||||
@@ -1105,10 +1150,18 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
inst.expect(base_wc + 1)?;
|
||||
"length"
|
||||
}
|
||||
Some(spirv::GLOp::Cross) => {
|
||||
inst.expect(base_wc + 2)?;
|
||||
"cross"
|
||||
}
|
||||
Some(spirv::GLOp::Normalize) => {
|
||||
inst.expect(base_wc + 1)?;
|
||||
"normalize"
|
||||
}
|
||||
Some(spirv::GLOp::Reflect) => {
|
||||
inst.expect(base_wc + 2)?;
|
||||
"reflect"
|
||||
}
|
||||
_ => return Err(Error::UnsupportedExtInst(inst_id)),
|
||||
};
|
||||
|
||||
@@ -1149,9 +1202,9 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
Op::ReturnValue => {
|
||||
inst.expect(2)?;
|
||||
let value_id = self.next()?;
|
||||
let value_expr = self.lookup_expression.lookup(value_id)?;
|
||||
let value_lexp = self.lookup_expression.lookup(value_id)?;
|
||||
break Terminator::Return {
|
||||
value: Some(value_expr.handle),
|
||||
value: Some(value_lexp.handle),
|
||||
};
|
||||
}
|
||||
Op::Branch => {
|
||||
|
||||
Reference in New Issue
Block a user