Supersedes !9616 and !9572
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/d3dkmt.c | 10 +-- dlls/win32u/sysparams.c | 121 +++++++++++++++++++---------------- dlls/win32u/vulkan.c | 2 +- dlls/win32u/win32u_private.h | 7 +- 4 files changed, 73 insertions(+), 67 deletions(-)
diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index 8da6886154a..5880a1338f2 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -573,7 +573,7 @@ static struct vulkan_physical_device *get_vulkan_physical_device( struct vulkan_ { GUID uuid;
- if (!get_vulkan_uuid_from_luid( luid, &uuid )) + if (!get_gpu_uuid_from_luid( luid, &uuid )) { WARN( "Failed to find Vulkan device with LUID %08x:%08x.\n", luid->HighPart, luid->LowPart ); return NULL; @@ -977,7 +977,7 @@ BOOL get_vulkan_gpus( struct list *gpus )
for (i = 0; i < instance->physical_device_count; ++i) { - struct vulkan_gpu *gpu; + struct gpu_info *gpu;
if (!(gpu = calloc( 1, sizeof(*gpu) ))) break; memcpy( &gpu->uuid, devinfo[i].id.deviceUUID, sizeof(gpu->uuid) ); @@ -998,12 +998,6 @@ BOOL get_vulkan_gpus( struct list *gpus ) return TRUE; }
-void free_vulkan_gpu( struct vulkan_gpu *gpu ) -{ - free( gpu->name ); - free( gpu ); -} - /****************************************************************************** * NtGdiDdDDIShareObjects (win32u.@) */ diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index eee81497139..d846a5f61c9 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -51,7 +51,7 @@ static const char control_keyA[] = "\Registry\Machine\System\CurrentControlS static const char config_keyA[] = "\Registry\Machine\System\CurrentControlSet\Hardware Profiles\Current"; static const char directx_keyA[] = "\Registry\Machine\Software\Microsoft\DirectX";
-static const char devpropkey_gpu_vulkan_uuidA[] = "Properties\{233A9EF3-AFC4-4ABD-B564-C32F21F1535C}\0002"; +static const char devpropkey_gpu_uuidA[] = "Properties\{233A9EF3-AFC4-4ABD-B564-C32F21F1535C}\0002"; static const char devpropkey_gpu_luidA[] = "Properties\{60B193CB-5276-4D0F-96FC-F173ABAD3EC6}\0002"; static const char devpkey_device_driver_date[] = "Properties\{A8B865DD-2E3D-4094-AD97-E593A70C75D6}\0002"; static const char devpkey_device_driver_version[] = "Properties\{A8B865DD-2E3D-4094-AD97-E593A70C75D6}\0003"; @@ -107,7 +107,7 @@ struct gpu char guid[39]; LUID luid; UINT index; - GUID vulkan_uuid; + GUID uuid; UINT source_count; };
@@ -1096,10 +1096,10 @@ static BOOL read_gpu_from_registry( struct gpu *gpu ) NtClose( subkey ); }
- if ((subkey = reg_open_ascii_key( hkey, devpropkey_gpu_vulkan_uuidA ))) + if ((subkey = reg_open_ascii_key( hkey, devpropkey_gpu_uuidA ))) { if (query_reg_value( subkey, NULL, value, sizeof(buffer) ) == sizeof(GUID)) - gpu->vulkan_uuid = *(const GUID *)value->Data; + gpu->uuid = *(const GUID *)value->Data; NtClose( subkey ); }
@@ -1583,10 +1583,9 @@ static BOOL write_gpu_to_registry( const struct gpu *gpu, const struct pci_id *p NtClose( subkey ); }
- if ((subkey = reg_create_ascii_key( hkey, devpropkey_gpu_vulkan_uuidA, 0, NULL ))) + if ((subkey = reg_create_ascii_key( hkey, devpropkey_gpu_uuidA, 0, NULL ))) { - set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_GUID, - &gpu->vulkan_uuid, sizeof(gpu->vulkan_uuid) ); + set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_GUID, &gpu->uuid, sizeof(gpu->uuid) ); NtClose( subkey ); }
@@ -1656,35 +1655,62 @@ static BOOL write_gpu_to_registry( const struct gpu *gpu, const struct pci_id *p return TRUE; }
-static struct vulkan_gpu *find_vulkan_gpu_from_uuid( const struct device_manager_ctx *ctx, const GUID *uuid ) +static struct gpu_info *find_gpu_info_from_uuid( const struct list *infos, const GUID *uuid ) { - struct vulkan_gpu *gpu; + struct gpu_info *gpu;
if (!uuid) return NULL;
- LIST_FOR_EACH_ENTRY( gpu, &ctx->vulkan_gpus, struct vulkan_gpu, entry ) + LIST_FOR_EACH_ENTRY( gpu, infos, struct gpu_info, entry ) if (!memcmp( &gpu->uuid, uuid, sizeof(*uuid) )) return gpu;
return NULL; }
-static struct vulkan_gpu *find_vulkan_gpu_from_pci_id( const struct device_manager_ctx *ctx, const struct pci_id *pci_id ) +static struct gpu_info *find_gpu_info_from_pci_id( const struct list *infos, const struct pci_id *pci_id ) { - struct vulkan_gpu *gpu; + struct gpu_info *gpu;
- LIST_FOR_EACH_ENTRY( gpu, &ctx->vulkan_gpus, struct vulkan_gpu, entry ) + LIST_FOR_EACH_ENTRY( gpu, infos, struct gpu_info, entry ) if (gpu->pci_id.vendor == pci_id->vendor && gpu->pci_id.device == pci_id->device) return gpu;
return NULL; }
-static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID *vulkan_uuid, void *param ) +static struct gpu_info *find_gpu_info( const struct list *infos, const GUID *uuid, const struct pci_id *pci_id ) +{ + struct gpu_info *info; + struct list *ptr; + + if ((info = find_gpu_info_from_uuid( infos, uuid ))) + TRACE( "Found GPU matching uuid %s, pci_id %#04x:%#04x, name %s\n", debugstr_guid( &info->uuid ), + info->pci_id.vendor, info->pci_id.device, debugstr_a(info->name) ); + else if ((info = find_gpu_info_from_pci_id( infos, pci_id ))) + TRACE( "Found GPU matching pci_id %#04x:%#04x, uuid %s, name %s\n", info->pci_id.vendor, + info->pci_id.device, debugstr_guid( &info->uuid ), debugstr_a(info->name) ); + else if ((ptr = list_head( infos ))) + { + info = LIST_ENTRY( ptr, struct gpu_info, entry ); + WARN( "Using GPU pci_id %#04x:%#04x, uuid %s, name %s\n", info->pci_id.vendor, + info->pci_id.device, debugstr_guid( &info->uuid ), debugstr_a(info->name) ); + } + + return info; +} + +static void free_gpu_info( struct gpu_info *info ) +{ + list_remove( &info->entry ); + free( info->name ); + free( info ); +} + +static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID *uuid, void *param ) { struct device_manager_ctx *ctx = param; char buffer[4096]; KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; - struct vulkan_gpu *vulkan_gpu = NULL; - struct list *ptr; + struct gpu_info *vulkan_gpu = NULL; struct gpu *gpu; unsigned int i; HKEY hkey, subkey; @@ -1693,7 +1719,7 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID * static const GUID empty_uuid;
TRACE( "%s %04X %04X %08X %02X %s\n", debugstr_a( name ), pci_id->vendor, pci_id->device, - pci_id->subsystem, pci_id->revision, debugstr_guid( vulkan_uuid ) ); + pci_id->subsystem, pci_id->revision, debugstr_guid( uuid ) );
if (!enum_key && !(enum_key = reg_create_ascii_key( NULL, enum_keyA, 0, NULL ))) return; @@ -1708,23 +1734,9 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID * gpu->refcount = 1; gpu->index = ctx->gpu_count;
- if ((vulkan_gpu = find_vulkan_gpu_from_uuid( ctx, vulkan_uuid ))) - TRACE( "Found vulkan GPU matching uuid %s, pci_id %#04x:%#04x, name %s\n", debugstr_guid(&vulkan_gpu->uuid), - vulkan_gpu->pci_id.vendor, vulkan_gpu->pci_id.device, debugstr_a(vulkan_gpu->name)); - else if ((vulkan_gpu = find_vulkan_gpu_from_pci_id( ctx, pci_id ))) - TRACE( "Found vulkan GPU matching pci_id %#04x:%#04x, uuid %s, name %s\n", - vulkan_gpu->pci_id.vendor, vulkan_gpu->pci_id.device, - debugstr_guid(&vulkan_gpu->uuid), debugstr_a(vulkan_gpu->name)); - else if ((ptr = list_head( &ctx->vulkan_gpus ))) - { - vulkan_gpu = LIST_ENTRY( ptr, struct vulkan_gpu, entry ); - WARN( "Using vulkan GPU pci_id %#04x:%#04x, uuid %s, name %s\n", - vulkan_gpu->pci_id.vendor, vulkan_gpu->pci_id.device, - debugstr_guid(&vulkan_gpu->uuid), debugstr_a(vulkan_gpu->name)); - } - - if (vulkan_uuid && !IsEqualGUID( vulkan_uuid, &empty_uuid )) gpu->vulkan_uuid = *vulkan_uuid; - else if (vulkan_gpu) gpu->vulkan_uuid = vulkan_gpu->uuid; + vulkan_gpu = find_gpu_info( &ctx->vulkan_gpus, uuid, pci_id ); + if (uuid && !IsEqualGUID( uuid, &empty_uuid )) gpu->uuid = *uuid; + else if (vulkan_gpu) gpu->uuid = vulkan_gpu->uuid;
if (!pci_id->vendor && !pci_id->device && vulkan_gpu) pci_id = &vulkan_gpu->pci_id;
@@ -1785,11 +1797,7 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID * ctx->gpu_count++; }
- if (vulkan_gpu) - { - list_remove( &vulkan_gpu->entry ); - free_vulkan_gpu( vulkan_gpu ); - } + if (vulkan_gpu) free_gpu_info( vulkan_gpu ); }
static BOOL write_source_to_registry( struct source *source ) @@ -2219,6 +2227,17 @@ static const struct gdi_device_manager device_manager = add_modes, };
+static void free_gpu_infos( struct list *infos ) +{ + struct list *ptr; + + while ((ptr = list_head( infos ))) + { + struct gpu_info *info = LIST_ENTRY( ptr, struct gpu_info, entry ); + free_gpu_info( info ); + } +} + static void release_display_manager_ctx( struct device_manager_ctx *ctx ) { if (ctx->mutex) @@ -2229,13 +2248,7 @@ static void release_display_manager_ctx( struct device_manager_ctx *ctx )
if (!list_empty( &sources )) last_query_display_time = 0; if (ctx->gpu_count) cleanup_devices(); - - while (!list_empty( &ctx->vulkan_gpus )) - { - struct vulkan_gpu *gpu = LIST_ENTRY( list_head( &ctx->vulkan_gpus ), struct vulkan_gpu, entry ); - list_remove( &gpu->entry ); - free_vulkan_gpu( gpu ); - } + free_gpu_infos( &ctx->vulkan_gpus ); }
static BOOL is_monitor_active( struct monitor *monitor ) @@ -2775,9 +2788,9 @@ static UINT update_display_devices( struct device_manager_ctx *ctx )
static void commit_display_devices( struct device_manager_ctx *ctx ) { - struct vulkan_gpu *gpu, *next; + struct gpu_info *gpu, *next;
- LIST_FOR_EACH_ENTRY_SAFE( gpu, next, &ctx->vulkan_gpus, struct vulkan_gpu, entry ) + LIST_FOR_EACH_ENTRY_SAFE( gpu, next, &ctx->vulkan_gpus, struct gpu_info, entry ) { TRACE( "adding vulkan-only gpu uuid %s, name %s\n", debugstr_guid(&gpu->uuid), debugstr_a(gpu->name)); add_gpu( gpu->name, &gpu->pci_id, &gpu->uuid, ctx ); @@ -8009,8 +8022,8 @@ done: return status; }
-/* Find the Vulkan device UUID corresponding to a LUID */ -BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ) +/* Find the GPU device UUID corresponding to a LUID */ +BOOL get_gpu_uuid_from_luid( const LUID *luid, GUID *uuid ) { BOOL found = FALSE; struct gpu *gpu; @@ -8021,7 +8034,7 @@ BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ) { if ((found = !memcmp( &gpu->luid, luid, sizeof(*luid) ))) { - *uuid = gpu->vulkan_uuid; + *uuid = gpu->uuid; break; } } @@ -8030,8 +8043,8 @@ BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ) return found; }
-/* Find the Vulkan LUID corresponding to a device UUID */ -BOOL get_luid_from_vulkan_uuid( const GUID *uuid, LUID *luid, UINT32 *node_mask ) +/* Find the GPU LUID corresponding to a device UUID */ +BOOL get_gpu_luid_from_uuid( const GUID *uuid, LUID *luid, UINT32 *node_mask ) { BOOL found = FALSE; struct gpu *gpu; @@ -8040,7 +8053,7 @@ BOOL get_luid_from_vulkan_uuid( const GUID *uuid, LUID *luid, UINT32 *node_mask
LIST_FOR_EACH_ENTRY( gpu, &gpus, struct gpu, entry ) { - if (!IsEqualGUID( uuid, &gpu->vulkan_uuid )) continue; + if (!IsEqualGUID( uuid, &gpu->uuid )) continue; *luid = gpu->luid; *node_mask = 1; found = TRUE; diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index d0bcffcb458..80d2129edb3 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -1673,7 +1673,7 @@ static void fill_luid_property( VkPhysicalDeviceProperties2 *properties2 )
if (!vk11 && !id) return; uuid = (const GUID *)(id ? id->deviceUUID : vk11->deviceUUID); - device_luid_valid = get_luid_from_vulkan_uuid( uuid, &luid, &node_mask ); + device_luid_valid = get_gpu_luid_from_uuid( uuid, &luid, &node_mask ); if (!device_luid_valid) WARN( "luid for %s not found\n", debugstr_guid(uuid) );
if (id) diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 0b69ccd481d..7cf642ecc17 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -189,10 +189,12 @@ extern void reset_monitor_update_serial(void); extern void user_lock(void); extern void user_unlock(void); extern void user_check_not_lock(void); +extern BOOL get_gpu_uuid_from_luid( const LUID *luid, GUID *uuid ); +extern BOOL get_gpu_luid_from_uuid( const GUID *uuid, LUID *luid, UINT32 *node_mask );
/* d3dkmtc. */
-struct vulkan_gpu +struct gpu_info { struct list entry; struct pci_id pci_id; @@ -202,9 +204,6 @@ struct vulkan_gpu };
extern BOOL get_vulkan_gpus( struct list *gpus ); -extern void free_vulkan_gpu( struct vulkan_gpu *gpu ); -extern BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ); -extern BOOL get_luid_from_vulkan_uuid( const GUID *uuid, LUID *luid, UINT32 *node_mask );
extern int d3dkmt_object_get_fd( D3DKMT_HANDLE local ); extern NTSTATUS d3dkmt_destroy_mutex( D3DKMT_HANDLE local );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 22 ++++++++++++++++++++++ dlls/win32u/sysparams.c | 34 +++++++++++++++++++++++++++------- dlls/win32u/win32u_private.h | 4 ++++ 3 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 0d4889c0a87..cda47d8cfaf 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -2604,3 +2604,25 @@ const struct opengl_funcs *__wine_get_opengl_driver( UINT version ) pthread_once( &init_once, display_funcs_init ); return &display_funcs; } + +BOOL get_opengl_gpus( struct list *gpus ) +{ + struct egl_platform *egl; + + if (!__wine_get_opengl_driver( WINE_OPENGL_DRIVER_VERSION )) return FALSE; + + LIST_FOR_EACH_ENTRY( egl, &devices_egl, struct egl_platform, entry ) + { + struct gpu_info *gpu; + + if (!(gpu = calloc( 1, sizeof(*gpu) ))) break; + memcpy( &gpu->uuid, &egl->device_uuid, sizeof(egl->device_uuid) ); + gpu->name = strdup( egl->device_name ); + gpu->pci_id.vendor = egl->vendor_id; + gpu->pci_id.device = egl->device_id; + gpu->memory = egl->video_memory; + list_add_tail( gpus, &gpu->entry ); + } + + return TRUE; +} diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index d846a5f61c9..6081b35cf23 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1027,6 +1027,7 @@ struct device_manager_ctx UINT monitor_count; HANDLE mutex; struct list vulkan_gpus; + struct list opengl_gpus; BOOL has_primary; /* for the virtual desktop settings */ BOOL is_primary; @@ -1617,9 +1618,6 @@ static BOOL write_gpu_to_registry( const struct gpu *gpu, const struct pci_id *p set_reg_value( hkey, chip_typeW, REG_SZ, gpu->name, name_size ); set_reg_value( hkey, dac_typeW, REG_SZ, ramdacW, sizeof(ramdacW) );
- /* If we failed to retrieve the gpu memory size set a default of 1Gb */ - if (!memory_size) memory_size = 1073741824; - set_reg_value( hkey, qw_memory_sizeW, REG_QWORD, &memory_size, sizeof(memory_size) ); value = (ULONG)min( memory_size, (ULONGLONG)ULONG_MAX ); set_reg_value( hkey, memory_sizeW, REG_DWORD, &value, sizeof(value) ); @@ -1710,7 +1708,8 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID * struct device_manager_ctx *ctx = param; char buffer[4096]; KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; - struct gpu_info *vulkan_gpu = NULL; + struct gpu_info *vulkan_gpu = NULL, *opengl_gpu = NULL; + ULONGLONG memory = 0; struct gpu *gpu; unsigned int i; HKEY hkey, subkey; @@ -1735,13 +1734,17 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID * gpu->index = ctx->gpu_count;
vulkan_gpu = find_gpu_info( &ctx->vulkan_gpus, uuid, pci_id ); + opengl_gpu = find_gpu_info( &ctx->opengl_gpus, uuid, pci_id ); if (uuid && !IsEqualGUID( uuid, &empty_uuid )) gpu->uuid = *uuid; else if (vulkan_gpu) gpu->uuid = vulkan_gpu->uuid; + else if (opengl_gpu) gpu->uuid = opengl_gpu->uuid;
if (!pci_id->vendor && !pci_id->device && vulkan_gpu) pci_id = &vulkan_gpu->pci_id; + if (!pci_id->vendor && !pci_id->device && opengl_gpu) pci_id = &opengl_gpu->pci_id;
name = gpu_device_name( pci_id->vendor, pci_id->device, name ); if (!strcmp( name, "Wine Adapter" ) && vulkan_gpu) name = vulkan_gpu->name; + if (!strcmp( name, "Wine Adapter" ) && opengl_gpu) name = opengl_gpu->name; RtlUTF8ToUnicodeN( gpu->name, sizeof(gpu->name) - sizeof(WCHAR), &len, name, strlen( name ) );
snprintf( gpu->path, sizeof(gpu->path), "PCI\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\%08X", @@ -1785,7 +1788,11 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID *
NtClose( hkey );
- if (!write_gpu_to_registry( gpu, pci_id, vulkan_gpu ? vulkan_gpu->memory : 0 )) + if (!memory && vulkan_gpu) memory = vulkan_gpu->memory; + if (!memory && opengl_gpu) memory = opengl_gpu->memory; + if (!memory) memory = 1024 * 1024 * 1024; + + if (!write_gpu_to_registry( gpu, pci_id, memory )) { WARN( "Failed to write gpu %p to registry\n", gpu ); gpu_release( gpu ); @@ -1798,6 +1805,7 @@ static void add_gpu( const char *name, const struct pci_id *pci_id, const GUID * }
if (vulkan_gpu) free_gpu_info( vulkan_gpu ); + if (opengl_gpu) free_gpu_info( opengl_gpu ); }
static BOOL write_source_to_registry( struct source *source ) @@ -2248,7 +2256,9 @@ static void release_display_manager_ctx( struct device_manager_ctx *ctx )
if (!list_empty( &sources )) last_query_display_time = 0; if (ctx->gpu_count) cleanup_devices(); + free_gpu_infos( &ctx->vulkan_gpus ); + free_gpu_infos( &ctx->opengl_gpus ); }
static BOOL is_monitor_active( struct monitor *monitor ) @@ -2795,6 +2805,11 @@ static void commit_display_devices( struct device_manager_ctx *ctx ) TRACE( "adding vulkan-only gpu uuid %s, name %s\n", debugstr_guid(&gpu->uuid), debugstr_a(gpu->name)); add_gpu( gpu->name, &gpu->pci_id, &gpu->uuid, ctx ); } + LIST_FOR_EACH_ENTRY_SAFE( gpu, next, &ctx->opengl_gpus, struct gpu_info, entry ) + { + TRACE( "adding opengl-only gpu uuid %s, name %s\n", debugstr_guid(&gpu->uuid), debugstr_a(gpu->name)); + add_gpu( gpu->name, &gpu->pci_id, &gpu->uuid, ctx ); + }
set_winstation_monitors( TRUE ); } @@ -2823,7 +2838,11 @@ static BOOL lock_display_devices( BOOL force ) { static const WCHAR wine_service_station_name[] = {'_','_','w','i','n','e','s','e','r','v','i','c','e','_','w','i','n','s','t','a','t','i','o','n',0}; - struct device_manager_ctx ctx = {.vulkan_gpus = LIST_INIT(ctx.vulkan_gpus)}; + struct device_manager_ctx ctx = + { + .opengl_gpus = LIST_INIT(ctx.opengl_gpus), + .vulkan_gpus = LIST_INIT(ctx.vulkan_gpus), + }; UINT64 serial; UINT status; WCHAR name[MAX_PATH]; @@ -2849,7 +2868,8 @@ static BOOL lock_display_devices( BOOL force ) if (!force && !update_display_cache_from_registry( serial )) force = TRUE; if (force) { - if (!get_vulkan_gpus( &ctx.vulkan_gpus )) WARN( "Failed to find any vulkan GPU\n" ); + if (!get_vulkan_gpus( &ctx.vulkan_gpus )) WARN( "Failed to find any Vulkan GPU\n" ); + if (!get_opengl_gpus( &ctx.opengl_gpus )) WARN( "Failed to find any OpenGL GPU\n" ); if (!(status = update_display_devices( &ctx ))) commit_display_devices( &ctx ); else WARN( "Failed to update display devices, status %#x\n", status ); release_display_manager_ctx( &ctx ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 7cf642ecc17..36769435dbf 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -216,6 +216,10 @@ extern D3DKMT_HANDLE d3dkmt_create_sync( int fd, D3DKMT_HANDLE *global ); extern D3DKMT_HANDLE d3dkmt_open_sync( D3DKMT_HANDLE global, HANDLE shared ); extern NTSTATUS d3dkmt_destroy_sync( D3DKMT_HANDLE local );
+/* opengl.c */ + +extern BOOL get_opengl_gpus( struct list *gpus ); + /* winstation.c */
struct object_lock
From: Rémi Bernon rbernon@codeweavers.com
Based on a patch from Derek Lesho. --- dlls/opengl32/make_opengl | 2 ++ dlls/opengl32/unix_thunks.c | 12 +++----- dlls/opengl32/unix_thunks.h | 2 ++ dlls/opengl32/unix_wgl.c | 36 +++++++++++++++++++++++ dlls/win32u/opengl.c | 56 ++++++++++++++++++++++++++++++++++-- dlls/win32u/tests/d3dkmt.c | 24 +++++++--------- include/wine/opengl_driver.h | 1 + 7 files changed, 108 insertions(+), 25 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index c8f6a5a7a49..3c862943b64 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -205,6 +205,8 @@ my %manual_unix_thunks = "glGetFramebufferParameterivEXT" => 1, "glGetInteger64v" => 1, "glGetIntegerv" => 1, + "glGetUnsignedBytevEXT" => 1, + "glGetUnsignedBytei_vEXT" => 1, "glGetString" => 1, "glGetStringi" => 1, "glNamedFramebufferDrawBuffer" => 1, diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 47b3c84623c..58cbb561160 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -11529,16 +11529,14 @@ static NTSTATUS ext_glGetUniformuivEXT( void *args ) static NTSTATUS ext_glGetUnsignedBytei_vEXT( void *args ) { struct glGetUnsignedBytei_vEXT_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glGetUnsignedBytei_vEXT( params->target, params->index, params->data ); + wrap_glGetUnsignedBytei_vEXT( params->teb, params->target, params->index, params->data ); return STATUS_SUCCESS; }
static NTSTATUS ext_glGetUnsignedBytevEXT( void *args ) { struct glGetUnsignedBytevEXT_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glGetUnsignedBytevEXT( params->pname, params->data ); + wrap_glGetUnsignedBytevEXT( params->teb, params->pname, params->data ); return STATUS_SUCCESS; }
@@ -51620,8 +51618,7 @@ static NTSTATUS wow64_ext_glGetUnsignedBytei_vEXT( void *args ) PTR32 data; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glGetUnsignedBytei_vEXT( params->target, params->index, ULongToPtr(params->data) ); + wrap_glGetUnsignedBytei_vEXT( teb, params->target, params->index, ULongToPtr(params->data) ); return STATUS_SUCCESS; }
@@ -51634,8 +51631,7 @@ static NTSTATUS wow64_ext_glGetUnsignedBytevEXT( void *args ) PTR32 data; } *params = args; TEB *teb = get_teb64( params->teb ); - const struct opengl_funcs *funcs = teb->glTable; - funcs->p_glGetUnsignedBytevEXT( params->pname, ULongToPtr(params->data) ); + wrap_glGetUnsignedBytevEXT( teb, params->pname, ULongToPtr(params->data) ); return STATUS_SUCCESS; }
diff --git a/dlls/opengl32/unix_thunks.h b/dlls/opengl32/unix_thunks.h index 3f00ad63832..70260b735fd 100644 --- a/dlls/opengl32/unix_thunks.h +++ b/dlls/opengl32/unix_thunks.h @@ -33,6 +33,8 @@ extern void wrap_glFramebufferReadBufferEXT( TEB *teb, GLuint framebuffer, GLenu extern void wrap_glGetFramebufferParameterivEXT( TEB *teb, GLuint framebuffer, GLenum pname, GLint *params ); extern void wrap_glGetInteger64v( TEB *teb, GLenum pname, GLint64 *data ); extern const GLubyte *wrap_glGetStringi( TEB *teb, GLenum name, GLuint index ); +extern void wrap_glGetUnsignedBytei_vEXT( TEB *teb, GLenum target, GLuint index, GLubyte *data ); +extern void wrap_glGetUnsignedBytevEXT( TEB *teb, GLenum pname, GLubyte *data ); extern void wrap_glNamedFramebufferDrawBuffer( TEB *teb, GLuint framebuffer, GLenum buf ); extern void wrap_glNamedFramebufferDrawBuffers( TEB *teb, GLuint framebuffer, GLsizei n, const GLenum *bufs ); extern void wrap_glNamedFramebufferReadBuffer( TEB *teb, GLuint framebuffer, GLenum src ); diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 48884fef88f..0e07565cea4 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -861,6 +861,7 @@ static BOOL get_default_fbo_integer( struct context *ctx, struct opengl_drawable
static BOOL get_integer( TEB *teb, GLenum pname, GLint *data ) { + const struct opengl_funcs *funcs = teb->glTable; struct opengl_drawable *draw, *read; struct context *ctx;
@@ -889,11 +890,46 @@ static BOOL get_integer( TEB *teb, GLenum pname, GLint *data ) if (!read->read_fbo) break; *data = ctx->read_fbo; return TRUE; + case GL_NUM_DEVICE_UUIDS_EXT: + case GL_DEVICE_NODE_MASK_EXT: + if (!funcs->p_query_renderer) break; + return funcs->p_query_renderer( 0, pname, data ); }
return get_default_fbo_integer( ctx, draw, read, pname, data ); }
+void wrap_glGetUnsignedBytei_vEXT( TEB *teb, GLenum target, GLuint index, GLubyte *data ) +{ + const struct opengl_funcs *funcs = teb->glTable; + + switch (target) + { + case GL_DEVICE_UUID_EXT: + if (!funcs->p_query_renderer) break; + funcs->p_query_renderer( index, target, data ); + return; + } + + return funcs->p_glGetUnsignedBytei_vEXT( target, index, data ); +} + +void wrap_glGetUnsignedBytevEXT( TEB *teb, GLenum pname, GLubyte *data ) +{ + const struct opengl_funcs *funcs = teb->glTable; + + switch (pname) + { + case GL_DRIVER_UUID_EXT: + case GL_DEVICE_LUID_EXT: + if (!funcs->p_query_renderer) break; + funcs->p_query_renderer( 0, pname, data ); + return; + } + + return funcs->p_glGetUnsignedBytevEXT( pname, data ); +} + const GLubyte *wrap_glGetString( TEB *teb, GLenum name ) { const struct opengl_funcs *funcs = teb->glTable; diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index cda47d8cfaf..691b1c0820e 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1073,6 +1073,7 @@ static void init_device_info( struct egl_platform *egl, const struct opengl_func { static const UINT versions[] = {46, 45, 44, 43, 42, 41, 40, 33, 32, 31, 30, 21, 20, 15, 14, 13, 12, 11, 10, 0}; EGLContext core_context = EGL_NO_CONTEXT, compat_context = EGL_NO_CONTEXT, context = EGL_NO_CONTEXT; + BOOL has_device_persistent_id; int i, count, values[3] = {0}; const char *extensions, *str; EGLConfig config; @@ -1095,13 +1096,11 @@ static void init_device_info( struct egl_platform *egl, const struct opengl_func TRACE( " - device_id: %#x\n", egl->device_id ); TRACE( " - vendor_id: %#x\n", egl->vendor_id );
- if (has_extension( extensions, "EGL_EXT_device_persistent_id" )) + if ((has_device_persistent_id = has_extension( extensions, "EGL_EXT_device_persistent_id" ))) { funcs->p_eglQueryDeviceBinaryEXT( egl->device, EGL_DEVICE_UUID_EXT, sizeof(egl->device_uuid), &egl->device_uuid, &count ); funcs->p_eglQueryDeviceBinaryEXT( egl->device, EGL_DRIVER_UUID_EXT, sizeof(egl->driver_uuid), &egl->driver_uuid, &count ); } - TRACE( " - device_uuid: %s\n", debugstr_guid(&egl->device_uuid) ); - TRACE( " - driver_uuid: %s\n", debugstr_guid(&egl->driver_uuid) );
funcs->p_eglBindAPI( EGL_OPENGL_API ); funcs->p_eglGetConfigs( egl->display, &config, 1, &count ); @@ -1165,9 +1164,18 @@ static void init_device_info( struct egl_platform *egl, const struct opengl_func } TRACE( " - video_memory: %u MiB\n", egl->video_memory );
+ if (!has_device_persistent_id && (has_extension( extensions, "GL_EXT_memory_object" ) || has_extension( extensions, "GL_EXT_semaphore" ))) + { + funcs->p_glGetUnsignedBytevEXT( GL_DRIVER_UUID_EXT, (GLubyte *)&egl->driver_uuid ); + funcs->p_glGetUnsignedBytei_vEXT( GL_DEVICE_UUID_EXT, 0, (GLubyte *)&egl->device_uuid ); + } + funcs->p_eglMakeCurrent( egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); }
+ TRACE( " - device_uuid: %s\n", debugstr_guid(&egl->device_uuid) ); + TRACE( " - driver_uuid: %s\n", debugstr_guid(&egl->driver_uuid) ); + if (compat_context) funcs->p_eglDestroyContext( egl->display, compat_context ); if (core_context) funcs->p_eglDestroyContext( egl->display, core_context );
@@ -2380,6 +2388,45 @@ static struct egl_platform *egl_platform_from_index( GLint index ) return NULL; }
+static BOOL win32u_query_renderer( UINT index, UINT attribute, void *value ) +{ + struct egl_platform *egl; + LUID luid; + UINT mask; + + TRACE( "index %u, attribute %#x, value %p\n", index, attribute, value ); + + if (attribute == GL_NUM_DEVICE_UUIDS_EXT) + { + *(GLuint *)value = list_count( &devices_egl ); + return TRUE; + } + + if (!(egl = egl_platform_from_index( index ))) + { + set_gl_error( GL_INVALID_INDEX ); + return FALSE; + } + + switch (attribute) + { + case GL_DRIVER_UUID_EXT: + memcpy( value, &egl->driver_uuid, sizeof(egl->driver_uuid) ); + return TRUE; + case GL_DEVICE_UUID_EXT: + memcpy( value, &egl->device_uuid, sizeof(egl->device_uuid) ); + return TRUE; + case GL_DEVICE_LUID_EXT: + return get_gpu_luid_from_uuid( &egl->device_uuid, (LUID *)value, &mask ); + case GL_DEVICE_NODE_MASK_EXT: + return get_gpu_luid_from_uuid( &egl->device_uuid, &luid, value ); + default: + FIXME( "Unsupported attribute %#x\n", attribute ); + set_gl_error( GL_INVALID_ENUM ); + return FALSE; + } +} + static BOOL query_renderer_integer( struct egl_platform *egl, GLenum attribute, GLuint *value ) { switch (attribute) @@ -2503,6 +2550,8 @@ static void display_funcs_init(void) USE_GL_FUNC(glDeleteFramebuffers) USE_GL_FUNC(glDeleteRenderbuffers) USE_GL_FUNC(glGetNamedFramebufferAttachmentParameteriv) + USE_GL_FUNC(glGetUnsignedBytei_vEXT) + USE_GL_FUNC(glGetUnsignedBytevEXT) USE_GL_FUNC(glNamedFramebufferDrawBuffer) USE_GL_FUNC(glNamedFramebufferReadBuffer) USE_GL_FUNC(glNamedFramebufferRenderbuffer) @@ -2578,6 +2627,7 @@ static void display_funcs_init(void) if (!list_empty( &devices_egl )) { register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_WINE_query_renderer" ); + display_funcs.p_query_renderer = win32u_query_renderer; display_funcs.p_wglQueryCurrentRendererIntegerWINE = win32u_wglQueryCurrentRendererIntegerWINE; display_funcs.p_wglQueryCurrentRendererStringWINE = win32u_wglQueryCurrentRendererStringWINE; display_funcs.p_wglQueryRendererIntegerWINE = win32u_wglQueryRendererIntegerWINE; diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index f5f6573d0f0..87c117e142d 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -4216,6 +4216,8 @@ static struct opengl_device *create_opengl_device( HWND hwnd, LUID *luid )
const char *extensions, *ptr; struct opengl_device *dev; + unsigned int nodes = 0; + LUID device_luid = {0}; int format, count; GUID guid; BOOL ret; @@ -4274,22 +4276,16 @@ static struct opengl_device *create_opengl_device( HWND hwnd, LUID *luid ) ok_x4( glGetError(), ==, 0 ); ok( !IsEqualGUID( &GUID_NULL, &guid ), "got GL_DRIVER_UUID_EXT %s\n", debugstr_guid( &guid ) );
- if (!winetest_platform_is_wine) /* crashes in host drivers */ - { - LUID device_luid = {0}; - unsigned int nodes = 0; - - p_glGetUnsignedBytevEXT( GL_DEVICE_LUID_EXT, (GLubyte *)&device_luid ); - if (!dev->broken) ok_x4( glGetError(), ==, 0 ); - else ok_x4( glGetError(), ==, GL_INVALID_ENUM ); + p_glGetUnsignedBytevEXT( GL_DEVICE_LUID_EXT, (GLubyte *)&device_luid ); + if (!dev->broken) ok_x4( glGetError(), ==, 0 ); + else ok_x4( glGetError(), ==, GL_INVALID_ENUM );
- glGetIntegerv( GL_DEVICE_NODE_MASK_EXT, (GLint *)&nodes ); - if (!dev->broken) ok_x4( glGetError(), ==, 0 ); - else ok_x4( glGetError(), ==, GL_INVALID_ENUM ); - if (!dev->broken) ok_u4( nodes, !=, 0 ); + glGetIntegerv( GL_DEVICE_NODE_MASK_EXT, (GLint *)&nodes ); + if (!dev->broken) ok_x4( glGetError(), ==, 0 ); + else ok_x4( glGetError(), ==, GL_INVALID_ENUM ); + if (!dev->broken) ok_u4( nodes, !=, 0 );
- if (luid_equals( luid, &luid_zero )) *luid = device_luid; - } + if (luid_equals( luid, &luid_zero )) *luid = device_luid;
return dev; } diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 2e4ee296159..cfdd4909b53 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -83,6 +83,7 @@ struct wgl_context /* interface between opengl32 and win32u */ struct opengl_funcs { + BOOL (*p_query_renderer)( UINT index, UINT attribute, void *value ); BOOL (*p_wgl_context_reset)( struct wgl_context *context, HDC hdc, struct wgl_context *share, const int *attribs ); BOOL (*p_wgl_context_flush)( struct wgl_context *context, void (*flush)(void), BOOL force_swap ); BOOL (*p_wglCopyContext)( struct wgl_context * hglrcSrc, struct wgl_context * hglrcDst, UINT mask );
From: Derek Lesho dlesho@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 23 ++++++++----- dlls/win32u/opengl.c | 62 ++++++++++++++++++++++++++++++++++++ dlls/win32u/tests/d3dkmt.c | 40 +++++++++++------------ dlls/win32u/vulkan.c | 2 +- dlls/win32u/win32u_private.h | 2 ++ 5 files changed, 100 insertions(+), 29 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 0e07565cea4..d0211278315 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -727,6 +727,15 @@ static BOOL is_extension_supported( struct context *ctx, const char *extension ) sizeof(ctx->extension_array[0]), string_array_cmp ) != NULL; }
+static char *append_extension( char *ptr, const char *name ) +{ + size_t size = strlen( name ); + memcpy( ptr, name, size ); + ptr += size; + *ptr++ = ' '; + return ptr; +} + /* build the extension string by filtering out the disabled extensions */ static GLubyte *filter_extensions( struct context *ctx, const char *extensions ) { @@ -735,6 +744,7 @@ static GLubyte *filter_extensions( struct context *ctx, const char *extensions ) char *p, *str;
size = strlen( extensions ) + 2; + if (opengl_funcs->p_glImportMemoryWin32HandleEXT) size += strlen( "GL_EXT_memory_object_win32" ) + 1; for (extra = legacy_extensions; *extra; extra++) size += strlen( *extra ) + 1; if (!(p = str = malloc( size ))) return NULL;
@@ -762,13 +772,8 @@ static GLubyte *filter_extensions( struct context *ctx, const char *extensions ) extensions = end; }
- for (extra = legacy_extensions; *extra; extra++) - { - size = strlen( *extra ); - memcpy( p, *extra, size ); - p += size; - *p++ = ' '; - } + if (opengl_funcs->p_glImportMemoryWin32HandleEXT) p = append_extension( p, "GL_EXT_memory_object_win32" ); + for (extra = legacy_extensions; *extra; extra++) p = append_extension( p, *extra );
if (p != str) --p; *p = 0; @@ -1279,6 +1284,8 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD if (!ctx->major_version) ctx->major_version = 1; TRACE( "context %p version %d.%d\n", ctx, ctx->major_version, ctx->minor_version );
+ if (opengl_funcs->p_glImportMemoryWin32HandleEXT) size++; + if (ctx->major_version >= 3) { GLint extensions_count; @@ -1318,7 +1325,6 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD } ext++; } - assert( count + ARRAYSIZE(legacy_extensions) - 1 == size ); }
if (!disabled && !(disabled = query_opengl_option( "DisabledExtensions" ))) disabled = ""; @@ -1336,6 +1342,7 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD count = j; }
+ if (opengl_funcs->p_glImportMemoryWin32HandleEXT) extensions[count++] = "GL_EXT_memory_object_win32"; for (i = 0; legacy_extensions[i]; i++) extensions[count++] = legacy_extensions[i]; qsort( extensions, count, sizeof(*extensions), string_array_cmp ); ctx->extension_array = extensions; diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 691b1c0820e..9d04fe6ea2a 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -26,6 +26,7 @@ #include <assert.h> #include <pthread.h> #include <dlfcn.h> +#include <unistd.h>
#include "ntstatus.h" #define WIN32_NO_STATUS @@ -2524,6 +2525,60 @@ static const char *win32u_wglQueryCurrentRendererStringWINE( GLenum attribute ) return query_renderer_string( LIST_ENTRY( ptr, struct egl_platform, entry ), attribute ); }
+static void import_memory( GLuint memory, GLuint64 size, GLenum type, void *handle ) +{ + const struct opengl_funcs *funcs = &display_funcs; + D3DKMT_HANDLE local, mutex, sync; + GLenum err; + int fd; + + switch (type) + { + case GL_HANDLE_TYPE_OPAQUE_WIN32_EXT: + local = d3dkmt_open_resource( 0, handle, &mutex, &sync ); + break; + case GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT: + local = d3dkmt_open_resource( PtrToUlong( handle ), NULL, &mutex, &sync ); + break; + default: return set_gl_error( GL_INVALID_ENUM ); + } + if (mutex) d3dkmt_destroy_mutex( mutex ); + if (sync) d3dkmt_destroy_sync( sync ); + fd = d3dkmt_object_get_fd( local ); + d3dkmt_destroy_resource( local ); + if (fd < 0) return set_gl_error( GL_INVALID_VALUE ); + + set_gl_error( funcs->p_glGetError() ); /* save the error in the wrapper so we can check for success */ + funcs->p_glImportMemoryFdEXT( memory, size, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd ); + if (!(err = funcs->p_glGetError())) return; + + close( fd ); + set_gl_error( err ); +} + +static void win32u_glImportMemoryWin32HandleEXT( GLuint memory, GLuint64 size, GLenum type, void *handle ) +{ + TRACE( "memory %u size %s type %#x handle %p\n", memory, wine_dbgstr_longlong( size ), type, handle ); + + if (handle) import_memory( memory, size, type, handle ); + else set_gl_error( GL_INVALID_VALUE ); +} + +static void win32u_glImportMemoryWin32NameEXT( GLuint memory, GLuint64 size, GLenum type, const void *name ) +{ + HANDLE handle; + + TRACE( "memory %u size %s type %#x name %s\n", memory, wine_dbgstr_longlong( size ), type, debugstr_w( name ) ); + + if (type != GL_HANDLE_TYPE_OPAQUE_WIN32_EXT) set_gl_error( GL_INVALID_ENUM ); + else if (!(handle = open_shared_resource_from_name( (const WCHAR *)name ))) set_gl_error( GL_INVALID_VALUE ); + else + { + import_memory( memory, size, type, handle ); + NtClose( handle ); + } +} + static void display_funcs_init(void) { struct egl_platform *egl; @@ -2552,6 +2607,7 @@ static void display_funcs_init(void) USE_GL_FUNC(glGetNamedFramebufferAttachmentParameteriv) USE_GL_FUNC(glGetUnsignedBytei_vEXT) USE_GL_FUNC(glGetUnsignedBytevEXT) + USE_GL_FUNC(glImportMemoryFdEXT) USE_GL_FUNC(glNamedFramebufferDrawBuffer) USE_GL_FUNC(glNamedFramebufferReadBuffer) USE_GL_FUNC(glNamedFramebufferRenderbuffer) @@ -2624,6 +2680,12 @@ static void display_funcs_init(void) display_funcs.p_wglSwapIntervalEXT = win32u_wglSwapIntervalEXT; display_funcs.p_wglGetSwapIntervalEXT = win32u_wglGetSwapIntervalEXT;
+ if (display_funcs.p_glImportMemoryFdEXT) + { + display_funcs.p_glImportMemoryWin32HandleEXT = win32u_glImportMemoryWin32HandleEXT; + display_funcs.p_glImportMemoryWin32NameEXT = win32u_glImportMemoryWin32NameEXT; + } + if (!list_empty( &devices_egl )) { register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_WINE_query_renderer" ); diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index 87c117e142d..dd8033def73 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -4252,7 +4252,7 @@ static struct opengl_device *create_opengl_device( HWND hwnd, LUID *luid ) ok_ptr( extensions, !=, NULL );
ptr = find_opengl_extension( extensions, "GL_EXT_memory_object_win32" ); - todo_wine ok_ptr( ptr, !=, NULL ); + ok_ptr( ptr, !=, NULL ); ptr = find_opengl_extension( extensions, "GL_EXT_semaphore_win32" ); todo_wine ok_ptr( ptr, !=, NULL ); ptr = find_opengl_extension( extensions, "GL_EXT_win32_keyed_mutex" ); @@ -4324,7 +4324,7 @@ static GLuint import_opengl_image( struct opengl_device *dev, UINT width, UINT h if (name) { PFN_glImportMemoryWin32NameEXT p_glImportMemoryWin32NameEXT = (void *)wglGetProcAddress( "glImportMemoryWin32NameEXT" ); - todo_wine ok_ptr( p_glImportMemoryWin32NameEXT, !=, NULL ); + ok_ptr( p_glImportMemoryWin32NameEXT, !=, NULL ); if (!p_glImportMemoryWin32NameEXT) return 0;
p_glCreateMemoryObjectsEXT( 1, &memory ); @@ -4335,7 +4335,7 @@ static GLuint import_opengl_image( struct opengl_device *dev, UINT width, UINT h else { PFN_glImportMemoryWin32HandleEXT p_glImportMemoryWin32HandleEXT = (void *)wglGetProcAddress( "glImportMemoryWin32HandleEXT" ); - todo_wine ok_ptr( p_glImportMemoryWin32HandleEXT, !=, NULL ); + ok_ptr( p_glImportMemoryWin32HandleEXT, !=, NULL ); if (!p_glImportMemoryWin32HandleEXT) return 0;
p_glCreateMemoryObjectsEXT( 1, &memory ); @@ -5697,25 +5697,25 @@ static void test_shared_resources(void) test_import_opengl_image( opengl_imp, resource_size, 1, 1, 1, name, handle, GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT ); ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, resource_size, 1, 1, 1, name, handle, GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); break; case 1: test_import_opengl_image( opengl_imp, width_1d, 1, array_1d, 4, name, handle, GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT ); ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_1d, 1, array_1d, 4, name, handle, GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); break; case 2: test_import_opengl_image( opengl_imp, width_2d, height_2d, 1, 4, name, handle, GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT ); ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_2d, height_2d, 1, 4, name, handle, GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); break; case 3: test_import_opengl_image( opengl_imp, width_3d, height_3d, depth_3d, 4, name, handle, GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT ); ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_3d, height_3d, depth_3d, 4, name, handle, GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); break; } } @@ -5727,41 +5727,41 @@ static void test_shared_resources(void) test_import_opengl_image( opengl_imp, resource_size, 1, 1, 1, name, handle, GL_HANDLE_TYPE_OPAQUE_WIN32_EXT ); ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, resource_size, 1, 1, 1, name, handle, GL_HANDLE_TYPE_D3D11_IMAGE_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, resource_size, 1, 1, 1, name, handle, GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, resource_size, 1, 1, 1, name, handle, GL_HANDLE_TYPE_D3D12_RESOURCE_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); break; case 1: test_import_opengl_image( opengl_imp, width_1d, 1, array_1d, 4, name, handle, GL_HANDLE_TYPE_OPAQUE_WIN32_EXT ); ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_1d, 1, array_1d, 4, name, handle, GL_HANDLE_TYPE_D3D11_IMAGE_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_1d, 1, array_1d, 4, name, handle, GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_1d, 1, array_1d, 4, name, handle, GL_HANDLE_TYPE_D3D12_RESOURCE_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); break; case 2: test_import_opengl_image( opengl_imp, width_2d, height_2d, 1, 4, name, handle, GL_HANDLE_TYPE_OPAQUE_WIN32_EXT ); ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_2d, height_2d, 1, 4, name, handle, GL_HANDLE_TYPE_D3D11_IMAGE_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_2d, height_2d, 1, 4, name, handle, GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_2d, height_2d, 1, 4, name, handle, GL_HANDLE_TYPE_D3D12_RESOURCE_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); break; case 3: test_import_opengl_image( opengl_imp, width_3d, height_3d, depth_3d, 4, name, handle, GL_HANDLE_TYPE_OPAQUE_WIN32_EXT ); ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_3d, height_3d, depth_3d, 4, name, handle, GL_HANDLE_TYPE_D3D11_IMAGE_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_3d, height_3d, depth_3d, 4, name, handle, GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); test_import_opengl_image( opengl_imp, width_3d, height_3d, depth_3d, 4, name, handle, GL_HANDLE_TYPE_D3D12_RESOURCE_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 ); break; } } @@ -5800,7 +5800,7 @@ static void test_shared_resources(void) if (opengl_imp && GET_DIM(test) == 2 && !opengl_imp->broken) { gl_img = import_opengl_image( opengl_imp, width_2d, height_2d, 1, 4, name, handle, GL_HANDLE_TYPE_OPAQUE_WIN32_EXT ); - ok_x4( glGetError(), ==, 0 ); + todo_wine ok_x4( glGetError(), ==, 0 );
CloseHandle( handle ); status = open_shared_resource( path, &handle ); diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 80d2129edb3..a6b10c8861b 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -312,7 +312,7 @@ static HANDLE create_shared_resource_handle( D3DKMT_HANDLE local, const VkExport return NULL; }
-static HANDLE open_shared_resource_from_name( const WCHAR *name ) +HANDLE open_shared_resource_from_name( const WCHAR *name ) { D3DKMT_OPENNTHANDLEFROMNAME open_name = {0}; WCHAR bufferW[MAX_PATH * 2]; diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 36769435dbf..ec573462ea8 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -208,6 +208,8 @@ extern BOOL get_vulkan_gpus( struct list *gpus ); extern int d3dkmt_object_get_fd( D3DKMT_HANDLE local ); extern NTSTATUS d3dkmt_destroy_mutex( D3DKMT_HANDLE local );
+extern HANDLE open_shared_resource_from_name( const WCHAR *name ); + extern D3DKMT_HANDLE d3dkmt_create_resource( int fd, D3DKMT_HANDLE *global ); extern D3DKMT_HANDLE d3dkmt_open_resource( D3DKMT_HANDLE global, HANDLE shared, D3DKMT_HANDLE *mutex_local, D3DKMT_HANDLE *sync_local ); extern NTSTATUS d3dkmt_destroy_resource( D3DKMT_HANDLE local );
From: Derek Lesho dlesho@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 4 +++ dlls/win32u/opengl.c | 58 ++++++++++++++++++++++++++++++++++++ dlls/win32u/tests/d3dkmt.c | 10 +++---- dlls/win32u/vulkan.c | 2 +- dlls/win32u/win32u_private.h | 1 + 5 files changed, 69 insertions(+), 6 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index d0211278315..4d6416fcc13 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -745,6 +745,7 @@ static GLubyte *filter_extensions( struct context *ctx, const char *extensions )
size = strlen( extensions ) + 2; if (opengl_funcs->p_glImportMemoryWin32HandleEXT) size += strlen( "GL_EXT_memory_object_win32" ) + 1; + if (opengl_funcs->p_glImportSemaphoreWin32HandleEXT) size += strlen( "GL_EXT_semaphore_win32" ) + 1; for (extra = legacy_extensions; *extra; extra++) size += strlen( *extra ) + 1; if (!(p = str = malloc( size ))) return NULL;
@@ -773,6 +774,7 @@ static GLubyte *filter_extensions( struct context *ctx, const char *extensions ) }
if (opengl_funcs->p_glImportMemoryWin32HandleEXT) p = append_extension( p, "GL_EXT_memory_object_win32" ); + if (opengl_funcs->p_glImportSemaphoreWin32HandleEXT) p = append_extension( p, "GL_EXT_semaphore_win32" ); for (extra = legacy_extensions; *extra; extra++) p = append_extension( p, *extra );
if (p != str) --p; @@ -1285,6 +1287,7 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD TRACE( "context %p version %d.%d\n", ctx, ctx->major_version, ctx->minor_version );
if (opengl_funcs->p_glImportMemoryWin32HandleEXT) size++; + if (opengl_funcs->p_glImportSemaphoreWin32HandleEXT) size++;
if (ctx->major_version >= 3) { @@ -1343,6 +1346,7 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD }
if (opengl_funcs->p_glImportMemoryWin32HandleEXT) extensions[count++] = "GL_EXT_memory_object_win32"; + if (opengl_funcs->p_glImportSemaphoreWin32HandleEXT) extensions[count++] = "GL_EXT_semaphore_win32"; for (i = 0; legacy_extensions[i]; i++) extensions[count++] = legacy_extensions[i]; qsort( extensions, count, sizeof(*extensions), string_array_cmp ); ctx->extension_array = extensions; diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 9d04fe6ea2a..5ecebc4802a 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -2579,6 +2579,58 @@ static void win32u_glImportMemoryWin32NameEXT( GLuint memory, GLuint64 size, GLe } }
+static void import_semaphore( GLuint semaphore, GLenum type, void *handle, const void *name ) +{ + const struct opengl_funcs *funcs = &display_funcs; + D3DKMT_HANDLE local; + GLenum err; + int fd; + + switch (type) + { + case GL_HANDLE_TYPE_OPAQUE_WIN32_EXT: + local = d3dkmt_open_sync( 0, handle ); + break; + case GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT: + local = d3dkmt_open_sync( PtrToUlong( handle ), NULL ); + break; + default: return set_gl_error( GL_INVALID_ENUM ); + } + fd = d3dkmt_object_get_fd( local ); + d3dkmt_destroy_sync( local ); + if (fd < 0) return set_gl_error( GL_INVALID_VALUE ); + + set_gl_error( funcs->p_glGetError() ); /* save the error in the wrapper so we can check for success */ + funcs->p_glImportSemaphoreFdEXT( semaphore, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd ); + if (!(err = funcs->p_glGetError())) return; + + close( fd ); + set_gl_error( err ); +} + +void win32u_glImportSemaphoreWin32HandleEXT( GLuint semaphore, GLenum type, void *handle ) +{ + TRACE( "semaphore %u type %#x handle %p\n", semaphore, type, handle ); + + if (handle) import_semaphore( semaphore, type, handle, NULL ); + else set_gl_error( GL_INVALID_VALUE ); +} + +void win32u_glImportSemaphoreWin32NameEXT( GLuint semaphore, GLenum type, const void *name ) +{ + HANDLE handle; + + TRACE( "semaphore %u type %#x name %s\n", semaphore, type, debugstr_w( name ) ); + + if (type != GL_HANDLE_TYPE_OPAQUE_WIN32_EXT) set_gl_error( GL_INVALID_ENUM ); + else if (!(handle = open_shared_semaphore_from_name( (const WCHAR *)name ))) set_gl_error( GL_INVALID_VALUE ); + else + { + import_semaphore( semaphore, type, handle, NULL ); + NtClose( handle ); + } +} + static void display_funcs_init(void) { struct egl_platform *egl; @@ -2608,6 +2660,7 @@ static void display_funcs_init(void) USE_GL_FUNC(glGetUnsignedBytei_vEXT) USE_GL_FUNC(glGetUnsignedBytevEXT) USE_GL_FUNC(glImportMemoryFdEXT) + USE_GL_FUNC(glImportSemaphoreFdEXT) USE_GL_FUNC(glNamedFramebufferDrawBuffer) USE_GL_FUNC(glNamedFramebufferReadBuffer) USE_GL_FUNC(glNamedFramebufferRenderbuffer) @@ -2685,6 +2738,11 @@ static void display_funcs_init(void) display_funcs.p_glImportMemoryWin32HandleEXT = win32u_glImportMemoryWin32HandleEXT; display_funcs.p_glImportMemoryWin32NameEXT = win32u_glImportMemoryWin32NameEXT; } + if (display_funcs.p_glImportSemaphoreFdEXT) + { + display_funcs.p_glImportSemaphoreWin32HandleEXT = win32u_glImportSemaphoreWin32HandleEXT; + display_funcs.p_glImportSemaphoreWin32NameEXT = win32u_glImportSemaphoreWin32NameEXT; + }
if (!list_empty( &devices_egl )) { diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index dd8033def73..0faf149aa85 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -4254,7 +4254,7 @@ static struct opengl_device *create_opengl_device( HWND hwnd, LUID *luid ) ptr = find_opengl_extension( extensions, "GL_EXT_memory_object_win32" ); ok_ptr( ptr, !=, NULL ); ptr = find_opengl_extension( extensions, "GL_EXT_semaphore_win32" ); - todo_wine ok_ptr( ptr, !=, NULL ); + ok_ptr( ptr, !=, NULL ); ptr = find_opengl_extension( extensions, "GL_EXT_win32_keyed_mutex" ); dev->broken = !winetest_platform_is_wine && ptr == NULL; /* missing on AMD, as is support for importing D3D handles */
@@ -6414,7 +6414,7 @@ static void test_import_opengl_semaphore( struct opengl_device *dev, const WCHAR if (name) { PFN_glImportSemaphoreWin32NameEXT p_glImportSemaphoreWin32NameEXT = (void *)wglGetProcAddress( "glImportSemaphoreWin32NameEXT" ); - todo_wine ok_ptr( p_glImportSemaphoreWin32NameEXT, !=, NULL ); + ok_ptr( p_glImportSemaphoreWin32NameEXT, !=, NULL ); if (!p_glImportSemaphoreWin32NameEXT) return;
p_glGenSemaphoresEXT( 1, &semaphore ); @@ -6424,7 +6424,7 @@ static void test_import_opengl_semaphore( struct opengl_device *dev, const WCHAR else { PFN_glImportSemaphoreWin32HandleEXT p_glImportSemaphoreWin32HandleEXT = (void *)wglGetProcAddress( "glImportSemaphoreWin32HandleEXT" ); - todo_wine ok_ptr( p_glImportSemaphoreWin32HandleEXT, !=, NULL ); + ok_ptr( p_glImportSemaphoreWin32HandleEXT, !=, NULL ); if (!p_glImportSemaphoreWin32HandleEXT) return;
p_glGenSemaphoresEXT( 1, &semaphore ); @@ -6695,8 +6695,8 @@ static void test_shared_fences(void) if (test == MAKETEST(2, 4)) ok_x4( glGetError(), ==, 0 ); else ok( (gl_err = glGetError()) == 0 || broken(gl_err == GL_INVALID_VALUE) /* NVIDIA */, "glGetError returned %#x\n", gl_err); test_import_opengl_semaphore( opengl_imp, name, handle, GL_HANDLE_TYPE_D3D12_FENCE_EXT ); - if (test != MAKETEST(2, 4)) ok_x4( glGetError(), ==, 0 ); - else ok( (gl_err = glGetError()) == 0 || broken(gl_err == GL_INVALID_VALUE) /* NVIDIA */, "glGetError returned %#x\n", gl_err); + if (test != MAKETEST(2, 4)) todo_wine ok_x4( glGetError(), ==, 0 ); + else todo_wine ok( (gl_err = glGetError()) == 0 || broken(gl_err == GL_INVALID_VALUE) /* NVIDIA */, "glGetError returned %#x\n", gl_err); } }
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index a6b10c8861b..89d916b0793 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -2345,7 +2345,7 @@ static HANDLE create_shared_semaphore_handle( D3DKMT_HANDLE local, const VkExpor return NULL; }
-static HANDLE open_shared_semaphore_from_name( const WCHAR *name ) +HANDLE open_shared_semaphore_from_name( const WCHAR *name ) { D3DKMT_OPENSYNCOBJECTNTHANDLEFROMNAME open_name = {0}; WCHAR bufferW[MAX_PATH * 2]; diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index ec573462ea8..254bd287473 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -209,6 +209,7 @@ extern int d3dkmt_object_get_fd( D3DKMT_HANDLE local ); extern NTSTATUS d3dkmt_destroy_mutex( D3DKMT_HANDLE local );
extern HANDLE open_shared_resource_from_name( const WCHAR *name ); +extern HANDLE open_shared_semaphore_from_name( const WCHAR *name );
extern D3DKMT_HANDLE d3dkmt_create_resource( int fd, D3DKMT_HANDLE *global ); extern D3DKMT_HANDLE d3dkmt_open_resource( D3DKMT_HANDLE global, HANDLE shared, D3DKMT_HANDLE *mutex_local, D3DKMT_HANDLE *sync_local );
This merge request was approved by Rémi Bernon.
Derek Lesho (@dlesho) commented about dlls/win32u/opengl.c:
return NULL;}
+static BOOL win32u_query_renderer( UINT index, UINT attribute, void *value ) +{
- struct egl_platform *egl;
- LUID luid;
- UINT mask;
- TRACE( "index %u, attribute %#x, value %p\n", index, attribute, value );
- if (attribute == GL_NUM_DEVICE_UUIDS_EXT)
- {
*(GLuint *)value = list_count( &devices_egl );
I'm not sure this is correct, as far as I understand the spec, GL_DRIVER_UUID_EXT should only include the devices used for the current context, for situations like multi-gpu.
(https://registry.khronos.org/OpenGL/extensions/EXT/EXT_external_objects.txt) "Because contexts may be associated with multiple physical GPUs in some cases, multiple values are returned for device UUIDs and multiple bits are set in the device node masks."
If I'm not mistaken, this could cause problems for apps following the spec, and failing when there is no Vulkan Device-Group containing every device in the system.
"When sharing with Vulkan device groups, the device UUIDs used by the context must match those of the Vulkan physical devices in the Vulkan device group."