wip(assembler): round S8 -- region rebuilds no longer stall admission; result backlog capped

voxel.CoreRegionConcurrentAdmission (default on): tiles independent of the
entering region keep submitting while a region page compiles; pages are
immutable shared_ptr owners so running readers survive eviction. 6 m/s: 11
whole-pass skips -> 0, walkable ring ready at every centre change.
voxel.StreamingResultBacklogCap=256 bounds finished results (slow-apply worst
case 125 -> 76 MB). Spawn unchanged at ~7.7 s: LOD8 is 46% of worker time.
At 60 m/s + teleport the collision ring is outrun (102/113 centres).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-19 09:43:03 +02:00
1 parent 5eb9ee76ff
commit 8440adc742
10 files changed
+1011 -78

No files matched your search

File diff suppressed because it is too large. Load diff
+31
View File
@@ -704,6 +704,11 @@ private:
TArray<FVoxelTileKey>& OutLeavers);
void StartPendingCoreRegionCompile();
void LoadCoreTile(const FVoxelTileKey& Tile, EVoxelTileWorkPriority WorkPriority);
void EnqueueStreamingResult(FChunkResult&& Result);
void RecordStreamingResultDequeued(const FChunkResult& Result);
uint64 GetStreamingResultPayloadBytes(const FChunkResult& Result) const;
int32 GetStreamingResultBacklogCount() const;
bool IsStreamingResultBacklogCapped() const;
void ApplyCoreModification(const FVoxelModification& Modification);
void BuildDesiredTransitionIndex();
float GetActiveVoxelSizeCm() const;
@@ -768,7 +773,20 @@ private:
FVector CoreFallbackCenterLocalCm = FVector::ZeroVector;
bool bCoreRegionCompilePending = false;
TArray<FVoxelTileKey> PendingCoreRegionTiles;
TSet<FVoxelTileKey> PendingCoreRegionTileSet;
TArray<FVoxelTileKey> PendingCoreRetainedTiles;
TSet<FVoxelTileKey> CoreRegionCompileTilesInFlight;
FIntVector LastCoreRegionRequestCenter = FIntVector(MAX_int32, MAX_int32, MAX_int32);
FIntVector PendingCoreRegionRequestCenter = FIntVector::ZeroValue;
FIntVector ActiveCoreRegionCompileCenter = FIntVector::ZeroValue;
bool bHasLastCoreRegionRequestCenter = false;
double CoreRegionPendingSinceSeconds = 0.0;
double ActiveCoreRegionCompileStartSeconds = 0.0;
uint64 ActiveCoreRegionCompileStartCycles = 0;
uint64 CoreRegionIndependentSubmissions = 0;
uint64 CoreRegionDependentDeclines = 0;
int32 CoreRegionCompileRequestSerial = 0;
int32 ActiveCoreRegionCompileRequestSerial = 0;
public:
@@ -1098,6 +1116,16 @@ public:
TQueue<FChunkResult, EQueueMode::Mpsc> EditedProcessQueue;
TQueue<FChunkResult, EQueueMode::Mpsc> NearProcessQueue;
TQueue<FChunkResult, EQueueMode::Mpsc> ProcessQueue;
// The cap counts completed MPSC results plus admitted tile tasks, so a slow game-thread apply
// cannot accumulate an unbounded payload queue while completed work never consumes worker slots.
// Le plafond compte les resultats MPSC et les taches admises; un apply lent ne peut donc pas
// accumuler sans limite, et les resultats termines ne reprennent pas de slot worker.
std::atomic<int32> QueuedStreamingResultCount{0};
std::atomic<uint64> QueuedStreamingResultBytes{0};
std::atomic<int32> PeakQueuedStreamingResultCount{0};
std::atomic<uint64> PeakQueuedStreamingResultBytes{0};
std::atomic<int32> ActiveTileTaskCount{0};
std::atomic<uint64> StreamingResultBacklogCapStops{0};
// Keys stay pending from task submission until the game thread applies the result; completed results can wait here.
// Les cles restent en attente de la soumission jusqu'a l'application sur le thread de jeu ; les resultats termines y attendent.
TSet<FVoxelTileKey> PendingTiles;
@@ -1302,6 +1330,9 @@ public:
float HeadlessStreamingTestSpeedCmPerSecond = 0.0f;
float HeadlessStreamingTestStartSeconds = 0.0f;
float HeadlessStreamingTestExitSeconds = 0.0f;
float HeadlessStreamingTestTeleportAtSeconds = 0.0f;
float HeadlessStreamingTestTeleportDistanceCm = 0.0f;
bool bHeadlessStreamingTestTeleportDone = false;
FVector HeadlessStreamingTestDirection = FVector::XAxisVector;
FVector HeadlessStreamingTestLastActualPosition = FVector::ZeroVector;
double HeadlessStreamingTestBeginSeconds = 0.0;