Просмотр исходного кода

gl_shader_decompiler: Implement VSETP

ReinUsesLisp 7 лет назад
Родитель
Сommit
7d6dca0d0a

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

@@ -1246,6 +1246,7 @@ public:
         OUT_R, // Emit vertex/primitive
         ISBERD,
         VMAD,
+        VSETP,
         FFMA_IMM, // Fused Multiply and Add
         FFMA_CR,
         FFMA_RC,
@@ -1501,6 +1502,7 @@ private:
             INST("1111101111100---", Id::OUT_R, Type::Trivial, "OUT_R"),
             INST("1110111111010---", Id::ISBERD, Type::Trivial, "ISBERD"),
             INST("01011111--------", Id::VMAD, Type::Trivial, "VMAD"),
+            INST("0101000011110---", Id::VSETP, Type::Trivial, "VSETP"),
             INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"),
             INST("010010011-------", Id::FFMA_CR, Type::Ffma, "FFMA_CR"),
             INST("010100011-------", Id::FFMA_RC, Type::Ffma, "FFMA_RC"),

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

@@ -3362,6 +3362,30 @@ private:
                                           instr.vmad.cc);
                 break;
             }
+            case OpCode::Id::VSETP: {
+                const std::string op_a = GetVideoOperandA(instr);
+                const std::string op_b = GetVideoOperandB(instr);
+
+                // We can't use the constant predicate as destination.
+                ASSERT(instr.vsetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
+
+                const std::string second_pred = GetPredicateCondition(instr.vsetp.pred39, false);
+
+                const std::string combiner = GetPredicateCombiner(instr.vsetp.op);
+
+                const std::string predicate = GetPredicateComparison(instr.vsetp.cond, op_a, op_b);
+                // Set the primary predicate to the result of Predicate OP SecondPredicate
+                SetPredicate(instr.vsetp.pred3,
+                             '(' + predicate + ") " + combiner + " (" + second_pred + ')');
+
+                if (instr.vsetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
+                    // Set the secondary predicate to the result of !Predicate OP SecondPredicate,
+                    // if enabled
+                    SetPredicate(instr.vsetp.pred0,
+                                 "!(" + predicate + ") " + combiner + " (" + second_pred + ')');
+                }
+                break;
+            }
             default: {
                 LOG_CRITICAL(HW_GPU, "Unhandled instruction: {}", opcode->GetName());
                 UNREACHABLE();