Module: vkd3d
Branch: master
Commit: 70962ae7d86297fd4b54cd5b9e2d2fd197f3a4b7
URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/70962ae7d86297fd4b54cd5b9e2d2…
Author: Conor McCarthy <cmccarthy(a)codeweavers.com>
Date: Sun Jul 30 13:25:56 2023 +1000
vkd3d: Update the descriptor `next` index before getting a reference for writing.
Fixes a race condition where the descriptor is modified between getting
its object and resetting the `next` index. The new object would never be
written. While it is invalid for the app to write descriptors used by a
command list which has been submitted to a queue, unused descriptors may
be written. This change also supports writing descriptors in a worker
thread.
---
libs/vkd3d/resource.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index abbdfbe2..0c9c911a 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -2632,20 +2632,18 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr
for (; i != UINT_MAX; i = next)
{
src = &descriptors[i];
- next = (int)src->next >> 1;
+ next = vkd3d_atomic_exchange(&src->next, 0);
+ next = (int)next >> 1;
+ /* A race exists here between updating src->next and getting the current object. The best
+ * we can do is get the object last, which may result in a harmless rewrite later. */
u.object = d3d12_desc_get_object_ref(src, device);
if (!u.object)
- {
- vkd3d_atomic_exchange(&src->next, 0);
continue;
- }
writes.held_refs[writes.held_ref_count++] = u.object;
d3d12_desc_write_vk_heap(descriptor_heap, i, &writes, u.object, device);
-
- vkd3d_atomic_exchange(&src->next, 0);
}
/* Avoid thunk calls wherever possible. */