Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- 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 d4069361424..219ccfae6a6 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 a415dc53372..6b69465c92b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1626,6 +1626,7 @@ struct wined3d_bo_vk
struct list users; uint64_t command_buffer_id; + bool host_synced; };
struct wined3d_bo_slab_vk_key