Jan Sikorski : wined3d: Avoid the pipeline barrier when mapping buffer objects backing textures.

Alexandre Julliard julliard at winehq.org
Wed Sep 15 16:21:32 CDT 2021


Module: wine
Branch: master
Commit: 752551fa309553259887280c40da8ca424f49d37
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=752551fa309553259887280c40da8ca424f49d37

Author: Jan Sikorski <jsikorski at codeweavers.com>
Date:   Fri Sep 10 15:58:42 2021 +0200

wined3d: Avoid the pipeline barrier when mapping buffer objects backing textures.

Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/adapter_vk.c      | 43 +++++++++++++++++++++++-------------------
 dlls/wined3d/context_vk.c      |  2 ++
 dlls/wined3d/texture.c         |  9 +++++++++
 dlls/wined3d/wined3d_private.h |  1 +
 4 files changed, 36 insertions(+), 19 deletions(-)

diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 69a93f88435..18c73312daf 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -934,9 +934,11 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
     {
         if (wined3d_context_vk_create_bo(context_vk, bo->size, bo->usage, bo->memory_type, &tmp))
         {
+            bool host_synced = bo->host_synced;
             list_move_head(&tmp.users, &bo->users);
             wined3d_context_vk_destroy_bo(context_vk, bo);
             *bo = tmp;
+            bo->host_synced = host_synced;
             list_init(&bo->users);
             list_move_head(&bo->users, &tmp.users);
             LIST_FOR_EACH_ENTRY(bo_user, &bo->users, struct wined3d_bo_user, entry)
@@ -952,25 +954,30 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
 
     if (map_flags & WINED3D_MAP_READ)
     {
-        if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk)))
+        if (!bo->host_synced)
         {
-            ERR("Failed to get command buffer.\n");
-            return NULL;
-        }
-
-        wined3d_context_vk_end_current_render_pass(context_vk);
+            if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk)))
+            {
+                ERR("Failed to get command buffer.\n");
+                return NULL;
+            }
 
-        vk_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
-        vk_barrier.pNext = NULL;
-        vk_barrier.srcAccessMask = vk_access_mask_from_buffer_usage(bo->usage);
-        vk_barrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
-        vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
-        vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
-        vk_barrier.buffer = bo->vk_buffer;
-        vk_barrier.offset = bo->buffer_offset + (uintptr_t)data->addr;
-        vk_barrier.size = size;
-        VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
-                VK_PIPELINE_STAGE_HOST_BIT, 0, 0, NULL, 1, &vk_barrier, 0, NULL));
+            wined3d_context_vk_end_current_render_pass(context_vk);
+
+            vk_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
+            vk_barrier.pNext = NULL;
+            vk_barrier.srcAccessMask = vk_access_mask_from_buffer_usage(bo->usage);
+            vk_barrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
+            vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+            vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+            vk_barrier.buffer = bo->vk_buffer;
+            vk_barrier.offset = bo->buffer_offset + (uintptr_t)data->addr;
+            vk_barrier.size = size;
+            VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                    VK_PIPELINE_STAGE_HOST_BIT, 0, 0, NULL, 1, &vk_barrier, 0, NULL));
+
+            wined3d_context_vk_reference_bo(context_vk, bo);
+        }
 
         if (!(bo->memory_type & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
         {
@@ -981,8 +988,6 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
             range.size = size;
             VK_CALL(vkInvalidateMappedMemoryRanges(device_vk->vk_device, 1, &range));
         }
-
-        wined3d_context_vk_reference_bo(context_vk, bo);
     }
 
     if (bo->command_buffer_id == context_vk->current_command_buffer.id)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 705f789ed5f..aeaeca322ff 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -415,6 +415,7 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
     bo->size = size;
     list_init(&bo->users);
     bo->command_buffer_id = 0;
+    bo->host_synced = false;
 
     TRACE("Using buffer 0x%s, memory 0x%s, offset 0x%s for bo %p.\n",
             wine_dbgstr_longlong(bo->vk_buffer), wine_dbgstr_longlong(bo->vk_memory),
@@ -494,6 +495,7 @@ BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDevic
     list_init(&bo->users);
     bo->command_buffer_id = 0;
     bo->slab = NULL;
+    bo->host_synced = false;
 
     TRACE("Created buffer 0x%s, memory 0x%s for bo %p.\n",
             wine_dbgstr_longlong(bo->vk_buffer), wine_dbgstr_longlong(bo->vk_memory), bo);
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 580bbd207e3..d3de37e75db 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -5019,6 +5019,12 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context,
         vk_barrier.dstAccessMask = vk_barrier.srcAccessMask;
         vk_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
 
+        if (dst_bo->host_synced)
+        {
+            vk_barrier.srcAccessMask |= VK_ACCESS_HOST_READ_BIT;
+            bo_stage_flags |= VK_PIPELINE_STAGE_HOST_BIT;
+        }
+
         VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
                 bo_stage_flags, 0, 0, NULL, 1, &vk_barrier, 0, NULL));
     }
@@ -5198,6 +5204,9 @@ static BOOL wined3d_texture_vk_prepare_buffer_object(struct wined3d_texture_vk *
             VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bo))
         return FALSE;
 
+    /* Texture buffer objects receive a barrier to HOST_READ in wined3d_texture_vk_download_data(),
+     * so they don't need it when they are mapped for reading. */
+    bo->host_synced = true;
     TRACE("Created buffer object %p for texture %p, sub-resource %u.\n", bo, texture_vk, sub_resource_idx);
     return TRUE;
 }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f2b967e82ad..df9cfc284b9 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1627,6 +1627,7 @@ struct wined3d_bo_vk
 
     struct list users;
     uint64_t command_buffer_id;
+    bool host_synced;
 };
 
 struct wined3d_bo_slab_vk_key




More information about the wine-cvs mailing list