profile: in-process SIGPROF sampler + exclusive route/phase census (L77); closes to 0.1%
Opt-in (L77 build + --linux77-profile; compiled out by default, 0.02% handler cost). FI/TN cost account closes against direct grid-fill timing within 0.15% (LOD0-2 bins within 1.4%). Passage carving = 66% of LOD0-2 CPU (52-54% whole view), passage support 10-14%, base packed + analytic field ~3%. Hotspots: value noise 17%, lower_bound in VisitNearestPassageSpatialNode 14%, ApplyResolvedStratePassageCarves 6.5%. LOD0/1 complete LAST (4.1/4.6 s) while LOD2 is ready at 2.2 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
68cba5a51d
commit
5e091d254c
14 files changed
+1205
-8
No files matched your search
@@ -0,0 +1,159 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace VoxelForgeCore::Linux77Profiler
|
||||
{
|
||||
enum class ERoute : std::uint8_t
|
||||
{
|
||||
Dispatch=0,PackedScalar=1,PackedX8=2,AnalyticScalar=3,
|
||||
AnalyticBatch=4,Native=5,LegacySurface=6,SharedSource=7,Count=8
|
||||
};
|
||||
enum class EStage : std::uint8_t
|
||||
{
|
||||
Other=0,GridFill=1,MarchingCubes=2,Skirt=3,Refine=4,Count=5
|
||||
};
|
||||
enum class EPhase : std::uint8_t
|
||||
{
|
||||
Dispatch=0,BaseField=1,CompositionGraph=2,Bands=3,Passage=4,
|
||||
Support=5,Caps=6,Stamps=7,Edit=8,Other=9,Count=10
|
||||
};
|
||||
inline constexpr std::size_t RouteCount=static_cast<std::size_t>(ERoute::Count);
|
||||
inline constexpr std::size_t StageCount=static_cast<std::size_t>(EStage::Count);
|
||||
inline constexpr std::size_t PhaseCount=static_cast<std::size_t>(EPhase::Count);
|
||||
inline thread_local bool ThreadContextActive=false;
|
||||
|
||||
struct FThreadContext
|
||||
{
|
||||
std::uint8_t lod=0xff;
|
||||
ERoute route=ERoute::Count;
|
||||
EStage stage=EStage::Other;
|
||||
EPhase phase=EPhase::Other;
|
||||
bool halo=false;
|
||||
};
|
||||
|
||||
#if defined(VF_L77_PROFILE)
|
||||
bool IsEnabled() noexcept;
|
||||
void SetEnabled(bool enabled) noexcept;
|
||||
void RegisterThread();
|
||||
void Start(std::uint32_t periodMicroseconds=1000);
|
||||
void StopAndPrint();
|
||||
inline thread_local FThreadContext CurrentContext{};
|
||||
|
||||
struct FScopedRoute
|
||||
{
|
||||
explicit FScopedRoute(ERoute value) noexcept
|
||||
:active(ThreadContextActive),previous(CurrentContext.route)
|
||||
{if(active)CurrentContext.route=value;}
|
||||
~FScopedRoute(){if(active)CurrentContext.route=previous;}
|
||||
bool active=false;ERoute previous=ERoute::Dispatch;
|
||||
};
|
||||
struct FScopedStage
|
||||
{
|
||||
explicit FScopedStage(EStage value) noexcept
|
||||
:active(ThreadContextActive),previous(CurrentContext.stage)
|
||||
{if(active)CurrentContext.stage=value;}
|
||||
~FScopedStage(){Restore();}
|
||||
void Restore() noexcept
|
||||
{if(active){CurrentContext.stage=previous;active=false;}}
|
||||
bool active=false;EStage previous=EStage::Other;
|
||||
};
|
||||
struct FScopedPhase
|
||||
{
|
||||
explicit FScopedPhase(EPhase value) noexcept
|
||||
:active(ThreadContextActive),previous(CurrentContext.phase)
|
||||
{if(active)CurrentContext.phase=value;}
|
||||
~FScopedPhase(){if(active)CurrentContext.phase=previous;}
|
||||
bool active=false;EPhase previous=EPhase::Dispatch;
|
||||
};
|
||||
struct FScopedLod
|
||||
{
|
||||
explicit FScopedLod(int value) noexcept
|
||||
:active(IsEnabled()),previous(CurrentContext.lod),previousContextActive(ThreadContextActive)
|
||||
{
|
||||
if(active)
|
||||
{
|
||||
ThreadContextActive=true;
|
||||
RegisterThread();
|
||||
CurrentContext.lod=static_cast<std::uint8_t>(value<0||value>8?0xff:value);
|
||||
}
|
||||
}
|
||||
~FScopedLod()
|
||||
{if(active){CurrentContext.lod=previous;ThreadContextActive=previousContextActive;}}
|
||||
bool active=false;std::uint8_t previous=0xff;
|
||||
bool previousContextActive=false;
|
||||
};
|
||||
struct FScopedHalo
|
||||
{
|
||||
explicit FScopedHalo(bool value) noexcept
|
||||
:active(ThreadContextActive),previous(CurrentContext.halo)
|
||||
{if(active)CurrentContext.halo=value;}
|
||||
~FScopedHalo(){if(active)CurrentContext.halo=previous;}
|
||||
bool active=false;bool previous=false;
|
||||
};
|
||||
#else
|
||||
inline bool IsEnabled() noexcept{return false;}
|
||||
inline void SetEnabled(bool) noexcept{}
|
||||
inline void RegisterThread(){}
|
||||
inline void Start(std::uint32_t=1000){}
|
||||
inline void StopAndPrint(){}
|
||||
struct FScopedRoute{explicit FScopedRoute(ERoute) noexcept{}};
|
||||
struct FScopedStage
|
||||
{explicit FScopedStage(EStage) noexcept{}void Restore() noexcept{}};
|
||||
struct FScopedPhase{explicit FScopedPhase(EPhase) noexcept{}};
|
||||
struct FScopedLod{explicit FScopedLod(int) noexcept{}};
|
||||
struct FScopedHalo{explicit FScopedHalo(bool) noexcept{}};
|
||||
#endif
|
||||
|
||||
struct FDispatchCounter
|
||||
{
|
||||
std::uint64_t calls=0;
|
||||
std::uint64_t points=0;
|
||||
};
|
||||
using FDispatchCounters=std::array<std::array<FDispatchCounter,RouteCount>,StageCount>;
|
||||
|
||||
inline const char* RouteName(ERoute value) noexcept
|
||||
{
|
||||
switch(value)
|
||||
{
|
||||
case ERoute::Dispatch:return "dispatch_lookup";
|
||||
case ERoute::PackedScalar:return "packed_scalar";
|
||||
case ERoute::PackedX8:return "packed_x8";
|
||||
case ERoute::AnalyticScalar:return "analytic_scalar";
|
||||
case ERoute::AnalyticBatch:return "analytic_batch";
|
||||
case ERoute::Native:return "native";
|
||||
case ERoute::LegacySurface:return "legacy_surface";
|
||||
case ERoute::SharedSource:return "shared_source";
|
||||
default:return "unknown";
|
||||
}
|
||||
}
|
||||
inline const char* StageName(EStage value) noexcept
|
||||
{
|
||||
switch(value)
|
||||
{
|
||||
case EStage::GridFill:return "grid_fill";
|
||||
case EStage::MarchingCubes:return "marching_cubes";
|
||||
case EStage::Skirt:return "skirt";
|
||||
case EStage::Refine:return "refine";
|
||||
default:return "other";
|
||||
}
|
||||
}
|
||||
inline const char* PhaseName(EPhase value) noexcept
|
||||
{
|
||||
switch(value)
|
||||
{
|
||||
case EPhase::Dispatch:return "dispatch_lookup";
|
||||
case EPhase::BaseField:return "base_field";
|
||||
case EPhase::CompositionGraph:return "composition_graph";
|
||||
case EPhase::Bands:return "composition_bands";
|
||||
case EPhase::Passage:return "passages";
|
||||
case EPhase::Support:return "support";
|
||||
case EPhase::Caps:return "caps";
|
||||
case EPhase::Stamps:return "stamps";
|
||||
case EPhase::Edit:return "edits";
|
||||
default:return "other";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "VoxelForgeCore/Linux77Profiler.h"
|
||||
|
||||
// UBT supplies this export/import macro for the runtime module. The standalone target has no
|
||||
// module boundary, so leave it empty there. UBT fournit la macro; le viewer autonome reste neutre.
|
||||
#ifndef VOXELFORGECORE_API
|
||||
@@ -170,6 +172,13 @@ namespace VoxelForgeCore
|
||||
std::array<std::uint64_t,9> legacyFieldTermCalls{};
|
||||
std::array<std::uint64_t,9> legacyFieldTermNanoseconds{};
|
||||
std::array<std::uint64_t,9> legacyFieldTermTimedCalls{};
|
||||
// Linux77-only mutually-exclusive route counts, flattened as
|
||||
// (stage * route_count + route) * 2 + {calls,points}.
|
||||
std::array<std::uint64_t,
|
||||
VoxelForgeCore::Linux77Profiler::StageCount
|
||||
*VoxelForgeCore::Linux77Profiler::RouteCount*2> linux77DispatchCounters{};
|
||||
std::uint64_t linux77GridInteriorSamples = 0;
|
||||
std::uint64_t linux77GridHaloSamples = 0;
|
||||
std::uint64_t legacyPrimitiveCandidateVisits = 0;
|
||||
std::uint64_t legacyPrimitiveDistanceEvaluations = 0;
|
||||
std::uint64_t legacySmoothMinCalls = 0;
|
||||
@@ -1797,6 +1806,8 @@ namespace VoxelForgeCore
|
||||
// Research-only: collect tile-drain kernel counters and floating-island cache metrics.
|
||||
// Inactive on ordinary generation so the hot path only pays the option check.
|
||||
bool instrumentTileDrain = false;
|
||||
// Linux headless measurement only. Compiled out of ordinary builds.
|
||||
bool linux77Profile = false;
|
||||
bool exactMidpointDensityMemo = false;
|
||||
bool activeLaneBatching = false;
|
||||
std::uint32_t proofBlockCells = 8;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "VoxelForgeCore/VoxelForgeCore.h"
|
||||
#include "VoxelForgeFieldShared.h"
|
||||
#include "VoxelForgeCore/FloatingIslandInstrumentation.h"
|
||||
#include "VoxelForgeCore/Linux77Profiler.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
@@ -988,6 +989,8 @@ public:
|
||||
|
||||
float ApplyResolvedStratePassageCarves(float density,float X,float Y,float Z) const
|
||||
{
|
||||
VoxelForgeCore::Linux77Profiler::FScopedPhase l77PassagePhase(
|
||||
VoxelForgeCore::Linux77Profiler::EPhase::Passage);
|
||||
if(!ResolvedLayout||ResolvedLayout->passages.empty()||!std::isfinite(X)
|
||||
||!std::isfinite(Y)||!std::isfinite(Z))return density;
|
||||
constexpr double Q=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
|
||||
@@ -1028,6 +1031,8 @@ public:
|
||||
float deferredSupportDensity=std::numeric_limits<float>::infinity();
|
||||
const auto composeRouteMouthSupport=[&](std::size_t passageIndex)
|
||||
{
|
||||
VoxelForgeCore::Linux77Profiler::FScopedPhase l77MouthSupportPhase(
|
||||
VoxelForgeCore::Linux77Profiler::EPhase::Support);
|
||||
// Surface-route treads may reinforce native solid terrain only.
|
||||
if(!(density<0.0f))return;
|
||||
if(passageIndex>=ResolvedLayout->passages.size()
|
||||
@@ -1882,8 +1887,14 @@ public:
|
||||
supportCenterIndex+1);
|
||||
selectedSupportSegmentIndex=supportCenterIndex>0
|
||||
?supportCenterIndex-1:supportCenterIndex;
|
||||
for(std::ptrdiff_t index=supportBegin;index<=supportEnd;++index)
|
||||
considerSupportSegment(index);
|
||||
{
|
||||
VoxelForgeCore::Linux77Profiler::FScopedPhase l77SupportSearchPhase(
|
||||
VoxelForgeCore::Linux77Profiler::EPhase::Support);
|
||||
for(std::ptrdiff_t index=supportBegin;index<=supportEnd;++index)
|
||||
considerSupportSegment(index);
|
||||
}
|
||||
VoxelForgeCore::Linux77Profiler::FScopedPhase l77SupportApplyPhase(
|
||||
VoxelForgeCore::Linux77Profiler::EPhase::Support);
|
||||
// Keep route treads inside the native rock envelope. Carving may reopen the
|
||||
// floor above this point, but a support cannot create a new surface in air.
|
||||
const bool passageColumnFloorSupport=hasSupportFloor
|
||||
@@ -1994,6 +2005,8 @@ public:
|
||||
{
|
||||
float graphDensity=0.0f;
|
||||
{
|
||||
VoxelForgeCore::Linux77Profiler::FScopedPhase l77GraphPhase(
|
||||
VoxelForgeCore::Linux77Profiler::EPhase::CompositionGraph);
|
||||
FScopedLegacyFieldTermTimer TermTimer(ELegacyFieldTerm::ComposerCavern);
|
||||
graphDensity=ApplyResolvedCavernGraph(density,X,Y,Z);
|
||||
}
|
||||
@@ -2009,6 +2022,8 @@ public:
|
||||
float boundary=graphDensity;
|
||||
if(!nativeLattice)
|
||||
{
|
||||
VoxelForgeCore::Linux77Profiler::FScopedPhase l77BandsPhase(
|
||||
VoxelForgeCore::Linux77Profiler::EPhase::Bands);
|
||||
FScopedLegacyFieldTermTimer TermTimer(ELegacyFieldTerm::ComposerBoundary);
|
||||
boundary=ApplyResolvedStrateBoundaryBand(graphDensity,X,Y,Z);
|
||||
}
|
||||
@@ -2018,6 +2033,8 @@ public:
|
||||
float composed=boundary;
|
||||
if(!nativeLattice)
|
||||
{
|
||||
VoxelForgeCore::Linux77Profiler::FScopedPhase l77PassagePhase(
|
||||
VoxelForgeCore::Linux77Profiler::EPhase::Passage);
|
||||
FScopedLegacyFieldTermTimer TermTimer(
|
||||
ELegacyFieldTerm::ComposerPassageAndSupport);
|
||||
composed=ApplyResolvedStratePassageCarves(boundary,X,Y,Z);
|
||||
@@ -2025,6 +2042,8 @@ public:
|
||||
float stamped=composed;
|
||||
if(!StampRuntime.empty())
|
||||
{
|
||||
VoxelForgeCore::Linux77Profiler::FScopedPhase l77StampPhase(
|
||||
VoxelForgeCore::Linux77Profiler::EPhase::Stamps);
|
||||
FScopedLegacyFieldTermTimer TermTimer(ELegacyFieldTerm::ComposerStamps);
|
||||
stamped=ApplyResolvedSdfStamps(composed,X,Y,Z);
|
||||
}
|
||||
@@ -2050,6 +2069,8 @@ public:
|
||||
// already combine each floor with its wall before the single void carve above.
|
||||
float final=0.0f;
|
||||
{
|
||||
VoxelForgeCore::Linux77Profiler::FScopedPhase l77CapsPhase(
|
||||
VoxelForgeCore::Linux77Profiler::EPhase::Caps);
|
||||
FScopedLegacyFieldTermTimer TermTimer(
|
||||
ELegacyFieldTerm::ComposerPassageAndSupport);
|
||||
final=ApplyResolvedCavernFloorCaps(stamped,X,Y,Z);
|
||||
@@ -2230,6 +2251,7 @@ public:
|
||||
std::array<uint64,LegacyFieldTermCount> LegacyFieldTermCalls{};
|
||||
std::array<uint64,LegacyFieldTermCount> LegacyFieldTermNanoseconds{};
|
||||
std::array<uint64,LegacyFieldTermCount> LegacyFieldTermTimedCalls{};
|
||||
VoxelForgeCore::Linux77Profiler::FDispatchCounters Linux77DispatchCounters{};
|
||||
uint64 LegacyPrimitiveCandidateVisits=0,LegacyPrimitiveDistanceEvaluations=0;
|
||||
uint64 LegacySmoothMinCalls=0,LegacySmoothMinNanoseconds=0,
|
||||
LegacySmoothMinTimedCalls=0;
|
||||
@@ -2248,6 +2270,21 @@ public:
|
||||
{ThreadClassificationStats().CaptureDensityQueryProfile=Enabled;}
|
||||
static FClassificationThreadStats GetThreadClassificationStats()
|
||||
{ return ThreadClassificationStats(); }
|
||||
static void RecordLinux77Dispatch(VoxelForgeCore::Linux77Profiler::ERoute route,
|
||||
uint64 points)
|
||||
{
|
||||
#if defined(VF_L77_PROFILE)
|
||||
using namespace VoxelForgeCore::Linux77Profiler;
|
||||
if(!ThreadContextActive)return;
|
||||
const auto stage=static_cast<std::size_t>(CurrentContext.stage);
|
||||
const auto routeIndex=static_cast<std::size_t>(route);
|
||||
if(stage>=StageCount||routeIndex>=RouteCount)return;
|
||||
auto& counter=ThreadClassificationStats().Linux77DispatchCounters[stage][routeIndex];
|
||||
++counter.calls;counter.points+=points;
|
||||
#else
|
||||
(void)route;(void)points;
|
||||
#endif
|
||||
}
|
||||
enum class EDensityQueryKind : uint8 { Float=0,Lattice=1,Unclamped=2,X8=3 };
|
||||
static uint32& DensityQuerySuppressionDepth()
|
||||
{static thread_local uint32 Depth=0;return Depth;}
|
||||
@@ -3400,8 +3437,14 @@ public:
|
||||
{
|
||||
if(SharedDensitySource)return SharedDensitySource->DensityAt(X,Y,Z);
|
||||
FScopedDensityQueryProfile queryProfile(EDensityQueryKind::Float);
|
||||
using namespace VoxelForgeCore::Linux77Profiler;
|
||||
FScopedRoute l77DispatchRoute(ERoute::Dispatch);
|
||||
FScopedPhase l77DispatchPhase(EPhase::Dispatch);
|
||||
if(bNativeOnly)
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::Native,1);
|
||||
FScopedRoute l77Route(ERoute::Native);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
if(!NativeOnlyContains(X,Y,Z))
|
||||
{RecordNativeOnlyViolation();return 0.0f;}
|
||||
float NativeDensity=0.0f;
|
||||
@@ -3412,22 +3455,41 @@ public:
|
||||
float IslandDensity=0.0f;
|
||||
if(NativeFloatingIslandDensityAt(X,Y,Z,IslandDensity))
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::Native,1);
|
||||
FScopedRoute l77Route(ERoute::Native);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
++ThreadClassificationStats().NativeFloatFieldCalls;
|
||||
return ApplyEditBrushes(ApplyResolvedStrateComposition(IslandDensity,X,Y,Z),X,Y,Z);
|
||||
}
|
||||
float NativeDensity=0.0f;
|
||||
if(NativeSurfaceDensityAt(X,Y,Z,NativeDensity))
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::Native,1);
|
||||
FScopedRoute l77Route(ERoute::Native);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
++ThreadClassificationStats().NativeFloatFieldCalls;
|
||||
return ApplyEditBrushes(ApplyResolvedStrateComposition(NativeDensity,X,Y,Z),X,Y,Z);
|
||||
}
|
||||
if(UsesLegacySurfaceField(X,Y,Z))
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::LegacySurface,1);
|
||||
FScopedRoute l77Route(ERoute::LegacySurface);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
return LegacySurfaceDensityAt(X,Y,Z);
|
||||
}
|
||||
int32 IX=0,IY=0,IZ=0;
|
||||
const bool bInteger=NearInteger(X,IX)&&NearInteger(Y,IY)&&NearInteger(Z,IZ);
|
||||
const bool bPacked=!bAnalyticOnly&&bInteger&&Contains(IX,IY,IZ);
|
||||
if(bPacked)
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::PackedScalar,1);
|
||||
FScopedRoute l77Route(ERoute::PackedScalar);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
return PackedDensityAt(IX,IY,IZ,IsRock(IX,IY,IZ),X,Y,Z);
|
||||
}
|
||||
RecordLinux77Dispatch(ERoute::AnalyticScalar,1);
|
||||
FScopedRoute l77Route(ERoute::AnalyticScalar);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
return AnalyticDensityAt(X,Y,Z);
|
||||
}
|
||||
|
||||
@@ -3474,10 +3536,22 @@ public:
|
||||
|
||||
float DensityAtLattice(int32 X,int32 Y,int32 Z) const
|
||||
{
|
||||
if(SharedDensitySource)return SharedDensitySource->DensityAtLattice(X,Y,Z);
|
||||
using namespace VoxelForgeCore::Linux77Profiler;
|
||||
if(SharedDensitySource)
|
||||
{
|
||||
if(ThreadContextActive)RecordLinux77Dispatch(ERoute::SharedSource,1);
|
||||
FScopedRoute l77Route(ERoute::SharedSource);
|
||||
FScopedPhase l77Phase(EPhase::BaseField);
|
||||
return SharedDensitySource->DensityAtLattice(X,Y,Z);
|
||||
}
|
||||
FScopedDensityQueryProfile queryProfile(EDensityQueryKind::Lattice);
|
||||
FScopedRoute l77DispatchRoute(ERoute::Dispatch);
|
||||
FScopedPhase l77DispatchPhase(EPhase::Dispatch);
|
||||
if(bNativeOnly)
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::Native,1);
|
||||
FScopedRoute l77Route(ERoute::Native);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
if(!NativeOnlyContains(static_cast<float>(X),static_cast<float>(Y),
|
||||
static_cast<float>(Z)))
|
||||
{RecordNativeOnlyViolation();return 0.0f;}
|
||||
@@ -3491,6 +3565,9 @@ public:
|
||||
if(NativeFloatingIslandDensityAt(static_cast<float>(X),static_cast<float>(Y),
|
||||
static_cast<float>(Z),IslandDensity))
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::Native,1);
|
||||
FScopedRoute l77Route(ERoute::Native);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
++ThreadClassificationStats().NativeLatticeFieldCalls;
|
||||
return ApplyEditBrushes(ApplyResolvedStrateComposition(IslandDensity,X,Y,Z),X,Y,Z);
|
||||
}
|
||||
@@ -3498,13 +3575,21 @@ public:
|
||||
if(NativeSurfaceDensityAt(static_cast<float>(X),static_cast<float>(Y),
|
||||
static_cast<float>(Z),NativeDensity))
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::Native,1);
|
||||
FScopedRoute l77Route(ERoute::Native);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
++ThreadClassificationStats().NativeLatticeFieldCalls;
|
||||
return ApplyEditBrushes(ApplyResolvedStrateComposition(NativeDensity,X,Y,Z),X,Y,Z);
|
||||
}
|
||||
if(UsesLegacySurfaceField(static_cast<float>(X),static_cast<float>(Y),
|
||||
static_cast<float>(Z)))
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::LegacySurface,1);
|
||||
FScopedRoute l77Route(ERoute::LegacySurface);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
return LegacySurfaceDensityAt(static_cast<float>(X),static_cast<float>(Y),
|
||||
static_cast<float>(Z));
|
||||
}
|
||||
const bool bPacked=!bAnalyticOnly&&Contains(X,Y,Z);
|
||||
static const bool bL75TraceTnDensity=[]
|
||||
{
|
||||
@@ -3545,18 +3630,38 @@ public:
|
||||
}
|
||||
}
|
||||
if(bPacked)
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::PackedScalar,1);
|
||||
FScopedRoute l77Route(ERoute::PackedScalar);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
return PackedDensityAt(X,Y,Z,IsRock(X,Y,Z),static_cast<float>(X),
|
||||
static_cast<float>(Y),static_cast<float>(Z));
|
||||
}
|
||||
RecordLinux77Dispatch(ERoute::AnalyticScalar,1);
|
||||
FScopedRoute l77Route(ERoute::AnalyticScalar);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
return AnalyticDensityAt(static_cast<float>(X),static_cast<float>(Y),
|
||||
static_cast<float>(Z));
|
||||
}
|
||||
|
||||
float DensityAtUnclamped(float X,float Y,float Z) const
|
||||
{
|
||||
if(SharedDensitySource)return SharedDensitySource->DensityAtUnclamped(X,Y,Z);
|
||||
using namespace VoxelForgeCore::Linux77Profiler;
|
||||
if(SharedDensitySource)
|
||||
{
|
||||
if(ThreadContextActive)RecordLinux77Dispatch(ERoute::SharedSource,1);
|
||||
FScopedRoute l77Route(ERoute::SharedSource);
|
||||
FScopedPhase l77Phase(EPhase::BaseField);
|
||||
return SharedDensitySource->DensityAtUnclamped(X,Y,Z);
|
||||
}
|
||||
FScopedDensityQueryProfile queryProfile(EDensityQueryKind::Unclamped);
|
||||
FScopedRoute l77DispatchRoute(ERoute::Dispatch);
|
||||
FScopedPhase l77DispatchPhase(EPhase::Dispatch);
|
||||
if(bNativeOnly)
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::Native,1);
|
||||
FScopedRoute l77Route(ERoute::Native);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
if(!NativeOnlyContains(X,Y,Z))
|
||||
{RecordNativeOnlyViolation();return 0.0f;}
|
||||
float NativeDensity=0.0f;
|
||||
@@ -3567,17 +3672,31 @@ public:
|
||||
float IslandDensity=0.0f;
|
||||
if(NativeFloatingIslandDensityAt(X,Y,Z,IslandDensity))
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::Native,1);
|
||||
FScopedRoute l77Route(ERoute::Native);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
++ThreadClassificationStats().NativeUnclampedFieldCalls;
|
||||
return ApplyEditBrushes(ApplyResolvedStrateComposition(IslandDensity,X,Y,Z),X,Y,Z);
|
||||
}
|
||||
float NativeDensity=0.0f;
|
||||
if(NativeSurfaceDensityAt(X,Y,Z,NativeDensity))
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::Native,1);
|
||||
FScopedRoute l77Route(ERoute::Native);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
++ThreadClassificationStats().NativeUnclampedFieldCalls;
|
||||
return ApplyEditBrushes(ApplyResolvedStrateComposition(NativeDensity,X,Y,Z),X,Y,Z);
|
||||
}
|
||||
if(UsesLegacySurfaceField(X,Y,Z))
|
||||
{
|
||||
RecordLinux77Dispatch(ERoute::LegacySurface,1);
|
||||
FScopedRoute l77Route(ERoute::LegacySurface);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
return LegacySurfaceDensityAt(X,Y,Z);
|
||||
}
|
||||
RecordLinux77Dispatch(ERoute::AnalyticScalar,1);
|
||||
FScopedRoute l77Route(ERoute::AnalyticScalar);
|
||||
FScopedPhase l77Base(EPhase::BaseField);
|
||||
return AnalyticDensityAt(X,Y,Z,false);
|
||||
}
|
||||
|
||||
@@ -3602,13 +3721,20 @@ public:
|
||||
void DensityAtLatticeX8(int32 XStart,int32 XStep,int32 Y,int32 Z,
|
||||
int32 Count,float OutDensity[8]) const
|
||||
{
|
||||
using namespace VoxelForgeCore::Linux77Profiler;
|
||||
if(SharedDensitySource)
|
||||
{
|
||||
if(ThreadContextActive&&Count>0)RecordLinux77Dispatch(ERoute::SharedSource,
|
||||
static_cast<uint64>(Count));
|
||||
FScopedRoute l77Route(ERoute::SharedSource);
|
||||
FScopedPhase l77Phase(EPhase::BaseField);
|
||||
SharedDensitySource->DensityAtLatticeX8(XStart,XStep,Y,Z,Count,OutDensity);
|
||||
return;
|
||||
}
|
||||
Count=std::clamp(Count,0,8);
|
||||
if(Count==0)return;
|
||||
FScopedRoute l77DispatchRoute(ERoute::Dispatch);
|
||||
FScopedPhase l77DispatchPhase(EPhase::Dispatch);
|
||||
FScopedDensityQueryProfile queryProfile(EDensityQueryKind::X8,
|
||||
static_cast<uint64>(Count));
|
||||
FScopedDensityQueryBatch queryBatch(queryProfile.IsActive());
|
||||
@@ -3681,6 +3807,10 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if(ThreadContextActive)RecordLinux77Dispatch(ERoute::PackedX8,
|
||||
static_cast<uint64>(Count));
|
||||
FScopedRoute l77PackedRoute(ERoute::PackedX8);
|
||||
FScopedPhase l77PackedBase(EPhase::BaseField);
|
||||
const size_t ColumnStart=static_cast<size_t>(Y-Min[1])*Size[0]
|
||||
+static_cast<size_t>(XStart-Min[0]);
|
||||
const size_t Zi=static_cast<size_t>(Z-Min[2]);
|
||||
@@ -7794,6 +7924,8 @@ private:
|
||||
|
||||
float ApplyEditBrushes(float Density,double X,double Y,double Z) const
|
||||
{
|
||||
VoxelForgeCore::Linux77Profiler::FScopedPhase l77EditPhase(
|
||||
VoxelForgeCore::Linux77Profiler::EPhase::Edit);
|
||||
if(EditBrushes.empty()||X<EditBoundsMin.X||X>EditBoundsMax.X
|
||||
||Y<EditBoundsMin.Y||Y>EditBoundsMax.Y||Z<EditBoundsMin.Z||Z>EditBoundsMax.Z)
|
||||
return Density;
|
||||
@@ -8492,6 +8624,8 @@ private:
|
||||
|
||||
float ApplyResolvedCavernFloorCaps(float density,float X,float Y,float Z) const
|
||||
{
|
||||
VoxelForgeCore::Linux77Profiler::FScopedPhase l77CapsPhase(
|
||||
VoxelForgeCore::Linux77Profiler::EPhase::Caps);
|
||||
if(CavernRuntime.empty()||!Owner||Owner->CoreVoxelSizeMicrons==0)return density;
|
||||
const auto* tileQueries=ActivePassageTileQueries;
|
||||
const bool scoped=tileQueries&&tileQueries->matches(*this);
|
||||
@@ -11462,12 +11596,19 @@ public:
|
||||
void DensityAtLatticeZRun(int32 X,int32 Y,int32 ZStart,int32 ZStep,
|
||||
int32 Count,float* OutDensity) const
|
||||
{
|
||||
using namespace VoxelForgeCore::Linux77Profiler;
|
||||
if(SharedDensitySource)
|
||||
{
|
||||
if(ThreadContextActive&&Count>0)RecordLinux77Dispatch(ERoute::SharedSource,
|
||||
static_cast<uint64>(Count));
|
||||
FScopedRoute l77Route(ERoute::SharedSource);
|
||||
FScopedPhase l77Phase(EPhase::BaseField);
|
||||
SharedDensitySource->DensityAtLatticeZRun(X,Y,ZStart,ZStep,Count,OutDensity);
|
||||
return;
|
||||
}
|
||||
if(Count<=0||OutDensity==nullptr)return;
|
||||
FScopedRoute l77DispatchRoute(ERoute::Dispatch);
|
||||
FScopedPhase l77DispatchPhase(EPhase::Dispatch);
|
||||
FScopedDensityQueryProfile queryProfile(EDensityQueryKind::Lattice,
|
||||
static_cast<uint64>(Count));
|
||||
FScopedDensityQueryBatch queryBatch(queryProfile.IsActive());
|
||||
@@ -11513,6 +11654,10 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if(ThreadContextActive)RecordLinux77Dispatch(ERoute::AnalyticBatch,
|
||||
static_cast<uint64>(Count));
|
||||
FScopedRoute l77BatchRoute(ERoute::AnalyticBatch);
|
||||
FScopedPhase l77BatchBase(EPhase::BaseField);
|
||||
FDetailNoiseLineContext DetailNoiseLine(
|
||||
static_cast<float>(X),static_cast<float>(Y),static_cast<uint32>(Owner->Seed));
|
||||
for(int32 Offset=0;Offset<Count;)
|
||||
|
||||
@@ -1997,6 +1997,7 @@ namespace VoxelForgeCore
|
||||
std::optional<TileMesh> World::generateTile(const TileKey& key,const TileGenerationOptions& options,
|
||||
std::string& error) const
|
||||
{
|
||||
VoxelForgeCore::Linux77Profiler::FScopedLod l77Lod(key.lod);
|
||||
// Fine owner tiles had zero direct-map conflict evictions in the cold audit. Keep their
|
||||
// single-probe path and use associativity for the coarse coordinate families that collide.
|
||||
// Les tuiles proches n'avaient aucun conflit; garder leur acces simple et associer les LOD grossiers.
|
||||
@@ -2162,6 +2163,22 @@ namespace VoxelForgeCore
|
||||
TileMesh out;out.key=key;
|
||||
const auto CopyIslandCacheMetrics=[&]()
|
||||
{
|
||||
if(options.linux77Profile)
|
||||
{
|
||||
const auto& QueryCounts=FStandaloneShapeWorld::GetThreadClassificationStats();
|
||||
for(std::size_t Stage=0;Stage<VoxelForgeCore::Linux77Profiler::StageCount;++Stage)
|
||||
for(std::size_t Route=0;Route<VoxelForgeCore::Linux77Profiler::RouteCount;++Route)
|
||||
{
|
||||
const std::size_t Index=(Stage*VoxelForgeCore::Linux77Profiler::RouteCount
|
||||
+Route)*2;
|
||||
out.diagnostics.linux77DispatchCounters[Index]=
|
||||
QueryCounts.Linux77DispatchCounters[Stage][Route].calls;
|
||||
out.diagnostics.linux77DispatchCounters[Index+1]=
|
||||
QueryCounts.Linux77DispatchCounters[Stage][Route].points;
|
||||
}
|
||||
out.diagnostics.linux77GridInteriorSamples=McStageTimings.DensityGridInteriorSamples;
|
||||
out.diagnostics.linux77GridHaloSamples=McStageTimings.DensityGridHaloSamples;
|
||||
}
|
||||
if(options.instrumentTileDrain)
|
||||
{
|
||||
const auto& QueryCounts=FStandaloneShapeWorld::GetThreadClassificationStats();
|
||||
@@ -2789,6 +2806,8 @@ namespace VoxelForgeCore
|
||||
const double MeshingMilliseconds=std::chrono::duration<double,std::milli>(
|
||||
std::chrono::steady_clock::now()-MeshingStart).count();
|
||||
out.diagnostics.farHorizonVersion=key.lod>=4?options.farHorizonVersion:0;
|
||||
VoxelForgeCore::Linux77Profiler::FScopedStage l77RefineStage(
|
||||
VoxelForgeCore::Linux77Profiler::EStage::Refine);
|
||||
const auto FarShellStart=std::chrono::steady_clock::now();
|
||||
const FStandaloneShapeWorld& farShape=tileShape.HasFarWorld()?tileShape:
|
||||
(bShapeReady?*impl_->shape:tileShape);
|
||||
@@ -2922,6 +2941,7 @@ namespace VoxelForgeCore
|
||||
AppendStratumBoundaryFloors(world,farShape,nativeKey,step,mesh);
|
||||
AppendStratumBoundaryCeilings(world,farShape,nativeKey,step,mesh);
|
||||
}
|
||||
l77RefineStage.Restore();
|
||||
|
||||
out.densitySampleCount=static_cast<std::uint64_t>(std::max<int64>(0,sampleCount));
|
||||
if(bHasWorldAssembly)
|
||||
|
||||
Reference in new issue
Block a user