wip(standalone): GPU step 28 -- skirted near tiles on GPU (correct, but SLOWER); 16 shape workers
Luna: near skirts were CPU-only by implementation gap, not correctness. Ported with
near-resolution refinement and overflow fallback; near-probe preparation split out so
the skirt kernels no longer inline the near field (first attempt: two fxc /O3 compiles
ran 10.5 h and were stopped). Shape compile proven identical at W1/W8/W16.
-SkipCpuDetailBand retired (154/640 skirt audit failures, +174 ms planning).
Audits: hashes W1/W8/W16, walk 5,642/5,642, whole-near 960 tiles + 640 skirt faces
0 sign/topology diffs (one 0.001 cm vertex-key delta), far/thin 0 diffs, both
survivals pass with 2,074 candidates at 7.00 / 7.02 GiB (was ~6.2), ten captures pass.
My runs outside the sandbox (Step28.exe). NOTE the machine was ~25% slower than last
night for every build (step 27 CPU full machine 0.97-1.02 s at night, 1.22-1.29 s now):
0xFF00: CPU 1.337 / 1.291 / 1.295 s; GPU miss 1.337 s;
GPU cached 1.663 / 1.424 / 1.617 s (GPU tiles 1,427 / 2,072 / 1,222)
0xFFFF: CPU 1.221 / 1.231 / 1.236 s (step 27 same session 1.285 / 1.222 s)
GPU cached 1.582 / 1.550 / 1.416, 1.635 / 1.441 / 1.470 / 1.445 s
(GPU tiles vary 593-2,074; timestamps up to ~470 ms)
=> GPU route now slower than the CPU route measured alongside it. Step 27 GPU control
was not clean (both exes load the same precompiled .cso files).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
1 parent
7d1808fdf2
commit
5aa285c3ef
26 files changed
+1536
-400
No files matched your search
@@ -66,7 +66,6 @@ public:
|
||||
uint64 LocalBandSkips=0;
|
||||
uint64 GpuVisualCandidates=0,CpuVisualCandidates=0,GpuOnlyCandidates=0;
|
||||
uint64 GpuVisualDetailEvaluations=0,GpuOnlyDetailEvaluations=0;
|
||||
uint64 GpuOnlySkippedCandidateMasks=0;
|
||||
uint64 DistanceSamples=0,DistanceSampleNanoseconds=0;
|
||||
uint64 DetailSamples=0,DetailSampleNanoseconds=0;
|
||||
uint64 ReliefSampleNanoseconds=0,LayerLookupSampleNanoseconds=0;
|
||||
@@ -282,18 +281,14 @@ public:
|
||||
bool bInRoundTunnels=false,bool bInProfileDetailBand=false,
|
||||
bool bValidatePassageRoutes=true,
|
||||
const std::vector<VoxelForgeCore::DetailBandTileRegion>& InGpuVisualDetailTiles={},
|
||||
const std::vector<VoxelForgeCore::DetailBandTileRegion>& InCpuVisualDetailTiles={},
|
||||
bool bInSkipCpuDetailBandForGpuVisuals=false)
|
||||
const std::vector<VoxelForgeCore::DetailBandTileRegion>& InCpuVisualDetailTiles={})
|
||||
{
|
||||
using Clock=std::chrono::steady_clock;
|
||||
const auto TotalStart=Clock::now();
|
||||
Owner=&World;WorkerCount=std::clamp(Workers,1,8);DetailVariant=Variant;
|
||||
Owner=&World;WorkerCount=std::clamp(Workers,1,16);DetailVariant=Variant;
|
||||
Scheduler=InScheduler;RoundTunnelsEnabled=bInRoundTunnels;
|
||||
bAnalyticOnly=false;
|
||||
bProfileDetailBand=bInProfileDetailBand;
|
||||
bSkipCpuDetailBandForGpuVisuals=bInSkipCpuDetailBandForGpuVisuals;
|
||||
if(bSkipCpuDetailBandForGpuVisuals&&InGpuVisualDetailTiles.empty())
|
||||
{Error="GPU visual detail-band skipping requires at least one GPU near tile region";return false;}
|
||||
for(int32 A=0;A<3;++A)
|
||||
{
|
||||
Min[A]=(&MinVoxels.X)[A]-2;
|
||||
@@ -333,9 +328,6 @@ public:
|
||||
Stats.CandidateMergeSeconds);
|
||||
if(!BuildGpuVisualDetailNodeSets(InGpuVisualDetailTiles,InCpuVisualDetailTiles,Error))
|
||||
return false;
|
||||
GpuVisualProxyValidWords.clear();
|
||||
if(bSkipCpuDetailBandForGpuVisuals)
|
||||
GpuVisualProxyValidWords.assign(CandidateWords.size(),0u);
|
||||
Stats.IntervalSeconds=std::chrono::duration<double>(Clock::now()-Stage).count();
|
||||
|
||||
Stage=Clock::now();
|
||||
@@ -777,14 +769,6 @@ public:
|
||||
const uint64 Mask=uint64{1}<<(Zi&63u);
|
||||
if((CandidateWords[Word]&Mask)==0)
|
||||
Out.nearPackedProxy[SampleIndex]=0u;
|
||||
else if(IsSkippedGpuVisualDetailNode(WX,WY,WZ)
|
||||
&&(GpuVisualProxyValidWords[Word]&Mask)==0)
|
||||
{
|
||||
// UINT_MAX asks ApplyNearFieldDetailCS to use its own exact
|
||||
// GPU roughness result instead of a CPU packed proxy.
|
||||
Out.nearPackedProxy[SampleIndex]=std::numeric_limits<uint32>::max();
|
||||
++Out.nearPackedSkippedSampleCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
++Out.nearPackedCandidateSampleCount;
|
||||
@@ -933,8 +917,6 @@ public:
|
||||
{
|
||||
int32 IX=0,IY=0,IZ=0;
|
||||
const bool bInteger=NearInteger(X,IX)&&NearInteger(Y,IY)&&NearInteger(Z,IZ);
|
||||
if(bInteger&&IsSkippedGpuVisualDetailNode(IX,IY,IZ))
|
||||
return GpuSkippedDetailDensityAt(IX,IY,IZ,X,Y,Z);
|
||||
const bool bPacked=!bAnalyticOnly&&bInteger&&Contains(IX,IY,IZ);
|
||||
if(bPacked)
|
||||
return PackedDensityAt(IX,IY,IZ,IsRock(IX,IY,IZ),X,Y,Z);
|
||||
@@ -943,9 +925,6 @@ public:
|
||||
|
||||
float DensityAtLattice(int32 X,int32 Y,int32 Z) const
|
||||
{
|
||||
if(IsSkippedGpuVisualDetailNode(X,Y,Z))
|
||||
return GpuSkippedDetailDensityAt(X,Y,Z,static_cast<float>(X),
|
||||
static_cast<float>(Y),static_cast<float>(Z));
|
||||
const bool bPacked=!bAnalyticOnly&&Contains(X,Y,Z);
|
||||
if(bPacked)
|
||||
return PackedDensityAt(X,Y,Z,IsRock(X,Y,Z),static_cast<float>(X),
|
||||
@@ -959,39 +938,6 @@ public:
|
||||
return AnalyticDensityAt(X,Y,Z,false);
|
||||
}
|
||||
|
||||
float GpuSkippedDetailDensityAt(int32 X,int32 Y,int32 Z,
|
||||
float FX,float FY,float FZ) const
|
||||
{
|
||||
const size_t Column=static_cast<size_t>(Y-Min[1])*Size[0]
|
||||
+static_cast<size_t>(X-Min[0]);
|
||||
const size_t Zi=static_cast<size_t>(Z-Min[2]);
|
||||
const size_t Word=Column*WordsPerZ+(Zi>>6);
|
||||
const uint64 Mask=uint64{1}<<(Zi&63u);
|
||||
if(!GpuVisualProxyValidWords.empty()&&(GpuVisualProxyValidWords[Word]&Mask))
|
||||
return PackedDensityAt(X,Y,Z,IsRock(X,Y,Z),FX,FY,FZ);
|
||||
|
||||
if(CandidateWords[Word]&Mask)
|
||||
{
|
||||
// The GPU-only compile omitted this packed cache entry. Reconstruct the
|
||||
// CPU reference's un-clamped detail density and the same signed Q8.8
|
||||
// proxy when an exceptional CPU mesh or field query needs the sample.
|
||||
const float ExactDensity=AnalyticDensityAt(FX,FY,FZ,false,
|
||||
nullptr,nullptr,nullptr,false);
|
||||
int32 Q=static_cast<int32>(std::lround(ExactDensity*256.0f));
|
||||
Q=std::clamp(Q,-32767,32767);
|
||||
if(Q==0)Q=ExactDensity<0.0f?-1:1;
|
||||
float Density=static_cast<float>(Q)*(1.0f/256.0f);
|
||||
const bool bRock=ExactDensity<=0.0f;
|
||||
if((Density<0.0f)!=bRock)
|
||||
Density=(bRock?-1.0f:1.0f)*std::max(std::abs(Density),1.0f/256.0f);
|
||||
return ApplyEditBrushes(Density,FX,FY,FZ);
|
||||
}
|
||||
|
||||
const bool bRock=((RockWords[Word]&Mask)!=0);
|
||||
constexpr float ProxyBandEdge=DetailSupremum+0.125f;
|
||||
return ApplyEditBrushes(bRock?-ProxyBandEdge:ProxyBandEdge,FX,FY,FZ);
|
||||
}
|
||||
|
||||
VoxelForgeCore::DetailFieldSample DetailSampleAt(float X,float Y,float Z) const
|
||||
{
|
||||
VoxelForgeCore::DetailFieldSample Sample;
|
||||
@@ -1018,18 +964,6 @@ public:
|
||||
OutDensity[Lane]=DensityAtLattice(XStart+Lane*XStep,Y,Z);
|
||||
return;
|
||||
}
|
||||
if(bSkipCpuDetailBandForGpuVisuals)
|
||||
{
|
||||
bool bContainsSkippedNode=false;
|
||||
for(int32 Lane=0;Lane<Count;++Lane)
|
||||
bContainsSkippedNode|=IsSkippedGpuVisualDetailNode(XStart+Lane*XStep,Y,Z);
|
||||
if(bContainsSkippedNode)
|
||||
{
|
||||
for(int32 Lane=0;Lane<Count;++Lane)
|
||||
OutDensity[Lane]=DensityAtLattice(XStart+Lane*XStep,Y,Z);
|
||||
return;
|
||||
}
|
||||
}
|
||||
bool bFast=EditBrushes.empty()&&Y>=Min[1]&&Y<=Max[1]
|
||||
&&Z>=Min[2]&&Z<=Max[2]
|
||||
&&XStart>=Min[0]
|
||||
@@ -1185,9 +1119,6 @@ public:
|
||||
|
||||
bool IsRock(int32 X,int32 Y,int32 Z) const
|
||||
{
|
||||
if(IsSkippedGpuVisualDetailNode(X,Y,Z))
|
||||
return AnalyticDensityAt(static_cast<float>(X),static_cast<float>(Y),
|
||||
static_cast<float>(Z))<=0.0f;
|
||||
if(!Contains(X,Y,Z))return EvaluateFast(X,Y,Z);
|
||||
const size_t Line=static_cast<size_t>(Y-Min[1])*Size[0]
|
||||
+static_cast<size_t>(X-Min[0]);
|
||||
@@ -3342,17 +3273,14 @@ private:
|
||||
if(GpuTiles.empty()&&CpuTiles.empty())
|
||||
{
|
||||
GpuVisualDetailWords.clear();CpuVisualDetailWords.clear();
|
||||
CpuVisualDetailGuardWords.clear();
|
||||
if(bProfileDetailBand)
|
||||
{
|
||||
GpuVisualDetailWords.assign(CandidateWords.size(),0u);
|
||||
CpuVisualDetailWords.assign(CandidateWords.size(),0u);
|
||||
CpuVisualDetailGuardWords.assign(CandidateWords.size(),0u);
|
||||
}
|
||||
GpuVisualDetailTileCount=CpuVisualDetailTileCount=0;
|
||||
GpuVisualDetailGridSamples=CpuVisualDetailGridSamples=0;
|
||||
GpuVisualDetailNodeCount=CpuVisualDetailNodeCount=0;
|
||||
CpuVisualDetailGuardNodeCount=0;
|
||||
return true;
|
||||
}
|
||||
const auto BuildSet=[&](const std::vector<VoxelForgeCore::DetailBandTileRegion>& Tiles,
|
||||
@@ -3403,55 +3331,16 @@ private:
|
||||
GpuVisualDetailNodeCount=0;CpuVisualDetailNodeCount=0;
|
||||
for(const uint64 Bits:GpuVisualDetailWords)GpuVisualDetailNodeCount+=std::popcount(Bits);
|
||||
for(const uint64 Bits:CpuVisualDetailWords)CpuVisualDetailNodeCount+=std::popcount(Bits);
|
||||
CpuVisualDetailGuardWords.assign(CandidateWords.size(),0u);
|
||||
if(bSkipCpuDetailBandForGpuVisuals&&!CpuTiles.empty())
|
||||
{
|
||||
constexpr int32 AxisOffsets[6][3]={{-1,0,0},{1,0,0},{0,-1,0},
|
||||
{0,1,0},{0,0,-1},{0,0,1}};
|
||||
for(size_t Word=0;Word<CpuVisualDetailWords.size();++Word)
|
||||
{
|
||||
uint64 Bits=CpuVisualDetailWords[Word];
|
||||
const size_t Column=Word/WordsPerZ;
|
||||
const int32 X=Min[0]+static_cast<int32>(Column%Size[0]);
|
||||
const int32 Y=Min[1]+static_cast<int32>(Column/Size[0]);
|
||||
const size_t ZiBase=(Word%WordsPerZ)*64u;
|
||||
while(Bits)
|
||||
{
|
||||
const uint32 Bit=std::countr_zero(Bits);Bits&=Bits-1;
|
||||
const size_t Zi=ZiBase+Bit;
|
||||
if(Zi>=static_cast<size_t>(Size[2]))continue;
|
||||
const int32 Z=Min[2]+static_cast<int32>(Zi);
|
||||
for(const auto& Offset:AxisOffsets)
|
||||
{
|
||||
const int32 GX=X+Offset[0],GY=Y+Offset[1],GZ=Z+Offset[2];
|
||||
if(GX<Min[0]||GX>Max[0]||GY<Min[1]||GY>Max[1]
|
||||
||GZ<Min[2]||GZ>Max[2])continue;
|
||||
const size_t GuardColumn=static_cast<size_t>(GY-Min[1])*Size[0]
|
||||
+static_cast<size_t>(GX-Min[0]);
|
||||
const size_t GuardZi=static_cast<size_t>(GZ-Min[2]);
|
||||
const size_t GuardWord=GuardColumn*WordsPerZ+(GuardZi>>6);
|
||||
const uint64 GuardMask=uint64{1}<<(GuardZi&63u);
|
||||
if(CandidateWords[GuardWord]&GuardMask)
|
||||
CpuVisualDetailGuardWords[GuardWord]|=GuardMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CpuVisualDetailGuardNodeCount=0;
|
||||
for(const uint64 Bits:CpuVisualDetailGuardWords)
|
||||
CpuVisualDetailGuardNodeCount+=std::popcount(Bits);
|
||||
GpuVisualDetailTileCount=GpuTiles.size();CpuVisualDetailTileCount=CpuTiles.size();
|
||||
if(!GpuTiles.empty()||!CpuTiles.empty())
|
||||
{
|
||||
std::printf("[GpuVisualDetailBandPlan] gpu_tiles=%llu gpu_sample_nodes=%llu gpu_unique_candidate_nodes=%llu cpu_near_tiles=%llu cpu_sample_nodes=%llu cpu_unique_candidate_nodes=%llu cpu_boundary_guard_candidate_nodes=%llu skip_enabled=%d\n",
|
||||
std::printf("[GpuVisualDetailBandPlan] gpu_tiles=%llu gpu_sample_nodes=%llu gpu_unique_candidate_nodes=%llu cpu_near_tiles=%llu cpu_sample_nodes=%llu cpu_unique_candidate_nodes=%llu\n",
|
||||
static_cast<unsigned long long>(GpuVisualDetailTileCount),
|
||||
static_cast<unsigned long long>(GpuVisualDetailGridSamples),
|
||||
static_cast<unsigned long long>(GpuVisualDetailNodeCount),
|
||||
static_cast<unsigned long long>(CpuVisualDetailTileCount),
|
||||
static_cast<unsigned long long>(CpuVisualDetailGridSamples),
|
||||
static_cast<unsigned long long>(CpuVisualDetailNodeCount),
|
||||
static_cast<unsigned long long>(CpuVisualDetailGuardNodeCount),
|
||||
bSkipCpuDetailBandForGpuVisuals?1:0);
|
||||
static_cast<unsigned long long>(CpuVisualDetailNodeCount));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -3476,25 +3365,6 @@ private:
|
||||
&(uint64{1}<<(Zi&63u)))!=0;
|
||||
}
|
||||
|
||||
bool IsSkippedGpuVisualDetailWord(size_t Word,uint64 Mask) const
|
||||
{
|
||||
return bSkipCpuDetailBandForGpuVisuals
|
||||
&&(GpuVisualDetailWords[Word]&Mask)!=0
|
||||
&&(CpuVisualDetailWords[Word]&Mask)==0
|
||||
&&(CpuVisualDetailGuardWords[Word]&Mask)==0;
|
||||
}
|
||||
|
||||
bool IsSkippedGpuVisualDetailNode(int32 X,int32 Y,int32 Z) const
|
||||
{
|
||||
if(!bSkipCpuDetailBandForGpuVisuals||!Contains(X,Y,Z)
|
||||
||GpuVisualDetailWords.empty())return false;
|
||||
const size_t Column=static_cast<size_t>(Y-Min[1])*Size[0]
|
||||
+static_cast<size_t>(X-Min[0]);
|
||||
const size_t Zi=static_cast<size_t>(Z-Min[2]);
|
||||
return IsSkippedGpuVisualDetailWord(Column*WordsPerZ+(Zi>>6),
|
||||
uint64{1}<<(Zi&63u));
|
||||
}
|
||||
|
||||
void ApplyDetailBand(FParallelTiming& Timing)
|
||||
{
|
||||
using Clock=std::chrono::steady_clock;
|
||||
@@ -3566,25 +3436,16 @@ private:
|
||||
if(std::abs(SDF)>DetailSupremum+0.125f)continue;
|
||||
const size_t VisualWordIndex=WordBase+(Zi>>6);
|
||||
const uint64 VisualMask=uint64{1}<<(Zi&63u);
|
||||
const bool bGpuVisualNode=(bProfile||bSkipCpuDetailBandForGpuVisuals)
|
||||
const bool bGpuVisualNode=bProfile
|
||||
&&(GpuVisualDetailWords[VisualWordIndex]&VisualMask)!=0;
|
||||
const bool bCpuVisualNode=(bProfile||bSkipCpuDetailBandForGpuVisuals)
|
||||
const bool bCpuVisualNode=bProfile
|
||||
&&(CpuVisualDetailWords[VisualWordIndex]&VisualMask)!=0;
|
||||
const bool bSkipDetail=bSkipCpuDetailBandForGpuVisuals&&bGpuVisualNode
|
||||
&&!bCpuVisualNode
|
||||
&&(CpuVisualDetailGuardWords[VisualWordIndex]&VisualMask)==0;
|
||||
if(bProfile)
|
||||
{
|
||||
if(bGpuVisualNode)++Profile.GpuVisualCandidates;
|
||||
if(bCpuVisualNode)++Profile.CpuVisualCandidates;
|
||||
if(bGpuVisualNode&&!bCpuVisualNode)++Profile.GpuOnlyCandidates;
|
||||
}
|
||||
if(bSkipDetail)
|
||||
{
|
||||
ValidBits|=uint64{1}<<(Zi&63u);
|
||||
if(bProfile)++Profile.GpuOnlySkippedCandidateMasks;
|
||||
continue;
|
||||
}
|
||||
const float SurfaceSDF=Sample.SurfaceSDF;
|
||||
const float CaveInfluence=Sample.CaveInfluence;
|
||||
const float FloorInfluence=Sample.FloorInfluence;
|
||||
@@ -3681,7 +3542,7 @@ private:
|
||||
uint64 LayerLookupSampleNs=0,OwnerSampleNs=0,OwnerFieldCalls=0,OwnerActiveCalls=0;
|
||||
uint64 OwnerCacheHits=0,OwnerCacheMisses=0;
|
||||
uint64 GpuVisualCandidates=0,CpuVisualCandidates=0,GpuOnlyCandidates=0;
|
||||
uint64 GpuVisualDetailCalls=0,GpuOnlyDetailCalls=0,GpuOnlySkippedMasks=0;
|
||||
uint64 GpuVisualDetailCalls=0,GpuOnlyDetailCalls=0;
|
||||
for(int32 Worker=0;Worker<WorkerCount;++Worker)
|
||||
{
|
||||
const FDetailWorkerProfile& P=WorkerProfile[static_cast<size_t>(Worker)];
|
||||
@@ -3701,7 +3562,6 @@ private:
|
||||
GpuOnlyCandidates+=P.GpuOnlyCandidates;
|
||||
GpuVisualDetailCalls+=P.GpuVisualDetailEvaluations;
|
||||
GpuOnlyDetailCalls+=P.GpuOnlyDetailEvaluations;
|
||||
GpuOnlySkippedMasks+=P.GpuOnlySkippedCandidateMasks;
|
||||
}
|
||||
const double DistanceAverageNs=DistanceSamples?static_cast<double>(DistanceSampleNs)/DistanceSamples:0.0;
|
||||
const double DetailAverageNs=DetailSamples?static_cast<double>(DetailSampleNs)/DetailSamples:0.0;
|
||||
@@ -3726,14 +3586,12 @@ private:
|
||||
static_cast<unsigned long long>(OwnerCacheHits),
|
||||
static_cast<unsigned long long>(OwnerCacheMisses),
|
||||
static_cast<unsigned long long>(LocalBandSkips));
|
||||
std::printf("[GpuDetailConsumerProfile] gpu_near_proxy_nodes=%llu cpu_near_mesh_nodes=%llu gpu_only_nodes=%llu gpu_near_detail_noise_evaluations=%llu gpu_only_detail_noise_evaluations=%llu gpu_only_skipped_candidate_masks=%llu skip_enabled=%d\n",
|
||||
std::printf("[GpuDetailConsumerProfile] gpu_near_proxy_nodes=%llu cpu_near_mesh_nodes=%llu gpu_only_nodes=%llu gpu_near_detail_noise_evaluations=%llu gpu_only_detail_noise_evaluations=%llu\n",
|
||||
static_cast<unsigned long long>(GpuVisualCandidates),
|
||||
static_cast<unsigned long long>(CpuVisualCandidates),
|
||||
static_cast<unsigned long long>(GpuOnlyCandidates),
|
||||
static_cast<unsigned long long>(GpuVisualDetailCalls),
|
||||
static_cast<unsigned long long>(GpuOnlyDetailCalls),
|
||||
static_cast<unsigned long long>(GpuOnlySkippedMasks),
|
||||
bSkipCpuDetailBandForGpuVisuals?1:0);
|
||||
static_cast<unsigned long long>(GpuOnlyDetailCalls));
|
||||
for(int32 Worker=0;Worker<WorkerCount;++Worker)
|
||||
{
|
||||
const FDetailWorkerProfile& P=WorkerProfile[static_cast<size_t>(Worker)];
|
||||
@@ -3769,8 +3627,6 @@ private:
|
||||
+static_cast<size_t>(X-Min[0]);
|
||||
StoreSurfaceDistance(Node,Density);
|
||||
CandidateWords[Word]|=Mask;
|
||||
if(IsSkippedGpuVisualDetailNode(X,Y,Z))
|
||||
GpuVisualProxyValidWords[Word]|=Mask;
|
||||
++AddedThisPass;
|
||||
|
||||
const bool bExactRock=Density<0.0f;
|
||||
@@ -4821,14 +4677,10 @@ private:
|
||||
std::unique_ptr<int16[]> SurfaceDistanceQ;
|
||||
std::array<std::vector<uint64>,3> CandidateAxisWords;
|
||||
std::vector<uint64> CandidateWords;
|
||||
bool bSkipCpuDetailBandForGpuVisuals=false;
|
||||
std::vector<uint64> GpuVisualDetailWords,CpuVisualDetailWords;
|
||||
std::vector<uint64> CpuVisualDetailGuardWords;
|
||||
uint64 GpuVisualDetailTileCount=0,CpuVisualDetailTileCount=0;
|
||||
uint64 GpuVisualDetailGridSamples=0,CpuVisualDetailGridSamples=0;
|
||||
uint64 GpuVisualDetailNodeCount=0,CpuVisualDetailNodeCount=0;
|
||||
uint64 CpuVisualDetailGuardNodeCount=0;
|
||||
std::vector<uint64> GpuVisualProxyValidWords;
|
||||
FBuildStats Stats;
|
||||
bool bAnalyticOnly=false;
|
||||
};
|
||||
@@ -307,7 +307,7 @@ namespace VoxelForgeCore
|
||||
static_cast<int32>(std::clamp<std::uint32_t>(request.workerLimit,1,8)),ToNative(request.detail),
|
||||
request.includeFarWorld,error,&scheduler,request.roundTunnels,request.profileDetailBand,
|
||||
request.validatePassageRoutes,request.gpuVisualDetailTiles,
|
||||
request.cpuVisualDetailTiles,request.skipCpuDetailBandForGpuVisuals);
|
||||
request.cpuVisualDetailTiles);
|
||||
if(ok)
|
||||
{
|
||||
impl_->shape=std::move(shape);
|
||||
|
||||
Reference in new issue
Block a user