Zebediah Figura : wined3d: Protect access to the OpenGL wined3d_allocator with a critical section.

Alexandre Julliard julliard at winehq.org
Wed Feb 16 15:30:24 CST 2022


Module: wine
Branch: master
Commit: 4a3cefab75e797398923c54340beb5764c42a28e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=4a3cefab75e797398923c54340beb5764c42a28e

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Tue Feb 15 21:28:10 2022 -0600

wined3d: Protect access to the OpenGL wined3d_allocator with a critical section.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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;




More information about the wine-cvs mailing list