Examples: Vulkan: Updated Changelog, removed debug code, tweaked code, made GLFW/SDL match each others. Initialize FrameDataForRender fields. Added Assertion. Clearing fields on DestroyFrameData(). (#2071)

This commit is contained in:
omar 2019-04-03 15:48:22 +02:00
parent c7eef99a33
commit 317859a3da
5 changed files with 61 additions and 86 deletions

View File

@ -49,6 +49,9 @@ Other Changes:
- Examples: OpenGL3: Minor tweaks + not calling glBindBuffer more than necessary in the render loop.
- Examples: Vulkan: Added missing support for 32-bit indices (#define ImDrawIdx unsigned int).
- Examples: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like.
- Examples: Vulkan: Added QueuedFramesCount field in ImGui_ImplVulkan_InitInfo, required during
initialization (was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2). (#2071) [@nathanvoglsam]
Added ImGui_ImplVulkan_SetQueuedFramesCount() to override QueuedFramesCount while running.
- Examples: DirectX9: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). (#2454)
- Examples: GLUT: Fixed existing FreeGLUT example to work with regular GLUT. (#2465) [@andrewwillmott]
- Examples: GLUT: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. (#2465) [@andrewwillmott]

View File

@ -23,7 +23,6 @@
#define IMGUI_VULKAN_DEBUG_REPORT
#endif
static uint32_t g_MinImageCount = 2;
static VkAllocationCallbacks* g_Allocator = NULL;
static VkInstance g_Instance = VK_NULL_HANDLE;
static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE;
@ -35,7 +34,8 @@ static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static ImGui_ImplVulkanH_WindowData g_WindowData;
static bool g_ResizeWanted = false;
static int g_MinImageCount = 2;
static bool g_WantSwapChainRebuild = false;
static int g_ResizeWidth = 0, g_ResizeHeight = 0;
static void check_vk_result(VkResult err)
@ -214,6 +214,7 @@ static void SetupVulkanWindowData(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR
// Create SwapChain, RenderPass, Framebuffer, etc.
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, wd, g_Allocator, width, height, g_MinImageCount);
ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, wd, g_Allocator);
IM_ASSERT(wd->BackBufferCount > 0);
}
static void CleanupVulkan()
@ -314,7 +315,7 @@ static void glfw_error_callback(int error, const char* description)
static void glfw_resize_callback(GLFWwindow*, int w, int h)
{
g_ResizeWanted = true;
g_WantSwapChainRebuild = true;
g_ResizeWidth = w;
g_ResizeHeight = h;
}
@ -373,8 +374,8 @@ int main(int, char**)
init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool;
init_info.Allocator = g_Allocator;
init_info.QueuedFramesCount = (int)wd->BackBufferCount;
init_info.CheckVkResultFn = check_vk_result;
init_info.QueuedFrames = wd->BackBufferCount;
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
// Load Fonts
@ -435,13 +436,13 @@ int main(int, char**)
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents();
if (g_ResizeWanted)
if (g_WantSwapChainRebuild)
{
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, g_ResizeWidth, g_ResizeHeight, g_MinImageCount);
ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, &g_WindowData, g_Allocator);
ImGui_ImplVulkan_SetQueuedFramesCount(g_WindowData.BackBufferCount);
g_WindowData.FrameIndex = 0;
g_ResizeWanted = false;
g_WantSwapChainRebuild = false;
}
// Start the Dear ImGui frame
@ -483,28 +484,6 @@ int main(int, char**)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
show_another_window = false;
if (ImGui::Button("Increase"))
{
g_MinImageCount++;
g_ResizeWanted = true;
}
ImGui::SameLine();
if (ImGui::Button("Decrease"))
{
if (g_MinImageCount != 2)
{
g_MinImageCount--;
g_ResizeWanted = true;
}
}
ImGui::SameLine();
ImGui::Text("Back Buffers: %i", g_MinImageCount);
ImGui::Text("Frame Index %i", wd->FrameIndex);
ImGui::End();
}

View File

@ -15,8 +15,6 @@
#define IMGUI_VULKAN_DEBUG_REPORT
#endif
static uint32_t g_MinImageCount = 2;
static bool g_PendingSwapchainRebuild = false;
static VkAllocationCallbacks* g_Allocator = NULL;
static VkInstance g_Instance = VK_NULL_HANDLE;
static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE;
@ -28,6 +26,8 @@ static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static ImGui_ImplVulkanH_WindowData g_WindowData;
static uint32_t g_MinImageCount = 2;
static bool g_WantSwapChainRebuild = false;
static void check_vk_result(VkResult err)
{
@ -205,6 +205,7 @@ static void SetupVulkanWindowData(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR
// Create SwapChain, RenderPass, Framebuffer, etc.
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, wd, g_Allocator, width, height, g_MinImageCount);
ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, wd, g_Allocator);
IM_ASSERT(wd->BackBufferCount > 0);
}
static void CleanupVulkan()
@ -298,15 +299,6 @@ static void FramePresent(ImGui_ImplVulkanH_WindowData* wd)
check_vk_result(err);
}
static void RebuildSwapChain(int width, int height)
{
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, width, height, g_MinImageCount);
ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, &g_WindowData, g_Allocator);
ImGui_ImplVulkan_SetQueuedFramesCount(g_WindowData.BackBufferCount);
g_WindowData.FrameIndex = 0;
g_PendingSwapchainRebuild = false;
}
int main(int, char**)
{
// Setup SDL
@ -365,7 +357,7 @@ int main(int, char**)
init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool;
init_info.Allocator = g_Allocator;
init_info.QueuedFrames = wd->BackBufferCount;
init_info.QueuedFramesCount = wd->BackBufferCount;
init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
@ -434,11 +426,21 @@ int main(int, char**)
if (event.type == SDL_QUIT)
done = true;
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window))
RebuildSwapChain((int)event.window.data1, (int)event.window.data2);
{
g_WindowData.Width = (int)event.window.data1;
g_WindowData.Height = (int)event.window.data2;
g_WantSwapChainRebuild = true;
}
}
if (g_PendingSwapchainRebuild)
RebuildSwapChain(g_WindowData.Width, g_WindowData.Height);
if (g_WantSwapChainRebuild)
{
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, g_WindowData.Width, g_WindowData.Height, g_MinImageCount);
ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, &g_WindowData, g_Allocator);
ImGui_ImplVulkan_SetQueuedFramesCount(g_WindowData.BackBufferCount);
g_WindowData.FrameIndex = 0;
g_WantSwapChainRebuild = false;
}
// Start the Dear ImGui frame
ImGui_ImplVulkan_NewFrame();
@ -479,28 +481,6 @@ int main(int, char**)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
show_another_window = false;
if (ImGui::Button("Increase"))
{
g_MinImageCount++;
g_PendingSwapchainRebuild = true;
}
ImGui::SameLine();
if (ImGui::Button("Decrease"))
{
if (g_MinImageCount != 2)
{
g_MinImageCount--;
g_PendingSwapchainRebuild = true;
}
}
ImGui::SameLine();
ImGui::Text("Back Buffers: %i", g_MinImageCount);
ImGui::Text("Frame Index %i", wd->FrameIndex);
ImGui::End();
}

View File

@ -13,6 +13,8 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2019-XX-XX: Vulkan: Added QueuedFramesCount field in ImGui_ImplVulkan_InitInfo, required for initialization (was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2).
// 2019-XX-XX: Vulkan: Added ImGui_ImplVulkan_SetQueuedFramesCount() to override QueuedFramesCount while running.
// 2019-04-04: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like.
// 2019-04-01: Vulkan: Support for 32-bit index buffer (#define ImDrawIdx unsigned int).
// 2019-02-16: Vulkan: Viewport and clipping rectangles correctly using draw_data->FramebufferScale to allow retina display.
@ -63,9 +65,11 @@ struct FrameDataForRender
VkDeviceSize IndexBufferSize;
VkBuffer VertexBuffer;
VkBuffer IndexBuffer;
FrameDataForRender() { VertexBufferMemory = IndexBufferMemory = VK_NULL_HANDLE; VertexBufferSize = IndexBufferSize = VK_NULL_HANDLE; VertexBuffer = IndexBuffer = VK_NULL_HANDLE; }
};
static int g_FrameIndex = 0;
static ImVector<FrameDataForRender> g_FramesDataBuffers = {};
static ImVector<FrameDataForRender> g_FramesDataBuffers;
// Font data
static VkSampler g_FontSampler = VK_NULL_HANDLE;
@ -240,7 +244,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
VkResult err;
FrameDataForRender* fd = &g_FramesDataBuffers[g_FrameIndex];
g_FrameIndex = (g_FrameIndex + 1) % g_FramesDataBuffers.size();
g_FrameIndex = (g_FrameIndex + 1) % g_FramesDataBuffers.Size;
// Create the Vertex and Index buffers:
size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
@ -739,7 +743,7 @@ void ImGui_ImplVulkan_InvalidateDeviceObjects()
void ImGui_ImplVulkan_InvalidateFrameDeviceObjects()
{
for (int i = 0; i < g_FramesDataBuffers.size(); i++)
for (int i = 0; i < g_FramesDataBuffers.Size; i++)
{
FrameDataForRender* fd = &g_FramesDataBuffers[i];
if (fd->VertexBuffer) { vkDestroyBuffer(g_Device, fd->VertexBuffer, g_Allocator); fd->VertexBuffer = VK_NULL_HANDLE; }
@ -747,6 +751,7 @@ void ImGui_ImplVulkan_InvalidateFrameDeviceObjects()
if (fd->IndexBuffer) { vkDestroyBuffer(g_Device, fd->IndexBuffer, g_Allocator); fd->IndexBuffer = VK_NULL_HANDLE; }
if (fd->IndexBufferMemory) { vkFreeMemory (g_Device, fd->IndexBufferMemory, g_Allocator); fd->IndexBufferMemory = VK_NULL_HANDLE; }
}
g_FramesDataBuffers.clear();
}
bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass)
@ -759,6 +764,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
IM_ASSERT(info->Device != VK_NULL_HANDLE);
IM_ASSERT(info->Queue != VK_NULL_HANDLE);
IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE);
IM_ASSERT(info->QueuedFramesCount >= 2);
IM_ASSERT(render_pass != VK_NULL_HANDLE);
g_Instance = info->Instance;
@ -771,9 +777,10 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
g_DescriptorPool = info->DescriptorPool;
g_Allocator = info->Allocator;
g_CheckVkResultFn = info->CheckVkResultFn;
g_FramesDataBuffers.resize(info->QueuedFrames);
for (int i = 0; i < g_FramesDataBuffers.size(); i++)
g_FramesDataBuffers[i] = FrameDataForRender();
g_FramesDataBuffers.reserve(info->QueuedFramesCount);
for (int i = 0; i < info->QueuedFramesCount; i++)
g_FramesDataBuffers.push_back(FrameDataForRender());
ImGui_ImplVulkan_CreateDeviceObjects();
@ -790,17 +797,16 @@ void ImGui_ImplVulkan_NewFrame()
{
}
void ImGui_ImplVulkan_SetQueuedFramesCount(uint32_t count)
void ImGui_ImplVulkan_SetQueuedFramesCount(int count)
{
if (count == g_FramesDataBuffers.size())
if (count == g_FramesDataBuffers.Size)
return;
ImGui_ImplVulkan_InvalidateFrameDeviceObjects();
uint32_t old_size = g_FramesDataBuffers.size();
g_FramesDataBuffers.resize(count);
for (uint32_t i = old_size; i < count; i++)
g_FramesDataBuffers[i] = FrameDataForRender();
g_FrameIndex = 0;
g_FramesDataBuffers.reserve(count);
for (int i = 0; i < count; i++)
g_FramesDataBuffers.push_back(FrameDataForRender());
}
@ -921,7 +927,7 @@ void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_
// Create Command Buffers
VkResult err;
for (int i = 0; i < wd->Frames.size(); i++)
for (int i = 0; i < wd->Frames.Size; i++)
{
ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[i];
{
@ -1035,12 +1041,13 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice
err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->BackBufferCount, wd->BackBuffer);
check_vk_result(err);
for (uint32_t i = 0; i < wd->Frames.size(); i++)
for (int i = 0; i < wd->Frames.Size; i++)
ImGui_ImplVulkanH_DestroyFrameData(g_Instance, device, &wd->Frames[i], allocator);
uint32_t old_size = wd->Frames.size();
wd->Frames.resize(wd->BackBufferCount);
for (uint32_t i = 0; i < wd->Frames.size(); i++)
wd->Frames[i] = ImGui_ImplVulkanH_FrameData();
wd->Frames.clear();
wd->Frames.reserve((int)wd->BackBufferCount);
for (int i = 0; i < (int)wd->BackBufferCount; i++)
wd->Frames.push_back(ImGui_ImplVulkanH_FrameData());
}
if (old_swapchain)
vkDestroySwapchainKHR(device, old_swapchain, allocator);
@ -1127,7 +1134,7 @@ void ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, I
vkDeviceWaitIdle(device); // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals)
//vkQueueWaitIdle(g_Queue);
for (int i = 0; i < wd->Frames.size(); i++)
for (int i = 0; i < wd->Frames.Size; i++)
{
ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[i];
ImGui_ImplVulkanH_DestroyFrameData(instance, device, fd, allocator);
@ -1145,9 +1152,15 @@ void ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, I
void ImGui_ImplVulkanH_DestroyFrameData(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameData* 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->BackbufferIndex = 0;
fd->Fence = VK_NULL_HANDLE;
fd->CommandBuffer = VK_NULL_HANDLE;
fd->CommandPool = VK_NULL_HANDLE;
fd->ImageAcquiredSemaphore = fd->RenderCompleteSemaphore = VK_NULL_HANDLE;
}

View File

@ -27,7 +27,7 @@ struct ImGui_ImplVulkan_InitInfo
VkQueue Queue;
VkPipelineCache PipelineCache;
VkDescriptorPool DescriptorPool;
int QueuedFrames;
int QueuedFramesCount;
const VkAllocationCallbacks* Allocator;
void (*CheckVkResultFn)(VkResult err);
};
@ -36,7 +36,7 @@ struct ImGui_ImplVulkan_InitInfo
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass);
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
IMGUI_IMPL_API void ImGui_ImplVulkan_SetQueuedFramesCount(uint32_t count);
IMGUI_IMPL_API void ImGui_ImplVulkan_SetQueuedFramesCount(int queued_frames_count); // To override QueuedFramesCount after initialization
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer);
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
IMGUI_IMPL_API void ImGui_ImplVulkan_InvalidateFontUploadObjects();