mirror of
https://github.com/ocornut/imgui.git
synced 2025-09-06 19:38:28 +00:00
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_vulkan.cpp # imgui.cpp # imgui_internal.h
This commit is contained in:
@@ -34,7 +34,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-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-01-11: Vulkan: Fixed vkMapMemory() calls unnecessarily using full buffer size (#3957). Fixed MinAllocationSize handing (#7189).
|
||||
// 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)
|
||||
@@ -93,14 +94,14 @@
|
||||
#endif
|
||||
|
||||
// Forward Declarations
|
||||
struct ImGui_ImplVulkanH_FrameRenderBuffers;
|
||||
struct ImGui_ImplVulkanH_WindowRenderBuffers;
|
||||
struct ImGui_ImplVulkan_FrameRenderBuffers;
|
||||
struct ImGui_ImplVulkan_WindowRenderBuffers;
|
||||
bool ImGui_ImplVulkan_CreateDeviceObjects();
|
||||
void ImGui_ImplVulkan_DestroyDeviceObjects();
|
||||
void ImGui_ImplVulkan_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkan_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(VkDevice device, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
|
||||
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator);
|
||||
@@ -200,7 +201,7 @@ static PFN_vkCmdEndRenderingKHR ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR;
|
||||
|
||||
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkanH_FrameRenderBuffers
|
||||
struct ImGui_ImplVulkan_FrameRenderBuffers
|
||||
{
|
||||
VkDeviceMemory VertexBufferMemory;
|
||||
VkDeviceMemory IndexBufferMemory;
|
||||
@@ -212,11 +213,11 @@ struct ImGui_ImplVulkanH_FrameRenderBuffers
|
||||
|
||||
// Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkanH_WindowRenderBuffers
|
||||
struct ImGui_ImplVulkan_WindowRenderBuffers
|
||||
{
|
||||
uint32_t Index;
|
||||
uint32_t Count;
|
||||
ImGui_ImplVulkanH_FrameRenderBuffers* FrameRenderBuffers;
|
||||
ImGui_ImplVulkan_FrameRenderBuffers* FrameRenderBuffers;
|
||||
};
|
||||
|
||||
// For multi-viewport support:
|
||||
@@ -225,7 +226,7 @@ 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_WindowRenderBuffers RenderBuffers; // Used by all viewports
|
||||
|
||||
ImGui_ImplVulkan_ViewportData() { WindowOwned = false; memset(&RenderBuffers, 0, sizeof(RenderBuffers)); }
|
||||
~ImGui_ImplVulkan_ViewportData() { }
|
||||
@@ -255,7 +256,7 @@ struct ImGui_ImplVulkan_Data
|
||||
VkCommandBuffer FontCommandBuffer;
|
||||
|
||||
// Render buffers for main window
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers;
|
||||
ImGui_ImplVulkan_WindowRenderBuffers MainWindowRenderBuffers;
|
||||
|
||||
ImGui_ImplVulkan_Data()
|
||||
{
|
||||
@@ -411,7 +412,13 @@ static void check_vk_result(VkResult err)
|
||||
v->CheckVkResultFn(err);
|
||||
}
|
||||
|
||||
static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& p_buffer_size, size_t new_size, VkBufferUsageFlagBits usage)
|
||||
// Same as IM_MEMALIGN(). 'alignment' must be a power of two.
|
||||
static inline VkDeviceSize AlignBufferSize(VkDeviceSize size, VkDeviceSize alignment)
|
||||
{
|
||||
return (size + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& buffer_size, size_t new_size, VkBufferUsageFlagBits usage)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
@@ -421,10 +428,10 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
|
||||
if (buffer_memory != VK_NULL_HANDLE)
|
||||
vkFreeMemory(v->Device, buffer_memory, v->Allocator);
|
||||
|
||||
VkDeviceSize vertex_buffer_size_aligned = ((new_size - 1) / bd->BufferMemoryAlignment + 1) * bd->BufferMemoryAlignment;
|
||||
VkDeviceSize buffer_size_aligned = AlignBufferSize(IM_MAX(v->MinAllocationSize, new_size), bd->BufferMemoryAlignment);
|
||||
VkBufferCreateInfo buffer_info = {};
|
||||
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
buffer_info.size = vertex_buffer_size_aligned;
|
||||
buffer_info.size = buffer_size_aligned;
|
||||
buffer_info.usage = usage;
|
||||
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &buffer);
|
||||
@@ -433,20 +440,19 @@ 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 = size;
|
||||
alloc_info.allocationSize = req.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 = size;
|
||||
buffer_size = buffer_size_aligned;
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkanH_FrameRenderBuffers* rb, int fb_width, int fb_height)
|
||||
static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkan_FrameRenderBuffers* rb, int fb_width, int fb_height)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
|
||||
@@ -507,23 +513,23 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
// Allocate array to store enough vertex/index buffers. Each unique viewport gets its own storage.
|
||||
ImGui_ImplVulkan_ViewportData* viewport_renderer_data = (ImGui_ImplVulkan_ViewportData*)draw_data->OwnerViewport->RendererUserData;
|
||||
IM_ASSERT(viewport_renderer_data != nullptr);
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &viewport_renderer_data->RenderBuffers;
|
||||
ImGui_ImplVulkan_WindowRenderBuffers* wrb = &viewport_renderer_data->RenderBuffers;
|
||||
if (wrb->FrameRenderBuffers == nullptr)
|
||||
{
|
||||
wrb->Index = 0;
|
||||
wrb->Count = v->ImageCount;
|
||||
wrb->FrameRenderBuffers = (ImGui_ImplVulkanH_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameRenderBuffers) * wrb->Count);
|
||||
memset(wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkanH_FrameRenderBuffers) * wrb->Count);
|
||||
wrb->FrameRenderBuffers = (ImGui_ImplVulkan_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count);
|
||||
memset(wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count);
|
||||
}
|
||||
IM_ASSERT(wrb->Count == v->ImageCount);
|
||||
wrb->Index = (wrb->Index + 1) % wrb->Count;
|
||||
ImGui_ImplVulkanH_FrameRenderBuffers* rb = &wrb->FrameRenderBuffers[wrb->Index];
|
||||
ImGui_ImplVulkan_FrameRenderBuffers* rb = &wrb->FrameRenderBuffers[wrb->Index];
|
||||
|
||||
if (draw_data->TotalVtxCount > 0)
|
||||
{
|
||||
// Create or resize the vertex/index buffers
|
||||
size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
|
||||
size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
|
||||
size_t vertex_size = AlignBufferSize(draw_data->TotalVtxCount * sizeof(ImDrawVert), bd->BufferMemoryAlignment);
|
||||
size_t index_size = AlignBufferSize(draw_data->TotalIdxCount * sizeof(ImDrawIdx), bd->BufferMemoryAlignment);
|
||||
if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size)
|
||||
CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size)
|
||||
@@ -532,9 +538,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, vertex_size, 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, index_size, 0, (void**)&idx_dst);
|
||||
check_vk_result(err);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
@@ -1241,6 +1247,26 @@ void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set)
|
||||
vkFreeDescriptorSets(v->Device, v->DescriptorPool, 1, &descriptor_set);
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
if (buffers->VertexBuffer) { vkDestroyBuffer(device, buffers->VertexBuffer, allocator); buffers->VertexBuffer = VK_NULL_HANDLE; }
|
||||
if (buffers->VertexBufferMemory) { vkFreeMemory(device, buffers->VertexBufferMemory, allocator); buffers->VertexBufferMemory = VK_NULL_HANDLE; }
|
||||
if (buffers->IndexBuffer) { vkDestroyBuffer(device, buffers->IndexBuffer, allocator); buffers->IndexBuffer = VK_NULL_HANDLE; }
|
||||
if (buffers->IndexBufferMemory) { vkFreeMemory(device, buffers->IndexBufferMemory, allocator); buffers->IndexBufferMemory = VK_NULL_HANDLE; }
|
||||
buffers->VertexBufferSize = 0;
|
||||
buffers->IndexBufferSize = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkan_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
for (uint32_t n = 0; n < buffers->Count; n++)
|
||||
ImGui_ImplVulkan_DestroyFrameRenderBuffers(device, &buffers->FrameRenderBuffers[n], allocator);
|
||||
IM_FREE(buffers->FrameRenderBuffers);
|
||||
buffers->FrameRenderBuffers = nullptr;
|
||||
buffers->Index = 0;
|
||||
buffers->Count = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own app.)
|
||||
@@ -1606,32 +1632,12 @@ void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH
|
||||
fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
if (buffers->VertexBuffer) { vkDestroyBuffer(device, buffers->VertexBuffer, allocator); buffers->VertexBuffer = VK_NULL_HANDLE; }
|
||||
if (buffers->VertexBufferMemory) { vkFreeMemory(device, buffers->VertexBufferMemory, allocator); buffers->VertexBufferMemory = VK_NULL_HANDLE; }
|
||||
if (buffers->IndexBuffer) { vkDestroyBuffer(device, buffers->IndexBuffer, allocator); buffers->IndexBuffer = VK_NULL_HANDLE; }
|
||||
if (buffers->IndexBufferMemory) { vkFreeMemory(device, buffers->IndexBufferMemory, allocator); buffers->IndexBufferMemory = VK_NULL_HANDLE; }
|
||||
buffers->VertexBufferSize = 0;
|
||||
buffers->IndexBufferSize = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
for (uint32_t n = 0; n < buffers->Count; n++)
|
||||
ImGui_ImplVulkanH_DestroyFrameRenderBuffers(device, &buffers->FrameRenderBuffers[n], allocator);
|
||||
IM_FREE(buffers->FrameRenderBuffers);
|
||||
buffers->FrameRenderBuffers = nullptr;
|
||||
buffers->Index = 0;
|
||||
buffers->Count = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(VkDevice device, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
||||
if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)platform_io.Viewports[n]->RendererUserData)
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(device, &vd->RenderBuffers, allocator);
|
||||
ImGui_ImplVulkan_DestroyWindowRenderBuffers(device, &vd->RenderBuffers, allocator);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
@@ -1693,7 +1699,7 @@ static void ImGui_ImplVulkan_DestroyWindow(ImGuiViewport* viewport)
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
if (vd->WindowOwned)
|
||||
ImGui_ImplVulkanH_DestroyWindow(v->Instance, v->Device, &vd->Window, v->Allocator);
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &vd->RenderBuffers, v->Allocator);
|
||||
ImGui_ImplVulkan_DestroyWindowRenderBuffers(v->Device, &vd->RenderBuffers, v->Allocator);
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->RendererUserData = nullptr;
|
||||
|
Reference in New Issue
Block a user