diff options
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp | 15 | ||||
-rw-r--r-- | xbmc/interfaces/legacy/Settings.h | 2 | ||||
-rw-r--r-- | xbmc/platform/win32/WIN32Util.cpp | 76 | ||||
-rw-r--r-- | xbmc/platform/win32/WIN32Util.h | 10 | ||||
-rw-r--r-- | xbmc/rendering/dx/DeviceResources.cpp | 41 | ||||
-rw-r--r-- | xbmc/rendering/dx/DeviceResources.h | 5 | ||||
-rw-r--r-- | xbmc/rendering/dx/DirectXHelper.h | 26 | ||||
-rw-r--r-- | xbmc/rendering/dx/RenderSystemDX.h | 7 |
8 files changed, 165 insertions, 17 deletions
diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp index a514fd0166..a9143b2397 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp @@ -1035,7 +1035,7 @@ static bool IsL41LimitedATI() DXGI_ADAPTER_DESC AIdentifier = {}; DX::DeviceResources::Get()->GetAdapterDesc(&AIdentifier); - if (AIdentifier.VendorId == PCIV_ATI) + if (AIdentifier.VendorId == PCIV_AMD) { for (unsigned idx = 0; UVDDeviceID[idx] != 0; idx++) { @@ -1052,7 +1052,7 @@ static bool HasVP3WidthBug(AVCodecContext* avctx) DXGI_ADAPTER_DESC AIdentifier = {}; DX::DeviceResources::Get()->GetAdapterDesc(&AIdentifier); - if (AIdentifier.VendorId == PCIV_nVidia && + if (AIdentifier.VendorId == PCIV_NVIDIA && !CDVDCodecUtils::IsVP3CompatibleWidth(avctx->coded_width)) { // Find the card in a known list of problematic VP3 hardware @@ -1067,7 +1067,7 @@ static bool HasATIMP2Bug(AVCodecContext* avctx) { DXGI_ADAPTER_DESC AIdentifier = {}; DX::DeviceResources::Get()->GetAdapterDesc(&AIdentifier); - if (AIdentifier.VendorId != PCIV_ATI) + if (AIdentifier.VendorId != PCIV_AMD) return false; // AMD/ATI card doesn't like some SD MPEG2 content @@ -1245,7 +1245,7 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, enum AVPixel "DXVA: used Intel ClearVideo decoder, but no support workaround for it in libavcodec."); #endif } - else if (ad.VendorId == PCIV_ATI && IsL41LimitedATI()) + else if (ad.VendorId == PCIV_AMD && IsL41LimitedATI()) { #ifdef FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG m_avD3D11Context->workaround |= FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG; @@ -1434,11 +1434,8 @@ bool CDecoder::OpenDecoder() m_avD3D11Context->video_context = nullptr; m_avD3D11Context->surface_count = m_refs; - DXGI_ADAPTER_DESC AIdentifier = {}; - DX::DeviceResources::Get()->GetAdapterDesc(&AIdentifier); - - // use true shared buffers on Intel - bool trueShared = m_dxvaContext->IsContextShared() && AIdentifier.VendorId == PCIV_Intel; + // use true shared buffers always on Intel or Nvidia/AMD with recent drivers + const bool trueShared = DX::DeviceResources::Get()->IsDXVA2SharedDecoderSurfaces(); if (!m_dxvaContext->CreateSurfaces(m_format, m_avD3D11Context->surface_count, m_surface_alignment, m_avD3D11Context->surface, &m_sharedHandle, trueShared)) diff --git a/xbmc/interfaces/legacy/Settings.h b/xbmc/interfaces/legacy/Settings.h index e4a583a269..8b8bb0eeb0 100644 --- a/xbmc/interfaces/legacy/Settings.h +++ b/xbmc/interfaces/legacy/Settings.h @@ -45,7 +45,7 @@ XBMCCOMMONS_STANDARD_EXCEPTION(SettingCallbacksNotSupportedException); /// **Example:** /// ~~~~~~~~~~~~~{.py} /// ... -/// settings = xbmc.Addon('id').getSettings() +/// settings = xbmcaddon.Addon('id').getSettings() /// ... /// ~~~~~~~~~~~~~ // diff --git a/xbmc/platform/win32/WIN32Util.cpp b/xbmc/platform/win32/WIN32Util.cpp index 02cb880a18..d2cf1363c7 100644 --- a/xbmc/platform/win32/WIN32Util.cpp +++ b/xbmc/platform/win32/WIN32Util.cpp @@ -15,6 +15,7 @@ #include "WindowHelper.h" #include "guilib/LocalizeStrings.h" #include "my_ntddscsi.h" +#include "rendering/dx/DirectXHelper.h" #include "storage/MediaManager.h" #include "storage/cdioSupport.h" #include "utils/CharsetConverter.h" @@ -1504,3 +1505,78 @@ void CWIN32Util::PlatformSyslog() CLog::Log(LOGINFO, "Display HDR capable is detected and Windows HDR switch is {}", (hdrStatus == HDR_STATUS::HDR_ON) ? "ON" : "OFF"); } + +VideoDriverInfo CWIN32Util::GetVideoDriverInfo(const UINT vendorId, const std::wstring& driverDesc) +{ + VideoDriverInfo info = {}; + +#ifdef TARGET_WINDOWS_DESKTOP + HKEY hKey = nullptr; + const wchar_t* SUBKEY = L"SYSTEM\\CurrentControlSet\\Control\\Video"; + + if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_LOCAL_MACHINE, SUBKEY, 0, KEY_ENUMERATE_SUB_KEYS, &hKey)) + return {}; + + LSTATUS sta = ERROR_SUCCESS; + wchar_t keyName[128] = {}; + DWORD index = 0; + DWORD len; + + using KODI::PLATFORM::WINDOWS::FromW; + + do + { + len = sizeof(keyName) / sizeof(wchar_t); + sta = RegEnumKeyExW(hKey, index, keyName, &len, nullptr, nullptr, nullptr, nullptr); + index++; + + if (sta != ERROR_SUCCESS) + continue; + + std::wstring subkey(SUBKEY); + subkey.append(L"\\"); + subkey.append(keyName); + subkey.append(L"\\"); + subkey.append(L"0000"); + DWORD lg; + + wchar_t desc[128] = {}; + lg = sizeof(desc) / sizeof(wchar_t); + if (ERROR_SUCCESS != RegGetValueW(HKEY_LOCAL_MACHINE, subkey.c_str(), L"DriverDesc", + RRF_RT_REG_SZ, nullptr, desc, &lg)) + continue; + + std::wstring s_desc(desc); + if (s_desc != driverDesc) + continue; + + // driver of interest found, we read version + wchar_t version[64] = {}; + lg = sizeof(version) / sizeof(wchar_t); + if (ERROR_SUCCESS != RegGetValueW(HKEY_LOCAL_MACHINE, subkey.c_str(), L"DriverVersion", + RRF_RT_REG_SZ, nullptr, version, &lg)) + continue; + + info.valid = true; + info.version = FromW(std::wstring(version)); + + // convert driver store version to Nvidia version + if (vendorId == PCIV_NVIDIA) + { + std::string ver(info.version); + StringUtils::Replace(ver, ".", ""); + info.majorVersion = std::stoi(ver.substr(ver.length() - 5, 3)); + info.minorVersion = std::stoi(ver.substr(ver.length() - 2, 2)); + } + else // for Intel/AMD fill major version only + { + info.majorVersion = std::stoi(info.version.substr(0, 2)); + } + + } while (sta == ERROR_SUCCESS && !info.valid); + + RegCloseKey(hKey); +#endif + + return info; +} diff --git a/xbmc/platform/win32/WIN32Util.h b/xbmc/platform/win32/WIN32Util.h index e87f9ee343..247bed0a35 100644 --- a/xbmc/platform/win32/WIN32Util.h +++ b/xbmc/platform/win32/WIN32Util.h @@ -20,6 +20,14 @@ #define BONJOUR_BROWSER_EVENT ( WM_USER + 0x110 ) #define TRAY_ICON_NOTIFY ( WM_USER + 0x120 ) +struct VideoDriverInfo +{ + int majorVersion; + int minorVersion; + bool valid; + std::string version; +}; + class CURL; // forward declaration class CWIN32Util @@ -74,4 +82,6 @@ public: static HDR_STATUS GetWindowsHDRStatus(); static void PlatformSyslog(); + + static VideoDriverInfo GetVideoDriverInfo(const UINT vendorId, const std::wstring& driverDesc); }; diff --git a/xbmc/rendering/dx/DeviceResources.cpp b/xbmc/rendering/dx/DeviceResources.cpp index b58a1e6df3..4993b9344b 100644 --- a/xbmc/rendering/dx/DeviceResources.cpp +++ b/xbmc/rendering/dx/DeviceResources.cpp @@ -432,6 +432,8 @@ void DX::DeviceResources::CreateDeviceResources() KODI::PLATFORM::WINDOWS::FromW(aDesc.Description), GetFeatureLevelDescription(m_d3dFeatureLevel)); + CheckDXVA2SharedDecoderSurfaces(); + m_bDeviceCreated = true; } @@ -1096,6 +1098,45 @@ void DX::DeviceResources::CheckNV12SharedTexturesSupport() m_NV12SharedTexturesSupport ? " " : " NOT "); } +void DX::DeviceResources::CheckDXVA2SharedDecoderSurfaces() +{ + if (CSysInfo::GetWindowsDeviceFamily() != CSysInfo::Desktop) + return; + + VideoDriverInfo driver = GetVideoDriverVersion(); + + if (!m_NV12SharedTexturesSupport) + return; + + DXGI_ADAPTER_DESC ad = {}; + GetAdapterDesc(&ad); + + m_DXVA2SharedDecoderSurfaces = + ad.VendorId == PCIV_Intel || + (ad.VendorId == PCIV_NVIDIA && driver.valid && driver.majorVersion >= 465) || + (ad.VendorId == PCIV_AMD && driver.valid && driver.majorVersion >= 30); + + CLog::LogF(LOGINFO, "DXVA2 shared decoder surfaces is{}supported", + m_DXVA2SharedDecoderSurfaces ? " " : " NOT "); +} + +VideoDriverInfo DX::DeviceResources::GetVideoDriverVersion() +{ + DXGI_ADAPTER_DESC ad = {}; + GetAdapterDesc(&ad); + + VideoDriverInfo driver = CWIN32Util::GetVideoDriverInfo(ad.VendorId, ad.Description); + + if (ad.VendorId == PCIV_NVIDIA) + CLog::LogF(LOGINFO, "video driver version is {} {}.{} ({})", GetGFXProviderName(ad.VendorId), + driver.majorVersion, driver.minorVersion, driver.version); + else + CLog::LogF(LOGINFO, "video driver version is {} {}", GetGFXProviderName(ad.VendorId), + driver.version); + + return driver; +} + #if defined(TARGET_WINDOWS_DESKTOP) // This method is called when the window (WND) is created (or re-created). void DX::DeviceResources::SetWindow(HWND window) diff --git a/xbmc/rendering/dx/DeviceResources.h b/xbmc/rendering/dx/DeviceResources.h index 33c93b1462..d45890264f 100644 --- a/xbmc/rendering/dx/DeviceResources.h +++ b/xbmc/rendering/dx/DeviceResources.h @@ -22,6 +22,7 @@ struct RESOLUTION_INFO; struct DEBUG_INFO_RENDER; +struct VideoDriverInfo; namespace DX { @@ -112,6 +113,7 @@ namespace DX void SetWindowPos(winrt::Windows::Foundation::Rect rect); #endif // TARGET_WINDOWS_STORE bool IsNV12SharedTexturesSupported() const { return m_NV12SharedTexturesSupport; } + bool IsDXVA2SharedDecoderSurfaces() const { return m_DXVA2SharedDecoderSurfaces; } // Gets debug info from swapchain DEBUG_INFO_RENDER GetDebugInfo() const; @@ -136,6 +138,8 @@ namespace DX void HandleOutputChange(const std::function<bool(DXGI_OUTPUT_DESC)>& cmpFunc); bool CreateFactory(); void CheckNV12SharedTexturesSupport(); + VideoDriverInfo GetVideoDriverVersion(); + void CheckDXVA2SharedDecoderSurfaces(); HWND m_window{ nullptr }; #if defined(TARGET_WINDOWS_STORE) @@ -178,5 +182,6 @@ namespace DX bool m_IsHDROutput; bool m_IsTransferPQ; bool m_NV12SharedTexturesSupport{false}; + bool m_DXVA2SharedDecoderSurfaces{false}; }; } diff --git a/xbmc/rendering/dx/DirectXHelper.h b/xbmc/rendering/dx/DirectXHelper.h index 1133b6b024..bb51ca6fd7 100644 --- a/xbmc/rendering/dx/DirectXHelper.h +++ b/xbmc/rendering/dx/DirectXHelper.h @@ -16,6 +16,13 @@ #include <d3d11_4.h> #include <ppltasks.h> // For create_task +enum PCI_Vendors +{ + PCIV_AMD = 0x1002, + PCIV_NVIDIA = 0x10DE, + PCIV_Intel = 0x8086, +}; + namespace DX { #define RATIONAL_TO_FLOAT(rational) ((rational.Denominator != 0) ? \ @@ -94,6 +101,25 @@ namespace DX return StringUtils::Format("D3D_FEATURE_LEVEL_{}_{}", fl_major, fl_minor); } + inline std::string GetGFXProviderName(UINT vendorId) + { + std::string name; + switch (vendorId) + { + case PCIV_AMD: + name = "AMD"; + break; + case PCIV_Intel: + name = "Intel"; + break; + case PCIV_NVIDIA: + name = "NVIDIA"; + break; + } + + return name; + } + template <typename T> struct SizeGen { SizeGen<T>() { Width = Height = 0; } diff --git a/xbmc/rendering/dx/RenderSystemDX.h b/xbmc/rendering/dx/RenderSystemDX.h index 0889fe096c..9a18e22045 100644 --- a/xbmc/rendering/dx/RenderSystemDX.h +++ b/xbmc/rendering/dx/RenderSystemDX.h @@ -17,13 +17,6 @@ #include <wrl/client.h> -enum PCI_Vendors -{ - PCIV_ATI = 0x1002, - PCIV_nVidia = 0x10DE, - PCIV_Intel = 0x8086 -}; - class ID3DResource; class CGUIShaderDX; enum AVPixelFormat; |