Skip to content

Commit 52b7ef9

Browse files
docs(ww3d2): add DX9Ex branch base rationale and known gaps
RENDER_BACKEND.md documents why topic/dx9ex stacks on feat/render-backend-interface-skeleton instead of PR TheSuperHackers#2613's branch (Override_* compile bug on topic/render-backend-interface), what skeleton is missing, and the explicit NOT-done-yet list (cmake wiring, VC6 guards, default backend selection, runtime flags, resource-class blockers). Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 0dea318 commit 52b7ef9

1 file changed

Lines changed: 181 additions & 0 deletions

File tree

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# IRenderBackend / DX9Ex — branch base and known gaps
2+
3+
`topic/dx9ex` is currently stacked on `bobtista/feat/render-backend-interface-skeleton`
4+
(the 11-commit foundational IRenderBackend + DX8Backend adapter), **not** on
5+
`bobtista/topic/render-backend-interface` (PR #2613). This file tracks why, and
6+
what that trade gives up so it can be picked back up deliberately instead of
7+
by accident.
8+
9+
## Why skeleton instead of PR #2613's branch
10+
11+
`topic/render-backend-interface` has a real bug on its current tip
12+
(`c2435cbb5`, confirmed against a fresh fetch, not a stale local ref):
13+
`W3DShaderManager.cpp` calls `g_renderBackend->Override_Terrain_Blend(...)`,
14+
`Override_Texcoord_Index(...)`, `Override_Alpha_Blend_Enable(...)`, and
15+
`Override_Blend(...)` (introduced in commit `6a5409977`,
16+
"feat(ww3d2): extend IRenderBackend with ZBias/FillMode/DepthTest/DepthFunc/ColorWriteMask
17+
and migrate callers"), but none of those four methods were ever declared on
18+
`IRenderBackend`. It does not compile on Windows/MSVC as-is.
19+
20+
Given a choice between fixing that upstream bug in place vs. starting the
21+
DX9Ex work clean, the decision was to rebuild the small DX9Ex-specific surface
22+
(`DX9ExBackend.cpp/h`, `RenderBackend.cpp` factory wiring, `GlobalData.h`
23+
selection enum, `cmake/dx9.cmake`) directly against skeleton, mirroring
24+
`DX8Backend.cpp/h` 1:1, rather than merge/cherry-pick the old work forward.
25+
26+
## What skeleton does NOT have (known gaps, in case they matter later)
27+
28+
### Caller migrations (the actual reason topic/render-backend-interface exists)
29+
30+
These commits, present on `topic/render-backend-interface` but **not** on
31+
skeleton, migrated dozens of call sites off `DX8Wrapper::Set_DX8_Render_State`
32+
and onto `g_renderBackend`. Without them, terrain shading, shroud rendering,
33+
and screen filters in `W3DShaderManager.cpp` / `W3DShroud.cpp` still talk to
34+
`DX8Wrapper`/D3D8 directly, so a non-DX8 backend (bgfx, or eventually a real
35+
DX9Ex device) will not actually intercept those draws:
36+
37+
- `cf12396ea` — route W3D subsystems and shadow/scene callers through
38+
`g_renderBackend`; extends `IRenderBackend` with blend/stencil/cursor/alpha
39+
state (`Set_Blend_Op`, `Set_Blend_Factors`, `Set_Color_Write_Enable`,
40+
`Set_Alpha_Blend_Enable`, `Show_Hardware_Cursor`,
41+
`Set_Hardware_Cursor_Image/Position`, `Set_Stencil_*`).
42+
- `10d5d6636` — deprecate remaining `DX8Wrapper` game-code callers in favor of
43+
`IRenderBackend`.
44+
- `6a5409977` — extends `IRenderBackend` with `Set_Z_Bias`, `Set_Fill_Mode`,
45+
`Set_Depth_Test_Enable`, `Set_Depth_Write_Enable`, `Set_Depth_Func`,
46+
`Set_Color_Write_Mask`; migrates `W3DShaderManager.cpp` callers. **Also
47+
introduces the four undeclared `Override_*` calls — the bug above.**
48+
- `b0084567c` — routes `W3DShroud`'s texture upload through
49+
`IRenderBackend::Upload_Texture_Region` (POOL_DEFAULT surfaces can't be
50+
locked directly).
51+
- `951a79613` — null-guards `g_renderBackend` in `addShadow` and shroud
52+
render paths.
53+
54+
Net effect: skeleton's `IRenderBackend` has **52 virtual methods**; the
55+
current PR #2613 tip has **74** (plus the 4 that should exist but don't).
56+
57+
### General upstream drift (unrelated to rendering)
58+
59+
Skeleton's merge-base with `upstream/main` is the same commit as its
60+
merge-base with `topic/render-backend-interface` (`fe72137f3`) — skeleton was
61+
branched once and never rebased forward. As of this writing it is **42
62+
commits behind `upstream/main`**, vs. 14 for the PR #2613 branch (which has
63+
been periodically rebased — its commits carry "(cherry picked from commit
64+
...)" notes). Notable things missing from skeleton as a result, in case a
65+
conflict or missing symbol traces back here:
66+
67+
- SDL3 windowing backend (`GeneralsMD/Code/Main/SDL3Main.cpp`, ~286 lines,
68+
doesn't exist on skeleton at all).
69+
- OpenAL audio manager (device/source/stream management, decoded-PCM sample
70+
cache) and FFmpeg movie-audio wiring.
71+
- macOS build/deploy scripts (`scripts/build/macos/*`), `docs/BUILD/GETTING_THE_GAME_FILES.md`.
72+
- `cmake/bgfx.cmake`, `cmake/openal.cmake`, `cmake/sdl3.cmake`.
73+
- A batch of `unify(*)`: Move-to-Core commits (ww3d2, particlesys, bezier,
74+
commandline, precompiled, etc.) and assorted bugfixes (see
75+
`git log --oneline remotes/bobtista/bobtista/feat/render-backend-interface-skeleton..upstream/main`
76+
for the full list of 42).
77+
- `BgfxBackend.cpp/h` exist on skeleton as files but are **not wired into**
78+
`RenderBackend.cpp`'s factory (no `#if defined(GGC_RENDER_BACKEND_BGFX)`
79+
branch there, unlike PR #2613).
80+
81+
## Current state of DX9ExBackend (as of this handoff)
82+
83+
`Backend/DX9ExBackend.cpp/h` now has a **real device lifecycle**:
84+
`Initialize(window, width, height)` dynamically loads `d3d9.dll`, resolves
85+
`Direct3DCreate9Ex` via `GetProcAddress`, and calls it — **forced, no
86+
fallback to plain `Direct3DCreate9`** (explicit decision: systems without
87+
D3D9Ex support should select `-dx8`/`GraphicsBackend=DX8` instead of silently
88+
downgrading). On success it calls `CreateDeviceEx` with
89+
`D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED |
90+
D3DCREATE_FPU_PRESERVE`, windowed-only, backbuffer format taken from
91+
`GetAdapterDisplayModeEx`, depth/stencil `D3DFMT_D24S8` with a `D3DFMT_D16`
92+
fallback if the driver can't do D24S8. `Shutdown()` releases both the device
93+
and the `IDirect3D9Ex` interface. This is entirely self-contained — it does
94+
**not** touch `DX8Wrapper`'s device or any of its static state.
95+
96+
Also implemented for real against the D3D9Ex device: `Begin_Scene`/
97+
`End_Scene` (via `PresentEx`, device-lost detected from the `HRESULT`)/
98+
`Clear`/`Set_Viewport`/`Set_Transform`/`Get_Transform` (world/view/projection,
99+
using the existing backend-agnostic `To_D3DMATRIX`/`To_Matrix4x4` helpers
100+
from `WWMath/matrix4.h` — those already work with D3D9's `D3DMATRIX` since
101+
the struct layout is identical between the D3D8 and D3D9 headers)/
102+
`Set_Light`/`Set_Ambient`/`Set_Fog`/`Set_Gamma`. World/view identity tracking
103+
is a plain bool pair owned by the backend instance (not shared with
104+
`DX8Wrapper::render_state`, deliberately — see Phase 0 in
105+
`BACKEND_AGNOSTIC_RESOURCES_PLAN.md`).
106+
107+
**Still stubbed (empty bodies), matching `BgfxBackend`'s precedent, because
108+
they need real D3D9 resources and `VertexBufferClass`/`IndexBufferClass`/
109+
`TextureBaseClass`/`SurfaceClass` are still hard-typed to D3D8 COM
110+
interfaces:** `Set_Vertex_Buffer` (both overloads), `Set_Index_Buffer` (both
111+
overloads), `Set_Index_Buffer_Index_Offset`, `Set_Shader`, `Get_Shader`,
112+
`Set_Material`, `Set_Texture`, `Apply_Render_State_Changes`,
113+
`Invalidate_Cached_Render_States`, `Draw_Triangles` (both overloads),
114+
`Draw_Strip`, `Set_Vertex_Shader`, `Set_Pixel_Shader`, `Create_Render_Target`,
115+
`Set_Render_Target_With_Z`, `Is_Render_To_Texture`, `Set_Shadow_Map`,
116+
`Get_Shadow_Map`. `Get_Back_Buffer`/`Get_Back_Buffer_Format` are also stubbed
117+
for the same reason (would need to wrap `IDirect3DSurface9`/convert
118+
`D3DFORMAT` — no `SurfaceClass`/`WW3DFormat` conversion path exists for D3D9
119+
yet).
120+
121+
## NOT done yet — explicit gaps at handoff
122+
123+
1. **`cmake/dx9.cmake` is not wired into the build at all.** Nothing includes
124+
it from top-level `CMakeLists.txt` (unlike `cmake/dx8.cmake`, included at
125+
line ~55 next to `miles.cmake`/`bink.cmake`), and nothing links its
126+
exposed `d3d9`/`dx9` targets into `corei_ww3d2`
127+
(`Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt`). **This means
128+
`DX9ExBackend.cpp`'s `#include <d3d9.h>` will not resolve and the current
129+
commit has NOT been compile-verified.** This is the first thing the next
130+
session needs to fix before anything else here can be trusted.
131+
2. **VC6 guard is not in place.** `Backend/DX9ExBackend.cpp/h` are
132+
unconditionally listed in `Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt`
133+
— nothing excludes them from `IS_VS6_BUILD`. VC6 cannot compile against
134+
modern D3D9 headers; these two files (and the `cmake/dx9.cmake` include
135+
once wired) need to be gated the same way `cmake/dx8.cmake` vs.
136+
`cmake/stlport.cmake` already branch on `IS_VS6_BUILD` in the top-level
137+
`CMakeLists.txt`.
138+
3. **Default backend selection is not implemented.** The requested behavior
139+
(DX9Ex default on modern compilers, DX8 the only option on VC6, both
140+
available as a build/runtime option on modern compilers) has no code yet.
141+
`RenderBackend.cpp`'s `#if defined(GGC_RENDER_BACKEND_DX9EX)` exists but
142+
nothing defines that macro anywhere — today every build silently gets
143+
`DX8Backend` regardless of compiler. Needs a `cmake` option (e.g. in
144+
`cmake/config-build.cmake`) that defaults ON when `NOT IS_VS6_BUILD` and
145+
is forced OFF (or not even offered) when `IS_VS6_BUILD`.
146+
4. **The `-dx8`/`-dx9ex` command-line flags and `Options.ini`
147+
`GraphicsBackend` runtime parsing** (item 3 of the original implementation
148+
plan) still don't exist — `GlobalData::m_renderBackend` is declared but
149+
nothing reads or writes it. Right now backend selection can only ever be
150+
compile-time (once item 3 above lands).
151+
5. **Resource-class work** (`BACKEND_AGNOSTIC_RESOURCES_PLAN.md` Phases 1-2)
152+
hasn't started. Until then, `DX9ExBackend` can create a real device, clear
153+
the screen, and set transforms/lights, but cannot draw any actual game
154+
geometry (no vertex/index/texture binding).
155+
6. **Caller-migration gap** (this file's earlier section) is unchanged: even
156+
once resource classes are fixed, `W3DShaderManager.cpp`/`W3DShroud.cpp`
157+
etc. still call `DX8Wrapper` directly for blend/stencil/cursor/terrain
158+
state, bypassing `g_renderBackend` entirely, because skeleton never got
159+
those caller-migration commits.
160+
161+
## Next steps, roughly in order
162+
163+
1. Wire `cmake/dx9.cmake` into the top-level `CMakeLists.txt` (guarded by
164+
`NOT IS_VS6_BUILD`, next to `include(cmake/dx8.cmake)`) and link its
165+
exposed target(s) into `corei_ww3d2`. **Compile-verify `DX9ExBackend.cpp`
166+
for the first time** — it has not built successfully yet.
167+
2. Exclude `Backend/DX9ExBackend.cpp/h` from VC6 builds in
168+
`Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt`.
169+
3. Add the cmake option + `#define GGC_RENDER_BACKEND_DX9EX` default-on for
170+
modern compilers, off for VC6, so `RenderBackend.cpp`'s existing
171+
`#if`/`#else` actually does something.
172+
4. Add the `-dx8`/`-dx9ex` command-line flags and `Options.ini`
173+
`GraphicsBackend` parsing that select `GGC_RENDER_BACKEND_DX9EX` /
174+
`TheGlobalData->m_renderBackend` at runtime.
175+
5. Start `BACKEND_AGNOSTIC_RESOURCES_PLAN.md` Phase 1 (`VertexBufferClass`/
176+
`IndexBufferClass` — additive, no base-class changes needed) so
177+
`DX9ExBackend` can actually bind and draw geometry.
178+
6. Decide whether to re-derive the caller-migration commits (blend/stencil/
179+
cursor/terrain-override plumbing) on top of this branch, or accept that
180+
DX9Ex — like skeleton's DX8Backend — won't actually see those draw calls
181+
until that's done.

0 commit comments

Comments
 (0)