Zebediah Figura : wined3d: Protect wined3d_chunk_gl map fields with a mutex.

Alexandre Julliard julliard at winehq.org
Thu Feb 17 15:33:58 CST 2022


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

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Thu Feb 17 00:13:52 2022 -0600

wined3d: Protect wined3d_chunk_gl map fields with a mutex.

Parallel to a5efc1d5e06bf1d88148b4800dc489a527e797c8. Unlike with the Vulkan
backend, we cannot map chunks from the client thread, but we can access the
mapped pointer and increase the map count of already mapped chunks.

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/context_gl.c      | 25 ++++++++++++++++++-------
 dlls/wined3d/device.c          |  3 +--
 dlls/wined3d/wined3d_private.h | 15 +++++++++++++++
 3 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 8217d04686c..b82849f8470 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2778,9 +2778,12 @@ static void *wined3d_allocator_chunk_gl_map(struct wined3d_allocator_chunk_gl *c
         struct wined3d_context_gl *context_gl)
 {
     const struct wined3d_gl_info *gl_info = context_gl->gl_info;
+    void *map_ptr;
 
     TRACE("chunk %p, gl_buffer %u, map_ptr %p.\n", chunk_gl, chunk_gl->gl_buffer, chunk_gl->c.map_ptr);
 
+    wined3d_allocator_chunk_gl_lock(chunk_gl);
+
     if (!chunk_gl->c.map_ptr)
     {
         unsigned int flags = wined3d_device_gl_get_memory_type_flags(chunk_gl->memory_type) & ~GL_CLIENT_STORAGE_BIT;
@@ -2795,6 +2798,7 @@ static void *wined3d_allocator_chunk_gl_map(struct wined3d_allocator_chunk_gl *c
                 0, WINED3D_ALLOCATOR_CHUNK_SIZE, flags));
         if (!chunk_gl->c.map_ptr)
         {
+            wined3d_allocator_chunk_gl_unlock(chunk_gl);
             ERR("Failed to map chunk memory.\n");
             return NULL;
         }
@@ -2803,8 +2807,11 @@ static void *wined3d_allocator_chunk_gl_map(struct wined3d_allocator_chunk_gl *c
     }
 
     ++chunk_gl->c.map_count;
+    map_ptr = chunk_gl->c.map_ptr;
 
-    return chunk_gl->c.map_ptr;
+    wined3d_allocator_chunk_gl_unlock(chunk_gl);
+
+    return map_ptr;
 }
 
 static void wined3d_allocator_chunk_gl_unmap(struct wined3d_allocator_chunk_gl *chunk_gl,
@@ -2814,14 +2821,18 @@ static void wined3d_allocator_chunk_gl_unmap(struct wined3d_allocator_chunk_gl *
 
     TRACE("chunk_gl %p, context_gl %p.\n", chunk_gl, context_gl);
 
-    if (--chunk_gl->c.map_count)
-        return;
+    wined3d_allocator_chunk_gl_lock(chunk_gl);
 
-    wined3d_context_gl_bind_bo(context_gl, GL_PIXEL_UNPACK_BUFFER, chunk_gl->gl_buffer);
-    GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
-    chunk_gl->c.map_ptr = NULL;
+    if (!--chunk_gl->c.map_count)
+    {
+        wined3d_context_gl_bind_bo(context_gl, GL_PIXEL_UNPACK_BUFFER, chunk_gl->gl_buffer);
+        GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
+        chunk_gl->c.map_ptr = NULL;
+
+        adapter_adjust_mapped_memory(context_gl->c.device->adapter, -WINED3D_ALLOCATOR_CHUNK_SIZE);
+    }
 
-    adapter_adjust_mapped_memory(context_gl->c.device->adapter, -WINED3D_ALLOCATOR_CHUNK_SIZE);
+    wined3d_allocator_chunk_gl_unlock(chunk_gl);
 }
 
 static void *wined3d_bo_gl_map(struct wined3d_bo_gl *bo, struct wined3d_context_gl *context_gl, uint32_t flags)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 9488e8c642e..f163e77fcf1 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -993,14 +993,13 @@ static struct wined3d_allocator_chunk *wined3d_allocator_gl_create_chunk(struct
 
 static void wined3d_allocator_gl_destroy_chunk(struct wined3d_allocator_chunk *chunk)
 {
+    struct wined3d_device_gl *device_gl = wined3d_device_gl_from_allocator(chunk->allocator);
     struct wined3d_allocator_chunk_gl *chunk_gl = wined3d_allocator_chunk_gl(chunk);
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context_gl *context_gl;
-    struct wined3d_device_gl *device_gl;
 
     TRACE("chunk %p.\n", chunk);
 
-    device_gl = CONTAINING_RECORD(chunk_gl->c.allocator, struct wined3d_device_gl, allocator);
     context_gl = wined3d_context_gl(context_acquire(&device_gl->d, NULL, 0));
     gl_info = context_gl->gl_info;
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 96ce75fbb58..c8c9bb7c8c6 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4213,6 +4213,11 @@ static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device
     return CONTAINING_RECORD(device, struct wined3d_device_gl, d);
 }
 
+static inline struct wined3d_device_gl *wined3d_device_gl_from_allocator(struct wined3d_allocator *allocator)
+{
+    return CONTAINING_RECORD(allocator, struct wined3d_device_gl, allocator);
+}
+
 static inline void wined3d_device_gl_allocator_lock(struct wined3d_device_gl *device_gl)
 {
     EnterCriticalSection(&device_gl->allocator_cs);
@@ -4223,6 +4228,16 @@ static inline void wined3d_device_gl_allocator_unlock(struct wined3d_device_gl *
     LeaveCriticalSection(&device_gl->allocator_cs);
 }
 
+static inline void wined3d_allocator_chunk_gl_lock(struct wined3d_allocator_chunk_gl *chunk_gl)
+{
+    wined3d_device_gl_allocator_lock(wined3d_device_gl_from_allocator(chunk_gl->c.allocator));
+}
+
+static inline void wined3d_allocator_chunk_gl_unlock(struct wined3d_allocator_chunk_gl *chunk_gl)
+{
+    wined3d_device_gl_allocator_unlock(wined3d_device_gl_from_allocator(chunk_gl->c.allocator));
+}
+
 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