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

Signed-off-by: Jan Sikorski <jsikorski@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jan Sikorski 2021-09-10 15:58:42 +02:00 committed by Alexandre Julliard
parent 4466d5b51c
commit 752551fa30
4 changed files with 36 additions and 19 deletions

View File

@ -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,26 +954,31 @@ 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;
if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk)))
{
ERR("Failed to get command buffer.\n");
return 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);
}
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));
if (!(bo->memory_type & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
{
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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