Linux'ta NVIDIA Frame Gen açamıyorum

RTX 4060 ile beraber Witcher 3’te FG açamıyorum. Nasıl açacağımı bilen var mı?

Ayrıca bazı araştırmalarım sonucun Wine/Proton/Staging 9.0.5+ patchlemem gerekiyormuş. Tam olarak nasıl patchleyeceğim?

diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec
index 44783e3600a..69ad9b2d60a 100644
--- a/dlls/gdi32/gdi32.spec
+++ b/dlls/gdi32/gdi32.spec
@@ -79,7 +79,7 @@
 @ stdcall D3DKMTCreateDevice(ptr) win32u.NtGdiDdDDICreateDevice
 @ stdcall D3DKMTDestroyDCFromMemory(ptr) win32u.NtGdiDdDDIDestroyDCFromMemory
 @ stdcall D3DKMTDestroyDevice(ptr) win32u.NtGdiDdDDIDestroyDevice
-@ stdcall D3DKMTEnumAdapters2(ptr)
+@ stdcall D3DKMTEnumAdapters2(ptr) win32u.NtGdiDdDDIEnumAdapters2
 @ stdcall D3DKMTEscape(ptr) win32u.NtGdiDdDDIEscape
 @ stdcall D3DKMTOpenAdapterFromDeviceName(ptr) win32u.NtGdiDdDDIOpenAdapterFromDeviceName
 @ stdcall D3DKMTOpenAdapterFromGdiDisplayName(ptr)
diff --git a/dlls/gdi32/objects.c b/dlls/gdi32/objects.c
index bddc29a3007..070ce9c3885 100644
--- a/dlls/gdi32/objects.c
+++ b/dlls/gdi32/objects.c
@@ -971,12 +971,6 @@ done:
 return status;
 }

-NTSTATUS WINAPI D3DKMTEnumAdapters2( const void *param )
-{
[LIST]
[*]FIXME( "param %p stub.\n", param );
[*]return STATUS_NOT_SUPPORTED;
[/LIST]
-}
-
 /***********************************************************************
 * SetObjectOwner (GDI32.@)
 */
diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c
index 7fe4b765a78..0a4b0ac3da0 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 bc3409a9e34..3ceb61ef820 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 */
@@ -1513,6 +1520,46 @@ NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc )
 return status;
 }

+/******************************************************************************
[LIST]
[*]* NtGdiDdDDIEnumAdapters2 (win32u.@)
[*]*/
[/LIST]
+NTSTATUS WINAPI NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc )
+{
[LIST]
[*]NTSTATUS status = STATUS_UNSUCCESSFUL;
[*]struct d3dkmt_adapter *adapter;
[*]ULONG i;
[/LIST]
+
+ TRACE("(%p)\n", desc);
+
+ if (!desc) return STATUS_INVALID_PARAMETER;
+
[LIST]
[*]if (get_display_driver()->pD3DKMTEnumAdapters2)
[*]{
[*]if (desc->pAdapters)
[*]{
[*]pthread_mutex_lock( &driver_lock );
[/LIST]
+
[LIST]
[*]for (i = 0; i < desc->NumAdapters; ++i)
[*]{
[*]if (!(adapter = malloc( sizeof( *adapter ) )))
[*]{
[*]pthread_mutex_unlock( &driver_lock );
[*]return STATUS_NO_MEMORY;
[*]}
[/LIST]
+
[LIST]
[*]desc->pAdapters[i].hAdapter = adapter->handle = ++handle_start;
[*]list_add_tail( &d3dkmt_adapters, &adapter->entry );
[*]}
[/LIST]
+
[LIST]
[*]pthread_mutex_unlock( &driver_lock );
[*]}
[/LIST]
+
[LIST]
[*]status = get_display_driver()->pD3DKMTEnumAdapters2( desc );
[*]}
[/LIST]
+
+ return status;
+}
+
 /******************************************************************************
 * NtGdiDdDDIOpenAdapterFromDeviceName (win32u.@)
 */
@@ -1538,7 +1585,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;
@@ -1632,16 +1678,43 @@ NTSTATUS WINAPI NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE *desc )
 return status;
 }

+static BOOL check_hags_enabled( void )
+{
[LIST]
[*]const char *winehags = getenv( "WINEHAGS" );
[*]return winehags && *winehags && *winehags != '0';
[/LIST]
+}
+
 /******************************************************************************
 * NtGdiDdDDIQueryAdapterInfo (win32u.@)
 */
 NTSTATUS WINAPI NtGdiDdDDIQueryAdapterInfo( D3DKMT_QUERYADAPTERINFO *desc )
 {
+ D3DKMT_WDDM_2_7_CAPS *d3dkmt_wddm_2_7_caps;
+
 if (!desc)
 return STATUS_INVALID_PARAMETER;

[LIST]
[*]FIXME("desc %p, type %d stub\n", desc, desc->Type);
[*]return STATUS_NOT_IMPLEMENTED;
[/LIST]
+ TRACE("desc %p, type %d\n", desc, desc->Type);
+
[LIST]
[*]switch (desc->Type)
[*]{
[*]case KMTQAITYPE_WDDM_2_7_CAPS:
[*]if (!desc->pPrivateDriverData || desc->PrivateDriverDataSize != sizeof(D3DKMT_WDDM_2_7_CAPS))
[*]return STATUS_INVALID_PARAMETER;
[/LIST]
+
[LIST]
[*]d3dkmt_wddm_2_7_caps = desc->pPrivateDriverData;
[*]d3dkmt_wddm_2_7_caps->HwSchSupported = 1;
[*]d3dkmt_wddm_2_7_caps->HwSchEnabled = check_hags_enabled() ? 1 : 0;
[*]d3dkmt_wddm_2_7_caps->HwSchEnabledByDefault = 0;
[*]d3dkmt_wddm_2_7_caps->IndependentVidPnVSyncControl = 0;
[*]break;
[/LIST]
+
[LIST]
[*]default:
[*]FIXME("type %d not supported\n", desc->Type);
[*]return STATUS_NOT_IMPLEMENTED;
[*]}
[/LIST]
+
+ return STATUS_SUCCESS;
 }

 /******************************************************************************
diff --git a/dlls/win32u/emfdrv.c b/dlls/win32u/emfdrv.c
index 069ad9d1297..9c07f9ef341 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 08060e0a9b7..4d8a1d18400 100644
--- a/dlls/win32u/font.c
+++ b/dlls/win32u/font.c
@@ -4794,6 +4794,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 ea3578407a1..54c7693069e 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 e0c96f5ef6f..6d494a92233 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 e5586fd67a6..d9050cee8a6 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 5576fdd50e6..998f704b390 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -388,6 +388,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 2868325055b..26c45b79ff4 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -162,6 +162,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 5f6f0773d92..405d7cbeb00 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -1179,6 +1179,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 )
+{
[LIST]
[*]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;
[/LIST]
+
+ mutex = get_display_device_init_mutex();
+
[LIST]
[*]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;
[/LIST]
+
[LIST]
[*]if (!(subkey = reg_open_key(pci_key, key->Name, key->NameLength)))
[*]continue;
[/LIST]
+
[LIST]
[*]while (!NtEnumerateKey(subkey, j++, KeyNodeInformation, key, sizeof(buffer), &size))
[*]{
[*]if (!(device_key = reg_open_key(subkey, key->Name, key->NameLength)))
[*]continue;
[/LIST]
+
[LIST]
[*]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;
[*]}
[/LIST]
+
[LIST]
[*]if (!(prop_key = reg_open_key(device_key, devpropkey_gpu_vulkan_uuidW,
[*]sizeof(devpropkey_gpu_vulkan_uuidW))))
[*]{
[*]NtClose(device_key);
[*]continue;
[*]}
[/LIST]
+
[LIST]
[*]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;
[*]}
[/LIST]
+
[LIST]
[*]if (!(prop_key = reg_open_key(device_key, devpropkey_gpu_luidW,
[*]sizeof(devpropkey_gpu_luidW))))
[*]{
[*]NtClose(device_key);
[*]continue;
[*]}
[/LIST]
+
[LIST]
[*]size = query_reg_value(prop_key, NULL, value, sizeof(buffer));
[*]NtClose(prop_key);
[*]if (size != sizeof(LUID))
[*]{
[*]NtClose(device_key);
[*]continue;
[*]}
[/LIST]
+
[LIST]
[*]*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);
[/LIST]
+
[LIST]
[*]release_display_device_init_mutex(mutex);
[*]return FALSE;
[/LIST]
+}
+
+NTSTATUS X11DRV_D3DKMTEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc )
+{
[LIST]
[*]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;
[/LIST]
+
[LIST]
[*]if (!(vulkan_funcs = get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION)))
[*]{
[*]WARN("Vulkan is unavailable.\n");
[*]return STATUS_UNSUCCESSFUL;
[*]}
[/LIST]
+
+ pthread_mutex_lock(&d3dkmt_mutex);
+
[LIST]
[*]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;
[/LIST]
+
[LIST]
[*]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;
[*]}
[*]}
[/LIST]
+
+#define LOAD_VK_FUNC(f) \
[LIST]
[*]if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(d3dkmt_vk_instance, #f))) \
[*]{ \
[*]WARN("Failed to load " #f ".\n"); \
[*]goto done; \
[*]}
[/LIST]
+
[LIST]
[*]LOAD_VK_FUNC(vkEnumeratePhysicalDevices)
[*]LOAD_VK_FUNC(vkGetPhysicalDeviceProperties2KHR)
[/LIST]
+#undef LOAD_VK_FUNC
+
[LIST]
[*]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;
[*]}
[/LIST]
+
[LIST]
[*]if (!desc->pAdapters)
[*]{
[*]status = STATUS_SUCCESS;
[*]goto done;
[*]}
[*]else if (desc->NumAdapters < device_count)
[*]{
[*]status = STATUS_BUFFER_TOO_SMALL;
[*]goto done;
[*]}
[/LIST]
+
[LIST]
[*]if (!(vk_physical_devices = calloc(device_count, sizeof(*vk_physical_devices))))
[*]{
[*]status = STATUS_NO_MEMORY;
[*]goto done;
[*]}
[/LIST]
+
[LIST]
[*]vr = pvkEnumeratePhysicalDevices(d3dkmt_vk_instance, &device_count, vk_physical_devices);
[*]if (vr != VK_SUCCESS)
[*]{
[*]WARN("vkEnumeratePhysicalDevices failed, vr %d.\n", vr);
[*]goto done;
[*]}
[/LIST]
+
[LIST]
[*]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;
[/LIST]
+
+ pvkGetPhysicalDeviceProperties2KHR(vk_physical_devices[device_idx], &properties2);
+
[LIST]
[*]if (!(adapter = malloc(sizeof(*adapter))))
[*]{
[*]status = STATUS_NO_MEMORY;
[*]goto done;
[*]}
[/LIST]
+
[LIST]
[*]adapter->handle = desc->pAdapters[device_idx].hAdapter;
[*]adapter->vk_device = vk_physical_devices[device_idx];
[*]list_add_tail(&x11_d3dkmt_adapters, &adapter->entry);
[/LIST]
+
[LIST]
[*]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));
[*]}
[/LIST]
+
[LIST]
[*]desc->pAdapters[device_idx].NumOfSources = 1;
[*]desc->pAdapters[device_idx].bPrecisePresentRegionsPreferred = FALSE;
[*]}
[/LIST]
+
+ status = STATUS_SUCCESS;
+
+done:
[LIST]
[*]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;
[/LIST]
+}
+
 /* 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 9180827143d..36d23066452 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -2439,6 +2439,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 36af173405c..993580c32c3 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 )
+{
[LIST]
[*]struct
[*]{
[*]ULONG NumAdapters;
[*]ULONG pAdapters;
[*]} *desc32 = get_ptr( &args );
[*]D3DKMT_ENUMADAPTERS2 desc;
[*]NTSTATUS status;
[/LIST]
+
+ if (!desc32) return STATUS_INVALID_PARAMETER;
+
[LIST]
[*]desc.NumAdapters = desc32->NumAdapters;
[*]desc.pAdapters = UlongToPtr( desc32->pAdapters );
[/LIST]
+
+ 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 2d30bdd8777..4b2c5a7f5a3 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
+{
[LIST]
[*]union
[*]{
[*]struct
[*]{
[*]UINT HwSchSupported : 1;
[*]UINT HwSchEnabled : 1;
[*]UINT HwSchEnabledByDefault : 1;
[*]UINT IndependentVidPnVSyncControl : 1;
[*]UINT Reserved : 28;
[*]};
[*]UINT Value;
[*]};
[/LIST]
+} D3DKMT_WDDM_2_7_CAPS;
+
 #ifdef __cplusplus
 extern "C"
 {
@@ -785,6 +801,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 c2cb1924730..50973535c7a 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 26562bfef2b..ba37098f7ad 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 *);

Son düzenleyen: @wise 2024-09-19T01:55:22Z

DLSS 3 açmak için Wine’ı patchlemem lazım ancak yapamıyorum.

diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec
index 44783e3600a..69ad9b2d60a 100644
--- a/dlls/gdi32/gdi32.spec
+++ b/dlls/gdi32/gdi32.spec
@@ -79,7 +79,7 @@
 @ stdcall D3DKMTCreateDevice(ptr) win32u.NtGdiDdDDICreateDevice
 @ stdcall D3DKMTDestroyDCFromMemory(ptr) win32u.NtGdiDdDDIDestroyDCFromMemory
 @ stdcall D3DKMTDestroyDevice(ptr) win32u.NtGdiDdDDIDestroyDevice
-@ stdcall D3DKMTEnumAdapters2(ptr)
+@ stdcall D3DKMTEnumAdapters2(ptr) win32u.NtGdiDdDDIEnumAdapters2
 @ stdcall D3DKMTEscape(ptr) win32u.NtGdiDdDDIEscape
 @ stdcall D3DKMTOpenAdapterFromDeviceName(ptr) win32u.NtGdiDdDDIOpenAdapterFromDeviceName
 @ stdcall D3DKMTOpenAdapterFromGdiDisplayName(ptr)
diff --git a/dlls/gdi32/objects.c b/dlls/gdi32/objects.c
index bddc29a3007..070ce9c3885 100644
--- a/dlls/gdi32/objects.c
+++ b/dlls/gdi32/objects.c
@@ -971,12 +971,6 @@ done:
 return status;
 }

-NTSTATUS WINAPI D3DKMTEnumAdapters2( const void *param )
-{
[LIST]
[*]FIXME( "param %p stub.\n", param );
[*]return STATUS_NOT_SUPPORTED;
[/LIST]
-}
-
 /***********************************************************************
 * SetObjectOwner (GDI32.@)
 */
diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c
index 7fe4b765a78..0a4b0ac3da0 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 bc3409a9e34..3ceb61ef820 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 */
@@ -1513,6 +1520,46 @@ NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc )
 return status;
 }

+/******************************************************************************
[LIST]
[*]* NtGdiDdDDIEnumAdapters2 (win32u.@)
[*]*/
[/LIST]
+NTSTATUS WINAPI NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc )
+{
[LIST]
[*]NTSTATUS status = STATUS_UNSUCCESSFUL;
[*]struct d3dkmt_adapter *adapter;
[*]ULONG i;
[/LIST]
+
+ TRACE("(%p)\n", desc);
+
+ if (!desc) return STATUS_INVALID_PARAMETER;
+
[LIST]
[*]if (get_display_driver()->pD3DKMTEnumAdapters2)
[*]{
[*]if (desc->pAdapters)
[*]{
[*]pthread_mutex_lock( &driver_lock );
[/LIST]
+
[LIST]
[*]for (i = 0; i < desc->NumAdapters; ++i)
[*]{
[*]if (!(adapter = malloc( sizeof( *adapter ) )))
[*]{
[*]pthread_mutex_unlock( &driver_lock );
[*]return STATUS_NO_MEMORY;
[*]}
[/LIST]
+
[LIST]
[*]desc->pAdapters[i].hAdapter = adapter->handle = ++handle_start;
[*]list_add_tail( &d3dkmt_adapters, &adapter->entry );
[*]}
[/LIST]
+
[LIST]
[*]pthread_mutex_unlock( &driver_lock );
[*]}
[/LIST]
+
[LIST]
[*]status = get_display_driver()->pD3DKMTEnumAdapters2( desc );
[*]}
[/LIST]
+
+ return status;
+}
+
 /******************************************************************************
 * NtGdiDdDDIOpenAdapterFromDeviceName (win32u.@)
 */
@@ -1538,7 +1585,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;
@@ -1632,16 +1678,43 @@ NTSTATUS WINAPI NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE *desc )
 return status;
 }

+static BOOL check_hags_enabled( void )
+{
[LIST]
[*]const char *winehags = getenv( "WINEHAGS" );
[*]return winehags && *winehags && *winehags != '0';
[/LIST]
+}
+
 /******************************************************************************
 * NtGdiDdDDIQueryAdapterInfo (win32u.@)
 */
 NTSTATUS WINAPI NtGdiDdDDIQueryAdapterInfo( D3DKMT_QUERYADAPTERINFO *desc )
 {
+ D3DKMT_WDDM_2_7_CAPS *d3dkmt_wddm_2_7_caps;
+
 if (!desc)
 return STATUS_INVALID_PARAMETER;

[LIST]
[*]FIXME("desc %p, type %d stub\n", desc, desc->Type);
[*]return STATUS_NOT_IMPLEMENTED;
[/LIST]
+ TRACE("desc %p, type %d\n", desc, desc->Type);
+
[LIST]
[*]switch (desc->Type)
[*]{
[*]case KMTQAITYPE_WDDM_2_7_CAPS:
[*]if (!desc->pPrivateDriverData || desc->PrivateDriverDataSize != sizeof(D3DKMT_WDDM_2_7_CAPS))
[*]return STATUS_INVALID_PARAMETER;
[/LIST]
+
[LIST]
[*]d3dkmt_wddm_2_7_caps = desc->pPrivateDriverData;
[*]d3dkmt_wddm_2_7_caps->HwSchSupported = 1;
[*]d3dkmt_wddm_2_7_caps->HwSchEnabled = check_hags_enabled() ? 1 : 0;
[*]d3dkmt_wddm_2_7_caps->HwSchEnabledByDefault = 0;
[*]d3dkmt_wddm_2_7_caps->IndependentVidPnVSyncControl = 0;
[*]break;
[/LIST]
+
[LIST]
[*]default:
[*]FIXME("type %d not supported\n", desc->Type);
[*]return STATUS_NOT_IMPLEMENTED;
[*]}
[/LIST]
+
+ return STATUS_SUCCESS;
 }

 /******************************************************************************
diff --git a/dlls/win32u/emfdrv.c b/dlls/win32u/emfdrv.c
index 069ad9d1297..9c07f9ef341 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 08060e0a9b7..4d8a1d18400 100644
--- a/dlls/win32u/font.c
+++ b/dlls/win32u/font.c
@@ -4794,6 +4794,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 ea3578407a1..54c7693069e 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 e0c96f5ef6f..6d494a92233 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 e5586fd67a6..d9050cee8a6 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 5576fdd50e6..998f704b390 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -388,6 +388,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 2868325055b..26c45b79ff4 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -162,6 +162,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 5f6f0773d92..405d7cbeb00 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -1179,6 +1179,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 )
+{
[LIST]
[*]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;
[/LIST]
+
+ mutex = get_display_device_init_mutex();
+
[LIST]
[*]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;
[/LIST]
+
[LIST]
[*]if (!(subkey = reg_open_key(pci_key, key->Name, key->NameLength)))
[*]continue;
[/LIST]
+
[LIST]
[*]while (!NtEnumerateKey(subkey, j++, KeyNodeInformation, key, sizeof(buffer), &size))
[*]{
[*]if (!(device_key = reg_open_key(subkey, key->Name, key->NameLength)))
[*]continue;
[/LIST]
+
[LIST]
[*]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;
[*]}
[/LIST]
+
[LIST]
[*]if (!(prop_key = reg_open_key(device_key, devpropkey_gpu_vulkan_uuidW,
[*]sizeof(devpropkey_gpu_vulkan_uuidW))))
[*]{
[*]NtClose(device_key);
[*]continue;
[*]}
[/LIST]
+
[LIST]
[*]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;
[*]}
[/LIST]
+
[LIST]
[*]if (!(prop_key = reg_open_key(device_key, devpropkey_gpu_luidW,
[*]sizeof(devpropkey_gpu_luidW))))
[*]{
[*]NtClose(device_key);
[*]continue;
[*]}
[/LIST]
+
[LIST]
[*]size = query_reg_value(prop_key, NULL, value, sizeof(buffer));
[*]NtClose(prop_key);
[*]if (size != sizeof(LUID))
[*]{
[*]NtClose(device_key);
[*]continue;
[*]}
[/LIST]
+
[LIST]
[*]*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);
[/LIST]
+
[LIST]
[*]release_display_device_init_mutex(mutex);
[*]return FALSE;
[/LIST]
+}
+
+NTSTATUS X11DRV_D3DKMTEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc )
+{
[LIST]
[*]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;
[/LIST]
+
[LIST]
[*]if (!(vulkan_funcs = get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION)))
[*]{
[*]WARN("Vulkan is unavailable.\n");
[*]return STATUS_UNSUCCESSFUL;
[*]}
[/LIST]
+
+ pthread_mutex_lock(&d3dkmt_mutex);
+
[LIST]
[*]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;
[/LIST]
+
[LIST]
[*]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;
[*]}
[*]}
[/LIST]
+
+#define LOAD_VK_FUNC(f) \
[LIST]
[*]if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(d3dkmt_vk_instance, #f))) \
[*]{ \
[*]WARN("Failed to load " #f ".\n"); \
[*]goto done; \
[*]}
[/LIST]
+
[LIST]
[*]LOAD_VK_FUNC(vkEnumeratePhysicalDevices)
[*]LOAD_VK_FUNC(vkGetPhysicalDeviceProperties2KHR)
[/LIST]
+#undef LOAD_VK_FUNC
+
[LIST]
[*]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;
[*]}
[/LIST]
+
[LIST]
[*]if (!desc->pAdapters)
[*]{
[*]status = STATUS_SUCCESS;
[*]goto done;
[*]}
[*]else if (desc->NumAdapters < device_count)
[*]{
[*]status = STATUS_BUFFER_TOO_SMALL;
[*]goto done;
[*]}
[/LIST]
+
[LIST]
[*]if (!(vk_physical_devices = calloc(device_count, sizeof(*vk_physical_devices))))
[*]{
[*]status = STATUS_NO_MEMORY;
[*]goto done;
[*]}
[/LIST]
+
[LIST]
[*]vr = pvkEnumeratePhysicalDevices(d3dkmt_vk_instance, &device_count, vk_physical_devices);
[*]if (vr != VK_SUCCESS)
[*]{
[*]WARN("vkEnumeratePhysicalDevices failed, vr %d.\n", vr);
[*]goto done;
[*]}
[/LIST]
+
[LIST]
[*]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;
[/LIST]
+
+ pvkGetPhysicalDeviceProperties2KHR(vk_physical_devices[device_idx], &properties2);
+
[LIST]
[*]if (!(adapter = malloc(sizeof(*adapter))))
[*]{
[*]status = STATUS_NO_MEMORY;
[*]goto done;
[*]}
[/LIST]
+
[LIST]
[*]adapter->handle = desc->pAdapters[device_idx].hAdapter;
[*]adapter->vk_device = vk_physical_devices[device_idx];
[*]list_add_tail(&x11_d3dkmt_adapters, &adapter->entry);
[/LIST]
+
[LIST]
[*]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));
[*]}
[/LIST]
+
[LIST]
[*]desc->pAdapters[device_idx].NumOfSources = 1;
[*]desc->pAdapters[device_idx].bPrecisePresentRegionsPreferred = FALSE;
[*]}
[/LIST]
+
+ status = STATUS_SUCCESS;
+
+done:
[LIST]
[*]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;
[/LIST]
+}
+
 /* 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 9180827143d..36d23066452 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -2439,6 +2439,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 36af173405c..993580c32c3 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 )
+{
[LIST]
[*]struct
[*]{
[*]ULONG NumAdapters;
[*]ULONG pAdapters;
[*]} *desc32 = get_ptr( &args );
[*]D3DKMT_ENUMADAPTERS2 desc;
[*]NTSTATUS status;
[/LIST]
+
+ if (!desc32) return STATUS_INVALID_PARAMETER;
+
[LIST]
[*]desc.NumAdapters = desc32->NumAdapters;
[*]desc.pAdapters = UlongToPtr( desc32->pAdapters );
[/LIST]
+
+ 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 2d30bdd8777..4b2c5a7f5a3 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
+{
[LIST]
[*]union
[*]{
[*]struct
[*]{
[*]UINT HwSchSupported : 1;
[*]UINT HwSchEnabled : 1;
[*]UINT HwSchEnabledByDefault : 1;
[*]UINT IndependentVidPnVSyncControl : 1;
[*]UINT Reserved : 28;
[*]};
[*]UINT Value;
[*]};
[/LIST]
+} D3DKMT_WDDM_2_7_CAPS;
+
 #ifdef __cplusplus
 extern "C"
 {
@@ -785,6 +801,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 c2cb1924730..50973535c7a 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 26562bfef2b..ba37098f7ad 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 *);

Bu patchin kaynağı neresi? Bu patch saf wine için mi yoksa proton veya başka bir wine versiyonu için mi ? Patchlemeniz için elinizde wine’ın kaynak kodunun olması lazım, patchledikten sonra da derlemeniz gerekiyor.

Hocam başka forumlarda araştırdım. Araştırdığım kadarıyla bu Wine Patch’i güvenli.

" winehags.patch: " gönderen kişi bu şekilde bir yazı yazmış.

Kaynağı sorgulamam patchin güvensiz olacağından değil, araştırmak içindi. Bilmeden yorum yapamam sonuçta. Bağlantıyı paylaşabilir misiniz?

1 Like
  1. sayfada Gen2 adlı kullanıcı.
1 Like

Ekran kartınız nedir? Wine ile çalıştırmayı düşündüğünüz oyun nedir? Bu oyunu Steam üzerinden mi oynayacaksınız? Steam’ın sunduğu Wine Proton’un versiyonları DLSS’i destekliyormuş, buradaki BENİOKU’dan öğrendim, siz de bakabilirsiniz.

1 Like

Ekran kartım RTX 4060. Witcher 3 oynayacağım ve evet Steam’den oynayacağım. Hocam Steam’in sunduğu sürüm düz DLSS’i destekliyor. Ancak DLSS 3 FG açılmıyor.

1 Like

O zaman onun hakkında pek bir bilgim yok maalesef.

1 Like

Benim bildiğim DLSS FG Linux’ta resmi olarak desteklenmiyor. FSR FG destekleniyor.

Konu hakkında Reddit’te yakın bir tartışma: https://old.reddit.com/r/linux_gaming/comments/1e4psvk/when_will_nvidia_frame_generation_come_to_linux/

Ne zaman gelecek? Bilmiyoruz, NVIDIA’ya kalmış bir durum.

DLSS FG oyunlarını FSR FG’a çevirerek oynayabiliyormuşsun. Böyle bir mod var: GitHub - Nukem9/dlssg-to-fsr3: Adds AMD FSR 3 Frame Generation to games by replacing Nvidia DLSS-G Frame Generation (nvngx_dlssg).

3 Likes

Hocam bu modu kurduğumda FG’yi açtığım an oyundan atıyor. Ancak LukeFZ diye bir mod daha var. Onda işe yarıyor ancak eski sürümünü bulduğum için çok kötü çalışıyor.

Ek: Oynadığım oyun Witcher 3.

Ek: Aşağıda attığım modu kurunca hiç açılmadı.

NVIDIA Frame Gen şu anda eklendi mi?