mirror of
https://github.com/ocornut/imgui.git
synced 2026-11-10 19:03:30 +00:00
Font Texture Atlas leaks when ImGui_ImplVulkan_CreateFontsTexture is called more than once #3743
Labels
No labels
accidentally closed
android
backends
bug
building
clipper
coloredit
color spaces
cplusplus
data types
demo
disabled
doc
docking
dpi
drag drop
drawing/drawlist
dropped
dx12
enhancement
focus
font/text
gallery
help wanted
idle/power saving
ime
in progress
inputs
inputtext
internals
label/id and id stack
language bindings
layout
linux/bsd
menus
multi-contexts
multi-threading
multi-viewports
nav
news/info
opengl
optimization
osx/ios
overlap
plot/graph
popups
question
scrolling
selection
settings
sliders/drags
style
tables/columns
tabs
test wanted
tools
tooltips
tree
tricks & tips
useful widgets
vulkan
web
window pos/depth
window sizing
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ocornut/imgui#3743
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Version/Branch of Dear ImGui:
Version: 1.79
Branch: v1.79
Back-end/Renderer/Compiler/OS
Back-ends: imgui_impl_vulkan.h + imgui_impl_glfw.cpp
Compiler: VS 2019
Operating System: Windows 10
My Issue/Question:
I would like my application to correctly handle GUI scaling. The current guideline suggests: "For correct scaling, prefer to reload font + rebuild ImFontAtlas + call style.ScaleAllSizes()".
To rebuild the texture atlas, I use ImGui_ImplVulkan_CreateFontsTexture() function. This works if the function is called just once. However, if it is called more than once, the old texture atlas leaks (g_FontImage, g_FontView, g_FontMemory are over-written).
One way to get around this would be to call ImGui_ImplVulkan_Shutdown, and then recreate Vulkan context from scratch. But this seems quite heavy/excessive.
It would be nice to have a function that destroys the font atlas. This function could be called explicitly by the user, or it could be called implicitly when invoking ImGui_ImplVulkan_CreateFontsTexture . For example:
You are absolutely right we need that function in.
Presently I'm not familiar enough with Vulkan to provide or use this correctly.
ImGui_ImplVulkan_CreateFontsTexture()stores the the value of g_FontSampler, g_FontView into a descriptor would that need cleaning? If I naively create a reload test before NewFrame()The call to
vkCmdPipelineBarrier()inImGui_ImplVulkan_CreateFontsTexture()gives me:I didn't investigate more than that. If you can provide a PR with ImGui_ImplVulkan_DestroyFontsTexture() that pass validation + a way to use it I can integrate it.
There are few old related issues #914 #2697 which needs solving together and maybe this can come with it.
Also note that the
shadowsbranch has experimental work to make it a general feature in backend to easily reload texture. Ref 3519b9c35ef9342a5b7b740e4347318342d8d620 4e7239c9a15f650c1ececb7d2cdf1d49f6923c88Hello Omar,
Sorry for not getting back to you sooner.
This is what the
ImGui_ImplVulkan_CreateFontsTexturefunction does:pixels)g_FontImageandg_FontMemory)g_FontView)g_DescriptorSet)g_UploadBufferandg_UploadBufferMemory)pixelsto the upload bufferg_UploadBuffer) to the device texture (g_FontImage); these commands are recorded into a command buffer supplied by the user.In your example, you use the per-frame command buffer. This buffer has already been recorded and it holds a reference to the
g_FontImage. CallingImGui_ImplVulkan_DestroyFontsTextureproduces a dangling reference in that command buffer. This is not a problem as long as we don't use the command buffer in its current (invalid) state. But a call toImGui_ImplVulkan_CreateFontsTextureattempts to record commands into it (step 7). At this point, the validation layer detects that the command buffer is no longer in a valid state and produces the InvalidCommandBuffer error.We can get around this, but I think it would be cleaner to side-step the issue, and create a temporary command buffer. Its only purpose will be to upload the font atlas to the device. The code might look like this:
I have omitted error checking for clarity. Now your example should work:
You other concerns relate to
g_FontViewandg_FontSampler.ImGui_ImplVulkan_CreateFontsTexturecreates a new font view, updatesg_FontViewand updates the descriptor. This is fine and, in fact, necessary. We would not want the descriptor to refer to the old (destroyed) font view. If you look at steps 1 - 7,ImGui_ImplVulkan_CreateFontsTexturedoes not create a new sampler; there is no danger of resource leak. We would only want to re-create the sampler if the font texture sampling depends on font size. Looking atImGui_ImplVulkan_CreateFontSampler, this is not the case.@guybrush77 I apologize for my late answer to this. Thank you for your thoughtful post.
Would you be able to make a PR for it?
The problem occurs because the command buffer with the bound image view may still be in use. To solve the problem, we would have to wait for all command buffers, which are not prerecorded according to the implementation, to finish execution. Can we assume that the command buffers are submitted to the queue inside
ImGui_ImplVulkan_InitInfo? If this was the case, we could simply wait for the queue to finish any execution.Unless I've missed something, you wouldn't even need a temporary command pool, since you generally create a temporary one for the execution of
ImGui_ImplVulkan_CreateFontsTexture. I was able to solve the validation layers issues withvkQueueWaitIdle, but assuming that the main rendering process is running on the queue insideImGui_ImplVulkan_InitInfo. Otherwise you would have to wait for the device withvkDeviceWaitIdle.I opened the pull request rather quickly (unfortunately too quickly) as I found the problem to be a very large and breaking one. I would be willing to work on the pull request and fix any issues, depending on whether @guybrush77 would be willing to create a new pull request. Then I would close it without hesitation of course. Apologies for any inconvenience caused by my pull request!