aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp15
-rw-r--r--xbmc/interfaces/legacy/Settings.h2
-rw-r--r--xbmc/platform/win32/WIN32Util.cpp76
-rw-r--r--xbmc/platform/win32/WIN32Util.h10
-rw-r--r--xbmc/rendering/dx/DeviceResources.cpp41
-rw-r--r--xbmc/rendering/dx/DeviceResources.h5
-rw-r--r--xbmc/rendering/dx/DirectXHelper.h26
-rw-r--r--xbmc/rendering/dx/RenderSystemDX.h7
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;