[PATCH v2 1/7] wined3d: Protect access to the Vulkan wined3d_allocator with a mutex.
Zebediah Figura
zfigura at codeweavers.com
Wed Nov 3 23:46:55 CDT 2021
So that it can be accessed from the client thread.
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 9 ++++++
dlls/wined3d/context_vk.c | 52 ++++++++++++++++++++++++++--------
dlls/wined3d/wined3d_private.h | 11 +++++++
3 files changed, 60 insertions(+), 12 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 02a359c4f07..cbf7c94fd3a 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -521,6 +521,10 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
goto fail;
}
+ InitializeCriticalSection(&device_vk->allocator_cs);
+ if (device_vk->allocator_cs.DebugInfo != (RTL_CRITICAL_SECTION_DEBUG *)-1)
+ device_vk->allocator_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wined3d_device_vk.allocator_cs");
+
*device = &device_vk->d;
return WINED3D_OK;
@@ -538,6 +542,11 @@ static void adapter_vk_destroy_device(struct wined3d_device *device)
wined3d_device_cleanup(&device_vk->d);
wined3d_allocator_cleanup(&device_vk->allocator);
+
+ if (device_vk->allocator_cs.DebugInfo != (RTL_CRITICAL_SECTION_DEBUG *)-1)
+ device_vk->allocator_cs.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&device_vk->allocator_cs);
+
VK_CALL(vkDestroyDevice(device_vk->vk_device, NULL));
heap_free(device_vk);
}
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index ad7b0a8ba86..54c5eb6bc24 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -313,27 +313,43 @@ static struct wined3d_allocator_block *wined3d_context_vk_allocate_memory(struct
struct wined3d_allocator *allocator = &device_vk->allocator;
struct wined3d_allocator_block *block;
+ wined3d_device_vk_allocator_lock(device_vk);
+
if (size > WINED3D_ALLOCATOR_CHUNK_SIZE / 2)
{
*vk_memory = wined3d_context_vk_allocate_vram_chunk_memory(context_vk, memory_type, size);
+ wined3d_device_vk_allocator_unlock(device_vk);
return NULL;
}
if (!(block = wined3d_allocator_allocate(allocator, &context_vk->c, memory_type, size)))
{
+ wined3d_device_vk_allocator_unlock(device_vk);
*vk_memory = VK_NULL_HANDLE;
return NULL;
}
*vk_memory = wined3d_allocator_chunk_vk(block->chunk)->vk_memory;
+ wined3d_device_vk_allocator_unlock(device_vk);
return block;
}
+static void wined3d_context_vk_free_memory(struct wined3d_context_vk *context_vk, struct wined3d_allocator_block *block)
+{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
+
+ assert(block->chunk->allocator == &device_vk->allocator);
+ wined3d_device_vk_allocator_lock(device_vk);
+ wined3d_allocator_block_free(block);
+ wined3d_device_vk_allocator_unlock(device_vk);
+}
+
static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context_vk,
VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo)
{
const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(context_vk->c.device->adapter);
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
const VkPhysicalDeviceLimits *limits = &adapter_vk->device_limits;
struct wined3d_bo_slab_vk_key key;
struct wined3d_bo_slab_vk *slab;
@@ -360,6 +376,8 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
key.usage = usage;
key.size = 32 * object_size;
+ wined3d_device_vk_allocator_lock(device_vk);
+
if ((entry = wine_rb_get(&context_vk->bo_slab_available, &key)))
{
slab = WINE_RB_ENTRY_VALUE(entry, struct wined3d_bo_slab_vk, entry);
@@ -369,27 +387,30 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
{
if (!(slab = heap_alloc_zero(sizeof(*slab))))
{
+ wined3d_device_vk_allocator_unlock(device_vk);
ERR("Failed to allocate bo slab.\n");
return false;
}
+ if (wine_rb_put(&context_vk->bo_slab_available, &key, &slab->entry) < 0)
+ {
+ wined3d_device_vk_allocator_unlock(device_vk);
+ ERR("Failed to add slab to available tree.\n");
+ heap_free(slab);
+ return false;
+ }
+
slab->requested_memory_type = memory_type;
if (!wined3d_context_vk_create_bo(context_vk, key.size, usage, memory_type, &slab->bo))
{
+ wined3d_device_vk_allocator_unlock(device_vk);
ERR("Failed to create slab bo.\n");
+ wine_rb_remove(&context_vk->bo_slab_available, &slab->entry);
heap_free(slab);
return false;
}
slab->map = ~0u;
- if (wine_rb_put(&context_vk->bo_slab_available, &key, &slab->entry) < 0)
- {
- ERR("Failed to add slab to available tree.\n");
- wined3d_context_vk_destroy_bo(context_vk, &slab->bo);
- heap_free(slab);
- return false;
- }
-
TRACE("Created new bo slab %p.\n", slab);
}
@@ -407,6 +428,8 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
}
}
+ wined3d_device_vk_allocator_unlock(device_vk);
+
*bo = slab->bo;
bo->memory = NULL;
bo->slab = slab;
@@ -480,7 +503,7 @@ BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDevic
{
ERR("Failed to bind buffer memory, vr %s.\n", wined3d_debug_vkresult(vr));
if (bo->memory)
- wined3d_allocator_block_free(bo->memory);
+ wined3d_context_vk_free_memory(context_vk, bo->memory);
else
VK_CALL(vkFreeMemory(device_vk->vk_device, bo->vk_memory, NULL));
VK_CALL(vkDestroyBuffer(device_vk->vk_device, bo->vk_buffer, NULL));
@@ -574,7 +597,7 @@ BOOL wined3d_context_vk_create_image(struct wined3d_context_vk *context_vk, VkIm
{
VK_CALL(vkDestroyImage(device_vk->vk_device, image->vk_image, NULL));
if (image->memory)
- wined3d_allocator_block_free(image->memory);
+ wined3d_context_vk_free_memory(context_vk, image->memory);
else
VK_CALL(vkFreeMemory(device_vk->vk_device, image->vk_memory, NULL));
ERR("Failed to bind image memory, vr %s.\n", wined3d_debug_vkresult(vr));
@@ -688,7 +711,7 @@ void wined3d_context_vk_destroy_allocator_block(struct wined3d_context_vk *conte
if (context_vk->completed_command_buffer_id > command_buffer_id)
{
- wined3d_allocator_block_free(block);
+ wined3d_context_vk_free_memory(context_vk, block);
TRACE("Freed block %p.\n", block);
return;
}
@@ -707,11 +730,14 @@ void wined3d_context_vk_destroy_allocator_block(struct wined3d_context_vk *conte
static void wined3d_bo_slab_vk_free_slice(struct wined3d_bo_slab_vk *slab,
SIZE_T idx, struct wined3d_context_vk *context_vk)
{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
struct wined3d_bo_slab_vk_key key;
struct wine_rb_entry *entry;
TRACE("slab %p, idx %lu, context_vk %p.\n", slab, idx, context_vk);
+ wined3d_device_vk_allocator_lock(device_vk);
+
if (!slab->map)
{
key.memory_type = slab->requested_memory_type;
@@ -729,6 +755,8 @@ static void wined3d_bo_slab_vk_free_slice(struct wined3d_bo_slab_vk *slab,
}
}
slab->map |= 1u << idx;
+
+ wined3d_device_vk_allocator_unlock(device_vk);
}
static void wined3d_context_vk_destroy_bo_slab_slice(struct wined3d_context_vk *context_vk,
@@ -1000,7 +1028,7 @@ static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *cont
case WINED3D_RETIRED_ALLOCATOR_BLOCK_VK:
TRACE("Destroying block %p.\n", o->u.block);
- wined3d_allocator_block_free(o->u.block);
+ wined3d_context_vk_free_memory(context_vk, o->u.block);
break;
case WINED3D_RETIRED_BO_SLAB_SLICE_VK:
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index aa8974366a6..62b92ce7c34 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4084,6 +4084,7 @@ struct wined3d_device_vk
struct wined3d_null_resources_vk null_resources_vk;
struct wined3d_null_views_vk null_views_vk;
+ CRITICAL_SECTION allocator_cs;
struct wined3d_allocator allocator;
struct wined3d_uav_clear_state_vk uav_clear_state;
@@ -4094,6 +4095,16 @@ static inline struct wined3d_device_vk *wined3d_device_vk(struct wined3d_device
return CONTAINING_RECORD(device, struct wined3d_device_vk, d);
}
+static inline void wined3d_device_vk_allocator_lock(struct wined3d_device_vk *device_vk)
+{
+ EnterCriticalSection(&device_vk->allocator_cs);
+}
+
+static inline void wined3d_device_vk_allocator_unlock(struct wined3d_device_vk *device_vk)
+{
+ LeaveCriticalSection(&device_vk->allocator_cs);
+}
+
bool wined3d_device_vk_create_null_resources(struct wined3d_device_vk *device_vk,
struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
bool wined3d_device_vk_create_null_views(struct wined3d_device_vk *device_vk,
--
2.33.0
More information about the wine-devel
mailing list