fix(streaming): prepare quiesced destination entities
Separate loaded spatial residency from the world presentation gate so destination live objects acquire mesh owners behind portal space while drawing and simulation stay quiesced. Prevent unowned CPU-cache hits from recreating stale GPU staging work. Co-authored-by: Erik Nilsson <erikn@users.noreply.github.com>
This commit is contained in:
parent
e991eeca34
commit
91e82c3c68
6 changed files with 142 additions and 23 deletions
|
|
@ -8,6 +8,7 @@ internal enum MeshStageResult
|
|||
Staged,
|
||||
AlreadyStaged,
|
||||
HighWater,
|
||||
NotOwned,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -282,7 +283,7 @@ internal sealed class CpuMeshUploadCache
|
|||
// review). Read via Stats from the diagnostics/checkpoint thread
|
||||
// without taking _data's lock, so plain fields with Interlocked
|
||||
// increments — the 4 concurrent preparation workers all consult
|
||||
// TryGetAndStage.
|
||||
// TryGetAndStageOwned.
|
||||
private long _hits;
|
||||
private long _misses;
|
||||
private long _evictions;
|
||||
|
|
@ -307,12 +308,15 @@ internal sealed class CpuMeshUploadCache
|
|||
internal int Capacity => _capacity;
|
||||
internal long ByteCapacity => _byteCapacity;
|
||||
|
||||
public bool TryGetAndStage(
|
||||
public bool TryGetAndStageOwned(
|
||||
ulong id,
|
||||
MeshUploadStagingQueue staging,
|
||||
MeshOwnershipCounter ownership,
|
||||
out ObjectMeshData? data,
|
||||
out MeshStageResult stageResult)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(staging);
|
||||
ArgumentNullException.ThrowIfNull(ownership);
|
||||
lock (_data)
|
||||
{
|
||||
if (!_data.TryGetValue(id, out data)) {
|
||||
|
|
@ -323,7 +327,13 @@ internal sealed class CpuMeshUploadCache
|
|||
Interlocked.Increment(ref _hits);
|
||||
_lru.Remove(id);
|
||||
_lru.AddLast(id);
|
||||
stageResult = staging.TryStage(data);
|
||||
// Prepared payload residency is deliberately independent from
|
||||
// live render ownership. A point-of-use lookup from a retiring
|
||||
// world generation must never recreate GPU staging work after
|
||||
// that generation released its final mesh reference.
|
||||
stageResult = ownership.IsOwned(id)
|
||||
? staging.TryStage(data)
|
||||
: MeshStageResult.NotOwned;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -876,9 +876,10 @@ namespace AcDream.App.Rendering.Wb
|
|||
}
|
||||
|
||||
ObjectMeshData? deferredCachedData = null;
|
||||
if (_cpuMeshCache.TryGetAndStage(
|
||||
if (_cpuMeshCache.TryGetAndStageOwned(
|
||||
geomId,
|
||||
_stagedMeshData,
|
||||
_ownership,
|
||||
out ObjectMeshData? cachedData,
|
||||
out MeshStageResult cacheStage))
|
||||
{
|
||||
|
|
@ -936,9 +937,10 @@ namespace AcDream.App.Rendering.Wb
|
|||
_terminalPreparationFailures.Remove(id);
|
||||
|
||||
ObjectMeshData? deferredCachedData = null;
|
||||
if (_cpuMeshCache.TryGetAndStage(
|
||||
if (_cpuMeshCache.TryGetAndStageOwned(
|
||||
id,
|
||||
_stagedMeshData,
|
||||
_ownership,
|
||||
out ObjectMeshData? cachedData,
|
||||
out MeshStageResult cacheStage))
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue