Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions OptiScaler/OwnedMutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
class OwnedMutex
{
private:
// shared* as basic mutex must only be unlocked by thread that locked it
std::shared_mutex mtx;

// Written under mutex, read independently
std::atomic<uint32_t> owner {}; // don't use 0

public:
Expand All @@ -33,6 +36,7 @@ class OwnedMutex
mtx.unlock();
}

// Result is truthful only if and while locked
uint32_t getOwner() { return owner.load(std::memory_order_seq_cst); }
};

Expand All @@ -48,5 +52,7 @@ class OwnedLockGuard
_mutex.lock(_owner_id);
}

OwnedLockGuard(const OwnedLockGuard&) = delete;

~OwnedLockGuard() { _mutex.unlockThis(_owner_id); }
};
27 changes: 13 additions & 14 deletions OptiScaler/framegen/ffx/FSRFG_Dx12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <upscalers/IFeature.h>
#include <menu/menu_overlay_dx.h>
#include <future>
#include <optional>

// #define USE_QUEUE_FOR_FG

Expand Down Expand Up @@ -100,10 +101,11 @@ bool FSRFG_Dx12::Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* ou

auto frameIndex = _frameCount % BUFFER_COUNT;

std::optional<OwnedLockGuard> lock;
if (Config::Instance()->FGUseMutexForSwapchain.value_or_default())
{
LOG_TRACE("Waiting Mutex 1, current: {}", Mutex.getOwner());
Mutex.lock(1);
lock.emplace(Mutex, 1);
LOG_TRACE("Accuired Mutex: {}", Mutex.getOwner());
}

Expand Down Expand Up @@ -250,10 +252,9 @@ bool FSRFG_Dx12::Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* ou
}
}

if (Config::Instance()->FGUseMutexForSwapchain.value_or_default())
if (lock)
{
LOG_TRACE("Releasing Mutex: {}", Mutex.getOwner());
Mutex.unlockThis(1);
}

return retCode == FFX_API_RETURN_OK;
Expand Down Expand Up @@ -522,10 +523,11 @@ void FSRFG_Dx12::FgDone()
{
return;

std::optional<OwnedLockGuard> lock;
if (Config::Instance()->FGUseMutexForSwapchain.value_or_default())
{
LOG_TRACE("Waiting Mutex 1, current: {}", Mutex.getOwner());
Mutex.lock(1);
lock.emplace(Mutex, 1);
LOG_TRACE("Accuired Mutex: {}", Mutex.getOwner());
}

Expand All @@ -545,10 +547,9 @@ void FSRFG_Dx12::FgDone()
LOG_INFO("D3D12_Configure result: {0:X}", result);
}

if (Config::Instance()->FGUseMutexForSwapchain.value_or_default())
if (lock)
{
LOG_TRACE("Releasing Mutex: {}", Mutex.getOwner());
Mutex.unlockThis(1);
}
}

Expand All @@ -570,12 +571,11 @@ void FSRFG_Dx12::StopAndDestroyContext(bool destroy, bool shutDown, bool useMute

LOG_DEBUG("");

bool mutexTaken = false;
std::optional<OwnedLockGuard> lock;
if (Config::Instance()->FGUseMutexForSwapchain.value_or_default() && useMutex)
{
LOG_TRACE("Waiting Mutex 1, current: {}", Mutex.getOwner());
Mutex.lock(1);
mutexTaken = true;
lock.emplace(Mutex, 1);
LOG_TRACE("Accuired Mutex: {}", Mutex.getOwner());
}

Expand Down Expand Up @@ -610,10 +610,9 @@ void FSRFG_Dx12::StopAndDestroyContext(bool destroy, bool shutDown, bool useMute
if (shutDown || State::Instance().isShuttingDown)
ReleaseObjects();

if (mutexTaken)
if (lock)
{
LOG_TRACE("Releasing Mutex: {}", Mutex.getOwner());
Mutex.unlockThis(1);
}
}

Expand Down Expand Up @@ -703,10 +702,11 @@ bool FSRFG_Dx12::ReleaseSwapchain(HWND hwnd)

LOG_DEBUG("");

std::optional<OwnedLockGuard> lock;
if (Config::Instance()->FGUseMutexForSwapchain.value_or_default())
{
LOG_TRACE("Waiting Mutex 1, current: {}", Mutex.getOwner());
Mutex.lock(1);
lock.emplace(Mutex, 1);
LOG_TRACE("Accuired Mutex: {}", Mutex.getOwner());
}

Expand All @@ -723,10 +723,9 @@ bool FSRFG_Dx12::ReleaseSwapchain(HWND hwnd)
_swapChainContext = nullptr;
}

if (Config::Instance()->FGUseMutexForSwapchain.value_or_default())
if (lock)
{
LOG_TRACE("Releasing Mutex: {}", Mutex.getOwner());
Mutex.unlockThis(1);
}

return true;
Expand Down
9 changes: 3 additions & 6 deletions OptiScaler/hooks/HooksDx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,9 @@ static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags)
// filter out posibly wrong measured high values
if (elapsedTimeMs < 100.0)
{
State::Instance().frameTimeMutex.lock();
std::lock_guard<std::mutex> lock(State::Instance().frameTimeMutex);
State::Instance().upscaleTimes.push_back(elapsedTimeMs);
State::Instance().upscaleTimes.pop_front();
State::Instance().frameTimeMutex.unlock();
}
}
else
Expand Down Expand Up @@ -425,10 +424,9 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags
// filter out posibly wrong measured high values
if (elapsedTimeMs < 100.0)
{
State::Instance().frameTimeMutex.lock();
std::lock_guard<std::mutex> lock(State::Instance().frameTimeMutex);
State::Instance().upscaleTimes.push_back(elapsedTimeMs);
State::Instance().upscaleTimes.pop_front();
State::Instance().frameTimeMutex.unlock();
}
}
else
Expand Down Expand Up @@ -466,10 +464,9 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags
// filter out posibly wrong measured high values
if (elapsedTimeMs < 100.0)
{
State::Instance().frameTimeMutex.lock();
std::lock_guard<std::mutex> lock(State::Instance().frameTimeMutex);
State::Instance().upscaleTimes.push_back(elapsedTimeMs);
State::Instance().upscaleTimes.pop_front();
State::Instance().frameTimeMutex.unlock();
}
}
}
Expand Down
28 changes: 13 additions & 15 deletions OptiScaler/hooks/wrapped_swapchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "HooksDx.h"

#include <misc/FrameLimit.h>
#include <optional>

// Used RenderDoc's wrapped object as referance
// https://github.com/baldurk/renderdoc/blob/v1.x/renderdoc/driver/dxgi/dxgi_wrapped.cpp
Expand Down Expand Up @@ -228,23 +229,21 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::SetFullscreenState(BOOL Fullsc
LOG_DEBUG("Fullscreen: {}, pTarget: {:X}", Fullscreen, (size_t) pTarget);
HRESULT result = S_OK;

bool ffxLock = false;

std::optional<OwnedLockGuard> lock;
{
#ifdef USE_LOCAL_MUTEX
// dlssg calls this from present it seems
// don't try to get a mutex when present owns it while dlssg mod is enabled
if (!(_localMutex.getOwner() == 4 && Config::Instance()->FGType.value_or_default() == FGType::Nukems))
OwnedLockGuard lock(_localMutex, 3);
OwnedLockGuard(_localMutex, 3);
#endif
if (Config::Instance()->FGUseMutexForSwapchain.value_or_default())
{

if (State::Instance().currentFG != nullptr && State::Instance().currentFG->Mutex.getOwner() != 3)
{
LOG_TRACE("Waiting ffxMutex 3, current: {}", State::Instance().currentFG->Mutex.getOwner());
State::Instance().currentFG->Mutex.lock(3);
ffxLock = true;
lock.emplace(State::Instance().currentFG->Mutex, 3);
LOG_TRACE("Accuired ffxMutex: {}", State::Instance().currentFG->Mutex.getOwner());
}
else
Expand Down Expand Up @@ -299,10 +298,9 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::SetFullscreenState(BOOL Fullsc
*/
}

if (Config::Instance()->FGUseMutexForSwapchain.value_or_default() && ffxLock)
if (lock)
{
LOG_TRACE("Releasing ffxMutex: {}", State::Instance().currentFG->Mutex.getOwner());
State::Instance().currentFG->Mutex.unlockThis(3);
}

return result;
Expand All @@ -327,13 +325,14 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::ResizeBuffers(UINT BufferCount
// dlssg calls this from present it seems
// don't try to get a mutex when present owns it while dlssg mod is enabled
if (!(_localMutex.getOwner() == 4 && Config::Instance()->FGType.value_or_default() == FGType::Nukems))
OwnedLockGuard lock(_localMutex, 1);
OwnedLockGuard(_localMutex, 1);
#endif

std::optional<OwnedLockGuard> lock;
if (State::Instance().currentFG != nullptr && Config::Instance()->FGUseMutexForSwapchain.value_or_default())
{
LOG_TRACE("Waiting ffxMutex 3, current: {}", State::Instance().currentFG->Mutex.getOwner());
State::Instance().currentFG->Mutex.lock(3);
lock.emplace(State::Instance().currentFG->Mutex, 3);
LOG_TRACE("Accuired ffxMutex: {}", State::Instance().currentFG->Mutex.getOwner());
}

Expand Down Expand Up @@ -436,10 +435,9 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::ResizeBuffers(UINT BufferCount

LOG_DEBUG("result: {0:X}", (UINT) result);

if (State::Instance().currentFG != nullptr && Config::Instance()->FGUseMutexForSwapchain.value_or_default())
if (lock)
{
LOG_TRACE("Releasing ffxMutex: {}", State::Instance().currentFG->Mutex.getOwner());
State::Instance().currentFG->Mutex.unlockThis(3);
}

return result;
Expand Down Expand Up @@ -601,13 +599,14 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::ResizeBuffers1(UINT BufferCoun
// dlssg calls this from present it seems
// don't try to get a mutex when present owns it while dlssg mod is enabled
if (!(_localMutex.getOwner() == 4 && Config::Instance()->FGType.value_or_default() == FGType::Nukems))
OwnedLockGuard lock(_localMutex, 2);
OwnedLockGuard(_localMutex, 2);
#endif

std::optional<OwnedLockGuard> lock;
if (State::Instance().activeFgType == OptiFG && Config::Instance()->FGUseMutexForSwapchain.value_or_default())
{
LOG_TRACE("Waiting ffxMutex 3, current: {}", State::Instance().currentFG->Mutex.getOwner());
State::Instance().currentFG->Mutex.lock(3);
lock.emplace(State::Instance().currentFG->Mutex, 3);
LOG_TRACE("Accuired ffxMutex: {}", State::Instance().currentFG->Mutex.getOwner());
}

Expand Down Expand Up @@ -709,10 +708,9 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::ResizeBuffers1(UINT BufferCoun

LOG_DEBUG("result: {0:X}", (UINT) result);

if (State::Instance().activeFgType == OptiFG && Config::Instance()->FGUseMutexForSwapchain.value_or_default())
if (lock)
{
LOG_TRACE("Releasing ffxMutex: {}", State::Instance().currentFG->Mutex.getOwner());
State::Instance().currentFG->Mutex.unlockThis(3);
}

return result;
Expand Down
3 changes: 1 addition & 2 deletions OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1598,8 +1598,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
if (fg->Mutex.getOwner() == 2)
{
LOG_TRACE("Waiting for present!");
fg->Mutex.lock(4);
fg->Mutex.unlockThis(4);
OwnedLockGuard lock(fg->Mutex, 4);
}

bool allocatorReset = false;
Expand Down