[spv] refactor binary operators, add module and addition

This commit is contained in:
Dzmitry Malyshau
2020-12-06 01:35:23 -05:00
committed by Timo de Kort
parent 5b14e26659
commit ef4e8cacf9
2 changed files with 60 additions and 210 deletions

View File

@@ -537,7 +537,7 @@ pub(super) fn instruction_composite_construct(
//
// Arithmetic Instructions
//
fn instruction_binary(
pub(super) fn instruction_binary(
op: Op,
result_type_id: Word,
id: Word,
@@ -552,125 +552,10 @@ fn instruction_binary(
instruction
}
pub(super) fn instruction_i_sub(
result_type_id: Word,
id: Word,
operand_1: Word,
operand_2: Word,
) -> Instruction {
instruction_binary(Op::ISub, result_type_id, id, operand_1, operand_2)
}
pub(super) fn instruction_f_sub(
result_type_id: Word,
id: Word,
operand_1: Word,
operand_2: Word,
) -> Instruction {
instruction_binary(Op::FSub, result_type_id, id, operand_1, operand_2)
}
pub(super) fn instruction_i_mul(
result_type_id: Word,
id: Word,
operand_1: Word,
operand_2: Word,
) -> Instruction {
instruction_binary(Op::IMul, result_type_id, id, operand_1, operand_2)
}
pub(super) fn instruction_f_mul(
result_type_id: Word,
id: Word,
operand_1: Word,
operand_2: Word,
) -> Instruction {
instruction_binary(Op::FMul, result_type_id, id, operand_1, operand_2)
}
pub(super) fn instruction_vector_times_scalar(
result_type_id: Word,
id: Word,
vector_type_id: Word,
scalar_type_id: Word,
) -> Instruction {
let mut instruction = Instruction::new(Op::VectorTimesScalar);
instruction.set_type(result_type_id);
instruction.set_result(id);
instruction.add_operand(vector_type_id);
instruction.add_operand(scalar_type_id);
instruction
}
pub(super) fn instruction_matrix_times_scalar(
result_type_id: Word,
id: Word,
matrix_id: Word,
scalar_id: Word,
) -> Instruction {
let mut instruction = Instruction::new(Op::MatrixTimesScalar);
instruction.set_type(result_type_id);
instruction.set_result(id);
instruction.add_operand(matrix_id);
instruction.add_operand(scalar_id);
instruction
}
pub(super) fn instruction_vector_times_matrix(
result_type_id: Word,
id: Word,
vector_id: Word,
matrix_id: Word,
) -> Instruction {
let mut instruction = Instruction::new(Op::VectorTimesMatrix);
instruction.set_type(result_type_id);
instruction.set_result(id);
instruction.add_operand(vector_id);
instruction.add_operand(matrix_id);
instruction
}
pub(super) fn instruction_matrix_times_vector(
result_type_id: Word,
id: Word,
matrix_id: Word,
vector_id: Word,
) -> Instruction {
let mut instruction = Instruction::new(Op::MatrixTimesVector);
instruction.set_type(result_type_id);
instruction.set_result(id);
instruction.add_operand(matrix_id);
instruction.add_operand(vector_id);
instruction
}
pub(super) fn instruction_matrix_times_matrix(
result_type_id: Word,
id: Word,
left_matrix: Word,
right_matrix: Word,
) -> Instruction {
let mut instruction = Instruction::new(Op::MatrixTimesMatrix);
instruction.set_type(result_type_id);
instruction.set_result(id);
instruction.add_operand(left_matrix);
instruction.add_operand(right_matrix);
instruction
}
//
// Bit Instructions
//
pub(super) fn instruction_bitwise_and(
result_type_id: Word,
id: Word,
operand_1: Word,
operand_2: Word,
) -> Instruction {
instruction_binary(Op::BitwiseAnd, result_type_id, id, operand_1, operand_2)
}
//
// Relational and Logical Instructions
//

View File

@@ -1147,116 +1147,81 @@ impl Writer {
let left_dimension = get_dimension(&left_ty_inner);
let right_dimension = get_dimension(&right_ty_inner);
let (instruction, lookup_ty) = match op {
let (spirv_op, lookup_ty) = match op {
crate::BinaryOperator::Add => match *left_ty_inner {
crate::TypeInner::Scalar { kind, .. }
| crate::TypeInner::Vector { kind, .. } => match kind {
crate::ScalarKind::Float => (spirv::Op::FAdd, left_lookup_ty),
_ => (spirv::Op::IAdd, left_lookup_ty),
},
_ => unreachable!(),
},
crate::BinaryOperator::Subtract => match *left_ty_inner {
crate::TypeInner::Scalar { kind, .. }
| crate::TypeInner::Vector { kind, .. } => match kind {
crate::ScalarKind::Float => (spirv::Op::FSub, left_lookup_ty),
_ => (spirv::Op::ISub, left_lookup_ty),
},
_ => unreachable!(),
},
crate::BinaryOperator::Multiply => match (left_dimension, right_dimension) {
(Dimension::Vector, Dimension::Scalar { .. }) => (
super::instructions::instruction_vector_times_scalar(
left_result_type_id,
id,
left_id,
right_id,
),
left_lookup_ty,
),
(Dimension::Vector, Dimension::Matrix) => (
super::instructions::instruction_vector_times_matrix(
left_result_type_id,
id,
left_id,
right_id,
),
left_lookup_ty,
),
(Dimension::Matrix, Dimension::Scalar { .. }) => (
super::instructions::instruction_matrix_times_scalar(
left_result_type_id,
id,
left_id,
right_id,
),
left_lookup_ty,
),
(Dimension::Matrix, Dimension::Vector) => (
super::instructions::instruction_matrix_times_vector(
right_result_type_id,
id,
left_id,
right_id,
),
right_lookup_ty,
),
(Dimension::Matrix, Dimension::Matrix) => (
super::instructions::instruction_matrix_times_matrix(
left_result_type_id,
id,
left_id,
right_id,
),
left_lookup_ty,
),
(Dimension::Vector, Dimension::Scalar { .. }) => {
(spirv::Op::VectorTimesScalar, left_lookup_ty)
}
(Dimension::Vector, Dimension::Matrix) => {
(spirv::Op::VectorTimesMatrix, left_lookup_ty)
}
(Dimension::Matrix, Dimension::Scalar { .. }) => {
(spirv::Op::MatrixTimesScalar, left_lookup_ty)
}
(Dimension::Matrix, Dimension::Vector) => {
(spirv::Op::MatrixTimesVector, right_lookup_ty)
}
(Dimension::Matrix, Dimension::Matrix) => {
(spirv::Op::MatrixTimesMatrix, left_lookup_ty)
}
(Dimension::Vector, Dimension::Vector)
| (Dimension::Scalar, Dimension::Scalar)
if left_ty_inner.scalar_kind() == Some(crate::ScalarKind::Float) =>
{
(
super::instructions::instruction_f_mul(
left_result_type_id,
id,
left_id,
right_id,
),
left_lookup_ty,
)
(spirv::Op::FMul, left_lookup_ty)
}
(Dimension::Vector, Dimension::Vector)
| (Dimension::Scalar, Dimension::Scalar) => (
super::instructions::instruction_i_mul(
left_result_type_id,
id,
left_id,
right_id,
),
left_lookup_ty,
),
| (Dimension::Scalar, Dimension::Scalar) => {
(spirv::Op::IMul, left_lookup_ty)
}
_ => unreachable!(),
},
crate::BinaryOperator::Subtract => match *left_ty_inner {
crate::TypeInner::Scalar { kind, .. } => match kind {
crate::ScalarKind::Sint | crate::ScalarKind::Uint => (
super::instructions::instruction_i_sub(
left_result_type_id,
id,
left_id,
right_id,
),
left_lookup_ty,
),
crate::ScalarKind::Float => (
super::instructions::instruction_f_sub(
left_result_type_id,
id,
left_id,
right_id,
),
left_lookup_ty,
),
crate::BinaryOperator::Divide => match *left_ty_inner {
crate::TypeInner::Scalar { kind, .. }
| crate::TypeInner::Vector { kind, .. } => match kind {
crate::ScalarKind::Sint => (spirv::Op::SDiv, left_lookup_ty),
crate::ScalarKind::Uint => (spirv::Op::UDiv, left_lookup_ty),
_ => unreachable!(),
},
_ => unreachable!(),
},
crate::BinaryOperator::And => (
super::instructions::instruction_bitwise_and(
left_result_type_id,
id,
left_id,
right_id,
),
left_lookup_ty,
),
crate::BinaryOperator::Modulo => match *left_ty_inner {
crate::TypeInner::Scalar { kind, .. }
| crate::TypeInner::Vector { kind, .. } => match kind {
crate::ScalarKind::Sint => (spirv::Op::SMod, left_lookup_ty),
crate::ScalarKind::Uint => (spirv::Op::UMod, left_lookup_ty),
crate::ScalarKind::Float => (spirv::Op::FMod, left_lookup_ty),
_ => unreachable!(),
},
_ => unreachable!(),
},
crate::BinaryOperator::And => (spirv::Op::BitwiseAnd, left_lookup_ty),
_ => unimplemented!("{:?}", op),
};
block.body.push(instruction);
block.body.push(super::instructions::instruction_binary(
spirv_op,
left_result_type_id,
id,
left_id,
right_id,
));
Ok((id, lookup_ty))
}
crate::Expression::LocalVariable(variable) => {