|
@@ -35,6 +35,8 @@
|
|
|
// CHANGELOG
|
|
|
// (minor and older changes stripped away, please see git history for details)
|
|
|
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
|
|
+// 2024-01-03: Vulkan: Added MinAllocationSize field in ImGui_ImplVulkan_InitInfo to workaround zealous "best practice" validation layer. (#7189, #4238)
|
|
|
+// 2024-01-03: Vulkan: Stoped creating command pools with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT as we don't reset them.
|
|
|
// 2023-11-29: Vulkan: Fixed mismatching allocator passed to vkCreateCommandPool() vs vkDestroyCommandPool(). (#7075)
|
|
|
// 2023-11-10: *BREAKING CHANGE*: Removed parameter from ImGui_ImplVulkan_CreateFontsTexture(): backend now creates its own command-buffer to upload fonts.
|
|
|
// *BREAKING CHANGE*: Removed ImGui_ImplVulkan_DestroyFontUploadObjects() which is now unecessary as we create and destroy those objects in the backend.
|
|
@@ -81,79 +83,18 @@
|
|
|
#ifndef IMGUI_DISABLE
|
|
|
#include "imgui_impl_vulkan.h"
|
|
|
#include <stdio.h>
|
|
|
+#ifndef IM_MAX
|
|
|
+#define IM_MAX(A, B) (((A) >= (B)) ? (A) : (B))
|
|
|
+#endif
|
|
|
|
|
|
// Visual Studio warnings
|
|
|
#ifdef _MSC_VER
|
|
|
#pragma warning (disable: 4127) // condition expression is constant
|
|
|
#endif
|
|
|
|
|
|
-// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
|
|
|
-// [Please zero-clear before use!]
|
|
|
-struct ImGui_ImplVulkanH_FrameRenderBuffers
|
|
|
-{
|
|
|
- VkDeviceMemory VertexBufferMemory;
|
|
|
- VkDeviceMemory IndexBufferMemory;
|
|
|
- VkDeviceSize VertexBufferSize;
|
|
|
- VkDeviceSize IndexBufferSize;
|
|
|
- VkBuffer VertexBuffer;
|
|
|
- VkBuffer IndexBuffer;
|
|
|
-};
|
|
|
-
|
|
|
-// Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers
|
|
|
-// [Please zero-clear before use!]
|
|
|
-struct ImGui_ImplVulkanH_WindowRenderBuffers
|
|
|
-{
|
|
|
- uint32_t Index;
|
|
|
- uint32_t Count;
|
|
|
- ImGui_ImplVulkanH_FrameRenderBuffers* FrameRenderBuffers;
|
|
|
-};
|
|
|
-
|
|
|
-// For multi-viewport support:
|
|
|
-// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
|
|
-struct ImGui_ImplVulkan_ViewportData
|
|
|
-{
|
|
|
- bool WindowOwned;
|
|
|
- ImGui_ImplVulkanH_Window Window; // Used by secondary viewports only
|
|
|
- ImGui_ImplVulkanH_WindowRenderBuffers RenderBuffers; // Used by all viewports
|
|
|
-
|
|
|
- ImGui_ImplVulkan_ViewportData() { WindowOwned = false; memset(&RenderBuffers, 0, sizeof(RenderBuffers)); }
|
|
|
- ~ImGui_ImplVulkan_ViewportData() { }
|
|
|
-};
|
|
|
-
|
|
|
-// Vulkan data
|
|
|
-struct ImGui_ImplVulkan_Data
|
|
|
-{
|
|
|
- ImGui_ImplVulkan_InitInfo VulkanInitInfo;
|
|
|
- VkRenderPass RenderPass;
|
|
|
- VkDeviceSize BufferMemoryAlignment;
|
|
|
- VkPipelineCreateFlags PipelineCreateFlags;
|
|
|
- VkDescriptorSetLayout DescriptorSetLayout;
|
|
|
- VkPipelineLayout PipelineLayout;
|
|
|
- VkPipeline Pipeline;
|
|
|
- uint32_t Subpass;
|
|
|
- VkShaderModule ShaderModuleVert;
|
|
|
- VkShaderModule ShaderModuleFrag;
|
|
|
-
|
|
|
- // Font data
|
|
|
- VkSampler FontSampler;
|
|
|
- VkDeviceMemory FontMemory;
|
|
|
- VkImage FontImage;
|
|
|
- VkImageView FontView;
|
|
|
- VkDescriptorSet FontDescriptorSet;
|
|
|
- VkCommandPool FontCommandPool;
|
|
|
- VkCommandBuffer FontCommandBuffer;
|
|
|
-
|
|
|
- // Render buffers for main window
|
|
|
- ImGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers;
|
|
|
-
|
|
|
- ImGui_ImplVulkan_Data()
|
|
|
- {
|
|
|
- memset((void*)this, 0, sizeof(*this));
|
|
|
- BufferMemoryAlignment = 256;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
// Forward Declarations
|
|
|
+struct ImGui_ImplVulkanH_FrameRenderBuffers;
|
|
|
+struct ImGui_ImplVulkanH_WindowRenderBuffers;
|
|
|
bool ImGui_ImplVulkan_CreateDeviceObjects();
|
|
|
void ImGui_ImplVulkan_DestroyDeviceObjects();
|
|
|
void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator);
|
|
@@ -257,6 +198,72 @@ static PFN_vkCmdBeginRenderingKHR ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR;
|
|
|
static PFN_vkCmdEndRenderingKHR ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR;
|
|
|
#endif
|
|
|
|
|
|
+// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
|
|
|
+// [Please zero-clear before use!]
|
|
|
+struct ImGui_ImplVulkanH_FrameRenderBuffers
|
|
|
+{
|
|
|
+ VkDeviceMemory VertexBufferMemory;
|
|
|
+ VkDeviceMemory IndexBufferMemory;
|
|
|
+ VkDeviceSize VertexBufferSize;
|
|
|
+ VkDeviceSize IndexBufferSize;
|
|
|
+ VkBuffer VertexBuffer;
|
|
|
+ VkBuffer IndexBuffer;
|
|
|
+};
|
|
|
+
|
|
|
+// Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers
|
|
|
+// [Please zero-clear before use!]
|
|
|
+struct ImGui_ImplVulkanH_WindowRenderBuffers
|
|
|
+{
|
|
|
+ uint32_t Index;
|
|
|
+ uint32_t Count;
|
|
|
+ ImGui_ImplVulkanH_FrameRenderBuffers* FrameRenderBuffers;
|
|
|
+};
|
|
|
+
|
|
|
+// For multi-viewport support:
|
|
|
+// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
|
|
+struct ImGui_ImplVulkan_ViewportData
|
|
|
+{
|
|
|
+ bool WindowOwned;
|
|
|
+ ImGui_ImplVulkanH_Window Window; // Used by secondary viewports only
|
|
|
+ ImGui_ImplVulkanH_WindowRenderBuffers RenderBuffers; // Used by all viewports
|
|
|
+
|
|
|
+ ImGui_ImplVulkan_ViewportData() { WindowOwned = false; memset(&RenderBuffers, 0, sizeof(RenderBuffers)); }
|
|
|
+ ~ImGui_ImplVulkan_ViewportData() { }
|
|
|
+};
|
|
|
+
|
|
|
+// Vulkan data
|
|
|
+struct ImGui_ImplVulkan_Data
|
|
|
+{
|
|
|
+ ImGui_ImplVulkan_InitInfo VulkanInitInfo;
|
|
|
+ VkRenderPass RenderPass;
|
|
|
+ VkDeviceSize BufferMemoryAlignment;
|
|
|
+ VkPipelineCreateFlags PipelineCreateFlags;
|
|
|
+ VkDescriptorSetLayout DescriptorSetLayout;
|
|
|
+ VkPipelineLayout PipelineLayout;
|
|
|
+ VkPipeline Pipeline;
|
|
|
+ uint32_t Subpass;
|
|
|
+ VkShaderModule ShaderModuleVert;
|
|
|
+ VkShaderModule ShaderModuleFrag;
|
|
|
+
|
|
|
+ // Font data
|
|
|
+ VkSampler FontSampler;
|
|
|
+ VkDeviceMemory FontMemory;
|
|
|
+ VkImage FontImage;
|
|
|
+ VkImageView FontView;
|
|
|
+ VkDescriptorSet FontDescriptorSet;
|
|
|
+ VkCommandPool FontCommandPool;
|
|
|
+ VkCommandBuffer FontCommandBuffer;
|
|
|
+
|
|
|
+ // Render buffers for main window
|
|
|
+ ImGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers;
|
|
|
+
|
|
|
+ ImGui_ImplVulkan_Data()
|
|
|
+ {
|
|
|
+ memset((void*)this, 0, sizeof(*this));
|
|
|
+ BufferMemoryAlignment = 256;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
//-----------------------------------------------------------------------------
|
|
|
// SHADERS
|
|
|
//-----------------------------------------------------------------------------
|
|
@@ -265,7 +272,7 @@ static PFN_vkCmdEndRenderingKHR ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR;
|
|
|
static void ImGui_ImplVulkan_InitPlatformInterface();
|
|
|
static void ImGui_ImplVulkan_ShutdownPlatformInterface();
|
|
|
|
|
|
-// glsl_shader.vert, compiled with:
|
|
|
+// backends/vulkan/glsl_shader.vert, compiled with:
|
|
|
// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
|
|
|
/*
|
|
|
#version 450 core
|
|
@@ -329,7 +336,7 @@ static uint32_t __glsl_shader_vert_spv[] =
|
|
|
0x0000002d,0x0000002c,0x000100fd,0x00010038
|
|
|
};
|
|
|
|
|
|
-// glsl_shader.frag, compiled with:
|
|
|
+// backends/vulkan/glsl_shader.frag, compiled with:
|
|
|
// # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag
|
|
|
/*
|
|
|
#version 450 core
|
|
@@ -426,16 +433,17 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
|
|
|
VkMemoryRequirements req;
|
|
|
vkGetBufferMemoryRequirements(v->Device, buffer, &req);
|
|
|
bd->BufferMemoryAlignment = (bd->BufferMemoryAlignment > req.alignment) ? bd->BufferMemoryAlignment : req.alignment;
|
|
|
+ VkDeviceSize size = IM_MAX(v->MinAllocationSize, req.size);
|
|
|
VkMemoryAllocateInfo alloc_info = {};
|
|
|
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
- alloc_info.allocationSize = req.size;
|
|
|
+ alloc_info.allocationSize = size;
|
|
|
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
|
|
|
err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &buffer_memory);
|
|
|
check_vk_result(err);
|
|
|
|
|
|
err = vkBindBufferMemory(v->Device, buffer, buffer_memory, 0);
|
|
|
check_vk_result(err);
|
|
|
- p_buffer_size = req.size;
|
|
|
+ p_buffer_size = size;
|
|
|
}
|
|
|
|
|
|
static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkanH_FrameRenderBuffers* rb, int fb_width, int fb_height)
|
|
@@ -524,9 +532,9 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|
|
// Upload vertex/index data into a single contiguous GPU buffer
|
|
|
ImDrawVert* vtx_dst = nullptr;
|
|
|
ImDrawIdx* idx_dst = nullptr;
|
|
|
- VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, rb->VertexBufferSize, 0, (void**)(&vtx_dst));
|
|
|
+ VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, rb->VertexBufferSize, 0, (void**)&vtx_dst);
|
|
|
check_vk_result(err);
|
|
|
- err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, rb->IndexBufferSize, 0, (void**)(&idx_dst));
|
|
|
+ err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, rb->IndexBufferSize, 0, (void**)&idx_dst);
|
|
|
check_vk_result(err);
|
|
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
|
|
{
|
|
@@ -645,7 +653,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
|
|
{
|
|
|
VkCommandPoolCreateInfo info = {};
|
|
|
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
|
|
- info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
|
|
+ info.flags = 0;
|
|
|
info.queueFamilyIndex = v->QueueFamily;
|
|
|
vkCreateCommandPool(v->Device, &info, v->Allocator, &bd->FontCommandPool);
|
|
|
}
|
|
@@ -697,7 +705,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
|
|
vkGetImageMemoryRequirements(v->Device, bd->FontImage, &req);
|
|
|
VkMemoryAllocateInfo alloc_info = {};
|
|
|
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
- alloc_info.allocationSize = req.size;
|
|
|
+ alloc_info.allocationSize = IM_MAX(v->MinAllocationSize, req.size);
|
|
|
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits);
|
|
|
err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &bd->FontMemory);
|
|
|
check_vk_result(err);
|
|
@@ -738,7 +746,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
|
|
bd->BufferMemoryAlignment = (bd->BufferMemoryAlignment > req.alignment) ? bd->BufferMemoryAlignment : req.alignment;
|
|
|
VkMemoryAllocateInfo alloc_info = {};
|
|
|
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
|
- alloc_info.allocationSize = req.size;
|
|
|
+ alloc_info.allocationSize = IM_MAX(v->MinAllocationSize, req.size);
|
|
|
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
|
|
|
err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &upload_buffer_memory);
|
|
|
check_vk_result(err);
|
|
@@ -1332,7 +1340,7 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_devi
|
|
|
{
|
|
|
VkCommandPoolCreateInfo info = {};
|
|
|
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
|
|
- info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
|
|
+ info.flags = 0;
|
|
|
info.queueFamilyIndex = queue_family;
|
|
|
err = vkCreateCommandPool(device, &info, allocator, &fd->CommandPool);
|
|
|
check_vk_result(err);
|