Witcher 3'te deniyorum.Oynadığınız oyun nedir?
FG öyle bir şey değil sen olayı yanlış anlamışsın. Oyunda DLSS 3/FSR 3 desteği varsa FG açarsın. DLSS dışında olanlar zaten bütün kartlarda açılabiliyor. Yani oyun içi ayarı bu.
Donanım hızlandırma falan dedin diye söyledim. Witcher 3'de ekran ayarlarında "DLSS kare oluşturma" yazmıyorsa muhtemelen Linux desteği yoktur.Oyunda zaten destek var. Hocam oyunda "Framgen" yazmasa buraya konu açmam anormal olurdu.
O modlar FSR 3.1 kuruyor değil mi?Linux, Frame Generation desteklemiyor. Belirli modlarla bunu yapabilirsin, biraz araştırırsan bulursun.
Oynadığınız oyun nedir?
Hocam bazı konular, Reddit'e ve videolara baktım. Araştırmam sonucunda Wine/Proton/Staging 9.0.5+ patchlemem gerektiğini öğrendim. Tam olarak nasıl patchleyeceğim?Linux, Frame Generation desteklemiyor. Belirli modlarla bunu yapabilirsin, biraz araştırırsan bulursun.
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 *);
Ekran ayarlarında "DLSS Kare Oluşturma" yazıyor. Ancak açamıyorum.Donanım hızlandırma falan dedin diye söyledim. Witcher 3'de ekran ayarlarında "DLSS kare oluşturma" yazmıyorsa muhtemelen Linux desteği yoktur.
Linux'da Vulkan kullanılıyorsa açamama nedenin o olabilir. Oyun için Windows kullanman daha doğru olur.Ekran ayarlarında "DLSS Kare Oluşturma" yazıyor. Ancak açamıyorum.
Frame Gen'i Windows'ta Vulkan oyunlarında açabiliyorsun. Yani Vulkan ile alakasız. Galiba NVIDIA FG'yi portlamamış. Bu sebeple üstte attığım gibi benim patchlemem lazım.Linux'da Vulkan kullanılıyorsa açamama nedenin o olabilir. Oyun için Windows kullanman daha doğru olur.
O modlar FSR 3.1 kuruyor değil mi?
Hocam bazı konular, Reddit'e ve videolara baktım. Araştırmam sonucunda Wine/Proton/Staging 9.0.5+ patchlemem gerektiğini öğrendim. Tam olarak nasıl patchleyeceğim?
Kod: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 *);
Linux'da Vulkan kullanılıyorsa açamama nedenin o olabilir. Oyun için Windows kullanman daha doğru olur.
Bu sitenin çalışmasını sağlamak için gerekli çerezleri ve deneyiminizi iyileştirmek için isteğe bağlı çerezleri kullanıyoruz.