From 4a3cefab75e797398923c54340beb5764c42a28e Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 15 Feb 2022 21:28:10 -0600 Subject: [PATCH] wined3d: Protect access to the OpenGL wined3d_allocator with a critical section. Signed-off-by: Zebediah Figura Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/adapter_gl.c | 4 ++++ dlls/wined3d/context_gl.c | 12 ++++++++++-- dlls/wined3d/device.c | 5 +++++ dlls/wined3d/wined3d_private.h | 11 +++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index 2e31d140dd5..bc54f46222f 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -4274,6 +4274,8 @@ static HRESULT adapter_gl_create_device(struct wined3d *wined3d, const struct wi return hr; } + wined3d_lock_init(&device_gl->allocator_cs, "wined3d_device_gl.allocator_cs"); + *device = &device_gl->d; return WINED3D_OK; } @@ -4283,6 +4285,8 @@ static void adapter_gl_destroy_device(struct wined3d_device *device) struct wined3d_device_gl *device_gl = wined3d_device_gl(device); wined3d_device_cleanup(&device_gl->d); + wined3d_lock_cleanup(&device_gl->allocator_cs); + heap_free(device_gl->retired_blocks); heap_free(device_gl); } diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 8901bafcce3..8217d04686c 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -2629,6 +2629,14 @@ static void wined3d_context_gl_poll_fences(struct wined3d_context_gl *context_gl } } +static void wined3d_device_gl_free_memory(struct wined3d_device_gl *device_gl, struct wined3d_allocator_block *block) +{ + assert(block->chunk->allocator == &device_gl->allocator); + wined3d_device_gl_allocator_lock(device_gl); + wined3d_allocator_block_free(block); + wined3d_device_gl_allocator_unlock(device_gl); +} + static void wined3d_context_gl_cleanup_resources(struct wined3d_context_gl *context_gl) { struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device); @@ -2651,7 +2659,7 @@ static void wined3d_context_gl_cleanup_resources(struct wined3d_context_gl *cont continue; } - wined3d_allocator_block_free(r->block); + wined3d_device_gl_free_memory(device_gl, r->block); if (i != --count) *r = blocks[count]; else @@ -2718,7 +2726,7 @@ static void wined3d_context_gl_destroy_allocator_block(struct wined3d_context_gl if (device_gl->completed_fence_id > fence_id) { - wined3d_allocator_block_free(block); + wined3d_device_gl_free_memory(device_gl, block); TRACE("Freed block %p.\n", block); return; } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 84d2e3a0ce8..e302e1917a6 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1059,20 +1059,25 @@ static struct wined3d_allocator_block *wined3d_device_gl_allocate_memory(struct struct wined3d_allocator *allocator = &device_gl->allocator; struct wined3d_allocator_block *block; + wined3d_device_gl_allocator_lock(device_gl); + if (size > WINED3D_ALLOCATOR_CHUNK_SIZE / 2) { *id = wined3d_context_gl_allocate_vram_chunk_buffer(context_gl, memory_type, size); + wined3d_device_gl_allocator_unlock(device_gl); return NULL; } if (!(block = wined3d_allocator_allocate(allocator, &context_gl->c, memory_type, size))) { + wined3d_device_gl_allocator_unlock(device_gl); *id = 0; return NULL; } *id = wined3d_allocator_chunk_gl(block->chunk)->gl_buffer; + wined3d_device_gl_allocator_unlock(device_gl); return block; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 48b760edc1b..96ce75fbb58 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4194,6 +4194,7 @@ struct wined3d_device_gl /* Textures for when no other textures are bound. */ struct wined3d_dummy_textures dummy_textures; + CRITICAL_SECTION allocator_cs; struct wined3d_allocator allocator; uint64_t completed_fence_id; uint64_t current_fence_id; @@ -4212,6 +4213,16 @@ static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device return CONTAINING_RECORD(device, struct wined3d_device_gl, d); } +static inline void wined3d_device_gl_allocator_lock(struct wined3d_device_gl *device_gl) +{ + EnterCriticalSection(&device_gl->allocator_cs); +} + +static inline void wined3d_device_gl_allocator_unlock(struct wined3d_device_gl *device_gl) +{ + LeaveCriticalSection(&device_gl->allocator_cs); +} + bool wined3d_device_gl_create_bo(struct wined3d_device_gl *device_gl, struct wined3d_context_gl *context_gl, GLsizeiptr size, GLenum binding, GLenum usage, bool coherent, GLbitfield flags, struct wined3d_bo_gl *bo) DECLSPEC_HIDDEN; -- 2.11.4.GIT