fix(render): #105 white indoor walls — restore WB's per-frame staged-texture flush dropped in the N.4/O-T4 extraction
Root cause: TextureAtlasManager.AddTexture only STAGES texture content (PBO write + ManagedGLTextureArray._pendingUpdates); the actual TexSubImage3D copies + mipmap regeneration happen in ProcessDirtyUpdates, which WB drives once per frame via ObjectMeshManager.GenerateMipmaps() from its render loop (WB GameScene.cs:975, just before the opaque pass). GameScene is the file we replaced with GameWindow, so the call site was silently dropped — staged updates only reached the GPU as a side effect of PBO growth (UpdateLayerInternal flushes pending updates before orphaning the PBO). Every layer staged after an array's LAST growth kept undefined TexStorage3D content behind a valid, resident bindless sampler handle: white/garbage walls, zh==0, dat tripwires silent — exactly the #105 signature. Only ObjectRenderBatch.BindlessTextureHandle consumers are affected (EnvCellRenderer cell shells = indoor walls); entities resolve via TextureCache (immediate TexImage2D) and terrain via TerrainAtlas (immediate GenerateMipmap), which is why only indoor walls ever struck. Fix: WbMeshAdapter.Tick() now calls _meshManager.GenerateMipmaps() after the staged-upload drain — Tick runs before all draw passes (GameWindow OnRender), the exact WB-equivalent position. Evidence (ACDREAM_PROBE_TEXFLUSH=1 apparatus, kept env-gated): - pre-fix (texflush-prefix.log): pending updates climb 0->48->...->142 and park at 126 across 34/34 atlas arrays at standstill, forever (19 heartbeats); brief dips only at PBO-growth crossings — the broken contract live. - post-fix (texflush-postfix.log): every line after=0 — staged updates drain the same frame, all 34 arrays clean. Intermittency explained: background decode-completion order shuffles which textures land in the never-flushed tail; whether a visible wall samples one is per-run luck. Also explains the #110 correlation: znear=0.1 makes close-up geometry newly visible -> more prepare/upload pressure indoors -> bigger tail -> higher strike probability. The near plane is mechanism-innocent (re-land follows as its own commit). Baseline maintained: App 223 / UI 420 / Net 294 / Core 1377 green + 4 pre-existing #99-era failures + 1 skip; CornerFloodReplayTests (5) and CameraCornerSealReplayTests (2) gates green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
5d63038b61
commit
c78720127a
4 changed files with 92 additions and 0 deletions
|
|
@ -301,6 +301,23 @@ namespace AcDream.App.Rendering.Wb {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// #105 diagnostic: counts staged-but-unflushed texture layer updates across all
|
||||
/// shared atlases (see <see cref="ManagedGLTextureArray.PendingUpdateCount"/>).
|
||||
/// Render thread only — <c>_globalAtlases</c> is render-thread-owned.
|
||||
/// </summary>
|
||||
public (int PendingUpdates, int ArraysWithPending, int TotalArrays) GetPendingTextureUpdateStats() {
|
||||
int pending = 0, arraysWith = 0, total = 0;
|
||||
foreach (var atlasList in _globalAtlases.Values) {
|
||||
foreach (var atlas in atlasList) {
|
||||
total++;
|
||||
int p = atlas.TextureArray.PendingUpdateCount;
|
||||
if (p > 0) { arraysWith++; pending += p; }
|
||||
}
|
||||
}
|
||||
return (pending, arraysWith, total);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrement reference count and unload GPU resources if no longer needed.
|
||||
/// </summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue