diff --git a/OptiScaler/Config.cpp b/OptiScaler/Config.cpp index 165185de..4df785e9 100644 --- a/OptiScaler/Config.cpp +++ b/OptiScaler/Config.cpp @@ -50,6 +50,7 @@ bool Config::Reload(std::filesystem::path iniPath) // Frame Generation { + FGUseFGSwapChain = readBool("FrameGen", "UseFGSwapChain"); FGEnabled = readBool("FrameGen", "Enabled"); FGDebugView = readBool("FrameGen", "DebugView"); FGAsync = readBool("FrameGen", "AllowAsync"); @@ -473,6 +474,7 @@ bool Config::SaveIni() // Frame Generation { + ini.SetValue("FrameGen", "UseFGSwapChain", GetBoolValue(Instance()->FGUseFGSwapChain).c_str()); ini.SetValue("FrameGen", "Enabled", GetBoolValue(Instance()->FGEnabled).c_str()); ini.SetValue("FrameGen", "DebugView", GetBoolValue(Instance()->FGDebugView).c_str()); ini.SetValue("FrameGen", "AllowAsync", GetBoolValue(Instance()->FGAsync).c_str()); diff --git a/OptiScaler/Config.h b/OptiScaler/Config.h index bd2c38a1..0395bc84 100644 --- a/OptiScaler/Config.h +++ b/OptiScaler/Config.h @@ -159,6 +159,7 @@ public: std::optional LoadSpecialK; // fg + std::optional FGUseFGSwapChain; std::optional FGEnabled; std::optional FGDebugView; std::optional FGAsync; diff --git a/OptiScaler/NVNGX_DLSS_Dx12.cpp b/OptiScaler/NVNGX_DLSS_Dx12.cpp index 5e17036c..6b4c51fa 100644 --- a/OptiScaler/NVNGX_DLSS_Dx12.cpp +++ b/OptiScaler/NVNGX_DLSS_Dx12.cpp @@ -1443,23 +1443,26 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom } // FG Init || Disable - if (!Config::Instance()->FGChanged && ImGuiOverlayDx::fgTarget < deviceContext->FrameCount() && Config::Instance()->FGEnabled.value_or(false) && - _createContext != nullptr && ImGuiOverlayDx::fgContext == nullptr && ImGuiOverlayDx::currentSwapchain != nullptr && - ImGuiOverlayDx::swapchainFormat != DXGI_FORMAT_UNKNOWN) + if (Config::Instance()->FGUseFGSwapChain.value_or(true) && Config::Instance()->OverlayMenu.value_or(true)) { - CreateFGContext(deviceContext); - CreateFGObjects(); - } - else if ((!Config::Instance()->FGEnabled.value_or(false) || Config::Instance()->FGChanged) && ImGuiOverlayDx::fgContext != nullptr) - { - StopAndDestroyFGContext(false); - } + if (!Config::Instance()->FGChanged && ImGuiOverlayDx::fgTarget < deviceContext->FrameCount() && Config::Instance()->FGEnabled.value_or(false) && + _createContext != nullptr && ImGuiOverlayDx::fgContext == nullptr && ImGuiOverlayDx::currentSwapchain != nullptr && + ImGuiOverlayDx::swapchainFormat != DXGI_FORMAT_UNKNOWN) + { + CreateFGContext(deviceContext); + CreateFGObjects(); + } + else if ((!Config::Instance()->FGEnabled.value_or(false) || Config::Instance()->FGChanged) && ImGuiOverlayDx::fgContext != nullptr) + { + StopAndDestroyFGContext(false); + } - if (Config::Instance()->FGChanged) - { - LOG_DEBUG(" FG disabled for 5 frames"); - ImGuiOverlayDx::fgTarget = deviceContext->FrameCount() + 5; - Config::Instance()->FGChanged = false; + if (Config::Instance()->FGChanged) + { + LOG_DEBUG(" FG disabled for 5 frames"); + ImGuiOverlayDx::fgTarget = deviceContext->FrameCount() + 5; + Config::Instance()->FGChanged = false; + } } // Record the first timestamp (before FSR2 upscaling) @@ -1527,7 +1530,9 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom ImGuiOverlayDx::upscaleRan = true; // FG Dispatch || Prepare - if (Config::Instance()->FGEnabled.value_or(false) && ImGuiOverlayDx::fgTarget < deviceContext->FrameCount() && ImGuiOverlayDx::fgContext != nullptr && ImGuiOverlayDx::currentSwapchain != nullptr) + if (Config::Instance()->FGUseFGSwapChain.value_or(true) && Config::Instance()->OverlayMenu.value_or(true) && + Config::Instance()->FGEnabled.value_or(false) && ImGuiOverlayDx::fgTarget < deviceContext->FrameCount() && + ImGuiOverlayDx::fgContext != nullptr && ImGuiOverlayDx::currentSwapchain != nullptr) { if (!Config::Instance()->FGHUDFix.value_or(false) || ImGuiOverlayDx::fgTarget + 10 > deviceContext->FrameCount()) { diff --git a/OptiScaler/imgui/imgui_common.cpp b/OptiScaler/imgui/imgui_common.cpp index 64e5b610..39daf1fd 100644 --- a/OptiScaler/imgui/imgui_common.cpp +++ b/OptiScaler/imgui/imgui_common.cpp @@ -878,7 +878,8 @@ void ImGuiCommon::RenderMenu() // DYNAMIC PROPERTIES ----------------------------- // Frame Generation - if (Config::Instance()->Api == NVNGX_DX12 && !Config::Instance()->WorkingAsNvngx) + if (Config::Instance()->FGUseFGSwapChain.value_or(true) && Config::Instance()->OverlayMenu.value_or(true) && + Config::Instance()->Api == NVNGX_DX12 && !Config::Instance()->WorkingAsNvngx) { ImGui::SeparatorText("Frame Generation (Dx12)"); diff --git a/OptiScaler/imgui/imgui_overlay_dx.cpp b/OptiScaler/imgui/imgui_overlay_dx.cpp index 7bf80997..b64b400c 100644 --- a/OptiScaler/imgui/imgui_overlay_dx.cpp +++ b/OptiScaler/imgui/imgui_overlay_dx.cpp @@ -61,6 +61,12 @@ typedef struct HeapInfo UINT numDescriptors = 0; } heap_info; +typedef struct ResourceHeapInfo +{ + SIZE_T cpuStart = NULL; + SIZE_T gpuStart = NULL; +} resource_heap_info; + // Hooks for FG typedef void (*PFN_CreateRenderTargetView)(ID3D12Device* This, ID3D12Resource* pResource, const D3D12_RENDER_TARGET_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); typedef void (*PFN_OMSetRenderTargets)(ID3D12GraphicsCommandList* This, UINT NumRenderTargetDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE* pRenderTargetDescriptors, @@ -123,8 +129,9 @@ static std::list fgHeaps; /// /// Captured resources by gpu addresses /// -static ankerl::unordered_dense::map fgHandleAddressResources; -static ankerl::unordered_dense::map fgHandleAddressResourcesByGpuHandle; +static ankerl::unordered_dense::map fgHandlesByResources; +static ankerl::unordered_dense::map fgResourcesByGpuHandle; +static ankerl::unordered_dense::map fgResourcesByCpuHandle; static std::shared_mutex heapMutex; static std::shared_mutex resourceMutex; @@ -272,6 +279,42 @@ static HRESULT hkEnumAdapters1(IDXGIFactory1* This, UINT Adapter, IUnknown** ppA static HRESULT hkEnumAdapterByLuid(IDXGIFactory4* This, LUID AdapterLuid, REFIID riid, IUnknown** ppvAdapter); static HRESULT hkEnumAdapterByGpuPreference(IDXGIFactory6* This, UINT Adapter, DXGI_GPU_PREFERENCE GpuPreference, REFIID riid, IUnknown** ppvAdapter); +static SIZE_T GetGPUHandle(ID3D12Device* This, SIZE_T cpuHandle, D3D12_DESCRIPTOR_HEAP_TYPE type) +{ + for (auto& val : fgHeaps) + { + if (val.cpuStart <= cpuHandle && val.cpuEnd >= cpuHandle) + { + auto incSize = This->GetDescriptorHandleIncrementSize(type); + auto addr = cpuHandle - val.cpuStart; + auto index = addr / incSize; + auto gpuAddr = val.gpuStart + (index * incSize); + + return gpuAddr; + } + } + + return NULL; +} + +static SIZE_T GetCPUHandle(ID3D12Device* This, SIZE_T gpuHandle, D3D12_DESCRIPTOR_HEAP_TYPE type) +{ + for (auto& val : fgHeaps) + { + if (val.gpuStart <= gpuHandle && val.gpuEnd >= gpuHandle) + { + auto incSize = This->GetDescriptorHandleIncrementSize(type); + auto addr = gpuHandle - val.gpuStart; + auto index = addr / incSize; + auto cpuAddr = val.cpuStart + (index * incSize); + + return cpuAddr; + } + } + + return NULL; +} + static void ResourceBarrier(ID3D12GraphicsCommandList* InCommandList, ID3D12Resource* InResource, D3D12_RESOURCE_STATES InBeforeState, D3D12_RESOURCE_STATES InAfterState) { D3D12_RESOURCE_BARRIER barrier = {}; @@ -679,35 +722,24 @@ static void hkCreateRenderTargetView(ID3D12Device* This, ID3D12Resource* pResour if (pResource == nullptr) return; - //{ - // std::shared_lock lock(heapMutex); + { + std::shared_lock lock(heapMutex); - // // Try to match resource with cpu & gpu handle info - // for (auto& val : fgHeaps) - // { - // if (val.cpuStart <= DestDescriptor.ptr && val.cpuEnd >= DestDescriptor.ptr) - // { - // auto increment = This->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - // auto addr = DestDescriptor.ptr - val.cpuStart; - // auto index = addr / increment; - // auto gpuAddr = val.gpuStart + (index * increment); + auto gpuHandle = GetGPUHandle(This, DestDescriptor.ptr, D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - // HeapInfo info{}; - // info.cpuStart = DestDescriptor.ptr; - // info.gpuStart = gpuAddr; + // Try to match resource with cpu & gpu handle info + if (gpuHandle != NULL) + { + ResourceHeapInfo info{}; + info.cpuStart = DestDescriptor.ptr; + info.gpuStart = gpuHandle; - // std::unique_lock lock2(resourceMutex); - // fgHandleAddressResources.insert_or_assign(pResource, info); - - // if (val.gpuStart != 0) - // fgHandleAddressResourcesByGpuHandle.insert_or_assign(gpuAddr, pResource); - // else - // LOG_DEBUG_ONLY("Gpu start is 0, CPU ptr : {}", (UINT64)DestDescriptor.ptr); - - // break; - // } - // } - //} + std::unique_lock lock2(resourceMutex); + fgHandlesByResources.insert_or_assign(pResource, info); + fgResourcesByCpuHandle.insert_or_assign(DestDescriptor.ptr, pResource); + fgResourcesByGpuHandle.insert_or_assign(gpuHandle, pResource); + } + } // Try to capture swapchain buffer RTV's once (cause issues otherwise) if (!fgCaptureRTVs || frameCounter > fgTargetFrame) @@ -1237,28 +1269,34 @@ static void hkSetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList* This, UI return; } - if (!Config::Instance()->FGEnabled.value_or(false) || !Config::Instance()->FGHUDFix.value_or(false) || fgSCBufferCaptured || Config::Instance()->CurrentFeature == nullptr || + if (!Config::Instance()->FGEnabled.value_or(false) || !Config::Instance()->FGHUDFix.value_or(false) || + (fgSCBufferCaptured && ImGuiOverlayDx::fgHUDlessCaptureCounter >= Config::Instance()->FGHUDLimit.value_or(1)) || Config::Instance()->CurrentFeature == nullptr || fgHudlessFrame == Config::Instance()->CurrentFeature->FrameCount() || !ImGuiOverlayDx::upscaleRan || ImGuiOverlayDx::fgContext == nullptr) { return; } - LOG_DEBUG("CommandList: {0:X}, RootParameterIndex: {1}", (UINT64)This, RootParameterIndex); - - if (!Config::Instance()->FGHUDPrevious.value_or(false)) + if (!Config::Instance()->FGHUDPrevious.value_or(false) || RootParameterIndex != 0) return; + LOG_DEBUG("CommandList: {0:X}, RootParameterIndex: {1}, BaseDescriptor: {2}", (SIZE_T)This, RootParameterIndex, BaseDescriptor.ptr); + { std::shared_lock lock(resourceMutex); // assume first one is source - if (RootParameterIndex == 0 && fgHandleAddressResourcesByGpuHandle.contains(BaseDescriptor.ptr)) + if (fgResourcesByGpuHandle.contains(BaseDescriptor.ptr)) { - fgPreviousBuffer = fgHandleAddressResourcesByGpuHandle[BaseDescriptor.ptr]; + fgPreviousBuffer = fgResourcesByGpuHandle[BaseDescriptor.ptr]; + + auto cpuHandle = GetCPUHandle(g_pd3dDeviceParam, BaseDescriptor.ptr, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + if (cpuHandle != NULL) + fgPreviousBufferCpuHandle = cpuHandle; } else { - LOG_DEBUG_ASYNC("Miss: {0:X}", (UINT64)BaseDescriptor.ptr); + LOG_DEBUG("Miss: {}", BaseDescriptor.ptr); } } } @@ -1268,7 +1306,7 @@ static HRESULT hkCreateDescriptorHeap(ID3D12Device* This, D3D12_DESCRIPTOR_HEAP_ auto result = o_CreateDescriptorHeap(This, pDescriptorHeapDesc, riid, ppvHeap); // try to calculate handle ranges for heap - if (result == S_OK && !Config::Instance()->SkipHeapCapture && (pDescriptorHeapDesc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || pDescriptorHeapDesc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_RTV)) //&& pDescriptorHeapDesc->Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) + if (result == S_OK) // && !Config::Instance()->SkipHeapCapture) // && (pDescriptorHeapDesc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || pDescriptorHeapDesc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_RTV)) //&& pDescriptorHeapDesc->Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) { HeapInfo info{}; auto heap = (ID3D12DescriptorHeap*)(*ppvHeap); @@ -1282,7 +1320,6 @@ static HRESULT hkCreateDescriptorHeap(ID3D12Device* This, D3D12_DESCRIPTOR_HEAP_ //if (info.gpuStart != 0) //{ LOG_DEBUG("Found heap, type: {}, cpu: {}-{}, gpu: {}-{}, desc count: {}", (UINT)pDescriptorHeapDesc->Type, info.cpuStart, info.cpuEnd, info.gpuStart, info.gpuEnd, info.numDescriptors); - std::unique_lock lock(heapMutex); fgHeaps.push_back(info); //} @@ -1295,7 +1332,7 @@ static HRESULT hkCreateDescriptorHeap(ID3D12Device* This, D3D12_DESCRIPTOR_HEAP_ else { auto heap = (ID3D12DescriptorHeap*)(*ppvHeap); - LOG_DEBUG("Skipping, type: {}, cpuStart: {}, gpu start: {}", (UINT)pDescriptorHeapDesc->Type, (SIZE_T)(heap->GetCPUDescriptorHandleForHeapStart().ptr), (SIZE_T)(heap->GetGPUDescriptorHandleForHeapStart().ptr)); + LOG_DEBUG("Skipping, type: {}, cpuStart: {}, gpu start: {}", (UINT)pDescriptorHeapDesc->Type, heap->GetCPUDescriptorHandleForHeapStart().ptr, heap->GetGPUDescriptorHandleForHeapStart().ptr); } return result; @@ -1311,54 +1348,87 @@ static void hkCreateShaderResourceView(ID3D12Device* This, ID3D12Resource* pReso { std::shared_lock lock(heapMutex); - // try to find heap of resource - for (auto& val : fgHeaps) + auto gpuHandle = GetGPUHandle(This, DestDescriptor.ptr, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + if (gpuHandle != NULL) { - if (val.cpuStart <= DestDescriptor.ptr && val.cpuEnd >= DestDescriptor.ptr) - { - auto incSize = This->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - auto addr = DestDescriptor.ptr - val.cpuStart; - auto index = addr / incSize; - auto gpuAddr = val.gpuStart + (index * incSize); + ResourceHeapInfo info{}; + info.cpuStart = DestDescriptor.ptr; + info.gpuStart = gpuHandle; - HeapInfo info{}; - info.cpuStart = DestDescriptor.ptr; - info.gpuStart = gpuAddr; + LOG_DEBUG("Found pResource: {0:X}, cpu: {1}, gpu: {2}", (SIZE_T)pResource, DestDescriptor.ptr, gpuHandle); - std::unique_lock lock(resourceMutex); - fgHandleAddressResources.insert_or_assign(pResource, info); - - if (val.gpuStart != 0) - fgHandleAddressResourcesByGpuHandle.insert_or_assign(gpuAddr, pResource); - else - LOG_DEBUG_ASYNC("Gpu start is 0, CPU ptr : {}", (UINT64)DestDescriptor.ptr); - - return; - } + std::unique_lock lock(resourceMutex); + fgHandlesByResources.insert_or_assign(pResource, info); + fgResourcesByGpuHandle.insert_or_assign(gpuHandle, pResource); + fgResourcesByCpuHandle.insert_or_assign(DestDescriptor.ptr, pResource); } } - LOG_DEBUG_ASYNC("Not found, CPU ptr: {}", (UINT64)DestDescriptor.ptr); + LOG_DEBUG("Not found, CPU ptr: {}", (UINT64)DestDescriptor.ptr); } -static void __stdcall hkCopyDescriptors(ID3D12Device* This, UINT NumDestDescriptorRanges, D3D12_CPU_DESCRIPTOR_HANDLE* pDestDescriptorRangeStarts, UINT* pDestDescriptorRangeSizes, UINT NumSrcDescriptorRanges, - D3D12_CPU_DESCRIPTOR_HANDLE* pSrcDescriptorRangeStarts, UINT* pSrcDescriptorRangeSizes, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) +static void __stdcall hkCopyDescriptors(ID3D12Device* This, + UINT NumDestDescriptorRanges, D3D12_CPU_DESCRIPTOR_HANDLE* pDestDescriptorRangeStarts, UINT* pDestDescriptorRangeSizes, + UINT NumSrcDescriptorRanges, D3D12_CPU_DESCRIPTOR_HANDLE* pSrcDescriptorRangeStarts, UINT* pSrcDescriptorRangeSizes, + D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) { o_CopyDescriptors(This, NumDestDescriptorRanges, pDestDescriptorRangeStarts, pDestDescriptorRangeSizes, NumSrcDescriptorRanges, pSrcDescriptorRangeStarts, pSrcDescriptorRangeSizes, DescriptorHeapsType); + if (!Config::Instance()->FGEnabled.value_or(false) || !Config::Instance()->FGHUDFix.value_or(false) || + (fgSCBufferCaptured && ImGuiOverlayDx::fgHUDlessCaptureCounter >= Config::Instance()->FGHUDLimit.value_or(1)) || Config::Instance()->CurrentFeature == nullptr || + fgHudlessFrame == Config::Instance()->CurrentFeature->FrameCount() || !ImGuiOverlayDx::upscaleRan || ImGuiOverlayDx::fgContext == nullptr) + { + return; + } + if (DescriptorHeapsType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || DescriptorHeapsType == D3D12_DESCRIPTOR_HEAP_TYPE_RTV) { - LOG_DEBUG_ASYNC("Found"); + LOG_DEBUG("Moved {} descs from {} to {} ", NumDestDescriptorRanges, pSrcDescriptorRangeStarts[0].ptr, pDestDescriptorRangeStarts[0].ptr); } } -static void __stdcall hkCopyDescriptorsSimple(ID3D12Device* This, UINT NumDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) +static void __stdcall hkCopyDescriptorsSimple(ID3D12Device* This, UINT NumDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, + D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) { o_CopyDescriptorsSimple(This, NumDescriptors, DestDescriptorRangeStart, SrcDescriptorRangeStart, DescriptorHeapsType); + if (!Config::Instance()->FGEnabled.value_or(false) || !Config::Instance()->FGHUDFix.value_or(false) || + (fgSCBufferCaptured && ImGuiOverlayDx::fgHUDlessCaptureCounter >= Config::Instance()->FGHUDLimit.value_or(1)) || Config::Instance()->CurrentFeature == nullptr || + fgHudlessFrame == Config::Instance()->CurrentFeature->FrameCount() || !ImGuiOverlayDx::upscaleRan || ImGuiOverlayDx::fgContext == nullptr) + { + return; + } + if (DescriptorHeapsType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || DescriptorHeapsType == D3D12_DESCRIPTOR_HEAP_TYPE_RTV) { - LOG_DEBUG_ASYNC("Found"); + //LOG_DEBUG("Moved {} descs from {} to {} ", NumDescriptors, SrcDescriptorRangeStart.ptr, DestDescriptorRangeStart.ptr); + + auto size = This->GetDescriptorHandleIncrementSize(DescriptorHeapsType); + + { + std::unique_lock lock(resourceMutex); + + for (size_t i = 0; i < NumDescriptors; i++) + { + auto handle = SrcDescriptorRangeStart.ptr + i * size; + if (fgResourcesByCpuHandle.contains(handle)) + { + auto buffer = fgResourcesByCpuHandle[handle]; + auto destHandle = DestDescriptorRangeStart.ptr + i * size; + fgResourcesByCpuHandle.insert_or_assign(destHandle, buffer); + LOG_DEBUG("Moved Cpu handle from {} to {}", handle, destHandle); + + auto destGpuHandle = GetGPUHandle(This, destHandle, DescriptorHeapsType); + + if (destGpuHandle != NULL) + { + fgResourcesByGpuHandle.insert_or_assign(destGpuHandle, buffer); + LOG_DEBUG("Moved Gpu handle to {}", destGpuHandle); + } + } + } + } } } @@ -1963,7 +2033,7 @@ static HRESULT hkCreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI } ID3D12CommandQueue* cq = nullptr; - if (!fgSkipSCWrapping && _createContext != nullptr && pDevice->QueryInterface(IID_PPV_ARGS(&cq)) == S_OK) + if (Config::Instance()->FGUseFGSwapChain.value_or(true) && !fgSkipSCWrapping && _createContext != nullptr && pDevice->QueryInterface(IID_PPV_ARGS(&cq)) == S_OK) { cq->SetName(L"GameQueue"); SwapChainInfo scInfo{}; @@ -2069,7 +2139,7 @@ static HRESULT hkCreateSwapChainForHwnd(IDXGIFactory* This, IUnknown* pDevice, H } ID3D12CommandQueue* cq = nullptr; - if (!fgSkipSCWrapping && _createContext != nullptr && pDevice->QueryInterface(IID_PPV_ARGS(&cq)) == S_OK) + if (Config::Instance()->FGUseFGSwapChain.value_or(true) && !fgSkipSCWrapping && _createContext != nullptr && pDevice->QueryInterface(IID_PPV_ARGS(&cq)) == S_OK) { SwapChainInfo scInfo{}; scInfo.gameCommandQueue = cq; @@ -2339,13 +2409,16 @@ static void HookCommandList(ID3D12Device* InDevice) // Get the vtable pointer PVOID* pVTable = *(PVOID**)commandList; + // hudless o_OMSetRenderTargets = (PFN_OMSetRenderTargets)pVTable[46]; - o_Close = (PFN_Close)pVTable[10]; o_DrawInstanced = (PFN_DrawInstanced)pVTable[12]; o_DrawIndexedInstanced = (PFN_DrawIndexedInstanced)pVTable[13]; o_CopyTextureRegion = (PFN_CopyTextureRegion)pVTable[16]; o_CopyResource = (PFN_CopyResource)pVTable[17]; + + // extended hudless o_SetGraphicsRootDescriptorTable = (PFN_SetGraphicsRootDescriptorTable)pVTable[31]; + o_Close = (PFN_Close)pVTable[10]; if (o_OMSetRenderTargets != nullptr || o_DrawIndexedInstanced != nullptr || o_DrawInstanced != nullptr) { @@ -2370,8 +2443,8 @@ static void HookCommandList(ID3D12Device* InDevice) //if (o_Close != nullptr) // DetourAttach(&(PVOID&)o_Close, hkClose); - //if (o_SetGraphicsRootDescriptorTable != nullptr) - // DetourAttach(&(PVOID&)o_SetGraphicsRootDescriptorTable, hkSetGraphicsRootDescriptorTable); + if (o_SetGraphicsRootDescriptorTable != nullptr) + DetourAttach(&(PVOID&)o_SetGraphicsRootDescriptorTable, hkSetGraphicsRootDescriptorTable); DetourTransactionCommit(); } @@ -2395,13 +2468,16 @@ static void HookToDevice(ID3D12Device* InDevice) // Get the vtable pointer PVOID* pVTable = *(PVOID**)InDevice; + // needed for basic hudless + o_CreateSampler = (PFN_CreateSampler)pVTable[22]; + o_CreateRenderTargetView = (PFN_CreateRenderTargetView)pVTable[20]; + + // extended hudless o_CreateCommandQueue = (PFN_CreateCommandQueue)pVTable[8]; o_CreateDescriptorHeap = (PFN_CreateDescriptorHeap)pVTable[14]; - o_CreateSampler = (PFN_CreateSampler)pVTable[22]; o_CopyDescriptors = (PFN_CopyDescriptors)pVTable[23]; o_CopyDescriptorsSimple = (PFN_CopyDescriptorsSimple)pVTable[24]; o_CreateShaderResourceView = (PFN_CreateShaderResourceView)pVTable[18]; - o_CreateRenderTargetView = (PFN_CreateRenderTargetView)pVTable[20]; // Apply the detour @@ -2410,31 +2486,35 @@ static void HookToDevice(ID3D12Device* InDevice) DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); - //if (o_CreateDescriptorHeap != nullptr) - // DetourAttach(&(PVOID&)o_CreateDescriptorHeap, hkCreateDescriptorHeap); + if (o_CreateDescriptorHeap != nullptr) + DetourAttach(&(PVOID&)o_CreateDescriptorHeap, hkCreateDescriptorHeap); if (o_CreateSampler != nullptr) DetourAttach(&(PVOID&)o_CreateSampler, hkCreateSampler); - if (o_CreateRenderTargetView != nullptr) - DetourAttach(&(PVOID&)o_CreateRenderTargetView, hkCreateRenderTargetView); + if (Config::Instance()->FGUseFGSwapChain.value_or(true) && Config::Instance()->OverlayMenu.value_or(true)) + { + if (o_CreateRenderTargetView != nullptr) + DetourAttach(&(PVOID&)o_CreateRenderTargetView, hkCreateRenderTargetView); - //if (o_CreateCommandQueue != nullptr) - // DetourAttach(&(PVOID&)o_CreateCommandQueue, hkCreateCommandQueue); + //if (o_CreateCommandQueue != nullptr) + // DetourAttach(&(PVOID&)o_CreateCommandQueue, hkCreateCommandQueue); - //if (o_CreateShaderResourceView != nullptr) - // DetourAttach(&(PVOID&)o_CreateShaderResourceView, hkCreateShaderResourceView); + if (o_CreateShaderResourceView != nullptr) + DetourAttach(&(PVOID&)o_CreateShaderResourceView, hkCreateShaderResourceView); - //if (o_CopyDescriptors != nullptr) - // DetourAttach(&(PVOID&)o_CopyDescriptors, hkCopyDescriptors); + if (o_CopyDescriptors != nullptr) + DetourAttach(&(PVOID&)o_CopyDescriptors, hkCopyDescriptors); - //if (o_CopyDescriptorsSimple != nullptr) - // DetourAttach(&(PVOID&)o_CopyDescriptorsSimple, hkCopyDescriptorsSimple); + if (o_CopyDescriptorsSimple != nullptr) + DetourAttach(&(PVOID&)o_CopyDescriptorsSimple, hkCopyDescriptorsSimple); + } DetourTransactionCommit(); } - HookCommandList(InDevice); + if (Config::Instance()->FGUseFGSwapChain.value_or(true) && Config::Instance()->OverlayMenu.value_or(true)) + HookCommandList(InDevice); } static void HookToDevice(ID3D11Device* InDevice) @@ -2466,6 +2546,8 @@ static HRESULT hkD3D11On12CreateDevice(IUnknown* pDevice, UINT Flags, D3D_FEATUR { LOG_FUNC(); + bool rtss = false; + // Assuming RTSS is creating a D3D11on12 device, not sure why but sometimes RTSS tries to create // it's D3D11on12 device with old CommandQueue which results crash // I am changing it's CommandQueue with current swapchain's command queue @@ -2473,13 +2555,14 @@ static HRESULT hkD3D11On12CreateDevice(IUnknown* pDevice, UINT Flags, D3D_FEATUR { LOG_INFO("Replaced RTSS CommandQueue with correct one {0:X} -> {1:X}", (UINT64)*ppCommandQueues, (UINT64)currentSCCommandQueue); *ppCommandQueues = currentSCCommandQueue; + rtss = true; } auto result = o_D3D11On12CreateDevice(pDevice, Flags, pFeatureLevels, FeatureLevels, ppCommandQueues, NumQueues, NodeMask, ppDevice, ppImmediateContext, pChosenFeatureLevel); - if (result == S_OK && *ppDevice != nullptr) + if (result == S_OK && *ppDevice != nullptr && !rtss) { - LOG_INFO("Device captured, CommandQueue: {0:X}", (UINT64)*ppCommandQueues); + LOG_INFO("Device captured, D3D11Device: {0:X}", (UINT64)*ppDevice); d3d11on12Device = *ppDevice; HookToDevice(d3d11on12Device); } diff --git a/OptiScaler/resource.h b/OptiScaler/resource.h index 59eecd3f..839c3cf3 100644 --- a/OptiScaler/resource.h +++ b/OptiScaler/resource.h @@ -21,7 +21,7 @@ #define VER_MAJOR_VERSION 0 #define VER_MINOR_VERSION 7 #define VER_HOTFIX_VERSION 0 -#define VER_BUILD_NUMBER 12 +#define VER_BUILD_NUMBER 13 #define VER_PRE_RELEASE