summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-08-19 13:19:16 -0400
committerGravatar GitHub2018-08-19 13:19:16 -0400
commitd6cb22b0df4e2b785827830e7af605477acbc9b4 (patch)
tree8b86c1cf73dbfb0d05013886f3e99b61cdb2ec67 /src
parentMerge pull request #838 from FearlessTobi/port-3616 (diff)
parentShader: Implemented the predicate and mode arguments of LOP. (diff)
downloadyuzu-d6cb22b0df4e2b785827830e7af605477acbc9b4.tar.gz
yuzu-d6cb22b0df4e2b785827830e7af605477acbc9b4.tar.xz
yuzu-d6cb22b0df4e2b785827830e7af605477acbc9b4.zip
Merge pull request #1103 from Subv/lop_pred
Shader: Implemented the predicate and mode arguments of LOP.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h7
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp43
2 files changed, 39 insertions, 11 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index b038a9d92..6cfb9c5f8 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -214,6 +214,11 @@ enum class FlowCondition : u64 {
214 Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for? 214 Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for?
215}; 215};
216 216
217enum class PredicateResultMode : u64 {
218 None = 0x0,
219 NotZero = 0x3,
220};
221
217union Instruction { 222union Instruction {
218 Instruction& operator=(const Instruction& instr) { 223 Instruction& operator=(const Instruction& instr) {
219 value = instr.value; 224 value = instr.value;
@@ -254,7 +259,7 @@ union Instruction {
254 BitField<39, 1, u64> invert_a; 259 BitField<39, 1, u64> invert_a;
255 BitField<40, 1, u64> invert_b; 260 BitField<40, 1, u64> invert_b;
256 BitField<41, 2, LogicOperation> operation; 261 BitField<41, 2, LogicOperation> operation;
257 BitField<44, 2, u64> unk44; 262 BitField<44, 2, PredicateResultMode> pred_result_mode;
258 BitField<48, 3, Pred> pred48; 263 BitField<48, 3, Pred> pred48;
259 } lop; 264 } lop;
260 265
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index bb01b3c27..77974b9d2 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -756,28 +756,51 @@ private:
756 } 756 }
757 757
758 void WriteLogicOperation(Register dest, LogicOperation logic_op, const std::string& op_a, 758 void WriteLogicOperation(Register dest, LogicOperation logic_op, const std::string& op_a,
759 const std::string& op_b) { 759 const std::string& op_b,
760 Tegra::Shader::PredicateResultMode predicate_mode,
761 Tegra::Shader::Pred predicate) {
762 std::string result{};
760 switch (logic_op) { 763 switch (logic_op) {
761 case LogicOperation::And: { 764 case LogicOperation::And: {
762 regs.SetRegisterToInteger(dest, true, 0, '(' + op_a + " & " + op_b + ')', 1, 1); 765 result = '(' + op_a + " & " + op_b + ')';
763 break; 766 break;
764 } 767 }
765 case LogicOperation::Or: { 768 case LogicOperation::Or: {
766 regs.SetRegisterToInteger(dest, true, 0, '(' + op_a + " | " + op_b + ')', 1, 1); 769 result = '(' + op_a + " | " + op_b + ')';
767 break; 770 break;
768 } 771 }
769 case LogicOperation::Xor: { 772 case LogicOperation::Xor: {
770 regs.SetRegisterToInteger(dest, true, 0, '(' + op_a + " ^ " + op_b + ')', 1, 1); 773 result = '(' + op_a + " ^ " + op_b + ')';
771 break; 774 break;
772 } 775 }
773 case LogicOperation::PassB: { 776 case LogicOperation::PassB: {
774 regs.SetRegisterToInteger(dest, true, 0, op_b, 1, 1); 777 result = op_b;
775 break; 778 break;
776 } 779 }
777 default: 780 default:
778 LOG_CRITICAL(HW_GPU, "Unimplemented logic operation: {}", static_cast<u32>(logic_op)); 781 LOG_CRITICAL(HW_GPU, "Unimplemented logic operation: {}", static_cast<u32>(logic_op));
779 UNREACHABLE(); 782 UNREACHABLE();
780 } 783 }
784
785 if (dest != Tegra::Shader::Register::ZeroIndex) {
786 regs.SetRegisterToInteger(dest, true, 0, result, 1, 1);
787 }
788
789 using Tegra::Shader::PredicateResultMode;
790 // Write the predicate value depending on the predicate mode.
791 switch (predicate_mode) {
792 case PredicateResultMode::None:
793 // Do nothing.
794 return;
795 case PredicateResultMode::NotZero:
796 // Set the predicate to true if the result is not zero.
797 SetPredicate(static_cast<u64>(predicate), '(' + result + ") != 0");
798 break;
799 default:
800 LOG_CRITICAL(HW_GPU, "Unimplemented predicate result mode: {}",
801 static_cast<u32>(predicate_mode));
802 UNREACHABLE();
803 }
781 } 804 }
782 805
783 void WriteTexsInstruction(const Instruction& instr, const std::string& coord, 806 void WriteTexsInstruction(const Instruction& instr, const std::string& coord,
@@ -1099,7 +1122,9 @@ private:
1099 if (instr.alu.lop32i.invert_b) 1122 if (instr.alu.lop32i.invert_b)
1100 op_b = "~(" + op_b + ')'; 1123 op_b = "~(" + op_b + ')';
1101 1124
1102 WriteLogicOperation(instr.gpr0, instr.alu.lop32i.operation, op_a, op_b); 1125 WriteLogicOperation(instr.gpr0, instr.alu.lop32i.operation, op_a, op_b,
1126 Tegra::Shader::PredicateResultMode::None,
1127 Tegra::Shader::Pred::UnusedIndex);
1103 break; 1128 break;
1104 } 1129 }
1105 default: { 1130 default: {
@@ -1165,16 +1190,14 @@ private:
1165 case OpCode::Id::LOP_C: 1190 case OpCode::Id::LOP_C:
1166 case OpCode::Id::LOP_R: 1191 case OpCode::Id::LOP_R:
1167 case OpCode::Id::LOP_IMM: { 1192 case OpCode::Id::LOP_IMM: {
1168 ASSERT_MSG(!instr.alu.lop.unk44, "Unimplemented");
1169 ASSERT_MSG(instr.alu.lop.pred48 == Pred::UnusedIndex, "Unimplemented");
1170
1171 if (instr.alu.lop.invert_a) 1193 if (instr.alu.lop.invert_a)
1172 op_a = "~(" + op_a + ')'; 1194 op_a = "~(" + op_a + ')';
1173 1195
1174 if (instr.alu.lop.invert_b) 1196 if (instr.alu.lop.invert_b)
1175 op_b = "~(" + op_b + ')'; 1197 op_b = "~(" + op_b + ')';
1176 1198
1177 WriteLogicOperation(instr.gpr0, instr.alu.lop.operation, op_a, op_b); 1199 WriteLogicOperation(instr.gpr0, instr.alu.lop.operation, op_a, op_b,
1200 instr.alu.lop.pred_result_mode, instr.alu.lop.pred48);
1178 break; 1201 break;
1179 } 1202 }
1180 case OpCode::Id::IMNMX_C: 1203 case OpCode::Id::IMNMX_C: