wip(standalone): GPU step 8 partial -- GPU skirts, first-present hold; remote gap open

Luna's session ended on an API "Bad Request" before a final report; state is
unverified by me. In the log: GPU clipped-skirt emitter (count/scan/emit,
protected signs and critical air honoured), exposed-skirt audit passing at
the end; first-present stall reproduced on every launch (2.36-2.59 s, not
exe identity/idle/CPU run) and hidden by holding the CPU-ready frame until
GPU residency. Remote LOD3-4 band still differs from CPU; draw ranges and the
one inspected LOD3 tile match, cause not yet found (one-tile probe mid-fix).

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-07 02:19:38 +02:00
1 parent 90421d0655
commit f2de8fe9c6
42 files changed
+1381 -59

No files matched your search

+246 -18
View File
@@ -1361,6 +1361,8 @@ namespace
VoxelForgeGpuFarViewer::GpuTimingQueries TimingQueries{};
uint64 VertexCapacityBytes=0;
uint32 OutputSlot=0,IndirectArgsByteOffset=0,BatchIndex=UINT32_MAX;
uint8 VisibleSkirtFaceMask=0;
bool bSkirtDrawArgsAudited=false;
double GpuDispatchMs=0.0;
bool bGpuComplete=false;
bool bTimingResolved=false;
@@ -1486,13 +1488,26 @@ namespace
bool bGpuFarEnabled=false;
bool bGpuFarAuditEnabled=false;
bool bGpuFarAuditReported=false;
bool bGpuSkirtEmitEnabled=true,bGpuConnectorRepairEnabled=true;
bool bDisableVSync=false;
bool bForceBlockingStartupPresent=false;
bool bPresentCpuFrameBeforeGpu=false;
bool bCpuReadyFramePresentedBeforeGpu=false;
bool bHoldCpuFrameDuringGpuWarmup=false,bGpuWarmupHoldReported=false;
bool bGpuWarmupReleaseReported=false;
uint64 GpuWarmupHeldPresents=0;
bool bAuditGpuSkirtDrawArgs=false,bGpuSkirtDrawAuditReported=false;
ID3D11Buffer* GpuSkirtArgsStaging=nullptr;
uint64 GpuSkirtDrawAuditTiles=0,GpuSkirtDrawAuditZeroCounts=0,
GpuSkirtDrawAuditOverflow=0,GpuSkirtDrawAuditBadStartIndex=0;
uint64 GpuSkirtDrawAuditSumIndices=0,GpuSkirtDrawAuditMaxIndices=0;
std::unique_ptr<FFarSurvivalAudit> GpuFarAudit;
bool bGpuFarFirstTileReported=false;
std::filesystem::path GpuFarShaderPath;
double GpuFarEnqueueWallSeconds=0.0;
uint64 GpuFarTilesSubmitted=0;
uint64 PresentCallCount=0;
uint64 StartupNonBlockingPresentCalls=0,StartupNonBlockingPresentSkips=0;
double GpuFarGpuDispatchMs=0.0;
double GpuFarGpuDispatchMaxMs=0.0;
double GpuFarSubmissionSpanMs=0.0,GpuFarSubmissionSpanMaxMs=0.0;
@@ -1549,6 +1564,10 @@ namespace
int32 ClipRadius=3;
int32 MaxClipLevelOverride=-1;
int32 CaptureTileLimit=0;
int32 CaptureOnlyLod=-1;
bool bCaptureOnlyTile=false;
int32 CaptureOnlyTileX=0,CaptureOnlyTileY=0,CaptureOnlyTileZ=0,CaptureOnlyTileLod=0;
int32 CaptureOutputSlot=-1;
int32 Width=1280,Height=800;
float Yaw=0.0f,Pitch=0.0f,MoveSpeed=8.0f;
V3 Position{};
@@ -1565,6 +1584,7 @@ namespace
StopGeneration(true);ReleaseMeshes();
if(SolidRasterizer)SolidRasterizer->Release();if(WireRasterizer)WireRasterizer->Release();
if(Constants)Constants->Release();if(InputLayout)InputLayout->Release();
if(GpuSkirtArgsStaging)GpuSkirtArgsStaging->Release();
if(VertexShader)VertexShader->Release();if(PixelShader)PixelShader->Release();
if(RenderTarget)RenderTarget->Release();if(DepthView)DepthView->Release();
if(SwapChain)SwapChain->Release();if(Context)Context->Release();if(Device)Device->Release();
@@ -2101,6 +2121,24 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
for(const auto& Key:CoreTiles)
DesiredTiles.emplace_back(FIntVector(Key.coordinate.x,Key.coordinate.y,Key.coordinate.z),Key.lod);
}
if(bCaptureOnlyTile)
{
const size_t Before=DesiredTiles.size();
DesiredTiles.erase(std::remove_if(DesiredTiles.begin(),DesiredTiles.end(),[&](const FVoxelTileKey& Key)
{
return Key.Level!=CaptureOnlyTileLod||Key.Coord.X!=CaptureOnlyTileX
||Key.Coord.Y!=CaptureOnlyTileY||Key.Coord.Z!=CaptureOnlyTileZ;
}),DesiredTiles.end());
std::printf("[CaptureOnlyTile] key=(%d,%d,%d,lod%d) before=%zu selected=%zu\n",
CaptureOnlyTileX,CaptureOnlyTileY,CaptureOnlyTileZ,CaptureOnlyTileLod,
Before,DesiredTiles.size());
if(DesiredTiles.empty())
{
Error="the requested capture-only tile is not in the desired clipmap";
std::fprintf(stderr,"World load failed: %s\n",Error.c_str());
return;
}
}
if(CaptureTileLimit>0&&CapturePath.size())
{
const size_t Before=DesiredTiles.size();
@@ -2155,7 +2193,7 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
}
}
if(bShapePipelineActive)Streamer->SetDesiredTileFilter(InitialNeighborhoodTiles);
else if(CaptureTileLimit>0&&CapturePath.size())
else if((CaptureTileLimit>0&&CapturePath.size())||bCaptureOnlyTile)
Streamer->SetDesiredTileFilter(DesiredTiles);
const FStandaloneStreamingUpdate Update=Streamer->Start(CameraVoxels,{},CrossingIndex);
if(bShapePipelineActive&&Update.DesiredTiles!=static_cast<int32>(InitialNeighborhoodTiles.size()))
@@ -2343,6 +2381,20 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
Inputs[Index]=Key.Level<World->FullResClipLevels
?ShapeWorld->exportGpuFieldTile(CoreKey,Errors[Index])
:ShapeWorld->exportFarFieldTile(CoreKey,Errors[Index]);
if(Inputs[Index]&&Key.Level>=World->FullResClipLevels)
{
Inputs[Index]->visibleSkirtFaceMask=World->bGenerateSkirts
&&bGpuSkirtEmitEnabled
?ComputeVisibleSkirtFaceMask(Key,DesiredTileSet):0;
Inputs[Index]->skirtDepthVoxels=std::max(1.0f,
static_cast<float>(World->SkirtCells))*Key.StepVoxels();
if(!bGpuConnectorRepairEnabled)
{
Inputs[Index]->connectorPanels.clear();
Inputs[Index]->connectorRingCount=0;
Inputs[Index]->connectorVertexCount=0;
}
}
}
catch(const std::exception& Error) { Errors[Index]=Error.what(); }
}
@@ -2390,12 +2442,22 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
{
const uint8 VisibleSkirtFaces=World->bGenerateSkirts
?ComputeVisibleSkirtFaceMask(Key,DesiredTileSet):0;
if(VisibleSkirtFaces!=0)
if(Key.Level>=World->FullResClipLevels)
{
// CPU tiles carry the established clipped LOD skirts. The GPU field
// and marching-cubes outputs match the CPU surface, but currently do
// not emit these seam curtains. Keep tiles with exposed LOD faces on
// the reference mesh path until a GPU skirt kernel is available.
const auto Existing=GpuFarTiles.find(Key);
if(Existing!=GpuFarTiles.end()
&&Existing->second.VisibleSkirtFaceMask!=VisibleSkirtFaces)
{
const uint32 ReusedSlot=Existing->second.OutputSlot;
ReleaseGpuFarTile(Existing->second);
GpuFarTiles.erase(Existing);
GpuFarFreeOutputSlots.push_back(ReusedSlot);
}
}
if(VisibleSkirtFaces!=0&&NearGpuEligible)
{
// Keep fine tiles on the CPU reference path. Far tiles carry the
// CPU-decided visible face mask to the deterministic GPU skirt pass.
CpuTiles.push_back(Key);
++SkirtTransitionFallbackTiles;
}
@@ -2411,6 +2473,14 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
}
if(!Eligible.empty()&&GpuFarOutputCapacitySlots==0)
GpuFarOutputCapacitySlots=static_cast<uint32>(Eligible.size());
if(bCaptureOnlyTile&&CaptureOutputSlot>=0)
{
GpuFarOutputCapacitySlots=std::max(GpuFarOutputCapacitySlots,
static_cast<uint32>(CaptureOutputSlot+1));
GpuFarNextOutputSlot=static_cast<uint32>(CaptureOutputSlot);
std::printf("[CaptureOutputSlotProbe] slot=%d pool_slots=%u\n",
CaptureOutputSlot,GpuFarOutputCapacitySlots);
}
if(!Eligible.empty())
{
std::string PoolError;const auto ReserveStart=std::chrono::steady_clock::now();
@@ -2473,7 +2543,7 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
{return Key.Level<World->FullResClipLevels;}));
std::printf("[GpuFieldEligibility] eligible_gpu_tiles=%zu near_gpu_tiles=%zu cpu_fallback_tiles=%zu\n",
GpuFarEligibleTiles.size(),NearGpuTiles,Keys.size()-GpuFarEligibleTiles.size());
std::printf("[GpuSkirtSeamFallback] tiles=%llu reason=visible_lod_skirt_faces status=active\n",
std::printf("[GpuSkirtSeamFallback] near_tiles=%llu reason=fine_visible_lod_skirts gpu_far_skirts=active\n",
static_cast<unsigned long long>(SkirtTransitionFallbackTiles));
}
@@ -2533,6 +2603,7 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
bGpuFarEnabled=false;
break;
}
const uint8 PreparedSkirtFaceMask=PreparedInput->visibleSkirtFaceMask;
if(!VoxelForgeGpuFarViewer::BuildFarTile(Device,Context,*ShapeWorld,CoreKey,
PreparedInput,
GpuFarShaderPath,&Tile.VertexBuffer,&Tile.IndexBuffer,&Tile.IndirectArgs,
@@ -2565,6 +2636,7 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
}
Tile.VertexCapacityBytes=static_cast<uint64>(
VoxelForgeGpuFarViewer::PooledOutputVertexCapacityPerTile)*32u;
Tile.VisibleSkirtFaceMask=PreparedSkirtFaceMask;
Tile.GpuDispatchMs=GpuDispatchMs;
GpuFarEnqueueWallSeconds+=EnqueueMs/1000.0;
if(GpuDispatchMs>0.0)
@@ -2643,6 +2715,9 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
bGpuFarEnabled=!bGpuFarEnabled;
if(bGpuFarEnabled)
{
bPresentCpuFrameBeforeGpu=true;
bHoldCpuFrameDuringGpuWarmup=true;
bCpuReadyFramePresentedBeforeGpu=false;
ScheduleGpuFarTiles(DesiredTiles);
std::vector<FVoxelTileKey> CpuFar;
for(const FVoxelTileKey& Key:DesiredTiles)
@@ -3241,6 +3316,10 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
static_cast<unsigned long long>(TotalIndices),StreamingBatches.size());
std::printf("[ColdTimeline] event=whole_clipmap_ready at_ms=%.3f waits_for=%zu_GPU_tiles_plus_CPU_fallback_and_uploads\n",
Elapsed*1000.0,GpuFarEligibleTiles.size());
std::printf("[PresentStartupSummary] nonblocking_startup_calls=%llu skipped_busy_calls=%llu gpu_warmup_held_calls=%llu policy=do_not_wait_until_initial_clipmap_ready\n",
static_cast<unsigned long long>(StartupNonBlockingPresentCalls),
static_cast<unsigned long long>(StartupNonBlockingPresentSkips),
static_cast<unsigned long long>(GpuWarmupHeldPresents));
if(bGpuFarEnabled)
{
SampleGpuFarMemory();
@@ -3307,7 +3386,10 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
void UpdateTitle()
{
uint64 VisibleIndices=0;for(const auto& Pair:StreamingBatches)if(bShowLevel[Pair.first.Level])VisibleIndices+=Pair.second.IndexCount;
uint64 VisibleIndices=0;for(const auto& Pair:StreamingBatches)
if(bShowLevel[Pair.first.Level]
&&(CaptureOnlyLod<0||Pair.first.Level==CaptureOnlyLod))
VisibleIndices+=Pair.second.IndexCount;
std::ostringstream S;S<<"VoxelForge standalone | seed "<<Seed<<" | "<<(bShapeWorld?"shape-interval owner world":(bRoundTunnels?"round/winding research tunnels":"base world"))
<<(bRoundTunnels?(bRoundTunnelEnhanced?" (detailed walls)":" (legacy walls)"):"")
<<" | "<<VisibleIndices/3<<" tris | "<<FrameMs<<" ms | field "<<(bGpuFarEnabled?"GPU":"CPU")
@@ -3323,7 +3405,9 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
?std::chrono::duration<double,std::milli>(DrawStart-LastDrawEndAt).count():0.0;
PumpGeneration();
const auto CpuPumpEnd=std::chrono::steady_clock::now();
PumpGpuFarGeneration();
const bool bDeferGpuUntilCpuFrame=bGpuFarEnabled&&bPresentCpuFrameBeforeGpu
&&!bCpuReadyFramePresentedBeforeGpu;
if(!bDeferGpuUntilCpuFrame)PumpGpuFarGeneration();
const auto GpuPumpEnd=std::chrono::steady_clock::now();
const auto Now=std::chrono::steady_clock::now();
if(FlightTargetCrossings>0&&bFullDetailReported&&!bFlightStarted)
@@ -3373,7 +3457,9 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
for(const auto& Pair:StreamingBatches)
{
const FStreamingGpuBatch& L=Pair.second;
if(!bShowLevel[Pair.first.Level]||!L.VertexBuffer||!L.IndexBuffer||!L.IndexCount)continue;
if(!bShowLevel[Pair.first.Level]
||(CaptureOnlyLod>=0&&Pair.first.Level!=CaptureOnlyLod)
||!L.VertexBuffer||!L.IndexBuffer||!L.IndexCount)continue;
const UINT Stride=sizeof(FGpuVertex),Offset=0;Context->IASetVertexBuffers(0,1,&L.VertexBuffer,&Stride,&Offset);
Context->IASetIndexBuffer(L.IndexBuffer,DXGI_FORMAT_R32_UINT,0);Context->DrawIndexed(L.IndexCount,0,0);
}
@@ -3385,12 +3471,59 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
C.Padding[0]=0.01f;
Context->UpdateSubresource(Constants,0,nullptr,&C,0,0);
Context->VSSetConstantBuffers(0,1,&Constants);Context->PSSetConstantBuffers(0,1,&Constants);
for(const auto& Pair:GpuFarTiles)
for(auto& Pair:GpuFarTiles)
{
const FGpuFarTile& Tile=Pair.second;
if(!bShowLevel[Pair.first.Level]||!Tile.VertexBuffer||!Tile.IndexBuffer||!Tile.IndirectArgs)continue;
FGpuFarTile& Tile=Pair.second;
if(!bShowLevel[Pair.first.Level]
||(CaptureOnlyLod>=0&&Pair.first.Level!=CaptureOnlyLod)
||!Tile.VertexBuffer||!Tile.IndexBuffer||!Tile.IndirectArgs)continue;
if(!bInitialClipmapReported&&Pair.first.Level>=World->FullResClipLevels)continue;
if(!IsRenderedTileReady(Pair.first))continue;
if(bAuditGpuSkirtDrawArgs&&Tile.VisibleSkirtFaceMask!=0&&!Tile.bSkirtDrawArgsAudited)
{
if(!GpuSkirtArgsStaging)
{
D3D11_BUFFER_DESC StagingDesc{};
StagingDesc.ByteWidth=11u*sizeof(uint32);
StagingDesc.Usage=D3D11_USAGE_STAGING;
StagingDesc.CPUAccessFlags=D3D11_CPU_ACCESS_READ;
const HRESULT CreateResult=Device->CreateBuffer(&StagingDesc,nullptr,
&GpuSkirtArgsStaging);
if(FAILED(CreateResult))
std::fprintf(stderr,"[GpuSkirtDrawAuditError] create_staging_hr=0x%08lx\n",
static_cast<unsigned long>(CreateResult));
}
if(GpuSkirtArgsStaging)
{
const D3D11_BOX ArgsSource{Tile.IndirectArgsByteOffset,0,0,
Tile.IndirectArgsByteOffset+11u*sizeof(uint32),1,1};
Context->CopySubresourceRegion(GpuSkirtArgsStaging,0,0,0,0,
Tile.IndirectArgs,0,&ArgsSource);
D3D11_MAPPED_SUBRESOURCE ArgsMapped{};
const HRESULT MapResult=Context->Map(GpuSkirtArgsStaging,0,
D3D11_MAP_READ,0,&ArgsMapped);
if(SUCCEEDED(MapResult))
{
const auto* Args=static_cast<const uint32*>(ArgsMapped.pData);
const uint32 ExpectedStartIndex=(Tile.IndirectArgsByteOffset
/(11u*sizeof(uint32)))*32768u;
++GpuSkirtDrawAuditTiles;
GpuSkirtDrawAuditSumIndices+=Args[5];
GpuSkirtDrawAuditMaxIndices=std::max<uint64>(GpuSkirtDrawAuditMaxIndices,Args[5]);
if(Args[5]==0)++GpuSkirtDrawAuditZeroCounts;
if(Args[10]!=0)++GpuSkirtDrawAuditOverflow;
if(Args[7]!=ExpectedStartIndex)++GpuSkirtDrawAuditBadStartIndex;
std::printf("[GpuSkirtDrawArgs] key=(%d,%d,%d,lod%d) face_mask=0x%02x output_slot=%u surface_indices=%u skirt_panel_indices=%u instances=%u connector_start_index=%u expected_start_index=%u overflow=%u\n",
Pair.first.Coord.X,Pair.first.Coord.Y,Pair.first.Coord.Z,Pair.first.Level,
static_cast<unsigned>(Tile.VisibleSkirtFaceMask),Tile.OutputSlot,
Args[0],Args[5],Args[6],Args[7],ExpectedStartIndex,Args[10]);
Context->Unmap(GpuSkirtArgsStaging,0);
}
else std::fprintf(stderr,"[GpuSkirtDrawAuditError] map_staging_hr=0x%08lx\n",
static_cast<unsigned long>(MapResult));
}
Tile.bSkirtDrawArgsAudited=true;
}
const UINT Stride=32,Offset=0;
Context->IASetVertexBuffers(0,1,&Tile.VertexBuffer,&Stride,&Offset);
Context->IASetIndexBuffer(Tile.IndexBuffer,DXGI_FORMAT_R32_UINT,0);
@@ -3404,20 +3537,84 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
}
}
}
if(bAuditGpuSkirtDrawArgs&&bInitialClipmapReported&&!bGpuSkirtDrawAuditReported)
{
std::printf("[GpuSkirtDrawArgsSummary] tiles=%llu zero_index_counts=%llu overflow=%llu bad_slot_start_indices=%llu total_panel_plus_skirt_indices=%llu max_panel_plus_skirt_indices=%llu status=%s\n",
static_cast<unsigned long long>(GpuSkirtDrawAuditTiles),
static_cast<unsigned long long>(GpuSkirtDrawAuditZeroCounts),
static_cast<unsigned long long>(GpuSkirtDrawAuditOverflow),
static_cast<unsigned long long>(GpuSkirtDrawAuditBadStartIndex),
static_cast<unsigned long long>(GpuSkirtDrawAuditSumIndices),
static_cast<unsigned long long>(GpuSkirtDrawAuditMaxIndices),
(GpuSkirtDrawAuditTiles>0&&GpuSkirtDrawAuditOverflow==0
&&GpuSkirtDrawAuditBadStartIndex==0)?"PASS":"FAIL");
bGpuSkirtDrawAuditReported=true;
std::fflush(stdout);
}
CaptureRenderedFrame();
const bool bHoldFrontBufferForGpuWarmup=bHoldCpuFrameDuringGpuWarmup
&&bCpuReadyFramePresentedBeforeGpu&&bGpuFarEnabled
&&GpuFarTilesSubmitted>0&&!bInitialClipmapReported;
if(bHoldFrontBufferForGpuWarmup)
{
if(!bGpuWarmupHoldReported)
{
bGpuWarmupHoldReported=true;
std::printf("[GpuWarmupPresentHold] begin_ms=%.3f policy=retain_last_CPU_ready_front_buffer_until_GPU_clipmap_ready\n",
std::chrono::duration<double,std::milli>(
std::chrono::steady_clock::now()-ColdProcessStart).count());
std::fflush(stdout);
}
++GpuWarmupHeldPresents;
// Keep pumping CPU and GPU work at the display cadence without
// calling the driver present path that stalls on its first GPU frame.
std::this_thread::sleep_for(std::chrono::milliseconds(11));
LastDrawEndAt=std::chrono::steady_clock::now();
return;
}
const auto BeforePresent=std::chrono::steady_clock::now();
const UINT PresentSyncInterval=bDisableVSync?0u:1u;
const bool bNonBlockingStartupPresent=bGpuFarEnabled&&!bInitialClipmapReported
&&!bForceBlockingStartupPresent;
const UINT PresentSyncInterval=(bDisableVSync||bNonBlockingStartupPresent)?0u:1u;
const UINT PresentFlags=bNonBlockingStartupPresent?DXGI_PRESENT_DO_NOT_WAIT:0u;
const auto PresentCallStart=std::chrono::steady_clock::now();
SwapChain->Present(PresentSyncInterval,0);
const HRESULT PresentResult=SwapChain->Present(PresentSyncInterval,PresentFlags);
const auto PresentCallEnd=std::chrono::steady_clock::now();
if(bGpuWarmupHoldReported&&!bGpuWarmupReleaseReported)
{
bGpuWarmupReleaseReported=true;
std::printf("[GpuWarmupPresentRelease] at_ms=%.3f first_post_warmup_present_ms=%.3f sync=%u hr=0x%08lx\n",
std::chrono::duration<double,std::milli>(PresentCallEnd-ColdProcessStart).count(),
std::chrono::duration<double,std::milli>(PresentCallEnd-PresentCallStart).count(),
PresentSyncInterval,static_cast<unsigned long>(PresentResult));
std::fflush(stdout);
}
const uint64 PresentOrdinal=++PresentCallCount;
if(bNonBlockingStartupPresent)
{
++StartupNonBlockingPresentCalls;
if(PresentResult==DXGI_ERROR_WAS_STILL_DRAWING)++StartupNonBlockingPresentSkips;
else if(FAILED(PresentResult))
std::fprintf(stderr,"[PresentStartupError] hr=0x%08lx\n",
static_cast<unsigned long>(PresentResult));
}
if(PresentOrdinal<=3)
std::printf("[PresentProfile] ordinal=%llu at_ms=%.3f sync=%u call_ms=%.3f gpu_tiles_submitted=%llu gpu_batches=%llu\n",
std::printf("[PresentProfile] ordinal=%llu at_ms=%.3f sync=%u flags=0x%08x mode=%s hr=0x%08lx call_ms=%.3f gpu_tiles_submitted=%llu gpu_batches=%llu\n",
static_cast<unsigned long long>(PresentOrdinal),
std::chrono::duration<double,std::milli>(PresentCallEnd-ColdProcessStart).count(),
PresentSyncInterval,std::chrono::duration<double,std::milli>(PresentCallEnd-PresentCallStart).count(),
PresentSyncInterval,PresentFlags,bNonBlockingStartupPresent?"startup-do-not-wait":"normal",
static_cast<unsigned long>(PresentResult),
std::chrono::duration<double,std::milli>(PresentCallEnd-PresentCallStart).count(),
static_cast<unsigned long long>(GpuFarTilesSubmitted),
static_cast<unsigned long long>(GpuFarSubmissionBatches));
if(bDeferGpuUntilCpuFrame&&!StreamingBatches.empty())
{
bCpuReadyFramePresentedBeforeGpu=true;
std::printf("[CpuReadyFrameBeforeGpu] at_ms=%.3f uploaded_cpu_batches=%zu next_action=submit_gpu_far\n",
std::chrono::duration<double,std::milli>(PresentCallEnd-ColdProcessStart).count(),
StreamingBatches.size());
std::fflush(stdout);
}
UpdateTitle();
const auto DrawEnd=std::chrono::steady_clock::now();
const double CpuPumpMs=std::chrono::duration<double,std::milli>(CpuPumpEnd-DrawStart).count();
@@ -5230,13 +5427,22 @@ int main(int Argc,char** Argv)
const std::string_view Arg=Argv[I];
if(Arg.starts_with("--capture="))App.CapturePath=std::string(Arg.substr(10));
else if(Arg=="--no-vsync")App.bDisableVSync=true;
else if(Arg=="--blocking-startup-present")App.bForceBlockingStartupPresent=true;
else if(Arg=="--cpu-frame-before-gpu")App.bPresentCpuFrameBeforeGpu=true;
else if(Arg=="--hold-cpu-frame-during-gpu-warmup")
App.bHoldCpuFrameDuringGpuWarmup=true,App.bPresentCpuFrameBeforeGpu=true;
else if(Arg=="--gpu-skirt-draw-audit")App.bAuditGpuSkirtDrawArgs=true;
else if(Arg=="--gpu-skirts-disabled")App.bGpuSkirtEmitEnabled=false;
else if(Arg=="--gpu-connectors-disabled")App.bGpuConnectorRepairEnabled=false;
else if(Arg=="--profile-attribution")App.bProfileAttribution=true;
else if(Arg=="--profile-detail-band")bProfileDetailBand=true;
else if(Arg=="--compare-evaluators")App.bCompareEvaluators=true;
else if(Arg=="--parity-only")App.bParityOnly=true;
else if(Arg=="--density-hash")App.bDensityHash=true;
else if(Arg=="--shape-world")App.bShapeWorld=true;
else if(Arg=="--gpu-far")App.bGpuFarEnabled=true,App.bShapeWorld=true,App.bForceGenerate=true;
else if(Arg=="--gpu-far")
App.bGpuFarEnabled=true,App.bShapeWorld=true,App.bForceGenerate=true,
App.bPresentCpuFrameBeforeGpu=true,App.bHoldCpuFrameDuringGpuWarmup=true;
else if(Arg=="--cpu-far")App.bGpuFarEnabled=false,App.bShapeWorld=true,App.bForceGenerate=true;
else if(Arg=="--gpu-far-audit")
{App.bGpuFarEnabled=true;App.bGpuFarAuditEnabled=true;App.bShapeWorld=true;App.bForceGenerate=true;App.bQuitAfterClipmap=true;}
@@ -5316,6 +5522,20 @@ int main(int Argc,char** Argv)
else if(Arg.starts_with("--capture-tile-limit="))
App.CaptureTileLimit=std::clamp(std::atoi(
std::string(Arg.substr(std::string_view("--capture-tile-limit=").size())).c_str()),1,4096);
else if(Arg.starts_with("--capture-only-lod="))
App.CaptureOnlyLod=std::clamp(std::atoi(
std::string(Arg.substr(std::string_view("--capture-only-lod=").size())).c_str()),0,8);
else if(Arg.starts_with("--capture-only-tile="))
{
const std::string Values(Arg.substr(std::string_view("--capture-only-tile=").size()));
if(std::sscanf(Values.c_str(),"%d,%d,%d,%d",&App.CaptureOnlyTileX,
&App.CaptureOnlyTileY,&App.CaptureOnlyTileZ,&App.CaptureOnlyTileLod)==4)
App.bCaptureOnlyTile=true;
else {std::fprintf(stderr,"Invalid --capture-only-tile value: %s\n",Values.c_str());return 2;}
}
else if(Arg.starts_with("--capture-output-slot="))
App.CaptureOutputSlot=std::max(-1,std::atoi(
std::string(Arg.substr(std::string_view("--capture-output-slot=").size())).c_str()));
else if(Arg.starts_with("--benchmark-level="))
BenchmarkLevel=std::atoi(std::string(Arg.substr(18)).c_str());
else if(Arg.starts_with("--benchmark-count="))
@@ -5334,6 +5554,14 @@ int main(int Argc,char** Argv)
}
else if(!Arg.empty()&&Arg.front()!='-')App.DataPath=std::string(Arg);
}
if(App.bCaptureOnlyTile&&App.bGpuFarEnabled)
{
// A single far-tile probe may have no CPU fallback batch to present.
// Let it submit directly instead of waiting for the normal CPU-first
// presentation gate that requires a nonempty CPU batch.
App.bPresentCpuFrameBeforeGpu=false;
App.bHoldCpuFrameDuringGpuWarmup=false;
}
App.bProfileDetailBand=bProfileDetailBand;
std::string Error;
std::printf("[ColdTimeline] stage=owner_data_load begin_ms=%.3f\n",