From 3c0f797ca6ecbe7619ff3705ad42735e8b5eadfa Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 15 Jul 2024 10:06:14 +1000 Subject: [PATCH] Added dxgi_getFrameStatistics patchset --- ...b-IDXGISwapChain4-GetFrameStatistics.patch | 125 ++++++++++++++++++ patches/dxgi_getFrameStatistics/definition | 1 + 2 files changed, 126 insertions(+) create mode 100644 patches/dxgi_getFrameStatistics/0001-dxgi-Semi-stub-IDXGISwapChain4-GetFrameStatistics.patch create mode 100644 patches/dxgi_getFrameStatistics/definition diff --git a/patches/dxgi_getFrameStatistics/0001-dxgi-Semi-stub-IDXGISwapChain4-GetFrameStatistics.patch b/patches/dxgi_getFrameStatistics/0001-dxgi-Semi-stub-IDXGISwapChain4-GetFrameStatistics.patch new file mode 100644 index 00000000..289e0339 --- /dev/null +++ b/patches/dxgi_getFrameStatistics/0001-dxgi-Semi-stub-IDXGISwapChain4-GetFrameStatistics.patch @@ -0,0 +1,125 @@ +From e31146d5dd91ef05298ae98f7db4868e73011865 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Thu, 23 May 2024 14:25:57 +1000 +Subject: [PATCH] dxgi: Semi-stub IDXGISwapChain::GetFrameStatistics. + +Not completely correct but does allow improved framerates. Mileage will vary. +--- + dlls/dxgi/swapchain.c | 89 +++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 85 insertions(+), 4 deletions(-) + +diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c +index 4797fcecd8d..4111a488407 100644 +--- a/dlls/dxgi/swapchain.c ++++ b/dlls/dxgi/swapchain.c +@@ -587,12 +587,66 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetContainingOutput(IDXGISwapCh + return dxgi_get_output_from_window(swapchain->factory, window, output); + } + ++static int get_display_frequency(void) ++{ ++ DEVMODEW mode; ++ BOOL ret; ++ ++ memset(&mode, 0, sizeof(mode)); ++ mode.dmSize = sizeof(mode); ++ ret = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &mode, 0); ++ if (ret && mode.dmFields & DM_DISPLAYFREQUENCY && mode.dmDisplayFrequency) ++ { ++ return mode.dmDisplayFrequency; ++ } ++ else ++ { ++ WARN("Failed to query display frequency, returning a fallback value.\n"); ++ return 60; ++ } ++} ++ ++static LARGE_INTEGER get_perf_req(void) ++{ ++ LARGE_INTEGER performance_frequency; ++ ++ QueryPerformanceFrequency(&performance_frequency); ++ return performance_frequency; ++} ++ + static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetFrameStatistics(IDXGISwapChain4 *iface, + DXGI_FRAME_STATISTICS *stats) + { +- FIXME("iface %p, stats %p stub!\n", iface, stats); ++ struct d3d11_swapchain *swapchain = d3d11_swapchain_from_IDXGISwapChain4(iface); ++ HRESULT hr = S_OK; ++ static BOOL once = 0; ++ const LARGE_INTEGER performance_frequency = get_perf_req(); ++ int display_frequency = get_display_frequency(); + +- return E_NOTIMPL; ++ LARGE_INTEGER count; ++ TRACE("iface %p, stats %p Semi-stub\n", iface, stats); ++ ++ if (!stats) ++ return E_INVALIDARG; ++ ++ QueryPerformanceCounter(&count); ++ ++ stats->PresentCount = swapchain->present_count; ++ stats->PresentRefreshCount = 0; ++ stats->SyncRefreshCount = 0; ++ stats->SyncQPCTime.QuadPart = count.QuadPart; ++ stats->SyncGPUTime.QuadPart = 0; ++ ++ stats->PresentRefreshCount = performance_frequency.QuadPart / display_frequency; ++ stats->SyncRefreshCount = display_frequency; ++ ++ if(!once) ++ { ++ once++; ++ hr = DXGI_ERROR_FRAME_STATISTICS_DISJOINT; ++ } ++ ++ return hr; + } + + static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetLastPresentCount(IDXGISwapChain4 *iface, +@@ -2704,9 +2758,36 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetContainingOutput(IDXGISwapCh + static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetFrameStatistics(IDXGISwapChain4 *iface, + DXGI_FRAME_STATISTICS *stats) + { +- FIXME("iface %p, stats %p stub!\n", iface, stats); ++ struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain4(iface); ++ HRESULT hr = S_OK; ++ static BOOL once = 0; ++ const LARGE_INTEGER performance_frequency = get_perf_req(); ++ int display_frequency = get_display_frequency(); + +- return E_NOTIMPL; ++ LARGE_INTEGER count; ++ TRACE("iface %p, stats %p Semi-stub\n", iface, stats); ++ ++ if (!stats) ++ return E_INVALIDARG; ++ ++ QueryPerformanceCounter(&count); ++ ++ stats->PresentCount = swapchain->frame_number; ++ stats->PresentRefreshCount = 0; ++ stats->SyncRefreshCount = 0; ++ stats->SyncQPCTime.QuadPart = count.QuadPart; ++ stats->SyncGPUTime.QuadPart = 0; ++ ++ stats->PresentRefreshCount = performance_frequency.QuadPart / display_frequency; ++ stats->SyncRefreshCount = display_frequency; ++ ++ if(!once) ++ { ++ once++; ++ hr = DXGI_ERROR_FRAME_STATISTICS_DISJOINT; ++ } ++ ++ return hr; + } + + static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetLastPresentCount(IDXGISwapChain4 *iface, +-- +2.43.0 + diff --git a/patches/dxgi_getFrameStatistics/definition b/patches/dxgi_getFrameStatistics/definition new file mode 100644 index 00000000..e826c0ed --- /dev/null +++ b/patches/dxgi_getFrameStatistics/definition @@ -0,0 +1 @@ +Fixes: [53696] d3d11: Semi-stub IDXGISwapChain::GetFrameStatistics.