[PATCH vkd3d 2/4] vkd3d: Skip redundant descriptor copies.

Conor McCarthy cmccarthy at codeweavers.com
Tue Sep 21 01:00:08 CDT 2021


Greatly improves performance in Control in Proton (but upstream
vkd3d/Wine currently only renders the intro screens in DX12 mode).

Based on a vkd3d-proton patch by Philip Rebohle.

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 libs/vkd3d/resource.c | 37 +++++++++++++++++++++++++++++--------
 1 file changed, 29 insertions(+), 8 deletions(-)

diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index cae5b580..2c6c07c7 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -2153,24 +2153,45 @@ static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_devic
 void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src,
         struct d3d12_device *device)
 {
+    bool needs_update = true;
     struct d3d12_desc tmp;
     pthread_mutex_t *mutex;
 
     assert(dst != src);
 
     /* Shadow of the Tomb Raider and possibly other titles sometimes destroy
-     * and rewrite a descriptor in another thread while it is being copied. */
-    mutex = d3d12_device_get_descriptor_mutex(device, src);
-    pthread_mutex_lock(mutex);
+     * and rewrite a descriptor in another thread while it is being copied.
+     * We don't need to lock either descriptor for the update check. We only care
+     * about preventing use-after-free of the vkd3d_view caused by a race condiion
+     * in the calling app. It's not important if needs_update falls out of date as
+     * it's their race condition, not ours. */
+    if (dst->magic == src->magic)
+    {
+        if (dst->magic & VKD3D_DESCRIPTOR_MAGIC_HAS_VIEW)
+        {
+            needs_update = dst->u.view != src->u.view;
+        }
+        else if (dst->magic != VKD3D_DESCRIPTOR_MAGIC_FREE)
+        {
+            needs_update = dst->u.vk_cbv_info.buffer != src->u.vk_cbv_info.buffer ||
+                dst->u.vk_cbv_info.offset != src->u.vk_cbv_info.offset ||
+                dst->u.vk_cbv_info.range != src->u.vk_cbv_info.range;
+        }
+    }
 
-    if (src->magic & VKD3D_DESCRIPTOR_MAGIC_HAS_VIEW)
-        vkd3d_view_incref(src->u.view);
+    if (needs_update)
+    {
+        mutex = d3d12_device_get_descriptor_mutex(device, src);
+        pthread_mutex_lock(mutex);
 
-    tmp = *src;
+        if (src->magic & VKD3D_DESCRIPTOR_MAGIC_HAS_VIEW)
+            vkd3d_view_incref(src->u.view);
+        tmp = *src;
 
-    pthread_mutex_unlock(mutex);
+        pthread_mutex_unlock(mutex);
 
-    d3d12_desc_write_atomic(dst, &tmp, device);
+        d3d12_desc_write_atomic(dst, &tmp, device);
+    }
 }
 
 static VkDeviceSize vkd3d_get_required_texel_buffer_alignment(const struct d3d12_device *device,
-- 
2.32.0




More information about the wine-devel mailing list