diff options
| author | 2021-04-01 22:20:57 +0200 | |
|---|---|---|
| committer | 2021-07-22 21:51:25 -0400 | |
| commit | ecb30c907266921818d5b6b03e341028fa2ea082 (patch) | |
| tree | 8bf3f0097653fa11b6dae823f79fe671204ad55e /src | |
| parent | shader: Mark SSBOs as written when they are (diff) | |
| download | yuzu-ecb30c907266921818d5b6b03e341028fa2ea082.tar.gz yuzu-ecb30c907266921818d5b6b03e341028fa2ea082.tar.xz yuzu-ecb30c907266921818d5b6b03e341028fa2ea082.zip | |
shader: Improve VOTE.VTG stub
Diffstat (limited to 'src')
7 files changed, 147 insertions, 4 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 9c9e0c5dd..d2eda1f8e 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -59,6 +59,14 @@ void EmitSetZFlag(EmitContext& ctx); | |||
| 59 | void EmitSetSFlag(EmitContext& ctx); | 59 | void EmitSetSFlag(EmitContext& ctx); |
| 60 | void EmitSetCFlag(EmitContext& ctx); | 60 | void EmitSetCFlag(EmitContext& ctx); |
| 61 | void EmitSetOFlag(EmitContext& ctx); | 61 | void EmitSetOFlag(EmitContext& ctx); |
| 62 | void EmitGetFCSMFlag(EmitContext& ctx); | ||
| 63 | void EmitGetTAFlag(EmitContext& ctx); | ||
| 64 | void EmitGetTRFlag(EmitContext& ctx); | ||
| 65 | void EmitGetMXFlag(EmitContext& ctx); | ||
| 66 | void EmitSetFCSMFlag(EmitContext& ctx); | ||
| 67 | void EmitSetTAFlag(EmitContext& ctx); | ||
| 68 | void EmitSetTRFlag(EmitContext& ctx); | ||
| 69 | void EmitSetMXFlag(EmitContext& ctx); | ||
| 62 | Id EmitWorkgroupId(EmitContext& ctx); | 70 | Id EmitWorkgroupId(EmitContext& ctx); |
| 63 | Id EmitLocalInvocationId(EmitContext& ctx); | 71 | Id EmitLocalInvocationId(EmitContext& ctx); |
| 64 | Id EmitLoadLocal(EmitContext& ctx, Id word_offset); | 72 | Id EmitLoadLocal(EmitContext& ctx, Id word_offset); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index e42407f1f..a96ee6f0d 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | |||
| @@ -263,6 +263,38 @@ void EmitSetOFlag(EmitContext&) { | |||
| 263 | throw NotImplementedException("SPIR-V Instruction"); | 263 | throw NotImplementedException("SPIR-V Instruction"); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | void EmitGetFCSMFlag(EmitContext&) { | ||
| 267 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 268 | } | ||
| 269 | |||
| 270 | void EmitGetTAFlag(EmitContext&) { | ||
| 271 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 272 | } | ||
| 273 | |||
| 274 | void EmitGetTRFlag(EmitContext&) { | ||
| 275 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 276 | } | ||
| 277 | |||
| 278 | void EmitGetMXFlag(EmitContext&) { | ||
| 279 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 280 | } | ||
| 281 | |||
| 282 | void EmitSetFCSMFlag(EmitContext&) { | ||
| 283 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 284 | } | ||
| 285 | |||
| 286 | void EmitSetTAFlag(EmitContext&) { | ||
| 287 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 288 | } | ||
| 289 | |||
| 290 | void EmitSetTRFlag(EmitContext&) { | ||
| 291 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 292 | } | ||
| 293 | |||
| 294 | void EmitSetMXFlag(EmitContext&) { | ||
| 295 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 296 | } | ||
| 297 | |||
| 266 | Id EmitWorkgroupId(EmitContext& ctx) { | 298 | Id EmitWorkgroupId(EmitContext& ctx) { |
| 267 | return ctx.OpLoad(ctx.U32[3], ctx.workgroup_id); | 299 | return ctx.OpLoad(ctx.U32[3], ctx.workgroup_id); |
| 268 | } | 300 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 5258ede09..ddaa873f2 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -198,6 +198,38 @@ void IREmitter::SetOFlag(const U1& value) { | |||
| 198 | Inst(Opcode::SetOFlag, value); | 198 | Inst(Opcode::SetOFlag, value); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | U1 IREmitter::GetFCSMFlag() { | ||
| 202 | return Inst<U1>(Opcode::GetFCSMFlag); | ||
| 203 | } | ||
| 204 | |||
| 205 | U1 IREmitter::GetTAFlag() { | ||
| 206 | return Inst<U1>(Opcode::GetTAFlag); | ||
| 207 | } | ||
| 208 | |||
| 209 | U1 IREmitter::GetTRFlag() { | ||
| 210 | return Inst<U1>(Opcode::GetTRFlag); | ||
| 211 | } | ||
| 212 | |||
| 213 | U1 IREmitter::GetMXFlag() { | ||
| 214 | return Inst<U1>(Opcode::GetMXFlag); | ||
| 215 | } | ||
| 216 | |||
| 217 | void IREmitter::SetFCSMFlag(const U1& value) { | ||
| 218 | Inst(Opcode::SetFCSMFlag, value); | ||
| 219 | } | ||
| 220 | |||
| 221 | void IREmitter::SetTAFlag(const U1& value) { | ||
| 222 | Inst(Opcode::SetTAFlag, value); | ||
| 223 | } | ||
| 224 | |||
| 225 | void IREmitter::SetTRFlag(const U1& value) { | ||
| 226 | Inst(Opcode::SetTRFlag, value); | ||
| 227 | } | ||
| 228 | |||
| 229 | void IREmitter::SetMXFlag(const U1& value) { | ||
| 230 | Inst(Opcode::SetMXFlag, value); | ||
| 231 | } | ||
| 232 | |||
| 201 | static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { | 233 | static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { |
| 202 | switch (flow_test) { | 234 | switch (flow_test) { |
| 203 | case FlowTest::F: | 235 | case FlowTest::F: |
| @@ -256,13 +288,14 @@ static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { | |||
| 256 | return ir.LogicalOr(ir.GetSFlag(), ir.GetZFlag()); | 288 | return ir.LogicalOr(ir.GetSFlag(), ir.GetZFlag()); |
| 257 | case FlowTest::RGT: | 289 | case FlowTest::RGT: |
| 258 | return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag())); | 290 | return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag())); |
| 291 | |||
| 292 | case FlowTest::FCSM_TR: | ||
| 293 | return ir.LogicalAnd(ir.GetFCSMFlag(), ir.GetTRFlag()); | ||
| 259 | case FlowTest::CSM_TA: | 294 | case FlowTest::CSM_TA: |
| 260 | case FlowTest::CSM_TR: | 295 | case FlowTest::CSM_TR: |
| 261 | case FlowTest::CSM_MX: | 296 | case FlowTest::CSM_MX: |
| 262 | case FlowTest::FCSM_TA: | 297 | case FlowTest::FCSM_TA: |
| 263 | case FlowTest::FCSM_TR: | ||
| 264 | case FlowTest::FCSM_MX: | 298 | case FlowTest::FCSM_MX: |
| 265 | return ir.Imm1(false); | ||
| 266 | default: | 299 | default: |
| 267 | throw NotImplementedException("Flow test {}", flow_test); | 300 | throw NotImplementedException("Flow test {}", flow_test); |
| 268 | } | 301 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index a4616e247..6e04eec7f 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -70,6 +70,16 @@ public: | |||
| 70 | void SetCFlag(const U1& value); | 70 | void SetCFlag(const U1& value); |
| 71 | void SetOFlag(const U1& value); | 71 | void SetOFlag(const U1& value); |
| 72 | 72 | ||
| 73 | [[nodiscard]] U1 GetFCSMFlag(); | ||
| 74 | [[nodiscard]] U1 GetTAFlag(); | ||
| 75 | [[nodiscard]] U1 GetTRFlag(); | ||
| 76 | [[nodiscard]] U1 GetMXFlag(); | ||
| 77 | |||
| 78 | void SetFCSMFlag(const U1& value); | ||
| 79 | void SetTAFlag(const U1& value); | ||
| 80 | void SetTRFlag(const U1& value); | ||
| 81 | void SetMXFlag(const U1& value); | ||
| 82 | |||
| 73 | [[nodiscard]] U1 Condition(IR::Condition cond); | 83 | [[nodiscard]] U1 Condition(IR::Condition cond); |
| 74 | [[nodiscard]] U1 GetFlowTestResult(FlowTest test); | 84 | [[nodiscard]] U1 GetFlowTestResult(FlowTest test); |
| 75 | 85 | ||
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index ffd0cc690..702372775 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -46,10 +46,18 @@ OPCODE(GetZFlag, U1, Void | |||
| 46 | OPCODE(GetSFlag, U1, Void, ) | 46 | OPCODE(GetSFlag, U1, Void, ) |
| 47 | OPCODE(GetCFlag, U1, Void, ) | 47 | OPCODE(GetCFlag, U1, Void, ) |
| 48 | OPCODE(GetOFlag, U1, Void, ) | 48 | OPCODE(GetOFlag, U1, Void, ) |
| 49 | OPCODE(GetFCSMFlag, U1, Void, ) | ||
| 50 | OPCODE(GetTAFlag, U1, Void, ) | ||
| 51 | OPCODE(GetTRFlag, U1, Void, ) | ||
| 52 | OPCODE(GetMXFlag, U1, Void, ) | ||
| 49 | OPCODE(SetZFlag, Void, U1, ) | 53 | OPCODE(SetZFlag, Void, U1, ) |
| 50 | OPCODE(SetSFlag, Void, U1, ) | 54 | OPCODE(SetSFlag, Void, U1, ) |
| 51 | OPCODE(SetCFlag, Void, U1, ) | 55 | OPCODE(SetCFlag, Void, U1, ) |
| 52 | OPCODE(SetOFlag, Void, U1, ) | 56 | OPCODE(SetOFlag, Void, U1, ) |
| 57 | OPCODE(SetFCSMFlag, Void, U1, ) | ||
| 58 | OPCODE(SetTAFlag, Void, U1, ) | ||
| 59 | OPCODE(SetTRFlag, Void, U1, ) | ||
| 60 | OPCODE(SetMXFlag, Void, U1, ) | ||
| 53 | OPCODE(WorkgroupId, U32x3, ) | 61 | OPCODE(WorkgroupId, U32x3, ) |
| 54 | OPCODE(LocalInvocationId, U32x3, ) | 62 | OPCODE(LocalInvocationId, U32x3, ) |
| 55 | 63 | ||
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp index 391520a18..2acabb662 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp | |||
| @@ -50,7 +50,10 @@ void TranslatorVisitor::VOTE(u64 insn) { | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | void TranslatorVisitor::VOTE_vtg(u64) { | 52 | void TranslatorVisitor::VOTE_vtg(u64) { |
| 53 | // Stub | 53 | // LOG_WARNING("VOTE.VTG: Stubbed!"); |
| 54 | auto imm = ir.Imm1(false); | ||
| 55 | ir.SetFCSMFlag(imm); | ||
| 56 | ir.SetTRFlag(imm); | ||
| 54 | } | 57 | } |
| 55 | 58 | ||
| 56 | } // namespace Shader::Maxwell | 59 | } // namespace Shader::Maxwell |
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index 259233746..7dab33034 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | |||
| @@ -38,6 +38,10 @@ struct ZeroFlagTag : FlagTag {}; | |||
| 38 | struct SignFlagTag : FlagTag {}; | 38 | struct SignFlagTag : FlagTag {}; |
| 39 | struct CarryFlagTag : FlagTag {}; | 39 | struct CarryFlagTag : FlagTag {}; |
| 40 | struct OverflowFlagTag : FlagTag {}; | 40 | struct OverflowFlagTag : FlagTag {}; |
| 41 | struct FCSMFlagTag : FlagTag {}; | ||
| 42 | struct TAFlagTag : FlagTag {}; | ||
| 43 | struct TRFlagTag : FlagTag {}; | ||
| 44 | struct MXFlagTag : FlagTag {}; | ||
| 41 | 45 | ||
| 42 | struct GotoVariable : FlagTag { | 46 | struct GotoVariable : FlagTag { |
| 43 | GotoVariable() = default; | 47 | GotoVariable() = default; |
| @@ -53,7 +57,8 @@ struct IndirectBranchVariable { | |||
| 53 | }; | 57 | }; |
| 54 | 58 | ||
| 55 | using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, | 59 | using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, |
| 56 | OverflowFlagTag, GotoVariable, IndirectBranchVariable>; | 60 | OverflowFlagTag, FCSMFlagTag, TAFlagTag, TRFlagTag, MXFlagTag, |
| 61 | GotoVariable, IndirectBranchVariable>; | ||
| 57 | using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; | 62 | using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; |
| 58 | 63 | ||
| 59 | struct DefTable { | 64 | struct DefTable { |
| @@ -89,6 +94,22 @@ struct DefTable { | |||
| 89 | return overflow_flag; | 94 | return overflow_flag; |
| 90 | } | 95 | } |
| 91 | 96 | ||
| 97 | [[nodiscard]] ValueMap& operator[](FCSMFlagTag) noexcept { | ||
| 98 | return fcsm_flag; | ||
| 99 | } | ||
| 100 | |||
| 101 | [[nodiscard]] ValueMap& operator[](TAFlagTag) noexcept { | ||
| 102 | return ta_flag; | ||
| 103 | } | ||
| 104 | |||
| 105 | [[nodiscard]] ValueMap& operator[](TRFlagTag) noexcept { | ||
| 106 | return tr_flag; | ||
| 107 | } | ||
| 108 | |||
| 109 | [[nodiscard]] ValueMap& operator[](MXFlagTag) noexcept { | ||
| 110 | return mr_flag; | ||
| 111 | } | ||
| 112 | |||
| 92 | std::array<ValueMap, IR::NUM_USER_REGS> regs; | 113 | std::array<ValueMap, IR::NUM_USER_REGS> regs; |
| 93 | std::array<ValueMap, IR::NUM_USER_PREDS> preds; | 114 | std::array<ValueMap, IR::NUM_USER_PREDS> preds; |
| 94 | boost::container::flat_map<u32, ValueMap> goto_vars; | 115 | boost::container::flat_map<u32, ValueMap> goto_vars; |
| @@ -97,6 +118,10 @@ struct DefTable { | |||
| 97 | ValueMap sign_flag; | 118 | ValueMap sign_flag; |
| 98 | ValueMap carry_flag; | 119 | ValueMap carry_flag; |
| 99 | ValueMap overflow_flag; | 120 | ValueMap overflow_flag; |
| 121 | ValueMap fcsm_flag; | ||
| 122 | ValueMap ta_flag; | ||
| 123 | ValueMap tr_flag; | ||
| 124 | ValueMap mr_flag; | ||
| 100 | }; | 125 | }; |
| 101 | 126 | ||
| 102 | IR::Opcode UndefOpcode(IR::Reg) noexcept { | 127 | IR::Opcode UndefOpcode(IR::Reg) noexcept { |
| @@ -247,6 +272,18 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) { | |||
| 247 | case IR::Opcode::SetOFlag: | 272 | case IR::Opcode::SetOFlag: |
| 248 | pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0)); | 273 | pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0)); |
| 249 | break; | 274 | break; |
| 275 | case IR::Opcode::SetFCSMFlag: | ||
| 276 | pass.WriteVariable(FCSMFlagTag{}, block, inst.Arg(0)); | ||
| 277 | break; | ||
| 278 | case IR::Opcode::SetTAFlag: | ||
| 279 | pass.WriteVariable(TAFlagTag{}, block, inst.Arg(0)); | ||
| 280 | break; | ||
| 281 | case IR::Opcode::SetTRFlag: | ||
| 282 | pass.WriteVariable(TRFlagTag{}, block, inst.Arg(0)); | ||
| 283 | break; | ||
| 284 | case IR::Opcode::SetMXFlag: | ||
| 285 | pass.WriteVariable(MXFlagTag{}, block, inst.Arg(0)); | ||
| 286 | break; | ||
| 250 | case IR::Opcode::GetRegister: | 287 | case IR::Opcode::GetRegister: |
| 251 | if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { | 288 | if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { |
| 252 | inst.ReplaceUsesWith(pass.ReadVariable(reg, block)); | 289 | inst.ReplaceUsesWith(pass.ReadVariable(reg, block)); |
| @@ -275,6 +312,18 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) { | |||
| 275 | case IR::Opcode::GetOFlag: | 312 | case IR::Opcode::GetOFlag: |
| 276 | inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block)); | 313 | inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block)); |
| 277 | break; | 314 | break; |
| 315 | case IR::Opcode::GetFCSMFlag: | ||
| 316 | inst.ReplaceUsesWith(pass.ReadVariable(FCSMFlagTag{}, block)); | ||
| 317 | break; | ||
| 318 | case IR::Opcode::GetTAFlag: | ||
| 319 | inst.ReplaceUsesWith(pass.ReadVariable(TAFlagTag{}, block)); | ||
| 320 | break; | ||
| 321 | case IR::Opcode::GetTRFlag: | ||
| 322 | inst.ReplaceUsesWith(pass.ReadVariable(TRFlagTag{}, block)); | ||
| 323 | break; | ||
| 324 | case IR::Opcode::GetMXFlag: | ||
| 325 | inst.ReplaceUsesWith(pass.ReadVariable(MXFlagTag{}, block)); | ||
| 326 | break; | ||
| 278 | default: | 327 | default: |
| 279 | break; | 328 | break; |
| 280 | } | 329 | } |