summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2018-05-20 17:53:06 -0500
committerGravatar Subv2018-05-20 17:53:06 -0500
commit8440cef2239cc86ec915513c722da835160515bb (patch)
tree69644862eca47e3e41d758e66fe4e6de2b230f9c /src
parentMerge pull request #436 from bunnei/multi-core (diff)
downloadyuzu-8440cef2239cc86ec915513c722da835160515bb.tar.gz
yuzu-8440cef2239cc86ec915513c722da835160515bb.tar.xz
yuzu-8440cef2239cc86ec915513c722da835160515bb.zip
Shaders: Implemented the FMNMX shader instruction.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp27
2 files changed, 26 insertions, 6 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index e1ceec268..4ed1429b0 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -193,6 +193,11 @@ union Instruction {
193 BitField<50, 1, u64> abs_d; 193 BitField<50, 1, u64> abs_d;
194 BitField<56, 1, u64> negate_imm; 194 BitField<56, 1, u64> negate_imm;
195 195
196 union {
197 BitField<39, 3, u64> pred;
198 BitField<42, 1, u64> negate_pred;
199 } fmnmx;
200
196 float GetImm20_19() const { 201 float GetImm20_19() const {
197 float result{}; 202 float result{};
198 u32 imm{static_cast<u32>(imm20_19)}; 203 u32 imm{static_cast<u32>(imm20_19)};
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index abbf0893d..1aa24da46 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -580,14 +580,17 @@ private:
580 * @param instr Instruction to generate the if condition for. 580 * @param instr Instruction to generate the if condition for.
581 * @returns string containing the predicate condition. 581 * @returns string containing the predicate condition.
582 */ 582 */
583 std::string GetPredicateCondition(Instruction instr) const { 583 std::string GetPredicateCondition(u64 index, bool negate) const {
584 using Tegra::Shader::Pred; 584 using Tegra::Shader::Pred;
585 ASSERT(instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)); 585 std::string variable;
586 586
587 std::string variable = 587 // Index 7 is used as an 'Always True' condition.
588 'p' + std::to_string(static_cast<u64>(instr.pred.pred_index.Value())); 588 if (index == static_cast<u64>(Pred::UnusedIndex))
589 variable = "true";
590 else
591 variable = 'p' + std::to_string(index);
589 592
590 if (instr.negate_pred) { 593 if (negate) {
591 return "!(" + variable + ')'; 594 return "!(" + variable + ')';
592 } 595 }
593 596
@@ -634,7 +637,9 @@ private:
634 "NeverExecute predicate not implemented"); 637 "NeverExecute predicate not implemented");
635 638
636 if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) { 639 if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) {
637 shader.AddLine("if (" + GetPredicateCondition(instr) + ')'); 640 shader.AddLine("if (" +
641 GetPredicateCondition(instr.pred.pred_index, instr.negate_pred != 0) +
642 ')');
638 shader.AddLine('{'); 643 shader.AddLine('{');
639 ++shader.scope; 644 ++shader.scope;
640 } 645 }
@@ -730,6 +735,16 @@ private:
730 } 735 }
731 break; 736 break;
732 } 737 }
738 case OpCode::Id::FMNMX: {
739 std::string condition =
740 GetPredicateCondition(instr.alu.fmnmx.pred, instr.alu.fmnmx.negate_pred != 0);
741 std::string parameters = op_a + ',' + op_b;
742 regs.SetRegisterToFloat(instr.gpr0, 0,
743 '(' + condition + ") ? min(" + parameters + ") : max(" +
744 parameters + ')',
745 1, 1);
746 break;
747 }
733 case OpCode::Id::RRO: { 748 case OpCode::Id::RRO: {
734 NGLOG_DEBUG(HW_GPU, "Skipping RRO instruction"); 749 NGLOG_DEBUG(HW_GPU, "Skipping RRO instruction");
735 break; 750 break;