From cdd912b162890a7352efbd531d7232c81dac1432 Mon Sep 17 00:00:00 2001 From: jpark37 Date: Fri, 12 Jun 2020 10:10:55 -0700 Subject: [PATCH] win-capture: Reset command pool rather than buffer Reorganize data to avoid best practices layer warning. Sort of a false positive in our case because we only have one buffer per pool now, but implicit layers should be clean citizens. --- .../graphics-hook/vulkan-capture.c | 167 ++++++++++-------- .../graphics-hook/vulkan-capture.h | 1 + 2 files changed, 91 insertions(+), 77 deletions(-) diff --git a/plugins/win-capture/graphics-hook/vulkan-capture.c b/plugins/win-capture/graphics-hook/vulkan-capture.c index 3723dc0d9..2f0c3c70c 100644 --- a/plugins/win-capture/graphics-hook/vulkan-capture.c +++ b/plugins/win-capture/graphics-hook/vulkan-capture.c @@ -63,11 +63,15 @@ struct vk_queue_data { uint32_t fam_idx; }; -struct vk_cmd_pool_data { +struct vk_frame_data { VkCommandPool cmd_pool; - VkCommandBuffer cmd_buffers[OBJ_MAX]; - VkFence fences[OBJ_MAX]; - bool cmd_buffer_busy[OBJ_MAX]; + VkCommandBuffer cmd_buffer; + VkFence fence; + bool cmd_buffer_busy; +}; + +struct vk_family_data { + struct vk_frame_data frames[OBJ_MAX]; uint32_t image_count; }; @@ -84,7 +88,7 @@ struct vk_data { struct vk_queue_data queues[OBJ_MAX]; uint32_t queue_count; - struct vk_cmd_pool_data cmd_pools[OBJ_MAX]; + struct vk_family_data families[OBJ_MAX]; VkExternalMemoryProperties external_mem_props; struct vk_inst_data *inst_data; @@ -173,36 +177,37 @@ static inline struct vk_data *get_device_data(void *dev) return &device_data[idx]; } -static void vk_shtex_clear_fence(struct vk_data *data, - struct vk_cmd_pool_data *pool_data, - uint32_t image_idx) +static void vk_shtex_clear_fence(const struct vk_data *data, + struct vk_frame_data *frame_data) { - VkFence fence = pool_data->fences[image_idx]; - if (pool_data->cmd_buffer_busy[image_idx]) { + const VkFence fence = frame_data->fence; + if (frame_data->cmd_buffer_busy) { VkDevice device = data->device; - struct vk_device_funcs *funcs = &data->funcs; + const struct vk_device_funcs *funcs = &data->funcs; funcs->WaitForFences(device, 1, &fence, VK_TRUE, ~0ull); funcs->ResetFences(device, 1, &fence); - pool_data->cmd_buffer_busy[image_idx] = false; + frame_data->cmd_buffer_busy = false; } } static void vk_shtex_wait_until_pool_idle(struct vk_data *data, - struct vk_cmd_pool_data *pool_data) + struct vk_family_data *family_data) { - for (uint32_t image_idx = 0; image_idx < pool_data->image_count; + for (uint32_t image_idx = 0; image_idx < family_data->image_count; image_idx++) { - vk_shtex_clear_fence(data, pool_data, image_idx); + struct vk_frame_data *frame_data = + &family_data->frames[image_idx]; + if (frame_data->cmd_pool != VK_NULL_HANDLE) + vk_shtex_clear_fence(data, frame_data); } } static void vk_shtex_wait_until_idle(struct vk_data *data) { - for (uint32_t fam_idx = 0; fam_idx < _countof(data->cmd_pools); + for (uint32_t fam_idx = 0; fam_idx < _countof(data->families); fam_idx++) { - struct vk_cmd_pool_data *pool_data = &data->cmd_pools[fam_idx]; - if (pool_data->cmd_pool != VK_NULL_HANDLE) - vk_shtex_wait_until_pool_idle(data, pool_data); + struct vk_family_data *family_data = &data->families[fam_idx]; + vk_shtex_wait_until_pool_idle(data, family_data); } } @@ -719,50 +724,49 @@ static bool vk_shtex_init(struct vk_data *data, HWND window, return false; } -static void vk_shtex_create_cmd_pool_objects(struct vk_data *data, - uint32_t fam_idx, - uint32_t image_count) +static void vk_shtex_create_family_objects(struct vk_data *data, + uint32_t fam_idx, + uint32_t image_count) { - struct vk_cmd_pool_data *pool_data = &data->cmd_pools[fam_idx]; + struct vk_family_data *family_data = &data->families[fam_idx]; - VkCommandPoolCreateInfo cpci; - cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - cpci.pNext = NULL; - cpci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - cpci.queueFamilyIndex = fam_idx; - - VkResult res = data->funcs.CreateCommandPool( - data->device, &cpci, data->ac, &pool_data->cmd_pool); - debug_res("CreateCommandPool", res); - - VkCommandBufferAllocateInfo cbai; - cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - cbai.pNext = NULL; - cbai.commandPool = pool_data->cmd_pool; - cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - cbai.commandBufferCount = image_count; - - res = data->funcs.AllocateCommandBuffers(data->device, &cbai, - pool_data->cmd_buffers); - debug_res("AllocateCommandBuffers", res); for (uint32_t image_index = 0; image_index < image_count; image_index++) { - /* Dispatch table something or other. Well-designed API. */ - VkCommandBuffer cmd_buffer = - pool_data->cmd_buffers[image_index]; - *(void **)cmd_buffer = *(void **)(data->device); + struct vk_frame_data *frame_data = + &family_data->frames[image_index]; + + VkCommandPoolCreateInfo cpci; + cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + cpci.pNext = NULL; + cpci.flags = 0; + cpci.queueFamilyIndex = fam_idx; + + VkResult res = data->funcs.CreateCommandPool( + data->device, &cpci, data->ac, &frame_data->cmd_pool); + debug_res("CreateCommandPool", res); + + VkCommandBufferAllocateInfo cbai; + cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + cbai.pNext = NULL; + cbai.commandPool = frame_data->cmd_pool; + cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + cbai.commandBufferCount = 1; + + res = data->funcs.AllocateCommandBuffers( + data->device, &cbai, &frame_data->cmd_buffer); + debug_res("AllocateCommandBuffers", res); + *(void **)frame_data->cmd_buffer = *(void **)(data->device); - VkFence *fence = &pool_data->fences[image_index]; VkFenceCreateInfo fci = {0}; fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fci.pNext = NULL; fci.flags = 0; res = data->funcs.CreateFence(data->device, &fci, data->ac, - fence); + &frame_data->fence); debug_res("CreateFence", res); } - pool_data->image_count = image_count; + family_data->image_count = image_count; } static void vk_shtex_destroy_fence(struct vk_data *data, bool *cmd_buffer_busy, @@ -779,21 +783,23 @@ static void vk_shtex_destroy_fence(struct vk_data *data, bool *cmd_buffer_busy, *fence = VK_NULL_HANDLE; } -static void -vk_shtex_destroy_cmd_pool_objects(struct vk_data *data, - struct vk_cmd_pool_data *pool_data) +static void vk_shtex_destroy_family_objects(struct vk_data *data, + struct vk_family_data *family_data) { - for (uint32_t image_idx = 0; image_idx < pool_data->image_count; + for (uint32_t image_idx = 0; image_idx < family_data->image_count; image_idx++) { - bool *cmd_buffer_busy = &pool_data->cmd_buffer_busy[image_idx]; - VkFence *fence = &pool_data->fences[image_idx]; + struct vk_frame_data *frame_data = + &family_data->frames[image_idx]; + bool *cmd_buffer_busy = &frame_data->cmd_buffer_busy; + VkFence *fence = &frame_data->fence; vk_shtex_destroy_fence(data, cmd_buffer_busy, fence); + + data->funcs.DestroyCommandPool(data->device, + frame_data->cmd_pool, data->ac); + frame_data->cmd_pool = VK_NULL_HANDLE; } - data->funcs.DestroyCommandPool(data->device, pool_data->cmd_pool, - data->ac); - pool_data->cmd_pool = VK_NULL_HANDLE; - pool_data->image_count = 0; + family_data->image_count = 0; } static void vk_shtex_capture(struct vk_data *data, @@ -825,21 +831,27 @@ static void vk_shtex_capture(struct vk_data *data, fam_idx = data->queues[i].fam_idx; } - if (fam_idx >= _countof(data->cmd_pools)) + if (fam_idx >= _countof(data->families)) return; - struct vk_cmd_pool_data *pool_data = &data->cmd_pools[fam_idx]; - VkCommandPool *pool = &pool_data->cmd_pool; + struct vk_family_data *family_data = &data->families[fam_idx]; const uint32_t image_count = swap->image_count; - if (pool_data->image_count < image_count) { - if (*pool != VK_NULL_HANDLE) - vk_shtex_destroy_cmd_pool_objects(data, pool_data); - vk_shtex_create_cmd_pool_objects(data, fam_idx, image_count); + if (family_data->image_count < image_count) { + if (family_data->image_count > 0) + vk_shtex_destroy_family_objects(data, family_data); + vk_shtex_create_family_objects(data, fam_idx, image_count); } - vk_shtex_clear_fence(data, pool_data, image_index); + struct vk_frame_data *frame_data = &family_data->frames[image_index]; + vk_shtex_clear_fence(data, frame_data); - VkCommandBuffer cmd_buffer = pool_data->cmd_buffers[image_index]; + res = funcs->ResetCommandPool(data->device, frame_data->cmd_pool, 0); + +#ifdef MORE_DEBUGGING + debug_res("ResetCommandPool", res); +#endif + + const VkCommandBuffer cmd_buffer = frame_data->cmd_buffer; res = funcs->BeginCommandBuffer(cmd_buffer, &begin_info); #ifdef MORE_DEBUGGING @@ -979,7 +991,7 @@ static void vk_shtex_capture(struct vk_data *data, submit_info.signalSemaphoreCount = 0; submit_info.pSignalSemaphores = NULL; - VkFence fence = pool_data->fences[image_index]; + const VkFence fence = frame_data->fence; res = funcs->QueueSubmit(queue, 1, &submit_info, fence); #ifdef MORE_DEBUGGING @@ -987,7 +999,7 @@ static void vk_shtex_capture(struct vk_data *data, #endif if (res == VK_SUCCESS) - pool_data->cmd_buffer_busy[image_index] = true; + frame_data->cmd_buffer_busy = true; } static inline bool valid_rect(struct vk_swap_data *swap) @@ -1299,6 +1311,7 @@ static VkResult VKAPI OBS_CreateDevice(VkPhysicalDevice phy_device, GETADDR(DestroyImage); GETADDR(GetImageMemoryRequirements); GETADDR(GetImageMemoryRequirements2); + GETADDR(ResetCommandPool); GETADDR(BeginCommandBuffer); GETADDR(EndCommandBuffer); GETADDR(CmdCopyImage); @@ -1396,13 +1409,13 @@ static void VKAPI OBS_DestroyDevice(VkDevice device, return; if (data->valid) { - for (uint32_t fam_idx = 0; fam_idx < _countof(data->cmd_pools); + for (uint32_t fam_idx = 0; fam_idx < _countof(data->families); fam_idx++) { - struct vk_cmd_pool_data *pool_data = - &data->cmd_pools[fam_idx]; - if (pool_data->cmd_pool != VK_NULL_HANDLE) { - vk_shtex_destroy_cmd_pool_objects(data, - pool_data); + struct vk_family_data *family_data = + &data->families[fam_idx]; + if (family_data->image_count > 0) { + vk_shtex_destroy_family_objects(data, + family_data); } } } diff --git a/plugins/win-capture/graphics-hook/vulkan-capture.h b/plugins/win-capture/graphics-hook/vulkan-capture.h index 533f42d7c..0e5b8b4ad 100644 --- a/plugins/win-capture/graphics-hook/vulkan-capture.h +++ b/plugins/win-capture/graphics-hook/vulkan-capture.h @@ -27,6 +27,7 @@ struct vk_device_funcs { DEF_FUNC(DestroyImage); DEF_FUNC(GetImageMemoryRequirements); DEF_FUNC(GetImageMemoryRequirements2); + DEF_FUNC(ResetCommandPool); DEF_FUNC(BeginCommandBuffer); DEF_FUNC(EndCommandBuffer); DEF_FUNC(CmdCopyImage);