fix(render): apply retail marker admission to the walk

This commit is contained in:
Erik 2026-08-31 04:31:22 +02:00
parent a40a57b9b3
commit 78547718c7
4 changed files with 32 additions and 0 deletions

View file

@ -1270,6 +1270,9 @@ public sealed partial class WbDrawDispatcher
// directly", correct for the non-Setup flat-MeshRef caller below. // directly", correct for the non-Setup flat-MeshRef caller below.
bool? entityHasCutoutSubsetOverride = null) bool? entityHasCutoutSubsetOverride = null)
{ {
if (_meshAdapter.IsRuntimeHiddenMarker(meshRef.GfxObjId))
return;
bool entityHasCutoutSubset = entityHasCutoutSubsetOverride ?? renderData.HasCutoutSubset; bool entityHasCutoutSubset = entityHasCutoutSubsetOverride ?? renderData.HasCutoutSubset;
for (int batchIndex = 0; for (int batchIndex = 0;
batchIndex < renderData.Batches.Count; batchIndex < renderData.Batches.Count;

View file

@ -223,6 +223,9 @@ public sealed partial class WbDrawDispatcher
for (int partIndex = 0; partIndex < meshRefs.Count; partIndex++) for (int partIndex = 0; partIndex < meshRefs.Count; partIndex++)
{ {
MeshRef meshRef = meshRefs[partIndex]; MeshRef meshRef = meshRefs[partIndex];
if (_meshAdapter.IsRuntimeHiddenMarker(meshRef.GfxObjId))
continue;
ObjectRenderData? renderData = _meshAdapter.TryGetRenderData(meshRef.GfxObjId); ObjectRenderData? renderData = _meshAdapter.TryGetRenderData(meshRef.GfxObjId);
if (renderData is null) if (renderData is null)
{ {
@ -246,6 +249,9 @@ public sealed partial class WbDrawDispatcher
for (int setupPartIndex = 0; setupPartIndex < renderData.SetupParts.Count; setupPartIndex++) for (int setupPartIndex = 0; setupPartIndex < renderData.SetupParts.Count; setupPartIndex++)
{ {
(ulong gfxObjId, Matrix4x4 partTransform) = renderData.SetupParts[setupPartIndex]; (ulong gfxObjId, Matrix4x4 partTransform) = renderData.SetupParts[setupPartIndex];
if (_meshAdapter.IsRuntimeHiddenMarker((uint)gfxObjId))
continue;
ObjectRenderData? partData = _meshAdapter.TryGetRenderData(gfxObjId); ObjectRenderData? partData = _meshAdapter.TryGetRenderData(gfxObjId);
if (partData is null) if (partData is null)
{ {

View file

@ -3314,6 +3314,9 @@ public sealed partial class WbDrawDispatcher : IDisposable
// a non-Setup single-mesh entity (see the flat MeshRef call site). // a non-Setup single-mesh entity (see the flat MeshRef call site).
bool? entityHasCutoutSubsetOverride = null) bool? entityHasCutoutSubsetOverride = null)
{ {
if (_meshAdapter.IsRuntimeHiddenMarker(meshRef.GfxObjId))
return true;
bool entityHasCutoutSubset = entityHasCutoutSubsetOverride ?? renderData.HasCutoutSubset; bool entityHasCutoutSubset = entityHasCutoutSubsetOverride ?? renderData.HasCutoutSubset;
bool allTexturesReady = true; bool allTexturesReady = true;
for (int batchIdx = 0; batchIdx < renderData.Batches.Count; batchIdx++) for (int batchIdx = 0; batchIdx < renderData.Batches.Count; batchIdx++)

View file

@ -49,6 +49,7 @@ public sealed class WbMeshAdapter
private readonly IMeshPipelineDevice? _graphicsDevice; private readonly IMeshPipelineDevice? _graphicsDevice;
private readonly ObjectMeshManager? _meshManager; private readonly ObjectMeshManager? _meshManager;
private readonly AcDream.App.Rendering.IGpuResourceRetirementQueue? _resourceRetirement; private readonly AcDream.App.Rendering.IGpuResourceRetirementQueue? _resourceRetirement;
private readonly Func<uint, bool> _runtimeHiddenMarker;
private readonly IPreparedAssetSource? _ownedPreparedAssets; private readonly IPreparedAssetSource? _ownedPreparedAssets;
private readonly MeshUploadFrameBudget _ordinaryUploadBudget = private readonly MeshUploadFrameBudget _ordinaryUploadBudget =
CreateUploadBudget(MaximumUploadsPerFrame); CreateUploadBudget(MaximumUploadsPerFrame);
@ -83,6 +84,15 @@ public sealed class WbMeshAdapter
internal (int Count, long Bytes) CpuMeshCacheDiagnostics => internal (int Count, long Bytes) CpuMeshCacheDiagnostics =>
_meshManager?.CpuCacheDiagnostics ?? default; _meshManager?.CpuCacheDiagnostics ?? default;
/// <summary>
/// Retail's statically decidable degrade-to-nothing admission. Marker
/// meshes whose only real level ends at distance zero never reach a draw
/// at runtime; the walk classifier and shadow caster share this exact
/// memoized predicate.
/// </summary>
internal bool IsRuntimeHiddenMarker(uint gfxObjId) =>
_runtimeHiddenMarker(gfxObjId);
internal void SetDestinationRevealUploadPriority(bool enabled) => internal void SetDestinationRevealUploadPriority(bool enabled) =>
_destinationRevealUploadPriority = enabled; _destinationRevealUploadPriority = enabled;
@ -182,6 +192,15 @@ public sealed class WbMeshAdapter
ArgumentNullException.ThrowIfNull(budgets); ArgumentNullException.ThrowIfNull(budgets);
_resourceRetirement = resourceRetirement; _resourceRetirement = resourceRetirement;
var hiddenMarkerMemo =
new System.Collections.Concurrent.ConcurrentDictionary<uint, bool>();
_runtimeHiddenMarker = gfxObjId =>
hiddenMarkerMemo.GetOrAdd(
gfxObjId,
static (id, source) =>
AcDream.Core.Meshing.GfxObjDegradeResolver
.IsRuntimeHiddenMarker(source, id),
dats);
var resources = new AcDream.App.Rendering.ResourceCleanupGroup(); var resources = new AcDream.App.Rendering.ResourceCleanupGroup();
IMeshPipelineDevice? graphicsDevice = null; IMeshPipelineDevice? graphicsDevice = null;
IPreparedAssetSource? resolvedPreparedAssets = preparedAssets; IPreparedAssetSource? resolvedPreparedAssets = preparedAssets;
@ -295,6 +314,7 @@ public sealed class WbMeshAdapter
// Uninitialized constructor — only for tests / flag-off cases where // Uninitialized constructor — only for tests / flag-off cases where
// the caller wants a Dispose-safe no-op instance. // the caller wants a Dispose-safe no-op instance.
_isUninitialized = true; _isUninitialized = true;
_runtimeHiddenMarker = static _ => false;
} }
/// <summary>Test/init helper — produces a Dispose-safe instance with no /// <summary>Test/init helper — produces a Dispose-safe instance with no