From 190c9b42164f74934eff195aee6384f02459e052 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 13 Aug 2023 16:14:06 -0500 Subject: [PATCH] Move AMF version check into display_vram_t to avoid blocking software encoding --- src/platform/windows/display_base.cpp | 41 -------------------- src/platform/windows/display_vram.cpp | 56 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 41 deletions(-) diff --git a/src/platform/windows/display_base.cpp b/src/platform/windows/display_base.cpp index 66a687d4..4fdf61b2 100644 --- a/src/platform/windows/display_base.cpp +++ b/src/platform/windows/display_base.cpp @@ -19,8 +19,6 @@ typedef long NTSTATUS; #include "src/platform/common.h" #include "src/video.h" -#include - namespace platf { using namespace std::literals; } @@ -487,45 +485,6 @@ namespace platf::dxgi { dup.use_dwmflush = config::video.dwmflush && !(config.framerate > refresh_rate) ? true : false; - // Older versions of the AMD AMF runtime can crash when fed P010 surfaces, so we'll - // check the AMF version if we are using HDR on an AMD GPU to avoid possibly crashing. - if (config.dynamicRange && adapter_desc.VendorId == 0x1002) { - HMODULE amfrt = LoadLibraryW(AMF_DLL_NAME); - if (amfrt) { - auto unload_amfrt = util::fail_guard([amfrt]() { - FreeLibrary(amfrt); - }); - - auto fnAMFQueryVersion = (AMFQueryVersion_Fn) GetProcAddress(amfrt, AMF_QUERY_VERSION_FUNCTION_NAME); - if (fnAMFQueryVersion) { - amf_uint64 version; - auto result = fnAMFQueryVersion(&version); - if (result == AMF_OK) { - // Fail if AMF version is below 1.4.23 where HEVC Main10 encoding was introduced. - // AMF 1.4.23 corresponds to driver version 21.12.1 (21.40.11.03) or newer. - if (version < AMF_MAKE_FULL_VERSION(1, 4, 23, 0)) { - BOOST_LOG(warning) << "HDR encoding is disabled on AMF version "sv - << AMF_GET_MAJOR_VERSION(version) << '.' - << AMF_GET_MINOR_VERSION(version) << '.' - << AMF_GET_SUBMINOR_VERSION(version) << '.' - << AMF_GET_BUILD_VERSION(version); - BOOST_LOG(warning) << "If your AMD GPU supports HEVC Main10 encoding, update your graphics drivers!"sv; - return -1; - } - } - else { - BOOST_LOG(warning) << "AMFQueryVersion() failed: "sv << result; - } - } - else { - BOOST_LOG(warning) << "AMF DLL missing export: "sv << AMF_QUERY_VERSION_FUNCTION_NAME; - } - } - else { - BOOST_LOG(warning) << "Detected AMD GPU but AMF failed to load"sv; - } - } - // Bump up thread priority { const DWORD flags = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY; diff --git a/src/platform/windows/display_vram.cpp b/src/platform/windows/display_vram.cpp index 601f084c..f5237389 100644 --- a/src/platform/windows/display_vram.cpp +++ b/src/platform/windows/display_vram.cpp @@ -23,6 +23,8 @@ extern "C" { #include "src/nvenc/nvenc_utils.h" #include "src/video.h" +#include + #define SUNSHINE_SHADERS_DIR SUNSHINE_ASSETS_DIR "/shaders/directx" namespace platf { using namespace std::literals; @@ -1324,6 +1326,60 @@ namespace platf::dxgi { return -1; } + DXGI_ADAPTER_DESC adapter_desc; + adapter->GetDesc(&adapter_desc); + + // Perform AMF version checks if we're using an AMD GPU. This check is placed in display_vram_t + // to avoid hitting the display_ram_t path which uses software encoding and doesn't touch AMF. + if ((config.dynamicRange || config.videoFormat == 2) && adapter_desc.VendorId == 0x1002) { + HMODULE amfrt = LoadLibraryW(AMF_DLL_NAME); + if (amfrt) { + auto unload_amfrt = util::fail_guard([amfrt]() { + FreeLibrary(amfrt); + }); + + auto fnAMFQueryVersion = (AMFQueryVersion_Fn) GetProcAddress(amfrt, AMF_QUERY_VERSION_FUNCTION_NAME); + if (fnAMFQueryVersion) { + amf_uint64 version; + auto result = fnAMFQueryVersion(&version); + if (result == AMF_OK) { + if (config.videoFormat == 2 && version < AMF_MAKE_FULL_VERSION(1, 4, 30, 0)) { + // AMF 1.4.30 adds ultra low latency mode for AV1. Don't use AV1 on earlier versions. + // This corresponds to driver version 23.5.2 (23.10.01.45) or newer. + BOOST_LOG(warning) << "AV1 encoding is disabled on AMF version "sv + << AMF_GET_MAJOR_VERSION(version) << '.' + << AMF_GET_MINOR_VERSION(version) << '.' + << AMF_GET_SUBMINOR_VERSION(version) << '.' + << AMF_GET_BUILD_VERSION(version); + BOOST_LOG(warning) << "If your AMD GPU supports AV1 encoding, update your graphics drivers!"sv; + return -1; + } + else if (config.dynamicRange && version < AMF_MAKE_FULL_VERSION(1, 4, 23, 0)) { + // Older versions of the AMD AMF runtime can crash when fed P010 surfaces. + // Fail if AMF version is below 1.4.23 where HEVC Main10 encoding was introduced. + // AMF 1.4.23 corresponds to driver version 21.12.1 (21.40.11.03) or newer. + BOOST_LOG(warning) << "HDR encoding is disabled on AMF version "sv + << AMF_GET_MAJOR_VERSION(version) << '.' + << AMF_GET_MINOR_VERSION(version) << '.' + << AMF_GET_SUBMINOR_VERSION(version) << '.' + << AMF_GET_BUILD_VERSION(version); + BOOST_LOG(warning) << "If your AMD GPU supports HEVC Main10 encoding, update your graphics drivers!"sv; + return -1; + } + } + else { + BOOST_LOG(warning) << "AMFQueryVersion() failed: "sv << result; + } + } + else { + BOOST_LOG(warning) << "AMF DLL missing export: "sv << AMF_QUERY_VERSION_FUNCTION_NAME; + } + } + else { + BOOST_LOG(warning) << "Detected AMD GPU but AMF failed to load"sv; + } + } + D3D11_SAMPLER_DESC sampler_desc {}; sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;