fix(N.4) Adjustment 2: revert Task 9 renderer-level routing
Smoke test flag-on showed characters/NPCs disappearing along with static scenery. Root cause: Task 9 routed all InstancedMeshRenderer.EnsureUploaded calls through WB. But that renderer is used for BOTH tiers in production — character per-part spawn (line 2302, per-instance) AND streaming-loader spawns (lines 5137 + 5155, atlas). The renderer is tier-blind by design. Tier-routing belongs at the spawn-callback layer per the spec's data-flow section: - LandblockSpawnAdapter (Task 11) calls IncrementRefCount per unique GfxObj — atlas-tier only. - EntitySpawnAdapter (Task 17) routes through per-instance path via TextureCache.GetOrUploadWithPaletteOverride. This commit removes the sentinel pattern + 4 sentinel-skip checks from InstancedMeshRenderer. Kept the _wbMeshAdapter constructor parameter (unused for now) so GameWindow's wire-up doesn't shift. Kept all the real WB pipeline construction in WbMeshAdapter (it's the substrate routing will use in Week 2). Verified flag-on === flag-off post-revert. Plan updated with Adjustment 2 explaining the discovery + correct architectural placement for routing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c49c6edde5
commit
4f318bcbba
2 changed files with 53 additions and 38 deletions
|
|
@ -35,19 +35,16 @@ public sealed unsafe class InstancedMeshRenderer : IDisposable
|
|||
private readonly TextureCache _textures;
|
||||
|
||||
/// <summary>
|
||||
/// Optional WB adapter. When non-null and <see cref="WbFoundationFlag.IsEnabled"/>,
|
||||
/// <see cref="EnsureUploaded"/> hands the GfxObj ref to the WB pipeline instead of
|
||||
/// uploading into our own VAO pool. The draw loop skips sentinel entries — Task 22's
|
||||
/// WbDrawDispatcher will eventually draw them.
|
||||
/// Optional WB adapter. Held but currently unused — Phase N.4 Adjustment 2
|
||||
/// (2026-05-08) reverted Task 9's renderer-level routing. Tier-routing decisions
|
||||
/// (atlas vs per-instance) belong at the spawn-callback layer (Task 11
|
||||
/// LandblockSpawnAdapter for atlas-tier; Task 17 EntitySpawnAdapter for
|
||||
/// per-instance), not in the renderer which is intentionally tier-blind. The
|
||||
/// constructor parameter is preserved so GameWindow's wire-up doesn't shift
|
||||
/// when later tasks need adapter access.
|
||||
/// </summary>
|
||||
private readonly WbMeshAdapter? _wbMeshAdapter;
|
||||
|
||||
// Sentinel: a GfxObj that has been handed to the WB pipeline gets this list
|
||||
// stored in _gpuByGfxObj. The Draw loop recognises it by reference identity
|
||||
// (object.ReferenceEquals) and skips it — no legacy VAO draw for WB-managed
|
||||
// objects until Task 22 wires up WbDrawDispatcher.
|
||||
private static readonly List<SubMeshGpu> WbManagedSentinel = new(0);
|
||||
|
||||
// One GPU bundle per unique GfxObj id. Each GfxObj can have multiple sub-meshes.
|
||||
private readonly Dictionary<uint, List<SubMeshGpu>> _gpuByGfxObj = new();
|
||||
|
||||
|
|
@ -100,17 +97,11 @@ public sealed unsafe class InstancedMeshRenderer : IDisposable
|
|||
if (_gpuByGfxObj.ContainsKey(gfxObjId))
|
||||
return;
|
||||
|
||||
// Phase N.4 Task 9: when the WB foundation flag is on and we have an
|
||||
// adapter, hand this GfxObj to the WB pipeline instead of uploading our
|
||||
// own VAO. The sentinel entry marks "this GfxObj lives in WB now" so the
|
||||
// draw loop knows to skip it. Task 22's WbDrawDispatcher will draw them.
|
||||
if (WbFoundationFlag.IsEnabled && _wbMeshAdapter is not null)
|
||||
{
|
||||
_wbMeshAdapter.IncrementRefCount(gfxObjId);
|
||||
_gpuByGfxObj[gfxObjId] = WbManagedSentinel;
|
||||
return;
|
||||
}
|
||||
|
||||
// Phase N.4 Adjustment 2 (2026-05-08): renderer is tier-blind. Tier-routing
|
||||
// (atlas vs per-instance) lives at the spawn-callback layer (Tasks 11 + 17),
|
||||
// not here. Smoke-test of the original Task 9 routing showed it caught
|
||||
// characters / NPCs (server-spawned, per-instance tier) along with static
|
||||
// scenery, because EnsureUploaded is called from both spawn paths.
|
||||
var list = new List<SubMeshGpu>(subMeshes.Count);
|
||||
foreach (var sm in subMeshes)
|
||||
list.Add(UploadSubMesh(sm));
|
||||
|
|
@ -245,11 +236,6 @@ public sealed unsafe class InstancedMeshRenderer : IDisposable
|
|||
if (!_gpuByGfxObj.TryGetValue(key.GfxObjId, out var subMeshes))
|
||||
continue;
|
||||
|
||||
// WB-managed GfxObjs have a sentinel entry; Task 22 (WbDrawDispatcher)
|
||||
// will draw them. Skip here to avoid drawing with stale/null VAO data.
|
||||
if (object.ReferenceEquals(subMeshes, WbManagedSentinel))
|
||||
continue;
|
||||
|
||||
bool hasOpaqueSubMesh = false;
|
||||
foreach (var sub in subMeshes)
|
||||
{
|
||||
|
|
@ -325,10 +311,6 @@ public sealed unsafe class InstancedMeshRenderer : IDisposable
|
|||
if (!_gpuByGfxObj.TryGetValue(key.GfxObjId, out var subMeshes))
|
||||
continue;
|
||||
|
||||
// WB-managed GfxObjs — skip; Task 22 will draw them.
|
||||
if (object.ReferenceEquals(subMeshes, WbManagedSentinel))
|
||||
continue;
|
||||
|
||||
bool hasTranslucentSubMesh = false;
|
||||
foreach (var sub in subMeshes)
|
||||
{
|
||||
|
|
@ -458,9 +440,6 @@ public sealed unsafe class InstancedMeshRenderer : IDisposable
|
|||
{
|
||||
if (!_gpuByGfxObj.TryGetValue(meshRef.GfxObjId, out var cachedMeshes))
|
||||
continue;
|
||||
// WB-managed GfxObjs don't go through our instance pipeline.
|
||||
if (object.ReferenceEquals(cachedMeshes, WbManagedSentinel))
|
||||
continue;
|
||||
|
||||
var model = meshRef.PartTransform * entityRoot;
|
||||
|
||||
|
|
@ -565,11 +544,6 @@ public sealed unsafe class InstancedMeshRenderer : IDisposable
|
|||
{
|
||||
foreach (var subs in _gpuByGfxObj.Values)
|
||||
{
|
||||
// WB-managed entries use the sentinel — no GL resources to free here;
|
||||
// ObjectMeshManager owns those resources.
|
||||
if (object.ReferenceEquals(subs, WbManagedSentinel))
|
||||
continue;
|
||||
|
||||
foreach (var sub in subs)
|
||||
{
|
||||
_gl.DeleteBuffer(sub.Vbo);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue