Submit current command buffer in wined3d_context_vk_get_command_buffer() and return a new one if the total size of retired buffer objects on that command buffer crosses a predefined threshold.
One way this issue may arise is when an application, by repeatedly doing resource updates, does not trigger a flush of the command buffer and accumulates transient staging buffers.
Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- v2: Changed accumulator type to VkDeviceSize, changed naming, added extra explanation to the commit message. --- dlls/wined3d/context_vk.c | 15 ++++++++++++--- dlls/wined3d/wined3d_private.h | 2 ++ 2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 45133eabb69..8719d54644b 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -921,6 +921,9 @@ void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const if (bo->map_ptr) VK_CALL(vkUnmapMemory(device_vk->vk_device, bo->vk_memory)); wined3d_context_vk_destroy_vk_memory(context_vk, bo->vk_memory, bo->command_buffer_id); + + if (bo->command_buffer_id == context_vk->current_command_buffer.id) + context_vk->retired_bo_size += bo->size; }
void wined3d_context_vk_poll_command_buffers(struct wined3d_context_vk *context_vk) @@ -1509,9 +1512,14 @@ VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk buffer = &context_vk->current_command_buffer; if (buffer->vk_command_buffer) { - TRACE("Returning existing command buffer %p with id 0x%s.\n", - buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id)); - return buffer->vk_command_buffer; + if (context_vk->retired_bo_size > WINED3D_RETIRED_BO_SIZE_THRESHOLD) + wined3d_context_vk_submit_command_buffer(context_vk, 0, NULL, NULL, 0, NULL); + else + { + TRACE("Returning existing command buffer %p with id 0x%s.\n", + buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id)); + return buffer->vk_command_buffer; + } }
command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; @@ -1628,6 +1636,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context context_vk->completed_command_buffer_id = 0; buffer->id = 1; } + context_vk->retired_bo_size = 0; wined3d_context_vk_cleanup_resources(context_vk); }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c3e3752ed71..0ef6e89f1f1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2549,6 +2549,7 @@ struct wined3d_context_vk VkCommandPool vk_command_pool; struct wined3d_command_buffer_vk current_command_buffer; uint64_t completed_command_buffer_id; + VkDeviceSize retired_bo_size;
struct { @@ -3921,6 +3922,7 @@ struct wined3d_null_views_vk #define WINED3D_ALLOCATOR_CHUNK_ORDER_COUNT 15 #define WINED3D_ALLOCATOR_MIN_BLOCK_SIZE (WINED3D_ALLOCATOR_CHUNK_SIZE >> (WINED3D_ALLOCATOR_CHUNK_ORDER_COUNT - 1)) #define WINED3D_SLAB_BO_MIN_OBJECT_ALIGN 16 +#define WINED3D_RETIRED_BO_SIZE_THRESHOLD (64 * 1024 * 1024)
struct wined3d_allocator_chunk {