Explorar o código

shader_decode: Implement PSETP

ReinUsesLisp %!s(int64=7) %!d(string=hai) anos
pai
achega
abdbafbc20
Modificáronse 1 ficheiros con 21 adicións e 1 borrados
  1. 21 1
      src/video_core/shader/decode/predicate_set_predicate.cpp

+ 21 - 1
src/video_core/shader/decode/predicate_set_predicate.cpp

@@ -11,12 +11,32 @@ namespace VideoCommon::Shader {
 
 using Tegra::Shader::Instruction;
 using Tegra::Shader::OpCode;
+using Tegra::Shader::Pred;
 
 u32 ShaderIR::DecodePredicateSetPredicate(BasicBlock& bb, u32 pc) {
     const Instruction instr = {program_code[pc]};
     const auto opcode = OpCode::Decode(instr);
 
-    UNIMPLEMENTED();
+    const Node op_a = GetPredicate(instr.psetp.pred12, instr.psetp.neg_pred12 != 0);
+    const Node op_b = GetPredicate(instr.psetp.pred29, instr.psetp.neg_pred29 != 0);
+
+    // We can't use the constant predicate as destination.
+    ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
+
+    const Node second_pred = GetPredicate(instr.psetp.pred39, instr.psetp.neg_pred39 != 0);
+
+    const OperationCode combiner = GetPredicateCombiner(instr.psetp.op);
+    const Node predicate = Operation(combiner, op_a, op_b);
+
+    // Set the primary predicate to the result of Predicate OP SecondPredicate
+    SetPredicate(bb, instr.psetp.pred3, Operation(combiner, predicate, 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(
+            bb, instr.psetp.pred0,
+            Operation(combiner, Operation(OperationCode::LogicalNegate, predicate), second_pred));
+    }
 
     return pc;
 }