Explorar o código

GPU: Implemented the PSETP shader instruction.

It's similar to the isetp and fsetp instructions but it works on predicates instead.
Subv %!s(int64=8) %!d(string=hai) anos
pai
achega
53a55bd751

+ 13 - 0
src/video_core/engines/shader_bytecode.h

@@ -328,6 +328,19 @@ union Instruction {
         BitField<49, 3, PredCondition> cond;
     } isetp;
 
+    union {
+        BitField<0, 3, u64> pred0;
+        BitField<3, 3, u64> pred3;
+        BitField<12, 3, u64> pred12;
+        BitField<15, 1, u64> neg_pred12;
+        BitField<24, 2, PredOperation> cond;
+        BitField<29, 3, u64> pred29;
+        BitField<32, 1, u64> neg_pred29;
+        BitField<39, 3, u64> pred39;
+        BitField<42, 1, u64> neg_pred39;
+        BitField<45, 2, PredOperation> op;
+    } psetp;
+
     union {
         BitField<39, 3, u64> pred39;
         BitField<42, 1, u64> neg_pred;

+ 30 - 0
src/video_core/renderer_opengl/gl_shader_decompiler.cpp

@@ -1477,6 +1477,36 @@ private:
             }
             break;
         }
+        case OpCode::Type::PredicateSetPredicate: {
+            std::string op_a =
+                GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0);
+            std::string op_b =
+                GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0);
+
+            using Tegra::Shader::Pred;
+            // We can't use the constant predicate as destination.
+            ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
+
+            std::string second_pred =
+                GetPredicateCondition(instr.psetp.pred39, instr.psetp.neg_pred39 != 0);
+
+            std::string combiner = GetPredicateCombiner(instr.psetp.op);
+
+            std::string predicate =
+                '(' + op_a + ") " + GetPredicateCombiner(instr.psetp.cond) + " (" + op_b + ')';
+
+            // Set the primary predicate to the result of Predicate OP SecondPredicate
+            SetPredicate(instr.psetp.pred3,
+                         '(' + predicate + ") " + combiner + " (" + second_pred + ')');
+
+            if (instr.psetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
+                // Set the secondary predicate to the result of !Predicate OP SecondPredicate,
+                // if enabled
+                SetPredicate(instr.psetp.pred0,
+                             "!(" + predicate + ") " + combiner + " (" + second_pred + ')');
+            }
+            break;
+        }
         case OpCode::Type::FloatSet: {
             std::string op_a = instr.fset.neg_a ? "-" : "";
             op_a += regs.GetRegisterAsFloat(instr.gpr8);