diff options
| author | 2018-12-15 17:32:51 -0300 | |
|---|---|---|
| committer | 2019-01-15 17:54:50 -0300 | |
| commit | c849b5b3201e8fda40727c3926b6389f609feafc (patch) | |
| tree | a90ad69899374115d99711f5a65d479565c6bda6 /src | |
| parent | shader_decode: Stub DEPBAR (diff) | |
| download | yuzu-c849b5b3201e8fda40727c3926b6389f609feafc.tar.gz yuzu-c849b5b3201e8fda40727c3926b6389f609feafc.tar.xz yuzu-c849b5b3201e8fda40727c3926b6389f609feafc.zip | |
shader_decode: Implement F2F
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/conversion.cpp | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp index c6eb2952c..465c63a9e 100644 --- a/src/video_core/shader/decode/conversion.cpp +++ b/src/video_core/shader/decode/conversion.cpp | |||
| @@ -11,12 +11,48 @@ namespace VideoCommon::Shader { | |||
| 11 | 11 | ||
| 12 | using Tegra::Shader::Instruction; | 12 | using Tegra::Shader::Instruction; |
| 13 | using Tegra::Shader::OpCode; | 13 | using Tegra::Shader::OpCode; |
| 14 | using Tegra::Shader::Register; | ||
| 14 | 15 | ||
| 15 | u32 ShaderIR::DecodeConversion(BasicBlock& bb, u32 pc) { | 16 | u32 ShaderIR::DecodeConversion(BasicBlock& bb, u32 pc) { |
| 16 | const Instruction instr = {program_code[pc]}; | 17 | const Instruction instr = {program_code[pc]}; |
| 17 | const auto opcode = OpCode::Decode(instr); | 18 | const auto opcode = OpCode::Decode(instr); |
| 18 | 19 | ||
| 19 | UNIMPLEMENTED(); | 20 | switch (opcode->get().GetId()) { |
| 21 | case OpCode::Id::F2F_R: { | ||
| 22 | UNIMPLEMENTED_IF(instr.conversion.dest_size != Register::Size::Word); | ||
| 23 | UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); | ||
| 24 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, | ||
| 25 | "Condition codes generation in F2F is not implemented"); | ||
| 26 | |||
| 27 | Node value = GetRegister(instr.gpr20); | ||
| 28 | value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); | ||
| 29 | |||
| 30 | value = [&]() { | ||
| 31 | switch (instr.conversion.f2f.rounding) { | ||
| 32 | case Tegra::Shader::F2fRoundingOp::None: | ||
| 33 | return value; | ||
| 34 | case Tegra::Shader::F2fRoundingOp::Round: | ||
| 35 | return Operation(OperationCode::FRoundEven, PRECISE, value); | ||
| 36 | case Tegra::Shader::F2fRoundingOp::Floor: | ||
| 37 | return Operation(OperationCode::FFloor, PRECISE, value); | ||
| 38 | case Tegra::Shader::F2fRoundingOp::Ceil: | ||
| 39 | return Operation(OperationCode::FCeil, PRECISE, value); | ||
| 40 | case Tegra::Shader::F2fRoundingOp::Trunc: | ||
| 41 | return Operation(OperationCode::FTrunc, PRECISE, value); | ||
| 42 | default: | ||
| 43 | UNIMPLEMENTED_MSG("Unimplemented F2F rounding mode {}", | ||
| 44 | static_cast<u32>(instr.conversion.f2f.rounding.Value())); | ||
| 45 | break; | ||
| 46 | } | ||
| 47 | }(); | ||
| 48 | value = GetSaturatedFloat(value, instr.alu.saturate_d); | ||
| 49 | |||
| 50 | SetRegister(bb, instr.gpr0, value); | ||
| 51 | break; | ||
| 52 | } | ||
| 53 | default: | ||
| 54 | UNIMPLEMENTED_MSG("Unhandled conversion instruction: {}", opcode->get().GetName()); | ||
| 55 | } | ||
| 20 | 56 | ||
| 21 | return pc; | 57 | return pc; |
| 22 | } | 58 | } |