summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/shader_bytecode.h10
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp38
2 files changed, 48 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index da64430e9..83f7cc3a9 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -239,6 +239,16 @@ union Instruction {
239 } fsetp; 239 } fsetp;
240 240
241 union { 241 union {
242 BitField<0, 3, u64> pred0;
243 BitField<3, 3, u64> pred3;
244 BitField<39, 3, u64> pred39;
245 BitField<42, 1, u64> neg_pred;
246 BitField<45, 2, PredOperation> op;
247 BitField<48, 1, u64> is_signed;
248 BitField<49, 3, PredCondition> cond;
249 } isetp;
250
251 union {
242 BitField<39, 3, u64> pred39; 252 BitField<39, 3, u64> pred39;
243 BitField<42, 1, u64> neg_pred; 253 BitField<42, 1, u64> neg_pred;
244 BitField<43, 1, u64> neg_a; 254 BitField<43, 1, u64> neg_a;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index bb5209a7e..b27543a65 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1017,6 +1017,44 @@ private:
1017 } 1017 }
1018 break; 1018 break;
1019 } 1019 }
1020 case OpCode::Type::IntegerSetPredicate: {
1021 std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.isetp.is_signed);
1022
1023 std::string op_b{};
1024
1025 ASSERT_MSG(!instr.is_b_imm, "ISETP_IMM not implemented");
1026
1027 if (instr.is_b_gpr) {
1028 op_b += regs.GetRegisterAsInteger(instr.gpr20, 0, instr.isetp.is_signed);
1029 } else {
1030 // TODO(Subv): This family of instructions don't store to a GPR, but GetUniform
1031 // needs to know the type of the output register.
1032 op_b += regs.GetUniform(instr.uniform, instr.gpr0);
1033 }
1034
1035 using Tegra::Shader::Pred;
1036 // We can't use the constant predicate as destination.
1037 ASSERT(instr.isetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
1038
1039 std::string second_pred =
1040 GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0);
1041
1042 std::string comparator = GetPredicateComparison(instr.isetp.cond);
1043 std::string combiner = GetPredicateCombiner(instr.isetp.op);
1044
1045 std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')';
1046 // Set the primary predicate to the result of Predicate OP SecondPredicate
1047 SetPredicate(instr.isetp.pred3,
1048 '(' + predicate + ") " + combiner + " (" + second_pred + ')');
1049
1050 if (instr.isetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
1051 // Set the secondary predicate to the result of !Predicate OP SecondPredicate,
1052 // if enabled
1053 SetPredicate(instr.isetp.pred0,
1054 "!(" + predicate + ") " + combiner + " (" + second_pred + ')');
1055 }
1056 break;
1057 }
1020 case OpCode::Type::FloatSet: { 1058 case OpCode::Type::FloatSet: {
1021 std::string op_a = instr.fset.neg_a ? "-" : ""; 1059 std::string op_a = instr.fset.neg_a ? "-" : "";
1022 op_a += regs.GetRegisterAsFloat(instr.gpr8); 1060 op_a += regs.GetRegisterAsFloat(instr.gpr8);