From 38156c9f7f69a0b806231539a7286368a284534d Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 13 Mar 2023 22:56:28 -0500 Subject: [PATCH] Default to D3D11VA on multi-GPU systems --- .../video/ffmpeg-renderers/dxva2.cpp | 33 +++++++++++++++---- app/streaming/video/ffmpeg-renderers/dxva2.h | 1 + 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index 4d4c040a..b8807b63 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -392,6 +392,14 @@ bool DXVA2Renderer::initializeDeviceQuirks() if (SUCCEEDED(hr)) { D3DCAPS9 caps; + UINT adapterCount = d3d9->GetAdapterCount(); + if (adapterCount > 1) { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Detected multi-GPU system with %d GPUs", + adapterCount); + m_DeviceQuirks |= DXVA2_QUIRK_MULTI_GPU; + } + hr = m_Device->GetDeviceCaps(&caps); if (SUCCEEDED(hr)) { D3DADAPTER_IDENTIFIER9 id; @@ -767,7 +775,8 @@ bool DXVA2Renderer::initialize(PDECODER_PARAMETERS params) } // If we have a WDDM 2.0 or later display driver and we're not running in - // full-screen exclusive mode, prefer the D3D11VA renderer. + // full-screen exclusive mode (or we're on a multi-GPU system in FSE), + // prefer the D3D11VA renderer. // // D3D11VA is better in this case because it can enable tearing in non-FSE // modes when the user has V-Sync disabled. In non-FSE V-Sync cases, D3D11VA @@ -775,15 +784,27 @@ bool DXVA2Renderer::initialize(PDECODER_PARAMETERS params) // in windowed mode. When using D3D9, DWM will not promote us to IFlip unless // we're full-screen (exclusive or not). // + // We prefer D3D11VA in FSE multi-GPU cases due to a plethora of issues with + // D3D9Ex PresentEx()/D3DPRESENT_DONOTWAIT on hybrid graphics systems (See + // issues #235, #240, #386, and #951 on GitHub). Clearly this codepath is not + // well tested by Microsoft or GPU vendors, so stick to the more common + // D3D11-based renderer which is much more likely to behave. + // // NB: The reason we only do this for WDDM 2.0 and later is because older // AMD drivers (such as those for the HD 5570) render garbage when using // the D3D11VA renderer. if (m_DecoderSelectionPass == 0 && - (m_DeviceQuirks & DXVA2_QUIRK_WDDM_20_PLUS) && - !((SDL_GetWindowFlags(params->window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN)) { - SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, - "Defaulting to D3D11VA for non-FSE mode"); - return false; + (m_DeviceQuirks & DXVA2_QUIRK_WDDM_20_PLUS)) { + if (!((SDL_GetWindowFlags(params->window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN)) { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Defaulting to D3D11VA for non-FSE mode"); + return false; + } + else if (m_DeviceQuirks & DXVA2_QUIRK_MULTI_GPU) { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Defaulting to D3D11VA for multi-GPU FSE mode"); + return false; + } } if (!initializeDecoder()) { diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.h b/app/streaming/video/ffmpeg-renderers/dxva2.h index a2e23cb3..f617beca 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.h +++ b/app/streaming/video/ffmpeg-renderers/dxva2.h @@ -81,5 +81,6 @@ private: #define DXVA2_QUIRK_NO_VP 0x01 #define DXVA2_QUIRK_SET_DEST_FORMAT 0x02 #define DXVA2_QUIRK_WDDM_20_PLUS 0x04 +#define DXVA2_QUIRK_MULTI_GPU 0x08 int m_DeviceQuirks; };