Significantly increase draw performance for large numbers of interleaved draw commands #14
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In our project we draw a significant number of items on a map view using ImGui. Each item consists of several sub-items which in many cases means that each item is split up into several ImGui draw calls (because the
TextureID
changes).The problem is now that SImGuiOverlay copies the entire vertex array for each single draw command. With vertex arrays having thousands of entries, this can quickly become a major bottleneck due to constant memory (re-)allocations.
I didn't find a good way to avoid copying the entire vertex array, but at least we can merge draw calls using the same parameters by merging the index arrays. The worst case I tested with previously took 250 ms per tick(!) to draw everything. With these changes, it now takes 3 ms. This is good enough for us for now, but it's likely that we have to spend some more time there in the future to scale up further.
The main points are:
FSlateVertex::Make()
and instead inline the required setup which saves additional timeMakeCustomVerts
: https://github.com/EpicGames/UnrealEngine/pull/12023, which also saves a few hundred microseconds with large arrays. However, that repo being what it is, I don't expect this to be merged anytime soon, if everUsedCommands
as a member seems unnecessary at first, but reallocating this all the time inOnPaint
was actually measurable, so made it a memberThis works perfectly for us. Maybe you don't want to take it as is, but I'd love if we could find an agreement here so that we don't have to maintain a divergence in our project