summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2018-12-15 17:32:51 -0300
committerGravatar ReinUsesLisp2019-01-15 17:54:50 -0300
commitc849b5b3201e8fda40727c3926b6389f609feafc (patch)
treea90ad69899374115d99711f5a65d479565c6bda6 /src
parentshader_decode: Stub DEPBAR (diff)
downloadyuzu-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.cpp38
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
12using Tegra::Shader::Instruction; 12using Tegra::Shader::Instruction;
13using Tegra::Shader::OpCode; 13using Tegra::Shader::OpCode;
14using Tegra::Shader::Register;
14 15
15u32 ShaderIR::DecodeConversion(BasicBlock& bb, u32 pc) { 16u32 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}