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;