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