Supersedes !9616 and !9572
-- v3: win32u: Implement glImportSemaphoreWin32(Handle/Name)EXT for opaque handle types. win32u: Implement glImportMemoryWin32(Handle/Name)EXT for opaque handle types.
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 | 1 + dlls/opengl32/unix_thunks.c | 6 ++---- dlls/opengl32/unix_thunks.h | 1 + dlls/opengl32/unix_wgl.c | 19 ++++++++++++++++++ dlls/win32u/opengl.c | 38 +++++++++++++++++++++++++++++++++--- dlls/win32u/tests/d3dkmt.c | 24 ++++++++++------------- include/wine/opengl_driver.h | 1 + 7 files changed, 69 insertions(+), 21 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index c8f6a5a7a49..3c7d65edd89 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -205,6 +205,7 @@ my %manual_unix_thunks = "glGetFramebufferParameterivEXT" => 1, "glGetInteger64v" => 1, "glGetIntegerv" => 1, + "glGetUnsignedBytevEXT" => 1, "glGetString" => 1, "glGetStringi" => 1, "glNamedFramebufferDrawBuffer" => 1, diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 47b3c84623c..429512678e3 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -11537,8 +11537,7 @@ static NTSTATUS ext_glGetUnsignedBytei_vEXT( void *args ) 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; }
@@ -51634,8 +51633,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..99ecd2ae6d6 100644 --- a/dlls/opengl32/unix_thunks.h +++ b/dlls/opengl32/unix_thunks.h @@ -33,6 +33,7 @@ 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_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..e37392549f3 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,29 @@ static BOOL get_integer( TEB *teb, GLenum pname, GLint *data ) if (!read->read_fbo) break; *data = ctx->read_fbo; return TRUE; + case GL_DEVICE_NODE_MASK_EXT: + if (!funcs->p_query_renderer) break; + return funcs->p_query_renderer( pname, data ); }
return get_default_fbo_integer( ctx, draw, read, pname, data ); }
+void wrap_glGetUnsignedBytevEXT( TEB *teb, GLenum pname, GLubyte *data ) +{ + const struct opengl_funcs *funcs = teb->glTable; + + switch (pname) + { + case GL_DEVICE_LUID_EXT: + if (!funcs->p_query_renderer) break; + funcs->p_query_renderer( 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..37c805ee740 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,27 @@ static struct egl_platform *egl_platform_from_index( GLint index ) return NULL; }
+static BOOL win32u_query_renderer( UINT attribute, void *value ) +{ + struct egl_platform *egl = &display_egl; + LUID luid; + UINT mask; + + TRACE( "attribute %#x, value %p\n", attribute, value ); + + switch (attribute) + { + 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 +2532,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 +2609,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..7c71bdcfd26 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 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 e37392549f3..b60d6bd8acf 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; @@ -1262,6 +1267,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; @@ -1301,7 +1308,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 = ""; @@ -1319,6 +1325,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 37c805ee740..536ac399594 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 @@ -2506,6 +2507,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( 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; @@ -2534,6 +2589,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) @@ -2606,6 +2662,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 b60d6bd8acf..4c0e5af8f6d 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; @@ -1268,6 +1270,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) { @@ -1326,6 +1329,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 536ac399594..f0e87651fdd 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -2561,6 +2561,58 @@ static void win32u_glImportMemoryWin32NameEXT( GLuint memory, GLuint64 size, GLe } }
+static void import_semaphore( GLuint semaphore, GLenum type, void *handle ) +{ + 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 ); + 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( name ))) set_gl_error( GL_INVALID_VALUE ); + else + { + import_semaphore( semaphore, type, handle ); + NtClose( handle ); + } +} + static void display_funcs_init(void) { struct egl_platform *egl; @@ -2590,6 +2642,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) @@ -2667,6 +2720,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 );
On Fri Dec 5 12:15:51 2025 +0000, Rémi Bernon wrote:
changed this line in [version 3 of the diff](/wine/wine/-/merge_requests/9690/diffs?diff_id=230152&start_sha=d96121905879b4733ab1020da6367dce3f815639#fcafffe4f28530d849afc9b80bc72edceb68e94e_2564_2564)
Right thanks, also removed some unnecessary casts.