-
-
Save Saancreed/0aa3f4188846146698f5da3dfa0dfcbd to your computer and use it in GitHub Desktop.
Wine HAGS hack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit abb67b8aee120c52847abda19efb7641eeb184ac | |
Author: Krzysztof Bogacki <krzysztof.bogacki@leancode.pl> | |
Date: Tue Dec 19 23:51:33 2023 +0100 | |
gdi32,win32u,winex11: Implement D3DKMTEnumAdapters2. | |
diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec | |
index 0ad4711..69ad9b2 100644 | |
--- a/dlls/gdi32/gdi32.spec | |
+++ b/dlls/gdi32/gdi32.spec | |
@@ -79,6 +79,7 @@ | |
@ stdcall D3DKMTCreateDevice(ptr) win32u.NtGdiDdDDICreateDevice | |
@ stdcall D3DKMTDestroyDCFromMemory(ptr) win32u.NtGdiDdDDIDestroyDCFromMemory | |
@ stdcall D3DKMTDestroyDevice(ptr) win32u.NtGdiDdDDIDestroyDevice | |
+@ stdcall D3DKMTEnumAdapters2(ptr) win32u.NtGdiDdDDIEnumAdapters2 | |
@ stdcall D3DKMTEscape(ptr) win32u.NtGdiDdDDIEscape | |
@ stdcall D3DKMTOpenAdapterFromDeviceName(ptr) win32u.NtGdiDdDDIOpenAdapterFromDeviceName | |
@ stdcall D3DKMTOpenAdapterFromGdiDisplayName(ptr) | |
diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c | |
index 7fe4b76..0a4b0ac 100644 | |
--- a/dlls/win32u/dibdrv/dc.c | |
+++ b/dlls/win32u/dibdrv/dc.c | |
@@ -709,6 +709,7 @@ const struct gdi_dc_funcs dib_driver = | |
NULL, /* pUnrealizePalette */ | |
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ | |
NULL, /* pD3DKMTCloseAdapter */ | |
+ NULL, /* pD3DKMTEnumAdapters2 */ | |
NULL, /* pD3DKMTOpenAdapterFromLuid */ | |
NULL, /* pD3DKMTQueryVideoMemoryInfo */ | |
NULL, /* pD3DKMTSetVidPnSourceOwner */ | |
@@ -1270,6 +1271,7 @@ static const struct gdi_dc_funcs window_driver = | |
NULL, /* pUnrealizePalette */ | |
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ | |
NULL, /* pD3DKMTCloseAdapter */ | |
+ NULL, /* pD3DKMTEnumAdapters2 */ | |
NULL, /* pD3DKMTOpenAdapterFromLuid */ | |
NULL, /* pD3DKMTQueryVideoMemoryInfo */ | |
NULL, /* pD3DKMTSetVidPnSourceOwner */ | |
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c | |
index 3065a61..3f7b9e4 100644 | |
--- a/dlls/win32u/driver.c | |
+++ b/dlls/win32u/driver.c | |
@@ -54,6 +54,7 @@ static struct user_driver_funcs null_user_driver; | |
static struct list d3dkmt_adapters = LIST_INIT( d3dkmt_adapters ); | |
static struct list d3dkmt_devices = LIST_INIT( d3dkmt_devices ); | |
+static D3DKMT_HANDLE handle_start = 0; | |
static pthread_mutex_t driver_lock = PTHREAD_MUTEX_INITIALIZER; | |
static WCHAR driver_load_error[80]; | |
@@ -549,6 +550,11 @@ static NTSTATUS nulldrv_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) | |
return STATUS_PROCEDURE_NOT_FOUND; | |
} | |
+static NTSTATUS nulldrv_D3DKMTEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) | |
+{ | |
+ return STATUS_PROCEDURE_NOT_FOUND; | |
+} | |
+ | |
static NTSTATUS nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) | |
{ | |
return STATUS_PROCEDURE_NOT_FOUND; | |
@@ -657,6 +663,7 @@ const struct gdi_dc_funcs null_driver = | |
nulldrv_UnrealizePalette, /* pUnrealizePalette */ | |
nulldrv_D3DKMTCheckVidPnExclusiveOwnership, /* pD3DKMTCheckVidPnExclusiveOwnership */ | |
nulldrv_D3DKMTCloseAdapter, /* pD3DKMTCloseAdapter */ | |
+ nulldrv_D3DKMTEnumAdapters2, /* pD3DKMTEnumAdapters2 */ | |
nulldrv_D3DKMTOpenAdapterFromLuid, /* pD3DKMTOpenAdapterFromLuid */ | |
nulldrv_D3DKMTQueryVideoMemoryInfo, /* pD3DKMTQueryVideoMemoryInfo */ | |
nulldrv_D3DKMTSetVidPnSourceOwner, /* pD3DKMTSetVidPnSourceOwner */ | |
@@ -1526,6 +1533,46 @@ NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) | |
return status; | |
} | |
+/****************************************************************************** | |
+ * NtGdiDdDDIEnumAdapters2 (win32u.@) | |
+ */ | |
+NTSTATUS WINAPI NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) | |
+{ | |
+ NTSTATUS status = STATUS_UNSUCCESSFUL; | |
+ struct d3dkmt_adapter *adapter; | |
+ ULONG i; | |
+ | |
+ TRACE("(%p)\n", desc); | |
+ | |
+ if (!desc) return STATUS_INVALID_PARAMETER; | |
+ | |
+ if (get_display_driver()->pD3DKMTEnumAdapters2) | |
+ { | |
+ if (desc->pAdapters) | |
+ { | |
+ pthread_mutex_lock( &driver_lock ); | |
+ | |
+ for (i = 0; i < desc->NumAdapters; ++i) | |
+ { | |
+ if (!(adapter = malloc( sizeof( *adapter ) ))) | |
+ { | |
+ pthread_mutex_unlock( &driver_lock ); | |
+ return STATUS_NO_MEMORY; | |
+ } | |
+ | |
+ desc->pAdapters[i].hAdapter = adapter->handle = ++handle_start; | |
+ list_add_tail( &d3dkmt_adapters, &adapter->entry ); | |
+ } | |
+ | |
+ pthread_mutex_unlock( &driver_lock ); | |
+ } | |
+ | |
+ status = get_display_driver()->pD3DKMTEnumAdapters2( desc ); | |
+ } | |
+ | |
+ return status; | |
+} | |
+ | |
/****************************************************************************** | |
* NtGdiDdDDIOpenAdapterFromDeviceName (win32u.@) | |
*/ | |
@@ -1551,7 +1598,6 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVIC | |
*/ | |
NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) | |
{ | |
- static D3DKMT_HANDLE handle_start = 0; | |
struct d3dkmt_adapter *adapter; | |
if (!(adapter = malloc( sizeof( *adapter ) ))) return STATUS_NO_MEMORY; | |
diff --git a/dlls/win32u/emfdrv.c b/dlls/win32u/emfdrv.c | |
index 069ad9d..9c07f9e 100644 | |
--- a/dlls/win32u/emfdrv.c | |
+++ b/dlls/win32u/emfdrv.c | |
@@ -521,6 +521,7 @@ static const struct gdi_dc_funcs emfdrv_driver = | |
NULL, /* pUnrealizePalette */ | |
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ | |
NULL, /* pD3DKMTCloseAdapter */ | |
+ NULL, /* pD3DKMTEnumAdapters2 */ | |
NULL, /* pD3DKMTOpenAdapterFromLuid */ | |
NULL, /* pD3DKMTQueryVideoMemoryInfo */ | |
NULL, /* pD3DKMTSetVidPnSourceOwner */ | |
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c | |
index af1a9b9..2f84ff3 100644 | |
--- a/dlls/win32u/font.c | |
+++ b/dlls/win32u/font.c | |
@@ -4774,6 +4774,7 @@ const struct gdi_dc_funcs font_driver = | |
NULL, /* pUnrealizePalette */ | |
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ | |
NULL, /* pD3DKMTCloseAdapter */ | |
+ NULL, /* pD3DKMTEnumAdapters2 */ | |
NULL, /* pD3DKMTOpenAdapterFromLuid */ | |
NULL, /* pD3DKMTQueryVideoMemoryInfo */ | |
NULL, /* pD3DKMTSetVidPnSourceOwner */ | |
diff --git a/dlls/win32u/main.c b/dlls/win32u/main.c | |
index 2dc66e5..3f910c2 100644 | |
--- a/dlls/win32u/main.c | |
+++ b/dlls/win32u/main.c | |
@@ -236,6 +236,11 @@ NTSTATUS SYSCALL_API NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE *desc ) | |
__ASM_SYSCALL_FUNC( __id_NtGdiDdDDIDestroyDevice ); | |
} | |
+NTSTATUS SYSCALL_API NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) | |
+{ | |
+ __ASM_SYSCALL_FUNC( __id_NtGdiDdDDIEnumAdapters2 ); | |
+} | |
+ | |
NTSTATUS SYSCALL_API NtGdiDdDDIEscape( const D3DKMT_ESCAPE *desc ) | |
{ | |
__ASM_SYSCALL_FUNC( __id_NtGdiDdDDIEscape ); | |
diff --git a/dlls/win32u/path.c b/dlls/win32u/path.c | |
index e0c96f5..6d494a9 100644 | |
--- a/dlls/win32u/path.c | |
+++ b/dlls/win32u/path.c | |
@@ -2120,6 +2120,7 @@ const struct gdi_dc_funcs path_driver = | |
NULL, /* pUnrealizePalette */ | |
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ | |
NULL, /* pD3DKMTCloseAdapter */ | |
+ NULL, /* pD3DKMTEnumAdapters2 */ | |
NULL, /* pD3DKMTOpenAdapterFromLuid */ | |
NULL, /* pD3DKMTQueryVideoMemoryInfo */ | |
NULL, /* pD3DKMTSetVidPnSourceOwner */ | |
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec | |
index 24dccb6..76a60bf 100644 | |
--- a/dlls/win32u/win32u.spec | |
+++ b/dlls/win32u/win32u.spec | |
@@ -223,7 +223,7 @@ | |
@ stub NtGdiDdDDIDispMgrSourceOperation | |
@ stub NtGdiDdDDIDispMgrTargetOperation | |
@ stub NtGdiDdDDIEnumAdapters | |
-@ stub NtGdiDdDDIEnumAdapters2 | |
+@ stdcall -syscall NtGdiDdDDIEnumAdapters2(ptr) | |
@ stdcall -syscall NtGdiDdDDIEscape(ptr) | |
@ stub NtGdiDdDDIEvict | |
@ stub NtGdiDdDDIExtractBundleObject | |
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c | |
index 71e9207..840a4a8 100644 | |
--- a/dlls/winex11.drv/init.c | |
+++ b/dlls/winex11.drv/init.c | |
@@ -415,6 +415,7 @@ static const struct user_driver_funcs x11drv_funcs = | |
.dc_funcs.pUnrealizePalette = X11DRV_UnrealizePalette, | |
.dc_funcs.pD3DKMTCheckVidPnExclusiveOwnership = X11DRV_D3DKMTCheckVidPnExclusiveOwnership, | |
.dc_funcs.pD3DKMTCloseAdapter = X11DRV_D3DKMTCloseAdapter, | |
+ .dc_funcs.pD3DKMTEnumAdapters2 = X11DRV_D3DKMTEnumAdapters2, | |
.dc_funcs.pD3DKMTOpenAdapterFromLuid = X11DRV_D3DKMTOpenAdapterFromLuid, | |
.dc_funcs.pD3DKMTQueryVideoMemoryInfo = X11DRV_D3DKMTQueryVideoMemoryInfo, | |
.dc_funcs.pD3DKMTSetVidPnSourceOwner = X11DRV_D3DKMTSetVidPnSourceOwner, | |
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h | |
index 666bd48..cf49660 100644 | |
--- a/dlls/winex11.drv/x11drv.h | |
+++ b/dlls/winex11.drv/x11drv.h | |
@@ -160,6 +160,7 @@ extern BOOL X11DRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom, | |
INT xstart, INT ystart, INT xend, INT yend ); | |
extern NTSTATUS X11DRV_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *desc ); | |
extern NTSTATUS X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ); | |
+extern NTSTATUS X11DRV_D3DKMTEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ); | |
extern NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ); | |
extern NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ); | |
extern NTSTATUS X11DRV_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc ); | |
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c | |
index c4978d1..e523b85 100644 | |
--- a/dlls/winex11.drv/x11drv_main.c | |
+++ b/dlls/winex11.drv/x11drv_main.c | |
@@ -1241,6 +1241,243 @@ static void release_display_device_init_mutex(HANDLE mutex) | |
NtClose( mutex ); | |
} | |
+/* Find the Vulkan device LUID corresponding to a GUID */ | |
+static BOOL get_vulkan_luid_from_uuid( const GUID *uuid, LUID *luid ) | |
+{ | |
+ static const WCHAR class_guidW[] = {'C','l','a','s','s','G','U','I','D',0}; | |
+ static const WCHAR devpropkey_gpu_vulkan_uuidW[] = | |
+ { | |
+ 'P','r','o','p','e','r','t','i','e','s', | |
+ '\\','{','2','3','3','A','9','E','F','3','-','A','F','C','4','-','4','A','B','D', | |
+ '-','B','5','6','4','-','C','3','2','F','2','1','F','1','5','3','5','C','}', | |
+ '\\','0','0','0','2' | |
+ }; | |
+ static const WCHAR devpropkey_gpu_luidW[] = | |
+ { | |
+ 'P','r','o','p','e','r','t','i','e','s', | |
+ '\\','{','6','0','B','1','9','3','C','B','-','5','2','7','6','-','4','D','0','F', | |
+ '-','9','6','F','C','-','F','1','7','3','A','B','A','D','3','E','C','6','}', | |
+ '\\','0','0','0','2' | |
+ }; | |
+ static const WCHAR guid_devclass_displayW[] = | |
+ {'{','4','D','3','6','E','9','6','8','-','E','3','2','5','-','1','1','C','E','-', | |
+ 'B','F','C','1','-','0','8','0','0','2','B','E','1','0','3','1','8','}',0}; | |
+ static const WCHAR pci_keyW[] = | |
+ { | |
+ '\\','R','e','g','i','s','t','r','y', | |
+ '\\','M','a','c','h','i','n','e', | |
+ '\\','S','y','s','t','e','m', | |
+ '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t', | |
+ '\\','E','n','u','m', | |
+ '\\','P','C','I' | |
+ }; | |
+ char buffer[4096]; | |
+ KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; | |
+ HKEY subkey, device_key, prop_key, pci_key; | |
+ KEY_NODE_INFORMATION *key = (void *)buffer; | |
+ DWORD size, i = 0; | |
+ HANDLE mutex; | |
+ | |
+ mutex = get_display_device_init_mutex(); | |
+ | |
+ pci_key = reg_open_key(NULL, pci_keyW, sizeof(pci_keyW)); | |
+ while (!NtEnumerateKey(pci_key, i++, KeyNodeInformation, key, sizeof(buffer), &size)) | |
+ { | |
+ unsigned int j = 0; | |
+ | |
+ if (!(subkey = reg_open_key(pci_key, key->Name, key->NameLength))) | |
+ continue; | |
+ | |
+ while (!NtEnumerateKey(subkey, j++, KeyNodeInformation, key, sizeof(buffer), &size)) | |
+ { | |
+ if (!(device_key = reg_open_key(subkey, key->Name, key->NameLength))) | |
+ continue; | |
+ | |
+ size = query_reg_value(device_key, class_guidW, value, sizeof(buffer)); | |
+ if (size != sizeof(guid_devclass_displayW) || | |
+ wcscmp((WCHAR *)value->Data, guid_devclass_displayW)) | |
+ { | |
+ NtClose(device_key); | |
+ continue; | |
+ } | |
+ | |
+ if (!(prop_key = reg_open_key(device_key, devpropkey_gpu_vulkan_uuidW, | |
+ sizeof(devpropkey_gpu_vulkan_uuidW)))) | |
+ { | |
+ NtClose(device_key); | |
+ continue; | |
+ } | |
+ | |
+ size = query_reg_value(prop_key, NULL, value, sizeof(buffer)); | |
+ NtClose(prop_key); | |
+ if (size != sizeof(GUID) || memcmp(value->Data, uuid, sizeof(GUID))) | |
+ { | |
+ NtClose(device_key); | |
+ continue; | |
+ } | |
+ | |
+ if (!(prop_key = reg_open_key(device_key, devpropkey_gpu_luidW, | |
+ sizeof(devpropkey_gpu_luidW)))) | |
+ { | |
+ NtClose(device_key); | |
+ continue; | |
+ } | |
+ | |
+ size = query_reg_value(prop_key, NULL, value, sizeof(buffer)); | |
+ NtClose(prop_key); | |
+ if (size != sizeof(LUID)) | |
+ { | |
+ NtClose(device_key); | |
+ continue; | |
+ } | |
+ | |
+ *luid = *(const LUID *)value->Data; | |
+ NtClose(device_key); | |
+ NtClose(subkey); | |
+ NtClose(pci_key); | |
+ release_display_device_init_mutex(mutex); | |
+ return TRUE; | |
+ } | |
+ NtClose(subkey); | |
+ } | |
+ NtClose(pci_key); | |
+ | |
+ release_display_device_init_mutex(mutex); | |
+ return FALSE; | |
+} | |
+ | |
+NTSTATUS X11DRV_D3DKMTEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) | |
+{ | |
+ static const char *extensions[] = | |
+ { | |
+ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, | |
+ VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, | |
+ }; | |
+ const struct vulkan_funcs *vulkan_funcs; | |
+ PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; | |
+ PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices; | |
+ VkPhysicalDevice *vk_physical_devices = NULL; | |
+ VkPhysicalDeviceProperties2 properties2; | |
+ NTSTATUS status = STATUS_UNSUCCESSFUL; | |
+ UINT device_count = 0, device_idx = 0; | |
+ struct x11_d3dkmt_adapter *adapter; | |
+ VkInstanceCreateInfo create_info; | |
+ VkPhysicalDeviceIDProperties id; | |
+ VkResult vr; | |
+ LUID luid; | |
+ | |
+ if (!(vulkan_funcs = get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION))) | |
+ { | |
+ WARN("Vulkan is unavailable.\n"); | |
+ return STATUS_UNSUCCESSFUL; | |
+ } | |
+ | |
+ pthread_mutex_lock(&d3dkmt_mutex); | |
+ | |
+ if (!d3dkmt_vk_instance) | |
+ { | |
+ memset(&create_info, 0, sizeof(create_info)); | |
+ create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; | |
+ create_info.enabledExtensionCount = ARRAY_SIZE(extensions); | |
+ create_info.ppEnabledExtensionNames = extensions; | |
+ | |
+ vr = vulkan_funcs->p_vkCreateInstance(&create_info, NULL, &d3dkmt_vk_instance); | |
+ if (vr != VK_SUCCESS) | |
+ { | |
+ WARN("Failed to create a Vulkan instance, vr %d.\n", vr); | |
+ goto done; | |
+ } | |
+ } | |
+ | |
+#define LOAD_VK_FUNC(f) \ | |
+ if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(d3dkmt_vk_instance, #f))) \ | |
+ { \ | |
+ WARN("Failed to load " #f ".\n"); \ | |
+ goto done; \ | |
+ } | |
+ | |
+ LOAD_VK_FUNC(vkEnumeratePhysicalDevices) | |
+ LOAD_VK_FUNC(vkGetPhysicalDeviceProperties2KHR) | |
+#undef LOAD_VK_FUNC | |
+ | |
+ vr = pvkEnumeratePhysicalDevices(d3dkmt_vk_instance, &device_count, NULL); | |
+ if (vr != VK_SUCCESS || !device_count) | |
+ { | |
+ WARN("No Vulkan device found, vr %d, device_count %d.\n", vr, device_count); | |
+ goto done; | |
+ } | |
+ | |
+ if (!desc->pAdapters) | |
+ { | |
+ status = STATUS_SUCCESS; | |
+ goto done; | |
+ } | |
+ else if (desc->NumAdapters < device_count) | |
+ { | |
+ status = STATUS_BUFFER_TOO_SMALL; | |
+ goto done; | |
+ } | |
+ | |
+ if (!(vk_physical_devices = calloc(device_count, sizeof(*vk_physical_devices)))) | |
+ { | |
+ status = STATUS_NO_MEMORY; | |
+ goto done; | |
+ } | |
+ | |
+ vr = pvkEnumeratePhysicalDevices(d3dkmt_vk_instance, &device_count, vk_physical_devices); | |
+ if (vr != VK_SUCCESS) | |
+ { | |
+ WARN("vkEnumeratePhysicalDevices failed, vr %d.\n", vr); | |
+ goto done; | |
+ } | |
+ | |
+ for (device_idx = 0; device_idx < device_count; ++device_idx) | |
+ { | |
+ memset(&id, 0, sizeof(id)); | |
+ id.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; | |
+ properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; | |
+ properties2.pNext = &id; | |
+ | |
+ pvkGetPhysicalDeviceProperties2KHR(vk_physical_devices[device_idx], &properties2); | |
+ | |
+ if (!(adapter = malloc(sizeof(*adapter)))) | |
+ { | |
+ status = STATUS_NO_MEMORY; | |
+ goto done; | |
+ } | |
+ | |
+ adapter->handle = desc->pAdapters[device_idx].hAdapter; | |
+ adapter->vk_device = vk_physical_devices[device_idx]; | |
+ list_add_tail(&x11_d3dkmt_adapters, &adapter->entry); | |
+ | |
+ if (get_vulkan_luid_from_uuid((const GUID *)id.deviceUUID, &luid)) | |
+ { | |
+ memcpy(&desc->pAdapters[device_idx].AdapterLuid, &luid, sizeof(LUID)); | |
+ } | |
+ else | |
+ { | |
+ WARN("get_vulkan_luid_from_uuid failed, AdapterLuid will remain empty.\n"); | |
+ memset(&desc->pAdapters[device_idx].AdapterLuid, 0, sizeof(LUID)); | |
+ } | |
+ | |
+ desc->pAdapters[device_idx].NumOfSources = 1; | |
+ desc->pAdapters[device_idx].bPrecisePresentRegionsPreferred = FALSE; | |
+ } | |
+ | |
+ status = STATUS_SUCCESS; | |
+ | |
+done: | |
+ desc->NumAdapters = device_count; | |
+ if (d3dkmt_vk_instance && list_empty(&x11_d3dkmt_adapters)) | |
+ { | |
+ vulkan_funcs->p_vkDestroyInstance(d3dkmt_vk_instance, NULL); | |
+ d3dkmt_vk_instance = NULL; | |
+ } | |
+ pthread_mutex_unlock(&d3dkmt_mutex); | |
+ free(vk_physical_devices); | |
+ return status; | |
+} | |
+ | |
/* Find the Vulkan device UUID corresponding to a LUID */ | |
static BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ) | |
{ | |
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c | |
index 7472391..7e605f9 100644 | |
--- a/dlls/winex11.drv/xrender.c | |
+++ b/dlls/winex11.drv/xrender.c | |
@@ -2236,6 +2236,7 @@ static const struct gdi_dc_funcs xrender_funcs = | |
NULL, /* pUnrealizePalette */ | |
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ | |
NULL, /* pD3DKMTCloseAdapter */ | |
+ NULL, /* pD3DKMTEnumAdapters2 */ | |
NULL, /* pD3DKMTOpenAdapterFromLuid */ | |
NULL, /* pD3DKMTQueryVideoMemoryInfo */ | |
NULL, /* pD3DKMTSetVidPnSourceOwner */ | |
diff --git a/dlls/wow64win/gdi.c b/dlls/wow64win/gdi.c | |
index 36af173..993580c 100644 | |
--- a/dlls/wow64win/gdi.c | |
+++ b/dlls/wow64win/gdi.c | |
@@ -507,6 +507,28 @@ NTSTATUS WINAPI wow64_NtGdiDdDDIDestroyDevice( UINT *args ) | |
return NtGdiDdDDIDestroyDevice( desc ); | |
} | |
+NTSTATUS WINAPI wow64_NtGdiDdDDIEnumAdapters2( UINT *args ) | |
+{ | |
+ struct | |
+ { | |
+ ULONG NumAdapters; | |
+ ULONG pAdapters; | |
+ } *desc32 = get_ptr( &args ); | |
+ D3DKMT_ENUMADAPTERS2 desc; | |
+ NTSTATUS status; | |
+ | |
+ if (!desc32) return STATUS_INVALID_PARAMETER; | |
+ | |
+ desc.NumAdapters = desc32->NumAdapters; | |
+ desc.pAdapters = UlongToPtr( desc32->pAdapters ); | |
+ | |
+ status = NtGdiDdDDIEnumAdapters2( &desc ); | |
+ | |
+ desc32->NumAdapters = desc.NumAdapters; | |
+ | |
+ return status; | |
+} | |
+ | |
NTSTATUS WINAPI wow64_NtGdiDdDDIEscape( UINT *args ) | |
{ | |
const struct | |
diff --git a/include/ddk/d3dkmthk.h b/include/ddk/d3dkmthk.h | |
index 2d30bdd..918a4ad 100644 | |
--- a/include/ddk/d3dkmthk.h | |
+++ b/include/ddk/d3dkmthk.h | |
@@ -785,6 +785,7 @@ NTSTATUS WINAPI D3DKMTCreateDCFromMemory(D3DKMT_CREATEDCFROMMEMORY *desc); | |
NTSTATUS WINAPI D3DKMTDestroyDCFromMemory(const D3DKMT_DESTROYDCFROMMEMORY *desc); | |
NTSTATUS WINAPI D3DKMTDestroyDevice(const D3DKMT_DESTROYDEVICE *desc); | |
NTSTATUS WINAPI D3DKMTEscape( const D3DKMT_ESCAPE *desc ); | |
+NTSTATUS WINAPI D3DKMTEnumAdapters2(D3DKMT_ENUMADAPTERS2 *desc); | |
NTSTATUS WINAPI D3DKMTOpenAdapterFromGdiDisplayName(D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *desc); | |
NTSTATUS WINAPI D3DKMTOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC *desc ); | |
NTSTATUS WINAPI D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID * desc ); | |
diff --git a/include/ntgdi.h b/include/ntgdi.h | |
index c2cb192..5097353 100644 | |
--- a/include/ntgdi.h | |
+++ b/include/ntgdi.h | |
@@ -481,6 +481,7 @@ W32KAPI NTSTATUS WINAPI NtGdiDdDDICreateDCFromMemory( D3DKMT_CREATEDCFROMMEMORY | |
W32KAPI NTSTATUS WINAPI NtGdiDdDDICreateDevice( D3DKMT_CREATEDEVICE *desc ); | |
W32KAPI NTSTATUS WINAPI NtGdiDdDDIDestroyDCFromMemory( const D3DKMT_DESTROYDCFROMMEMORY *desc ); | |
W32KAPI NTSTATUS WINAPI NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE *desc ); | |
+W32KAPI NTSTATUS WINAPI NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ); | |
W32KAPI NTSTATUS WINAPI NtGdiDdDDIEscape( const D3DKMT_ESCAPE *desc ); | |
W32KAPI NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC *desc ); | |
W32KAPI NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVICENAME *desc ); | |
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h | |
index 5689e8c..0c3c919 100644 | |
--- a/include/wine/gdi_driver.h | |
+++ b/include/wine/gdi_driver.h | |
@@ -168,6 +168,7 @@ struct gdi_dc_funcs | |
BOOL (*pUnrealizePalette)(HPALETTE); | |
NTSTATUS (*pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *); | |
NTSTATUS (*pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *); | |
+ NTSTATUS (*pD3DKMTEnumAdapters2)(D3DKMT_ENUMADAPTERS2 *); | |
NTSTATUS (*pD3DKMTOpenAdapterFromLuid)(D3DKMT_OPENADAPTERFROMLUID *); | |
NTSTATUS (*pD3DKMTQueryVideoMemoryInfo)(D3DKMT_QUERYVIDEOMEMORYINFO *); | |
NTSTATUS (*pD3DKMTSetVidPnSourceOwner)(const D3DKMT_SETVIDPNSOURCEOWNER *); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 078cdc32a3c1c7cf95f213159d4a97b98b04789b | |
Author: Krzysztof Bogacki <krzysztof.bogacki@leancode.pl> | |
Date: Tue Dec 19 23:57:14 2023 +0100 | |
win32u: Allow faking HAGS in QueryAdapterInfo. | |
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c | |
index 3f7b9e4..2bc7c37 100644 | |
--- a/dlls/win32u/driver.c | |
+++ b/dlls/win32u/driver.c | |
@@ -1691,16 +1691,49 @@ NTSTATUS WINAPI NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE *desc ) | |
return status; | |
} | |
+static BOOL check_hags_enabled( void ) | |
+{ | |
+ const char *winehags = getenv( "WINEHAGS" ); | |
+ return winehags && *winehags != '0'; | |
+} | |
+ | |
/****************************************************************************** | |
* NtGdiDdDDIQueryAdapterInfo (win32u.@) | |
*/ | |
NTSTATUS WINAPI NtGdiDdDDIQueryAdapterInfo( D3DKMT_QUERYADAPTERINFO *desc ) | |
{ | |
+ D3DKMT_WDDM_2_7_CAPS *d3dkmt_wddm_2_7_caps; | |
+ | |
if (!desc) | |
return STATUS_INVALID_PARAMETER; | |
- FIXME("desc %p, type %d stub\n", desc, desc->Type); | |
- return STATUS_NOT_IMPLEMENTED; | |
+ TRACE("desc %p, type %d\n", desc, desc->Type); | |
+ | |
+ switch (desc->Type) | |
+ { | |
+ case KMTQAITYPE_WDDM_2_7_CAPS: | |
+ if (!desc->pPrivateDriverData || desc->PrivateDriverDataSize != sizeof(D3DKMT_WDDM_2_7_CAPS)) | |
+ return STATUS_INVALID_PARAMETER; | |
+ | |
+ d3dkmt_wddm_2_7_caps = desc->pPrivateDriverData; | |
+ d3dkmt_wddm_2_7_caps->HwSchSupported = 1; | |
+ d3dkmt_wddm_2_7_caps->HwSchEnabled = 0; | |
+ d3dkmt_wddm_2_7_caps->HwSchEnabledByDefault = 0; | |
+ d3dkmt_wddm_2_7_caps->IndependentVidPnVSyncControl = 0; | |
+ | |
+ if (check_hags_enabled()) | |
+ { | |
+ d3dkmt_wddm_2_7_caps->HwSchEnabled = 1; | |
+ d3dkmt_wddm_2_7_caps->HwSchEnabledByDefault = 1; | |
+ } | |
+ break; | |
+ | |
+ default: | |
+ FIXME("type %d not supported\n", desc->Type); | |
+ return STATUS_NOT_IMPLEMENTED; | |
+ } | |
+ | |
+ return STATUS_SUCCESS; | |
} | |
/****************************************************************************** | |
diff --git a/include/ddk/d3dkmthk.h b/include/ddk/d3dkmthk.h | |
index 918a4ad..4b2c5a7 100644 | |
--- a/include/ddk/d3dkmthk.h | |
+++ b/include/ddk/d3dkmthk.h | |
@@ -773,6 +773,22 @@ typedef struct _D3DKMT_ENUMADAPTERS2 | |
D3DKMT_ADAPTERINFO *pAdapters; | |
} D3DKMT_ENUMADAPTERS2; | |
+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; | |
+ | |
#ifdef __cplusplus | |
extern "C" | |
{ |
@oscarbg Does my diff from ValveSoftware/Proton#7361 (comment) not apply anymore?
it's the same patch!.. wasn't aware of it.. I redid the same work as you!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
correct 002 patch for 9.5+: