[spv-out] fix generation of OpConvert

This commit is contained in:
Dzmitry Malyshau 2020-11-20 12:09:35 -05:00 committed by Dzmitry Malyshau
parent 1b8b3845be
commit 23b1e4dd76
2 changed files with 25 additions and 79 deletions

View File

@ -505,7 +505,12 @@ pub(super) fn instruction_image_sample_implicit_lod(
//
// Conversion Instructions
//
fn instruction_unary(op: Op, result_type_id: Word, id: Word, value: Word) -> Instruction {
pub(super) fn instruction_unary(
op: Op,
result_type_id: Word,
id: Word,
value: Word,
) -> Instruction {
let mut instruction = Instruction::new(op);
instruction.set_type(result_type_id);
instruction.set_result(id);
@ -513,41 +518,6 @@ fn instruction_unary(op: Op, result_type_id: Word, id: Word, value: Word) -> Ins
instruction
}
pub(super) fn instruction_convert_f_to_u(
result_type_id: Word,
id: Word,
float_value: Word,
) -> Instruction {
instruction_unary(Op::ConvertFToU, result_type_id, id, float_value)
}
pub(super) fn instruction_convert_f_to_s(
result_type_id: Word,
id: Word,
float_value: Word,
) -> Instruction {
instruction_unary(Op::ConvertFToS, result_type_id, id, float_value)
}
pub(super) fn instruction_convert_s_to_f(
result_type_id: Word,
id: Word,
signed_value: Word,
) -> Instruction {
instruction_unary(Op::ConvertSToF, result_type_id, id, signed_value)
}
pub(super) fn instruction_convert_u_to_f(
result_type_id: Word,
id: Word,
unsigned_value: Word,
) -> Instruction {
instruction_unary(Op::ConvertUToF, result_type_id, id, unsigned_value)
}
pub(super) fn instruction_bit_cast(result_type_id: Word, id: Word, operand: Word) -> Instruction {
instruction_unary(Op::Bitcast, result_type_id, id, operand)
}
//
// Composite Instructions
//

View File

@ -1369,55 +1369,31 @@ impl Writer {
let id = self.generate_id();
let expr_type_inner = self.get_type_inner(&ir_module.types, expr_type.unwrap());
let instruction = match *expr_type_inner {
let (expr_kind, local_type) = match *expr_type_inner {
crate::TypeInner::Scalar {
kind: expr_kind,
width,
} => {
let kind_type_id = self.get_type_id(
&ir_module.types,
LookupType::Local(LocalType::Scalar { kind, width }),
);
if convert {
super::instructions::instruction_bit_cast(kind_type_id, id, expr_id)
} else {
match (expr_kind, kind) {
(crate::ScalarKind::Float, crate::ScalarKind::Uint) => {
super::instructions::instruction_convert_f_to_u(
kind_type_id,
id,
expr_id,
)
}
(crate::ScalarKind::Float, crate::ScalarKind::Sint) => {
super::instructions::instruction_convert_f_to_s(
kind_type_id,
id,
expr_id,
)
}
(crate::ScalarKind::Sint, crate::ScalarKind::Float) => {
super::instructions::instruction_convert_s_to_f(
kind_type_id,
id,
expr_id,
)
}
(crate::ScalarKind::Uint, crate::ScalarKind::Float) => {
super::instructions::instruction_convert_u_to_f(
kind_type_id,
id,
expr_id,
)
}
_ => unreachable!(),
}
}
}
} => (expr_kind, LocalType::Scalar { kind, width }),
crate::TypeInner::Vector {
size,
kind: expr_kind,
width,
} => (expr_kind, LocalType::Vector { size, kind, width }),
_ => unreachable!(),
};
let op = match (expr_kind, kind) {
_ if !convert => spirv::Op::Bitcast,
(crate::ScalarKind::Float, crate::ScalarKind::Uint) => spirv::Op::ConvertFToU,
(crate::ScalarKind::Float, crate::ScalarKind::Sint) => spirv::Op::ConvertFToS,
(crate::ScalarKind::Sint, crate::ScalarKind::Float) => spirv::Op::ConvertSToF,
(crate::ScalarKind::Uint, crate::ScalarKind::Float) => spirv::Op::ConvertUToF,
_ => unreachable!(),
};
let kind_type_id =
self.get_type_id(&ir_module.types, LookupType::Local(local_type));
let instruction =
super::instructions::instruction_unary(op, kind_type_id, id, expr_id);
block.body.push(instruction);
Ok((id, None))