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