wip(assembler): round S5 -- streaming gates + trace; coarse-first order kept opt-in (no win)

Walkable/enclosed/refined gates defined; JSONL trace joins request, worker start,
build/apply and discards. Coarse-first + dynamic near reserve behind
voxel.StreamingCoarseFirst / voxel.StreamingDynamicNearReserve (default 0 =
S4 order): matched runs showed no walkability or full-view win and slower
LOD0/1 refinement. Instruments settled: 3.1 s standalone reproduced (16.7 s was
another generation route); black early captures were clear-only frames.
Hashes equal S4; Core-off, M2, SurfaceWorld/FloatingIslands BuildHost pass.

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 04:42:41 +02:00
1 parent 9d3c50ca95
commit c0596c5f24
32 files changed
+1049 -65

No files matched your search

+117 -4
View File
@@ -1635,6 +1635,9 @@ namespace
uint64 GpuFarProtectedThinSamples=0,GpuFarProtectedSolidSamples=0;
uint64 GpuFarProtectedSealSamples=0,GpuFarProtectedOverlaySamples=0;
uint64 PresentCallCount=0;
uint64 LastCapturedFrameOrdinal=0,LastCapturedPresentOrdinal=0;
int32 LastCapturedSequenceIndex=-1;
bool bLastCapturedSequenceIsFlight=false;
uint64 StartupNonBlockingPresentCalls=0,StartupNonBlockingPresentSkips=0;
double GpuFarGpuDispatchMs=0.0;
double GpuFarGpuDispatchMaxMs=0.0;
@@ -1692,6 +1695,10 @@ namespace
float FlightSpeedMps=16.0f;
std::string FlightCaptureSequencePrefix;
int32 FlightCaptureSequenceIndex=0;
int32 FlightCaptureCloseIndex=-1;
std::string SpawnCaptureSequencePrefix;
int32 SpawnCaptureSequenceIndex=0;
bool bQuitAfterSpawnCaptures=false,bSpawnCaptureClosePosted=false;
bool bFlightStarted=false;
bool bFlightFinished=false;
bool bFlightClosePosted=false;
@@ -5509,6 +5516,71 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
void CaptureRenderedFrame()
{
auto LogCaptureFrameAudit=[&](const char* Mode,int32 Index,double ElapsedSeconds)
{
std::size_t ReadyTiles=0;
for(const FVoxelTileKey& Key:DesiredTiles)
if(IsRenderedTileReady(Key))++ReadyTiles;
uint64 DrawIndices=0;
uint64 DrawBatches=0;
for(const auto& Pair:StreamingBatches)
{
const FStreamingGpuBatch& Batch=Pair.second;
if(!bShowLevel[Pair.first.Level]
||(CaptureOnlyLod>=0&&Pair.first.Level!=CaptureOnlyLod)
||!Batch.VertexBuffer||!Batch.IndexBuffer||!Batch.IndexCount
||(bDrawOnlyTile&&Batch.DrawOnlyIndexCount==0))continue;
DrawIndices+=bDrawOnlyTile?Batch.DrawOnlyIndexCount:Batch.IndexCount;
++DrawBatches;
}
std::printf("[CaptureFrameAudit] mode=%s index=%d elapsed_s=%.3f capture_phase=pre_present frame=%llu presents_completed=%llu next_present=%llu resident_tiles=%zu/%zu resident_meshes=%zu draw_batches=%llu draw_triangles=%llu queued_upload_batches=%zu gpu_far_tiles=%zu\n",
Mode,Index,ElapsedSeconds,
static_cast<unsigned long long>(ColdTimelineFrame()),
static_cast<unsigned long long>(PresentCallCount),
static_cast<unsigned long long>(PresentCallCount+1),
ReadyTiles,DesiredTiles.size(),ResidentTiles.size(),
static_cast<unsigned long long>(DrawBatches),
static_cast<unsigned long long>(DrawIndices/3),DirtyBatchSet.size(),GpuFarTiles.size());
std::fflush(stdout);
};
// Capturer apres le rendu, avant le present imminent du meme frame.
// Capture after rendering, before this same frame's imminent present.
if(!SpawnCaptureSequencePrefix.empty()&&SpawnCaptureSequenceIndex<3
&&GenerationStart.time_since_epoch().count()!=0)
{
static constexpr std::array<double,3> CaptureSeconds={0.5,1.0,2.0};
const double SpawnElapsed=std::chrono::duration<double>(
std::chrono::steady_clock::now()-GenerationStart).count();
if(SpawnElapsed>=CaptureSeconds[SpawnCaptureSequenceIndex])
{
LogCaptureFrameAudit("spawn",SpawnCaptureSequenceIndex,SpawnElapsed);
char Suffix[16]{};
std::snprintf(Suffix,sizeof(Suffix),"_%02d.png",SpawnCaptureSequenceIndex);
const std::string Path=SpawnCaptureSequencePrefix+Suffix;
if(SaveBackBufferPng(Path))
{
LastCapturedFrameOrdinal=ColdTimelineFrame();
LastCapturedPresentOrdinal=PresentCallCount+1;
LastCapturedSequenceIndex=SpawnCaptureSequenceIndex;
bLastCapturedSequenceIsFlight=false;
std::printf("[SpawnSequenceCapture] index=%d elapsed_s=%.3f path=%s\n",
SpawnCaptureSequenceIndex,SpawnElapsed,Path.c_str());
}
else
std::fprintf(stderr,"[SpawnSequenceCapture] index=%d elapsed_s=%.3f failed path=%s\n",
SpawnCaptureSequenceIndex,SpawnElapsed,Path.c_str());
++SpawnCaptureSequenceIndex;
std::fflush(stdout);
if(bQuitAfterSpawnCaptures&&SpawnCaptureSequenceIndex>=3
&&!bSpawnCaptureClosePosted)
{
bSpawnCaptureClosePosted=true;
PostMessageA(Window,WM_CLOSE,0,0);
}
}
}
// Capturer le vol dans la boucle de rendu conserve les transitions LOD.
// Capture the flight inside the render loop to retain LOD transition frames.
if(!FlightCaptureSequencePrefix.empty()&&bFlightStarted)
@@ -5519,17 +5591,30 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
if(FlightCaptureSequenceIndex<static_cast<int32>(CaptureSeconds.size())
&&FlightElapsed>=CaptureSeconds[FlightCaptureSequenceIndex])
{
LogCaptureFrameAudit("flight",FlightCaptureSequenceIndex,FlightElapsed);
char Suffix[16]{};
std::snprintf(Suffix,sizeof(Suffix),"_%02d.png",FlightCaptureSequenceIndex);
const std::string Path=FlightCaptureSequencePrefix+Suffix;
const int32 CapturedIndex=FlightCaptureSequenceIndex;
if(SaveBackBufferPng(Path))
{
LastCapturedFrameOrdinal=ColdTimelineFrame();
LastCapturedPresentOrdinal=PresentCallCount+1;
LastCapturedSequenceIndex=CapturedIndex;
bLastCapturedSequenceIsFlight=true;
std::printf("[FlightSequenceCapture] index=%d elapsed_s=%.3f path=%s\n",
FlightCaptureSequenceIndex,FlightElapsed,Path.c_str());
CapturedIndex,FlightElapsed,Path.c_str());
}
else
std::fprintf(stderr,"[FlightSequenceCapture] index=%d failed path=%s\n",
FlightCaptureSequenceIndex,Path.c_str());
CapturedIndex,Path.c_str());
++FlightCaptureSequenceIndex;
std::fflush(stdout);
if(FlightCaptureCloseIndex==CapturedIndex&&!bFlightClosePosted)
{
bFlightClosePosted=true;
PostMessageA(Window,WM_CLOSE,0,0);
}
}
}
const bool bReadyToCapture=bCaptureAfterClipmap?bInitialClipmapReported:IsFullDetailUploaded();
@@ -5816,7 +5901,6 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
bGpuSkirtDrawAuditReported=true;
std::fflush(stdout);
}
CaptureRenderedFrame();
const bool bHoldFrontBufferForGpuWarmup=bHoldCpuFrameDuringGpuWarmup
&&bCpuReadyFramePresentedBeforeGpu&&bGpuFarEnabled
&&GpuFarTilesSubmitted>0&&!bInitialClipmapReported;
@@ -5864,6 +5948,8 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
std::chrono::duration<double,std::milli>(GpuPumpEnd-CpuPumpEnd).count());
return;
}
const bool bDidPresent=!bGpuFarNoPresent||bDeferGpuUntilCpuFrame;
if(bDidPresent)CaptureRenderedFrame();
const auto BeforePresent=std::chrono::steady_clock::now();
const bool bNonBlockingStartupPresent=bGpuFarEnabled&&!bInitialClipmapReported
&&!bForceBlockingStartupPresent;
@@ -5872,10 +5958,23 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
const auto PresentCallStart=std::chrono::steady_clock::now();
// The CPU-ready frame is the ownership handoff gate for this route.
// Keep that one presentation, then suppress presents while GPU work runs.
const bool bDidPresent=!bGpuFarNoPresent||bDeferGpuUntilCpuFrame;
const HRESULT PresentResult=bDidPresent
?SwapChain->Present(PresentSyncInterval,PresentFlags):S_FALSE;
const auto PresentCallEnd=std::chrono::steady_clock::now();
if(LastCapturedFrameOrdinal==FrameOrdinal)
{
std::printf("[CaptureFramePresentation] mode=%s index=%d frame=%llu present_ordinal=%llu hr=0x%08lx present_called=%d status_succeeded=%d occluded=%d window_visible=%d\n",
bLastCapturedSequenceIsFlight?"flight":"spawn",LastCapturedSequenceIndex,
static_cast<unsigned long long>(LastCapturedFrameOrdinal),
static_cast<unsigned long long>(LastCapturedPresentOrdinal),
static_cast<unsigned long>(PresentResult),
bDidPresent?1:0,SUCCEEDED(PresentResult)?1:0,
PresentResult==DXGI_STATUS_OCCLUDED?1:0,IsWindowVisible(Window)?1:0);
std::fflush(stdout);
LastCapturedFrameOrdinal=0;
LastCapturedPresentOrdinal=0;
LastCapturedSequenceIndex=-1;
}
if(!bDidPresent&&!bGpuFarNoPresentReported)
{
bGpuFarNoPresentReported=true;
@@ -9399,6 +9498,7 @@ int main(int Argc,char** Argv)
std::string WorldAssemblyManifestOutputPath;
bool bStreamBenchmark=false;
bool bStreamPipeline=false;
bool bCoarseFirstStreamOrder=false;
bool bProfileDetailBand=false;
bool bPassageDetailAuditOnly=false;
bool bGridStairAudit=false;
@@ -9423,6 +9523,13 @@ int main(int Argc,char** Argv)
else if(Arg.starts_with("--capture-flight-sequence-prefix="))
App.FlightCaptureSequencePrefix=std::string(
Arg.substr(std::string_view("--capture-flight-sequence-prefix=").size()));
else if(Arg.starts_with("--flight-capture-close-index="))
App.FlightCaptureCloseIndex=std::atoi(
std::string(Arg.substr(std::string_view("--flight-capture-close-index=").size())).c_str());
else if(Arg.starts_with("--capture-spawn-sequence-prefix="))
App.SpawnCaptureSequencePrefix=std::string(
Arg.substr(std::string_view("--capture-spawn-sequence-prefix=").size()));
else if(Arg=="--quit-after-spawn-captures")App.bQuitAfterSpawnCaptures=true;
else if(Arg=="--no-vsync")App.bDisableVSync=true;
else if(Arg.starts_with("--frame-limit="))
{FrameLimitHz=std::clamp(std::atoi(std::string(Arg.substr(14)).c_str()),1,60);bFrameLimitSpecified=true;}
@@ -9521,6 +9628,8 @@ int main(int Argc,char** Argv)
else if(Arg=="--round-tunnels-legacy")
{App.bRoundTunnels=true;App.bRoundTunnelEnhanced=false;}
else if(Arg=="--stream-benchmark")bStreamBenchmark=true;
else if(Arg=="--legacy-stream-order")bCoarseFirstStreamOrder=false;
else if(Arg=="--coarse-first-stream-order")bCoarseFirstStreamOrder=true;
else if(Arg=="--stream-pipeline")
{bStreamPipeline=true;bStreamBenchmark=true;App.bShapeWorld=true;App.bForceGenerate=true;}
else if(Arg=="--edit-benchmark")
@@ -9613,6 +9722,10 @@ int main(int Argc,char** Argv)
}
else if(!Arg.empty()&&Arg.front()!='-')App.DataPath=std::string(Arg);
}
FStandaloneStreamingGenerator::SetCoarseFirstSchedulingEnabled(bCoarseFirstStreamOrder);
std::printf("[StandaloneStreamOrder] mode=%s negative_control=%s\n",
bCoarseFirstStreamOrder?"walkable_coarse_refine":"legacy_distance_lod",
bCoarseFirstStreamOrder?"--legacy-stream-order":"none");
std::printf("[FrameLimiter] target_fps=%d maximum=true vsync=%s source=%s\n",FrameLimitHz,
App.bDisableVSync?"off":"on",bFrameLimitSpecified?"argument":"default");
if(App.bCaptureOnlyTile&&App.bGpuFarEnabled)
+79 -7
View File
@@ -9,6 +9,7 @@
#include <atomic>
#include <bit>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <cstring>
#include <deque>
@@ -409,6 +410,11 @@ namespace StandaloneWorldMesher
class FStandaloneStreamingGenerator
{
public:
static void SetCoarseFirstSchedulingEnabled(bool bEnabled)
{bCoarseFirstSchedulingEnabled.store(bEnabled,std::memory_order_relaxed);}
static bool IsCoarseFirstSchedulingEnabled()
{return bCoarseFirstSchedulingEnabled.load(std::memory_order_relaxed);}
explicit FStandaloneStreamingGenerator(FStandaloneOwnerWorld& InWorld,int32 InWorkerCount=8,
bool bInHashDensity=false,
const FStandaloneMeshCache* InMeshCache=nullptr,
@@ -448,6 +454,7 @@ public:
bStop=false;
}
for(int32 I=0;I<WorkerCount;++I)Workers.emplace_back([this](){WorkerLoop();});
bHasLastCameraPosition=false;TravelDirection=FVector::ZeroVector;
return UpdateDesired(CameraPositionVoxels,ResidentKeys,CrossingIndex);
}
@@ -461,6 +468,7 @@ public:
bStop=false;
}
for(int32 I=0;I<WorkerCount;++I)Workers.emplace_back([this](){WorkerLoop();});
bHasLastCameraPosition=false;TravelDirection=FVector::ZeroVector;
return UpdateDesiredSet(InitialDesired,ResidentKeys,CrossingIndex);
}
@@ -507,6 +515,23 @@ public:
const FVector& CameraPositionVoxels,const std::vector<FVoxelTileKey>& ResidentKeys,
uint64 CrossingIndex=0)
{
if(bHasLastCameraPosition)
{
const FVector Delta=CameraPositionVoxels-LastCameraPositionVoxels;
const double LengthSquared=static_cast<double>(Delta.X)*Delta.X
+static_cast<double>(Delta.Y)*Delta.Y;
if(LengthSquared>1.0e-12)
{
const double InverseLength=1.0/std::sqrt(LengthSquared);
TravelDirection=FVector(static_cast<float>(Delta.X*InverseLength),
static_cast<float>(Delta.Y*InverseLength),0.0f);
}
else TravelDirection=FVector::ZeroVector;
}
else
TravelDirection=FVector::ZeroVector;
LastCameraPositionVoxels=CameraPositionVoxels;
bHasLastCameraPosition=true;
FStandaloneDesiredTileSet NewDesired=StandaloneWorldMesher::BuildDesiredSet(*World,CameraPositionVoxels);
if(CoreWorld)
{
@@ -652,17 +677,60 @@ private:
Stats.CancelledByCrossing.reserve(CancelledByCrossing.size());
for(const auto& Pair:CancelledByCrossing)Stats.CancelledByCrossing.push_back(Pair);
std::vector<VoxelForgeCore::TileKey> Unordered;Unordered.reserve(NewDesired.Tiles.size());
for(const FVoxelTileKey& Key:NewDesired.Tiles)
Unordered.push_back({{Key.Coord.X,Key.Coord.Y,Key.Coord.Z},Key.Level});
const auto Prioritized=VoxelForgeCore::World::prioritizeTiles(Unordered,
{NewDesired.CenterChunk.X,NewDesired.CenterChunk.Y,NewDesired.CenterChunk.Z});
std::vector<FVoxelTileKey> Prioritized=NewDesired.Tiles;
if(IsCoarseFirstSchedulingEnabled())
{
// The local walkable ring leads, the coarse enclosure follows, then target-detail work.
// L'anneau praticable local passe d'abord, puis l'enveloppe grossiere, puis le detail cible.
const int32 FirstCoarseLevel=FMath::Max(2,World->FullResClipLevels);
auto Tier=[&](const FVoxelTileKey& Key)
{
if(Key.Level==0&&std::abs(Key.Coord.X-NewDesired.CenterChunk.X)<=1
&&std::abs(Key.Coord.Y-NewDesired.CenterChunk.Y)<=1
&&std::abs(Key.Coord.Z-NewDesired.CenterChunk.Z)<=1)return 0;
return Key.Level>=FirstCoarseLevel?1:2;
};
auto IsAhead=[&](const FVoxelTileKey& Key)
{
if(TravelDirection.X*TravelDirection.X+TravelDirection.Y*TravelDirection.Y<=1.0e-12f)
return false;
const double Scale=static_cast<double>(1<<Key.Level);
const double OffsetX=(static_cast<double>(Key.Coord.X)+0.5)*Scale-NewDesired.CenterChunk.X;
const double OffsetY=(static_cast<double>(Key.Coord.Y)+0.5)*Scale-NewDesired.CenterChunk.Y;
return OffsetX*TravelDirection.X+OffsetY*TravelDirection.Y>0.0;
};
std::sort(Prioritized.begin(),Prioritized.end(),[&](const FVoxelTileKey& A,const FVoxelTileKey& B)
{
const int32 TierA=Tier(A),TierB=Tier(B);
if(TierA!=TierB)return TierA<TierB;
if(TierA==1&&A.Level!=B.Level)return A.Level>B.Level;
const bool bAheadA=IsAhead(A),bAheadB=IsAhead(B);
if(bAheadA!=bAheadB)return bAheadA;
const double DA=StandaloneWorldMesher::TileDistanceSquaredChunks(A,NewDesired.CenterChunk);
const double DB=StandaloneWorldMesher::TileDistanceSquaredChunks(B,NewDesired.CenterChunk);
if(DA!=DB)return DA<DB;
if(A.Level!=B.Level)return A.Level<B.Level;
if(A.Coord.Z!=B.Coord.Z)return A.Coord.Z<B.Coord.Z;
if(A.Coord.Y!=B.Coord.Y)return A.Coord.Y<B.Coord.Y;
return A.Coord.X<B.Coord.X;
});
}
else
{
std::vector<VoxelForgeCore::TileKey> Unordered;Unordered.reserve(NewDesired.Tiles.size());
for(const FVoxelTileKey& Key:NewDesired.Tiles)
Unordered.push_back({{Key.Coord.X,Key.Coord.Y,Key.Coord.Z},Key.Level});
const auto CorePrioritized=VoxelForgeCore::World::prioritizeTiles(Unordered,
{NewDesired.CenterChunk.X,NewDesired.CenterChunk.Y,NewDesired.CenterChunk.Z});
Prioritized.clear();Prioritized.reserve(CorePrioritized.size());
for(const auto& Key:CorePrioritized)
Prioritized.emplace_back(FIntVector(Key.coordinate.x,Key.coordinate.y,Key.coordinate.z),Key.lod);
}
std::unordered_map<FVoxelTileKey,size_t,FStandaloneTileKeyHash> PriorityRanks;
PriorityRanks.reserve(Prioritized.size()*2+1);
for(size_t Rank=0;Rank<Prioritized.size();++Rank)
{
const auto& Key=Prioritized[Rank];
PriorityRanks.emplace(FVoxelTileKey(FIntVector(Key.coordinate.x,Key.coordinate.y,Key.coordinate.z),Key.lod),Rank);
PriorityRanks.emplace(Prioritized[Rank],Rank);
}
for(FStandaloneTileJob& Job:Queue)Job.PriorityRank=PriorityRanks.at(Job.Key);
@@ -884,6 +952,10 @@ private:
TimelineMilliseconds(Started),TimelineMilliseconds(Finished),WorkerMs);
}
FStandaloneOwnerWorld* World=nullptr;
inline static std::atomic<bool> bCoarseFirstSchedulingEnabled{true};
FVector LastCameraPositionVoxels=FVector::ZeroVector;
FVector TravelDirection=FVector::ZeroVector;
bool bHasLastCameraPosition=false;
int32 WorkerCount=8;
bool bHashDensity=false;
const FStandaloneMeshCache* MeshCache=nullptr;