diff --git a/OptiScaler/NVNGX_DLSS_Dx11.cpp b/OptiScaler/NVNGX_DLSS_Dx11.cpp
index 248f5586..240b67fc 100644
--- a/OptiScaler/NVNGX_DLSS_Dx11.cpp
+++ b/OptiScaler/NVNGX_DLSS_Dx11.cpp
@@ -194,9 +194,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Shutdown()
DLSSFeatureDx11::Shutdown(D3D11Device);
- //if (Config::Instance()->OverlayMenu.value_or(true) && ImGuiOverlayDx11::IsInitedDx11())
- // ImGuiOverlayDx11::ShutdownDx11();
-
if (Config::Instance()->DLSSEnabled.value_or(true) && NVNGXProxy::IsDx11Inited() && NVNGXProxy::D3D11_Shutdown() != nullptr)
{
auto result = NVNGXProxy::D3D11_Shutdown()();
@@ -204,6 +201,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Shutdown()
LOG_INFO("D3D11_Shutdown result: {0:X}", (UINT)result);
}
+ ImGuiOverlayDx::UnHookDx();
+
return NVSDK_NGX_Result_Success;
}
diff --git a/OptiScaler/NVNGX_DLSS_Dx12.cpp b/OptiScaler/NVNGX_DLSS_Dx12.cpp
index 59e9595f..95fe90ce 100644
--- a/OptiScaler/NVNGX_DLSS_Dx12.cpp
+++ b/OptiScaler/NVNGX_DLSS_Dx12.cpp
@@ -394,6 +394,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown(void)
LOG_INFO("D3D12_Shutdown result: {0:X}", (UINT)result);
}
+ ImGuiOverlayDx::UnHookDx();
+
return NVSDK_NGX_Result_Success;
}
diff --git a/OptiScaler/NVNGX_DLSS_Vk.cpp b/OptiScaler/NVNGX_DLSS_Vk.cpp
index ba3a25ef..b7539a60 100644
--- a/OptiScaler/NVNGX_DLSS_Vk.cpp
+++ b/OptiScaler/NVNGX_DLSS_Vk.cpp
@@ -979,6 +979,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Shutdown(void)
LOG_INFO("VULKAN_Shutdown result: {0:X}", (UINT)result);
}
+ ImGuiOverlayVk::UnHookVk();
+
return NVSDK_NGX_Result_Success;
}
diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj
index 80ca5794..068b654e 100644
--- a/OptiScaler/OptiScaler.vcxproj
+++ b/OptiScaler/OptiScaler.vcxproj
@@ -82,7 +82,7 @@
$(SolutionDir)external\vulkan\include;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\FidelityFX-SDK\ffx-api\include\ffx_api;$(SolutionDir)external\simpleini;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\spdlog\include;$(IncludePath)
$(ProjectDir)fsr2\lib;$(ProjectDir)fsr2_212\lib;$(ProjectDir)vulkan;$(ProjectDir)d3dx;$(ProjectDir)detours;$(SolutionDir)external\xess\lib;$(LibraryPath)
dxgi
- D:\Folders\Games\God of War\
+ D:\Folders\Games\Cyberpunk 2077\bin\x64\
.\x64\Debug
diff --git a/OptiScaler/dllmain.h b/OptiScaler/dllmain.h
index 4a169d2f..ef30b20a 100644
--- a/OptiScaler/dllmain.h
+++ b/OptiScaler/dllmain.h
@@ -1708,6 +1708,8 @@ void AttachToAdapter(IUnknown* unkAdapter)
PVOID* pVTable = *(PVOID**)unkAdapter;
+ bool dxvkStatus = Config::Instance()->IsRunningOnDXVK;
+
IDXGIAdapter* adapter = nullptr;
bool adapterOk = unkAdapter->QueryInterface(__uuidof(IDXGIAdapter), (void**)&adapter) == S_OK;
@@ -1718,7 +1720,8 @@ void AttachToAdapter(IUnknown* unkAdapter)
((IDXGIAdapter*)dxvkAdapter)->Release();
}
- LOG_INFO("IDXGIVkInteropDevice interface {0}", Config::Instance()->IsRunningOnDXVK ? "found" : "not found");
+ if(Config::Instance()->IsRunningOnDXVK != dxvkStatus)
+ LOG_INFO("IDXGIVkInteropDevice interface {0}", Config::Instance()->IsRunningOnDXVK ? "found" : "not found");
if (ptrGetDesc == nullptr && adapterOk)
{
diff --git a/OptiScaler/imgui/imgui_overlay_dx.cpp b/OptiScaler/imgui/imgui_overlay_dx.cpp
index 3d9030a4..ee9fbd75 100644
--- a/OptiScaler/imgui/imgui_overlay_dx.cpp
+++ b/OptiScaler/imgui/imgui_overlay_dx.cpp
@@ -49,6 +49,7 @@ static PFN_D3D12_CREATE_DEVICE o_D3D12CreateDevice = nullptr;
static PFN_CreateSampler o_CreateSampler = nullptr;
static PFN_D3D11_CREATE_DEVICE o_D3D11CreateDevice = nullptr;
+static PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN o_D3D11CreateDeviceAndSwapChain = nullptr;
static PFN_CreateSamplerState o_CreateSamplerState = nullptr;
static PFN_D3D11ON12_CREATE_DEVICE o_D3D11On12CreateDevice = nullptr;
static ID3D11Device* d3d11Device = nullptr;
@@ -156,8 +157,6 @@ static void CleanupRenderTargetDx12(bool clearQueue)
if (!_isInited || !_dx12Device)
return;
- LOG_DEBUG("clearQueue: {0}!", clearQueue);
-
for (UINT i = 0; i < NUM_BACK_BUFFERS; ++i)
{
if (g_mainRenderTargetResource[i])
@@ -206,15 +205,13 @@ static void CleanupRenderTargetDx12(bool clearQueue)
if (g_pd3dCommandQueue != nullptr)
{
- auto count = g_pd3dCommandQueue->Release();
- LOG_DEBUG("D3D12 Queue refcount: {}", count);
+ g_pd3dCommandQueue->Release();
g_pd3dCommandQueue = nullptr;
}
if (g_pd3dDeviceParam != nullptr)
{
- auto count = g_pd3dDeviceParam->Release();
- LOG_DEBUG("D3D12 device refcount: {}", count);
+ g_pd3dDeviceParam->Release();
g_pd3dDeviceParam = nullptr;
}
@@ -372,7 +369,7 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags
ImGuiOverlayDx::currentFrameIndex = (ImGuiOverlayDx::currentFrameIndex + 1) % ImGuiOverlayDx::QUERY_BUFFER_COUNT;
}
- // DXVK & process hWnd check
+ // DXVK & process hWnd check
if (Config::Instance()->IsRunningOnDXVK || hWnd != Util::GetProcessWindow())
{
if (cq != nullptr)
@@ -430,11 +427,8 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags
g_pd3dCommandQueue = cq;
g_pd3dDeviceParam = device12;
- auto count = g_pd3dCommandQueue->AddRef();
- LOG_DEBUG("D3D12 Queue refcount: {}", count);
-
- count = g_pd3dDeviceParam->AddRef();
- LOG_DEBUG("D3D12 Device refcount: {}", count);
+ g_pd3dCommandQueue->AddRef();
+ g_pd3dDeviceParam->AddRef();
ImGuiOverlayBase::Dx12Ready();
_isInited = true;
@@ -972,6 +966,64 @@ static HRESULT hkD3D11CreateDevice(IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE Drive
return result;
}
+static HRESULT hkD3D11CreateDeviceAndSwapChain(IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, CONST D3D_FEATURE_LEVEL* pFeatureLevels,
+ UINT FeatureLevels, UINT SDKVersion, DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, IDXGISwapChain** ppSwapChain, ID3D11Device** ppDevice, D3D_FEATURE_LEVEL* pFeatureLevel, ID3D11DeviceContext** ppImmediateContext)
+{
+ LOG_FUNC();
+
+ IDXGISwapChain* buffer = nullptr;
+ auto result = o_D3D11CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, pSwapChainDesc, &buffer, ppDevice, pFeatureLevel, ppImmediateContext);
+
+ if (result == S_OK && *ppDevice != nullptr)
+ {
+ LOG_INFO("Device captured");
+ d3d11Device = *ppDevice;
+
+ HookToDevice(d3d11Device);
+
+ WrappedIDXGISwapChain4* buf = nullptr;
+ if (buffer != nullptr && buffer->QueryInterface(IID_PPV_ARGS(&buf)) != S_OK)
+ {
+ // check for SL proxy
+ IID riid;
+ IDXGISwapChain* real = nullptr;
+ auto iidResult = IIDFromString(L"{ADEC44E2-61F0-45C3-AD9F-1B37379284FF}", &riid);
+
+ if (iidResult == S_OK)
+ {
+ auto qResult = buffer->QueryInterface(riid, (void**)&real);
+
+ if (qResult == S_OK && real != nullptr)
+ {
+ LOG_INFO("Streamline proxy found");
+ real->Release();
+ }
+ else
+ {
+ LOG_DEBUG("Streamline proxy not found");
+ }
+ }
+
+ Config::Instance()->ScreenWidth = pSwapChainDesc->BufferDesc.Width;
+ Config::Instance()->ScreenHeight = pSwapChainDesc->BufferDesc.Height;
+
+ LOG_DEBUG("created new swapchain: {0:X}, hWnd", (UINT64)buffer, (UINT64)pSwapChainDesc->OutputWindow);
+ *ppSwapChain = new WrappedIDXGISwapChain4(real == nullptr ? buffer : real, d3d11Device, pSwapChainDesc->OutputWindow, Present, CleanupRenderTarget);
+ LOG_DEBUG("created new WrappedIDXGISwapChain4: {0:X}, pDevice: {1:X}", (UINT64)buffer, (UINT64)d3d11Device);
+ }
+
+ if (buf != nullptr)
+ buf->Release();
+ }
+
+ if (buffer != nullptr)
+ buffer->Release();
+
+ LOG_FUNC_RESULT(result);
+
+ return result;
+}
+
static HRESULT hkD3D12CreateDevice(IUnknown* pAdapter, D3D_FEATURE_LEVEL MinimumFeatureLevel, REFIID riid, void** ppDevice)
{
LOG_FUNC();
@@ -1380,7 +1432,7 @@ void DeatachAllHooks()
if (o_D3D11On12CreateDevice != nullptr)
{
DetourDetach(&(PVOID&)o_D3D11On12CreateDevice, hkD3D11On12CreateDevice);
- o_D3D11CreateDevice = nullptr;
+ o_D3D11On12CreateDevice = nullptr;
}
if (o_D3D12CreateDevice != nullptr)
@@ -1439,8 +1491,9 @@ void ImGuiOverlayDx::HookDx()
}
o_D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)DetourFindFunction("d3d11.dll", "D3D11CreateDevice");
+ o_D3D11CreateDeviceAndSwapChain = (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)DetourFindFunction("d3d11.dll", "D3D11CreateDeviceAndSwapChain");
o_D3D11On12CreateDevice = (PFN_D3D11ON12_CREATE_DEVICE)DetourFindFunction("d3d11.dll", "D3D11On12CreateDevice");
- if (o_D3D11CreateDevice != nullptr || o_D3D11On12CreateDevice != nullptr)
+ if (o_D3D11CreateDevice != nullptr || o_D3D11On12CreateDevice != nullptr || o_D3D11CreateDeviceAndSwapChain != nullptr)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
@@ -1451,6 +1504,9 @@ void ImGuiOverlayDx::HookDx()
if (o_D3D11On12CreateDevice != nullptr)
DetourAttach(&(PVOID&)o_D3D11On12CreateDevice, hkD3D11On12CreateDevice);
+ if (o_D3D11CreateDeviceAndSwapChain != nullptr)
+ DetourAttach(&(PVOID&)o_D3D11CreateDeviceAndSwapChain, hkD3D11CreateDeviceAndSwapChain);
+
DetourTransactionCommit();
}
diff --git a/OptiScaler/imgui/wrapped_swapchain.cpp b/OptiScaler/imgui/wrapped_swapchain.cpp
index fe1a67ed..6d915ae2 100644
--- a/OptiScaler/imgui/wrapped_swapchain.cpp
+++ b/OptiScaler/imgui/wrapped_swapchain.cpp
@@ -82,6 +82,12 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::QueryInterface(REFIID riid, vo
return E_NOINTERFACE;
}
}
+ else if (riid == __uuidof(this))
+ {
+ AddRef();
+ *ppvObject = (IUnknown*)this;
+ return S_OK;
+ }
else if (riid == __uuidof(IUnknown))
{
AddRef();
@@ -108,10 +114,18 @@ HRESULT WrappedIDXGISwapChain4::ResizeBuffers(UINT BufferCount, UINT Width, UINT
{
LOG_FUNC();
- if (ClearTrig != nullptr)
- ClearTrig(false, Handle);
+ _mutex.lock();
- return m_pReal->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags);
+ if (ClearTrig != nullptr)
+ ClearTrig(true, Handle);
+
+ auto result = m_pReal->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags);
+
+ LOG_FUNC_RESULT(result);
+
+ _mutex.unlock();
+
+ return result;
}
HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::GetContainingOutput(IDXGIOutput** ppOutput)
@@ -124,10 +138,17 @@ HRESULT WrappedIDXGISwapChain4::ResizeBuffers1(UINT BufferCount, UINT Width, UIN
{
LOG_FUNC();
- if (ClearTrig != nullptr)
- ClearTrig(false, Handle);
+ _mutex.lock();
- return m_pReal3->ResizeBuffers1(BufferCount, Width, Height, Format, SwapChainFlags, pCreationNodeMask, ppPresentQueue);
+ if (ClearTrig != nullptr)
+ ClearTrig(true, Handle);
+
+
+ auto result = m_pReal3->ResizeBuffers1(BufferCount, Width, Height, Format, SwapChainFlags, pCreationNodeMask, ppPresentQueue);
+
+ _mutex.unlock();
+
+ return result;
}
HRESULT WrappedIDXGISwapChain4::SetFullscreenState(BOOL Fullscreen, IDXGIOutput* pTarget)
diff --git a/OptiScaler/imgui/wrapped_swapchain.h b/OptiScaler/imgui/wrapped_swapchain.h
index d9c7f470..61eeb0cb 100644
--- a/OptiScaler/imgui/wrapped_swapchain.h
+++ b/OptiScaler/imgui/wrapped_swapchain.h
@@ -251,5 +251,7 @@ struct DECLSPEC_UUID("3af622a3-82d0-49cd-994f-cce05122c222") WrappedIDXGISwapCha
PFN_SC_Clean ClearTrig = nullptr;
HWND Handle = nullptr;
+ std::mutex _mutex;
+
int id = 0;
};
diff --git a/OptiScaler/pch.h b/OptiScaler/pch.h
index 769d48ed..b30fcbfd 100644
--- a/OptiScaler/pch.h
+++ b/OptiScaler/pch.h
@@ -25,7 +25,8 @@
// Enables logging of DLSS NV Parameters
//#define DLSS_PARAM_DUMP
-inline HMODULE dllModule;
+inline HMODULE dllModule = nullptr;
+inline HMODULE skHandle = nullptr;
inline DWORD processId;
#define LOG_TRACE(msg, ...) \
diff --git a/OptiScaler/resource.h b/OptiScaler/resource.h
index 6b1415b1..7d01a027 100644
--- a/OptiScaler/resource.h
+++ b/OptiScaler/resource.h
@@ -21,7 +21,7 @@
#define VER_MAJOR_VERSION 0
#define VER_MINOR_VERSION 6
#define VER_HOTFIX_VERSION 7
-#define VER_BUILD_NUMBER 8
+#define VER_BUILD_NUMBER 9
#define VER_PRE_RELEASE