wip(standalone): GPU step 11 -- per-shader cold cost measured; far EmitCS split, still CPU wins

Cold first-use per shader (queue ms): EvaluateFarField 1757, EmitNear 2429,
FarConnectorRings 784, FarSkirts 507+975; the far EmitCS dropped 2327 -> 3.2
by splitting out the near midpoint fallback into EmitNearCS. Warm-up under
0xFF00 ~2.0 s (worker count and thread priority do not change it; 0xFFFF run:
1.71 s). Whole view median CPU 1.428 s vs hybrid 3.154 s. Audits unchanged.
AMD DxCache was last written 2026-10-06 23:27 -- shaders may no longer be
cached across launches (unverified).

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 06:13:59 +02:00
1 parent 10580650cb
commit b6ac950073
19 files changed
+908 -24

No files matched your search

+78 -7
View File
@@ -1490,6 +1490,9 @@ namespace
bool bGpuFarAuditEnabled=false;
bool bGpuFarShaderPrewarm=false,bDisableGpuWarmupPresentHold=false;
bool bGpuFarWarmupResourcesOnly=false;
bool bGpuFarWarmupNormalPriority=false,bGpuFarWarmupBeforeWorkers=false;
bool bGpuFarWarmupOnly=false;
std::string GpuWarmupEntryFilter;
std::thread GpuShaderWarmupThread;
bool bGpuShaderWarmupQueueSucceeded=false;
std::string GpuShaderWarmupQueueError;
@@ -1882,11 +1885,22 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
bGpuShaderWarmupQueueSucceeded=false;GpuShaderWarmupQueueError.clear();
GpuShaderWarmupThread=std::thread([this]()
{
bool bNormalBasePriority=false;
if(bGpuFarWarmupNormalPriority)
{
// The process stays BelowNormal; HIGHEST relative priority raises this
// worker thread to a normal base priority on Windows.
bNormalBasePriority=SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST)!=0;
std::printf("[GpuShaderWarmupThread] priority=%s process=BelowNormal thread_relative=Highest\n",
bNormalBasePriority?"Normal":"set_failed");
std::fflush(stdout);
}
bGpuShaderWarmupQueueSucceeded=VoxelForgeGpuFarViewer::QueueFarShaderWarmup(
Device,Context,GpuFarShaderPath,!bGpuFarWarmupResourcesOnly,
Device,Context,GpuFarShaderPath,!bGpuFarWarmupResourcesOnly,GpuWarmupEntryFilter,
GpuShaderWarmupQueueError);
});
std::printf("[GpuShaderWarmup] queue_thread=started overlap=CPU_shape_compile\n");
std::printf("[GpuShaderWarmup] queue_thread=started overlap=%s\n",
bGpuFarWarmupBeforeWorkers?"none_before_generation_workers":"CPU_shape_compile");
std::fflush(stdout);
}
@@ -5520,7 +5534,14 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
int main(int Argc,char** Argv)
{
SetPriorityClass(GetCurrentProcess(),BELOW_NORMAL_PRIORITY_CLASS);
SetProcessAffinityMask(GetCurrentProcess(),static_cast<DWORD_PTR>(0xFF00));
const bool bAllCpuAffinity=std::find_if(Argv+1,Argv+Argc,[](const char* Arg)
{return std::string_view(Arg)=="--affinity-all-cpu";})!=Argv+Argc;
const DWORD_PTR RequestedAffinity=static_cast<DWORD_PTR>(bAllCpuAffinity?0xFFFF:0xFF00);
const BOOL bAffinitySet=SetProcessAffinityMask(GetCurrentProcess(),RequestedAffinity);
DWORD_PTR ProcessAffinity=0,SystemAffinity=0;
GetProcessAffinityMask(GetCurrentProcess(),&ProcessAffinity,&SystemAffinity);
std::printf("[ProcessControls] priority_class=BelowNormal affinity_mask=0x%llX set=%s\n",
static_cast<unsigned long long>(ProcessAffinity),bAffinitySet?"true":"false");
const auto ColdProcessStart=std::chrono::steady_clock::now();
FApp App;App.DataPath=DefaultDataPath().string();App.ColdProcessStart=ColdProcessStart;
wchar_t ExecutablePath[MAX_PATH]{};
@@ -5584,6 +5605,18 @@ int main(int Argc,char** Argv)
App.bGpuFarEnabled=true,App.bGpuFarShaderPrewarm=true,App.bGpuFarWarmupResourcesOnly=true,
App.bShapeWorld=true,App.bForceGenerate=true,App.bPresentCpuFrameBeforeGpu=true,
App.bHoldCpuFrameDuringGpuWarmup=true;
else if(Arg=="--gpu-far-warmup-normal-priority")
App.bGpuFarWarmupNormalPriority=true;
else if(Arg=="--gpu-far-warmup-before-workers")
App.bGpuFarEnabled=true,App.bGpuFarShaderPrewarm=true,App.bGpuFarWarmupBeforeWorkers=true,
App.bShapeWorld=true,App.bForceGenerate=true,App.bPresentCpuFrameBeforeGpu=true,
App.bHoldCpuFrameDuringGpuWarmup=true;
else if(Arg=="--gpu-far-warmup-only")
App.bGpuFarEnabled=true,App.bGpuFarShaderPrewarm=true,App.bGpuFarWarmupOnly=true,
App.bShapeWorld=true,App.bForceGenerate=true;
else if(Arg.starts_with("--gpu-far-warmup-entry="))
App.GpuWarmupEntryFilter=std::string(Arg.substr(std::string_view("--gpu-far-warmup-entry=").size()));
else if(Arg=="--affinity-all-cpu"){}
else if(Arg=="--gpu-far-no-present-hold")
App.bDisableGpuWarmupPresentHold=true;
else if(Arg=="--gpu-far-no-prewarm")
@@ -5836,12 +5869,50 @@ int main(int Argc,char** Argv)
std::printf("[ColdTimeline] stage=viewer_device_init end_ms=%.3f duration_ms=%.3f\n",
std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now()-ColdProcessStart).count(),
std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now()-DeviceInitStart).count());
ShowWindow(App.Window,SW_SHOW);UpdateWindow(App.Window);
std::printf("Controls: hold right mouse to look; WASD move; Space/Ctrl (E/Q) up/down; Shift faster; wheel changes speed; F wireframe; G toggles legacy/detailed round walls; H toggles CPU/GPU far tiles; 1-9 toggle LOD; 0 toggle all levels; N/P change seed; T swaps base/round tunnels; V swaps owner density/shape intervals; Esc quit.\n");
std::printf("Owner data: %s; starting at first-strate open-space sample (%.2f, %.2f, %.2f) m.\n",
App.DataPath.c_str(),App.Position.X,App.Position.Y,App.Position.Z);
if(!App.bGpuFarWarmupOnly)
{
ShowWindow(App.Window,SW_SHOW);UpdateWindow(App.Window);
std::printf("Controls: hold right mouse to look; WASD move; Space/Ctrl (E/Q) up/down; Shift faster; wheel changes speed; F wireframe; G toggles legacy/detailed round walls; H toggles CPU/GPU far tiles; 1-9 toggle LOD; 0 toggle all levels; N/P change seed; T swaps base/round tunnels; V swaps owner density/shape intervals; Esc quit.\n");
std::printf("Owner data: %s; starting at first-strate open-space sample (%.2f, %.2f, %.2f) m.\n",
App.DataPath.c_str(),App.Position.X,App.Position.Y,App.Position.Z);
}
std::fflush(stdout);
if(App.bGpuFarWarmupOnly)
{
const auto WarmupOnlyStart=std::chrono::steady_clock::now();
std::string WarmupError;
if(!VoxelForgeGpuFarViewer::QueueFarShaderWarmup(App.Device,App.Context,App.GpuFarShaderPath,
true,App.GpuWarmupEntryFilter,WarmupError))
{std::fprintf(stderr,"[GpuShaderWarmupError] queue: %s\n",WarmupError.c_str());return 5;}
if(!VoxelForgeGpuFarViewer::CompleteFarShaderWarmup(App.Device,App.Context,
App.GpuFarShaderPath,WarmupError))
{std::fprintf(stderr,"[GpuShaderWarmupError] completion: %s\n",WarmupError.c_str());return 5;}
uint64 WarmupDxgiUsage=0,WarmupDxgiBudget=0;
if(VoxelForgeGpuFarViewer::QueryFarGpuMemory(App.Device,App.Context,App.GpuFarShaderPath,
WarmupDxgiUsage,WarmupDxgiBudget,WarmupError))
std::printf("[GpuFarMemory] dxgi_local_sampled_peak_mb=%.3f budget_mb=%.3f\n",
static_cast<double>(WarmupDxgiUsage)/1048576.0,
static_cast<double>(WarmupDxgiBudget)/1048576.0);
else
std::printf("[GpuFarMemory] dxgi_local_sampled_peak_mb=unavailable reason=%s\n",
WarmupError.c_str());
std::printf("[GpuShaderWarmupOnlyComplete] entry=%s total_ms=%.3f\n",
App.GpuWarmupEntryFilter.empty()?"all":App.GpuWarmupEntryFilter.c_str(),
std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now()-WarmupOnlyStart).count());
return 0;
}
App.StartGpuShaderWarmupAsync();
if(App.bGpuFarWarmupBeforeWorkers)
{
if(App.GpuShaderWarmupThread.joinable())App.GpuShaderWarmupThread.join();
if(!App.bGpuShaderWarmupQueueSucceeded)
{std::fprintf(stderr,"[GpuShaderWarmupError] queue: %s\n",App.GpuShaderWarmupQueueError.c_str());return 5;}
std::string WarmupError;
if(!VoxelForgeGpuFarViewer::CompleteFarShaderWarmup(App.Device,App.Context,
App.GpuFarShaderPath,WarmupError))
{std::fprintf(stderr,"[GpuShaderWarmupError] completion: %s\n",WarmupError.c_str());return 5;}
std::printf("[GpuShaderWarmupBeforeWorkers] completed_before_generation_workers=true\n");
}
App.StartGeneration();
MSG Message{};
while(Message.message!=WM_QUIT)