shader/conversion: Fix F2F rounding operations with different sizes

Rounding operations only matter when the conversion size of source and
destination is the same, i.e. .F16.F16, .F32.F32 and .F64.F64.

When there is a mismatch (.F16.F32), these bits are used for IEEE
rounding, we don't emulate this because GLSL and SPIR-V don't support
configuring it per operation.
This commit is contained in:
ReinUsesLisp 2020-03-26 01:58:49 -03:00
parent 23c7dda710
commit 46791c464a

View file

@ -138,18 +138,23 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);
value = [&]() { value = [&] {
if (instr.conversion.src_size != instr.conversion.dst_size) {
// Rounding operations only matter when the source and destination conversion size
// is the same.
return value;
}
switch (instr.conversion.f2f.GetRoundingMode()) { switch (instr.conversion.f2f.GetRoundingMode()) {
case Tegra::Shader::F2fRoundingOp::None: case Tegra::Shader::F2fRoundingOp::None:
return value; return value;
case Tegra::Shader::F2fRoundingOp::Round: case Tegra::Shader::F2fRoundingOp::Round:
return Operation(OperationCode::FRoundEven, PRECISE, value); return Operation(OperationCode::FRoundEven, value);
case Tegra::Shader::F2fRoundingOp::Floor: case Tegra::Shader::F2fRoundingOp::Floor:
return Operation(OperationCode::FFloor, PRECISE, value); return Operation(OperationCode::FFloor, value);
case Tegra::Shader::F2fRoundingOp::Ceil: case Tegra::Shader::F2fRoundingOp::Ceil:
return Operation(OperationCode::FCeil, PRECISE, value); return Operation(OperationCode::FCeil, value);
case Tegra::Shader::F2fRoundingOp::Trunc: case Tegra::Shader::F2fRoundingOp::Trunc:
return Operation(OperationCode::FTrunc, PRECISE, value); return Operation(OperationCode::FTrunc, value);
default: default:
UNIMPLEMENTED_MSG("Unimplemented F2F rounding mode {}", UNIMPLEMENTED_MSG("Unimplemented F2F rounding mode {}",
static_cast<u32>(instr.conversion.f2f.rounding.Value())); static_cast<u32>(instr.conversion.f2f.rounding.Value()));