mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-11-04 01:34:32 +00:00 
			
		
		
		
	Vulkan, Viewports: Fix for resizing viewport windows crashing. (#2472)
This commit is contained in:
		@@ -252,7 +252,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
 | 
			
		||||
{
 | 
			
		||||
    VkResult err;
 | 
			
		||||
 | 
			
		||||
    VkSemaphore& image_acquired_semaphore  = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore;
 | 
			
		||||
    VkSemaphore image_acquired_semaphore  = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
 | 
			
		||||
    VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
 | 
			
		||||
    err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
 | 
			
		||||
    check_vk_result(err);
 | 
			
		||||
 | 
			
		||||
@@ -300,7 +301,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
 | 
			
		||||
        info.commandBufferCount = 1;
 | 
			
		||||
        info.pCommandBuffers = &fd->CommandBuffer;
 | 
			
		||||
        info.signalSemaphoreCount = 1;
 | 
			
		||||
        info.pSignalSemaphores = &fd->RenderCompleteSemaphore;
 | 
			
		||||
        info.pSignalSemaphores = &render_complete_semaphore;
 | 
			
		||||
 | 
			
		||||
        err = vkEndCommandBuffer(fd->CommandBuffer);
 | 
			
		||||
        check_vk_result(err);
 | 
			
		||||
@@ -311,11 +312,11 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
 | 
			
		||||
 | 
			
		||||
static void FramePresent(ImGui_ImplVulkanH_Window* wd)
 | 
			
		||||
{
 | 
			
		||||
    ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
 | 
			
		||||
    VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
 | 
			
		||||
    VkPresentInfoKHR info = {};
 | 
			
		||||
    info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
 | 
			
		||||
    info.waitSemaphoreCount = 1;
 | 
			
		||||
    info.pWaitSemaphores = &fd->RenderCompleteSemaphore;
 | 
			
		||||
    info.pWaitSemaphores = &render_complete_semaphore;
 | 
			
		||||
    info.swapchainCount = 1;
 | 
			
		||||
    info.pSwapchains = &wd->Swapchain;
 | 
			
		||||
    info.pImageIndices = &wd->FrameIndex;
 | 
			
		||||
 
 | 
			
		||||
@@ -244,7 +244,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
 | 
			
		||||
{
 | 
			
		||||
    VkResult err;
 | 
			
		||||
 | 
			
		||||
    VkSemaphore& image_acquired_semaphore  = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore;
 | 
			
		||||
    VkSemaphore image_acquired_semaphore  = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
 | 
			
		||||
    VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
 | 
			
		||||
    err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
 | 
			
		||||
    check_vk_result(err);
 | 
			
		||||
 | 
			
		||||
@@ -292,7 +293,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
 | 
			
		||||
        info.commandBufferCount = 1;
 | 
			
		||||
        info.pCommandBuffers = &fd->CommandBuffer;
 | 
			
		||||
        info.signalSemaphoreCount = 1;
 | 
			
		||||
        info.pSignalSemaphores = &fd->RenderCompleteSemaphore;
 | 
			
		||||
        info.pSignalSemaphores = &render_complete_semaphore;
 | 
			
		||||
 | 
			
		||||
        err = vkEndCommandBuffer(fd->CommandBuffer);
 | 
			
		||||
        check_vk_result(err);
 | 
			
		||||
@@ -303,11 +304,11 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
 | 
			
		||||
 | 
			
		||||
static void FramePresent(ImGui_ImplVulkanH_Window* wd)
 | 
			
		||||
{
 | 
			
		||||
    ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
 | 
			
		||||
    VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
 | 
			
		||||
    VkPresentInfoKHR info = {};
 | 
			
		||||
    info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
 | 
			
		||||
    info.waitSemaphoreCount = 1;
 | 
			
		||||
    info.pWaitSemaphores = &fd->RenderCompleteSemaphore;
 | 
			
		||||
    info.pWaitSemaphores = &render_complete_semaphore;
 | 
			
		||||
    info.swapchainCount = 1;
 | 
			
		||||
    info.pSwapchains = &wd->Swapchain;
 | 
			
		||||
    info.pImageIndices = &wd->FrameIndex;
 | 
			
		||||
 
 | 
			
		||||
@@ -64,6 +64,7 @@ static VkBuffer                 g_UploadBuffer = VK_NULL_HANDLE;
 | 
			
		||||
 | 
			
		||||
// Forward Declarations
 | 
			
		||||
void ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator);
 | 
			
		||||
void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator);
 | 
			
		||||
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
 | 
			
		||||
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator);
 | 
			
		||||
 | 
			
		||||
@@ -889,6 +890,7 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkInstance instance, VkPhysica
 | 
			
		||||
    for (uint32_t i = 0; i < wd->FramesQueueSize; i++)
 | 
			
		||||
    {
 | 
			
		||||
        ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i];
 | 
			
		||||
        ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[i];
 | 
			
		||||
        {
 | 
			
		||||
            VkCommandPoolCreateInfo info = {};
 | 
			
		||||
            info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
 | 
			
		||||
@@ -916,9 +918,9 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkInstance instance, VkPhysica
 | 
			
		||||
        {
 | 
			
		||||
            VkSemaphoreCreateInfo info = {};
 | 
			
		||||
            info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
 | 
			
		||||
            err = vkCreateSemaphore(device, &info, allocator, &fd->ImageAcquiredSemaphore);
 | 
			
		||||
            err = vkCreateSemaphore(device, &info, allocator, &fsd->ImageAcquiredSemaphore);
 | 
			
		||||
            check_vk_result(err);
 | 
			
		||||
            err = vkCreateSemaphore(device, &info, allocator, &fd->RenderCompleteSemaphore);
 | 
			
		||||
            err = vkCreateSemaphore(device, &info, allocator, &fsd->RenderCompleteSemaphore);
 | 
			
		||||
            check_vk_result(err);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -947,9 +949,14 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi
 | 
			
		||||
    // 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->FramesQueueSize; i++)
 | 
			
		||||
    {
 | 
			
		||||
        ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator);
 | 
			
		||||
        ImGui_ImplVulkanH_DestroyFrameSemaphores(instance, device, &wd->FrameSemaphores[i], allocator);
 | 
			
		||||
    }
 | 
			
		||||
    delete[] wd->Frames;
 | 
			
		||||
    delete[] wd->FrameSemaphores;
 | 
			
		||||
    wd->Frames = NULL;
 | 
			
		||||
    wd->FrameSemaphores = NULL;
 | 
			
		||||
    wd->FramesQueueSize = 0;
 | 
			
		||||
    if (wd->RenderPass)
 | 
			
		||||
        vkDestroyRenderPass(device, wd->RenderPass, allocator);
 | 
			
		||||
@@ -1004,7 +1011,9 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi
 | 
			
		||||
 | 
			
		||||
        IM_ASSERT(wd->Frames == NULL);
 | 
			
		||||
        wd->Frames = new ImGui_ImplVulkanH_Frame[wd->FramesQueueSize];
 | 
			
		||||
        wd->FrameSemaphores = new ImGui_ImplVulkanH_FrameSemaphores[wd->FramesQueueSize];
 | 
			
		||||
        memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->FramesQueueSize);
 | 
			
		||||
        memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->FramesQueueSize);
 | 
			
		||||
        for (uint32_t i = 0; i < wd->FramesQueueSize; i++)
 | 
			
		||||
            wd->Frames[i].Backbuffer = backbuffers[i];
 | 
			
		||||
    }
 | 
			
		||||
@@ -1102,9 +1111,14 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui
 | 
			
		||||
    //vkQueueWaitIdle(g_Queue);
 | 
			
		||||
 | 
			
		||||
    for (uint32_t i = 0; i < wd->FramesQueueSize; i++)
 | 
			
		||||
    {
 | 
			
		||||
        ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator);
 | 
			
		||||
        ImGui_ImplVulkanH_DestroyFrameSemaphores(instance, device, &wd->FrameSemaphores[i], allocator);
 | 
			
		||||
    }
 | 
			
		||||
    delete[] wd->Frames;
 | 
			
		||||
    delete[] wd->FrameSemaphores;
 | 
			
		||||
    wd->Frames = NULL;
 | 
			
		||||
    wd->FrameSemaphores = NULL;
 | 
			
		||||
    vkDestroyRenderPass(device, wd->RenderPass, allocator);
 | 
			
		||||
    vkDestroySwapchainKHR(device, wd->Swapchain, allocator);
 | 
			
		||||
    vkDestroySurfaceKHR(instance, wd->Surface, allocator);
 | 
			
		||||
@@ -1112,22 +1126,26 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui
 | 
			
		||||
    *wd = ImGui_ImplVulkanH_Window();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator)
 | 
			
		||||
{
 | 
			
		||||
    (void)instance;
 | 
			
		||||
    vkDestroySemaphore(device, fsd->ImageAcquiredSemaphore, allocator);
 | 
			
		||||
    vkDestroySemaphore(device, fsd->RenderCompleteSemaphore, allocator);
 | 
			
		||||
    fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator)
 | 
			
		||||
{
 | 
			
		||||
    (void)instance;
 | 
			
		||||
    vkDestroyFence(device, fd->Fence, allocator);
 | 
			
		||||
    vkFreeCommandBuffers(device, fd->CommandPool, 1, &fd->CommandBuffer);
 | 
			
		||||
    vkDestroyCommandPool(device, fd->CommandPool, allocator);
 | 
			
		||||
    vkDestroySemaphore(device, fd->ImageAcquiredSemaphore, allocator);
 | 
			
		||||
    vkDestroySemaphore(device, fd->RenderCompleteSemaphore, allocator);
 | 
			
		||||
    fd->Fence = VK_NULL_HANDLE;
 | 
			
		||||
    fd->CommandBuffer = VK_NULL_HANDLE;
 | 
			
		||||
    fd->CommandPool = VK_NULL_HANDLE;
 | 
			
		||||
    fd->ImageAcquiredSemaphore = fd->RenderCompleteSemaphore = VK_NULL_HANDLE;
 | 
			
		||||
 | 
			
		||||
    vkDestroyImageView(device, fd->BackbufferView, allocator);
 | 
			
		||||
    vkDestroyFramebuffer(device, fd->Framebuffer, allocator);
 | 
			
		||||
 | 
			
		||||
    ImGui_ImplVulkan_DestroyFrameRenderBuffers(instance, device, &fd->RenderBuffers, allocator);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -101,14 +101,18 @@ struct ImGui_ImplVulkanH_Frame
 | 
			
		||||
    VkCommandPool       CommandPool;
 | 
			
		||||
    VkCommandBuffer     CommandBuffer;
 | 
			
		||||
    VkFence             Fence;
 | 
			
		||||
    VkSemaphore         ImageAcquiredSemaphore;
 | 
			
		||||
    VkSemaphore         RenderCompleteSemaphore;
 | 
			
		||||
    VkImage             Backbuffer;
 | 
			
		||||
    VkImageView         BackbufferView;
 | 
			
		||||
    VkFramebuffer       Framebuffer;
 | 
			
		||||
    ImGui_ImplVulkan_FrameRenderBuffers RenderBuffers;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ImGui_ImplVulkanH_FrameSemaphores
 | 
			
		||||
{
 | 
			
		||||
    VkSemaphore         ImageAcquiredSemaphore;
 | 
			
		||||
    VkSemaphore         RenderCompleteSemaphore;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Helper structure to hold the data needed by one rendering context into one OS window
 | 
			
		||||
// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
 | 
			
		||||
struct ImGui_ImplVulkanH_Window
 | 
			
		||||
@@ -124,7 +128,10 @@ struct ImGui_ImplVulkanH_Window
 | 
			
		||||
    VkClearValue        ClearValue;
 | 
			
		||||
    uint32_t            FrameIndex;             // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
 | 
			
		||||
    uint32_t            FramesQueueSize;        // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
 | 
			
		||||
    uint32_t            SemaphoreIndex;         // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
 | 
			
		||||
    ImGui_ImplVulkanH_Frame* Frames;
 | 
			
		||||
    ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ImGui_ImplVulkanH_Window() 
 | 
			
		||||
    { 
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user