diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index d759cbe0..cba4cf32 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -10,6 +10,7 @@ namespace dxvk { this->dcSingleUseMode = config.getOption("d3d11.dcSingleUseMode", true); this->enableRtOutputNanFixup = config.getOption("d3d11.enableRtOutputNanFixup", false); this->zeroInitWorkgroupMemory = config.getOption("d3d11.zeroInitWorkgroupMemory", false); + this->forceTgsmBarriers = config.getOption("d3d11.forceTgsmBarriers", false); this->relaxedBarriers = config.getOption("d3d11.relaxedBarriers", false); this->maxTessFactor = config.getOption("d3d11.maxTessFactor", 0); this->samplerAnisotropy = config.getOption("d3d11.samplerAnisotropy", -1); diff --git a/src/d3d11/d3d11_options.h b/src/d3d11/d3d11_options.h index bc40c855..e59b3c47 100644 --- a/src/d3d11/d3d11_options.h +++ b/src/d3d11/d3d11_options.h @@ -35,6 +35,13 @@ namespace dxvk { /// TGSM in compute shaders before reading it. bool zeroInitWorkgroupMemory; + /// Force thread-group shared memory barriers + /// + /// Workaround for compute shaders that read and + /// write from the same shared memory location + /// without explicit synchronization. + bool forceTgsmBarriers; + /// Use relaxed memory barriers /// /// May improve performance in some games, diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 555ffa1c..95d61dfd 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -5221,6 +5221,15 @@ namespace dxvk { srcComponentIndex += 1; } } + + // Make sure that shared memory stores are made visible in + // case the game does not synchronize invocations properly + if (isTgsm && m_moduleInfo.options.forceTgsmBarriers) { + m_module.opMemoryBarrier( + m_module.constu32(spv::ScopeWorkgroup), + m_module.constu32(spv::MemorySemanticsWorkgroupMemoryMask + | spv::MemorySemanticsAcquireReleaseMask)); + } // End conditional block if (!isTgsm) { diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 883fcef8..090ddfa2 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -40,6 +40,7 @@ namespace dxvk { invariantPosition = options.invariantPosition; enableRtOutputNanFixup = options.enableRtOutputNanFixup; zeroInitWorkgroupMemory = options.zeroInitWorkgroupMemory; + forceTgsmBarriers = options.forceTgsmBarriers; dynamicIndexedConstantBufferAsSsbo = options.constantBufferRangeCheck; // Disable early discard on RADV (with LLVM) due to GPU hangs diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index a94a3a4a..9a4c3c15 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -45,6 +45,9 @@ namespace dxvk { /// Declare vertex positions as invariant bool invariantPosition = false; + /// Insert memory barriers after TGSM stoes + bool forceTgsmBarriers = false; + /// Minimum storage buffer alignment VkDeviceSize minSsboAlignment = 0; };