summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar FernandoS272021-04-03 01:48:39 +0200
committerGravatar ameerj2021-07-22 21:51:26 -0400
commitbaec84247fe815199595d9e8077b71f3b5c8317e (patch)
tree84195625ffb43922ba87b25296057bdeb9f22a2c /src
parentshader: Implement SR_LaneId (diff)
downloadyuzu-baec84247fe815199595d9e8077b71f3b5c8317e.tar.gz
yuzu-baec84247fe815199595d9e8077b71f3b5c8317e.tar.xz
yuzu-baec84247fe815199595d9e8077b71f3b5c8317e.zip
shader: Address Feedback
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.cpp3
-rw-r--r--src/shader_recompiler/backend/spirv/emit_context.h2
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.cpp4
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h12
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp37
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp39
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp49
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h12
-rw-r--r--src/shader_recompiler/frontend/ir/modifiers.h13
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc12
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp12
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp5
-rw-r--r--src/shader_recompiler/ir_opt/constant_propagation_pass.cpp9
-rw-r--r--src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp10
-rw-r--r--src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp50
16 files changed, 60 insertions, 211 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp
index 794cd4ed8..32f679f2a 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_context.cpp
@@ -510,7 +510,8 @@ void EmitContext::DefineOutputs(const Info& info) {
510 const Id type{TypeArray(F32[1], Constant(U32[1], 8U))}; 510 const Id type{TypeArray(F32[1], Constant(U32[1], 8U))};
511 clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance); 511 clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance);
512 } 512 }
513 if (info.stores_viewport_index && !ignore_viewport_layer) { 513 if (info.stores_viewport_index &&
514 (profile.support_viewport_index_layer_non_geometry || stage == Shader::Stage::Geometry)) {
514 if (stage == Stage::Fragment) { 515 if (stage == Stage::Fragment) {
515 throw NotImplementedException("Storing ViewportIndex in Fragment stage"); 516 throw NotImplementedException("Storing ViewportIndex in Fragment stage");
516 } 517 }
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h
index 1573c2560..f4715a709 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.h
+++ b/src/shader_recompiler/backend/spirv/emit_context.h
@@ -134,8 +134,6 @@ public:
134 134
135 std::vector<Id> interfaces; 135 std::vector<Id> interfaces;
136 136
137 bool ignore_viewport_layer{};
138
139private: 137private:
140 void DefineCommonTypes(const Info& info); 138 void DefineCommonTypes(const Info& info);
141 void DefineCommonConstants(); 139 void DefineCommonConstants();
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
index cc6b98f7e..191380db0 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
@@ -228,11 +228,9 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
228 if (info.stores_viewport_index) { 228 if (info.stores_viewport_index) {
229 ctx.AddCapability(spv::Capability::MultiViewport); 229 ctx.AddCapability(spv::Capability::MultiViewport);
230 if (profile.support_viewport_index_layer_non_geometry && 230 if (profile.support_viewport_index_layer_non_geometry &&
231 ctx.stage == Shader::Stage::VertexB) { 231 ctx.stage != Shader::Stage::Geometry) {
232 ctx.AddExtension("SPV_EXT_shader_viewport_index_layer"); 232 ctx.AddExtension("SPV_EXT_shader_viewport_index_layer");
233 ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); 233 ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT);
234 } else {
235 ctx.ignore_viewport_layer = true;
236 } 234 }
237 } 235 }
238 if (!profile.support_vertex_instance_id && (info.loads_instance_id || info.loads_vertex_id)) { 236 if (!profile.support_vertex_instance_id && (info.loads_instance_id || info.loads_vertex_id)) {
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index 17a452e0e..5d0f16b3a 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -28,7 +28,9 @@ void EmitSelectionMerge(EmitContext& ctx, Id merge_label);
28void EmitReturn(EmitContext& ctx); 28void EmitReturn(EmitContext& ctx);
29void EmitUnreachable(EmitContext& ctx); 29void EmitUnreachable(EmitContext& ctx);
30void EmitDemoteToHelperInvocation(EmitContext& ctx, Id continue_label); 30void EmitDemoteToHelperInvocation(EmitContext& ctx, Id continue_label);
31void EmitMemoryBarrier(EmitContext& ctx, IR::Inst* inst); 31void EmitMemoryBarrierWorkgroupLevel(EmitContext& ctx);
32void EmitMemoryBarrierDeviceLevel(EmitContext& ctx);
33void EmitMemoryBarrierSystemLevel(EmitContext& ctx);
32void EmitPrologue(EmitContext& ctx); 34void EmitPrologue(EmitContext& ctx);
33void EmitEpilogue(EmitContext& ctx); 35void EmitEpilogue(EmitContext& ctx);
34void EmitGetRegister(EmitContext& ctx); 36void EmitGetRegister(EmitContext& ctx);
@@ -60,14 +62,6 @@ void EmitSetZFlag(EmitContext& ctx);
60void EmitSetSFlag(EmitContext& ctx); 62void EmitSetSFlag(EmitContext& ctx);
61void EmitSetCFlag(EmitContext& ctx); 63void EmitSetCFlag(EmitContext& ctx);
62void EmitSetOFlag(EmitContext& ctx); 64void EmitSetOFlag(EmitContext& ctx);
63void EmitGetFCSMFlag(EmitContext& ctx);
64void EmitGetTAFlag(EmitContext& ctx);
65void EmitGetTRFlag(EmitContext& ctx);
66void EmitGetMXFlag(EmitContext& ctx);
67void EmitSetFCSMFlag(EmitContext& ctx);
68void EmitSetTAFlag(EmitContext& ctx);
69void EmitSetTRFlag(EmitContext& ctx);
70void EmitSetMXFlag(EmitContext& ctx);
71Id EmitWorkgroupId(EmitContext& ctx); 65Id EmitWorkgroupId(EmitContext& ctx);
72Id EmitLocalInvocationId(EmitContext& ctx); 66Id EmitLocalInvocationId(EmitContext& ctx);
73Id EmitLoadLocal(EmitContext& ctx, Id word_offset); 67Id EmitLoadLocal(EmitContext& ctx, Id word_offset);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp
index 413ac25a0..18f512319 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp
@@ -7,34 +7,27 @@
7 7
8namespace Shader::Backend::SPIRV { 8namespace Shader::Backend::SPIRV {
9namespace { 9namespace {
10spv::Scope MemoryScopeToSpirVScope(IR::MemoryScope scope) { 10void EmitMemoryBarrierImpl(EmitContext& ctx, spv::Scope scope) {
11 switch (scope) {
12 case IR::MemoryScope::Warp:
13 return spv::Scope::Subgroup;
14 case IR::MemoryScope::Workgroup:
15 return spv::Scope::Workgroup;
16 case IR::MemoryScope::Device:
17 return spv::Scope::Device;
18 case IR::MemoryScope::System:
19 return spv::Scope::CrossDevice;
20 case IR::MemoryScope::DontCare:
21 return spv::Scope::Invocation;
22 default:
23 throw NotImplementedException("Unknown memory scope!");
24 }
25}
26
27} // namespace
28
29void EmitMemoryBarrier(EmitContext& ctx, IR::Inst* inst) {
30 const auto info{inst->Flags<IR::BarrierInstInfo>()};
31 const auto semantics = 11 const auto semantics =
32 spv::MemorySemanticsMask::AcquireRelease | spv::MemorySemanticsMask::UniformMemory | 12 spv::MemorySemanticsMask::AcquireRelease | spv::MemorySemanticsMask::UniformMemory |
33 spv::MemorySemanticsMask::WorkgroupMemory | spv::MemorySemanticsMask::AtomicCounterMemory | 13 spv::MemorySemanticsMask::WorkgroupMemory | spv::MemorySemanticsMask::AtomicCounterMemory |
34 spv::MemorySemanticsMask::ImageMemory; 14 spv::MemorySemanticsMask::ImageMemory;
35 const auto scope = MemoryScopeToSpirVScope(info.scope);
36 ctx.OpMemoryBarrier(ctx.Constant(ctx.U32[1], static_cast<u32>(scope)), 15 ctx.OpMemoryBarrier(ctx.Constant(ctx.U32[1], static_cast<u32>(scope)),
37 ctx.Constant(ctx.U32[1], static_cast<u32>(semantics))); 16 ctx.Constant(ctx.U32[1], static_cast<u32>(semantics)));
38} 17}
39 18
19} // Anonymous namespace
20
21void EmitMemoryBarrierWorkgroupLevel(EmitContext& ctx) {
22 EmitMemoryBarrierImpl(ctx, spv::Scope::Workgroup);
23}
24
25void EmitMemoryBarrierDeviceLevel(EmitContext& ctx) {
26 EmitMemoryBarrierImpl(ctx, spv::Scope::Device);
27}
28
29void EmitMemoryBarrierSystemLevel(EmitContext& ctx) {
30 EmitMemoryBarrierImpl(ctx, spv::Scope::CrossDevice);
31}
32
40} // namespace Shader::Backend::SPIRV 33} // namespace Shader::Backend::SPIRV
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 f13c0ee72..caab9aa12 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
@@ -58,7 +58,10 @@ std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
58 return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num); 58 return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num);
59 } 59 }
60 case IR::Attribute::ViewportIndex: 60 case IR::Attribute::ViewportIndex:
61 return ctx.ignore_viewport_layer ? std::nullopt : std::optional<Id>{ctx.viewport_index}; 61 return (ctx.profile.support_viewport_index_layer_non_geometry ||
62 ctx.stage == Shader::Stage::Geometry)
63 ? std::optional<Id>{ctx.viewport_index}
64 : std::nullopt;
62 default: 65 default:
63 throw NotImplementedException("Read attribute {}", attr); 66 throw NotImplementedException("Read attribute {}", attr);
64 } 67 }
@@ -206,7 +209,7 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr) {
206} 209}
207 210
208void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value) { 211void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value) {
209 auto output = OutputAttrPointer(ctx, attr); 212 const std::optional<Id> output{OutputAttrPointer(ctx, attr)};
210 if (!output) { 213 if (!output) {
211 return; 214 return;
212 } 215 }
@@ -263,38 +266,6 @@ void EmitSetOFlag(EmitContext&) {
263 throw NotImplementedException("SPIR-V Instruction"); 266 throw NotImplementedException("SPIR-V Instruction");
264} 267}
265 268
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
298Id EmitWorkgroupId(EmitContext& ctx) { 269Id EmitWorkgroupId(EmitContext& ctx) {
299 return ctx.OpLoad(ctx.U32[3], ctx.workgroup_id); 270 return ctx.OpLoad(ctx.U32[3], ctx.workgroup_id);
300} 271}
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index b5f61956a..5e94edd74 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -82,8 +82,17 @@ void IREmitter::SelectionMerge(Block* merge_block) {
82 Inst(Opcode::SelectionMerge, merge_block); 82 Inst(Opcode::SelectionMerge, merge_block);
83} 83}
84 84
85void IREmitter::MemoryBarrier(BarrierInstInfo info) { 85void IREmitter::MemoryBarrier(MemoryScope scope) {
86 Inst(Opcode::MemoryBarrier, Flags{info}); 86 switch (scope) {
87 case MemoryScope::Workgroup:
88 Inst(Opcode::MemoryBarrierWorkgroupLevel);
89 case MemoryScope::Device:
90 Inst(Opcode::MemoryBarrierDeviceLevel);
91 case MemoryScope::System:
92 Inst(Opcode::MemoryBarrierSystemLevel);
93 default:
94 throw InvalidArgument("Invalid memory scope {}", scope);
95 }
87} 96}
88 97
89void IREmitter::Return() { 98void IREmitter::Return() {
@@ -202,38 +211,6 @@ void IREmitter::SetOFlag(const U1& value) {
202 Inst(Opcode::SetOFlag, value); 211 Inst(Opcode::SetOFlag, value);
203} 212}
204 213
205U1 IREmitter::GetFCSMFlag() {
206 return Inst<U1>(Opcode::GetFCSMFlag);
207}
208
209U1 IREmitter::GetTAFlag() {
210 return Inst<U1>(Opcode::GetTAFlag);
211}
212
213U1 IREmitter::GetTRFlag() {
214 return Inst<U1>(Opcode::GetTRFlag);
215}
216
217U1 IREmitter::GetMXFlag() {
218 return Inst<U1>(Opcode::GetMXFlag);
219}
220
221void IREmitter::SetFCSMFlag(const U1& value) {
222 Inst(Opcode::SetFCSMFlag, value);
223}
224
225void IREmitter::SetTAFlag(const U1& value) {
226 Inst(Opcode::SetTAFlag, value);
227}
228
229void IREmitter::SetTRFlag(const U1& value) {
230 Inst(Opcode::SetTRFlag, value);
231}
232
233void IREmitter::SetMXFlag(const U1& value) {
234 Inst(Opcode::SetMXFlag, value);
235}
236
237static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { 214static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) {
238 switch (flow_test) { 215 switch (flow_test) {
239 case FlowTest::F: 216 case FlowTest::F:
@@ -292,9 +269,9 @@ static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) {
292 return ir.LogicalOr(ir.GetSFlag(), ir.GetZFlag()); 269 return ir.LogicalOr(ir.GetSFlag(), ir.GetZFlag());
293 case FlowTest::RGT: 270 case FlowTest::RGT:
294 return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag())); 271 return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag()));
295
296 case FlowTest::FCSM_TR: 272 case FlowTest::FCSM_TR:
297 return ir.LogicalAnd(ir.GetFCSMFlag(), ir.GetTRFlag()); 273 // LOG_WARNING(ShaderDecompiler, "FCSM_TR CC State (Stubbed)");
274 return ir.Imm1(false);
298 case FlowTest::CSM_TA: 275 case FlowTest::CSM_TA:
299 case FlowTest::CSM_TR: 276 case FlowTest::CSM_TR:
300 case FlowTest::CSM_MX: 277 case FlowTest::CSM_MX:
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index e034d672f..14b743975 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -70,16 +70,6 @@ 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
83 [[nodiscard]] U1 Condition(IR::Condition cond); 73 [[nodiscard]] U1 Condition(IR::Condition cond);
84 [[nodiscard]] U1 GetFlowTestResult(FlowTest test); 74 [[nodiscard]] U1 GetFlowTestResult(FlowTest test);
85 75
@@ -138,7 +128,7 @@ public:
138 [[nodiscard]] Value Select(const U1& condition, const Value& true_value, 128 [[nodiscard]] Value Select(const U1& condition, const Value& true_value,
139 const Value& false_value); 129 const Value& false_value);
140 130
141 [[nodiscard]] void MemoryBarrier(BarrierInstInfo info); 131 [[nodiscard]] void MemoryBarrier(MemoryScope scope);
142 132
143 template <typename Dest, typename Source> 133 template <typename Dest, typename Source>
144 [[nodiscard]] Dest BitCast(const Source& value); 134 [[nodiscard]] Dest BitCast(const Source& value);
diff --git a/src/shader_recompiler/frontend/ir/modifiers.h b/src/shader_recompiler/frontend/ir/modifiers.h
index 7730c25a9..2aa4ac79b 100644
--- a/src/shader_recompiler/frontend/ir/modifiers.h
+++ b/src/shader_recompiler/frontend/ir/modifiers.h
@@ -25,13 +25,7 @@ enum class FpRounding : u8 {
25 RZ, // Round towards zero 25 RZ, // Round towards zero
26}; 26};
27 27
28enum class MemoryScope : u32 { 28enum class MemoryScope : u32 { DontCare, Warp, Workgroup, Device, System };
29 DontCare,
30 Warp,
31 Workgroup,
32 Device,
33 System
34};
35 29
36struct FpControl { 30struct FpControl {
37 bool no_contraction{false}; 31 bool no_contraction{false};
@@ -40,11 +34,6 @@ struct FpControl {
40}; 34};
41static_assert(sizeof(FpControl) <= sizeof(u32)); 35static_assert(sizeof(FpControl) <= sizeof(u32));
42 36
43union BarrierInstInfo {
44 u32 raw;
45 BitField<0, 3, MemoryScope> scope;
46};
47
48union TextureInstInfo { 37union TextureInstInfo {
49 u32 raw; 38 u32 raw;
50 BitField<0, 8, TextureType> type; 39 BitField<0, 8, TextureType> type;
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index 74e956930..3640a5d24 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -17,7 +17,9 @@ OPCODE(Unreachable, Void,
17OPCODE(DemoteToHelperInvocation, Void, Label, ) 17OPCODE(DemoteToHelperInvocation, Void, Label, )
18 18
19// Barriers 19// Barriers
20OPCODE(MemoryBarrier, Void, ) 20OPCODE(MemoryBarrierWorkgroupLevel, Void, )
21OPCODE(MemoryBarrierDeviceLevel, Void, )
22OPCODE(MemoryBarrierSystemLevel, Void, )
21 23
22// Special operations 24// Special operations
23OPCODE(Prologue, Void, ) 25OPCODE(Prologue, Void, )
@@ -49,18 +51,10 @@ OPCODE(GetZFlag, U1, Void
49OPCODE(GetSFlag, U1, Void, ) 51OPCODE(GetSFlag, U1, Void, )
50OPCODE(GetCFlag, U1, Void, ) 52OPCODE(GetCFlag, U1, Void, )
51OPCODE(GetOFlag, U1, Void, ) 53OPCODE(GetOFlag, U1, Void, )
52OPCODE(GetFCSMFlag, U1, Void, )
53OPCODE(GetTAFlag, U1, Void, )
54OPCODE(GetTRFlag, U1, Void, )
55OPCODE(GetMXFlag, U1, Void, )
56OPCODE(SetZFlag, Void, U1, ) 54OPCODE(SetZFlag, Void, U1, )
57OPCODE(SetSFlag, Void, U1, ) 55OPCODE(SetSFlag, Void, U1, )
58OPCODE(SetCFlag, Void, U1, ) 56OPCODE(SetCFlag, Void, U1, )
59OPCODE(SetOFlag, Void, U1, ) 57OPCODE(SetOFlag, Void, U1, )
60OPCODE(SetFCSMFlag, Void, U1, )
61OPCODE(SetTAFlag, Void, U1, )
62OPCODE(SetTRFlag, Void, U1, )
63OPCODE(SetMXFlag, Void, U1, )
64OPCODE(WorkgroupId, U32x3, ) 58OPCODE(WorkgroupId, U32x3, )
65OPCODE(LocalInvocationId, U32x3, ) 59OPCODE(LocalInvocationId, U32x3, )
66OPCODE(LaneId, U32, ) 60OPCODE(LaneId, U32, )
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp
index 933af572c..26d5e276b 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp
@@ -5,8 +5,8 @@
5#include "common/bit_field.h" 5#include "common/bit_field.h"
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "shader_recompiler/frontend/ir/modifiers.h" 7#include "shader_recompiler/frontend/ir/modifiers.h"
8#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
9#include "shader_recompiler/frontend/maxwell/opcodes.h" 8#include "shader_recompiler/frontend/maxwell/opcodes.h"
9#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
10 10
11namespace Shader::Maxwell { 11namespace Shader::Maxwell {
12namespace { 12namespace {
@@ -21,28 +21,24 @@ enum class LocalScope : u64 {
21IR::MemoryScope LocalScopeToMemoryScope(LocalScope scope) { 21IR::MemoryScope LocalScopeToMemoryScope(LocalScope scope) {
22 switch (scope) { 22 switch (scope) {
23 case LocalScope::CTG: 23 case LocalScope::CTG:
24 return IR::MemoryScope::Warp; 24 return IR::MemoryScope::Workgroup;
25 case LocalScope::GL: 25 case LocalScope::GL:
26 return IR::MemoryScope::Device; 26 return IR::MemoryScope::Device;
27 case LocalScope::SYS: 27 case LocalScope::SYS:
28 return IR::MemoryScope::System; 28 return IR::MemoryScope::System;
29 case LocalScope::VC:
30 return IR::MemoryScope::Workgroup; // or should be device?
31 default: 29 default:
32 throw NotImplementedException("Unimplemented Local Scope {}", scope); 30 throw NotImplementedException("Unimplemented Local Scope {}", scope);
33 } 31 }
34} 32}
35 33
36} // namespace 34} // Anonymous namespace
37 35
38void TranslatorVisitor::MEMBAR(u64 inst) { 36void TranslatorVisitor::MEMBAR(u64 inst) {
39 union { 37 union {
40 u64 raw; 38 u64 raw;
41 BitField<8, 2, LocalScope> scope; 39 BitField<8, 2, LocalScope> scope;
42 } membar{inst}; 40 } membar{inst};
43 IR::BarrierInstInfo info{}; 41 ir.MemoryBarrier(LocalScopeToMemoryScope(membar.scope));
44 info.scope.Assign(LocalScopeToMemoryScope(membar.scope));
45 ir.MemoryBarrier(info);
46} 42}
47 43
48void TranslatorVisitor::DEPBAR() { 44void TranslatorVisitor::DEPBAR() {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp
index 731ac643f..7d9c42a83 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp
@@ -96,8 +96,10 @@ enum class SpecialRegister : u64 {
96 case SpecialRegister::SR_CTAID_Z: 96 case SpecialRegister::SR_CTAID_Z:
97 return ir.WorkgroupIdZ(); 97 return ir.WorkgroupIdZ();
98 case SpecialRegister::SR_WSCALEFACTOR_XY: 98 case SpecialRegister::SR_WSCALEFACTOR_XY:
99 // LOG_WARNING(ShaderDecompiler, "SR_WSCALEFACTOR_XY (Stubbed)");
99 return ir.Imm32(Common::BitCast<u32>(1.0f)); 100 return ir.Imm32(Common::BitCast<u32>(1.0f));
100 case SpecialRegister::SR_WSCALEFACTOR_Z: 101 case SpecialRegister::SR_WSCALEFACTOR_Z:
102 // LOG_WARNING(ShaderDecompiler, "SR_WSCALEFACTOR_Z (Stubbed)");
101 return ir.Imm32(Common::BitCast<u32>(1.0f)); 103 return ir.Imm32(Common::BitCast<u32>(1.0f));
102 case SpecialRegister::SR_LANEID: 104 case SpecialRegister::SR_LANEID:
103 return ir.LaneId(); 105 return ir.LaneId();
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp
index 2acabb662..d508e1e23 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp
@@ -50,10 +50,7 @@ void TranslatorVisitor::VOTE(u64 insn) {
50} 50}
51 51
52void TranslatorVisitor::VOTE_vtg(u64) { 52void TranslatorVisitor::VOTE_vtg(u64) {
53 // LOG_WARNING("VOTE.VTG: Stubbed!"); 53 // LOG_WARNING(ShaderDecompiler, "VOTE.VTG: Stubbed!");
54 auto imm = ir.Imm1(false);
55 ir.SetFCSMFlag(imm);
56 ir.SetTRFlag(imm);
57} 54}
58 55
59} // namespace Shader::Maxwell 56} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
index 8999c3a3d..1720d7a09 100644
--- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
+++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
@@ -374,17 +374,14 @@ std::optional<IR::Value> FoldCompositeExtractImpl(IR::Value inst_value, IR::Opco
374 if (inst->Opcode() == construct) { 374 if (inst->Opcode() == construct) {
375 return inst->Arg(first_index); 375 return inst->Arg(first_index);
376 } 376 }
377
378 if (inst->Opcode() != insert) { 377 if (inst->Opcode() != insert) {
379 return std::nullopt; 378 return std::nullopt;
380 } 379 }
381
382 IR::Value value_index{inst->Arg(2)}; 380 IR::Value value_index{inst->Arg(2)};
383 if (!value_index.IsImmediate()) { 381 if (!value_index.IsImmediate()) {
384 return std::nullopt; 382 return std::nullopt;
385 } 383 }
386 384 const u32 second_index{value_index.U32()};
387 const u32 second_index = value_index.U32();
388 if (first_index != second_index) { 385 if (first_index != second_index) {
389 IR::Value value_composite{inst->Arg(0)}; 386 IR::Value value_composite{inst->Arg(0)};
390 if (value_composite.IsImmediate()) { 387 if (value_composite.IsImmediate()) {
@@ -404,8 +401,8 @@ void FoldCompositeExtract(IR::Inst& inst, IR::Opcode construct, IR::Opcode inser
404 if (!value_2.IsImmediate()) { 401 if (!value_2.IsImmediate()) {
405 return; 402 return;
406 } 403 }
407 const u32 first_index = value_2.U32(); 404 const u32 first_index{value_2.U32()};
408 auto result = FoldCompositeExtractImpl(value_1, insert, construct, first_index); 405 const std::optional result{FoldCompositeExtractImpl(value_1, insert, construct, first_index)};
409 if (!result) { 406 if (!result) {
410 return; 407 return;
411 } 408 }
diff --git a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
index d4bae249b..8876a5c33 100644
--- a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
+++ b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
@@ -4,9 +4,9 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <compare> 6#include <compare>
7#include <map>
7#include <optional> 8#include <optional>
8#include <ranges> 9#include <ranges>
9#include <map>
10 10
11#include <boost/container/flat_set.hpp> 11#include <boost/container/flat_set.hpp>
12#include <boost/container/small_vector.hpp> 12#include <boost/container/small_vector.hpp>
@@ -295,12 +295,12 @@ void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageBufferSet& s
295 } 295 }
296 } 296 }
297 // Collect storage buffer and the instruction 297 // Collect storage buffer and the instruction
298 const bool is_a_write = IsGlobalMemoryWrite(inst); 298 const bool is_a_write{IsGlobalMemoryWrite(inst)};
299 auto it = writes_map.find(*storage_buffer); 299 auto it{writes_map.find(*storage_buffer)};
300 if (it == writes_map.end()) { 300 if (it == writes_map.end()) {
301 writes_map[*storage_buffer] = is_a_write; 301 writes_map[*storage_buffer] = is_a_write;
302 } else { 302 } else {
303 it->second = it->second || is_a_write; 303 it->second = it->second || is_a_write;
304 } 304 }
305 storage_buffer_set.insert(*storage_buffer); 305 storage_buffer_set.insert(*storage_buffer);
306 to_replace.push_back(StorageInst{ 306 to_replace.push_back(StorageInst{
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
index 7dab33034..72d4abb77 100644
--- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
+++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
@@ -38,10 +38,6 @@ 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 {};
45 41
46struct GotoVariable : FlagTag { 42struct GotoVariable : FlagTag {
47 GotoVariable() = default; 43 GotoVariable() = default;
@@ -57,8 +53,7 @@ struct IndirectBranchVariable {
57}; 53};
58 54
59using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, 55using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag,
60 OverflowFlagTag, FCSMFlagTag, TAFlagTag, TRFlagTag, MXFlagTag, 56 OverflowFlagTag, GotoVariable, IndirectBranchVariable>;
61 GotoVariable, IndirectBranchVariable>;
62using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; 57using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>;
63 58
64struct DefTable { 59struct DefTable {
@@ -94,22 +89,6 @@ struct DefTable {
94 return overflow_flag; 89 return overflow_flag;
95 } 90 }
96 91
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
113 std::array<ValueMap, IR::NUM_USER_REGS> regs; 92 std::array<ValueMap, IR::NUM_USER_REGS> regs;
114 std::array<ValueMap, IR::NUM_USER_PREDS> preds; 93 std::array<ValueMap, IR::NUM_USER_PREDS> preds;
115 boost::container::flat_map<u32, ValueMap> goto_vars; 94 boost::container::flat_map<u32, ValueMap> goto_vars;
@@ -118,10 +97,6 @@ struct DefTable {
118 ValueMap sign_flag; 97 ValueMap sign_flag;
119 ValueMap carry_flag; 98 ValueMap carry_flag;
120 ValueMap overflow_flag; 99 ValueMap overflow_flag;
121 ValueMap fcsm_flag;
122 ValueMap ta_flag;
123 ValueMap tr_flag;
124 ValueMap mr_flag;
125}; 100};
126 101
127IR::Opcode UndefOpcode(IR::Reg) noexcept { 102IR::Opcode UndefOpcode(IR::Reg) noexcept {
@@ -272,18 +247,6 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) {
272 case IR::Opcode::SetOFlag: 247 case IR::Opcode::SetOFlag:
273 pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0)); 248 pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0));
274 break; 249 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;
287 case IR::Opcode::GetRegister: 250 case IR::Opcode::GetRegister:
288 if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { 251 if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) {
289 inst.ReplaceUsesWith(pass.ReadVariable(reg, block)); 252 inst.ReplaceUsesWith(pass.ReadVariable(reg, block));
@@ -312,17 +275,6 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) {
312 case IR::Opcode::GetOFlag: 275 case IR::Opcode::GetOFlag:
313 inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block)); 276 inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block));
314 break; 277 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 break;
327 default: 279 default:
328 break; 280 break;