diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index 83c321de..6a3f371c 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -16,7 +16,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->forceVolatileTgsmAccess = config.getOption("d3d11.forceVolatileTgsmAccess", false); this->relaxedBarriers = config.getOption("d3d11.relaxedBarriers", false); this->ignoreGraphicsBarriers = config.getOption("d3d11.ignoreGraphicsBarriers", false); this->maxTessFactor = config.getOption("d3d11.maxTessFactor", 0); diff --git a/src/d3d11/d3d11_options.h b/src/d3d11/d3d11_options.h index 67bceaa5..59458020 100644 --- a/src/d3d11/d3d11_options.h +++ b/src/d3d11/d3d11_options.h @@ -30,12 +30,12 @@ namespace dxvk { /// TGSM in compute shaders before reading it. bool zeroInitWorkgroupMemory; - /// Force thread-group shared memory barriers + /// Force thread-group shared memory accesses to be volatile /// /// Workaround for compute shaders that read and /// write from the same shared memory location /// without explicit synchronization. - bool forceTgsmBarriers; + bool forceVolatileTgsmAccess; /// Use relaxed memory barriers /// diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 926a4254..b45dce51 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -5190,17 +5190,23 @@ namespace dxvk { SpirvImageOperands imageOperands; imageOperands.sparse = sparseFeedbackId != 0; - if (isTgsm) + uint32_t coherence = bufferInfo.coherence; + + if (isTgsm || coherence) memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask; - if (bufferInfo.coherence) { - memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask - | spv::MemoryAccessMakePointerVisibleMask; - memoryOperands.makeVisible = m_module.constu32(bufferInfo.coherence); + if (isTgsm && m_moduleInfo.options.forceVolatileTgsmAccess) { + memoryOperands.flags |= spv::MemoryAccessVolatileMask; + coherence = spv::ScopeWorkgroup; + } + + if (coherence) { + memoryOperands.flags |= spv::MemoryAccessMakePointerVisibleMask; + memoryOperands.makeVisible = m_module.constu32(coherence); imageOperands.flags = spv::ImageOperandsNonPrivateTexelMask | spv::ImageOperandsMakeTexelVisibleMask; - imageOperands.makeVisible = m_module.constu32(bufferInfo.coherence); + imageOperands.makeVisible = m_module.constu32(coherence); } sparseFeedbackId = 0; @@ -5308,17 +5314,23 @@ namespace dxvk { SpirvMemoryOperands memoryOperands; SpirvImageOperands imageOperands; - if (isTgsm) + uint32_t coherence = bufferInfo.coherence; + + if (isTgsm || coherence) memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask; - if (bufferInfo.coherence) { - memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask - | spv::MemoryAccessMakePointerAvailableMask; - memoryOperands.makeAvailable = m_module.constu32(bufferInfo.coherence); + if (isTgsm && m_moduleInfo.options.forceVolatileTgsmAccess) { + memoryOperands.flags |= spv::MemoryAccessVolatileMask; + coherence = spv::ScopeWorkgroup; + } + + if (coherence) { + memoryOperands.flags |= spv::MemoryAccessMakePointerAvailableMask; + memoryOperands.makeAvailable = m_module.constu32(coherence); imageOperands.flags = spv::ImageOperandsNonPrivateTexelMask | spv::ImageOperandsMakeTexelAvailableMask; - imageOperands.makeAvailable = m_module.constu32(bufferInfo.coherence); + imageOperands.makeAvailable = m_module.constu32(coherence); } for (uint32_t i = 0; i < 4; i++) { diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index ba373dde..51c565bd 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -37,7 +37,7 @@ namespace dxvk { invariantPosition = options.invariantPosition; enableRtOutputNanFixup = options.enableRtOutputNanFixup; zeroInitWorkgroupMemory = options.zeroInitWorkgroupMemory; - forceTgsmBarriers = options.forceTgsmBarriers; + forceVolatileTgsmAccess = options.forceVolatileTgsmAccess; disableMsaa = options.disableMsaa; // Figure out float control flags to match D3D11 rules diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index d472b358..0949a6e1 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -41,7 +41,7 @@ namespace dxvk { bool invariantPosition = false; /// Insert memory barriers after TGSM stoes - bool forceTgsmBarriers = false; + bool forceVolatileTgsmAccess = false; /// Replace ld_ms with ld bool disableMsaa = false; diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 51dcf5a9..9460b618 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -181,7 +181,7 @@ namespace dxvk { /* F1 games - do not synchronize TGSM access * * in a compute shader, causing artifacts */ { R"(\\F1_20(1[89]|[2-9][0-9])\.exe$)", {{ - { "d3d11.forceTgsmBarriers", "True" }, + { "d3d11.forceVolatileTgsmAccess", "True" }, }} }, /* Darksiders Warmastered - apparently reads * * from write-only mapped buffers */