Vulkan, Viewports: Fix for resizing viewport windows crashing. (#2472)

This commit is contained in:
MindSpunk 2019-04-05 15:50:21 +11:00 committed by omar
parent 0034e65c26
commit a45840746e
4 changed files with 43 additions and 16 deletions

View File

@ -252,7 +252,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
{ {
VkResult err; 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); err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
check_vk_result(err); check_vk_result(err);
@ -300,7 +301,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
info.commandBufferCount = 1; info.commandBufferCount = 1;
info.pCommandBuffers = &fd->CommandBuffer; info.pCommandBuffers = &fd->CommandBuffer;
info.signalSemaphoreCount = 1; info.signalSemaphoreCount = 1;
info.pSignalSemaphores = &fd->RenderCompleteSemaphore; info.pSignalSemaphores = &render_complete_semaphore;
err = vkEndCommandBuffer(fd->CommandBuffer); err = vkEndCommandBuffer(fd->CommandBuffer);
check_vk_result(err); check_vk_result(err);
@ -311,11 +312,11 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
static void FramePresent(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 = {}; VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.waitSemaphoreCount = 1; info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &fd->RenderCompleteSemaphore; info.pWaitSemaphores = &render_complete_semaphore;
info.swapchainCount = 1; info.swapchainCount = 1;
info.pSwapchains = &wd->Swapchain; info.pSwapchains = &wd->Swapchain;
info.pImageIndices = &wd->FrameIndex; info.pImageIndices = &wd->FrameIndex;

View File

@ -244,7 +244,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
{ {
VkResult err; 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); err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
check_vk_result(err); check_vk_result(err);
@ -292,7 +293,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
info.commandBufferCount = 1; info.commandBufferCount = 1;
info.pCommandBuffers = &fd->CommandBuffer; info.pCommandBuffers = &fd->CommandBuffer;
info.signalSemaphoreCount = 1; info.signalSemaphoreCount = 1;
info.pSignalSemaphores = &fd->RenderCompleteSemaphore; info.pSignalSemaphores = &render_complete_semaphore;
err = vkEndCommandBuffer(fd->CommandBuffer); err = vkEndCommandBuffer(fd->CommandBuffer);
check_vk_result(err); check_vk_result(err);
@ -303,11 +304,11 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
static void FramePresent(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 = {}; VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.waitSemaphoreCount = 1; info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &fd->RenderCompleteSemaphore; info.pWaitSemaphores = &render_complete_semaphore;
info.swapchainCount = 1; info.swapchainCount = 1;
info.pSwapchains = &wd->Swapchain; info.pSwapchains = &wd->Swapchain;
info.pImageIndices = &wd->FrameIndex; info.pImageIndices = &wd->FrameIndex;

View File

@ -64,6 +64,7 @@ static VkBuffer g_UploadBuffer = VK_NULL_HANDLE;
// Forward Declarations // Forward Declarations
void ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator); 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_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); 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++) for (uint32_t i = 0; i < wd->FramesQueueSize; i++)
{ {
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i]; ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i];
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[i];
{ {
VkCommandPoolCreateInfo info = {}; VkCommandPoolCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
@ -916,9 +918,9 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkInstance instance, VkPhysica
{ {
VkSemaphoreCreateInfo info = {}; VkSemaphoreCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_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); check_vk_result(err);
err = vkCreateSemaphore(device, &info, allocator, &fd->RenderCompleteSemaphore); err = vkCreateSemaphore(device, &info, allocator, &fsd->RenderCompleteSemaphore);
check_vk_result(err); 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. // We don't use ImGui_ImplVulkanH_DestroyWindow() because we want to preserve the old swapchain to create the new one.
// Destroy old Framebuffer // Destroy old Framebuffer
for (uint32_t i = 0; i < wd->FramesQueueSize; i++) for (uint32_t i = 0; i < wd->FramesQueueSize; i++)
{
ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator); ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator);
ImGui_ImplVulkanH_DestroyFrameSemaphores(instance, device, &wd->FrameSemaphores[i], allocator);
}
delete[] wd->Frames; delete[] wd->Frames;
delete[] wd->FrameSemaphores;
wd->Frames = NULL; wd->Frames = NULL;
wd->FrameSemaphores = NULL;
wd->FramesQueueSize = 0; wd->FramesQueueSize = 0;
if (wd->RenderPass) if (wd->RenderPass)
vkDestroyRenderPass(device, wd->RenderPass, allocator); vkDestroyRenderPass(device, wd->RenderPass, allocator);
@ -1004,7 +1011,9 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi
IM_ASSERT(wd->Frames == NULL); IM_ASSERT(wd->Frames == NULL);
wd->Frames = new ImGui_ImplVulkanH_Frame[wd->FramesQueueSize]; 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->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++) for (uint32_t i = 0; i < wd->FramesQueueSize; i++)
wd->Frames[i].Backbuffer = backbuffers[i]; wd->Frames[i].Backbuffer = backbuffers[i];
} }
@ -1102,9 +1111,14 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui
//vkQueueWaitIdle(g_Queue); //vkQueueWaitIdle(g_Queue);
for (uint32_t i = 0; i < wd->FramesQueueSize; i++) for (uint32_t i = 0; i < wd->FramesQueueSize; i++)
{
ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator); ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator);
ImGui_ImplVulkanH_DestroyFrameSemaphores(instance, device, &wd->FrameSemaphores[i], allocator);
}
delete[] wd->Frames; delete[] wd->Frames;
delete[] wd->FrameSemaphores;
wd->Frames = NULL; wd->Frames = NULL;
wd->FrameSemaphores = NULL;
vkDestroyRenderPass(device, wd->RenderPass, allocator); vkDestroyRenderPass(device, wd->RenderPass, allocator);
vkDestroySwapchainKHR(device, wd->Swapchain, allocator); vkDestroySwapchainKHR(device, wd->Swapchain, allocator);
vkDestroySurfaceKHR(instance, wd->Surface, allocator); vkDestroySurfaceKHR(instance, wd->Surface, allocator);
@ -1112,22 +1126,26 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui
*wd = ImGui_ImplVulkanH_Window(); *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 ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator)
{ {
(void)instance; (void)instance;
vkDestroyFence(device, fd->Fence, allocator); vkDestroyFence(device, fd->Fence, allocator);
vkFreeCommandBuffers(device, fd->CommandPool, 1, &fd->CommandBuffer); vkFreeCommandBuffers(device, fd->CommandPool, 1, &fd->CommandBuffer);
vkDestroyCommandPool(device, fd->CommandPool, allocator); vkDestroyCommandPool(device, fd->CommandPool, allocator);
vkDestroySemaphore(device, fd->ImageAcquiredSemaphore, allocator);
vkDestroySemaphore(device, fd->RenderCompleteSemaphore, allocator);
fd->Fence = VK_NULL_HANDLE; fd->Fence = VK_NULL_HANDLE;
fd->CommandBuffer = VK_NULL_HANDLE; fd->CommandBuffer = VK_NULL_HANDLE;
fd->CommandPool = VK_NULL_HANDLE; fd->CommandPool = VK_NULL_HANDLE;
fd->ImageAcquiredSemaphore = fd->RenderCompleteSemaphore = VK_NULL_HANDLE;
vkDestroyImageView(device, fd->BackbufferView, allocator); vkDestroyImageView(device, fd->BackbufferView, allocator);
vkDestroyFramebuffer(device, fd->Framebuffer, allocator); vkDestroyFramebuffer(device, fd->Framebuffer, allocator);
ImGui_ImplVulkan_DestroyFrameRenderBuffers(instance, device, &fd->RenderBuffers, allocator); ImGui_ImplVulkan_DestroyFrameRenderBuffers(instance, device, &fd->RenderBuffers, allocator);
} }

View File

@ -101,14 +101,18 @@ struct ImGui_ImplVulkanH_Frame
VkCommandPool CommandPool; VkCommandPool CommandPool;
VkCommandBuffer CommandBuffer; VkCommandBuffer CommandBuffer;
VkFence Fence; VkFence Fence;
VkSemaphore ImageAcquiredSemaphore;
VkSemaphore RenderCompleteSemaphore;
VkImage Backbuffer; VkImage Backbuffer;
VkImageView BackbufferView; VkImageView BackbufferView;
VkFramebuffer Framebuffer; VkFramebuffer Framebuffer;
ImGui_ImplVulkan_FrameRenderBuffers RenderBuffers; 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 // 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.) // (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
struct ImGui_ImplVulkanH_Window struct ImGui_ImplVulkanH_Window
@ -124,7 +128,10 @@ struct ImGui_ImplVulkanH_Window
VkClearValue ClearValue; VkClearValue ClearValue;
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount) 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 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_Frame* Frames;
ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
ImGui_ImplVulkanH_Window() ImGui_ImplVulkanH_Window()
{ {