From 98b66a5fc9cd7e01cfca3b3ec44f77944bfe40c3 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 13 Mar 2018 21:45:09 +0100 Subject: [PATCH] Examples: Using draw_data->DisplaySize, followup to c50198debe4978853f3f8ed6e84a7b2685991c06. Fix Vulkan secondary viewport rendering. SDL+Vulkan: Matched changes. Fix vcprojs. (#1542, #1042) --- examples/imgui_impl_dx9.cpp | 12 +-- examples/imgui_impl_opengl2.cpp | 4 +- examples/imgui_impl_vulkan.cpp | 4 +- examples/sdl_opengl2_example/main.cpp | 2 +- examples/sdl_vulkan_example/main.cpp | 74 +++++++------------ .../sdl_vulkan_example.vcxproj | 2 +- .../vulkan_example/vulkan_example.vcxproj | 2 +- 7 files changed, 39 insertions(+), 61 deletions(-) diff --git a/examples/imgui_impl_dx9.cpp b/examples/imgui_impl_dx9.cpp index 8be032d51..931e5148a 100644 --- a/examples/imgui_impl_dx9.cpp +++ b/examples/imgui_impl_dx9.cpp @@ -42,8 +42,7 @@ struct CUSTOMVERTEX void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) { // Avoid rendering when minimized - ImGuiIO& io = ImGui::GetIO(); - if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f) + if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) return; // Create and grow buffers if needed @@ -101,8 +100,8 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) // Setup viewport D3DVIEWPORT9 vp; vp.X = vp.Y = 0; - vp.Width = (DWORD)io.DisplaySize.x; - vp.Height = (DWORD)io.DisplaySize.y; + vp.Width = (DWORD)draw_data->DisplaySize.x; + vp.Height = (DWORD)draw_data->DisplaySize.y; vp.MinZ = 0.0f; vp.MaxZ = 1.0f; g_pd3dDevice->SetViewport(&vp); @@ -131,7 +130,10 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) // Setup orthographic projection matrix // Being agnostic of whether or can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH() { - const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f; + float L = draw_data->DisplayPos.x + 0.5f; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f; + float T = draw_data->DisplayPos.y + 0.5f; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f; D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } }; D3DMATRIX mat_projection = { diff --git a/examples/imgui_impl_opengl2.cpp b/examples/imgui_impl_opengl2.cpp index ae1c234d1..cf763efd4 100644 --- a/examples/imgui_impl_opengl2.cpp +++ b/examples/imgui_impl_opengl2.cpp @@ -60,8 +60,8 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + int fb_width = (int)(draw_data->DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(draw_data->DisplaySize.y * io.DisplayFramebufferScale.y); if (fb_width == 0 || fb_height == 0) return; draw_data->ScaleClipRects(io.DisplayFramebufferScale); diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index 28f074133..11d8e8de6 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -263,8 +263,8 @@ void ImGui_ImplVulkan_RenderDrawData(VkCommandBuffer command_buffer, ImDrawData* VkViewport viewport; viewport.x = 0; viewport.y = 0; - viewport.width = io.DisplaySize.x; - viewport.height = io.DisplaySize.y; + viewport.width = draw_data->DisplaySize.x; + viewport.height = draw_data->DisplaySize.y; viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; vkCmdSetViewport(command_buffer, 0, 1, &viewport); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 05b358c85..1b5c50348 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -121,7 +121,7 @@ int main(int, char**) } // Rendering - glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); + glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound diff --git a/examples/sdl_vulkan_example/main.cpp b/examples/sdl_vulkan_example/main.cpp index 5c4e60088..08db99ce1 100644 --- a/examples/sdl_vulkan_example/main.cpp +++ b/examples/sdl_vulkan_example/main.cpp @@ -9,7 +9,6 @@ #include #include -// FIXME-VULKAN: Resizing with IMGUI_UNLIMITED_FRAME_RATE triggers errors from the validation layer. #define IMGUI_UNLIMITED_FRAME_RATE #ifdef _DEBUG #define IMGUI_VULKAN_DEBUG_REPORT @@ -220,19 +219,20 @@ static void CleanupVulkan() vkDestroyInstance(g_Instance, g_Allocator); } -static void FrameBegin(ImGui_ImplVulkan_WindowData* wd) +static void FrameRender(ImGui_ImplVulkan_WindowData* wd) { + VkResult err; + + VkSemaphore& image_acquired_semaphore = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore; + err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); + check_vk_result(err); + ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex]; - VkResult err; - for (;;) { - err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, 100); - if (err == VK_SUCCESS) break; - if (err == VK_TIMEOUT) continue; + err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking check_vk_result(err); - } - { - err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, fd->PresentCompleteSemaphore, VK_NULL_HANDLE, &fd->BackbufferIndex); + + err = vkResetFences(g_Device, 1, &fd->Fence); check_vk_result(err); } { @@ -248,26 +248,25 @@ static void FrameBegin(ImGui_ImplVulkan_WindowData* wd) VkRenderPassBeginInfo info = {}; info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; info.renderPass = wd->RenderPass; - info.framebuffer = wd->Framebuffer[fd->BackbufferIndex]; + info.framebuffer = wd->Framebuffer[wd->FrameIndex]; info.renderArea.extent.width = wd->Width; info.renderArea.extent.height = wd->Height; info.clearValueCount = 1; info.pClearValues = &wd->ClearValue; vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); } -} -static void FrameEnd(ImGui_ImplVulkan_WindowData* wd) -{ - ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex]; - VkResult err; + // Record Imgui Draw Data and draw funcs into command buffer + ImGui_ImplVulkan_RenderDrawData(fd->CommandBuffer, ImGui::GetDrawData()); + + // Submit command buffer vkCmdEndRenderPass(fd->CommandBuffer); { VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo info = {}; info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; info.waitSemaphoreCount = 1; - info.pWaitSemaphores = &fd->PresentCompleteSemaphore; + info.pWaitSemaphores = &image_acquired_semaphore; info.pWaitDstStageMask = &wait_stage; info.commandBufferCount = 1; info.pCommandBuffers = &fd->CommandBuffer; @@ -276,8 +275,6 @@ static void FrameEnd(ImGui_ImplVulkan_WindowData* wd) err = vkEndCommandBuffer(fd->CommandBuffer); check_vk_result(err); - err = vkResetFences(g_Device, 1, &fd->Fence); - check_vk_result(err); err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence); check_vk_result(err); } @@ -285,23 +282,15 @@ static void FrameEnd(ImGui_ImplVulkan_WindowData* wd) static void FramePresent(ImGui_ImplVulkan_WindowData* wd) { - VkResult err; - // If IMGUI_UNLIMITED_FRAME_RATE is defined we present the latest but one frame. Otherwise we present the latest rendered frame -#ifdef IMGUI_UNLIMITED_FRAME_RATE - uint32_t PresentIndex = (wd->FrameIndex + IMGUI_VK_QUEUED_FRAMES - 1) % IMGUI_VK_QUEUED_FRAMES; -#else - uint32_t PresentIndex = wd->FrameIndex; -#endif // IMGUI_UNLIMITED_FRAME_RATE - - ImGui_ImplVulkan_FrameData* fd = &wd->Frames[PresentIndex]; + ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex]; VkPresentInfoKHR info = {}; info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; info.waitSemaphoreCount = 1; info.pWaitSemaphores = &fd->RenderCompleteSemaphore; info.swapchainCount = 1; info.pSwapchains = &wd->Swapchain; - info.pImageIndices = &fd->BackbufferIndex; - err = vkQueuePresentKHR(g_Queue, &info); + info.pImageIndices = &wd->FrameIndex; + VkResult err = vkQueuePresentKHR(g_Queue, &info); check_vk_result(err); } @@ -329,6 +318,7 @@ int main(int, char**) // Create Window Surface VkSurfaceKHR surface; + VkResult err; if (SDL_Vulkan_CreateSurface(window, g_Instance, &surface) == 0) { printf("Failed to create Vulkan surface.\n"); @@ -348,6 +338,9 @@ int main(int, char**) io.ConfigFlags |= ImGuiConfigFlags_PlatformNoTaskBar; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + // Setup SDL binding + ImGui_ImplSDL2_Init(window, NULL); + // Setup Vulkan binding ImGui_ImplVulkan_InitInfo init_info = {}; init_info.Instance = g_Instance; @@ -359,7 +352,6 @@ int main(int, char**) init_info.DescriptorPool = g_DescriptorPool; init_info.Allocator = g_Allocator; init_info.CheckVkResultFn = check_vk_result; - ImGui_ImplSDL2_Init(window, NULL); ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); // Setup style @@ -387,7 +379,6 @@ int main(int, char**) VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool; VkCommandBuffer command_buffer = wd->Frames[wd->FrameIndex].CommandBuffer; - VkResult err; err = vkResetCommandPool(g_Device, command_pool, 0); check_vk_result(err); VkCommandBufferBeginInfo begin_info = {}; @@ -416,8 +407,6 @@ int main(int, char**) bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); - bool swap_chain_has_at_least_one_image = false; - // Main loop bool done = false; while (!done) @@ -478,26 +467,13 @@ int main(int, char**) // Rendering ImGui::Render(); memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); - FrameBegin(wd); - ImGui_ImplVulkan_RenderDrawData(wd->Frames[wd->FrameIndex].CommandBuffer, ImGui::GetDrawData()); - FrameEnd(wd); - + FrameRender(wd); ImGui::RenderAdditionalViewports(); - -#ifdef IMGUI_UNLIMITED_FRAME_RATE - // When IMGUI_UNLIMITED_FRAME_RATE is defined we render into latest image acquired from the swapchain but we display the image which was rendered before. - // Hence we must render once and increase the FrameIndex without presenting. - if (swap_chain_has_at_least_one_image) - FramePresent(wd); -#else FramePresent(wd); -#endif - swap_chain_has_at_least_one_image = true; - wd->FrameIndex = (wd->FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; } // Cleanup - VkResult err = vkDeviceWaitIdle(g_Device); + err = vkDeviceWaitIdle(g_Device); check_vk_result(err); ImGui_ImplVulkan_Shutdown(); ImGui_ImplSDL2_Shutdown(); diff --git a/examples/sdl_vulkan_example/sdl_vulkan_example.vcxproj b/examples/sdl_vulkan_example/sdl_vulkan_example.vcxproj index f848f1ffc..3f7733a80 100644 --- a/examples/sdl_vulkan_example/sdl_vulkan_example.vcxproj +++ b/examples/sdl_vulkan_example/sdl_vulkan_example.vcxproj @@ -20,7 +20,7 @@ {BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3} - opengl3_example + sdl_vulkan_example diff --git a/examples/vulkan_example/vulkan_example.vcxproj b/examples/vulkan_example/vulkan_example.vcxproj index 299b26f4f..0523bb18d 100644 --- a/examples/vulkan_example/vulkan_example.vcxproj +++ b/examples/vulkan_example/vulkan_example.vcxproj @@ -20,7 +20,7 @@ {57E2DF5A-6FC8-45BB-99DD-91A18C646E80} - opengl3_example + vulkan_example