[PATCH 5/8] wined3d: Protect access to the Vulkan wined3d_allocator with a critical section.
Zebediah Figura
zfigura at codeweavers.com
Tue Nov 2 18:20:10 CDT 2021
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 9 +++++++++
dlls/wined3d/context_vk.c | 31 +++++++++++++++++++++++++++----
dlls/wined3d/wined3d_private.h | 1 +
3 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 218b7dc74ba..020a70b4ed4 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -517,6 +517,10 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
#undef VK_DEVICE_EXT_PFN
#undef VK_DEVICE_PFN
+ 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");
+
if (!wined3d_allocator_init(&device_vk->allocator,
adapter_vk->memory_properties.memoryTypeCount, &wined3d_allocator_vk_ops))
{
@@ -551,6 +555,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 a6a2ea8a44b..21239bd74b9 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -312,23 +312,36 @@ static struct wined3d_allocator_block *wined3d_device_vk_allocate_memory(struct
struct wined3d_allocator *allocator = &device_vk->allocator;
struct wined3d_allocator_block *block;
+ EnterCriticalSection(&device_vk->allocator_cs);
+
if (size > WINED3D_ALLOCATOR_CHUNK_SIZE / 2)
{
*vk_memory = wined3d_context_vk_allocate_vram_chunk_memory(context_vk, memory_type, size);
+ LeaveCriticalSection(&device_vk->allocator_cs);
return NULL;
}
if (!(block = wined3d_allocator_allocate(allocator, &context_vk->c, memory_type, size)))
{
+ LeaveCriticalSection(&device_vk->allocator_cs);
*vk_memory = VK_NULL_HANDLE;
return NULL;
}
*vk_memory = wined3d_allocator_chunk_vk(block->chunk)->vk_memory;
+ LeaveCriticalSection(&device_vk->allocator_cs);
return block;
}
+static void wined3d_device_vk_free_memory(struct wined3d_device_vk *device_vk, struct wined3d_allocator_block *block)
+{
+ assert(block->chunk->allocator == &device_vk->allocator);
+ EnterCriticalSection(&device_vk->allocator_cs);
+ wined3d_allocator_block_free(block);
+ LeaveCriticalSection(&device_vk->allocator_cs);
+}
+
static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk,
VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo)
{
@@ -359,6 +372,8 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
key.usage = usage;
key.size = 32 * object_size;
+ EnterCriticalSection(&device_vk->allocator_cs);
+
if ((entry = wine_rb_get(&device_vk->bo_slab_available, &key)))
{
slab = WINE_RB_ENTRY_VALUE(entry, struct wined3d_bo_slab_vk, entry);
@@ -368,6 +383,7 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
{
if (!(slab = heap_alloc_zero(sizeof(*slab))))
{
+ LeaveCriticalSection(&device_vk->allocator_cs);
ERR("Failed to allocate bo slab.\n");
return false;
}
@@ -375,6 +391,7 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
slab->requested_memory_type = memory_type;
if (!wined3d_device_vk_create_bo(device_vk, context_vk, key.size, usage, memory_type, &slab->bo))
{
+ LeaveCriticalSection(&device_vk->allocator_cs);
ERR("Failed to create slab bo.\n");
heap_free(slab);
return false;
@@ -406,6 +423,8 @@ static bool wined3d_device_vk_create_slab_bo(struct wined3d_device_vk *device_vk
}
}
+ LeaveCriticalSection(&device_vk->allocator_cs);
+
*bo = slab->bo;
bo->memory = NULL;
bo->slab = slab;
@@ -478,7 +497,7 @@ BOOL wined3d_device_vk_create_bo(struct wined3d_device_vk *device_vk, struct win
{
ERR("Failed to bind buffer memory, vr %s.\n", wined3d_debug_vkresult(vr));
if (bo->memory)
- wined3d_allocator_block_free(bo->memory);
+ wined3d_device_vk_free_memory(device_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));
@@ -572,7 +591,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_device_vk_free_memory(device_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));
@@ -686,7 +705,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_device_vk_free_memory(wined3d_device_vk(context_vk->c.device), block);
TRACE("Freed block %p.\n", block);
return;
}
@@ -711,6 +730,8 @@ static void wined3d_bo_slab_vk_free_slice(struct wined3d_bo_slab_vk *slab,
TRACE("slab %p, idx %lu, context_vk %p.\n", slab, idx, context_vk);
+ EnterCriticalSection(&device_vk->allocator_cs);
+
if (!slab->map)
{
key.memory_type = slab->requested_memory_type;
@@ -728,6 +749,8 @@ static void wined3d_bo_slab_vk_free_slice(struct wined3d_bo_slab_vk *slab,
}
}
slab->map |= 1u << idx;
+
+ LeaveCriticalSection(&device_vk->allocator_cs);
}
static void wined3d_context_vk_destroy_bo_slab_slice(struct wined3d_context_vk *context_vk,
@@ -999,7 +1022,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_device_vk_free_memory(device_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 d8b16c0d074..21b4ef2e103 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4081,6 +4081,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;
--
2.33.0
More information about the wine-devel
mailing list