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 4d0a411d9ab..8c48c040174 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 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; @@ -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 );