From 8074d56bdd9117483cdc7f2811f9d59db3a6ea15 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 28 Feb 2018 18:51:40 +0100 Subject: [PATCH 1/6] Renamed ImGuiNavFlags io.NavFlags to ImGuiConfigFlags io.ConfigFlags. (#787) --- CHANGELOG.txt | 8 ++++---- README.md | 2 +- examples/allegro5_example/main.cpp | 2 +- examples/directx10_example/main.cpp | 2 +- examples/directx11_example/main.cpp | 2 +- examples/directx12_example/main.cpp | 2 +- examples/directx9_example/main.cpp | 2 +- examples/imgui_impl_glfw.cpp | 9 +++++---- examples/imgui_impl_glfw.h | 2 +- examples/imgui_impl_win32.cpp | 2 +- examples/marmalade_example/main.cpp | 2 +- examples/opengl2_example/main.cpp | 2 +- examples/opengl3_example/main.cpp | 4 ++-- examples/sdl_opengl2_example/main.cpp | 2 +- examples/sdl_opengl3_example/main.cpp | 2 +- examples/sdl_vulkan_example/main.cpp | 5 +++-- examples/vulkan_example/main.cpp | 6 ++++-- imgui.cpp | 28 +++++++++++++-------------- imgui.h | 22 ++++++++++----------- imgui_demo.cpp | 6 +++--- imgui_internal.h | 4 ++-- 21 files changed, 60 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index a0f0e2a7f..06ee3c3ba 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -66,11 +66,11 @@ Other Changes: - Navigation: merged in the gamepad/keyboard navigation (about one million changes!). (#787, #323) The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. - To use Keyboard Navigation: - - Set io.NavFlags |= ImGuiNavFlags_EnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. - - When keyboard navigation is active (io.NavActive + NavFlags_EnableKeyboard), the io.WantCaptureKeyboard flag will be set. + - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. + - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), the io.WantCaptureKeyboard flag will be set. For more advanced uses, you may want to read from io.NavActive or io.NavVisible. Read imgui.cpp for more details. - To use Gamepad Navigation: - - Set io.NavFlags |= ImGuiNavFlags_EnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). + - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). - See https://github.com/ocornut/imgui/issues/1599 for recommended gamepad mapping. - See 'enum ImGuiNavInput_' in imgui.h for a description of inputs. Read imgui.cpp for more details. - Navigation: SetItemDefaultFocus() sets the navigation position in addition to scrolling. (#787) @@ -78,7 +78,7 @@ Other Changes: - Navigation: Added window flags: ImGuiWindowFlags_NoNav (ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus). - Navigation: Style: Added ImGuiCol_NavHighlight, ImGuiCol_NavWindowingHighlight colors. (#787) - Navigation: TreeNode: Added ImGuiTreeNodeFlags_NavLeftJumpsBackHere flag to allow Nav Left direction to jump back to parent tree node from any of its child. (#1079) -- Navigation: IO: Added io.NavFlags (input), io.NavActive (output), io.NavVisible (output). (#787) +- Navigation: IO: Added io.ConfigFlags (input), io.NavActive (output), io.NavVisible (output). (#787) - Context: Removed the default global context and font atlas instances, which caused various problems to users of multiple contexts and DLL users. (#1565) YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. Existing apps will assert/crash without it. - Context: Removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions() and shared by all contexts. (#1565, #586, #992, #1007, #1558) diff --git a/README.md b/README.md index 1190405ac..da7979635 100644 --- a/README.md +++ b/README.md @@ -248,7 +248,7 @@ See the FAQ in imgui.cpp for answers. How do you use Dear ImGui on a platform that may not have a mouse or keyboard? -You can control Dear ImGui with a gamepad, see the explanation in imgui.cpp about how to use the navigation feature (short version: map your gamepad inputs into the `io.NavInputs[]` array and set `io.NavFlags |= ImGuiNavFlags_EnableGamepad`). +You can control Dear ImGui with a gamepad, see the explanation in imgui.cpp about how to use the navigation feature (short version: map your gamepad inputs into the `io.NavInputs[]` array and set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad`). You can share your computer mouse seamlessy with your console/tablet/phone using [Synergy](http://synergy-project.org). This is the prefered solution for developer productivity. In particular, their [micro-synergy-client](https://github.com/symless/micro-synergy-client) repo there is _uSynergy.c_ sources for a small embeddable that you can use on any platform to connect to your host PC. You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui). diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index 4a5346102..80326bca9 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -25,8 +25,8 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplAllegro5_Init(display); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4dc5939e0..db7c01a77 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -115,9 +115,9 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX10_Init(g_pd3dDevice); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index c52fe00a8..51f42793e 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -118,9 +118,9 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/directx12_example/main.cpp b/examples/directx12_example/main.cpp index e6d19b8f6..b8be4bfe0 100644 --- a/examples/directx12_example/main.cpp +++ b/examples/directx12_example/main.cpp @@ -289,7 +289,7 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX12_Init(g_pd3dDevice, NUM_FRAMES_IN_FLIGHT, DXGI_FORMAT_R8G8B8A8_UNORM, g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart()); diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index c7f54255a..1035cee29 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -78,9 +78,9 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX9_Init(g_pd3dDevice); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/imgui_impl_glfw.cpp b/examples/imgui_impl_glfw.cpp index 1342a9b1e..f0c06e80e 100644 --- a/examples/imgui_impl_glfw.cpp +++ b/examples/imgui_impl_glfw.cpp @@ -3,7 +3,7 @@ // (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) // Implemented features: -// [X] Gamepad navigation mapping. Enable with 'io.NavFlags |= ImGuiNavFlags_EnableGamepad'. +// [X] Gamepad navigation mapping. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). @@ -15,8 +15,8 @@ // 2018-XX-XX: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. -// 2018-01-25: Inputs: Added gamepad support if ImGuiNavFlags_EnableGamepad is set. -// 2018-01-25: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. +// 2018-01-25: Inputs: Added gamepad support if ImGuiConfigFlags_NavEnableGamepad is set. +// 2018-01-25: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. // 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. // 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). @@ -152,6 +152,7 @@ void ImGui_ImplGlfw_Shutdown() static void ImGui_ImplGlfw_UpdateMousePosButtons() { // Update buttons + ImGuiIO& io = ImGui::GetIO(); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) { // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. @@ -214,7 +215,7 @@ void ImGui_ImplGlfw_NewFrame() // Gamepad navigation mapping [BETA] memset(io.NavInputs, 0, sizeof(io.NavInputs)); - if (io.NavFlags & ImGuiNavFlags_EnableGamepad) + if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) { // Update gamepad inputs #define MAP_BUTTON(NAV_NO, BUTTON_NO) { if (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS) io.NavInputs[NAV_NO] = 1.0f; } diff --git a/examples/imgui_impl_glfw.h b/examples/imgui_impl_glfw.h index c6cb4c8a3..3e8fd6c7e 100644 --- a/examples/imgui_impl_glfw.h +++ b/examples/imgui_impl_glfw.h @@ -3,7 +3,7 @@ // (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) // Implemented features: -// [X] Gamepad navigation mapping. Enable with 'io.NavFlags |= ImGuiNavFlags_EnableGamepad'. +// [X] Gamepad navigation mapping. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). diff --git a/examples/imgui_impl_win32.cpp b/examples/imgui_impl_win32.cpp index f538590a7..ffe8d90f9 100644 --- a/examples/imgui_impl_win32.cpp +++ b/examples/imgui_impl_win32.cpp @@ -9,7 +9,7 @@ // CHANGELOG // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. -// 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. +// 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. // 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index 08f8b1d5c..817a28727 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -19,8 +19,8 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_Marmalade_Init(true); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index 6eefca8ff..0b2885c42 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -30,9 +30,9 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplGlfw_Init(window, true); ImGui_ImplOpenGL2_Init(); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index 3a49f8ee5..37667235d 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -35,10 +35,10 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls ImGui_ImplGlfw_Init(window, true); ImGui_ImplOpenGL3_Init(); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls - //io.NavFlags |= ImGuiNavFlags_EnableGamepad; // Enable Gamepad Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 6c8dd1d3b..eb12c539f 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -37,9 +37,9 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplSDL2_Init(window); ImGui_ImplOpenGL2_Init(); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index 24f2f8dc5..eb4249cc4 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -37,9 +37,9 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplSDL2_Init(window); ImGui_ImplOpenGL3_Init(); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Setup style ImGui::StyleColorsDark(); diff --git a/examples/sdl_vulkan_example/main.cpp b/examples/sdl_vulkan_example/main.cpp index 158a1b3e9..973d75b7b 100644 --- a/examples/sdl_vulkan_example/main.cpp +++ b/examples/sdl_vulkan_example/main.cpp @@ -612,8 +612,6 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); (void)io; - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; ImGui_ImplVulkan_InitData init_data = {}; init_data.allocator = g_Allocator; @@ -623,6 +621,9 @@ int main(int, char**) init_data.pipeline_cache = g_PipelineCache; init_data.descriptor_pool = g_DescriptorPool; init_data.check_vk_result = check_vk_result; + + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplVulkan_Init(&init_data); ImGui_ImplSDL2_Init(window); diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 24135e269..b979fc004 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -615,7 +615,7 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); (void)io; + ImGui_ImplVulkan_InitData init_data = {}; init_data.allocator = g_Allocator; init_data.gpu = g_Gpu; @@ -624,9 +624,11 @@ int main(int, char**) init_data.pipeline_cache = g_PipelineCache; init_data.descriptor_pool = g_DescriptorPool; init_data.check_vk_result = check_vk_result; + + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplVulkan_Init(&init_data); ImGui_ImplGlfw_Init(window, true); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/imgui.cpp b/imgui.cpp index 8a577564b..3e9f690d1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -216,15 +216,15 @@ - Ask questions and report issues at https://github.com/ocornut/imgui/issues/787 - The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. - Keyboard: - - Set io.NavFlags |= ImGuiNavFlags_EnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. - - When keyboard navigation is active (io.NavActive + NavFlags_EnableKeyboard), the io.WantCaptureKeyboard flag will be set. + - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. + - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), the io.WantCaptureKeyboard flag will be set. For more advanced uses, you may want to read from: - io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set. - io.NavVisible: true when the navigation cursor is visible (and usually goes false when mouse is used). - or query focus information with e.g. IsWindowFocused(), IsItemFocused() etc. functions. Please reach out if you think the game vs navigation input sharing could be improved. - Gamepad: - - Set io.NavFlags |= ImGuiNavFlags_EnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). + - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). - See 'enum ImGuiNavInput_' in imgui.h for a description of inputs. For each entry of io.NavInputs[], set the following values: 0.0f= not held. 1.0f= fully held. Pass intermediate 0.0f..1.0f values for analog triggers/sticks. - We uses a simple >0.0f test for activation testing, and won't attempt to test for a dead-zone. @@ -234,11 +234,11 @@ - Mouse: - PS4 users: Consider emulating a mouse cursor with DualShock4 touch pad or a spare analog stick as a mouse-emulation fallback. - Consoles/Tablet/Phone users: Consider using Synergy host (on your computer) + uSynergy.c (in your console/tablet/phone app) to use your PC mouse/keyboard. - - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiNavFlags_MoveMouse flag in io.NavFlags. - Enabling ImGuiNavFlags_MoveMouse instructs dear imgui to move your mouse cursor along with navigation movements. + - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavMoveMouse flag. + Enabling ImGuiConfigFlags_NavMoveMouse instructs dear imgui to move your mouse cursor along with navigation movements. When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantMoveMouse' to notify you that it wants the mouse cursor to be moved. When that happens your back-end NEEDS to move the OS or underlying mouse cursor on the next frame. Some of the binding in examples/ do that. - (If you set the ImGuiNavFlags_MoveMouse flag but don't honor 'io.WantMoveMouse' properly, imgui will misbehave as it will see your mouse as moving back and forth.) + (If you set the NavMoveMouse flag but don't honor 'io.WantMoveMouse' properly, imgui will misbehave as it will see your mouse as moving back and forth!) (In a setup when you may not have easy control over the mouse cursor, e.g. uSynergy.c doesn't expose moving remote mouse cursor, you may want to set a boolean to ignore your other external mouse positions until the external source is moved again.) @@ -847,7 +847,7 @@ ImGuiIO::ImGuiIO() // Settings DisplaySize = ImVec2(-1.0f, -1.0f); DeltaTime = 1.0f/60.0f; - NavFlags = 0x00; + ConfigFlags = 0x00; IniSavingRate = 5.0f; IniFilename = "imgui.ini"; LogFilename = "imgui_log.txt"; @@ -2810,7 +2810,7 @@ static void ImGui::NavUpdateWindowing() bool apply_toggle_layer = false; bool start_windowing_with_gamepad = !g.NavWindowingTarget && IsNavInputPressed(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed); - bool start_windowing_with_keyboard = !g.NavWindowingTarget && g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard); + bool start_windowing_with_keyboard = !g.NavWindowingTarget && g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard); if (start_windowing_with_gamepad || start_windowing_with_keyboard) if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavigable(g.Windows.Size - 1, -INT_MAX, -1)) { @@ -2965,7 +2965,7 @@ static void ImGui::NavUpdate() // Update Keyboard->Nav inputs mapping memset(g.IO.NavInputs + ImGuiNavInput_InternalStart_, 0, (ImGuiNavInput_COUNT - ImGuiNavInput_InternalStart_) * sizeof(g.IO.NavInputs[0])); - if (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) + if (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) { #define NAV_MAP_KEY(_KEY, _NAV_INPUT) if (g.IO.KeyMap[_KEY] != -1 && IsKeyDown(g.IO.KeyMap[_KEY])) g.IO.NavInputs[_NAV_INPUT] = 1.0f; NAV_MAP_KEY(ImGuiKey_Space, ImGuiNavInput_Activate ); @@ -3037,7 +3037,7 @@ static void ImGui::NavUpdate() if (g.NavMousePosDirty && g.NavIdIsAlive) { // Set mouse position given our knowledge of the nav widget position from last frame - if (g.IO.NavFlags & ImGuiNavFlags_MoveMouse) + if (g.IO.ConfigFlags & ImGuiConfigFlags_NavMoveMouse) { g.IO.MousePos = g.IO.MousePosPrev = NavCalcPreferredMousePos(); g.IO.WantMoveMouse = true; @@ -3057,7 +3057,7 @@ static void ImGui::NavUpdate() NavUpdateWindowing(); // Set output flags for user application - g.IO.NavActive = (g.IO.NavFlags & (ImGuiNavFlags_EnableGamepad | ImGuiNavFlags_EnableKeyboard)) && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs); + g.IO.NavActive = (g.IO.ConfigFlags & (ImGuiConfigFlags_NavEnableGamepad | ImGuiConfigFlags_NavEnableKeyboard)) && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs); g.IO.NavVisible = (g.IO.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL) || g.NavInitRequest; // Process NavCancel input (to close a popup, get back to parent, clear focus) @@ -3282,7 +3282,7 @@ void ImGui::NewFrame() IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)"); // Do a simple check for required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was super recently added in 1.60 WIP) - if (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) + if (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation."); // Load settings on first frame @@ -3449,7 +3449,7 @@ void ImGui::NewFrame() g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0); else g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL); - if (g.IO.NavActive && (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) && !(g.IO.NavFlags & ImGuiNavFlags_NoCaptureKeyboard)) + if (g.IO.NavActive && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard)) g.IO.WantCaptureKeyboard = true; g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0; @@ -5844,7 +5844,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) float sc = g.Style.MouseCursorScale; ImVec2 ref_pos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos; ImRect rect_to_avoid; - if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.NavFlags & ImGuiNavFlags_MoveMouse)) + if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavMoveMouse)) rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8); else rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important. diff --git a/imgui.h b/imgui.h index 608ce1b28..66144d6d5 100644 --- a/imgui.h +++ b/imgui.h @@ -95,7 +95,7 @@ typedef int ImGuiComboFlags; // flags: for BeginCombo() typedef int ImGuiFocusedFlags; // flags: for IsWindowFocused() // enum ImGuiFocusedFlags_ typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() etc. // enum ImGuiHoveredFlags_ typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ -typedef int ImGuiNavFlags; // flags: for io.NavFlags // enum ImGuiNavFlags_ +typedef int ImGuiConfigFlags; // flags: for io.ConfigFlags // enum ImGuiConfigFlags_ typedef int ImGuiSelectableFlags; // flags: for Selectable() // enum ImGuiSelectableFlags_ typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(),CollapsingHeader()// enum ImGuiTreeNodeFlags_ typedef int ImGuiWindowFlags; // flags: for Begin*() // enum ImGuiWindowFlags_ @@ -710,8 +710,8 @@ enum ImGuiKey_ }; // [BETA] Gamepad/Keyboard directional navigation -// Keyboard: Set io.NavFlags |= ImGuiNavFlags_EnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. -// Gamepad: Set io.NavFlags |= ImGuiNavFlags_EnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). +// Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_EnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. +// Gamepad: Set io.ConfigFlags |= ImGuiConfigFlags_EnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). // Read instructions in imgui.cpp for more details. enum ImGuiNavInput_ { @@ -744,13 +744,13 @@ enum ImGuiNavInput_ ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyMenu_ }; -// [BETA] Gamepad/Keyboard directional navigation flags, stored in io.NavFlags -enum ImGuiNavFlags_ +// Configuration flags stored in io.ConfigFlags +enum ImGuiConfigFlags_ { - ImGuiNavFlags_EnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeyDown[]. - ImGuiNavFlags_EnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui back-end to fill io.NavInputs[]. - ImGuiNavFlags_MoveMouse = 1 << 2, // Request navigation to allow moving the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantMoveMouse=true. If enabled you MUST honor io.WantMoveMouse requests in your binding, otherwise ImGui will react as if the mouse is jumping around back and forth. - ImGuiNavFlags_NoCaptureKeyboard = 1 << 3 // Do not set the io.WantCaptureKeyboard flag with io.NavActive is set. + ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeyDown[]. + ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui back-end to fill io.NavInputs[]. + ImGuiConfigFlags_NavMoveMouse = 1 << 2, // Request navigation to allow moving the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantMoveMouse=true. If enabled you MUST honor io.WantMoveMouse requests in your binding, otherwise ImGui will react as if the mouse is jumping around back and forth. + ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3 // Do not set the io.WantCaptureKeyboard flag with io.NavActive is set. }; // Enumeration for PushStyleColor() / PopStyleColor() @@ -953,7 +953,7 @@ struct ImGuiIO ImVec2 DisplaySize; // // Display size, in pixels. For clamping windows positions. float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. - ImGuiNavFlags NavFlags; // = 0x00 // See ImGuiNavFlags_. Gamepad/keyboard navigation options. + ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Gamepad/keyboard navigation options, etc. float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds. const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving. const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). @@ -1028,7 +1028,7 @@ struct ImGuiIO bool WantCaptureMouse; // When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. This is set by ImGui when it wants to use your mouse (e.g. unclicked mouse is hovering a window, or a widget is active). bool WantCaptureKeyboard; // When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. This is set by ImGui when it wants to use your keyboard inputs. bool WantTextInput; // Mobile/console: when io.WantTextInput is true, you may display an on-screen keyboard. This is set by ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). - bool WantMoveMouse; // MousePos has been altered, back-end should reposition mouse on next frame. Set only when ImGuiNavFlags_MoveMouse flag is enabled in io.NavFlags. + bool WantMoveMouse; // MousePos has been altered, back-end should reposition mouse on next frame. Set only when ImGuiConfigFlags_NavMoveMouse flag is enabled. bool NavActive; // Directional navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. bool NavVisible; // Directional navigation is visible and allowed (will handle ImGuiKey_NavXXX events). float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 00cd299dc..abc1d5ba2 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1806,9 +1806,9 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); ImGui::SameLine(); ShowHelpMarker("Request ImGui to render a mouse cursor for you in software. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); - ImGui::CheckboxFlags("io.NavFlags: EnableGamepad", (unsigned int *)&io.NavFlags, ImGuiNavFlags_EnableGamepad); - ImGui::CheckboxFlags("io.NavFlags: EnableKeyboard", (unsigned int *)&io.NavFlags, ImGuiNavFlags_EnableKeyboard); - ImGui::CheckboxFlags("io.NavFlags: MoveMouse", (unsigned int *)&io.NavFlags, ImGuiNavFlags_MoveMouse); + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad); + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard); + ImGui::CheckboxFlags("io.ConfigFlags: NavMoveMouse", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavMoveMouse); ImGui::SameLine(); ShowHelpMarker("Request ImGui to move your move cursor when using gamepad/keyboard navigation. NewFrame() will change io.MousePos and set the io.WantMoveMouse flag, your backend will need to apply the new mouse position."); if (ImGui::TreeNode("Keyboard, Mouse & Navigation State")) diff --git a/imgui_internal.h b/imgui_internal.h index ddbbf0d77..9b8204369 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -633,8 +633,8 @@ struct ImGuiContext int NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later. int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRefRectRel is valid - bool NavMousePosDirty; // When set we will update mouse position if (NavFlags & ImGuiNavFlags_MoveMouse) if set (NB: this not enabled by default) - bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (nb: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) + bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavMoveMouse) if set (NB: this not enabled by default) + bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) bool NavDisableMouseHover; // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again. bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest bool NavInitRequest; // Init request for appearing window to select first item From cf365ed00b5ad222956ffc379908b557da8a4d9a Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 1 Mar 2018 18:41:19 +0100 Subject: [PATCH 2/6] Examples: Fixed enabling IMGUI_VULKAN_DEBUG_REPORT which was broken during refactor because of duplicate 'extensions' local variable. --- examples/sdl_vulkan_example/main.cpp | 19 +++++++++---------- examples/vulkan_example/main.cpp | 19 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/examples/sdl_vulkan_example/main.cpp b/examples/sdl_vulkan_example/main.cpp index 973d75b7b..9e08a9656 100644 --- a/examples/sdl_vulkan_example/main.cpp +++ b/examples/sdl_vulkan_example/main.cpp @@ -189,9 +189,9 @@ static void resize_vulkan(SDL_Window*, int w, int h) } #ifdef IMGUI_VULKAN_DEBUG_REPORT -static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report( - VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) +static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) { + (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguemnts printf("[vulkan] ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); return VK_FALSE; } @@ -209,25 +209,24 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e create_info.ppEnabledExtensionNames = extensions; #ifdef IMGUI_VULKAN_DEBUG_REPORT - // enabling multiple validation layers grouped as lunarg standard validation + // Enabling multiple validation layers grouped as LunarG standard validation const char* layers[] = { "VK_LAYER_LUNARG_standard_validation" }; create_info.enabledLayerCount = 1; create_info.ppEnabledLayerNames = layers; - // need additional storage for char pointer to debug report extension - const char** extensions = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); - for (size_t i = 0; i < extensions_count; i++) - extensions[i] = extensions[i]; - extensions[extensions_count] = "VK_EXT_debug_report"; + // Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it) + const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); + memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*)); + extensions_ext[extensions_count] = "VK_EXT_debug_report"; create_info.enabledExtensionCount = extensions_count + 1; - create_info.ppEnabledExtensionNames = extensions; + create_info.ppEnabledExtensionNames = extensions_ext; #endif // IMGUI_VULKAN_DEBUG_REPORT err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); check_vk_result(err); #ifdef IMGUI_VULKAN_DEBUG_REPORT - free(extensions); + free(extensions_ext); // create the debug report callback VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index b979fc004..ca0cdcca0 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -192,9 +192,9 @@ static void resize_vulkan(GLFWwindow*, int w, int h) } #ifdef IMGUI_VULKAN_DEBUG_REPORT -static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report( - VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) +static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) { + (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguemnts printf("[vulkan] ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); return VK_FALSE; } @@ -212,25 +212,24 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e create_info.ppEnabledExtensionNames = extensions; #ifdef IMGUI_VULKAN_DEBUG_REPORT - // enabling multiple validation layers grouped as lunarg standard validation + // Enabling multiple validation layers grouped as LunarG standard validation const char* layers[] = { "VK_LAYER_LUNARG_standard_validation" }; create_info.enabledLayerCount = 1; create_info.ppEnabledLayerNames = layers; - // need additional storage for char pointer to debug report extension - const char** extensions = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); - for (size_t i = 0; i < extensions_count; i++) - extensions[i] = extensions[i]; - extensions[extensions_count] = "VK_EXT_debug_report"; + // Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it) + const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); + memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*)); + extensions_ext[extensions_count] = "VK_EXT_debug_report"; create_info.enabledExtensionCount = extensions_count + 1; - create_info.ppEnabledExtensionNames = extensions; + create_info.ppEnabledExtensionNames = extensions_ext; #endif // IMGUI_VULKAN_DEBUG_REPORT err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); check_vk_result(err); #ifdef IMGUI_VULKAN_DEBUG_REPORT - free(extensions); + free(extensions_ext); // create the debug report callback VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; From 57e9f618529a7378284512e2ac01e617b76299df Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 1 Mar 2018 18:59:07 +0100 Subject: [PATCH 3/6] Examples: Vulkan: Debug report tweak + always enable in Debug build. --- examples/sdl_vulkan_example/main.cpp | 25 ++++++++++++------------- examples/vulkan_example/main.cpp | 25 ++++++++++++------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/examples/sdl_vulkan_example/main.cpp b/examples/sdl_vulkan_example/main.cpp index 9e08a9656..973fd5d90 100644 --- a/examples/sdl_vulkan_example/main.cpp +++ b/examples/sdl_vulkan_example/main.cpp @@ -11,9 +11,9 @@ #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16 #define IMGUI_UNLIMITED_FRAME_RATE -//#ifdef _DEBUG -//#define IMGUI_VULKAN_DEBUG_REPORT -//#endif +#ifdef _DEBUG +#define IMGUI_VULKAN_DEBUG_REPORT +#endif static VkAllocationCallbacks* g_Allocator = NULL; static VkInstance g_Instance = VK_NULL_HANDLE; @@ -24,7 +24,7 @@ static VkSwapchainKHR g_Swapchain = VK_NULL_HANDLE; static VkRenderPass g_RenderPass = VK_NULL_HANDLE; static uint32_t g_QueueFamily = 0; static VkQueue g_Queue = VK_NULL_HANDLE; -static VkDebugReportCallbackEXT g_Debug_Report = VK_NULL_HANDLE; +static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE; static VkSurfaceFormatKHR g_SurfaceFormat; static VkImageSubresourceRange g_ImageRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; @@ -228,18 +228,17 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e #ifdef IMGUI_VULKAN_DEBUG_REPORT free(extensions_ext); - // create the debug report callback + // Get the function pointer (required for any extensions) + auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); + IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL); + + // Setup the debug report callback VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; debug_report_ci.pfnCallback = debug_report; debug_report_ci.pUserData = NULL; - - // get the proc address of the function pointer, required for used extensions - PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = - (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); - - err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_Debug_Report); + err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); check_vk_result(err); #endif // IMGUI_VULKAN_DEBUG_REPORT } @@ -492,9 +491,9 @@ static void cleanup_vulkan() vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator); #ifdef IMGUI_VULKAN_DEBUG_REPORT - // get the proc address of the function pointer, required for used extensions + // Remove the debug report callback auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); - vkDestroyDebugReportCallbackEXT(g_Instance, g_Debug_Report, g_Allocator); + vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); #endif // IMGUI_VULKAN_DEBUG_REPORT vkDestroyDevice(g_Device, g_Allocator); diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index ca0cdcca0..1c5100e16 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -14,9 +14,9 @@ #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16 #define IMGUI_UNLIMITED_FRAME_RATE -//#ifdef _DEBUG -//#define IMGUI_VULKAN_DEBUG_REPORT -//#endif +#ifdef _DEBUG +#define IMGUI_VULKAN_DEBUG_REPORT +#endif static VkAllocationCallbacks* g_Allocator = NULL; static VkInstance g_Instance = VK_NULL_HANDLE; @@ -27,7 +27,7 @@ static VkSwapchainKHR g_Swapchain = VK_NULL_HANDLE; static VkRenderPass g_RenderPass = VK_NULL_HANDLE; static uint32_t g_QueueFamily = 0; static VkQueue g_Queue = VK_NULL_HANDLE; -static VkDebugReportCallbackEXT g_Debug_Report = VK_NULL_HANDLE; +static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE; static VkSurfaceFormatKHR g_SurfaceFormat; static VkImageSubresourceRange g_ImageRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; @@ -231,18 +231,17 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e #ifdef IMGUI_VULKAN_DEBUG_REPORT free(extensions_ext); - // create the debug report callback + // Get the function pointer (required for any extensions) + auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); + IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL); + + // Setup the debug report callback VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; debug_report_ci.pfnCallback = debug_report; debug_report_ci.pUserData = NULL; - - // get the proc address of the function pointer, required for used extensions - PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = - (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); - - err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_Debug_Report); + err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); check_vk_result(err); #endif // IMGUI_VULKAN_DEBUG_REPORT } @@ -492,9 +491,9 @@ static void cleanup_vulkan() vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator); #ifdef IMGUI_VULKAN_DEBUG_REPORT - // get the proc address of the function pointer, required for used extensions + // Remove the debug report callback auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); - vkDestroyDebugReportCallbackEXT(g_Instance, g_Debug_Report, g_Allocator); + vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); #endif // IMGUI_VULKAN_DEBUG_REPORT vkDestroyDevice(g_Device, g_Allocator); From 3171d61dfc19606e29db0ec9d641cd57d459043b Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 1 Mar 2018 21:11:22 +0100 Subject: [PATCH 4/6] Examples: Vulkan: Various tweaks to name variable more consistently like Vulkan + a few comments + a few imgui style code compaction. --- examples/imgui_impl_vulkan.cpp | 35 +++---- examples/imgui_impl_vulkan.h | 18 ++-- examples/sdl_vulkan_example/main.cpp | 133 ++++++++++++--------------- examples/vulkan_example/main.cpp | 133 ++++++++++++--------------- 4 files changed, 147 insertions(+), 172 deletions(-) diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index 312bb486f..70adbf5ca 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -11,7 +11,8 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) -// 2018-XX-XX: Vulkan: Offset projection matrix and clipping rectangle by io.DisplayPos (which will be non-zero for multi-viewport applications). +// 2018-03-01: Vulkan: Renamed ImGui_ImplVulkan_Init_Info to ImGui_ImplVulkan_InitInfo and fields to match more closely Vulkan terminology. +// 2018-02-18: Vulkan: Offset projection matrix and clipping rectangle by io.DisplayPos (which will be non-zero for multi-viewport applications). // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback, ImGui_ImplVulkan_Render() calls ImGui_ImplVulkan_RenderDrawData() itself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2017-05-15: Vulkan: Fix scissor offset being negative. Fix new Vulkan validation warnings. Set required depth member for buffer image copy. @@ -23,13 +24,13 @@ #include "imgui_impl_vulkan.h" // Vulkan data -static VkAllocationCallbacks* g_Allocator = NULL; -static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE; -static VkDevice g_Device = VK_NULL_HANDLE; -static VkRenderPass g_RenderPass = VK_NULL_HANDLE; -static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; -static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; -static void (*g_CheckVkResult)(VkResult err) = NULL; +static const VkAllocationCallbacks* g_Allocator = NULL; +static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE; +static VkDevice g_Device = VK_NULL_HANDLE; +static VkRenderPass g_RenderPass = VK_NULL_HANDLE; +static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; +static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; +static void (*g_CheckVkResult)(VkResult err) = NULL; static VkCommandBuffer g_CommandBuffer = VK_NULL_HANDLE; static VkDeviceSize g_BufferMemoryAlignment = 256; @@ -133,7 +134,7 @@ static uint32_t __glsl_shader_frag_spv[] = static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits) { VkPhysicalDeviceMemoryProperties prop; - vkGetPhysicalDeviceMemoryProperties(g_Gpu, &prop); + vkGetPhysicalDeviceMemoryProperties(g_PhysicalDevice, &prop); for (uint32_t i = 0; i < prop.memoryTypeCount; i++) if ((prop.memoryTypes[i].propertyFlags & properties) == properties && type_bits & (1<allocator; - g_Gpu = init_data->gpu; - g_Device = init_data->device; - g_RenderPass = init_data->render_pass; - g_PipelineCache = init_data->pipeline_cache; - g_DescriptorPool = init_data->descriptor_pool; - g_CheckVkResult = init_data->check_vk_result; + g_Allocator = init_data->Allocator; + g_PhysicalDevice = init_data->PhysicalDevice; + g_Device = init_data->Device; + g_RenderPass = init_data->RenderPass; + g_PipelineCache = init_data->PipelineCache; + g_DescriptorPool = init_data->DescriptorPool; + g_CheckVkResult = init_data->CheckVkResultFn; ImGui_ImplVulkan_CreateDeviceObjects(); return true; diff --git a/examples/imgui_impl_vulkan.h b/examples/imgui_impl_vulkan.h index c27c11eeb..04ea473e9 100644 --- a/examples/imgui_impl_vulkan.h +++ b/examples/imgui_impl_vulkan.h @@ -13,18 +13,18 @@ #define IMGUI_VK_QUEUED_FRAMES 2 -struct ImGui_ImplVulkan_InitData +struct ImGui_ImplVulkan_InitInfo { - VkAllocationCallbacks* allocator; - VkPhysicalDevice gpu; - VkDevice device; - VkRenderPass render_pass; - VkPipelineCache pipeline_cache; - VkDescriptorPool descriptor_pool; - void (*check_vk_result)(VkResult err); + const VkAllocationCallbacks* Allocator; + VkPhysicalDevice PhysicalDevice; + VkDevice Device; + VkRenderPass RenderPass; + VkPipelineCache PipelineCache; + VkDescriptorPool DescriptorPool; + void (*CheckVkResultFn)(VkResult err); }; -IMGUI_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitData *init_data); +IMGUI_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo *init_data); IMGUI_API void ImGui_ImplVulkan_Shutdown(); IMGUI_API void ImGui_ImplVulkan_NewFrame(); IMGUI_API void ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer); diff --git a/examples/sdl_vulkan_example/main.cpp b/examples/sdl_vulkan_example/main.cpp index 973fd5d90..24b022160 100644 --- a/examples/sdl_vulkan_example/main.cpp +++ b/examples/sdl_vulkan_example/main.cpp @@ -9,6 +9,7 @@ #include #include +// FIXME-VULKAN: Resizing with IMGUI_UNLIMITED_FRAME_RATE triggers errors from the validation layer. #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16 #define IMGUI_UNLIMITED_FRAME_RATE #ifdef _DEBUG @@ -18,16 +19,15 @@ static VkAllocationCallbacks* g_Allocator = NULL; static VkInstance g_Instance = VK_NULL_HANDLE; static VkSurfaceKHR g_Surface = VK_NULL_HANDLE; -static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE; +static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE; static VkDevice g_Device = VK_NULL_HANDLE; static VkSwapchainKHR g_Swapchain = VK_NULL_HANDLE; static VkRenderPass g_RenderPass = VK_NULL_HANDLE; -static uint32_t g_QueueFamily = 0; +static uint32_t g_QueueFamily = (uint32_t)-1; static VkQueue g_Queue = VK_NULL_HANDLE; static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE; static VkSurfaceFormatKHR g_SurfaceFormat; -static VkImageSubresourceRange g_ImageRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; static VkPresentModeKHR g_PresentMode; static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; @@ -64,17 +64,18 @@ static void resize_vulkan(SDL_Window*, int w, int h) err = vkDeviceWaitIdle(g_Device); check_vk_result(err); - // Destroy old Framebuffer: + // Destroy old Framebuffer for (uint32_t i = 0; i < g_BackBufferCount; i++) + { if (g_BackBufferView[i]) vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator); - for (uint32_t i = 0; i < g_BackBufferCount; i++) if (g_Framebuffer[i]) vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator); + } if (g_RenderPass) vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator); - // Create Swapchain: + // Create Swapchain { VkSwapchainCreateInfoKHR info = {}; info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; @@ -82,15 +83,15 @@ static void resize_vulkan(SDL_Window*, int w, int h) info.imageFormat = g_SurfaceFormat.format; info.imageColorSpace = g_SurfaceFormat.colorSpace; info.imageArrayLayers = 1; - info.imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; // Assume that graphics family == present family info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; info.presentMode = g_PresentMode; info.clipped = VK_TRUE; info.oldSwapchain = old_swapchain; VkSurfaceCapabilitiesKHR cap; - err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_Gpu, g_Surface, &cap); + err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_PhysicalDevice, g_Surface, &cap); check_vk_result(err); if (cap.maxImageCount > 0) info.minImageCount = (cap.minImageCount + 2 < cap.maxImageCount) ? (cap.minImageCount + 2) : cap.maxImageCount; @@ -99,17 +100,13 @@ static void resize_vulkan(SDL_Window*, int w, int h) if (cap.currentExtent.width == 0xffffffff) { - fb_width = w; - fb_height = h; - info.imageExtent.width = fb_width; - info.imageExtent.height = fb_height; + info.imageExtent.width = fb_width = w; + info.imageExtent.height = fb_height = h; } else { - fb_width = cap.currentExtent.width; - fb_height = cap.currentExtent.height; - info.imageExtent.width = fb_width; - info.imageExtent.height = fb_height; + info.imageExtent.width = fb_width = cap.currentExtent.width; + info.imageExtent.height = fb_height = cap.currentExtent.height; } err = vkCreateSwapchainKHR(g_Device, &info, g_Allocator, &g_Swapchain); check_vk_result(err); @@ -121,7 +118,7 @@ static void resize_vulkan(SDL_Window*, int w, int h) if (old_swapchain) vkDestroySwapchainKHR(g_Device, old_swapchain, g_Allocator); - // Create the Render Pass: + // Create the Render Pass { VkAttachmentDescription attachment = {}; attachment.format = g_SurfaceFormat.format; @@ -159,7 +156,8 @@ static void resize_vulkan(SDL_Window*, int w, int h) info.components.g = VK_COMPONENT_SWIZZLE_G; info.components.b = VK_COMPONENT_SWIZZLE_B; info.components.a = VK_COMPONENT_SWIZZLE_A; - info.subresourceRange = g_ImageRange; + VkImageSubresourceRange image_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; + info.subresourceRange = image_range; for (uint32_t i = 0; i < g_BackBufferCount; i++) { info.image = g_BackBuffer[i]; @@ -168,7 +166,7 @@ static void resize_vulkan(SDL_Window*, int w, int h) } } - // Create Framebuffer: + // Create Framebuffer { VkImageView attachment[1]; VkFramebufferCreateInfo info = {}; @@ -253,7 +251,7 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e } } - // Get GPU + // Select GPU { uint32_t gpu_count; err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); @@ -266,31 +264,30 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e // If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc. // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family. - g_Gpu = gpus[0]; + g_PhysicalDevice = gpus[0]; free(gpus); } - // Get queue + // Select graphics queue family { uint32_t count; - vkGetPhysicalDeviceQueueFamilyProperties(g_Gpu, &count, NULL); + vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, NULL); VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count); - vkGetPhysicalDeviceQueueFamilyProperties(g_Gpu, &count, queues); + vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues); for (uint32_t i = 0; i < count; i++) - { if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { g_QueueFamily = i; break; } - } free(queues); + IM_ASSERT(g_QueueFamily != -1); } // Check for WSI support { VkBool32 res; - vkGetPhysicalDeviceSurfaceSupportKHR(g_Gpu, g_QueueFamily, g_Surface, &res); + vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, g_Surface, &res); if (res != VK_TRUE) { fprintf(stderr, "Error no WSI support on physical device 0\n"); @@ -301,15 +298,15 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e // Get Surface Format { // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation - // Assuming that the default behavior is without setting this bit, there is no need for separate Spawchain image and image view format - // additionally several new color spaces were introduced with Vulkan Spec v1.0.40 - // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used + // Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format + // Additionally several new color spaces were introduced with Vulkan Spec v1.0.40, + // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used. uint32_t count; - vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, NULL); - VkSurfaceFormatKHR *formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count); - vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, formats); + vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, NULL); + VkSurfaceFormatKHR* formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count); + vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, formats); - // first check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available + // First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available if (count == 1) { if (formats[0].format == VK_FORMAT_UNDEFINED) @@ -318,32 +315,27 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e g_SurfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; } else - { // no point in searching another format + { + // No point in searching another format g_SurfaceFormat = formats[0]; } } else { - // request several formats, the first found will be used + // Request several formats, the first found will be used VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - bool requestedFound = false; - for (size_t i = 0; i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++) - { - if (requestedFound) - break; + bool found = false; + for (size_t i = 0; found == false && i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++) for (uint32_t j = 0; j < count; j++) - { if (formats[j].format == requestSurfaceImageFormat[i] && formats[j].colorSpace == requestSurfaceColorSpace) { g_SurfaceFormat = formats[j]; - requestedFound = true; + found = true; } - } - } - // if none of the requested image formats could be found, use the first available - if (!requestedFound) + // If none of the requested image formats could be found, use the first available + if (!found) g_SurfaceFormat = formats[0]; } free(formats); @@ -352,41 +344,34 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e // Get Present Mode { - // Requst a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory + // Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory #ifdef IMGUI_UNLIMITED_FRAME_RATE g_PresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; #else g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; #endif uint32_t count = 0; - vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, nullptr); + vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, nullptr); VkPresentModeKHR* presentModes = (VkPresentModeKHR*)malloc(sizeof(VkQueueFamilyProperties) * count); - vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, presentModes); + vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, presentModes); bool presentModeAvailable = false; - for (size_t i = 0; i < count; i++) - { + for (size_t i = 0; i < count && !presentModeAvailable; i++) if (presentModes[i] == g_PresentMode) - { presentModeAvailable = true; - break; - } - } if (!presentModeAvailable) - g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // always available + g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // Always available } - // Create Logical Device + // Create Logical Device (with 1 queue) { int device_extension_count = 1; const char* device_extensions[] = { "VK_KHR_swapchain" }; - const uint32_t queue_index = 0; - const uint32_t queue_count = 1; const float queue_priority[] = { 1.0f }; VkDeviceQueueCreateInfo queue_info[1] = {}; queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_info[0].queueFamilyIndex = g_QueueFamily; - queue_info[0].queueCount = queue_count; + queue_info[0].queueCount = 1; queue_info[0].pQueuePriorities = queue_priority; VkDeviceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; @@ -394,11 +379,12 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e create_info.pQueueCreateInfos = queue_info; create_info.enabledExtensionCount = device_extension_count; create_info.ppEnabledExtensionNames = device_extensions; - err = vkCreateDevice(g_Gpu, &create_info, g_Allocator, &g_Device); + err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device); check_vk_result(err); - vkGetDeviceQueue(g_Device, g_QueueFamily, queue_index, &g_Queue); + vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue); } + // Create Framebuffers { int w, h; @@ -406,6 +392,7 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e resize_vulkan(window, w, h); } + // Create Command Buffers for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) { @@ -611,18 +598,18 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); - ImGui_ImplVulkan_InitData init_data = {}; - init_data.allocator = g_Allocator; - init_data.gpu = g_Gpu; - init_data.device = g_Device; - init_data.render_pass = g_RenderPass; - init_data.pipeline_cache = g_PipelineCache; - init_data.descriptor_pool = g_DescriptorPool; - init_data.check_vk_result = check_vk_result; + ImGui_ImplVulkan_InitInfo init_info = {}; + init_info.Allocator = g_Allocator; + init_info.PhysicalDevice = g_PhysicalDevice; + init_info.Device = g_Device; + init_info.RenderPass = g_RenderPass; + init_info.PipelineCache = g_PipelineCache; + init_info.DescriptorPool = g_DescriptorPool; + init_info.CheckVkResultFn = check_vk_result; ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - ImGui_ImplVulkan_Init(&init_data); + ImGui_ImplVulkan_Init(&init_info); ImGui_ImplSDL2_Init(window); // Setup style diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 1c5100e16..e0c0fab35 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -12,6 +12,7 @@ #include #include +// FIXME-VULKAN: Resizing with IMGUI_UNLIMITED_FRAME_RATE triggers errors from the validation layer. #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16 #define IMGUI_UNLIMITED_FRAME_RATE #ifdef _DEBUG @@ -21,16 +22,15 @@ static VkAllocationCallbacks* g_Allocator = NULL; static VkInstance g_Instance = VK_NULL_HANDLE; static VkSurfaceKHR g_Surface = VK_NULL_HANDLE; -static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE; +static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE; static VkDevice g_Device = VK_NULL_HANDLE; static VkSwapchainKHR g_Swapchain = VK_NULL_HANDLE; static VkRenderPass g_RenderPass = VK_NULL_HANDLE; -static uint32_t g_QueueFamily = 0; +static uint32_t g_QueueFamily = (uint32_t)-1; static VkQueue g_Queue = VK_NULL_HANDLE; static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE; static VkSurfaceFormatKHR g_SurfaceFormat; -static VkImageSubresourceRange g_ImageRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; static VkPresentModeKHR g_PresentMode; static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; @@ -67,17 +67,18 @@ static void resize_vulkan(GLFWwindow*, int w, int h) err = vkDeviceWaitIdle(g_Device); check_vk_result(err); - // Destroy old Framebuffer: + // Destroy old Framebuffer for (uint32_t i = 0; i < g_BackBufferCount; i++) + { if (g_BackBufferView[i]) vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator); - for (uint32_t i = 0; i < g_BackBufferCount; i++) if (g_Framebuffer[i]) vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator); + } if (g_RenderPass) vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator); - // Create Swapchain: + // Create Swapchain { VkSwapchainCreateInfoKHR info = {}; info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; @@ -85,15 +86,15 @@ static void resize_vulkan(GLFWwindow*, int w, int h) info.imageFormat = g_SurfaceFormat.format; info.imageColorSpace = g_SurfaceFormat.colorSpace; info.imageArrayLayers = 1; - info.imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; // Assume that graphics family == present family info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; info.presentMode = g_PresentMode; info.clipped = VK_TRUE; info.oldSwapchain = old_swapchain; VkSurfaceCapabilitiesKHR cap; - err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_Gpu, g_Surface, &cap); + err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_PhysicalDevice, g_Surface, &cap); check_vk_result(err); if (cap.maxImageCount > 0) info.minImageCount = (cap.minImageCount + 2 < cap.maxImageCount) ? (cap.minImageCount + 2) : cap.maxImageCount; @@ -102,17 +103,13 @@ static void resize_vulkan(GLFWwindow*, int w, int h) if (cap.currentExtent.width == 0xffffffff) { - fb_width = w; - fb_height = h; - info.imageExtent.width = fb_width; - info.imageExtent.height = fb_height; + info.imageExtent.width = fb_width = w; + info.imageExtent.height = fb_height = h; } else { - fb_width = cap.currentExtent.width; - fb_height = cap.currentExtent.height; - info.imageExtent.width = fb_width; - info.imageExtent.height = fb_height; + info.imageExtent.width = fb_width = cap.currentExtent.width; + info.imageExtent.height = fb_height = cap.currentExtent.height; } err = vkCreateSwapchainKHR(g_Device, &info, g_Allocator, &g_Swapchain); check_vk_result(err); @@ -124,7 +121,7 @@ static void resize_vulkan(GLFWwindow*, int w, int h) if (old_swapchain) vkDestroySwapchainKHR(g_Device, old_swapchain, g_Allocator); - // Create the Render Pass: + // Create the Render Pass { VkAttachmentDescription attachment = {}; attachment.format = g_SurfaceFormat.format; @@ -162,7 +159,8 @@ static void resize_vulkan(GLFWwindow*, int w, int h) info.components.g = VK_COMPONENT_SWIZZLE_G; info.components.b = VK_COMPONENT_SWIZZLE_B; info.components.a = VK_COMPONENT_SWIZZLE_A; - info.subresourceRange = g_ImageRange; + VkImageSubresourceRange image_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; + info.subresourceRange = image_range; for (uint32_t i = 0; i < g_BackBufferCount; i++) { info.image = g_BackBuffer[i]; @@ -171,7 +169,7 @@ static void resize_vulkan(GLFWwindow*, int w, int h) } } - // Create Framebuffer: + // Create Framebuffer { VkImageView attachment[1]; VkFramebufferCreateInfo info = {}; @@ -252,7 +250,7 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e check_vk_result(err); } - // Get GPU + // Select GPU { uint32_t gpu_count; err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); @@ -265,31 +263,30 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e // If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc. // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family. - g_Gpu = gpus[0]; + g_PhysicalDevice = gpus[0]; free(gpus); } - // Get queue + // Select graphics queue family { uint32_t count; - vkGetPhysicalDeviceQueueFamilyProperties(g_Gpu, &count, NULL); + vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, NULL); VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count); - vkGetPhysicalDeviceQueueFamilyProperties(g_Gpu, &count, queues); + vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues); for (uint32_t i = 0; i < count; i++) - { if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { g_QueueFamily = i; break; } - } free(queues); + IM_ASSERT(g_QueueFamily != -1); } // Check for WSI support { VkBool32 res; - vkGetPhysicalDeviceSurfaceSupportKHR(g_Gpu, g_QueueFamily, g_Surface, &res); + vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, g_Surface, &res); if (res != VK_TRUE) { fprintf(stderr, "Error no WSI support on physical device 0\n"); @@ -300,15 +297,15 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e // Get Surface Format { // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation - // Assuming that the default behavior is without setting this bit, there is no need for separate Spawchain image and image view format - // additionally several new color spaces were introduced with Vulkan Spec v1.0.40 - // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used + // Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format + // Additionally several new color spaces were introduced with Vulkan Spec v1.0.40, + // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used. uint32_t count; - vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, NULL); - VkSurfaceFormatKHR *formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count); - vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, formats); + vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, NULL); + VkSurfaceFormatKHR* formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count); + vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, formats); - // first check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available + // First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available if (count == 1) { if (formats[0].format == VK_FORMAT_UNDEFINED) @@ -317,32 +314,27 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e g_SurfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; } else - { // no point in searching another format + { + // No point in searching another format g_SurfaceFormat = formats[0]; } } else { - // request several formats, the first found will be used + // Request several formats, the first found will be used VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - bool requestedFound = false; - for (size_t i = 0; i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++) - { - if (requestedFound) - break; + bool found = false; + for (size_t i = 0; found == false && i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++) for (uint32_t j = 0; j < count; j++) - { if (formats[j].format == requestSurfaceImageFormat[i] && formats[j].colorSpace == requestSurfaceColorSpace) { g_SurfaceFormat = formats[j]; - requestedFound = true; + found = true; } - } - } - // if none of the requested image formats could be found, use the first available - if (!requestedFound) + // If none of the requested image formats could be found, use the first available + if (!found) g_SurfaceFormat = formats[0]; } free(formats); @@ -351,41 +343,34 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e // Get Present Mode { - // Requst a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory + // Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory #ifdef IMGUI_UNLIMITED_FRAME_RATE g_PresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; #else g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; #endif uint32_t count = 0; - vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, nullptr); + vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, nullptr); VkPresentModeKHR* presentModes = (VkPresentModeKHR*)malloc(sizeof(VkQueueFamilyProperties) * count); - vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, presentModes); + vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, presentModes); bool presentModeAvailable = false; - for (size_t i = 0; i < count; i++) - { + for (size_t i = 0; i < count && !presentModeAvailable; i++) if (presentModes[i] == g_PresentMode) - { presentModeAvailable = true; - break; - } - } if (!presentModeAvailable) - g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // always available + g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // Always available } - // Create Logical Device + // Create Logical Device (with 1 queue) { int device_extension_count = 1; const char* device_extensions[] = { "VK_KHR_swapchain" }; - const uint32_t queue_index = 0; - const uint32_t queue_count = 1; const float queue_priority[] = { 1.0f }; VkDeviceQueueCreateInfo queue_info[1] = {}; queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_info[0].queueFamilyIndex = g_QueueFamily; - queue_info[0].queueCount = queue_count; + queue_info[0].queueCount = 1; queue_info[0].pQueuePriorities = queue_priority; VkDeviceCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; @@ -393,11 +378,12 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e create_info.pQueueCreateInfos = queue_info; create_info.enabledExtensionCount = device_extension_count; create_info.ppEnabledExtensionNames = device_extensions; - err = vkCreateDevice(g_Gpu, &create_info, g_Allocator, &g_Device); + err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device); check_vk_result(err); - vkGetDeviceQueue(g_Device, g_QueueFamily, queue_index, &g_Queue); + vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue); } + // Create Framebuffers { int w, h; @@ -406,6 +392,7 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e glfwSetFramebufferSizeCallback(window, resize_vulkan); } + // Create Command Buffers for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) { @@ -614,18 +601,18 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); - ImGui_ImplVulkan_InitData init_data = {}; - init_data.allocator = g_Allocator; - init_data.gpu = g_Gpu; - init_data.device = g_Device; - init_data.render_pass = g_RenderPass; - init_data.pipeline_cache = g_PipelineCache; - init_data.descriptor_pool = g_DescriptorPool; - init_data.check_vk_result = check_vk_result; + ImGui_ImplVulkan_InitInfo init_info = {}; + init_info.Allocator = g_Allocator; + init_info.PhysicalDevice = g_PhysicalDevice; + init_info.Device = g_Device; + init_info.RenderPass = g_RenderPass; + init_info.PipelineCache = g_PipelineCache; + init_info.DescriptorPool = g_DescriptorPool; + init_info.CheckVkResultFn = check_vk_result; ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - ImGui_ImplVulkan_Init(&init_data); + ImGui_ImplVulkan_Init(&init_info); ImGui_ImplGlfw_Init(window, true); // Setup style From 296db2ed3341bed19b233a83065b3c2c00087e2b Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 1 Mar 2018 22:16:51 +0100 Subject: [PATCH 5/6] Examples: Vulkan: Moved code into shared helpers: ImGui_ImplVulkan_SelectSurfaceFormat, ImGui_ImplVulkan_SelectPresentMode. --- examples/imgui_impl_vulkan.cpp | 70 ++++++++++++++++++++++++++++ examples/imgui_impl_vulkan.h | 4 ++ examples/sdl_vulkan_example/main.cpp | 61 +++--------------------- examples/vulkan_example/main.cpp | 62 +++--------------------- 4 files changed, 87 insertions(+), 110 deletions(-) diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index 70adbf5ca..2e4ca7af3 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -720,3 +720,73 @@ void ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer) g_CommandBuffer = VK_NULL_HANDLE; g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; } + +//------------------------------------------------------------------------- +// Miscellaneous Vulkan Helpers +// (Those are currently not strictly needed by the binding, but will be once if we support multi-viewports) +//------------------------------------------------------------------------- + +#include // malloc + +VkSurfaceFormatKHR ImGui_ImplVulkan_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space) +{ + IM_ASSERT(request_formats != NULL); + IM_ASSERT(request_formats_count > 0); + + // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation + // Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format + // Additionally several new color spaces were introduced with Vulkan Spec v1.0.40, + // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used. + uint32_t avail_count; + vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &avail_count, NULL); + ImVector avail_format; + avail_format.resize((int)avail_count); + vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &avail_count, avail_format.Data); + + // First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available + if (avail_count == 1) + { + if (avail_format[0].format == VK_FORMAT_UNDEFINED) + { + VkSurfaceFormatKHR ret; + ret.format = request_formats[0]; + ret.colorSpace = request_color_space; + return ret; + } + else + { + // No point in searching another format + return avail_format[0]; + } + } + else + { + // Request several formats, the first found will be used + for (int request_i = 0; request_i < request_formats_count; request_i++) + for (uint32_t avail_i = 0; avail_i < avail_count; avail_i++) + if (avail_format[avail_i].format == request_formats[request_i] && avail_format[avail_i].colorSpace == request_color_space) + return avail_format[avail_i]; + + // If none of the requested image formats could be found, use the first available + return avail_format[0]; + } +} + +VkPresentModeKHR ImGui_ImplVulkan_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count) +{ + IM_ASSERT(request_modes != NULL); + IM_ASSERT(request_modes_count > 0); + + // Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory + uint32_t avail_count = 0; + vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &avail_count, NULL); + ImVector avail_modes; + avail_modes.resize((int)avail_count); + vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &avail_count, avail_modes.Data); + for (int request_i = 0; request_i < request_modes_count; request_i++) + for (uint32_t avail_i = 0; avail_i < avail_count; avail_i++) + if (request_modes[request_i] == avail_modes[avail_i]) + return request_modes[request_i]; + + return VK_PRESENT_MODE_FIFO_KHR; // Always available +} diff --git a/examples/imgui_impl_vulkan.h b/examples/imgui_impl_vulkan.h index 04ea473e9..188f0e111 100644 --- a/examples/imgui_impl_vulkan.h +++ b/examples/imgui_impl_vulkan.h @@ -34,3 +34,7 @@ IMGUI_API void ImGui_ImplVulkan_InvalidateFontUploadObjects(); IMGUI_API void ImGui_ImplVulkan_InvalidateDeviceObjects(); IMGUI_API bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer); IMGUI_API bool ImGui_ImplVulkan_CreateDeviceObjects(); + +// Miscellaneous Vulkan Helpers +IMGUI_API VkSurfaceFormatKHR ImGui_ImplVulkan_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space); +IMGUI_API VkPresentModeKHR ImGui_ImplVulkan_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count); diff --git a/examples/sdl_vulkan_example/main.cpp b/examples/sdl_vulkan_example/main.cpp index 24b022160..1be9584d5 100644 --- a/examples/sdl_vulkan_example/main.cpp +++ b/examples/sdl_vulkan_example/main.cpp @@ -297,69 +297,20 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e // Get Surface Format { - // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation - // Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format - // Additionally several new color spaces were introduced with Vulkan Spec v1.0.40, - // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used. - uint32_t count; - vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, NULL); - VkSurfaceFormatKHR* formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count); - vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, formats); - - // First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available - if (count == 1) - { - if (formats[0].format == VK_FORMAT_UNDEFINED) - { - g_SurfaceFormat.format = VK_FORMAT_B8G8R8A8_UNORM; - g_SurfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - } - else - { - // No point in searching another format - g_SurfaceFormat = formats[0]; - } - } - else - { - // Request several formats, the first found will be used - VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; - VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - bool found = false; - for (size_t i = 0; found == false && i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++) - for (uint32_t j = 0; j < count; j++) - if (formats[j].format == requestSurfaceImageFormat[i] && formats[j].colorSpace == requestSurfaceColorSpace) - { - g_SurfaceFormat = formats[j]; - found = true; - } - - // If none of the requested image formats could be found, use the first available - if (!found) - g_SurfaceFormat = formats[0]; - } - free(formats); + const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; + const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + g_SurfaceFormat = ImGui_ImplVulkan_SelectSurfaceFormat(g_PhysicalDevice, g_Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); } // Get Present Mode { - // Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory #ifdef IMGUI_UNLIMITED_FRAME_RATE - g_PresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + VkPresentModeKHR present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; #else - g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; + VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; #endif - uint32_t count = 0; - vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, nullptr); - VkPresentModeKHR* presentModes = (VkPresentModeKHR*)malloc(sizeof(VkQueueFamilyProperties) * count); - vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, presentModes); - bool presentModeAvailable = false; - for (size_t i = 0; i < count && !presentModeAvailable; i++) - if (presentModes[i] == g_PresentMode) - presentModeAvailable = true; - if (!presentModeAvailable) - g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // Always available + g_PresentMode = ImGui_ImplVulkan_SelectPresentMode(g_PhysicalDevice, g_Surface, &present_mode, 1); } diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index e0c0fab35..5b82f5bcc 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -294,71 +294,23 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e } } + // Get Surface Format { - // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation - // Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format - // Additionally several new color spaces were introduced with Vulkan Spec v1.0.40, - // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used. - uint32_t count; - vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, NULL); - VkSurfaceFormatKHR* formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count); - vkGetPhysicalDeviceSurfaceFormatsKHR(g_PhysicalDevice, g_Surface, &count, formats); - - // First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available - if (count == 1) - { - if (formats[0].format == VK_FORMAT_UNDEFINED) - { - g_SurfaceFormat.format = VK_FORMAT_B8G8R8A8_UNORM; - g_SurfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - } - else - { - // No point in searching another format - g_SurfaceFormat = formats[0]; - } - } - else - { - // Request several formats, the first found will be used - VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; - VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - bool found = false; - for (size_t i = 0; found == false && i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++) - for (uint32_t j = 0; j < count; j++) - if (formats[j].format == requestSurfaceImageFormat[i] && formats[j].colorSpace == requestSurfaceColorSpace) - { - g_SurfaceFormat = formats[j]; - found = true; - } - - // If none of the requested image formats could be found, use the first available - if (!found) - g_SurfaceFormat = formats[0]; - } - free(formats); + const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; + const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + g_SurfaceFormat = ImGui_ImplVulkan_SelectSurfaceFormat(g_PhysicalDevice, g_Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); } // Get Present Mode { - // Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory #ifdef IMGUI_UNLIMITED_FRAME_RATE - g_PresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + VkPresentModeKHR present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; #else - g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; + VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; #endif - uint32_t count = 0; - vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, nullptr); - VkPresentModeKHR* presentModes = (VkPresentModeKHR*)malloc(sizeof(VkQueueFamilyProperties) * count); - vkGetPhysicalDeviceSurfacePresentModesKHR(g_PhysicalDevice, g_Surface, &count, presentModes); - bool presentModeAvailable = false; - for (size_t i = 0; i < count && !presentModeAvailable; i++) - if (presentModes[i] == g_PresentMode) - presentModeAvailable = true; - if (!presentModeAvailable) - g_PresentMode = VK_PRESENT_MODE_FIFO_KHR; // Always available + g_PresentMode = ImGui_ImplVulkan_SelectPresentMode(g_PhysicalDevice, g_Surface, &present_mode, 1); } From 68e9ef9885c9c3f103364161b2e6d2c154345cd2 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 1 Mar 2018 22:39:06 +0100 Subject: [PATCH 6/6] Examples: Vulkan: SDL: Fixed missing resize handler (not properly merged from #1367) + tweaks. --- examples/sdl_vulkan_example/main.cpp | 6 ++++-- examples/vulkan_example/main.cpp | 11 ++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/examples/sdl_vulkan_example/main.cpp b/examples/sdl_vulkan_example/main.cpp index 1be9584d5..7756880b7 100644 --- a/examples/sdl_vulkan_example/main.cpp +++ b/examples/sdl_vulkan_example/main.cpp @@ -57,7 +57,7 @@ static void check_vk_result(VkResult err) abort(); } -static void resize_vulkan(SDL_Window*, int w, int h) +static void CreateOrResizeSwapChainAndFrameBuffer(int w, int h) { VkResult err; VkSwapchainKHR old_swapchain = g_Swapchain; @@ -340,7 +340,7 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e { int w, h; SDL_GetWindowSize(window, &w, &h); - resize_vulkan(window, w, h); + CreateOrResizeSwapChainAndFrameBuffer(w, h); } @@ -639,6 +639,8 @@ int main(int, char**) ImGui_ImplSDL2_ProcessEvent(&event); if (event.type == SDL_QUIT) done = true; + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window)) + CreateOrResizeSwapChainAndFrameBuffer((int)event.window.data1, (int)event.window.data2); } ImGui_ImplVulkan_NewFrame(); ImGui_ImplSDL2_NewFrame(window); diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 5b82f5bcc..78b6615ed 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -60,7 +60,7 @@ static void check_vk_result(VkResult err) abort(); } -static void resize_vulkan(GLFWwindow*, int w, int h) +static void CreateOrResizeSwapChainAndFrameBuffer(int w, int h) { VkResult err; VkSwapchainKHR old_swapchain = g_Swapchain; @@ -189,6 +189,11 @@ static void resize_vulkan(GLFWwindow*, int w, int h) } } +static void GlfwResizeCallback(GLFWwindow*, int w, int h) +{ + CreateOrResizeSwapChainAndFrameBuffer(w, h); +} + #ifdef IMGUI_VULKAN_DEBUG_REPORT static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) { @@ -340,8 +345,8 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e { int w, h; glfwGetFramebufferSize(window, &w, &h); - resize_vulkan(window, w, h); - glfwSetFramebufferSizeCallback(window, resize_vulkan); + CreateOrResizeSwapChainAndFrameBuffer(w, h); + glfwSetFramebufferSizeCallback(window, GlfwResizeCallback); }