From: Derek Lesho dlesho@codeweavers.com
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/win32u/opengl.c | 74 ++++++++++++++++++++++++++++++++++++ dlls/win32u/tests/d3dkmt.c | 38 +++++++++--------- dlls/win32u/vulkan.c | 2 +- dlls/win32u/win32u_private.h | 2 + 4 files changed, 96 insertions(+), 20 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 09e2214f2ff..a8b18dc0613 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 @@ -2487,6 +2488,77 @@ static void win32u_glGetUnsignedBytevEXT( GLenum pname, GLubyte *data ) } }
+static void import_memory( GLuint memory, GLuint64 size, GLenum handleType, void *handle, const void *name ) +{ + struct opengl_funcs *funcs = &display_funcs; + + D3DKMT_HANDLE local, mutex, sync; + GLenum err; + int fd; + + switch (handleType) + { + case GL_HANDLE_TYPE_OPAQUE_WIN32_EXT: + if (name) handle = open_shared_resource_from_name( (const WCHAR *)name ); + if (!handle) + { + set_gl_error( NtCurrentTeb(), GL_INVALID_VALUE ); + return; + } + local = d3dkmt_open_resource( 0, handle, &mutex, &sync ); + if (name) NtClose( handle ); + break; + case GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT: + if (!handle) + { + set_gl_error( NtCurrentTeb(), GL_INVALID_VALUE ); + return; + } + local = d3dkmt_open_resource( PtrToUlong( handle ), NULL, &mutex, &sync ); + break; + default: + set_gl_error( NtCurrentTeb(), GL_INVALID_ENUM ); + return; + } + + if (mutex) + d3dkmt_destroy_mutex( mutex ); + if (sync) + d3dkmt_destroy_sync( sync ); + + if ((fd = d3dkmt_object_get_fd( local )) < 0) + { + set_gl_error( NtCurrentTeb(), GL_INVALID_VALUE ); + return; + } + + d3dkmt_destroy_resource( local ); + + set_gl_error( NtCurrentTeb(), funcs->p_glGetError() ); + + funcs->p_glImportMemoryFdEXT( memory, size, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd ); + + if ((err = funcs->p_glGetError()) != GL_NO_ERROR) + { + close( fd ); + set_gl_error( NtCurrentTeb(), err ); + } +} + +static void win32u_glImportMemoryWin32HandleEXT( GLuint memory, GLuint64 size, GLenum handleType, void *handle ) +{ + TRACE( "memory %u size %s handleType %#x handle %p\n", memory, wine_dbgstr_longlong( size ), handleType, handle ); + + return import_memory( memory, size, handleType, handle, NULL ); +} + +static void win32u_glImportMemoryWin32NameEXT( GLuint memory, GLuint64 size, GLenum handleType, const void *name ) +{ + TRACE( "memory %u size %s handleType %#x name %s\n", memory, wine_dbgstr_longlong( size ), handleType, debugstr_w( name ) ); + + return import_memory( memory, size, handleType, NULL, name ); +} + static void display_funcs_init(void) { struct egl_platform *egl; @@ -2591,6 +2663,8 @@ static void display_funcs_init(void) /* EXT_external_objects_win32 */ display_funcs.p_glGetIntegerv = win32u_glGetIntegerv; display_funcs.p_glGetUnsignedBytevEXT = win32u_glGetUnsignedBytevEXT; + display_funcs.p_glImportMemoryWin32HandleEXT = win32u_glImportMemoryWin32HandleEXT; + display_funcs.p_glImportMemoryWin32NameEXT = win32u_glImportMemoryWin32NameEXT;
if (!list_empty( &devices_egl )) { diff --git a/dlls/win32u/tests/d3dkmt.c b/dlls/win32u/tests/d3dkmt.c index f5f6573d0f0..a852c2f45d9 100644 --- a/dlls/win32u/tests/d3dkmt.c +++ b/dlls/win32u/tests/d3dkmt.c @@ -4328,7 +4328,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 ); @@ -4339,7 +4339,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 ); @@ -5701,25 +5701,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; } } @@ -5731,41 +5731,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; } } @@ -5804,7 +5804,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 d0bcffcb458..98436367756 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 0b69ccd481d..5b39b12d6c8 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -209,6 +209,8 @@ extern BOOL get_luid_from_vulkan_uuid( const GUID *uuid, LUID *luid, UINT32 *nod 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 );