From cefa567f9584cb1dd46f67cefb8ab01612a76b5b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 26 Mar 2024 23:04:54 -0500 Subject: [PATCH] Demote DXVA2 renderer to second pass of hwaccels --- .../video/ffmpeg-renderers/dxva2.cpp | 35 ------------------- app/streaming/video/ffmpeg-renderers/dxva2.h | 2 +- app/streaming/video/ffmpeg.cpp | 14 +++----- 3 files changed, 6 insertions(+), 45 deletions(-) diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index dda82407..0e81fc6e 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -447,13 +447,6 @@ bool DXVA2Renderer::initializeQuirksForAdapter(IDirect3D9Ex* d3d9ex, int adapter // For other GPUs, we'll avoid populating it as was our previous behavior. m_DeviceQuirks |= DXVA2_QUIRK_SET_DEST_FORMAT; } - - // Tag this display device if it has a WDDM 2.0+ driver for the decoder selection logic - if (HIWORD(id.DriverVersion.HighPart) >= 20) { - SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, - "Detected WDDM 2.0 or later display driver"); - m_DeviceQuirks |= DXVA2_QUIRK_WDDM_20_PLUS; - } } return true; @@ -568,34 +561,6 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync) return false; } - // If we have a WDDM 2.0 or later display driver, 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 - // provides lower display latency on systems that support Independent Flip - // in windowed mode. When using D3D9, DWM will not promote us to IFlip unless - // we're full-screen (exclusive or not). - // - // We want 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. - // - // DXVA2 video processing is also quite buggy on AMD, Intel, and Qualcomm - // hardware with various issues documented in initializeQuirksForAdapter(). - // We can avoid all this by using our own shaders in the D3D11VA renderer. - // - // 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_LogInfo(SDL_LOG_CATEGORY_APPLICATION, - "Defaulting to D3D11VA for WDDM 2.0 GPU driver"); - d3d9ex->Release(); - return false; - } - D3DCAPS9 deviceCaps; d3d9ex->GetDeviceCaps(adapterIndex, D3DDEVTYPE_HAL, &deviceCaps); diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.h b/app/streaming/video/ffmpeg-renderers/dxva2.h index 0d5df725..fcda92bf 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.h +++ b/app/streaming/video/ffmpeg-renderers/dxva2.h @@ -80,7 +80,7 @@ private: #define DXVA2_QUIRK_NO_VP 0x01 #define DXVA2_QUIRK_SET_DEST_FORMAT 0x02 -#define DXVA2_QUIRK_WDDM_20_PLUS 0x04 +#define DXVA2_QUIRK_WDDM_20_PLUS 0x04 // Unused #define DXVA2_QUIRK_MULTI_GPU 0x08 int m_DeviceQuirks; }; diff --git a/app/streaming/video/ffmpeg.cpp b/app/streaming/video/ffmpeg.cpp index c81c7b69..ba11b8af 100644 --- a/app/streaming/video/ffmpeg.cpp +++ b/app/streaming/video/ffmpeg.cpp @@ -814,12 +814,8 @@ IFFmpegRenderer* FFmpegVideoDecoder::createHwAccelRenderer(const AVCodecHWConfig if (pass == 0) { switch (hwDecodeCfg->device_type) { #ifdef Q_OS_WIN32 - // DXVA2 appears in the hwaccel list before D3D11VA, so we will prefer it. - // - // There is logic in DXVA2 that may elect to fail on the first selection pass - // to allow D3D11VA to be used in cases where it is known to be better. - case AV_HWDEVICE_TYPE_DXVA2: - return new DXVA2Renderer(pass); + // DXVA2 appears in the hwaccel list before D3D11VA, so we only check for D3D11VA + // on the first pass to ensure we prefer D3D11VA over DXVA2. case AV_HWDEVICE_TYPE_D3D11VA: return new D3D11VARenderer(pass); #endif @@ -857,9 +853,9 @@ IFFmpegRenderer* FFmpegVideoDecoder::createHwAccelRenderer(const AVCodecHWConfig return new CUDARenderer(); #endif #ifdef Q_OS_WIN32 - // This gives DXVA2 and D3D11VA another shot at handling cases where they - // chose to purposefully fail in the first selection pass to allow a more - // optimal decoder to be tried. + // This gives us another shot if D3D11VA failed in the first pass. + // Since DXVA2 is in the hwaccel list first, we'll first try to fall back + // to that before giving D3D11VA another try as a last resort. case AV_HWDEVICE_TYPE_DXVA2: return new DXVA2Renderer(pass); case AV_HWDEVICE_TYPE_D3D11VA: