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