Skip to content

refactor(renderer): route Shader/Texture/Framebuffer through GfxDevice (RC5)#42

Merged
esengine merged 1 commit into
masterfrom
rearch/rc5-gfxdevice
Jun 18, 2026
Merged

refactor(renderer): route Shader/Texture/Framebuffer through GfxDevice (RC5)#42
esengine merged 1 commit into
masterfrom
rearch/rc5-gfxdevice

Conversation

@esengine

Copy link
Copy Markdown
Owner

What

RC5 step toward "GfxDevice as the sole GPU entry" (see docs/REARCHITECTURE.md). The renderer had two parallel ways to reach the GPU: through GfxDevice/StateTracker, and raw glXxx inside the resource classes — the latter bypassed the device and silently desynced StateTracker's cache (e.g. a Shader::bind() could leave the tracker thinking a different program was bound, so a later cache hit would skip the real bind → wrong shader, silently).

This collapses that onto one device boundary + one state cache.

Changes

  • GfxDevice: add createProgram/deleteProgram/getAttribLocation/setClearStencil/setUnpackFlipY and Depth24Stencil8 / DepthStencil enums. GLDevice implements them — the multi-step shader compile/link protocol moves out of Shader.cpp into GLDevice, so the WebGL-only constants live in the one GL file.
  • StateTracker: now caches VAO / VBO / IBO / framebuffer binds (was program/texture/render-state only) and is promoted to a per-App service so every renderer subsystem shares one authoritative cache.
  • Shader / Texture / Framebuffer: thin RAII handles over GfxDevice with zero raw gl and zero GL includes. Texture drops its ES_PLATFORM_WEB-only bodies, so native textures work again instead of being dead.
  • ResourceManager now holds the GfxDevice& (it is the GPU-resource factory); EstellaContext creates GLDevice before it. RenderTarget/RenderTargetManager thread the device through to Framebuffer.

Verification

No emsdk locally, so the production web build is validated in CI. Locally, the converted resource classes are compiled against a new tests/renderer/MockGfxDevice.hpplinking proves they no longer touch GL — plus three native CTest harnesses (state_tracker, shader_device, texture_fb, all green) that need no GL/emsdk and run in CI.

Raw gl* outside GLDevice: 135 → 41 (Shader/Texture/Framebuffer eliminated).

Follow-up (separate PR)

Convert Buffer/VertexArray + CustomGeometry; retire Renderer/BatchRenderer2D and rebase ImmediateDraw on TransientBufferPool; then a CI guard that fails the build on any gl* outside GLDevice.

…e (RC5)

Collapse the duplicate GPU-resource layer onto a single device boundary plus a
single state cache — the keystone of RC5's "GfxDevice as sole GPU entry". The
resource classes used to call raw glXxx directly, bypassing GfxDevice and
silently desyncing StateTracker's cache.

- GfxDevice: add createProgram/deleteProgram/getAttribLocation/setClearStencil/
  setUnpackFlipY and Depth24Stencil8 / DepthStencil enums. GLDevice implements
  them (the multi-step shader compile/link protocol moves out of Shader.cpp into
  GLDevice, so the WebGL-only constants stay in the one GL file).
- StateTracker: cache VAO/VBO/IBO/framebuffer binds (was program/texture/render
  state only); promote it to a per-App service so every renderer subsystem
  shares one authoritative cache instead of each binding behind its back.
- Shader/Texture/Framebuffer: become thin RAII handles over GfxDevice with zero
  raw gl and zero GL includes. Texture drops its ES_PLATFORM_WEB-only bodies, so
  native textures work again instead of being dead.
- ResourceManager now holds the GfxDevice& (it is the GPU-resource factory);
  EstellaContext creates GLDevice before it and injects it. RenderTarget /
  RenderTargetManager thread the device through to Framebuffer.

Tests: MockGfxDevice + three native CTest harnesses (state_tracker,
shader_device, texture_fb) that compile the converted classes against the mock —
linking proves GL-decoupling, and they run without emsdk.

Raw gl* outside GLDevice: 135 -> 41 (Shader/Texture/Framebuffer eliminated).

Follow-up (separate, CI-verified PR): convert Buffer/VAO + CustomGeometry,
retire Renderer/BatchRenderer2D and rebase ImmediateDraw on TransientBufferPool,
then add the CI guard that fails the build on any gl* outside GLDevice.
@esengine esengine force-pushed the rearch/rc5-gfxdevice branch from 689cba2 to 7a2b60f Compare June 18, 2026 10:05
@esengine esengine merged commit 58475f4 into master Jun 18, 2026
2 checks passed
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