1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-09 23:54:20 +00:00
This commit is contained in:
Christian Tomasino 2025-12-23 20:13:22 +01:00 committed by GitHub
commit 754471823b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 92 additions and 75 deletions

View file

@ -1618,10 +1618,7 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_devi
err = vkCreateFence(device, &info, allocator, &fd->Fence);
check_vk_result(err);
}
}
for (uint32_t i = 0; i < wd->SemaphoreCount; i++)
{
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[i];
{
VkSemaphoreCreateInfo info = {};
@ -1658,12 +1655,15 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
// We don't use ImGui_ImplVulkanH_DestroyWindow() because we want to preserve the old swapchain to create the new one.
// Destroy old Framebuffer
for (uint32_t i = 0; i < wd->ImageCount; i++)
{
ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator);
for (uint32_t i = 0; i < wd->SemaphoreCount; i++)
ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
}
wd->Frames.clear();
wd->FrameSemaphores.clear();
wd->ImageCount = 0;
wd->FrameIndex = 0;
if (wd->RenderPass)
vkDestroyRenderPass(device, wd->RenderPass, allocator);
@ -1720,9 +1720,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, backbuffers);
check_vk_result(err);
wd->SemaphoreCount = wd->ImageCount + 1;
wd->Frames.resize(wd->ImageCount);
wd->FrameSemaphores.resize(wd->SemaphoreCount);
wd->FrameSemaphores.resize(wd->ImageCount);
memset(wd->Frames.Data, 0, wd->Frames.size_in_bytes());
memset(wd->FrameSemaphores.Data, 0, wd->FrameSemaphores.size_in_bytes());
for (uint32_t i = 0; i < wd->ImageCount; i++)
@ -1908,9 +1907,11 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui
//vkQueueWaitIdle(bd->Queue);
for (uint32_t i = 0; i < wd->ImageCount; i++)
{
ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator);
for (uint32_t i = 0; i < wd->SemaphoreCount; i++)
ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
}
wd->Frames.clear();
wd->FrameSemaphores.clear();
vkDestroyRenderPass(device, wd->RenderPass, allocator);
@ -2077,11 +2078,26 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
vd->SwapChainNeedRebuild = vd->SwapChainSuboptimal = false;
}
ImGui_ImplVulkanH_Frame* fd = nullptr;
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[wd->SemaphoreIndex];
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
for (;;)
{
err = vkWaitForFences(v->Device, 1, &fd->Fence, VK_TRUE, 100);
if (err == VK_SUCCESS)
{
err = vkResetFences(v->Device, 1,&fd->Fence);
check_vk_result(err);
break;
}
if (err == VK_TIMEOUT) continue;
check_vk_result(err);
}
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[wd->FrameIndex];
{
{
err = vkAcquireNextImageKHR(v->Device, wd->Swapchain, UINT64_MAX, fsd->ImageAcquiredSemaphore, VK_NULL_HANDLE, &wd->FrameIndex);
err = vkAcquireNextImageKHR(v->Device, wd->Swapchain, UINT64_MAX, fsd->ImageAcquiredSemaphore, VK_NULL_HANDLE, &wd->ImageIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR)
{
vd->SwapChainNeedRebuild = true; // Since we are not going to swap this frame anyway, it's ok that recreation happens on next frame.
@ -2091,15 +2107,8 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
vd->SwapChainSuboptimal = true;
else
check_vk_result(err);
fd = &wd->Frames[wd->FrameIndex];
}
for (;;)
{
err = vkWaitForFences(v->Device, 1, &fd->Fence, VK_TRUE, 100);
if (err == VK_SUCCESS) break;
if (err == VK_TIMEOUT) continue;
check_vk_result(err);
}
{
err = vkResetCommandPool(v->Device, fd->CommandPool, 0);
check_vk_result(err);
@ -2223,9 +2232,9 @@ static void ImGui_ImplVulkan_SwapBuffers(ImGuiViewport* viewport, void*)
return;
VkResult err;
uint32_t present_index = wd->FrameIndex;
uint32_t present_index = wd->ImageIndex;
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[wd->SemaphoreIndex];
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[present_index];
VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.waitSemaphoreCount = 1;
@ -2243,7 +2252,7 @@ static void ImGui_ImplVulkan_SwapBuffers(ImGuiViewport* viewport, void*)
vd->SwapChainSuboptimal = true;
else
check_vk_result(err);
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
wd->FrameIndex = (wd->FrameIndex + 1) % wd->ImageCount; // Swap frame
}
void ImGui_ImplVulkan_InitMultiViewportSupport()

View file

@ -243,8 +243,7 @@ struct ImGui_ImplVulkanH_Window
VkClearValue ClearValue;
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
uint32_t SemaphoreCount; // Number of simultaneous in-flight frames + 1, to be able to use it in vkAcquireNextImageKHR
uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
uint32_t ImageIndex; // Current available swapchain image index (returned by vkAcquireNextImageKHR) used to access RenderCompleteSemaphore
ImVector<ImGui_ImplVulkanH_Frame> Frames;
ImVector<ImGui_ImplVulkanH_FrameSemaphores> FrameSemaphores;

View file

@ -263,16 +263,7 @@ static void CleanupVulkanWindow()
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
{
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
VkResult err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
if (err == VK_ERROR_OUT_OF_DATE_KHR)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
VkResult err;
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
{
err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking
@ -281,6 +272,16 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
err = vkResetFences(g_Device, 1, &fd->Fence);
check_vk_result(err);
}
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->FrameIndex].ImageAcquiredSemaphore;
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->ImageIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
if (err == VK_ERROR_OUT_OF_DATE_KHR)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
{
err = vkResetCommandPool(g_Device, fd->CommandPool, 0);
check_vk_result(err);
@ -308,6 +309,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
// Submit command buffer
vkCmdEndRenderPass(fd->CommandBuffer);
{
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->ImageIndex].RenderCompleteSemaphore;
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@ -330,14 +332,14 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
{
if (g_SwapChainRebuild)
return;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->ImageIndex].RenderCompleteSemaphore;
VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &render_complete_semaphore;
info.swapchainCount = 1;
info.pSwapchains = &wd->Swapchain;
info.pImageIndices = &wd->FrameIndex;
info.pImageIndices = &wd->ImageIndex;
VkResult err = vkQueuePresentKHR(g_Queue, &info);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
@ -345,7 +347,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
wd->FrameIndex = (wd->FrameIndex + 1) % wd->ImageCount; // Swap frame
}
// Main code

View file

@ -254,16 +254,7 @@ static void CleanupVulkanWindow()
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
{
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
VkResult err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
if (err == VK_ERROR_OUT_OF_DATE_KHR)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
VkResult err;
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
{
err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking
@ -272,6 +263,16 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
err = vkResetFences(g_Device, 1, &fd->Fence);
check_vk_result(err);
}
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->FrameIndex].ImageAcquiredSemaphore;
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->ImageIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
if (err == VK_ERROR_OUT_OF_DATE_KHR)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
{
err = vkResetCommandPool(g_Device, fd->CommandPool, 0);
check_vk_result(err);
@ -299,6 +300,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
// Submit command buffer
vkCmdEndRenderPass(fd->CommandBuffer);
{
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->ImageIndex].RenderCompleteSemaphore;
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@ -321,14 +323,14 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
{
if (g_SwapChainRebuild)
return;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->ImageIndex].RenderCompleteSemaphore;
VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &render_complete_semaphore;
info.swapchainCount = 1;
info.pSwapchains = &wd->Swapchain;
info.pImageIndices = &wd->FrameIndex;
info.pImageIndices = &wd->ImageIndex;
VkResult err = vkQueuePresentKHR(g_Queue, &info);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
@ -336,7 +338,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
wd->FrameIndex = (wd->FrameIndex + 1) % wd->ImageCount; // Swap frame
}
// Main code

View file

@ -256,16 +256,7 @@ static void CleanupVulkanWindow()
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
{
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
VkResult err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
if (err == VK_ERROR_OUT_OF_DATE_KHR)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
VkResult err;
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
{
err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking
@ -274,6 +265,17 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
err = vkResetFences(g_Device, 1, &fd->Fence);
check_vk_result(err);
}
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->FrameIndex].ImageAcquiredSemaphore;
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->ImageIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
if (err == VK_ERROR_OUT_OF_DATE_KHR)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
{
err = vkResetCommandPool(g_Device, fd->CommandPool, 0);
check_vk_result(err);
@ -301,6 +303,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
// Submit command buffer
vkCmdEndRenderPass(fd->CommandBuffer);
{
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->ImageIndex].RenderCompleteSemaphore;
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@ -323,14 +326,14 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
{
if (g_SwapChainRebuild)
return;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->ImageIndex].RenderCompleteSemaphore;
VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &render_complete_semaphore;
info.swapchainCount = 1;
info.pSwapchains = &wd->Swapchain;
info.pImageIndices = &wd->FrameIndex;
info.pImageIndices = &wd->ImageIndex;
VkResult err = vkQueuePresentKHR(g_Queue, &info);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
@ -338,7 +341,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
wd->FrameIndex = (wd->FrameIndex + 1) % wd->ImageCount; // Swap frame
}
// Main code

View file

@ -252,16 +252,7 @@ static void CleanupVulkanWindow()
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
{
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
VkResult err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
if (err == VK_ERROR_OUT_OF_DATE_KHR)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
VkResult err;
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
{
err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking
@ -270,6 +261,16 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
err = vkResetFences(g_Device, 1, &fd->Fence);
check_vk_result(err);
}
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->FrameIndex].ImageAcquiredSemaphore;
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->ImageIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
if (err == VK_ERROR_OUT_OF_DATE_KHR)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
{
err = vkResetCommandPool(g_Device, fd->CommandPool, 0);
check_vk_result(err);
@ -297,6 +298,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
// Submit command buffer
vkCmdEndRenderPass(fd->CommandBuffer);
{
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->ImageIndex].RenderCompleteSemaphore;
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@ -319,14 +321,14 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
{
if (g_SwapChainRebuild)
return;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->ImageIndex].RenderCompleteSemaphore;
VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &render_complete_semaphore;
info.swapchainCount = 1;
info.pSwapchains = &wd->Swapchain;
info.pImageIndices = &wd->FrameIndex;
info.pImageIndices = &wd->ImageIndex;
VkResult err = vkQueuePresentKHR(g_Queue, &info);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
g_SwapChainRebuild = true;
@ -334,7 +336,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
return;
if (err != VK_SUBOPTIMAL_KHR)
check_vk_result(err);
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
wd->FrameIndex = (wd->FrameIndex + 1) % wd->ImageCount; // Swap frame
}
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);