Просмотр исходного кода

libobs-d3d11: Log HAGS driver support and status

Rodney 2 лет назад
Родитель
Сommit
6efe7ab1c8
1 измененных файлов с 110 добавлено и 12 удалено
  1. 110 12
      libobs-d3d11/d3d11-subsystem.cpp

+ 110 - 12
libobs-d3d11/d3d11-subsystem.cpp

@@ -17,6 +17,7 @@
 
 #include <cassert>
 #include <cinttypes>
+#include <optional>
 #include <util/base.h>
 #include <util/platform.h>
 #include <util/dstr.h>
@@ -503,18 +504,87 @@ static bool set_priority(ID3D11Device *device, bool hags_enabled)
 }
 #endif
 
-static bool adapter_hags_enabled(DXGI_ADAPTER_DESC *desc)
+struct HagsStatus {
+	enum DriverSupport {
+		ALWAYS_OFF,
+		ALWAYS_ON,
+		EXPERIMENTAL,
+		STABLE,
+		UNKNOWN
+	};
+
+	bool enabled;
+	bool enabled_by_default;
+	DriverSupport support;
+
+	explicit HagsStatus(const D3DKMT_WDDM_2_7_CAPS *caps)
+	{
+		enabled = caps->HwSchEnabled;
+		enabled_by_default = caps->HwSchEnabledByDefault;
+		support = caps->HwSchSupported ? DriverSupport::STABLE
+					       : DriverSupport::ALWAYS_OFF;
+	}
+
+	void SetDriverSupport(const UINT DXGKVal)
+	{
+		switch (DXGKVal) {
+		case DXGK_FEATURE_SUPPORT_ALWAYS_OFF:
+			support = ALWAYS_OFF;
+			break;
+		case DXGK_FEATURE_SUPPORT_ALWAYS_ON:
+			support = ALWAYS_ON;
+			break;
+		case DXGK_FEATURE_SUPPORT_EXPERIMENTAL:
+			support = EXPERIMENTAL;
+			break;
+		case DXGK_FEATURE_SUPPORT_STABLE:
+			support = STABLE;
+			break;
+		default:
+			support = UNKNOWN;
+		}
+	}
+
+	string ToString() const
+	{
+		string status = enabled ? "Enabled" : "Disabled";
+		status += " (Default: ";
+		status += enabled_by_default ? "Yes" : "No";
+		status += ", Driver status: ";
+		status += DriverSupportToString();
+		status += ")";
+
+		return status;
+	}
+
+private:
+	const char *DriverSupportToString() const
+	{
+		switch (support) {
+		case ALWAYS_OFF:
+			return "Unsupported";
+		case ALWAYS_ON:
+			return "Always On";
+		case EXPERIMENTAL:
+			return "Experimental";
+		case STABLE:
+			return "Supported";
+		default:
+			return "Unknown";
+		}
+	}
+};
+
+static optional<HagsStatus> GetAdapterHagsStatus(const DXGI_ADAPTER_DESC *desc)
 {
+	optional<HagsStatus> ret;
 	D3DKMT_OPENADAPTERFROMLUID d3dkmt_openluid{};
-	bool hags_enabled = false;
-	NTSTATUS res;
-
 	d3dkmt_openluid.AdapterLuid = desc->AdapterLuid;
 
-	res = D3DKMTOpenAdapterFromLuid(&d3dkmt_openluid);
+	NTSTATUS res = D3DKMTOpenAdapterFromLuid(&d3dkmt_openluid);
 	if (FAILED(res)) {
 		blog(LOG_DEBUG, "Failed opening D3DKMT adapter: %x", res);
-		return hags_enabled;
+		return ret;
 	}
 
 	D3DKMT_WDDM_2_7_CAPS caps = {};
@@ -525,10 +595,28 @@ static bool adapter_hags_enabled(DXGI_ADAPTER_DESC *desc)
 	args.PrivateDriverDataSize = sizeof(caps);
 	res = D3DKMTQueryAdapterInfo(&args);
 
-	/* On Windows 10 pre-2004 this will fail, but HAGS isn't supported
-	 * there anyway. */
-	if (SUCCEEDED(res))
-		hags_enabled = caps.HwSchEnabled;
+	/* If this still fails we're likely on Windows 10 pre-2004
+	 * where HAGS is not supported anyway. */
+	if (SUCCEEDED(res)) {
+		HagsStatus status(&caps);
+
+		/* Starting with Windows 10 21H2 we can query more detailed
+		 * support information (e.g. experimental status).
+		 * This Is optional and failure doesn't matter. */
+		D3DKMT_WDDM_2_9_CAPS ext_caps = {};
+		args.hAdapter = d3dkmt_openluid.hAdapter;
+		args.Type = KMTQAITYPE_WDDM_2_9_CAPS;
+		args.pPrivateDriverData = &ext_caps;
+		args.PrivateDriverDataSize = sizeof(ext_caps);
+		res = D3DKMTQueryAdapterInfo(&args);
+
+		if (SUCCEEDED(res))
+			status.SetDriverSupport(ext_caps.HwSchSupportState);
+
+		ret = status;
+	} else {
+		blog(LOG_WARNING, "Failed querying WDDM 2.7 caps: %x", res);
+	}
 
 	D3DKMT_CLOSEADAPTER d3dkmt_close = {d3dkmt_openluid.hAdapter};
 	res = D3DKMTCloseAdapter(&d3dkmt_close);
@@ -537,7 +625,7 @@ static bool adapter_hags_enabled(DXGI_ADAPTER_DESC *desc)
 		     d3dkmt_openluid.hAdapter, res);
 	}
 
-	return hags_enabled;
+	return ret;
 }
 
 static bool CheckFormat(ID3D11Device *device, DXGI_FORMAT format)
@@ -590,7 +678,10 @@ void gs_device::InitDevice(uint32_t adapterIdx)
 	}
 
 	/* Log HAGS status */
-	bool hags_enabled = adapter_hags_enabled(&desc);
+	bool hags_enabled = false;
+	if (auto hags_status = GetAdapterHagsStatus(&desc))
+		hags_enabled = hags_status->enabled;
+
 	if (hags_enabled) {
 		blog(LOG_WARNING,
 		     "Hardware-Accelerated GPU Scheduling enabled on adapter!");
@@ -1370,6 +1461,13 @@ static inline void LogD3DAdapters()
 		blog(LOG_INFO, "\t  PCI ID:         %x:%x", desc.VendorId,
 		     desc.DeviceId);
 
+		if (auto hags_support = GetAdapterHagsStatus(&desc)) {
+			blog(LOG_INFO, "\t  HAGS Status:    %s",
+			     hags_support->ToString().c_str());
+		} else {
+			blog(LOG_WARNING, "\t  HAGS Status:    Unknown");
+		}
+
 		/* driver version */
 		LARGE_INTEGER umd;
 		hr = adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice),