mirror of
https://github.com/ocornut/imgui.git
synced 2026-11-14 19:04:44 +00:00
Bug with VertexBuffer size > UINT16_MAX #514
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#514
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?
Hello,
With lot of widgets, I have an ImGUI generated vertex-buffer with 71180 vertices (so, more than UINT16_MAX) :
The IndexBuffers are defined using ImDrawIdx with its standard definition :
It would mean that some vertices won't be reachable. Not a big deal.
But, the result is more interesting : the App violently crashes the METAL api, and the OS remains completely frozen (thx for these drivers Mr. Apple). So I reboot between each test.
I know that I can customise the ImDrawIdx and use 32 bit indices, but that would be too easy :)
I think there may be a bug in the VertexBuffer generation, or at least there is missing an ASSERT checking that the size of VertexBuffers match the indice length.
EDIT: I just made an expensive change in my engine, just to be sure, by using 32bits indices everywhere (in ImGui too). It works. But, I continue to think that a good old ASSERT in ImGui to verify that vertex-buffers have a correct size (depending on the ImDrawIdx length) would spare some time for developers.
There's already an assert in AddDrawListToRenderList()
It is a bug if it doesn't trigger, could you investigate?
You can also look at the ImGui metrics windows for some extra information.
However note that you could and should probably add a similar test in your backend especially if you know it is crashing your system...
71180 vertices in a single window is an unusual amount, are you doing custom drawing?
While the ImDrawList api is convenient with anti-aliasing and rounding enabled it currently uses a lot of vertices. If all you are doing is drawing axis-aligned rounded rectangle/outline I would like eventually to bake some of the rendering into the texture atlas to save on vertices. But realistically no time to do so.
You can also manually split draw commands to avoid getting past the 64k limits and save that bandwidth. See the thread
https://github.com/ocornut/imgui/issues/292
You're right, there is an ASSERT which is not triggered, and I'm doing intensive tests of ImGUI with lot of things on the screen.
I rollbacked my modifs in order to debug with 16bits indices. Give me few minutes to see what's wrong.
(after thinking a little bit, I finally decided to keep 32bits indices which I should have done one day or another, so this isn't a blocking point for me anymore)
EDIT: the figures from the Metrics window are consistent with the number of vertices (>= 65536).
Need to understand why the im_assert is not triggered by mine is...
Ok, there is a missing assert somewhere else.
Here is a short log of what is happening :
As you can see, there is vertex-buffer which is close to explode (V: 65274), and it explodes when I create new fake guis.
But the verification in ImGui doesn't show anything wrong.
There should be another verification to add.
Don't you think the ASSERT should be this one instead of the existing one ?
This one is triggered.
_VtxCurrentIdx should always be equal to _VtxBuffer.Size at the end of rendering, else it means that PrimReserve() haven't been used correctly, or there is a bug somewhere.
In ShowMetrics if I change
bool node_opened = ImGui::TreeNode(draw_list, "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->IdxBuffer.Size, draw_list->CmdBuffer.Size);to
bool node_opened = ImGui::TreeNode(draw_list, "%s: '%s' %d/%d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->_VtxCurrentIdx, draw_list->IdxBuffer.Size, draw_list->CmdBuffer.Size);I only seem to get matching values.
So there is something fishy. Do you have a repro?
Difficult to share my complete source code to reproduce it... or in private maybe.
I sent you an email
OK I think I've found the bug in ImDrawList::AddText()
_VtxCurrentIdx = (ImDrawIdx)VtxBuffer.Size;should be
_VtxCurrentIdx = (unsigned int)VtxBuffer.Size;Could you confirm?
Great, thanks !
EDIT : I confirm the bug is fixed => the ASSERT is correctly triggered.
Committed fix and added an extra assert:
IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); // Sanity check. Bug or mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.I think there is something fishy because I can't explain the 1060/1152 difference, and 5644 isn't 65274 mod 64K. So this second assert may also trigger even as you switch to 32-bits and I'm interested in hearing about it. Thanks!
Thanks for the fix !
I will bump ImGui as soon as I finish the migration to 32 bits (I disabled tri-strips to be quicker... and I'm moving from NvTriStrip (16bits) to TriStripper (32bits)). It should take me one hour. I keep you informed when I have some results. Thx again !
I bumped ImGui to tip.
No assert is triggered, so the values should be correct.
But in release, I noticed that some columns are missing in my test-case. I will dig into it tomorrow..