summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar FernandoS272021-04-01 22:20:57 +0200
committerGravatar ameerj2021-07-22 21:51:25 -0400
commitecb30c907266921818d5b6b03e341028fa2ea082 (patch)
tree8bf3f0097653fa11b6dae823f79fe671204ad55e /src
parentshader: Mark SSBOs as written when they are (diff)
downloadyuzu-ecb30c907266921818d5b6b03e341028fa2ea082.tar.gz
yuzu-ecb30c907266921818d5b6b03e341028fa2ea082.tar.xz
yuzu-ecb30c907266921818d5b6b03e341028fa2ea082.zip
shader: Improve VOTE.VTG stub
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h8
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp32
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp37
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h10
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc8
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp5
-rw-r--r--src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp51
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);
59void EmitSetSFlag(EmitContext& ctx); 59void EmitSetSFlag(EmitContext& ctx);
60void EmitSetCFlag(EmitContext& ctx); 60void EmitSetCFlag(EmitContext& ctx);
61void EmitSetOFlag(EmitContext& ctx); 61void EmitSetOFlag(EmitContext& ctx);
62void EmitGetFCSMFlag(EmitContext& ctx);
63void EmitGetTAFlag(EmitContext& ctx);
64void EmitGetTRFlag(EmitContext& ctx);
65void EmitGetMXFlag(EmitContext& ctx);
66void EmitSetFCSMFlag(EmitContext& ctx);
67void EmitSetTAFlag(EmitContext& ctx);
68void EmitSetTRFlag(EmitContext& ctx);
69void EmitSetMXFlag(EmitContext& ctx);
62Id EmitWorkgroupId(EmitContext& ctx); 70Id EmitWorkgroupId(EmitContext& ctx);
63Id EmitLocalInvocationId(EmitContext& ctx); 71Id EmitLocalInvocationId(EmitContext& ctx);
64Id EmitLoadLocal(EmitContext& ctx, Id word_offset); 72Id 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
266void EmitGetFCSMFlag(EmitContext&) {
267 throw NotImplementedException("SPIR-V Instruction");
268}
269
270void EmitGetTAFlag(EmitContext&) {
271 throw NotImplementedException("SPIR-V Instruction");
272}
273
274void EmitGetTRFlag(EmitContext&) {
275 throw NotImplementedException("SPIR-V Instruction");
276}
277
278void EmitGetMXFlag(EmitContext&) {
279 throw NotImplementedException("SPIR-V Instruction");
280}
281
282void EmitSetFCSMFlag(EmitContext&) {
283 throw NotImplementedException("SPIR-V Instruction");
284}
285
286void EmitSetTAFlag(EmitContext&) {
287 throw NotImplementedException("SPIR-V Instruction");
288}
289
290void EmitSetTRFlag(EmitContext&) {
291 throw NotImplementedException("SPIR-V Instruction");
292}
293
294void EmitSetMXFlag(EmitContext&) {
295 throw NotImplementedException("SPIR-V Instruction");
296}
297
266Id EmitWorkgroupId(EmitContext& ctx) { 298Id 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
201U1 IREmitter::GetFCSMFlag() {
202 return Inst<U1>(Opcode::GetFCSMFlag);
203}
204
205U1 IREmitter::GetTAFlag() {
206 return Inst<U1>(Opcode::GetTAFlag);
207}
208
209U1 IREmitter::GetTRFlag() {
210 return Inst<U1>(Opcode::GetTRFlag);
211}
212
213U1 IREmitter::GetMXFlag() {
214 return Inst<U1>(Opcode::GetMXFlag);
215}
216
217void IREmitter::SetFCSMFlag(const U1& value) {
218 Inst(Opcode::SetFCSMFlag, value);
219}
220
221void IREmitter::SetTAFlag(const U1& value) {
222 Inst(Opcode::SetTAFlag, value);
223}
224
225void IREmitter::SetTRFlag(const U1& value) {
226 Inst(Opcode::SetTRFlag, value);
227}
228
229void IREmitter::SetMXFlag(const U1& value) {
230 Inst(Opcode::SetMXFlag, value);
231}
232
201static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { 233static 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
46OPCODE(GetSFlag, U1, Void, ) 46OPCODE(GetSFlag, U1, Void, )
47OPCODE(GetCFlag, U1, Void, ) 47OPCODE(GetCFlag, U1, Void, )
48OPCODE(GetOFlag, U1, Void, ) 48OPCODE(GetOFlag, U1, Void, )
49OPCODE(GetFCSMFlag, U1, Void, )
50OPCODE(GetTAFlag, U1, Void, )
51OPCODE(GetTRFlag, U1, Void, )
52OPCODE(GetMXFlag, U1, Void, )
49OPCODE(SetZFlag, Void, U1, ) 53OPCODE(SetZFlag, Void, U1, )
50OPCODE(SetSFlag, Void, U1, ) 54OPCODE(SetSFlag, Void, U1, )
51OPCODE(SetCFlag, Void, U1, ) 55OPCODE(SetCFlag, Void, U1, )
52OPCODE(SetOFlag, Void, U1, ) 56OPCODE(SetOFlag, Void, U1, )
57OPCODE(SetFCSMFlag, Void, U1, )
58OPCODE(SetTAFlag, Void, U1, )
59OPCODE(SetTRFlag, Void, U1, )
60OPCODE(SetMXFlag, Void, U1, )
53OPCODE(WorkgroupId, U32x3, ) 61OPCODE(WorkgroupId, U32x3, )
54OPCODE(LocalInvocationId, U32x3, ) 62OPCODE(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
52void TranslatorVisitor::VOTE_vtg(u64) { 52void 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 {};
38struct SignFlagTag : FlagTag {}; 38struct SignFlagTag : FlagTag {};
39struct CarryFlagTag : FlagTag {}; 39struct CarryFlagTag : FlagTag {};
40struct OverflowFlagTag : FlagTag {}; 40struct OverflowFlagTag : FlagTag {};
41struct FCSMFlagTag : FlagTag {};
42struct TAFlagTag : FlagTag {};
43struct TRFlagTag : FlagTag {};
44struct MXFlagTag : FlagTag {};
41 45
42struct GotoVariable : FlagTag { 46struct GotoVariable : FlagTag {
43 GotoVariable() = default; 47 GotoVariable() = default;
@@ -53,7 +57,8 @@ struct IndirectBranchVariable {
53}; 57};
54 58
55using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, 59using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag,
56 OverflowFlagTag, GotoVariable, IndirectBranchVariable>; 60 OverflowFlagTag, FCSMFlagTag, TAFlagTag, TRFlagTag, MXFlagTag,
61 GotoVariable, IndirectBranchVariable>;
57using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; 62using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>;
58 63
59struct DefTable { 64struct 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
102IR::Opcode UndefOpcode(IR::Reg) noexcept { 127IR::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 }