Use realtime GPU priority to avoid stalls during high GPU usage

Change derived from OBS project commit: ec769ef008
See related discussion: https://obsproject.com/forum/threads/obs-studio-24-0-3-gpu-priority-fix-testing.111669/
This commit is contained in:
Conn O'Griofa 2021-01-04 04:45:46 +00:00
parent 415dec37ad
commit 0a883ab651
2 changed files with 43 additions and 0 deletions

View File

@ -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 {

View File

@ -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 };