Jan Sikorski : wined3d: Don't do a full cleanup when waiting for a command buffer.
Alexandre Julliard
julliard at winehq.org
Fri May 13 15:45:12 CDT 2022
Module: wine
Branch: master
Commit: 3147de2569af8e6b17d35822140ffd01f6c8d8b6
URL: https://source.winehq.org/git/wine.git/?a=commit;h=3147de2569af8e6b17d35822140ffd01f6c8d8b6
Author: Jan Sikorski <jsikorski at codeweavers.com>
Date: Tue May 3 17:03:28 2022 +0200
wined3d: Don't do a full cleanup when waiting for a command buffer.
Only clean while the command buffer is running. A full cleanup is done
after submitting to the queue. It can take a while, and we don't
necessarily want to delay submitting.
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/context_vk.c | 65 ++++++++++++++++++++++++++----------------
dlls/wined3d/wined3d_private.h | 1 -
2 files changed, 40 insertions(+), 26 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index b19220c2e34..aa3b45d54fd 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -1067,11 +1067,30 @@ void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const
wined3d_context_vk_destroy_vk_memory(context_vk, bo->vk_memory, bo->command_buffer_id);
}
-void wined3d_context_vk_poll_command_buffers(struct wined3d_context_vk *context_vk)
+static void wined3d_context_vk_remove_command_buffer(struct wined3d_context_vk *context_vk,
+ unsigned int submit_index)
{
+ struct wined3d_command_buffer_vk *buffer = &context_vk->submitted.buffers[submit_index];
struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+
+ VK_CALL(vkDestroyFence(device_vk->vk_device, buffer->vk_fence, NULL));
+ VK_CALL(vkFreeCommandBuffers(device_vk->vk_device,
+ context_vk->vk_command_pool, 1, &buffer->vk_command_buffer));
+
+ if (buffer->id > context_vk->completed_command_buffer_id)
+ context_vk->completed_command_buffer_id = buffer->id;
+ *buffer = context_vk->submitted.buffers[--context_vk->submitted.buffer_count];
+}
+
+static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *context_vk, VkFence vk_fence)
+{
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
+ struct wined3d_retired_objects_vk *retired = &context_vk->retired;
+ const struct wined3d_vk_info *vk_info = context_vk->vk_info;
struct wined3d_command_buffer_vk *buffer;
+ struct wined3d_retired_object_vk *o;
+ uint64_t command_buffer_id;
SIZE_T i = 0;
while (i < context_vk->submitted.buffer_count)
@@ -1085,26 +1104,11 @@ void wined3d_context_vk_poll_command_buffers(struct wined3d_context_vk *context_
TRACE("Command buffer %p with id 0x%s has finished.\n",
buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id));
- VK_CALL(vkDestroyFence(device_vk->vk_device, buffer->vk_fence, NULL));
- VK_CALL(vkFreeCommandBuffers(device_vk->vk_device,
- context_vk->vk_command_pool, 1, &buffer->vk_command_buffer));
-
- if (buffer->id > context_vk->completed_command_buffer_id)
- context_vk->completed_command_buffer_id = buffer->id;
- *buffer = context_vk->submitted.buffers[--context_vk->submitted.buffer_count];
+ if (buffer->vk_fence == vk_fence)
+ return;
+ wined3d_context_vk_remove_command_buffer(context_vk, i);
}
-}
-static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *context_vk)
-{
- struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
- struct wined3d_retired_objects_vk *retired = &context_vk->retired;
- const struct wined3d_vk_info *vk_info = context_vk->vk_info;
- struct wined3d_retired_object_vk *o;
- uint64_t command_buffer_id;
- SIZE_T i = 0;
-
- wined3d_context_vk_poll_command_buffers(context_vk);
command_buffer_id = context_vk->completed_command_buffer_id;
retired->free = NULL;
@@ -1194,6 +1198,9 @@ static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *cont
o->type = WINED3D_RETIRED_FREE_VK;
o->u.next = retired->free;
retired->free = o;
+
+ if (vk_fence && VK_CALL(vkGetFenceStatus(device_vk->vk_device, vk_fence)) != VK_NOT_READY)
+ break;
}
}
@@ -1649,7 +1656,7 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
VK_CALL(vkDestroyCommandPool(device_vk->vk_device, context_vk->vk_command_pool, NULL));
if (context_vk->vk_so_counter_bo.vk_buffer)
wined3d_context_vk_destroy_bo(context_vk, &context_vk->vk_so_counter_bo);
- wined3d_context_vk_cleanup_resources(context_vk);
+ wined3d_context_vk_cleanup_resources(context_vk, VK_NULL_HANDLE);
wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_occlusion_query_pools);
wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_timestamp_query_pools);
wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_pipeline_statistics_query_pools);
@@ -1820,13 +1827,14 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context
buffer->id = 1;
}
context_vk->retired_bo_size = 0;
- wined3d_context_vk_cleanup_resources(context_vk);
+ wined3d_context_vk_cleanup_resources(context_vk, VK_NULL_HANDLE);
}
void wined3d_context_vk_wait_command_buffer(struct wined3d_context_vk *context_vk, uint64_t id)
{
struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+ VkFence vk_fence;
SIZE_T i;
if (id <= context_vk->completed_command_buffer_id
@@ -1838,10 +1846,17 @@ void wined3d_context_vk_wait_command_buffer(struct wined3d_context_vk *context_v
if (context_vk->submitted.buffers[i].id != id)
continue;
- VK_CALL(vkWaitForFences(device_vk->vk_device, 1,
- &context_vk->submitted.buffers[i].vk_fence, VK_TRUE, UINT64_MAX));
- wined3d_context_vk_cleanup_resources(context_vk);
- return;
+ vk_fence = context_vk->submitted.buffers[i].vk_fence;
+ wined3d_context_vk_cleanup_resources(context_vk, vk_fence);
+ for (i = 0; i < context_vk->submitted.buffer_count; ++i)
+ {
+ if (context_vk->submitted.buffers[i].id != id)
+ continue;
+
+ VK_CALL(vkWaitForFences(device_vk->vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX));
+ wined3d_context_vk_remove_command_buffer(context_vk, i);
+ return;
+ }
}
ERR("Failed to find fence for command buffer with id 0x%s.\n", wine_dbgstr_longlong(id));
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 3a12f5ef261..385c84ffcbf 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2685,7 +2685,6 @@ void wined3d_context_vk_image_barrier(struct wined3d_context_vk *context_vk,
VkImageLayout new_layout, VkImage image, const VkImageSubresourceRange *range) DECLSPEC_HIDDEN;
HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
-void wined3d_context_vk_poll_command_buffers(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context_vk,
unsigned int wait_semaphore_count, const VkSemaphore *wait_semaphores, const VkPipelineStageFlags *wait_stages,
unsigned int signal_semaphore_count, const VkSemaphore *signal_semaphores) DECLSPEC_HIDDEN;
More information about the wine-cvs
mailing list