From b9f481afb7b5dbb9fdb8663b93bd92063f7f2110 Mon Sep 17 00:00:00 2001 From: Liam Middlebrook Date: Sat, 12 Oct 2024 15:35:53 -0700 Subject: [PATCH] winex11.drv: Implement D3DKMTQueryAdapterInfo WDDM_2_7_CAPS Used by applications to query support for "Hardware Scheduling" for GPU workloads. This is used as a proxy to determine scheduling guarantees between userspace command submission and GPU execution. Signed-off-by: Liam Middlebrook Note: This commit is specifically targeted towards ValveSoftware/wine experimental_9.0 branch. Upstream wine contains commits which change how this would be implemented. Notably, the changes in `dlls/winex11.drv/x11drv_main.c` should be instead made in `dlls/win32u/d3dkmt.c`. --- dlls/winex11.drv/x11drv_main.c | 50 ++++++++++++++++++++++++++++++++++ include/ddk/d3dkmthk.h | 14 ++++++++++ 2 files changed, 64 insertions(+) diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index d5461e1124ea..ea29548eb41f 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -1401,19 +1401,69 @@ NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) NTSTATUS X11DRV_D3DKMTQueryAdapterInfo( D3DKMT_QUERYADAPTERINFO *desc ) { + const struct vulkan_funcs *vulkan_funcs = get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION); + PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; + VkPhysicalDeviceDriverPropertiesKHR driverProperties; + VkPhysicalDeviceProperties2KHR properties2; NTSTATUS status = STATUS_INVALID_PARAMETER; struct x11_d3dkmt_adapter *adapter; + if (!vulkan_funcs) + { + WARN("Vulkan is unavailable.\n"); + return STATUS_UNSUCCESSFUL; + } + pthread_mutex_lock(&d3dkmt_mutex); LIST_FOR_EACH_ENTRY(adapter, &x11_d3dkmt_adapters, struct x11_d3dkmt_adapter, entry) { if (adapter->handle != desc->hAdapter) continue; + if (!(pvkGetPhysicalDeviceProperties2KHR = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(d3dkmt_vk_instance, "vkGetPhysicalDeviceProperties2KHR"))) + { + WARN("Failed to load vkGetPhysicalDeviceProperties2KHR.\n"); + status = STATUS_UNSUCCESSFUL; + goto done; + } + + memset(&driverProperties, 0, sizeof(driverProperties)); + memset(&properties2, 0, sizeof(properties2)); + driverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR; + properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; + properties2.pNext = &driverProperties; + pvkGetPhysicalDeviceProperties2KHR(adapter->vk_device, &properties2); + + if (desc->Type == KMTQAITYPE_WDDM_2_7_CAPS) + { + /* + * Advertise Hardware-Scheduling as enabled for NVIDIA Adapters. NVIDIA driver does + * userspace submission. + */ + D3DKMT_WDDM_2_7_CAPS *data = desc->pPrivateDriverData; + if (driverProperties.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY) + { + data->HwSchEnabled = 1; + data->HwSchSupported = 1; + data->HwSchEnabledByDefault = 1; + status = STATUS_SUCCESS; + goto done; + } + else + { + data->HwSchEnabled = 0; + data->HwSchSupported = 0; + data->HwSchEnabledByDefault = 0; + status = STATUS_SUCCESS; + goto done; + } + } + FIXME("desc %p, type %d stub\n", desc, desc->Type); status = STATUS_NOT_IMPLEMENTED; break; } +done: pthread_mutex_unlock(&d3dkmt_mutex); return status; } diff --git a/include/ddk/d3dkmthk.h b/include/ddk/d3dkmthk.h index 2d30bdd8777e..d4d4f88a6059 100644 --- a/include/ddk/d3dkmthk.h +++ b/include/ddk/d3dkmthk.h @@ -266,6 +266,20 @@ typedef struct _D3DKMT_QUERYADAPTERINFO UINT PrivateDriverDataSize; } D3DKMT_QUERYADAPTERINFO; +typedef struct _D3DKMT_WDDM_2_7_CAPS +{ + union { + struct { + UINT HwSchSupported : 1; + UINT HwSchEnabled : 1; + UINT HwSchEnabledByDefault : 1; + UINT IndependentVidPnVSyncControl : 1; + UINT Reserved : 28; + }; + UINT Value; + }; +} D3DKMT_WDDM_2_7_CAPS; + typedef enum _D3DKMT_QUERYRESULT_PREEMPTION_ATTEMPT_RESULT { D3DKMT_PreemptionAttempt = 0,