Skip to content

bugfix(render2d): Flush batched 2D draws before they overflow the dynamic buffers - #3487

Open
tintinhamans wants to merge 1 commit into
TheSuperHackers:mainfrom
tintinhamans:arctic/fix/render2d-batch-overflow
Open

tintinhamans wants to merge 1 commit into
TheSuperHackers:mainfrom
tintinhamans:arctic/fix/render2d-batch-overflow

Conversation

@tintinhamans

Copy link
Copy Markdown

Render2DClass::Render passes Indices.Count() to DynamicIBAccessClass, which takes an unsigned short. 65538 indices become 2, the index buffer is locked for 2, and the copy loop writes all 65538.

Before batching, W3DDisplay called Render after every draw call, so the renderer never held more than one. Now setup2DRenderState only flushes when the texture, mode or grayscale changes, so identical draws accumulate for the whole batch.

Drawable::drawAmmo hits this: it draws one pip image per round in the clip, and ClipSize is a plain INI::parseInt. A weapon with ShowsAmmoPips and a clip of 10923 is 65538 indices, and selecting or hovering the unit writes up to 128 KB past the buffer.

Render2DClass now has MAX_VERTEX_COUNT, MAX_INDEX_COUNT and Can_Add. setup2DRenderState also flushes once half that capacity is used, and Render skips geometry that does not fit instead of copying it.

drawRiverWater has the same narrowing with the point count of a river polygon and will be handled in follow-up.

@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6be48f9d-75da-4e73-99bf-05d24fe5af09

📥 Commits

Reviewing files that changed from the base of the PR and between 0e6a06c and 1bdda9d.


📒 Files selected for processing (5)
  • Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
  • Generals/Code/Libraries/Source/WWVegas/WW3D2/render2d.cpp
  • Generals/Code/Libraries/Source/WWVegas/WW3D2/render2d.h
  • GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/render2d.cpp
  • GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/render2d.h

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 1 remain after this review.



Walkthrough

The change adds vertex and index capacity checks to the 2D renderer in Generals and GeneralsMD. Rendering stops when current buffer counts exceed the limits. W3DDisplay uses a capacity check to decide whether to continue batching or start a new batch.

Changes

2D renderer capacity checks

Layer / File(s) Summary
Capacity contract and render guard
Generals/Code/Libraries/Source/WWVegas/WW3D2/render2d.h, Generals/Code/Libraries/Source/WWVegas/WW3D2/render2d.cpp, GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/render2d.h, GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/render2d.cpp
Both variants define 65,535 vertex and index limits and add Can_Add. Render2DClass::Render asserts and returns when Can_Add(0, 0) fails.
Batch capacity check
Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
setup2DRenderState reuses the current batch only when Can_Add reports room for at least half the maximum vertex and index counts.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: bobtista

Merge Risk: ⚪ Minimal · up to 1bdda

No actionable buffer-overflow risk was established in the changed rendering paths; the PR appears mergeable after normal checks.

Pre-merge checks | Passed 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: flushing batched 2D draws before dynamic buffer overflow.
Description check Passed The description directly explains the buffer-overflow risk, the affected code paths, and the implemented safeguards.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium impact] This PR appears safe to merge; no actionable issues were found.

Summary

This PR keeps batched 2D draws within the dynamic buffers’ 16-bit limits.

  • 2D draw batches flush before their dynamic buffers fill.

Author tintinhamans explicitly describes skipping oversized geometry as intentional and defers the separate drawRiverWater narrowing issue to a follow-up. Neither is reported here.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A["Next 2D draw"] --> B{"Same settings and room for half-capacity?"}
  B -->|Yes| E["Append geometry"]
  B -->|No| C["Render and reset current batch"]
  C --> D["Apply draw settings"]
  D --> E
  E --> F["Next draw or batch end"]
  F --> G{"Geometry fits 16-bit counts?"}
  G -->|Yes| H["Copy buffers and draw"]
  G -->|No| I["Skip oversized geometry"]
Loading

Reviews (1) · Last reviewed commit: "bugfix(render2d): Flush batched 2D draws..." · Reviewed by Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant