From: Derek Lesho <dlesho(a)codeweavers.com> Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com> --- dlls/win32u/opengl.c | 55 ++++++++++++++++++++++++++++++++++++ dlls/win32u/tests/d3dkmt.c | 10 +++---- dlls/win32u/vulkan.c | 2 +- dlls/win32u/win32u_private.h | 1 + 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 7fb82c8263e..1287bb70223 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -2544,6 +2544,59 @@ static void win32u_glImportMemoryWin32NameEXT( GLuint memory, GLuint64 size, GLe import_memory( memory, size, handleType, NULL, name ); } +static void import_semaphore( GLuint semaphore, GLenum handleType, void *handle, const void *name ) +{ + const struct opengl_funcs *funcs = &display_funcs; + D3DKMT_HANDLE local; + GLenum err; + int fd; + + switch (handleType) + { + case GL_HANDLE_TYPE_OPAQUE_WIN32_EXT: + if (name) handle = open_shared_semaphore_from_name( (const WCHAR *)name ); + if (!handle) return set_gl_error( NtCurrentTeb(), GL_INVALID_VALUE ); + local = d3dkmt_open_sync( 0, handle ); + if (name) NtClose( handle ); + break; + case GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT: + if (!handle) return set_gl_error( NtCurrentTeb(), GL_INVALID_VALUE ); + local = d3dkmt_open_sync( PtrToUlong( handle ), NULL ); + break; + default: + return set_gl_error( NtCurrentTeb(), GL_INVALID_ENUM); + } + + if ((fd = d3dkmt_object_get_fd( local )) < 0) + return set_gl_error( NtCurrentTeb(), GL_INVALID_VALUE ); + + d3dkmt_destroy_sync( local ); + + set_gl_error( NtCurrentTeb(), funcs->p_glGetError() ); + + funcs->p_glImportSemaphoreFdEXT( semaphore, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd ); + + if ((err = funcs->p_glGetError()) != GL_NO_ERROR) + { + close(fd); + set_gl_error( NtCurrentTeb(), err ); + } +} + +void win32u_glImportSemaphoreWin32HandleEXT( GLuint semaphore, GLenum handleType, void *handle ) +{ + TRACE( "semaphore %u handleType %#x handle %p\n", semaphore, handleType, handle ); + + import_semaphore( semaphore, handleType, handle, NULL ); +} + +void win32u_glImportSemaphoreWin32NameEXT( GLuint semaphore, GLenum handleType, const void *name ) +{ + TRACE( "semaphore %u handleType %#x name %s\n", semaphore, handleType, debugstr_w( name ) ); + + import_semaphore( semaphore, handleType, NULL, name ); +} + static void display_funcs_init(void) { struct egl_platform *egl; @@ -2650,6 +2703,8 @@ static void display_funcs_init(void) display_funcs.p_glGetUnsignedBytevEXT = win32u_glGetUnsignedBytevEXT; display_funcs.p_glImportMemoryWin32HandleEXT = win32u_glImportMemoryWin32HandleEXT; display_funcs.p_glImportMemoryWin32NameEXT = win32u_glImportMemoryWin32NameEXT; + 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 a852c2f45d9..07afdb08ca4 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 ) ptr = find_opengl_extension( extensions, "GL_EXT_memory_object_win32" ); todo_wine 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 */ @@ -6418,7 +6418,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 ); @@ -6428,7 +6428,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 ); @@ -6699,8 +6699,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 98436367756..b1ca12f6be5 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 5b39b12d6c8..627b21c21ac 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -210,6 +210,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 ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9616