diff options
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 23 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 24 |
2 files changed, 47 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 22c122fcc..8d4ea3401 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -233,6 +233,22 @@ union Instruction { | |||
| 233 | } alu; | 233 | } alu; |
| 234 | 234 | ||
| 235 | union { | 235 | union { |
| 236 | BitField<39, 5, u64> shift_amount; | ||
| 237 | BitField<20, 19, u64> immediate_low; | ||
| 238 | BitField<56, 1, u64> immediate_high; | ||
| 239 | BitField<48, 1, u64> negate_b; | ||
| 240 | BitField<49, 1, u64> negate_a; | ||
| 241 | |||
| 242 | s32 GetImmediate() const { | ||
| 243 | u32 immediate = static_cast<u32>(immediate_low | (immediate_high << 19)); | ||
| 244 | // Sign extend the 20-bit value. | ||
| 245 | u32 mask = 1U << (20 - 1); | ||
| 246 | return static_cast<s32>((immediate ^ mask) - mask); | ||
| 247 | } | ||
| 248 | |||
| 249 | } iscadd; | ||
| 250 | |||
| 251 | union { | ||
| 236 | BitField<48, 1, u64> negate_b; | 252 | BitField<48, 1, u64> negate_b; |
| 237 | BitField<49, 1, u64> negate_c; | 253 | BitField<49, 1, u64> negate_c; |
| 238 | } ffma; | 254 | } ffma; |
| @@ -362,6 +378,9 @@ public: | |||
| 362 | FMUL_R, | 378 | FMUL_R, |
| 363 | FMUL_IMM, | 379 | FMUL_IMM, |
| 364 | FMUL32_IMM, | 380 | FMUL32_IMM, |
| 381 | ISCADD_C, // Scale and Add | ||
| 382 | ISCADD_R, | ||
| 383 | ISCADD_IMM, | ||
| 365 | MUFU, // Multi-Function Operator | 384 | MUFU, // Multi-Function Operator |
| 366 | RRO_C, // Range Reduction Operator | 385 | RRO_C, // Range Reduction Operator |
| 367 | RRO_R, | 386 | RRO_R, |
| @@ -405,6 +424,7 @@ public: | |||
| 405 | Trivial, | 424 | Trivial, |
| 406 | Arithmetic, | 425 | Arithmetic, |
| 407 | Logic, | 426 | Logic, |
| 427 | ScaledAdd, | ||
| 408 | Ffma, | 428 | Ffma, |
| 409 | Flow, | 429 | Flow, |
| 410 | Memory, | 430 | Memory, |
| @@ -528,6 +548,9 @@ private: | |||
| 528 | INST("0101110001101---", Id::FMUL_R, Type::Arithmetic, "FMUL_R"), | 548 | INST("0101110001101---", Id::FMUL_R, Type::Arithmetic, "FMUL_R"), |
| 529 | INST("0011100-01101---", Id::FMUL_IMM, Type::Arithmetic, "FMUL_IMM"), | 549 | INST("0011100-01101---", Id::FMUL_IMM, Type::Arithmetic, "FMUL_IMM"), |
| 530 | INST("00011110--------", Id::FMUL32_IMM, Type::Arithmetic, "FMUL32_IMM"), | 550 | INST("00011110--------", Id::FMUL32_IMM, Type::Arithmetic, "FMUL32_IMM"), |
| 551 | INST("0100110000011---", Id::ISCADD_C, Type::ScaledAdd, "ISCADD_C"), | ||
| 552 | INST("0101110000011---", Id::ISCADD_R, Type::ScaledAdd, "ISCADD_R"), | ||
| 553 | INST("0011100-00011---", Id::ISCADD_IMM, Type::ScaledAdd, "ISCADD_IMM"), | ||
| 531 | INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), | 554 | INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), |
| 532 | INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), | 555 | INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), |
| 533 | INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), | 556 | INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 9943394c6..30ba9be67 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -884,6 +884,30 @@ private: | |||
| 884 | } | 884 | } |
| 885 | break; | 885 | break; |
| 886 | } | 886 | } |
| 887 | case OpCode::Type::ScaledAdd: { | ||
| 888 | std::string op_a = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 889 | |||
| 890 | if (instr.iscadd.negate_a) | ||
| 891 | op_a = '-' + op_a; | ||
| 892 | |||
| 893 | std::string op_b = instr.iscadd.negate_b ? "-" : ""; | ||
| 894 | |||
| 895 | if (instr.is_b_imm) { | ||
| 896 | op_b += '(' + std::to_string(instr.iscadd.GetImmediate()) + ')'; | ||
| 897 | } else { | ||
| 898 | if (instr.is_b_gpr) { | ||
| 899 | op_b += regs.GetRegisterAsInteger(instr.gpr20); | ||
| 900 | } else { | ||
| 901 | op_b += regs.GetUniform(instr.uniform, instr.gpr0); | ||
| 902 | } | ||
| 903 | } | ||
| 904 | |||
| 905 | std::string shift = std::to_string(instr.iscadd.shift_amount.Value()); | ||
| 906 | |||
| 907 | regs.SetRegisterToInteger(instr.gpr0, true, 0, | ||
| 908 | "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); | ||
| 909 | break; | ||
| 910 | } | ||
| 887 | case OpCode::Type::Ffma: { | 911 | case OpCode::Type::Ffma: { |
| 888 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | 912 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); |
| 889 | std::string op_b = instr.ffma.negate_b ? "-" : ""; | 913 | std::string op_b = instr.ffma.negate_b ? "-" : ""; |