[PATCH v2 0/5] MR11226: opengl32: Isolate WOW64 buffer storage in WOW64 code.
Using win32u to initialize the vulkan device, and allowing us to use the vulkan_driver.h interface. -- v2: opengl32: Reduce WOW64 locking to the buffer storage map accesses. opengl32: Use an array instead of rb_tree for the buffer storage map. opengl32: Use a static variable for the buffer storage map. opengl32: Move more wow64 wrappers out of the generated code. opengl32: Flag GL_EXT_external_buffer extension as unsupported. https://gitlab.winehq.org/wine/wine/-/merge_requests/11226
From: Rémi Bernon <rbernon@codeweavers.com> It is EGL specific. --- dlls/opengl32/make_opengl | 3 +- dlls/opengl32/thunks.c | 21 ----------- dlls/opengl32/unix_thunks.c | 72 ------------------------------------- dlls/opengl32/unixlib.h | 22 ------------ include/wine/wgl.h | 5 --- 5 files changed, 1 insertion(+), 122 deletions(-) diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index fcca05838bf..9824efd3375 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -301,14 +301,12 @@ my %wow64_invalidate_buffer = "glBufferData" => 1, "glBufferDataARB" => 1, "glBufferStorage" => 1, - "glBufferStorageExternalEXT" => 1, "glBufferStorageMemEXT" => 1, "glNamedBufferAttachMemoryNV" => 1, "glNamedBufferData" => 1, "glNamedBufferDataEXT" => 1, "glNamedBufferStorage" => 1, "glNamedBufferStorageEXT" => 1, - "glNamedBufferStorageExternalEXT" => 1, "glNamedBufferStorageMemEXT" => 1, ); my %pointer_array_count = @@ -1106,6 +1104,7 @@ my %unsupported_extgroups = ); my %unsupported_extensions = ( + "GL_EXT_external_buffer" => 1, "WGL_AMD_gpu_association" => 1, "WGL_ARB_buffer_region" => 1, "WGL_EXT_display_color_table" => 1, diff --git a/dlls/opengl32/thunks.c b/dlls/opengl32/thunks.c index 1c471268d8b..3083ad3ad60 100644 --- a/dlls/opengl32/thunks.c +++ b/dlls/opengl32/thunks.c @@ -4022,14 +4022,6 @@ static void WINAPI glBufferStorage( GLenum target, GLsizeiptr size, const void * if ((status = UNIX_CALL( glBufferStorage, &args ))) WARN( "glBufferStorage returned %#lx\n", status ); } -static void WINAPI glBufferStorageExternalEXT( GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags ) -{ - struct glBufferStorageExternalEXT_params args = { .teb = NtCurrentTeb(), .target = target, .offset = offset, .size = size, .clientBuffer = clientBuffer, .flags = flags }; - NTSTATUS status; - TRACE( "target %d, offset %Id, size %Id, clientBuffer %p, flags %d\n", target, offset, size, clientBuffer, flags ); - if ((status = UNIX_CALL( glBufferStorageExternalEXT, &args ))) WARN( "glBufferStorageExternalEXT returned %#lx\n", status ); -} - static void WINAPI glBufferStorageMemEXT( GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset ) { struct glBufferStorageMemEXT_params args = { .teb = NtCurrentTeb(), .target = target, .size = size, .offset = offset }; @@ -15220,15 +15212,6 @@ static void WINAPI glNamedBufferStorageEXT( GLuint buffer, GLsizeiptr size, cons if ((status = UNIX_CALL( glNamedBufferStorageEXT, &args ))) WARN( "glNamedBufferStorageEXT returned %#lx\n", status ); } -static void WINAPI glNamedBufferStorageExternalEXT( GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags ) -{ - struct glNamedBufferStorageExternalEXT_params args = { .teb = NtCurrentTeb(), .offset = offset, .size = size, .clientBuffer = clientBuffer, .flags = flags }; - NTSTATUS status; - TRACE( "buffer %d, offset %Id, size %Id, clientBuffer %p, flags %d\n", buffer, offset, size, clientBuffer, flags ); - args.buffer = *map_context_objects( OBJ_TYPE_BUFFER, 1, &buffer ); - if ((status = UNIX_CALL( glNamedBufferStorageExternalEXT, &args ))) WARN( "glNamedBufferStorageExternalEXT returned %#lx\n", status ); -} - static void WINAPI glNamedBufferStorageMemEXT( GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset ) { struct glNamedBufferStorageMemEXT_params args = { .teb = NtCurrentTeb(), .size = size, .offset = offset }; @@ -26248,7 +26231,6 @@ const void *extension_procs[] = glBufferParameteriAPPLE, glBufferRegionEnabled, glBufferStorage, - glBufferStorageExternalEXT, glBufferStorageMemEXT, glBufferSubData, glBufferSubDataARB, @@ -27569,7 +27551,6 @@ const void *extension_procs[] = glNamedBufferPageCommitmentMemNV, glNamedBufferStorage, glNamedBufferStorageEXT, - glNamedBufferStorageExternalEXT, glNamedBufferStorageMemEXT, glNamedBufferSubData, glNamedBufferSubDataEXT, @@ -29009,7 +28990,6 @@ const struct registry_entry extension_registry[] = { "glBufferParameteriAPPLE", glBufferParameteriAPPLE, 0, 0, { GL_APPLE_flush_buffer_range, GL_EXTENSION_COUNT }}, { "glBufferRegionEnabled", glBufferRegionEnabled, 0, 0, { GL_KTX_buffer_region, GL_EXTENSION_COUNT }}, { "glBufferStorage", glBufferStorage, 4, 4, { GL_ARB_buffer_storage, GL_EXTENSION_COUNT }}, - { "glBufferStorageExternalEXT", glBufferStorageExternalEXT, 0, 0, { GL_EXT_external_buffer, GL_EXTENSION_COUNT }}, { "glBufferStorageMemEXT", glBufferStorageMemEXT, 0, 0, { GL_EXT_memory_object, GL_EXTENSION_COUNT }}, { "glBufferSubData", glBufferSubData, 1, 5, { GL_EXTENSION_COUNT }}, { "glBufferSubDataARB", glBufferSubDataARB, 0, 0, { GL_ARB_vertex_buffer_object, GL_EXTENSION_COUNT }}, @@ -30330,7 +30310,6 @@ const struct registry_entry extension_registry[] = { "glNamedBufferPageCommitmentMemNV", glNamedBufferPageCommitmentMemNV, 0, 0, { GL_NV_memory_object_sparse, GL_EXTENSION_COUNT }}, { "glNamedBufferStorage", glNamedBufferStorage, 4, 5, { GL_ARB_direct_state_access, GL_EXTENSION_COUNT }}, { "glNamedBufferStorageEXT", glNamedBufferStorageEXT, 0, 0, { GL_EXT_direct_state_access, GL_EXTENSION_COUNT }}, - { "glNamedBufferStorageExternalEXT", glNamedBufferStorageExternalEXT, 0, 0, { GL_EXT_external_buffer, GL_EXTENSION_COUNT }}, { "glNamedBufferStorageMemEXT", glNamedBufferStorageMemEXT, 0, 0, { GL_EXT_memory_object, GL_EXTENSION_COUNT }}, { "glNamedBufferSubData", glNamedBufferSubData, 4, 5, { GL_ARB_direct_state_access, GL_EXTENSION_COUNT }}, { "glNamedBufferSubDataEXT", glNamedBufferSubDataEXT, 0, 0, { GL_EXT_direct_state_access, GL_EXTENSION_COUNT }}, diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 1d3f8a8dbd3..04b6b25bfd5 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -4818,16 +4818,6 @@ static NTSTATUS ext_glBufferStorage( void *args ) return STATUS_SUCCESS; } -static NTSTATUS ext_glBufferStorageExternalEXT( void *args ) -{ - struct glBufferStorageExternalEXT_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - if (!funcs->p_glBufferStorageExternalEXT) return STATUS_NOT_IMPLEMENTED; - funcs->p_glBufferStorageExternalEXT( params->target, params->offset, params->size, params->clientBuffer, params->flags ); - set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); - return STATUS_SUCCESS; -} - static NTSTATUS ext_glBufferStorageMemEXT( void *args ) { struct glBufferStorageMemEXT_params *params = args; @@ -17627,16 +17617,6 @@ static NTSTATUS ext_glNamedBufferStorageEXT( void *args ) return STATUS_SUCCESS; } -static NTSTATUS ext_glNamedBufferStorageExternalEXT( void *args ) -{ - struct glNamedBufferStorageExternalEXT_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - if (!funcs->p_glNamedBufferStorageExternalEXT) return STATUS_NOT_IMPLEMENTED; - funcs->p_glNamedBufferStorageExternalEXT( params->buffer, params->offset, params->size, params->clientBuffer, params->flags ); - set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); - return STATUS_SUCCESS; -} - static NTSTATUS ext_glNamedBufferStorageMemEXT( void *args ) { struct glNamedBufferStorageMemEXT_params *params = args; @@ -31006,7 +30986,6 @@ const unixlib_entry_t __wine_unix_call_funcs[] = ext_glBufferParameteriAPPLE, ext_glBufferRegionEnabled, ext_glBufferStorage, - ext_glBufferStorageExternalEXT, ext_glBufferStorageMemEXT, ext_glBufferSubData, ext_glBufferSubDataARB, @@ -32327,7 +32306,6 @@ const unixlib_entry_t __wine_unix_call_funcs[] = ext_glNamedBufferPageCommitmentMemNV, ext_glNamedBufferStorage, ext_glNamedBufferStorageEXT, - ext_glNamedBufferStorageExternalEXT, ext_glNamedBufferStorageMemEXT, ext_glNamedBufferSubData, ext_glNamedBufferSubDataEXT, @@ -41649,30 +41627,6 @@ static NTSTATUS wow64_ext_glBufferStorage( void *args ) return STATUS_SUCCESS; } -static NTSTATUS wow64_ext_glBufferStorageExternalEXT( void *args ) -{ - struct - { - PTR32 teb; - GLenum target; - PTR32 offset; - PTR32 size; - PTR32 clientBuffer; - GLbitfield flags; - } *params = args; - TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; - const struct opengl_funcs *funcs = teb->glTable; - if (!funcs->p_glBufferStorageExternalEXT) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_target( teb, params->target ); - funcs->p_glBufferStorageExternalEXT( params->target, (GLintptr)ULongToPtr(params->offset), (GLsizeiptr)ULongToPtr(params->size), ULongToPtr(params->clientBuffer), params->flags ); - pthread_mutex_unlock( &wgl_lock ); - set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); - return STATUS_SUCCESS; -} - static NTSTATUS wow64_ext_glBufferStorageMemEXT( void *args ) { struct @@ -64353,30 +64307,6 @@ static NTSTATUS wow64_ext_glNamedBufferStorageEXT( void *args ) return STATUS_SUCCESS; } -static NTSTATUS wow64_ext_glNamedBufferStorageExternalEXT( void *args ) -{ - struct - { - PTR32 teb; - GLuint buffer; - PTR32 offset; - PTR32 size; - PTR32 clientBuffer; - GLbitfield flags; - } *params = args; - TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; - const struct opengl_funcs *funcs = teb->glTable; - if (!funcs->p_glNamedBufferStorageExternalEXT) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_name( teb, params->buffer ); - funcs->p_glNamedBufferStorageExternalEXT( params->buffer, (GLintptr)ULongToPtr(params->offset), (GLsizeiptr)ULongToPtr(params->size), ULongToPtr(params->clientBuffer), params->flags ); - pthread_mutex_unlock( &wgl_lock ); - set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); - return STATUS_SUCCESS; -} - static NTSTATUS wow64_ext_glNamedBufferStorageMemEXT( void *args ) { struct @@ -87322,7 +87252,6 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = wow64_ext_glBufferParameteriAPPLE, wow64_ext_glBufferRegionEnabled, wow64_ext_glBufferStorage, - wow64_ext_glBufferStorageExternalEXT, wow64_ext_glBufferStorageMemEXT, wow64_ext_glBufferSubData, wow64_ext_glBufferSubDataARB, @@ -88643,7 +88572,6 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = wow64_ext_glNamedBufferPageCommitmentMemNV, wow64_ext_glNamedBufferStorage, wow64_ext_glNamedBufferStorageEXT, - wow64_ext_glNamedBufferStorageExternalEXT, wow64_ext_glNamedBufferStorageMemEXT, wow64_ext_glNamedBufferSubData, wow64_ext_glNamedBufferSubDataEXT, diff --git a/dlls/opengl32/unixlib.h b/dlls/opengl32/unixlib.h index 8f5f6391bbe..6df1d2fafd4 100644 --- a/dlls/opengl32/unixlib.h +++ b/dlls/opengl32/unixlib.h @@ -3699,16 +3699,6 @@ struct glBufferStorage_params GLbitfield flags; }; -struct glBufferStorageExternalEXT_params -{ - TEB *teb; - GLenum target; - GLintptr offset; - GLsizeiptr size; - GLeglClientBufferEXT clientBuffer; - GLbitfield flags; -}; - struct glBufferStorageMemEXT_params { TEB *teb; @@ -14898,16 +14888,6 @@ struct glNamedBufferStorageEXT_params GLbitfield flags; }; -struct glNamedBufferStorageExternalEXT_params -{ - TEB *teb; - GLuint buffer; - GLintptr offset; - GLsizeiptr size; - GLeglClientBufferEXT clientBuffer; - GLbitfield flags; -}; - struct glNamedBufferStorageMemEXT_params { TEB *teb; @@ -26293,7 +26273,6 @@ enum unix_funcs unix_glBufferParameteriAPPLE, unix_glBufferRegionEnabled, unix_glBufferStorage, - unix_glBufferStorageExternalEXT, unix_glBufferStorageMemEXT, unix_glBufferSubData, unix_glBufferSubDataARB, @@ -27614,7 +27593,6 @@ enum unix_funcs unix_glNamedBufferPageCommitmentMemNV, unix_glNamedBufferStorage, unix_glNamedBufferStorageEXT, - unix_glNamedBufferStorageExternalEXT, unix_glNamedBufferStorageMemEXT, unix_glNamedBufferSubData, unix_glNamedBufferSubDataEXT, diff --git a/include/wine/wgl.h b/include/wine/wgl.h index 3b46ee51b87..36df3a2d5ee 100644 --- a/include/wine/wgl.h +++ b/include/wine/wgl.h @@ -7880,7 +7880,6 @@ typedef void (GLAPIENTRY *PFN_glBufferParameteriAPPLE)( GLenum target, GLe typedef GLuint (GLAPIENTRY *PFN_glBufferRegionEnabled)(void); typedef void (GLAPIENTRY *PFN_glBufferStorage)( GLenum target, GLsizeiptr size, const void *data, GLbitfield flags ); typedef void (GLAPIENTRY *PFN_glBufferStorageEXT)( GLenum target, GLsizeiptr size, const void *data, GLbitfield flags ); -typedef void (GLAPIENTRY *PFN_glBufferStorageExternalEXT)( GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags ); typedef void (GLAPIENTRY *PFN_glBufferStorageMemEXT)( GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset ); typedef void (GLAPIENTRY *PFN_glBufferSubData)( GLenum target, GLintptr offset, GLsizeiptr size, const void *data ); typedef void (GLAPIENTRY *PFN_glBufferSubDataARB)( GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data ); @@ -9353,7 +9352,6 @@ typedef void (GLAPIENTRY *PFN_glNamedBufferPageCommitmentEXT)( GLuint buff typedef void (GLAPIENTRY *PFN_glNamedBufferPageCommitmentMemNV)( GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit ); typedef void (GLAPIENTRY *PFN_glNamedBufferStorage)( GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags ); typedef void (GLAPIENTRY *PFN_glNamedBufferStorageEXT)( GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags ); -typedef void (GLAPIENTRY *PFN_glNamedBufferStorageExternalEXT)( GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags ); typedef void (GLAPIENTRY *PFN_glNamedBufferStorageMemEXT)( GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset ); typedef void (GLAPIENTRY *PFN_glNamedBufferSubData)( GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data ); typedef void (GLAPIENTRY *PFN_glNamedBufferSubDataEXT)( GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data ); @@ -11444,7 +11442,6 @@ typedef BOOL (GLAPIENTRY *PFN_wglSwapIntervalEXT)( int interval ); USE_GL_EXT(GL_EXT_draw_buffers2) \ USE_GL_EXT(GL_EXT_draw_instanced) \ USE_GL_EXT(GL_EXT_draw_range_elements) \ - USE_GL_EXT(GL_EXT_external_buffer) \ USE_GL_EXT(GL_EXT_float_blend) \ USE_GL_EXT(GL_EXT_fog_coord) \ USE_GL_EXT(GL_EXT_frag_depth) \ @@ -12434,7 +12431,6 @@ typedef BOOL (GLAPIENTRY *PFN_wglSwapIntervalEXT)( int interval ); USE_GL_FUNC(glBufferRegionEnabled) \ USE_GL_FUNC(glBufferStorage) \ USE_GL_FUNC(glBufferStorageEXT) \ - USE_GL_FUNC(glBufferStorageExternalEXT) \ USE_GL_FUNC(glBufferStorageMemEXT) \ USE_GL_FUNC(glBufferSubData) \ USE_GL_FUNC(glBufferSubDataARB) \ @@ -13907,7 +13903,6 @@ typedef BOOL (GLAPIENTRY *PFN_wglSwapIntervalEXT)( int interval ); USE_GL_FUNC(glNamedBufferPageCommitmentMemNV) \ USE_GL_FUNC(glNamedBufferStorage) \ USE_GL_FUNC(glNamedBufferStorageEXT) \ - USE_GL_FUNC(glNamedBufferStorageExternalEXT) \ USE_GL_FUNC(glNamedBufferStorageMemEXT) \ USE_GL_FUNC(glNamedBufferSubData) \ USE_GL_FUNC(glNamedBufferSubDataEXT) \ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11226
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/make_opengl | 39 ++--------- dlls/opengl32/unix_private.h | 5 -- dlls/opengl32/unix_thunks.c | 71 +++----------------- dlls/opengl32/unix_thunks.h | 6 ++ dlls/opengl32/unix_wgl.c | 127 +++++++++++++++++++++++++---------- 5 files changed, 110 insertions(+), 138 deletions(-) diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 9824efd3375..e9b584859c5 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -276,8 +276,9 @@ sub map_default_fbo($$) sub manual_wow64_wrapper($) { my $name = shift; - return 0 if $name =~ /^glBufferStorageExternal/; - return 0 if $name =~ /^glBufferStorageMem/; + return "glBufferAttachMemoryNV" if $name =~ /^glBufferAttachMemory/; + return "glBufferData" if $name =~ /^glBufferData/; + return "glBufferStorageMemEXT" if $name =~ /^glBufferStorageMem/; return "glBufferStorage" if $name =~ /^glBufferStorage/; return "glDeleteBuffers" if $name =~ /^glDeleteBuffers/; return "glFlushMappedBufferRange" if $name =~ /^glFlushMappedBufferRange/; @@ -288,27 +289,14 @@ sub manual_wow64_wrapper($) return "glMapBuffer" if $name =~ /^glMapBuffer/; return "glMapNamedBufferRange" if $name =~ /^glMapNamedBufferRange/; return "glMapNamedBuffer" if $name =~ /^glMapNamedBuffer/; - return 0 if $name =~ /^glNamedBufferStorageExternal/; - return 0 if $name =~ /^glNamedBufferStorageMem/; + return "glNamedBufferAttachMemoryNV" if $name =~ /^glNamedBufferAttachMemory/; + return "glNamedBufferData" if $name =~ /^glNamedBufferData/; + return "glNamedBufferStorageMemEXT" if $name =~ /^glNamedBufferStorageMem/; return "glNamedBufferStorage" if $name =~ /^glNamedBufferStorage/; return "glUnmapBuffer" if $name =~ /^glUnmapBuffer/; return "glUnmapNamedBuffer" if $name =~ /^glUnmapNamedBuffer/; } -my %wow64_invalidate_buffer = - ( - "glBufferAttachMemoryNV" => 1, - "glBufferData" => 1, - "glBufferDataARB" => 1, - "glBufferStorage" => 1, - "glBufferStorageMemEXT" => 1, - "glNamedBufferAttachMemoryNV" => 1, - "glNamedBufferData" => 1, - "glNamedBufferDataEXT" => 1, - "glNamedBufferStorage" => 1, - "glNamedBufferStorageEXT" => 1, - "glNamedBufferStorageMemEXT" => 1, - ); my %pointer_array_count = ( "glCompileShaderIncludeARB" => "count", @@ -410,11 +398,9 @@ sub generate_unix_thunk($$$$) my $func_ret = get_func_ret( $func ); my $wow64_wrap = $is_wow64 ? manual_wow64_wrapper( $name ) : 0; my $wrapper = $wow64_wrap || needs_wrapper( $name, $func ); - my $need_lock = 0; my $need_funcs = !$wrapper || $name !~ /^wgl/; my $teb = $is_wow64 ? "teb" : "params->teb"; my $ret_stat = "return STATUS_SUCCESS;"; - my $invalidation = ""; my $input_conv = ""; my $output_conv = ""; my $use_pbuffer = 0; @@ -495,7 +481,6 @@ sub generate_unix_thunk($$$$) { $call_args .= " ULongToPtr(params->$pname),"; $need_manual_thunk = 1 if $arg_type =~ /(\*.*\*|(sizei|int)ptr.*\*)/; - $need_lock = 1 if $arg_type =~ /GLsync/; } } $call_args .= " UlongToHandle( params->ret )," if $func_ret =~ /HPBUFFERARB|HGLRC|GLsync/; @@ -524,16 +509,6 @@ sub generate_unix_thunk($$$$) $ret .= "}\n\n"; return $ret; } - if (defined $wow64_invalidate_buffer{$name}) - { - $need_lock = 1; - $need_funcs = 1; - $vars .= " struct buffer *buffer;\n"; - $invalidation .= $name =~ /NamedBuffer/ - ? " buffer = invalidate_buffer_name( $teb, params->buffer );\n" - : " buffer = invalidate_buffer_target( $teb, params->target );\n"; - $output_conv .= " if (buffer) free_buffer( funcs, buffer );\n"; - } $ret .= " TEB *teb = get_teb64( params->teb );\n" if $wrapper || (!$use_dc && !$use_pbuffer && !$use_context); } else @@ -597,7 +572,6 @@ sub generate_unix_thunk($$$$) } $ret .= " resolve_default_fbo( $teb, TRUE );\n" if resolve_default_fbo( $name ); $ret .= " push_default_fbo( $teb );\n" if hide_default_fbo( $name ); - $ret .= " pthread_mutex_lock( &wgl_lock );\n$invalidation" if $need_lock; $ret .= " $ret_expr"; if ($wow64_wrap) { @@ -614,7 +588,6 @@ sub generate_unix_thunk($$$$) $call_args =~ s/,$/ /; $ret .= "funcs->p_$name($call_args);\n"; } - $ret .= " pthread_mutex_unlock( &wgl_lock );\n" if $need_lock; $ret .= " set_current_fbo( $teb, params->target, params->framebuffer );\n" if $name =~ /glBindFramebuffer/; $ret .= " pop_default_fbo( $teb );\n" if hide_default_fbo( $name ); if (defined $state_attrib_funcs{$name}) diff --git a/dlls/opengl32/unix_private.h b/dlls/opengl32/unix_private.h index 8f05f6218e7..10722acf7ec 100644 --- a/dlls/opengl32/unix_private.h +++ b/dlls/opengl32/unix_private.h @@ -81,15 +81,10 @@ static inline TEB *get_teb64( ULONG teb32 ) return (TEB *)((char *)teb32_ptr + teb32_ptr->WowTebOffset); } -extern struct buffer *invalidate_buffer_name( TEB *teb, GLuint name ); -extern struct buffer *invalidate_buffer_target( TEB *teb, GLenum target ); -extern void free_buffer( const struct opengl_funcs *funcs, struct buffer *buffer ); extern NTSTATUS return_wow64_string( const void *str, PTR32 *wow64_str ); #endif -extern pthread_mutex_t wgl_lock; - extern NTSTATUS process_attach( void *args ); extern NTSTATUS thread_attach( void *args ); extern NTSTATUS process_detach( void *args ); diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 04b6b25bfd5..ee35199ffc0 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -41476,15 +41476,10 @@ static NTSTATUS wow64_ext_glBufferAttachMemoryNV( void *args ) GLuint64 offset; } *params = args; TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glBufferAttachMemoryNV) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_target( teb, params->target ); - funcs->p_glBufferAttachMemoryNV( params->target, params->memory, params->offset ); - pthread_mutex_unlock( &wgl_lock ); + wow64_glBufferAttachMemoryNV( teb, params->target, params->memory, params->offset, funcs->p_glBufferAttachMemoryNV ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); return STATUS_SUCCESS; } @@ -41499,15 +41494,10 @@ static NTSTATUS wow64_ext_glBufferData( void *args ) GLenum usage; } *params = args; TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glBufferData) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_target( teb, params->target ); - funcs->p_glBufferData( params->target, (GLsizeiptr)ULongToPtr(params->size), ULongToPtr(params->data), params->usage ); - pthread_mutex_unlock( &wgl_lock ); + wow64_glBufferData( teb, params->target, (GLsizeiptr)ULongToPtr(params->size), ULongToPtr(params->data), params->usage, funcs->p_glBufferData ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); return STATUS_SUCCESS; } @@ -41522,15 +41512,10 @@ static NTSTATUS wow64_ext_glBufferDataARB( void *args ) GLenum usage; } *params = args; TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glBufferDataARB) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_target( teb, params->target ); - funcs->p_glBufferDataARB( params->target, (GLsizeiptrARB)ULongToPtr(params->size), ULongToPtr(params->data), params->usage ); - pthread_mutex_unlock( &wgl_lock ); + wow64_glBufferData( teb, params->target, (GLsizeiptrARB)ULongToPtr(params->size), ULongToPtr(params->data), params->usage, funcs->p_glBufferDataARB ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); return STATUS_SUCCESS; } @@ -41615,15 +41600,10 @@ static NTSTATUS wow64_ext_glBufferStorage( void *args ) GLbitfield flags; } *params = args; TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glBufferStorage) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_target( teb, params->target ); wow64_glBufferStorage( teb, params->target, (GLsizeiptr)ULongToPtr(params->size), ULongToPtr(params->data), params->flags, funcs->p_glBufferStorage ); - pthread_mutex_unlock( &wgl_lock ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); return STATUS_SUCCESS; } @@ -41638,15 +41618,10 @@ static NTSTATUS wow64_ext_glBufferStorageMemEXT( void *args ) GLuint64 offset; } *params = args; TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glBufferStorageMemEXT) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_target( teb, params->target ); - funcs->p_glBufferStorageMemEXT( params->target, (GLsizeiptr)ULongToPtr(params->size), params->memory, params->offset ); - pthread_mutex_unlock( &wgl_lock ); + wow64_glBufferStorageMemEXT( teb, params->target, (GLsizeiptr)ULongToPtr(params->size), params->memory, params->offset, funcs->p_glBufferStorageMemEXT ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); return STATUS_SUCCESS; } @@ -64147,15 +64122,10 @@ static NTSTATUS wow64_ext_glNamedBufferAttachMemoryNV( void *args ) GLuint64 offset; } *params = args; TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glNamedBufferAttachMemoryNV) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_name( teb, params->buffer ); - funcs->p_glNamedBufferAttachMemoryNV( params->buffer, params->memory, params->offset ); - pthread_mutex_unlock( &wgl_lock ); + wow64_glNamedBufferAttachMemoryNV( teb, params->buffer, params->memory, params->offset, funcs->p_glNamedBufferAttachMemoryNV ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); return STATUS_SUCCESS; } @@ -64170,15 +64140,10 @@ static NTSTATUS wow64_ext_glNamedBufferData( void *args ) GLenum usage; } *params = args; TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glNamedBufferData) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_name( teb, params->buffer ); - funcs->p_glNamedBufferData( params->buffer, (GLsizeiptr)ULongToPtr(params->size), ULongToPtr(params->data), params->usage ); - pthread_mutex_unlock( &wgl_lock ); + wow64_glNamedBufferData( teb, params->buffer, (GLsizeiptr)ULongToPtr(params->size), ULongToPtr(params->data), params->usage, funcs->p_glNamedBufferData ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); return STATUS_SUCCESS; } @@ -64193,15 +64158,10 @@ static NTSTATUS wow64_ext_glNamedBufferDataEXT( void *args ) GLenum usage; } *params = args; TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glNamedBufferDataEXT) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_name( teb, params->buffer ); - funcs->p_glNamedBufferDataEXT( params->buffer, (GLsizeiptr)ULongToPtr(params->size), ULongToPtr(params->data), params->usage ); - pthread_mutex_unlock( &wgl_lock ); + wow64_glNamedBufferData( teb, params->buffer, (GLsizeiptr)ULongToPtr(params->size), ULongToPtr(params->data), params->usage, funcs->p_glNamedBufferDataEXT ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); return STATUS_SUCCESS; } @@ -64272,15 +64232,10 @@ static NTSTATUS wow64_ext_glNamedBufferStorage( void *args ) GLbitfield flags; } *params = args; TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glNamedBufferStorage) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_name( teb, params->buffer ); wow64_glNamedBufferStorage( teb, params->buffer, (GLsizeiptr)ULongToPtr(params->size), ULongToPtr(params->data), params->flags, funcs->p_glNamedBufferStorage ); - pthread_mutex_unlock( &wgl_lock ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); return STATUS_SUCCESS; } @@ -64295,15 +64250,10 @@ static NTSTATUS wow64_ext_glNamedBufferStorageEXT( void *args ) GLbitfield flags; } *params = args; TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glNamedBufferStorageEXT) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_name( teb, params->buffer ); wow64_glNamedBufferStorage( teb, params->buffer, (GLsizeiptr)ULongToPtr(params->size), ULongToPtr(params->data), params->flags, funcs->p_glNamedBufferStorageEXT ); - pthread_mutex_unlock( &wgl_lock ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); return STATUS_SUCCESS; } @@ -64318,15 +64268,10 @@ static NTSTATUS wow64_ext_glNamedBufferStorageMemEXT( void *args ) GLuint64 offset; } *params = args; TEB *teb = get_teb64( params->teb ); - struct buffer *buffer; const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glNamedBufferStorageMemEXT) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_name( teb, params->buffer ); - funcs->p_glNamedBufferStorageMemEXT( params->buffer, (GLsizeiptr)ULongToPtr(params->size), params->memory, params->offset ); - pthread_mutex_unlock( &wgl_lock ); + wow64_glNamedBufferStorageMemEXT( teb, params->buffer, (GLsizeiptr)ULongToPtr(params->size), params->memory, params->offset, funcs->p_glNamedBufferStorageMemEXT ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); - if (buffer) free_buffer( funcs, buffer ); return STATUS_SUCCESS; } diff --git a/dlls/opengl32/unix_thunks.h b/dlls/opengl32/unix_thunks.h index bc83223cdef..1ba8ad4c5a0 100644 --- a/dlls/opengl32/unix_thunks.h +++ b/dlls/opengl32/unix_thunks.h @@ -39,7 +39,10 @@ extern HPBUFFERARB wrap_wglCreatePbufferARB( TEB *teb, HDC hDC, int iPixelFormat extern BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC hDrawDC, HDC hReadDC, HGLRC hglrc ); #ifdef _WIN64 +extern void wow64_glBufferAttachMemoryNV( TEB *teb, GLenum target, GLuint memory, GLuint64 offset, PFN_glBufferAttachMemoryNV func ); +extern void wow64_glBufferData( TEB *teb, GLenum target, GLsizeiptr size, const void *data, GLenum usage, PFN_glBufferData func ); extern void wow64_glBufferStorage( TEB *teb, GLenum target, GLsizeiptr size, const void *data, GLbitfield flags, PFN_glBufferStorage func ); +extern void wow64_glBufferStorageMemEXT( TEB *teb, GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset, PFN_glBufferStorageMemEXT func ); extern void wow64_glDeleteBuffers( TEB *teb, GLsizei n, const GLuint *buffers, PFN_glDeleteBuffers func ); extern void wow64_glFlushMappedBufferRange( TEB *teb, GLenum target, GLintptr offset, GLsizeiptr length, PFN_glFlushMappedBufferRange func ); extern void wow64_glFlushMappedNamedBufferRange( TEB *teb, GLuint buffer, GLintptr offset, GLsizeiptr length, PFN_glFlushMappedNamedBufferRange func ); @@ -49,7 +52,10 @@ extern void *wow64_glMapBuffer( TEB *teb, GLenum target, GLenum access, PFN_glMa extern void *wow64_glMapBufferRange( TEB *teb, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, PFN_glMapBufferRange func ); extern void *wow64_glMapNamedBuffer( TEB *teb, GLuint buffer, GLenum access, PFN_glMapNamedBuffer func ); extern void *wow64_glMapNamedBufferRange( TEB *teb, GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access, PFN_glMapNamedBufferRange func ); +extern void wow64_glNamedBufferAttachMemoryNV( TEB *teb, GLuint buffer, GLuint memory, GLuint64 offset, PFN_glNamedBufferAttachMemoryNV func ); +extern void wow64_glNamedBufferData( TEB *teb, GLuint buffer, GLsizeiptr size, const void *data, GLenum usage, PFN_glNamedBufferData func ); extern void wow64_glNamedBufferStorage( TEB *teb, GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags, PFN_glNamedBufferStorage func ); +extern void wow64_glNamedBufferStorageMemEXT( TEB *teb, GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset, PFN_glNamedBufferStorageMemEXT func ); extern GLboolean wow64_glUnmapBuffer( TEB *teb, GLenum target, PFN_glUnmapBuffer func ); extern GLboolean wow64_glUnmapNamedBuffer( TEB *teb, GLuint buffer, PFN_glUnmapNamedBuffer func ); #endif diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 9786a32e209..5f5fae6a2a1 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -53,7 +53,6 @@ static BOOL is_wow64(void) } static UINT64 call_gl_debug_message_callback; -pthread_mutex_t wgl_lock = PTHREAD_MUTEX_INITIALIZER; /* context state management */ @@ -397,7 +396,7 @@ static int compare_buffer_name( const void *key, const struct rb_entry *entry ) return memcmp( key, &buffer->name, sizeof(buffer->name) ); } -void free_buffer( const struct opengl_funcs *funcs, struct buffer *buffer ) +static void free_buffer( const struct opengl_funcs *funcs, struct buffer *buffer ) { if (buffer->vk_memory) { @@ -1798,6 +1797,8 @@ NTSTATUS get_pixel_formats( void *args ) #ifdef _WIN64 +static pthread_mutex_t wgl_lock = PTHREAD_MUTEX_INITIALIZER; + struct wow64_string_entry { const char *str; @@ -1884,7 +1885,7 @@ static struct buffer *get_named_buffer( TEB *teb, GLuint name ) return NULL; } -struct buffer *invalidate_buffer_name( TEB *teb, GLuint name ) +static struct buffer *invalidate_buffer_name( TEB *teb, GLuint name ) { struct buffer *buffer = get_named_buffer( teb, name ); if (buffer) @@ -1895,7 +1896,7 @@ struct buffer *invalidate_buffer_name( TEB *teb, GLuint name ) return buffer; } -struct buffer *invalidate_buffer_target( TEB *teb, GLenum target ) +static struct buffer *invalidate_buffer_target( TEB *teb, GLenum target ) { GLuint name = get_target_name( teb, target ); return name ? invalidate_buffer_name( teb, name ) : NULL; @@ -2218,34 +2219,37 @@ void wow64_glDeleteBuffers( TEB *teb, GLsizei n, const GLuint *buffers, PFN_glDe void wow64_glBufferStorage( TEB *teb, GLenum target, GLsizeiptr size, const void *data, GLbitfield flags, PFN_glBufferStorage p_glBufferStorage ) { - struct buffer *buffer = NULL; + const struct opengl_funcs *funcs = teb->glTable; + struct buffer *buffer = NULL, *previous; + + pthread_mutex_lock( &wgl_lock ); + previous = invalidate_buffer_target( teb, target ); if (flags & GL_MAP_PERSISTENT_BIT) buffer = create_buffer_storage( teb, target, 0, size, data, flags ); if (!buffer) p_glBufferStorage( target, size, data, flags ); + + pthread_mutex_unlock( &wgl_lock ); + if (previous) free_buffer( funcs, previous ); } void wow64_glNamedBufferStorage( TEB *teb, GLuint name, GLsizeiptr size, const void *data, GLbitfield flags, PFN_glNamedBufferStorage p_glNamedBufferStorage ) { - struct buffer *buffer = NULL; + const struct opengl_funcs *funcs = teb->glTable; + struct buffer *buffer = NULL, *previous; + + pthread_mutex_lock( &wgl_lock ); + previous = invalidate_buffer_name( teb, name ); if (flags & GL_MAP_PERSISTENT_BIT) buffer = create_buffer_storage( teb, 0, name, size, data, flags ); if (!buffer) p_glNamedBufferStorage( name, size, data, flags ); -} -void wow64_glNamedBufferStorageEXT( TEB *teb, GLuint name, GLsizeiptr size, const void *data, - GLbitfield flags, PFN_glNamedBufferStorageEXT p_glNamedBufferStorageEXT ) -{ - struct buffer *buffer = NULL; - - if (flags & GL_MAP_PERSISTENT_BIT) - buffer = create_buffer_storage( teb, 0, name, size, data, flags ); - - if (!buffer) p_glNamedBufferStorageEXT( name, size, data, flags ); + pthread_mutex_unlock( &wgl_lock ); + if (previous) free_buffer( funcs, previous ); } static BOOL wow64_gl_get_buffer_pointer_v( TEB *teb, GLenum target, GLuint name, GLenum pname, PTR32 *wow_ptr ) @@ -2274,15 +2278,6 @@ void wow64_glGetBufferPointerv( TEB *teb, GLenum target, GLenum pname, PTR32 *pa *params = PtrToUlong(ptr); } -void wow64_glGetBufferPointervARB( TEB *teb, GLenum target, GLenum pname, PTR32 *params ) -{ - const struct opengl_funcs *funcs = teb->glTable; - void *ptr; - if (wow64_gl_get_buffer_pointer_v( teb, target, 0, pname, params )) return; - funcs->p_glGetBufferPointerv( target, pname, &ptr ); - *params = PtrToUlong(ptr); -} - void wow64_glGetNamedBufferPointerv( TEB *teb, GLuint buffer, GLenum pname, PTR32 *params, PFN_glGetNamedBufferPointerv p_glGetNamedBufferPointerv ) { @@ -2292,15 +2287,6 @@ void wow64_glGetNamedBufferPointerv( TEB *teb, GLuint buffer, GLenum pname, PTR3 *params = PtrToUlong(ptr); } -void wow64_glGetNamedBufferPointervEXT( TEB *teb, GLuint buffer, GLenum pname, PTR32 *params ) -{ - const struct opengl_funcs *funcs = teb->glTable; - void *ptr; - if (buffer && wow64_gl_get_buffer_pointer_v( teb, 0, buffer, pname, params )) return; - funcs->p_glGetNamedBufferPointervEXT( buffer, pname, &ptr ); - *params = PtrToUlong(ptr); -} - void *wow64_glMapBuffer( TEB *teb, GLenum target, GLenum access, PFN_glMapBuffer p_glMapBuffer ) { GLbitfield range_access = map_range_flags_from_map_flags( access ); @@ -2427,15 +2413,82 @@ void wow64_glFlushMappedNamedBufferRange( TEB *teb, GLuint name, GLintptr offset pthread_mutex_unlock( &wgl_lock ); } -void wow64_glFlushMappedNamedBufferRangeEXT( TEB *teb, GLuint name, GLintptr offset, GLsizeiptr length ) +void wow64_glBufferAttachMemoryNV( TEB *teb, GLenum target, GLuint memory, GLuint64 offset, PFN_glBufferAttachMemoryNV p_glBufferAttachMemoryNV ) { const struct opengl_funcs *funcs = teb->glTable; struct buffer *buffer; pthread_mutex_lock( &wgl_lock ); - if ((buffer = get_named_buffer( teb, name ))) flush_buffer( teb, buffer, offset, length ); - if (use_driver_buffer_map( buffer )) funcs->p_glFlushMappedNamedBufferRangeEXT( name, offset, length ); + buffer = invalidate_buffer_target( teb, target ); + p_glBufferAttachMemoryNV( target, memory, offset ); pthread_mutex_unlock( &wgl_lock ); + + if (buffer) free_buffer( funcs, buffer ); +} + +void wow64_glBufferData( TEB *teb, GLenum target, GLsizeiptr size, const void *data, GLenum usage, PFN_glBufferData p_glBufferData ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct buffer *buffer; + + pthread_mutex_lock( &wgl_lock ); + buffer = invalidate_buffer_target( teb, target ); + p_glBufferData( target, size, data, usage ); + pthread_mutex_unlock( &wgl_lock ); + + if (buffer) free_buffer( funcs, buffer ); +} + +void wow64_glBufferStorageMemEXT( TEB *teb, GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset, PFN_glBufferStorageMemEXT p_glBufferStorageMemEXT ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct buffer *buffer; + + pthread_mutex_lock( &wgl_lock ); + buffer = invalidate_buffer_target( teb, target ); + p_glBufferStorageMemEXT( target, size, memory, offset ); + pthread_mutex_unlock( &wgl_lock ); + + if (buffer) free_buffer( funcs, buffer ); +} + +void wow64_glNamedBufferAttachMemoryNV( TEB *teb, GLuint name, GLuint memory, GLuint64 offset, PFN_glNamedBufferAttachMemoryNV p_glNamedBufferAttachMemoryNV ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct buffer *buffer; + + pthread_mutex_lock( &wgl_lock ); + buffer = invalidate_buffer_name( teb, name ); + p_glNamedBufferAttachMemoryNV( name, memory, offset ); + pthread_mutex_unlock( &wgl_lock ); + + if (buffer) free_buffer( funcs, buffer ); +} + +void wow64_glNamedBufferData( TEB *teb, GLuint name, GLsizeiptr size, const void *data, GLenum usage, PFN_glNamedBufferData p_glNamedBufferData ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct buffer *buffer; + + pthread_mutex_lock( &wgl_lock ); + buffer = invalidate_buffer_name( teb, name ); + p_glNamedBufferData( name, size, data, usage ); + pthread_mutex_unlock( &wgl_lock ); + + if (buffer) free_buffer( funcs, buffer ); +} + +void wow64_glNamedBufferStorageMemEXT( TEB *teb, GLuint name, GLsizeiptr size, GLuint memory, GLuint64 offset, PFN_glNamedBufferStorageMemEXT p_glNamedBufferStorageMemEXT ) +{ + const struct opengl_funcs *funcs = teb->glTable; + struct buffer *buffer; + + pthread_mutex_lock( &wgl_lock ); + buffer = invalidate_buffer_name( teb, name ); + p_glNamedBufferStorageMemEXT( name, size, memory, offset ); + pthread_mutex_unlock( &wgl_lock ); + + if (buffer) free_buffer( funcs, buffer ); } NTSTATUS wow64_thread_attach( void *args ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11226
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/unix_wgl.c | 83 +++++++++++++--------------------------- 1 file changed, 26 insertions(+), 57 deletions(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 5f5fae6a2a1..b614879911f 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -114,13 +114,6 @@ struct hint_state GLenum multisample_nv; }; -struct buffers -{ - unsigned int ref; - struct rb_tree map; - struct vk_device *vk_device; -}; - struct context { struct opengl_context base; @@ -131,7 +124,6 @@ struct context UINT64 debug_user; /* client pointer */ GLubyte *extensions; /* extension string */ char *wow64_version; /* wow64 GL version override */ - struct buffers *buffers; /* wow64 buffers map */ BOOL use_pinned_memory; /* use GL_AMD_pinned_memory to emulate persistent maps */ /* semi-stub state tracker for wglCopyContext */ @@ -185,7 +177,6 @@ struct vk_device static ULONG_PTR zero_bits; -static struct buffers *buffers; static const struct vulkan_funcs *vk_funcs; static VkInstance vk_instance; static PFN_vkDestroyInstance p_vkDestroyInstance; @@ -396,6 +387,12 @@ static int compare_buffer_name( const void *key, const struct rb_entry *entry ) return memcmp( key, &buffer->name, sizeof(buffer->name) ); } +static struct +{ + struct rb_tree map; + struct vk_device *vk_device; +} buffers = { .map = { compare_buffer_name } }; + static void free_buffer( const struct opengl_funcs *funcs, struct buffer *buffer ) { if (buffer->vk_memory) @@ -403,34 +400,11 @@ static void free_buffer( const struct opengl_funcs *funcs, struct buffer *buffer if (buffer->map_ptr) unmap_vk_buffer( buffer ); buffer->vk_device->p_vkFreeMemory( buffer->vk_device->vk_device, buffer->vk_memory, NULL ); } - if (buffer->gl_memory) funcs->p_glDeleteMemoryObjectsEXT( 1, &buffer->gl_memory ); + if (buffer->gl_memory && funcs) funcs->p_glDeleteMemoryObjectsEXT( 1, &buffer->gl_memory ); if (buffer->vm_ptr) NtFreeVirtualMemory( GetCurrentProcess(), &buffer->vm_ptr, &buffer->vm_size, MEM_RELEASE ); free( buffer ); } -static void release_buffers( const struct opengl_funcs *funcs ) -{ - struct buffer *buffer, *next; - - if (--buffers->ref) return; - - RB_FOR_EACH_ENTRY_DESTRUCTOR( buffer, next, &buffers->map, struct buffer, entry ) - free_buffer( funcs, buffer ); - free( buffers ); - buffers = NULL; -} - -static struct buffers *acquire_buffers(void) -{ - if (buffers) buffers->ref++; - else if ((buffers = calloc( 1, sizeof(*buffers )))) - { - buffers->ref = 1; - rb_init( &buffers->map, compare_buffer_name ); - } - return buffers; -} - static struct context *context_from_client_context( HGLRC client_context ) { struct opengl_context *base = opengl_context_from_handle( client_context ); @@ -845,7 +819,7 @@ static BOOL initialize_vk_device( TEB *teb, struct context *ctx ) static PFN_vkGetPhysicalDeviceMemoryProperties p_vkGetPhysicalDeviceMemoryProperties; static PFN_vkGetPhysicalDeviceProperties2KHR p_vkGetPhysicalDeviceProperties2KHR; - if (buffers->vk_device) return TRUE; /* already initialized */ + if (buffers.vk_device) return TRUE; /* already initialized */ if (!client->extensions[GL_EXT_memory_object_win32] ) { TRACE( "GL_EXT_memory_object_win32 is not supported\n" ); @@ -906,7 +880,7 @@ static BOOL initialize_vk_device( TEB *teb, struct context *ctx ) vk_device = RB_ENTRY_VALUE( entry, struct vk_device, entry ); if (!vk_device->vk_device) continue; /* known incompatible device */ TRACE( "Found existing device %p for uuid %s\n", vk_device, debugstr_guid(&vk_device->uuid) ); - buffers->vk_device = vk_device; + buffers.vk_device = vk_device; free( vk_physical_devices ); return TRUE; } @@ -1091,7 +1065,7 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD TRACE( "-- %s (disabled by config)\n", all_extensions[i].name ); } - if (is_win64 && ctx->buffers && !initialize_vk_device( teb, ctx ) + if (is_win64 && is_wow64() && !initialize_vk_device( teb, ctx ) && !(ctx->use_pinned_memory = client->extensions[GL_AMD_pinned_memory])) { if (client->major_version > 4 || (client->major_version == 4 && client->minor_version > 3)) @@ -1121,7 +1095,6 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD static void free_context( const struct opengl_funcs *funcs, struct context *ctx ) { - if (ctx->buffers) release_buffers( funcs ); free( ctx->wow64_version ); free( ctx->extensions ); free( ctx->attribs ); @@ -1294,8 +1267,6 @@ HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC client_shared, c context->base.client_context = client_context; context->attribs = memdup_attribs( attribs ); - if (is_win64 && is_wow64()) context->buffers = acquire_buffers(); - if (!(funcs->p_context_create( &context->base, hdc, attribs ))) { free_context( funcs, context ); @@ -1768,8 +1739,15 @@ NTSTATUS thread_attach( void *args ) NTSTATUS process_detach( void *args ) { - struct vk_device *vk_device, *next; + struct vk_device *vk_device; + struct buffer *buffer; + void *next; + RB_FOR_EACH_ENTRY_DESTRUCTOR( buffer, next, &buffers.map, struct buffer, entry ) + { + WARN( "Leaked buffer %p\n", buffer ); + free_buffer( NULL, buffer ); + } RB_FOR_EACH_ENTRY_DESTRUCTOR( vk_device, next, &vk_devices, struct vk_device, entry ) { if (vk_device->vk_device) vk_device->p_vkDestroyDevice( vk_device->vk_device, NULL ); @@ -1877,22 +1855,15 @@ static GLuint get_target_name( TEB *teb, GLenum target ) static struct buffer *get_named_buffer( TEB *teb, GLuint name ) { - struct context *ctx = get_current_context( teb, NULL, NULL ); struct rb_entry *entry; - - if (ctx && (entry = rb_get( &ctx->buffers->map, &name ))) - return RB_ENTRY_VALUE( entry, struct buffer, entry ); - return NULL; + if (!(entry = rb_get( &buffers.map, &name ))) return NULL; + return RB_ENTRY_VALUE( entry, struct buffer, entry ); } static struct buffer *invalidate_buffer_name( TEB *teb, GLuint name ) { struct buffer *buffer = get_named_buffer( teb, name ); - if (buffer) - { - struct context *ctx = get_current_context( teb, NULL, NULL ); - rb_remove( &ctx->buffers->map, &buffer->entry ); - } + if (buffer) rb_remove( &buffers.map, &buffer->entry ); return buffer; } @@ -1990,7 +1961,7 @@ static struct buffer *create_buffer_storage( TEB *teb, GLenum target, GLuint nam VkResult vr; if (!(flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))) return NULL; - if ((!(vk_device = ctx->buffers->vk_device) || !vk_device->vk_device) && !ctx->use_pinned_memory) return NULL; + if ((!(vk_device = buffers.vk_device) || !vk_device->vk_device) && !ctx->use_pinned_memory) return NULL; if (!(buffer = calloc( 1, sizeof(*buffer) ))) return NULL; buffer->name = buffer_name; @@ -2010,7 +1981,7 @@ static struct buffer *create_buffer_storage( TEB *teb, GLenum target, GLuint nam * to support it. */ funcs->p_glBindBuffer( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, buffer_name ); funcs->p_glBufferData( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, size, buffer->vm_ptr, GL_DYNAMIC_COPY ); - rb_put( &ctx->buffers->map, &buffer->name, &buffer->entry ); + rb_put( &buffers.map, &buffer->name, &buffer->entry ); TRACE( "created buffer %p with pinned memory %p\n", buffer, buffer->vm_ptr ); return buffer; } @@ -2077,7 +2048,7 @@ static struct buffer *create_buffer_storage( TEB *teb, GLenum target, GLuint nam funcs->p_glNamedBufferStorageMemEXT( buffer->name, size, buffer->gl_memory, 0 ); else funcs->p_glBufferStorageMemEXT( target, size, buffer->gl_memory, 0 ); - rb_put( &ctx->buffers->map, &buffer->name, &buffer->entry ); + rb_put( &buffers.map, &buffer->name, &buffer->entry ); TRACE( "created buffer_storage %p\n", buffer ); return buffer; } @@ -2108,8 +2079,7 @@ static void *wow64_map_buffer( TEB *teb, struct buffer *buffer, GLenum target, G .size = VK_WHOLE_SIZE, }; VkResult vr; - struct context *ctx = get_current_context( teb, NULL, NULL ); - struct vk_device *vk_device = ctx->buffers->vk_device; + struct vk_device *vk_device = buffers.vk_device; if (!buffer_vm_alloc( teb, buffer, buffer->size )) return NULL; placed_info.pPlacedAddress = buffer->vm_ptr; @@ -2136,7 +2106,6 @@ static void *wow64_map_buffer( TEB *teb, struct buffer *buffer, GLenum target, G if (!buffer) { - struct context *ctx = get_current_context( teb, NULL, NULL ); GLint size; if (name) funcs->p_glGetNamedBufferParameteriv( name, GL_BUFFER_SIZE, &size ); @@ -2145,7 +2114,7 @@ static void *wow64_map_buffer( TEB *teb, struct buffer *buffer, GLenum target, G if (!(buffer = calloc( 1, sizeof(*buffer) ))) return NULL; buffer->name = name ? name : get_target_name( teb, target ); buffer->size = size; - rb_put( &ctx->buffers->map, &buffer->name, &buffer->entry ); + rb_put( &buffers.map, &buffer->name, &buffer->entry ); TRACE( "allocated buffer %p for %u\n", buffer, buffer->name ); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11226
From: Rémi Bernon <rbernon@codeweavers.com> As we now implement implicit buffer names on the PE side, names are now always explicitly, and therefore sequentially, allocated. --- dlls/opengl32/unix_wgl.c | 92 +++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index b614879911f..91ae50af2db 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -142,8 +142,6 @@ struct context struct buffer { - struct rb_entry entry; - GLuint name; size_t size; void *host_ptr; void *map_ptr; @@ -156,7 +154,6 @@ struct buffer struct vk_device *vk_device; VkDeviceMemory vk_memory; GLuint gl_memory; - GLbitfield flags; }; struct vk_device @@ -381,17 +378,13 @@ static void unmap_vk_buffer( struct buffer *buffer ) if (vr) ERR( "VkMemoryUnmapInfoKHR failed: %x\n", vr); } -static int compare_buffer_name( const void *key, const struct rb_entry *entry ) -{ - struct buffer *buffer = RB_ENTRY_VALUE( entry, struct buffer, entry ); - return memcmp( key, &buffer->name, sizeof(buffer->name) ); -} - static struct { - struct rb_tree map; + UINT size; + UINT capacity; + struct buffer **map; struct vk_device *vk_device; -} buffers = { .map = { compare_buffer_name } }; +} buffers; static void free_buffer( const struct opengl_funcs *funcs, struct buffer *buffer ) { @@ -1743,11 +1736,14 @@ NTSTATUS process_detach( void *args ) struct buffer *buffer; void *next; - RB_FOR_EACH_ENTRY_DESTRUCTOR( buffer, next, &buffers.map, struct buffer, entry ) + for (UINT i = 0; i < buffers.size; i++) { + if (!(buffer = buffers.map[i])) continue; WARN( "Leaked buffer %p\n", buffer ); free_buffer( NULL, buffer ); } + free( buffers.map ); + RB_FOR_EACH_ENTRY_DESTRUCTOR( vk_device, next, &vk_devices, struct vk_device, entry ) { if (vk_device->vk_device) vk_device->p_vkDestroyDevice( vk_device->vk_device, NULL ); @@ -1853,18 +1849,40 @@ static GLuint get_target_name( TEB *teb, GLenum target ) return name; } -static struct buffer *get_named_buffer( TEB *teb, GLuint name ) +static struct buffer *set_buffer_storage( GLuint idx, struct buffer *buffer ) +{ + struct buffer *previous = buffer; + + if (idx >= buffers.capacity && buffer) + { + size_t capacity = max( idx + 1, buffers.capacity ? buffers.capacity : 16 ) * 3 / 2; + struct buffer **tmp; + + if (!(tmp = realloc( buffers.map, capacity * sizeof(*tmp) ))) return buffer; + memset( tmp + buffers.capacity, 0, (capacity - buffers.capacity) * sizeof(*tmp) ); + buffers.capacity = capacity; + buffers.map = tmp; + } + if (idx < buffers.capacity) + { + previous = buffers.map[idx]; + buffers.map[idx] = buffer; + buffers.size = max( buffers.size, idx + 1 ); + } + + TRACE( "idx %#x capacity %#x size %#x buffer %p -> %p\n", idx, buffers.capacity, buffers.size, previous, buffer ); + return previous; +} + +static struct buffer *get_named_buffer_storage( TEB *teb, GLuint name ) { - struct rb_entry *entry; - if (!(entry = rb_get( &buffers.map, &name ))) return NULL; - return RB_ENTRY_VALUE( entry, struct buffer, entry ); + if (!name || name > buffers.size) return NULL; + return buffers.map[name - 1]; } static struct buffer *invalidate_buffer_name( TEB *teb, GLuint name ) { - struct buffer *buffer = get_named_buffer( teb, name ); - if (buffer) rb_remove( &buffers.map, &buffer->entry ); - return buffer; + return name ? set_buffer_storage( name - 1, NULL ) : NULL; } static struct buffer *invalidate_buffer_target( TEB *teb, GLenum target ) @@ -1873,10 +1891,10 @@ static struct buffer *invalidate_buffer_target( TEB *teb, GLenum target ) return name ? invalidate_buffer_name( teb, name ) : NULL; } -static struct buffer *get_target_buffer( TEB *teb, GLenum target ) +static struct buffer *get_target_buffer_storage( TEB *teb, GLenum target ) { GLuint name = get_target_name( teb, target ); - return name ? get_named_buffer( teb, name ) : NULL; + return name ? get_named_buffer_storage( teb, name ) : NULL; } static BOOL use_driver_buffer_map( struct buffer *buffer ) @@ -1964,8 +1982,6 @@ static struct buffer *create_buffer_storage( TEB *teb, GLenum target, GLuint nam if ((!(vk_device = buffers.vk_device) || !vk_device->vk_device) && !ctx->use_pinned_memory) return NULL; if (!(buffer = calloc( 1, sizeof(*buffer) ))) return NULL; - buffer->name = buffer_name; - buffer->flags = flags; buffer->size = size; buffer->vk_device = vk_device; @@ -1981,7 +1997,7 @@ static struct buffer *create_buffer_storage( TEB *teb, GLenum target, GLuint nam * to support it. */ funcs->p_glBindBuffer( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, buffer_name ); funcs->p_glBufferData( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, size, buffer->vm_ptr, GL_DYNAMIC_COPY ); - rb_put( &buffers.map, &buffer->name, &buffer->entry ); + set_buffer_storage( buffer_name - 1, buffer ); TRACE( "created buffer %p with pinned memory %p\n", buffer, buffer->vm_ptr ); return buffer; } @@ -2045,10 +2061,10 @@ static struct buffer *create_buffer_storage( TEB *teb, GLenum target, GLuint nam funcs->p_glCreateMemoryObjectsEXT( 1, &buffer->gl_memory ); funcs->p_glImportMemoryFdEXT( buffer->gl_memory, size, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd ); if (name) - funcs->p_glNamedBufferStorageMemEXT( buffer->name, size, buffer->gl_memory, 0 ); + funcs->p_glNamedBufferStorageMemEXT( buffer_name, size, buffer->gl_memory, 0 ); else funcs->p_glBufferStorageMemEXT( target, size, buffer->gl_memory, 0 ); - rb_put( &buffers.map, &buffer->name, &buffer->entry ); + set_buffer_storage( buffer_name - 1, buffer ); TRACE( "created buffer_storage %p\n", buffer ); return buffer; } @@ -2112,10 +2128,10 @@ static void *wow64_map_buffer( TEB *teb, struct buffer *buffer, GLenum target, G else funcs->p_glGetBufferParameteriv( target, GL_BUFFER_SIZE, &size ); if (!(buffer = calloc( 1, sizeof(*buffer) ))) return NULL; - buffer->name = name ? name : get_target_name( teb, target ); + if (!name) name = get_target_name( teb, target ); buffer->size = size; - rb_put( &buffers.map, &buffer->name, &buffer->entry ); - TRACE( "allocated buffer %p for %u\n", buffer, buffer->name ); + set_buffer_storage( name - 1, buffer ); + TRACE( "allocated buffer %p for %u\n", buffer, name ); } buffer->host_ptr = ptr; @@ -2229,7 +2245,7 @@ static BOOL wow64_gl_get_buffer_pointer_v( TEB *teb, GLenum target, GLuint name, if (pname != GL_BUFFER_MAP_POINTER) return FALSE; pthread_mutex_lock( &wgl_lock ); - buffer = name ? get_named_buffer( teb, name ) : get_target_buffer( teb, target ); + buffer = name ? get_named_buffer_storage( teb, name ) : get_target_buffer_storage( teb, target ); if (buffer) { *wow_ptr = PtrToUlong( buffer->map_ptr ); @@ -2263,7 +2279,7 @@ void *wow64_glMapBuffer( TEB *teb, GLenum target, GLenum access, PFN_glMapBuffer void *ptr = NULL; pthread_mutex_lock( &wgl_lock ); - buffer = get_target_buffer( teb, target ); + buffer = get_target_buffer_storage( teb, target ); if (use_driver_buffer_map( buffer )) ptr = p_glMapBuffer( target, access ); ptr = wow64_map_buffer( teb, buffer, target, 0, 0, 0, range_access, ptr ); pthread_mutex_unlock( &wgl_lock ); @@ -2277,7 +2293,7 @@ void *wow64_glMapBufferRange( TEB *teb, GLenum target, GLintptr offset, GLsizeip void *ptr = NULL; pthread_mutex_lock( &wgl_lock ); - buffer = get_target_buffer( teb, target ); + buffer = get_target_buffer_storage( teb, target ); if (use_driver_buffer_map( buffer )) ptr = p_glMapBufferRange( target, offset, length, access ); ptr = wow64_map_buffer( teb, buffer, target, 0, offset, length, access, ptr ); pthread_mutex_unlock( &wgl_lock ); @@ -2291,7 +2307,7 @@ void *wow64_glMapNamedBuffer( TEB *teb, GLuint name, GLenum access, PFN_glMapNam void *ptr = NULL; pthread_mutex_lock( &wgl_lock ); - buffer = get_named_buffer( teb, name ); + buffer = get_named_buffer_storage( teb, name ); if (use_driver_buffer_map( buffer )) ptr = p_glMapNamedBuffer( name, access ); ptr = wow64_map_buffer( teb, buffer, 0, name, 0, 0, range_access, ptr ); pthread_mutex_unlock( &wgl_lock ); @@ -2305,7 +2321,7 @@ void *wow64_glMapNamedBufferRange( TEB *teb, GLuint name, GLintptr offset, GLsiz void *ptr = NULL; pthread_mutex_lock( &wgl_lock ); - buffer = get_named_buffer( teb, name ); + buffer = get_named_buffer_storage( teb, name ); if (use_driver_buffer_map( buffer )) ptr = p_glMapNamedBufferRange( name, offset, length, access ); ptr = wow64_map_buffer( teb, buffer, 0, name, offset, length, access, ptr ); pthread_mutex_unlock( &wgl_lock ); @@ -2342,7 +2358,7 @@ GLboolean wow64_glUnmapBuffer( TEB *teb, GLenum target, PFN_glUnmapBuffer p_glUn GLboolean ret; pthread_mutex_lock( &wgl_lock ); - if ((buffer = get_target_buffer( teb, target ))) ret = wow64_unmap_buffer( teb, buffer ); + if ((buffer = get_target_buffer_storage( teb, target ))) ret = wow64_unmap_buffer( teb, buffer ); if (use_driver_buffer_map( buffer )) ret = p_glUnmapBuffer( target ); pthread_mutex_unlock( &wgl_lock ); return ret; @@ -2354,7 +2370,7 @@ GLboolean wow64_glUnmapNamedBuffer( TEB *teb, GLuint name, PFN_glUnmapBuffer p_g GLboolean ret; pthread_mutex_lock( &wgl_lock ); - if ((buffer = get_named_buffer( teb, name ))) ret = wow64_unmap_buffer( teb, buffer ); + if ((buffer = get_named_buffer_storage( teb, name ))) ret = wow64_unmap_buffer( teb, buffer ); if (use_driver_buffer_map( buffer )) ret = p_glUnmapNamedBuffer( name ); pthread_mutex_unlock( &wgl_lock ); return ret; @@ -2366,7 +2382,7 @@ void wow64_glFlushMappedBufferRange( TEB *teb, GLenum target, GLintptr offset, G struct buffer *buffer; pthread_mutex_lock( &wgl_lock ); - if ((buffer = get_target_buffer( teb, target ))) flush_buffer( teb, buffer, offset, length ); + if ((buffer = get_target_buffer_storage( teb, target ))) flush_buffer( teb, buffer, offset, length ); if (use_driver_buffer_map( buffer )) p_glFlushMappedBufferRange( target, offset, length ); pthread_mutex_unlock( &wgl_lock ); } @@ -2377,7 +2393,7 @@ void wow64_glFlushMappedNamedBufferRange( TEB *teb, GLuint name, GLintptr offset struct buffer *buffer; pthread_mutex_lock( &wgl_lock ); - if ((buffer = get_named_buffer( teb, name ))) flush_buffer( teb, buffer, offset, length ); + if ((buffer = get_named_buffer_storage( teb, name ))) flush_buffer( teb, buffer, offset, length ); if (use_driver_buffer_map( buffer )) p_glFlushMappedNamedBufferRange( name, offset, length ); pthread_mutex_unlock( &wgl_lock ); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11226
From: Rémi Bernon <rbernon@codeweavers.com> Mapping, unmapping and flushing a given buffer is left unguarded, under the assumption that is is undefined to do such calls concurrently. --- dlls/opengl32/unix_wgl.c | 131 ++++++++++++++------------------------- 1 file changed, 46 insertions(+), 85 deletions(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 91ae50af2db..1050cb3a19c 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1849,6 +1849,12 @@ static GLuint get_target_name( TEB *teb, GLenum target ) return name; } +static struct buffer *get_buffer_storage( GLuint idx ) +{ + if (idx < buffers.size) return buffers.map[idx]; + return NULL; +} + static struct buffer *set_buffer_storage( GLuint idx, struct buffer *buffer ) { struct buffer *previous = buffer; @@ -1876,19 +1882,26 @@ static struct buffer *set_buffer_storage( GLuint idx, struct buffer *buffer ) static struct buffer *get_named_buffer_storage( TEB *teb, GLuint name ) { - if (!name || name > buffers.size) return NULL; - return buffers.map[name - 1]; + struct buffer *buffer; + pthread_mutex_lock( &wgl_lock ); + buffer = name ? get_buffer_storage( name - 1 ) : NULL; + pthread_mutex_unlock( &wgl_lock ); + return buffer; } -static struct buffer *invalidate_buffer_name( TEB *teb, GLuint name ) +static struct buffer *set_named_buffer_storage( TEB *teb, GLuint name, struct buffer *buffer ) { - return name ? set_buffer_storage( name - 1, NULL ) : NULL; + struct buffer *previous; + pthread_mutex_lock( &wgl_lock ); + previous = name ? set_buffer_storage( name - 1, buffer ) : NULL; + pthread_mutex_unlock( &wgl_lock ); + return previous; } -static struct buffer *invalidate_buffer_target( TEB *teb, GLenum target ) +static struct buffer *set_target_buffer_storage( TEB *teb, GLenum target, struct buffer *buffer ) { GLuint name = get_target_name( teb, target ); - return name ? invalidate_buffer_name( teb, name ) : NULL; + return name ? set_named_buffer_storage( teb, name, buffer ) : NULL; } static struct buffer *get_target_buffer_storage( TEB *teb, GLenum target ) @@ -1997,7 +2010,6 @@ static struct buffer *create_buffer_storage( TEB *teb, GLenum target, GLuint nam * to support it. */ funcs->p_glBindBuffer( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, buffer_name ); funcs->p_glBufferData( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, size, buffer->vm_ptr, GL_DYNAMIC_COPY ); - set_buffer_storage( buffer_name - 1, buffer ); TRACE( "created buffer %p with pinned memory %p\n", buffer, buffer->vm_ptr ); return buffer; } @@ -2064,7 +2076,6 @@ static struct buffer *create_buffer_storage( TEB *teb, GLenum target, GLuint nam funcs->p_glNamedBufferStorageMemEXT( buffer_name, size, buffer->gl_memory, 0 ); else funcs->p_glBufferStorageMemEXT( target, size, buffer->gl_memory, 0 ); - set_buffer_storage( buffer_name - 1, buffer ); TRACE( "created buffer_storage %p\n", buffer ); return buffer; } @@ -2122,15 +2133,19 @@ static void *wow64_map_buffer( TEB *teb, struct buffer *buffer, GLenum target, G if (!buffer) { + struct buffer *previous; GLint size; if (name) funcs->p_glGetNamedBufferParameteriv( name, GL_BUFFER_SIZE, &size ); else funcs->p_glGetBufferParameteriv( target, GL_BUFFER_SIZE, &size ); if (!(buffer = calloc( 1, sizeof(*buffer) ))) return NULL; - if (!name) name = get_target_name( teb, target ); buffer->size = size; - set_buffer_storage( name - 1, buffer ); + + if (name) previous = set_named_buffer_storage( teb, name, buffer ); + else previous = set_target_buffer_storage( teb, target, buffer ); + assert( !previous ); + TRACE( "allocated buffer %p for %u\n", buffer, name ); } @@ -2184,21 +2199,23 @@ static GLbitfield map_range_flags_from_map_flags( GLenum flags ) } } -void wow64_glDeleteBuffers( TEB *teb, GLsizei n, const GLuint *buffers, PFN_glDeleteBuffers p_glDeleteBuffers ) +void wow64_glDeleteBuffers( TEB *teb, GLsizei n, const GLuint *names, PFN_glDeleteBuffers p_glDeleteBuffers ) { const struct opengl_funcs *funcs = teb->glTable; - struct buffer *buffer; + struct buffer **tmp; GLsizei i; - pthread_mutex_lock( &wgl_lock ); - - p_glDeleteBuffers( n, buffers ); - for (i = 0; i < n; i++) + if ((tmp = malloc( n * sizeof(*tmp) ))) { - if ((buffer = invalidate_buffer_name( teb, buffers[i] ))) free_buffer( funcs, buffer ); + pthread_mutex_lock( &wgl_lock ); + for (i = 0; i < n; i++) if (names[i]) tmp[i] = set_buffer_storage( names[i] - 1, NULL ); + pthread_mutex_unlock( &wgl_lock ); + + for (i = 0; i < n; i++) if (tmp[i]) free_buffer( funcs, tmp[i] ); + free( tmp ); } - pthread_mutex_unlock( &wgl_lock ); + p_glDeleteBuffers( n, names ); } void wow64_glBufferStorage( TEB *teb, GLenum target, GLsizeiptr size, const void *data, @@ -2207,15 +2224,9 @@ void wow64_glBufferStorage( TEB *teb, GLenum target, GLsizeiptr size, const void const struct opengl_funcs *funcs = teb->glTable; struct buffer *buffer = NULL, *previous; - pthread_mutex_lock( &wgl_lock ); - previous = invalidate_buffer_target( teb, target ); - - if (flags & GL_MAP_PERSISTENT_BIT) - buffer = create_buffer_storage( teb, target, 0, size, data, flags ); - + if (flags & GL_MAP_PERSISTENT_BIT) buffer = create_buffer_storage( teb, target, 0, size, data, flags ); + previous = set_target_buffer_storage( teb, target, buffer ); if (!buffer) p_glBufferStorage( target, size, data, flags ); - - pthread_mutex_unlock( &wgl_lock ); if (previous) free_buffer( funcs, previous ); } @@ -2225,15 +2236,9 @@ void wow64_glNamedBufferStorage( TEB *teb, GLuint name, GLsizeiptr size, const v const struct opengl_funcs *funcs = teb->glTable; struct buffer *buffer = NULL, *previous; - pthread_mutex_lock( &wgl_lock ); - previous = invalidate_buffer_name( teb, name ); - - if (flags & GL_MAP_PERSISTENT_BIT) - buffer = create_buffer_storage( teb, 0, name, size, data, flags ); - + if (flags & GL_MAP_PERSISTENT_BIT) buffer = create_buffer_storage( teb, 0, name, size, data, flags ); + previous = set_named_buffer_storage( teb, name, buffer ); if (!buffer) p_glNamedBufferStorage( name, size, data, flags ); - - pthread_mutex_unlock( &wgl_lock ); if (previous) free_buffer( funcs, previous ); } @@ -2243,15 +2248,11 @@ static BOOL wow64_gl_get_buffer_pointer_v( TEB *teb, GLenum target, GLuint name, BOOL ret = FALSE; if (pname != GL_BUFFER_MAP_POINTER) return FALSE; - - pthread_mutex_lock( &wgl_lock ); - buffer = name ? get_named_buffer_storage( teb, name ) : get_target_buffer_storage( teb, target ); - if (buffer) + if ((buffer = name ? get_named_buffer_storage( teb, name ) : get_target_buffer_storage( teb, target ))) { *wow_ptr = PtrToUlong( buffer->map_ptr ); ret = TRUE; } - pthread_mutex_unlock( &wgl_lock ); return ret; } @@ -2278,11 +2279,9 @@ void *wow64_glMapBuffer( TEB *teb, GLenum target, GLenum access, PFN_glMapBuffer struct buffer *buffer; void *ptr = NULL; - pthread_mutex_lock( &wgl_lock ); buffer = get_target_buffer_storage( teb, target ); if (use_driver_buffer_map( buffer )) ptr = p_glMapBuffer( target, access ); ptr = wow64_map_buffer( teb, buffer, target, 0, 0, 0, range_access, ptr ); - pthread_mutex_unlock( &wgl_lock ); return ptr; } @@ -2292,11 +2291,9 @@ void *wow64_glMapBufferRange( TEB *teb, GLenum target, GLintptr offset, GLsizeip struct buffer *buffer; void *ptr = NULL; - pthread_mutex_lock( &wgl_lock ); buffer = get_target_buffer_storage( teb, target ); if (use_driver_buffer_map( buffer )) ptr = p_glMapBufferRange( target, offset, length, access ); ptr = wow64_map_buffer( teb, buffer, target, 0, offset, length, access, ptr ); - pthread_mutex_unlock( &wgl_lock ); return ptr; } @@ -2306,11 +2303,9 @@ void *wow64_glMapNamedBuffer( TEB *teb, GLuint name, GLenum access, PFN_glMapNam struct buffer *buffer; void *ptr = NULL; - pthread_mutex_lock( &wgl_lock ); buffer = get_named_buffer_storage( teb, name ); if (use_driver_buffer_map( buffer )) ptr = p_glMapNamedBuffer( name, access ); ptr = wow64_map_buffer( teb, buffer, 0, name, 0, 0, range_access, ptr ); - pthread_mutex_unlock( &wgl_lock ); return ptr; } @@ -2320,11 +2315,9 @@ void *wow64_glMapNamedBufferRange( TEB *teb, GLuint name, GLintptr offset, GLsiz struct buffer *buffer; void *ptr = NULL; - pthread_mutex_lock( &wgl_lock ); buffer = get_named_buffer_storage( teb, name ); if (use_driver_buffer_map( buffer )) ptr = p_glMapNamedBufferRange( name, offset, length, access ); ptr = wow64_map_buffer( teb, buffer, 0, name, offset, length, access, ptr ); - pthread_mutex_unlock( &wgl_lock ); return ptr; } @@ -2357,10 +2350,8 @@ GLboolean wow64_glUnmapBuffer( TEB *teb, GLenum target, PFN_glUnmapBuffer p_glUn struct buffer *buffer; GLboolean ret; - pthread_mutex_lock( &wgl_lock ); if ((buffer = get_target_buffer_storage( teb, target ))) ret = wow64_unmap_buffer( teb, buffer ); if (use_driver_buffer_map( buffer )) ret = p_glUnmapBuffer( target ); - pthread_mutex_unlock( &wgl_lock ); return ret; } @@ -2369,10 +2360,8 @@ GLboolean wow64_glUnmapNamedBuffer( TEB *teb, GLuint name, PFN_glUnmapBuffer p_g struct buffer *buffer; GLboolean ret; - pthread_mutex_lock( &wgl_lock ); if ((buffer = get_named_buffer_storage( teb, name ))) ret = wow64_unmap_buffer( teb, buffer ); if (use_driver_buffer_map( buffer )) ret = p_glUnmapNamedBuffer( name ); - pthread_mutex_unlock( &wgl_lock ); return ret; } @@ -2381,10 +2370,8 @@ void wow64_glFlushMappedBufferRange( TEB *teb, GLenum target, GLintptr offset, G { struct buffer *buffer; - pthread_mutex_lock( &wgl_lock ); if ((buffer = get_target_buffer_storage( teb, target ))) flush_buffer( teb, buffer, offset, length ); if (use_driver_buffer_map( buffer )) p_glFlushMappedBufferRange( target, offset, length ); - pthread_mutex_unlock( &wgl_lock ); } void wow64_glFlushMappedNamedBufferRange( TEB *teb, GLuint name, GLintptr offset, GLsizeiptr length, @@ -2392,10 +2379,8 @@ void wow64_glFlushMappedNamedBufferRange( TEB *teb, GLuint name, GLintptr offset { struct buffer *buffer; - pthread_mutex_lock( &wgl_lock ); if ((buffer = get_named_buffer_storage( teb, name ))) flush_buffer( teb, buffer, offset, length ); if (use_driver_buffer_map( buffer )) p_glFlushMappedNamedBufferRange( name, offset, length ); - pthread_mutex_unlock( &wgl_lock ); } void wow64_glBufferAttachMemoryNV( TEB *teb, GLenum target, GLuint memory, GLuint64 offset, PFN_glBufferAttachMemoryNV p_glBufferAttachMemoryNV ) @@ -2403,12 +2388,8 @@ void wow64_glBufferAttachMemoryNV( TEB *teb, GLenum target, GLuint memory, GLuin const struct opengl_funcs *funcs = teb->glTable; struct buffer *buffer; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_target( teb, target ); + if ((buffer = set_target_buffer_storage( teb, target, NULL ))) free_buffer( funcs, buffer ); p_glBufferAttachMemoryNV( target, memory, offset ); - pthread_mutex_unlock( &wgl_lock ); - - if (buffer) free_buffer( funcs, buffer ); } void wow64_glBufferData( TEB *teb, GLenum target, GLsizeiptr size, const void *data, GLenum usage, PFN_glBufferData p_glBufferData ) @@ -2416,12 +2397,8 @@ void wow64_glBufferData( TEB *teb, GLenum target, GLsizeiptr size, const void *d const struct opengl_funcs *funcs = teb->glTable; struct buffer *buffer; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_target( teb, target ); + if ((buffer = set_target_buffer_storage( teb, target, NULL ))) free_buffer( funcs, buffer ); p_glBufferData( target, size, data, usage ); - pthread_mutex_unlock( &wgl_lock ); - - if (buffer) free_buffer( funcs, buffer ); } void wow64_glBufferStorageMemEXT( TEB *teb, GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset, PFN_glBufferStorageMemEXT p_glBufferStorageMemEXT ) @@ -2429,12 +2406,8 @@ void wow64_glBufferStorageMemEXT( TEB *teb, GLenum target, GLsizeiptr size, GLui const struct opengl_funcs *funcs = teb->glTable; struct buffer *buffer; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_target( teb, target ); + if ((buffer = set_target_buffer_storage( teb, target, NULL ))) free_buffer( funcs, buffer ); p_glBufferStorageMemEXT( target, size, memory, offset ); - pthread_mutex_unlock( &wgl_lock ); - - if (buffer) free_buffer( funcs, buffer ); } void wow64_glNamedBufferAttachMemoryNV( TEB *teb, GLuint name, GLuint memory, GLuint64 offset, PFN_glNamedBufferAttachMemoryNV p_glNamedBufferAttachMemoryNV ) @@ -2442,12 +2415,8 @@ void wow64_glNamedBufferAttachMemoryNV( TEB *teb, GLuint name, GLuint memory, GL const struct opengl_funcs *funcs = teb->glTable; struct buffer *buffer; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_name( teb, name ); + if ((buffer = set_named_buffer_storage( teb, name, NULL ))) free_buffer( funcs, buffer ); p_glNamedBufferAttachMemoryNV( name, memory, offset ); - pthread_mutex_unlock( &wgl_lock ); - - if (buffer) free_buffer( funcs, buffer ); } void wow64_glNamedBufferData( TEB *teb, GLuint name, GLsizeiptr size, const void *data, GLenum usage, PFN_glNamedBufferData p_glNamedBufferData ) @@ -2455,12 +2424,8 @@ void wow64_glNamedBufferData( TEB *teb, GLuint name, GLsizeiptr size, const void const struct opengl_funcs *funcs = teb->glTable; struct buffer *buffer; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_name( teb, name ); + if ((buffer = set_named_buffer_storage( teb, name, NULL ))) free_buffer( funcs, buffer ); p_glNamedBufferData( name, size, data, usage ); - pthread_mutex_unlock( &wgl_lock ); - - if (buffer) free_buffer( funcs, buffer ); } void wow64_glNamedBufferStorageMemEXT( TEB *teb, GLuint name, GLsizeiptr size, GLuint memory, GLuint64 offset, PFN_glNamedBufferStorageMemEXT p_glNamedBufferStorageMemEXT ) @@ -2468,12 +2433,8 @@ void wow64_glNamedBufferStorageMemEXT( TEB *teb, GLuint name, GLsizeiptr size, G const struct opengl_funcs *funcs = teb->glTable; struct buffer *buffer; - pthread_mutex_lock( &wgl_lock ); - buffer = invalidate_buffer_name( teb, name ); + if ((buffer = set_named_buffer_storage( teb, name, NULL ))) free_buffer( funcs, buffer ); p_glNamedBufferStorageMemEXT( name, size, memory, offset ); - pthread_mutex_unlock( &wgl_lock ); - - if (buffer) free_buffer( funcs, buffer ); } NTSTATUS wow64_thread_attach( void *args ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11226
On Thu Jun 25 05:42:33 2026 +0000, Jacek Caban wrote:
What is the point of this? The Vulkan device must be synchronized by the caller, meaning you cannot use that device outside of opengl32 anyway. This splits the logic in a way that makes it both more complicated and awkward (creating and storing it in win32u, but synchronizing it in opengl32, etc.). Note that the synchronization should probably be more fine-tuned than the current global mutex (see bug 58834), and this change will not make implementing that any easier. The point was mostly to isolate the WOW64 code. Creating the device in win32u only seemed to make the code simpler to me, by removing the need for instance and physical device lookup, and allowing us to use the vulkan_driver.h interface, but the current device creation can be kept if it's considered better. Note that all the device lookup and device map isn't very useful, there's only ever going to be one device that matches the OpenGL device, which is why this was creating it on OpenGL init and kept it process-wide.
I'm then not sure what you mean by "the vulkan device must be synchronized", what needs to be synchronized? The vulkan calls? Isn't it fine to call the Vulkan functions we use concurrently? Regarding finer locking, I repurposed this MR to that end instead, as it seems more important, and I'm leaving the device changes for later. Note that however it doesn't fix #58834, because that regression doesn't originate from locking contention. The performance regression is caused by the WOW64 buffer mechanism, and should've appeared earlier. But https://gitlab.winehq.org/wine/wine/-/commit/c25a83bc67e944bdee73c0e43a22b25... fixed a missing length update, and caused an extra copy to happen when buffers are mapped, that wasn't happening before. But I think there's some possible workaround if we allow using pinned memory storage for non-persistent mapping. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11226#note_144172
v2: Drop the code move and Vulkan device creation changes, add buffer storage array and finer locking. The Vulkan device calls are now unguarded, if that actually matters, but I don't think it does? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11226#note_144173
participants (2)
-
Rémi Bernon -
Rémi Bernon (@rbernon)