Răsfoiți Sursa

shader: Fix memory barriers

ReinUsesLisp 5 ani în urmă
părinte
comite
0a0818c025

+ 2 - 3
src/shader_recompiler/backend/spirv/emit_spirv.h

@@ -29,9 +29,8 @@ void EmitReturn(EmitContext& ctx);
 void EmitUnreachable(EmitContext& ctx);
 void EmitDemoteToHelperInvocation(EmitContext& ctx, Id continue_label);
 void EmitBarrier(EmitContext& ctx);
-void EmitMemoryBarrierWorkgroupLevel(EmitContext& ctx);
-void EmitMemoryBarrierDeviceLevel(EmitContext& ctx);
-void EmitMemoryBarrierSystemLevel(EmitContext& ctx);
+void EmitWorkgroupMemoryBarrier(EmitContext& ctx);
+void EmitDeviceMemoryBarrier(EmitContext& ctx);
 void EmitPrologue(EmitContext& ctx);
 void EmitEpilogue(EmitContext& ctx);
 void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream);

+ 5 - 9
src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp

@@ -7,7 +7,7 @@
 
 namespace Shader::Backend::SPIRV {
 namespace {
-void EmitMemoryBarrierImpl(EmitContext& ctx, spv::Scope scope) {
+void MemoryBarrier(EmitContext& ctx, spv::Scope scope) {
     const auto semantics{
         spv::MemorySemanticsMask::AcquireRelease | spv::MemorySemanticsMask::UniformMemory |
         spv::MemorySemanticsMask::WorkgroupMemory | spv::MemorySemanticsMask::AtomicCounterMemory |
@@ -27,16 +27,12 @@ void EmitBarrier(EmitContext& ctx) {
                          ctx.Constant(ctx.U32[1], static_cast<u32>(memory_semantics)));
 }
 
-void EmitMemoryBarrierWorkgroupLevel(EmitContext& ctx) {
-    EmitMemoryBarrierImpl(ctx, spv::Scope::Workgroup);
+void EmitWorkgroupMemoryBarrier(EmitContext& ctx) {
+    MemoryBarrier(ctx, spv::Scope::Workgroup);
 }
 
-void EmitMemoryBarrierDeviceLevel(EmitContext& ctx) {
-    EmitMemoryBarrierImpl(ctx, spv::Scope::Device);
-}
-
-void EmitMemoryBarrierSystemLevel(EmitContext& ctx) {
-    EmitMemoryBarrierImpl(ctx, spv::Scope::CrossDevice);
+void EmitDeviceMemoryBarrier(EmitContext& ctx) {
+    MemoryBarrier(ctx, spv::Scope::Device);
 }
 
 } // namespace Shader::Backend::SPIRV

+ 6 - 14
src/shader_recompiler/frontend/ir/ir_emitter.cpp

@@ -86,20 +86,12 @@ void IREmitter::Barrier() {
     Inst(Opcode::Barrier);
 }
 
-void IREmitter::MemoryBarrier(MemoryScope scope) {
-    switch (scope) {
-    case MemoryScope::Workgroup:
-        Inst(Opcode::MemoryBarrierWorkgroupLevel);
-        break;
-    case MemoryScope::Device:
-        Inst(Opcode::MemoryBarrierDeviceLevel);
-        break;
-    case MemoryScope::System:
-        Inst(Opcode::MemoryBarrierSystemLevel);
-        break;
-    default:
-        throw InvalidArgument("Invalid memory scope {}", scope);
-    }
+void IREmitter::WorkgroupMemoryBarrier() {
+    Inst(Opcode::WorkgroupMemoryBarrier);
+}
+
+void IREmitter::DeviceMemoryBarrier() {
+    Inst(Opcode::DeviceMemoryBarrier);
 }
 
 void IREmitter::Return() {

+ 3 - 2
src/shader_recompiler/frontend/ir/ir_emitter.h

@@ -144,8 +144,9 @@ public:
     [[nodiscard]] Value Select(const U1& condition, const Value& true_value,
                                const Value& false_value);
 
-    [[nodiscard]] void Barrier();
-    [[nodiscard]] void MemoryBarrier(MemoryScope scope);
+    void Barrier();
+    void WorkgroupMemoryBarrier();
+    void DeviceMemoryBarrier();
 
     template <typename Dest, typename Source>
     [[nodiscard]] Dest BitCast(const Source& value);

+ 2 - 3
src/shader_recompiler/frontend/ir/microinstruction.cpp

@@ -64,9 +64,8 @@ bool Inst::MayHaveSideEffects() const noexcept {
     case Opcode::Unreachable:
     case Opcode::DemoteToHelperInvocation:
     case Opcode::Barrier:
-    case Opcode::MemoryBarrierWorkgroupLevel:
-    case Opcode::MemoryBarrierDeviceLevel:
-    case Opcode::MemoryBarrierSystemLevel:
+    case Opcode::WorkgroupMemoryBarrier:
+    case Opcode::DeviceMemoryBarrier:
     case Opcode::Prologue:
     case Opcode::Epilogue:
     case Opcode::EmitVertex:

+ 0 - 8
src/shader_recompiler/frontend/ir/modifiers.h

@@ -25,14 +25,6 @@ enum class FpRounding : u8 {
     RZ,       // Round towards zero
 };
 
-enum class MemoryScope : u32 {
-    DontCare,
-    Warp,
-    Workgroup,
-    Device,
-    System,
-};
-
 struct FpControl {
     bool no_contraction{false};
     FpRounding rounding{FpRounding::DontCare};

+ 2 - 3
src/shader_recompiler/frontend/ir/opcodes.inc

@@ -18,9 +18,8 @@ OPCODE(DemoteToHelperInvocation,                            Void,           Labe
 
 // Barriers
 OPCODE(Barrier,                                             Void,                                                                                           )
-OPCODE(MemoryBarrierWorkgroupLevel,                         Void,                                                                                           )
-OPCODE(MemoryBarrierDeviceLevel,                            Void,                                                                                           )
-OPCODE(MemoryBarrierSystemLevel,                            Void,                                                                                           )
+OPCODE(WorkgroupMemoryBarrier,                              Void,                                                                                           )
+OPCODE(DeviceMemoryBarrier,                                 Void,                                                                                           )
 
 // Special operations
 OPCODE(Prologue,                                            Void,                                                                                           )

+ 10 - 20
src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp

@@ -12,34 +12,24 @@ namespace Shader::Maxwell {
 namespace {
 // Seems to be in CUDA terminology.
 enum class LocalScope : u64 {
-    CTG = 0,
-    GL = 1,
-    SYS = 2,
-    VC = 3,
+    CTA,
+    GL,
+    SYS,
+    VC,
 };
-
-IR::MemoryScope LocalScopeToMemoryScope(LocalScope scope) {
-    switch (scope) {
-    case LocalScope::CTG:
-        return IR::MemoryScope::Workgroup;
-    case LocalScope::GL:
-        return IR::MemoryScope::Device;
-    case LocalScope::SYS:
-        return IR::MemoryScope::System;
-    default:
-        throw NotImplementedException("Unimplemented Local Scope {}", scope);
-    }
-}
-
 } // Anonymous namespace
 
 void TranslatorVisitor::MEMBAR(u64 inst) {
     union {
         u64 raw;
         BitField<8, 2, LocalScope> scope;
-    } membar{inst};
+    } const membar{inst};
 
-    ir.MemoryBarrier(LocalScopeToMemoryScope(membar.scope));
+    if (membar.scope == LocalScope::CTA) {
+        ir.WorkgroupMemoryBarrier();
+    } else {
+        ir.DeviceMemoryBarrier();
+    }
 }
 
 void TranslatorVisitor::DEPBAR() {