diff options
| author | 2018-04-25 11:17:38 -0500 | |
|---|---|---|
| committer | 2018-04-25 12:52:32 -0500 | |
| commit | 1740aa544408d32a5c904f40d92c6e06ace6d00a (patch) | |
| tree | 2568887ed57e86f19a2c21b5223d051e295289f8 /src | |
| parent | Shaders: Added decodings for the FSET instructions. (diff) | |
| download | yuzu-1740aa544408d32a5c904f40d92c6e06ace6d00a.tar.gz yuzu-1740aa544408d32a5c904f40d92c6e06ace6d00a.tar.xz yuzu-1740aa544408d32a5c904f40d92c6e06ace6d00a.zip | |
Shaders: Implemented the FSET instruction.
This instruction is similar to the FSETP instruction, but it doesn't set a predicate, it sets the destination register to 1.0 if the condition holds, and 0 otherwise.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 896b6cd2c..3dffb205d 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -570,6 +570,59 @@ private: | |||
| 570 | } | 570 | } |
| 571 | break; | 571 | break; |
| 572 | } | 572 | } |
| 573 | case OpCode::Type::FloatSet: { | ||
| 574 | std::string dest = GetRegister(instr.gpr0); | ||
| 575 | std::string op_a = instr.fset.neg_a ? "-" : ""; | ||
| 576 | op_a += GetRegister(instr.gpr8); | ||
| 577 | |||
| 578 | if (instr.fset.abs_a) { | ||
| 579 | op_a = "abs(" + op_a + ')'; | ||
| 580 | } | ||
| 581 | |||
| 582 | std::string op_b = instr.fset.neg_b ? "-" : ""; | ||
| 583 | |||
| 584 | if (instr.is_b_imm) { | ||
| 585 | std::string imm = GetImmediate19(instr); | ||
| 586 | if (instr.fset.neg_imm) | ||
| 587 | op_b += "(-" + imm + ')'; | ||
| 588 | else | ||
| 589 | op_b += imm; | ||
| 590 | } else { | ||
| 591 | if (instr.is_b_gpr) { | ||
| 592 | op_b += GetRegister(instr.gpr20); | ||
| 593 | } else { | ||
| 594 | op_b += GetUniform(instr.uniform); | ||
| 595 | } | ||
| 596 | } | ||
| 597 | |||
| 598 | if (instr.fset.abs_b) { | ||
| 599 | op_b = "abs(" + op_b + ")"; | ||
| 600 | } | ||
| 601 | |||
| 602 | using Tegra::Shader::Pred; | ||
| 603 | ASSERT_MSG(instr.fset.pred39 == static_cast<u64>(Pred::UnusedIndex), | ||
| 604 | "Compound predicates are not implemented"); | ||
| 605 | |||
| 606 | // The fset instruction sets a register to 1.0 if the condition is true, and to 0 | ||
| 607 | // otherwise. | ||
| 608 | using Tegra::Shader::PredCondition; | ||
| 609 | switch (instr.fset.cond) { | ||
| 610 | case PredCondition::LessThan: | ||
| 611 | SetDest(0, dest, "((" + op_a + ") < (" + op_b + ")) ? 1.0 : 0", 1, 1); | ||
| 612 | break; | ||
| 613 | case PredCondition::Equal: | ||
| 614 | SetDest(0, dest, "((" + op_a + ") == (" + op_b + ")) ? 1.0 : 0", 1, 1); | ||
| 615 | break; | ||
| 616 | case PredCondition::GreaterThan: | ||
| 617 | SetDest(0, dest, "((" + op_a + ") > (" + op_b + ")) ? 1.0 : 0", 1, 1); | ||
| 618 | break; | ||
| 619 | default: | ||
| 620 | NGLOG_CRITICAL(HW_GPU, "Unhandled predicate condition: {} (a: {}, b: {})", | ||
| 621 | static_cast<unsigned>(instr.fset.cond.Value()), op_a, op_b); | ||
| 622 | UNREACHABLE(); | ||
| 623 | } | ||
| 624 | break; | ||
| 625 | } | ||
| 573 | default: { | 626 | default: { |
| 574 | switch (opcode->GetId()) { | 627 | switch (opcode->GetId()) { |
| 575 | case OpCode::Id::EXIT: { | 628 | case OpCode::Id::EXIT: { |