Przeglądaj źródła

shader: Improve VOTE.VTG stub

FernandoS27 5 lat temu
rodzic
commit
ecb30c9072

+ 8 - 0
src/shader_recompiler/backend/spirv/emit_spirv.h

@@ -59,6 +59,14 @@ void EmitSetZFlag(EmitContext& ctx);
 void EmitSetSFlag(EmitContext& ctx);
 void EmitSetCFlag(EmitContext& ctx);
 void EmitSetOFlag(EmitContext& ctx);
+void EmitGetFCSMFlag(EmitContext& ctx);
+void EmitGetTAFlag(EmitContext& ctx);
+void EmitGetTRFlag(EmitContext& ctx);
+void EmitGetMXFlag(EmitContext& ctx);
+void EmitSetFCSMFlag(EmitContext& ctx);
+void EmitSetTAFlag(EmitContext& ctx);
+void EmitSetTRFlag(EmitContext& ctx);
+void EmitSetMXFlag(EmitContext& ctx);
 Id EmitWorkgroupId(EmitContext& ctx);
 Id EmitLocalInvocationId(EmitContext& ctx);
 Id EmitLoadLocal(EmitContext& ctx, Id word_offset);

+ 32 - 0
src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp

@@ -263,6 +263,38 @@ void EmitSetOFlag(EmitContext&) {
     throw NotImplementedException("SPIR-V Instruction");
 }
 
+void EmitGetFCSMFlag(EmitContext&) {
+    throw NotImplementedException("SPIR-V Instruction");
+}
+
+void EmitGetTAFlag(EmitContext&) {
+    throw NotImplementedException("SPIR-V Instruction");
+}
+
+void EmitGetTRFlag(EmitContext&) {
+    throw NotImplementedException("SPIR-V Instruction");
+}
+
+void EmitGetMXFlag(EmitContext&) {
+    throw NotImplementedException("SPIR-V Instruction");
+}
+
+void EmitSetFCSMFlag(EmitContext&) {
+    throw NotImplementedException("SPIR-V Instruction");
+}
+
+void EmitSetTAFlag(EmitContext&) {
+    throw NotImplementedException("SPIR-V Instruction");
+}
+
+void EmitSetTRFlag(EmitContext&) {
+    throw NotImplementedException("SPIR-V Instruction");
+}
+
+void EmitSetMXFlag(EmitContext&) {
+    throw NotImplementedException("SPIR-V Instruction");
+}
+
 Id EmitWorkgroupId(EmitContext& ctx) {
     return ctx.OpLoad(ctx.U32[3], ctx.workgroup_id);
 }

+ 35 - 2
src/shader_recompiler/frontend/ir/ir_emitter.cpp

@@ -198,6 +198,38 @@ void IREmitter::SetOFlag(const U1& value) {
     Inst(Opcode::SetOFlag, value);
 }
 
+U1 IREmitter::GetFCSMFlag() {
+    return Inst<U1>(Opcode::GetFCSMFlag);
+}
+
+U1 IREmitter::GetTAFlag() {
+    return Inst<U1>(Opcode::GetTAFlag);
+}
+
+U1 IREmitter::GetTRFlag() {
+    return Inst<U1>(Opcode::GetTRFlag);
+}
+
+U1 IREmitter::GetMXFlag() {
+    return Inst<U1>(Opcode::GetMXFlag);
+}
+
+void IREmitter::SetFCSMFlag(const U1& value) {
+    Inst(Opcode::SetFCSMFlag, value);
+}
+
+void IREmitter::SetTAFlag(const U1& value) {
+    Inst(Opcode::SetTAFlag, value);
+}
+
+void IREmitter::SetTRFlag(const U1& value) {
+    Inst(Opcode::SetTRFlag, value);
+}
+
+void IREmitter::SetMXFlag(const U1& value) {
+    Inst(Opcode::SetMXFlag, value);
+}
+
 static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) {
     switch (flow_test) {
     case FlowTest::F:
@@ -256,13 +288,14 @@ static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) {
         return ir.LogicalOr(ir.GetSFlag(), ir.GetZFlag());
     case FlowTest::RGT:
         return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag()));
+
+    case FlowTest::FCSM_TR:
+        return ir.LogicalAnd(ir.GetFCSMFlag(), ir.GetTRFlag());
     case FlowTest::CSM_TA:
     case FlowTest::CSM_TR:
     case FlowTest::CSM_MX:
     case FlowTest::FCSM_TA:
-    case FlowTest::FCSM_TR:
     case FlowTest::FCSM_MX:
-        return ir.Imm1(false);
     default:
         throw NotImplementedException("Flow test {}", flow_test);
     }

+ 10 - 0
src/shader_recompiler/frontend/ir/ir_emitter.h

@@ -70,6 +70,16 @@ public:
     void SetCFlag(const U1& value);
     void SetOFlag(const U1& value);
 
+    [[nodiscard]] U1 GetFCSMFlag();
+    [[nodiscard]] U1 GetTAFlag();
+    [[nodiscard]] U1 GetTRFlag();
+    [[nodiscard]] U1 GetMXFlag();
+
+    void SetFCSMFlag(const U1& value);
+    void SetTAFlag(const U1& value);
+    void SetTRFlag(const U1& value);
+    void SetMXFlag(const U1& value);
+
     [[nodiscard]] U1 Condition(IR::Condition cond);
     [[nodiscard]] U1 GetFlowTestResult(FlowTest test);
 

+ 8 - 0
src/shader_recompiler/frontend/ir/opcodes.inc

@@ -46,10 +46,18 @@ OPCODE(GetZFlag,                                            U1,             Void
 OPCODE(GetSFlag,                                            U1,             Void,                                                                           )
 OPCODE(GetCFlag,                                            U1,             Void,                                                                           )
 OPCODE(GetOFlag,                                            U1,             Void,                                                                           )
+OPCODE(GetFCSMFlag,                                         U1,             Void,                                                                           )
+OPCODE(GetTAFlag,                                           U1,             Void,                                                                           )
+OPCODE(GetTRFlag,                                           U1,             Void,                                                                           )
+OPCODE(GetMXFlag,                                           U1,             Void,                                                                           )
 OPCODE(SetZFlag,                                            Void,           U1,                                                                             )
 OPCODE(SetSFlag,                                            Void,           U1,                                                                             )
 OPCODE(SetCFlag,                                            Void,           U1,                                                                             )
 OPCODE(SetOFlag,                                            Void,           U1,                                                                             )
+OPCODE(SetFCSMFlag,                                         Void,           U1,                                                                             )
+OPCODE(SetTAFlag,                                           Void,           U1,                                                                             )
+OPCODE(SetTRFlag,                                           Void,           U1,                                                                             )
+OPCODE(SetMXFlag,                                           Void,           U1,                                                                             )
 OPCODE(WorkgroupId,                                         U32x3,                                                                                          )
 OPCODE(LocalInvocationId,                                   U32x3,                                                                                          )
 

+ 4 - 1
src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp

@@ -50,7 +50,10 @@ void TranslatorVisitor::VOTE(u64 insn) {
 }
 
 void TranslatorVisitor::VOTE_vtg(u64) {
-    // Stub
+    // LOG_WARNING("VOTE.VTG: Stubbed!");
+    auto imm = ir.Imm1(false);
+    ir.SetFCSMFlag(imm);
+    ir.SetTRFlag(imm);
 }
 
 } // namespace Shader::Maxwell

+ 50 - 1
src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp

@@ -38,6 +38,10 @@ struct ZeroFlagTag : FlagTag {};
 struct SignFlagTag : FlagTag {};
 struct CarryFlagTag : FlagTag {};
 struct OverflowFlagTag : FlagTag {};
+struct FCSMFlagTag : FlagTag {};
+struct TAFlagTag : FlagTag {};
+struct TRFlagTag : FlagTag {};
+struct MXFlagTag : FlagTag {};
 
 struct GotoVariable : FlagTag {
     GotoVariable() = default;
@@ -53,7 +57,8 @@ struct IndirectBranchVariable {
 };
 
 using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag,
-                             OverflowFlagTag, GotoVariable, IndirectBranchVariable>;
+                             OverflowFlagTag, FCSMFlagTag, TAFlagTag, TRFlagTag, MXFlagTag,
+                             GotoVariable, IndirectBranchVariable>;
 using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>;
 
 struct DefTable {
@@ -89,6 +94,22 @@ struct DefTable {
         return overflow_flag;
     }
 
+    [[nodiscard]] ValueMap& operator[](FCSMFlagTag) noexcept {
+        return fcsm_flag;
+    }
+
+    [[nodiscard]] ValueMap& operator[](TAFlagTag) noexcept {
+        return ta_flag;
+    }
+
+    [[nodiscard]] ValueMap& operator[](TRFlagTag) noexcept {
+        return tr_flag;
+    }
+
+    [[nodiscard]] ValueMap& operator[](MXFlagTag) noexcept {
+        return mr_flag;
+    }
+
     std::array<ValueMap, IR::NUM_USER_REGS> regs;
     std::array<ValueMap, IR::NUM_USER_PREDS> preds;
     boost::container::flat_map<u32, ValueMap> goto_vars;
@@ -97,6 +118,10 @@ struct DefTable {
     ValueMap sign_flag;
     ValueMap carry_flag;
     ValueMap overflow_flag;
+    ValueMap fcsm_flag;
+    ValueMap ta_flag;
+    ValueMap tr_flag;
+    ValueMap mr_flag;
 };
 
 IR::Opcode UndefOpcode(IR::Reg) noexcept {
@@ -247,6 +272,18 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) {
     case IR::Opcode::SetOFlag:
         pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0));
         break;
+    case IR::Opcode::SetFCSMFlag:
+        pass.WriteVariable(FCSMFlagTag{}, block, inst.Arg(0));
+        break;
+    case IR::Opcode::SetTAFlag:
+        pass.WriteVariable(TAFlagTag{}, block, inst.Arg(0));
+        break;
+    case IR::Opcode::SetTRFlag:
+        pass.WriteVariable(TRFlagTag{}, block, inst.Arg(0));
+        break;
+    case IR::Opcode::SetMXFlag:
+        pass.WriteVariable(MXFlagTag{}, block, inst.Arg(0));
+        break;
     case IR::Opcode::GetRegister:
         if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) {
             inst.ReplaceUsesWith(pass.ReadVariable(reg, block));
@@ -275,6 +312,18 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) {
     case IR::Opcode::GetOFlag:
         inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block));
         break;
+    case IR::Opcode::GetFCSMFlag:
+        inst.ReplaceUsesWith(pass.ReadVariable(FCSMFlagTag{}, block));
+        break;
+    case IR::Opcode::GetTAFlag:
+        inst.ReplaceUsesWith(pass.ReadVariable(TAFlagTag{}, block));
+        break;
+    case IR::Opcode::GetTRFlag:
+        inst.ReplaceUsesWith(pass.ReadVariable(TRFlagTag{}, block));
+        break;
+    case IR::Opcode::GetMXFlag:
+        inst.ReplaceUsesWith(pass.ReadVariable(MXFlagTag{}, block));
+        break;
     default:
         break;
     }