From 0a883ab651ec5e496c3bb39072cd3cb5f13cf3bc Mon Sep 17 00:00:00 2001 From: Conn O'Griofa Date: Mon, 4 Jan 2021 04:45:46 +0000 Subject: [PATCH] Use realtime GPU priority to avoid stalls during high GPU usage Change derived from OBS project commit: https://github.com/obsproject/obs-studio/commit/ec769ef008b748f7dfba211daec9eb203ea4bea0 See related discussion: https://obsproject.com/forum/threads/obs-studio-24-0-3-gpu-priority-fix-testing.111669/ --- sunshine/platform/windows/display.h | 13 ++++++++++ sunshine/platform/windows/display_base.cpp | 30 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/sunshine/platform/windows/display.h b/sunshine/platform/windows/display.h index 662115e8..039e6a75 100644 --- a/sunshine/platform/windows/display.h +++ b/sunshine/platform/windows/display.h @@ -84,6 +84,19 @@ public: DXGI_FORMAT format; D3D_FEATURE_LEVEL feature_level; + + typedef enum _D3DKMT_SCHEDULINGPRIORITYCLASS + { + D3DKMT_SCHEDULINGPRIORITYCLASS_IDLE, + D3DKMT_SCHEDULINGPRIORITYCLASS_BELOW_NORMAL, + D3DKMT_SCHEDULINGPRIORITYCLASS_NORMAL, + D3DKMT_SCHEDULINGPRIORITYCLASS_ABOVE_NORMAL, + D3DKMT_SCHEDULINGPRIORITYCLASS_HIGH, + D3DKMT_SCHEDULINGPRIORITYCLASS_REALTIME + } + D3DKMT_SCHEDULINGPRIORITYCLASS; + + typedef NTSTATUS WINAPI (*PD3DKMTSetProcessSchedulingPriorityClass)(HANDLE, D3DKMT_SCHEDULINGPRIORITYCLASS); }; class display_ram_t : public display_base_t { diff --git a/sunshine/platform/windows/display_base.cpp b/sunshine/platform/windows/display_base.cpp index 4b42880c..c510b044 100644 --- a/sunshine/platform/windows/display_base.cpp +++ b/sunshine/platform/windows/display_base.cpp @@ -206,6 +206,36 @@ int display_base_t::init() { // Bump up thread priority { + const DWORD flags = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY; + TOKEN_PRIVILEGES tp; + HANDLE token; + LUID val; + + if (OpenProcessToken(GetCurrentProcess(), flags, &token) && + !!LookupPrivilegeValue(NULL, SE_INC_BASE_PRIORITY_NAME, &val)) { + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = val; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if (!AdjustTokenPrivileges(token, false, &tp, sizeof(tp), NULL, NULL)) { + BOOST_LOG(error) << "Could not set privilege to increase GPU priority"; + } + } + + CloseHandle(token); + + HMODULE gdi32 = GetModuleHandleA("GDI32"); + if (gdi32) { + PD3DKMTSetProcessSchedulingPriorityClass fn = + (PD3DKMTSetProcessSchedulingPriorityClass)GetProcAddress(gdi32, "D3DKMTSetProcessSchedulingPriorityClass"); + if (fn) { + status = fn(GetCurrentProcess(), D3DKMT_SCHEDULINGPRIORITYCLASS_REALTIME); + if (FAILED(status)) { + BOOST_LOG(error) << "Failed to set realtime GPU priority. Please run application as administrator for optimal performance."; + } + } + } + dxgi::dxgi_t::pointer dxgi_p {}; status = device->QueryInterface(IID_IDXGIDevice, (void**)&dxgi_p); dxgi::dxgi_t dxgi { dxgi_p };