wip(standalone): speed round -- interrupted by a PC hard reset at 10:16 (Kernel-Power 41)

Verified before the reset (density + full mesh hashes equal at 1/8/16 workers, routes 5642/5642,
look audits green):
- merged field lookups, parallel mask merge, compact inline spatial bins, line-local relief hash
  cache, lattice-specific mesher entry, fused sign+magnitude evaluation, far connectors as one
  capsule each (181,836 -> 16,491 far primitives).
- crater edit (sphere+box+capsule, one transaction across LOD0/1): 15-27 ms; player 3x3x3
  neighbourhood meshes ready ~18 ms after streaming starts.
NOT yet verified (in the tree, unhashed): standalone-only skips of UV/colour arrays and of the
ceiling/ground material grouping (best cold whole view 0.958 s @16 workers) and a far-bin reserve
tweak. Those skips drop data the plugin's materials may need: not a game-path win as-is.

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-04 12:18:48 +02:00
1 parent 97c0455939
commit ee5b05b357
16 files changed
+1011 -156

No files matched your search

+149 -17
View File
@@ -670,7 +670,8 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
}
if(!FineTiles){Error="no full-detail tiles are available for shape compilation";return false;}
ShapeWorld=std::make_unique<FStandaloneShapeWorld>();
if(!ShapeWorld->Build(*World,Min,Max,ClipMin,ClipMax,WorkerCount,ShapeDetailVariant,bIncludeFarWorld,Error))
if(!ShapeWorld->Build(*World,Min,Max,ClipMin,ClipMax,WorkerCount,
ShapeDetailVariant,bIncludeFarWorld,Error))
{ShapeWorld.reset();return false;}
FStandaloneShapeWorldAccess::SetActive(ShapeWorld.get());
bFarShapeStagePending=bShapeWorld&&!ShapeWorld->HasFarWorld();
@@ -1721,11 +1722,24 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
Desired.Tiles.begin(),Desired.Tiles.end(),[&](const FVoxelTileKey& Tile)
{return Tile.Level<World.FullResClipLevels;}));
std::array<std::vector<FHashedTile>,MaxLevels+1> HashRows;
std::array<std::vector<FHashedTile>,MaxLevels+1> MeshHashRows;
std::array<uint64,MaxLevels+1> SamplesByLevel{};
std::array<uint64,MaxLevels+1> VerticesByLevel{};
std::array<uint64,MaxLevels+1> IndicesByLevel{};
std::array<uint64,MaxLevels+1> TilesByLevel{};
std::array<double,MaxLevels+1> WorkerSecondsByLevel{};
std::array<double,MaxLevels+1> FirstCompletionByLevel{};
std::array<double,MaxLevels+1> LastCompletionByLevel{};
std::array<uint64,MaxLevels+1> OutputBytesByLevel{};
FirstCompletionByLevel.fill(std::numeric_limits<double>::infinity());
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> PlayerNeighborhoodTiles;
for(const FVoxelTileKey& Tile:Desired.Tiles)
if(Tile.Level==0&&std::abs(Tile.Coord.X-Desired.CenterChunk.X)<=1
&&std::abs(Tile.Coord.Y-Desired.CenterChunk.Y)<=1
&&std::abs(Tile.Coord.Z-Desired.CenterChunk.Z)<=1)
PlayerNeighborhoodTiles.insert(Tile);
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> PlayerNeighborhoodReady;
auto PlayerNeighborhoodCompleted=std::chrono::steady_clock::time_point{};
std::vector<FStandaloneCpuTile> CacheTiles;
if(!BakeCachePath.empty())CacheTiles.reserve(Desired.Tiles.size());
const auto Start=std::chrono::steady_clock::now();
@@ -1758,6 +1772,12 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
{
++Finished;
const int32 Level=Tile.Key.Level;
if(PlayerNeighborhoodTiles.contains(Tile.Key))
{
PlayerNeighborhoodReady.insert(Tile.Key);
if(PlayerNeighborhoodReady.size()==PlayerNeighborhoodTiles.size())
PlayerNeighborhoodCompleted=Tile.CompletedAt;
}
if(Level>=0&&Level<=MaxLevels)
{
SamplesByLevel[Level]+=Tile.DensitySamples;
@@ -1765,7 +1785,13 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
IndicesByLevel[Level]+=Tile.Indices.size();
++TilesByLevel[Level];
WorkerSecondsByLevel[Level]+=Tile.WorkerSeconds;
const double CompletedSeconds=std::chrono::duration<double>(Tile.CompletedAt-Start).count();
FirstCompletionByLevel[Level]=std::min(FirstCompletionByLevel[Level],CompletedSeconds);
LastCompletionByLevel[Level]=std::max(LastCompletionByLevel[Level],CompletedSeconds);
OutputBytesByLevel[Level]+=static_cast<uint64>(Tile.Vertices.capacity())*sizeof(FStandaloneCpuVertex)
+static_cast<uint64>(Tile.Indices.capacity())*sizeof(uint32);
if(Tile.bHasDensityHash)HashRows[Level].push_back({Tile.Key,Tile.DensityHash});
if(Tile.bHasMeshHash)MeshHashRows[Level].push_back({Tile.Key,Tile.MeshHash});
}
if(Level<World.FullResClipLevels)++FullDetailFinished;
if(bShardAudit&&Level==0)
@@ -1793,12 +1819,17 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
FullDetailSeconds=std::chrono::duration<double>(
std::chrono::steady_clock::now()-Start).count();
std::vector<FHashedTile> FullRows;
std::vector<FHashedTile> FullMeshRows;
for(int32 Level=0;Level<World.FullResClipLevels&&Level<=MaxLevels;++Level)
{
FullRows.insert(FullRows.end(),HashRows[Level].begin(),HashRows[Level].end());
FullMeshRows.insert(FullMeshRows.end(),MeshHashRows[Level].begin(),MeshHashRows[Level].end());
}
if(bHashDensity||!BakeCachePath.empty())
std::printf("[StreamFullDetail] wall=%.3fs generated=%d/%d resident_tiles_cpu_only=1 density_hash=0x%016llx\n",
std::printf("[StreamFullDetail] wall=%.3fs generated=%d/%d resident_tiles_cpu_only=1 density_hash=0x%016llx mesh_hash=0x%016llx\n",
FullDetailSeconds,FullDetailFinished,FullDetailExpected,
static_cast<unsigned long long>(HashTileRows(FullRows)));
static_cast<unsigned long long>(HashTileRows(FullRows)),
static_cast<unsigned long long>(HashTileRows(FullMeshRows)));
else
std::printf("[StreamFullDetail] wall=%.3fs generated=%d/%d resident_tiles_cpu_only=1 hash=off\n",
FullDetailSeconds,FullDetailFinished,FullDetailExpected);
@@ -1807,18 +1838,34 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
}
const double FullClipSeconds=std::chrono::duration<double>(
std::chrono::steady_clock::now()-Start).count();
std::vector<FHashedTile> AllRows;
if(bHashDensity||!BakeCachePath.empty())
for(auto& LevelRows:HashRows)AllRows.insert(AllRows.end(),LevelRows.begin(),LevelRows.end());
if(bHashDensity||!BakeCachePath.empty())
std::printf("[StreamFullClipmap] wall=%.3fs generated=%d/%d worker_sum=%.3fs tiles=%d density_hash=0x%016llx\n",
FullClipSeconds,Finished,DesiredTotal,
std::accumulate(WorkerSecondsByLevel.begin(),WorkerSecondsByLevel.end(),0.0),
DesiredTotal,static_cast<unsigned long long>(HashTileRows(AllRows)));
if(!PlayerNeighborhoodTiles.empty()&&PlayerNeighborhoodReady.size()==PlayerNeighborhoodTiles.size())
std::printf("[PlayerNeighborhood] lod0_tiles=%zu/%zu mesh_ready=%.3fs collision_cook=unavailable_in_standalone\n",
PlayerNeighborhoodReady.size(),PlayerNeighborhoodTiles.size(),
std::chrono::duration<double>(PlayerNeighborhoodCompleted-Start).count());
else
std::printf("[StreamFullClipmap] wall=%.3fs generated=%d/%d worker_sum=%.3fs tiles=%d hash=off\n",
FullClipSeconds,Finished,DesiredTotal,
std::accumulate(WorkerSecondsByLevel.begin(),WorkerSecondsByLevel.end(),0.0),DesiredTotal);
std::printf("[PlayerNeighborhood] lod0_tiles=%zu/%zu mesh_ready=missing collision_cook=unavailable_in_standalone\n",
PlayerNeighborhoodReady.size(),PlayerNeighborhoodTiles.size());
const double TotalWorkerSeconds=std::accumulate(WorkerSecondsByLevel.begin(),WorkerSecondsByLevel.end(),0.0);
const double WorkerBusyPercent=100.0*TotalWorkerSeconds
/(std::max(1,WorkerCount)*std::max(0.001,FullClipSeconds));
std::vector<FHashedTile> AllRows;
std::vector<FHashedTile> AllMeshRows;
if(bHashDensity||!BakeCachePath.empty())
for(int32 Level=0;Level<=MaxLevels;++Level)
{
AllRows.insert(AllRows.end(),HashRows[Level].begin(),HashRows[Level].end());
AllMeshRows.insert(AllMeshRows.end(),MeshHashRows[Level].begin(),MeshHashRows[Level].end());
}
if(bHashDensity||!BakeCachePath.empty())
std::printf("[StreamFullClipmap] wall=%.3fs generated=%d/%d worker_sum=%.3fs worker_busy=%.1f%% worker_idle=%.1f%% tiles=%d density_hash=0x%016llx mesh_hash=0x%016llx\n",
FullClipSeconds,Finished,DesiredTotal,TotalWorkerSeconds,WorkerBusyPercent,
std::max(0.0,100.0-WorkerBusyPercent),
DesiredTotal,static_cast<unsigned long long>(HashTileRows(AllRows)),
static_cast<unsigned long long>(HashTileRows(AllMeshRows)));
else
std::printf("[StreamFullClipmap] wall=%.3fs generated=%d/%d worker_sum=%.3fs worker_busy=%.1f%% worker_idle=%.1f%% tiles=%d hash=off\n",
FullClipSeconds,Finished,DesiredTotal,TotalWorkerSeconds,WorkerBusyPercent,
std::max(0.0,100.0-WorkerBusyPercent),DesiredTotal);
std::printf("[StreamCacheUse] hits=%llu requested=%d\n",
static_cast<unsigned long long>(Streamer.GetCacheHits()),DesiredTotal);
if(bShardAudit)
@@ -1835,16 +1882,23 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
{
if(TilesByLevel[Level]==0)continue;
if(bHashDensity||!BakeCachePath.empty())
std::printf("[StreamLevel] lod=%d tiles=%llu samples=%.3fM worker_sum=%.3fs vertices=%llu indices=%llu density_hash=0x%016llx\n",
std::printf("[StreamLevel] lod=%d tiles=%llu samples=%.3fM worker_sum=%.3fs first_ready=%.3fs complete=%.3fs worker_busy=%.1f%% output=%.2fMiB vertices=%llu indices=%llu density_hash=0x%016llx mesh_hash=0x%016llx\n",
Level,static_cast<unsigned long long>(TilesByLevel[Level]),
static_cast<double>(SamplesByLevel[Level])/1.0e6,WorkerSecondsByLevel[Level],
FirstCompletionByLevel[Level],LastCompletionByLevel[Level],
100.0*WorkerSecondsByLevel[Level]/(WorkerCount*std::max(0.001,LastCompletionByLevel[Level])),
static_cast<double>(OutputBytesByLevel[Level])/1048576.0,
static_cast<unsigned long long>(VerticesByLevel[Level]),
static_cast<unsigned long long>(IndicesByLevel[Level]),
static_cast<unsigned long long>(HashTileRows(HashRows[Level])));
static_cast<unsigned long long>(HashTileRows(HashRows[Level])),
static_cast<unsigned long long>(HashTileRows(MeshHashRows[Level])));
else
std::printf("[StreamLevel] lod=%d tiles=%llu samples=%.3fM worker_sum=%.3fs vertices=%llu indices=%llu hash=off\n",
std::printf("[StreamLevel] lod=%d tiles=%llu samples=%.3fM worker_sum=%.3fs first_ready=%.3fs complete=%.3fs worker_busy=%.1f%% output=%.2fMiB vertices=%llu indices=%llu hash=off\n",
Level,static_cast<unsigned long long>(TilesByLevel[Level]),
static_cast<double>(SamplesByLevel[Level])/1.0e6,WorkerSecondsByLevel[Level],
FirstCompletionByLevel[Level],LastCompletionByLevel[Level],
100.0*WorkerSecondsByLevel[Level]/(WorkerCount*std::max(0.001,LastCompletionByLevel[Level])),
static_cast<double>(OutputBytesByLevel[Level])/1048576.0,
static_cast<unsigned long long>(VerticesByLevel[Level]),
static_cast<unsigned long long>(IndicesByLevel[Level]));
}
@@ -1864,6 +1918,78 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
if(bShardAudit&&(MeshSheetStats.ThinSheets!=0||MeshSheetStats.SmallComponentsInView!=0))return 13;
return 0;
}
int RunEditTransactionBenchmark(FStandaloneOwnerWorld& World,FStandaloneShapeWorld& Shape,
const FVector& CameraPositionVoxels,int32 WorkerCount)
{
using Clock=std::chrono::steady_clock;
// Place the spell across the LOD0/LOD1 clipmap seam so one edit exercises every visible
// level it intersects, instead of timing only the center LOD0 tiles.
const double X=CameraPositionVoxels.X+3.0*CHUNK_SIZE;
const double Y=CameraPositionVoxels.Y,Z=CameraPositionVoxels.Z;
std::vector<FStandaloneShapeWorld::FEditBrush> Brushes(3);
Brushes[0].Shape=FStandaloneShapeWorld::FEditBrush::EShape::Sphere;
Brushes[0].Operation=FStandaloneShapeWorld::FEditBrush::EOperation::Carve;
Brushes[0].A={X,Y,Z};Brushes[0].Radius=20.0;
Brushes[1].Shape=FStandaloneShapeWorld::FEditBrush::EShape::RoundedBox;
Brushes[1].Operation=FStandaloneShapeWorld::FEditBrush::EOperation::Carve;
Brushes[1].A={X,Y,Z+12.0};Brushes[1].HalfExtent={11.0,11.0,4.0};Brushes[1].Rounding=3.0;
Brushes[2].Shape=FStandaloneShapeWorld::FEditBrush::EShape::Capsule;
Brushes[2].Operation=FStandaloneShapeWorld::FEditBrush::EOperation::AddRock;
Brushes[2].A={X-22.0,Y,Z-8.0};Brushes[2].B={X+22.0,Y,Z-8.0};Brushes[2].Radius=3.0;
const auto EditStart=Clock::now();
Shape.SetEditTransaction(std::move(Brushes));
FStandaloneDesiredTileSet Desired=StandaloneWorldMesher::BuildDesiredSet(World,CameraPositionVoxels);
const FIntVector EditMin=Shape.GetEditBoundsMin(),EditMax=Shape.GetEditBoundsMax();
std::vector<FVoxelTileKey> Affected;Affected.reserve(128);
std::array<uint64,MaxLevels+1> AffectedByLevel{},FinishedByLevel{};
for(const FVoxelTileKey& Tile:Desired.Tiles)
{
const FIntVector Origin=Tile.OriginVoxels();const int32 Extent=Tile.ExtentVoxels();
const int32 Pad=std::max(2,Tile.StepVoxels());
if(Origin.X-Pad>EditMax.X||Origin.X+Extent+Pad<EditMin.X
||Origin.Y-Pad>EditMax.Y||Origin.Y+Extent+Pad<EditMin.Y
||Origin.Z-Pad>EditMax.Z||Origin.Z+Extent+Pad<EditMin.Z)continue;
Affected.push_back(Tile);
if(Tile.Level>=0&&Tile.Level<=MaxLevels)++AffectedByLevel[Tile.Level];
}
if(Affected.empty())
{
std::fprintf(stderr,"[EditTransaction] failed: no desired tiles intersect the edit bounds.\n");
return 9;
}
FStandaloneStreamingGenerator Streamer(World,WorkerCount,false,nullptr,-1);
Streamer.SetDesiredTileFilter(Affected);
const auto Start=Clock::now();
const FStandaloneStreamingUpdate Update=Streamer.Start(CameraPositionVoxels);
int32 Finished=0;
double WorkerSeconds=0.0;
while(Finished<Update.DesiredTiles)
{
std::vector<FStandaloneCpuTile> Ready=Streamer.TakeReady();
if(Ready.empty()){std::this_thread::sleep_for(std::chrono::milliseconds(1));continue;}
for(const FStandaloneCpuTile& Tile:Ready)
{
++Finished;WorkerSeconds+=Tile.WorkerSeconds;
if(Tile.Key.Level>=0&&Tile.Key.Level<=MaxLevels)++FinishedByLevel[Tile.Key.Level];
}
}
const double RemeshWall=std::chrono::duration<double>(Clock::now()-Start).count();
Streamer.Stop();
std::printf("[EditTransaction] operation=crater_batch transaction_count=1 brushes=3 diameter=10.0m offset_from_player=%.2fm affected_tiles=%d/%zu workers=%d cache_hits=%llu remesh_wall=%.3fs worker_sum=%.3fs edit_to_ready=%.3fs status=%s\n",
3.0*CHUNK_SIZE*VOXEL_SIZE/100.0,
Finished,Affected.size(),WorkerCount,static_cast<unsigned long long>(Streamer.GetCacheHits()),
RemeshWall,WorkerSeconds,std::chrono::duration<double>(Clock::now()-EditStart).count(),
Finished==static_cast<int32>(Affected.size())?"PASS":"FAIL");
for(int32 Level=0;Level<=MaxLevels;++Level)
if(AffectedByLevel[Level])
std::printf("[EditTransactionLevel] lod=%d tiles=%llu remeshed=%llu status=%s\n",Level,
static_cast<unsigned long long>(AffectedByLevel[Level]),
static_cast<unsigned long long>(FinishedByLevel[Level]),
AffectedByLevel[Level]==FinishedByLevel[Level]?"PASS":"FAIL");
return Finished==static_cast<int32>(Affected.size())?0:10;
}
}
int main(int Argc,char** Argv)
@@ -1878,6 +2004,7 @@ int main(int Argc,char** Argv)
bool bStreamBenchmark=false;
bool bShardAudit=false;
bool bStreamHash=false;
bool bEditBenchmark=false;
bool bRoundWallCompare=false;
int32 RoundCompareTileCount=16;
std::string BakeMeshCachePath;
@@ -1907,6 +2034,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=="--edit-benchmark")
{bEditBenchmark=true;bStreamBenchmark=true;App.bShapeWorld=true;}
else if(Arg=="--stream-hash")bStreamHash=true;
else if(Arg=="--shard-audit")bShardAudit=true;
else if(Arg=="--compare-round-walls")
@@ -1984,6 +2113,9 @@ int main(int Argc,char** Argv)
return RunRoundWallComparison(*App.World,App.Position,RoundCompareTileCount);
if(bStreamBenchmark)
{
if(bEditBenchmark)
return RunEditTransactionBenchmark(*App.World,*App.ShapeWorld,
FVector(App.Position.X*4.0,App.Position.Y*4.0,App.Position.Z*4.0),App.WorkerCount);
const double FullDetailWidth=static_cast<double>(2*App.ClipRadius+2)
*CHUNK_SIZE*VOXEL_SIZE/100.0;
std::printf("Standalone clip override: exported radius=%d (112 m cube) -> radius=%d (%.0f m LOD0 cube), voxel size=25 cm.\n",