diff options
| author | 2018-12-21 01:57:13 -0300 | |
|---|---|---|
| committer | 2019-01-15 17:54:51 -0300 | |
| commit | 3052eae25e9a35bdffdd72c2598929e6a9c72607 (patch) | |
| tree | dd06785fca45a0ec0518846cb7470145ae6d8bfd /src | |
| parent | shader_decode: Implement I2F (diff) | |
| download | yuzu-3052eae25e9a35bdffdd72c2598929e6a9c72607.tar.gz yuzu-3052eae25e9a35bdffdd72c2598929e6a9c72607.tar.xz yuzu-3052eae25e9a35bdffdd72c2598929e6a9c72607.zip | |
shader_decode: Implement F2I
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/conversion.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp index 7c691982d..82fe5e21a 100644 --- a/src/video_core/shader/decode/conversion.cpp +++ b/src/video_core/shader/decode/conversion.cpp | |||
| @@ -73,6 +73,43 @@ u32 ShaderIR::DecodeConversion(BasicBlock& bb, u32 pc) { | |||
| 73 | SetRegister(bb, instr.gpr0, value); | 73 | SetRegister(bb, instr.gpr0, value); |
| 74 | break; | 74 | break; |
| 75 | } | 75 | } |
| 76 | case OpCode::Id::F2I_R: | ||
| 77 | case OpCode::Id::F2I_C: { | ||
| 78 | UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); | ||
| 79 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, | ||
| 80 | "Condition codes generation in F2I is not implemented"); | ||
| 81 | Node value = [&]() { | ||
| 82 | if (instr.is_b_gpr) { | ||
| 83 | return GetRegister(instr.gpr20); | ||
| 84 | } else { | ||
| 85 | return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); | ||
| 86 | } | ||
| 87 | }(); | ||
| 88 | |||
| 89 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); | ||
| 90 | |||
| 91 | value = [&]() { | ||
| 92 | switch (instr.conversion.f2i.rounding) { | ||
| 93 | case Tegra::Shader::F2iRoundingOp::None: | ||
| 94 | return value; | ||
| 95 | case Tegra::Shader::F2iRoundingOp::Floor: | ||
| 96 | return Operation(OperationCode::FFloor, PRECISE, value); | ||
| 97 | case Tegra::Shader::F2iRoundingOp::Ceil: | ||
| 98 | return Operation(OperationCode::FCeil, PRECISE, value); | ||
| 99 | case Tegra::Shader::F2iRoundingOp::Trunc: | ||
| 100 | return Operation(OperationCode::FTrunc, PRECISE, value); | ||
| 101 | default: | ||
| 102 | UNIMPLEMENTED_MSG("Unimplemented F2I rounding mode {}", | ||
| 103 | static_cast<u32>(instr.conversion.f2i.rounding.Value())); | ||
| 104 | } | ||
| 105 | }(); | ||
| 106 | const bool is_signed = instr.conversion.is_output_signed; | ||
| 107 | value = SignedOperation(OperationCode::ICastFloat, is_signed, PRECISE, value); | ||
| 108 | value = ConvertIntegerSize(value, instr.conversion.dest_size, is_signed); | ||
| 109 | |||
| 110 | SetRegister(bb, instr.gpr0, value); | ||
| 111 | break; | ||
| 112 | } | ||
| 76 | default: | 113 | default: |
| 77 | UNIMPLEMENTED_MSG("Unhandled conversion instruction: {}", opcode->get().GetName()); | 114 | UNIMPLEMENTED_MSG("Unhandled conversion instruction: {}", opcode->get().GetName()); |
| 78 | } | 115 | } |