Fix text corruption in oversized labels (16-bit text index overflow)#19
Fix text corruption in oversized labels (16-bit text index overflow)#19Schogol wants to merge 1 commit into
Conversation
Text sprite batches used 16-bit index counts and 16-bit index values, so a single label overflowed once its geometry exceeded 65535 indices: 2 quads/glyph = 12 indices/glyph with Text Shadow, i.e. ~5461 visible glyphs. Past that, the index count wrapped (and beyond ~8191 glyphs the per-draw-call vertex index values wrapped too), corrupting the render of large popups such as contracts and acceleration-gate messages. Widen the sprite index path to 32-bit: - RenderTriangleVerts / EnsureBufferSpace / CopyIndicesWithOffset / GrowCaptureIndexBuffer index counts unsigned short -> unsigned int - Tr2FontMeasurer index values (m_indices, AdjustIndicesIfNeeded) to unsigned int, submitted via new 32-bit RenderTriangleVerts / CopyIndicesWithOffset overloads so the existing 16-bit path used by other sprite types is untouched The GPU index buffer is already 32-bit (stride 4), so no format change is needed. Relates to EDR-1989.
|
Hi looks promising. Did you test this and does it work? |
|
It compiles with warnings-as-errors on, and links into both _trinity_dx11 and _trinity_dx12 using python 3. Previous issue: I reproduced the overflow and confirmed the fix removes it (standalone demo - not using the compiled dll). Index overflow vs. label size (16-bit vs. 32-bit) |
Summary
Popup windows with a very large amount of text (e.g. contract confirmations with many items, "can't activate" acceleration-gate messages) render corrupt. The text sprite batch used 16-bit indices, which overflow once a single label exceeds 65,535 indices.
Should fix EDR-1989.
Root cause
EVE's font emits 2 quads per glyph = 12 indices/glyph with Text Shadow on, so a single label overflows the 16-bit index space at 65,535 / 12, i.e. about 5,461 visible glyphs. Two 16-bit bottlenecks:
RenderTriangleVerts/EnsureBufferSpace/CopyIndicesWithOffset/GrowCaptureIndexBuffertookunsigned short indexCount, truncating theunsigned intcount the font passes (the ~5,461-glyph limit).Tr2FontMeasurer::m_indiceswasunsigned short, so per-draw-call vertex indices wrap once a single-texture run exceeds 65,535 vertices (~8,191 glyphs with shadow).UI text goes through the capture/display-list path, which does not split batches, so the whole label hits these 16-bit boundaries in one submission.
Fix
Widen the text sprite index path to 32-bit:
unsigned short->unsigned intinRenderTriangleVerts(both overloads),EnsureBufferSpace,CopyIndicesWithOffset,GrowCaptureIndexBuffer.Tr2FontMeasurer(m_indices,AdjustIndicesIfNeeded) ->unsigned int, submitted via new 32-bitRenderTriangleVerts/CopyIndicesWithOffsetoverloads. The existing 16-bit overloads are kept for the other sprite types (frames, lines, brackets) that pass 16-bit index arrays, so their callers are untouched.The GPU index buffer is already 32-bit (
m_indexBuffer.Create(indexCount, 4)), so no GPU format change is needed; this only stops the CPU-side truncation before the data reaches the already-32-bit buffer.