the other thing I was working on (main thread metrics)
This commit is contained in:
parent
89ca3efb3e
commit
f0d552c47b
@ -309,21 +309,6 @@
|
|||||||
"jitter scale": 0.0625,
|
"jitter scale": 0.0625,
|
||||||
"preset": "native" // native (1x), quality (1.5x), balanced (1.7x), performance (2.0x), ultra (3.0x)
|
"preset": "native" // native (1x), quality (1.5x), balanced (1.7x), performance (2.0x), ultra (3.0x)
|
||||||
},
|
},
|
||||||
"reactphysics": {
|
|
||||||
"global storage": false,
|
|
||||||
"timescale": 0.01666666666, // 0.03333333333,
|
|
||||||
"interpolate": true,
|
|
||||||
"gravity": {
|
|
||||||
"mode": "default", // default / per-object / universal
|
|
||||||
"constant": 6.67408e-11
|
|
||||||
},
|
|
||||||
"debug draw": {
|
|
||||||
"enabled": false,
|
|
||||||
"line width": 8,
|
|
||||||
"layer": "Gui",
|
|
||||||
"rate": 0.0125
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"vr" : {
|
"vr" : {
|
||||||
"enable" : false,
|
"enable" : false,
|
||||||
"manifest": "./data/openvr_manifest.json",
|
"manifest": "./data/openvr_manifest.json",
|
||||||
@ -349,7 +334,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"memory pool": {
|
"memory pool": {
|
||||||
"enabled": true, // needs to be kept on for GC
|
"enabled": true,
|
||||||
"subPools": true,
|
"subPools": true,
|
||||||
"alignment": 64,
|
"alignment": 64,
|
||||||
"override": true,
|
"override": true,
|
||||||
@ -363,7 +348,7 @@
|
|||||||
"render modes": { "gui": true, "deferred": true },
|
"render modes": { "gui": true, "deferred": true },
|
||||||
"limiters": {
|
"limiters": {
|
||||||
"deltaTime": 5,
|
"deltaTime": 5,
|
||||||
"framerate": "auto" // "auto" // for some reason drops to 60
|
"framerate": "auto"
|
||||||
},
|
},
|
||||||
"threads": {
|
"threads": {
|
||||||
"workers" : "auto",
|
"workers" : "auto",
|
||||||
|
|||||||
@ -192,7 +192,6 @@ void main() {
|
|||||||
if ( projectedSize < 0.08 ) lodLevel = 2;
|
if ( projectedSize < 0.08 ) lodLevel = 2;
|
||||||
if ( projectedSize < 0.02 ) lodLevel = 3;
|
if ( projectedSize < 0.02 ) lodLevel = 3;
|
||||||
lodLevel = min(lodLevel, MAX_LODS - 1);
|
lodLevel = min(lodLevel, MAX_LODS - 1);
|
||||||
lodLevel = 3;
|
|
||||||
|
|
||||||
LOD lod = lodMetadata[drawCommand.instanceID].levels[lodLevel];
|
LOD lod = lodMetadata[drawCommand.instanceID].levels[lodLevel];
|
||||||
|
|
||||||
|
|||||||
@ -726,16 +726,8 @@ void UF_API uf::initialize() {
|
|||||||
payload["scene"] = uf::config["engine"]["scenes"]["start"];
|
payload["scene"] = uf::config["engine"]["scenes"]["start"];
|
||||||
/*global*/::sceneTransition.payload = payload;
|
/*global*/::sceneTransition.payload = payload;
|
||||||
/*global*/::sceneTransition.phase = 0;
|
/*global*/::sceneTransition.phase = 0;
|
||||||
|
|
||||||
// auto& scene = uf::scene::loadScene( uf::config["engine"]["scenes"]["start"] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
uf::thread::add( uf::thread::fetchWorker(), [&]{
|
|
||||||
uf::asset::processQueue();
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
uf::ready = true;
|
uf::ready = true;
|
||||||
UF_MSG_INFO("EXT took {} seconds to initialize", /*global*/::times.sys.elapsed().asDouble());
|
UF_MSG_INFO("EXT took {} seconds to initialize", /*global*/::times.sys.elapsed().asDouble());
|
||||||
}
|
}
|
||||||
@ -743,13 +735,20 @@ void UF_API uf::initialize() {
|
|||||||
void UF_API uf::tick() {
|
void UF_API uf::tick() {
|
||||||
++uf::time::frame;
|
++uf::time::frame;
|
||||||
|
|
||||||
|
static pod::Thread& threadMain = uf::thread::get(uf::thread::mainThreadName);
|
||||||
|
#if UF_THREAD_METRICS
|
||||||
|
auto activeStart = std::chrono::high_resolution_clock::now();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
// skip the next tick to load the next scene to ensure nothing's happening
|
||||||
if ( /*global*/::sceneTransition.phase >= 0 ) {
|
if ( /*global*/::sceneTransition.phase >= 0 ) {
|
||||||
auto target = /*global*/::sceneTransition.payload["scene"].as<uf::stl::string>();
|
auto target = /*global*/::sceneTransition.payload["scene"].as<uf::stl::string>();
|
||||||
auto& phase = /*global*/::sceneTransition.phase;
|
auto& phase = /*global*/::sceneTransition.phase;
|
||||||
|
|
||||||
++phase;
|
++phase;
|
||||||
|
|
||||||
|
// might be necessary since i bluescreened with a dedicated thread
|
||||||
#if UF_USE_VULKAN
|
#if UF_USE_VULKAN
|
||||||
uf::renderer::flushCommandBuffers();
|
uf::renderer::flushCommandBuffers();
|
||||||
#endif
|
#endif
|
||||||
@ -775,9 +774,6 @@ void UF_API uf::tick() {
|
|||||||
uf::renderer::flushCommandBuffers();
|
uf::renderer::flushCommandBuffers();
|
||||||
#endif
|
#endif
|
||||||
uf::renderer::synchronize();
|
uf::renderer::synchronize();
|
||||||
|
|
||||||
// uf::scene::tick();
|
|
||||||
// uf::renderer::tick();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -844,7 +840,7 @@ void UF_API uf::tick() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Tick Main Thread Queue */ {
|
/* Tick Main Thread Queue */ {
|
||||||
uf::thread::process( uf::thread::get(uf::thread::mainThreadName) );
|
uf::thread::process( threadMain );
|
||||||
}
|
}
|
||||||
#if UF_USE_ULTRALIGHT
|
#if UF_USE_ULTRALIGHT
|
||||||
/* Ultralight-UX */ if ( /*global*/::config.engine.ext.ultralight.enabled ) {
|
/* Ultralight-UX */ if ( /*global*/::config.engine.ext.ultralight.enabled ) {
|
||||||
@ -865,6 +861,66 @@ void UF_API uf::tick() {
|
|||||||
ext::imgui::tick();
|
ext::imgui::tick();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// perform GC on entities
|
||||||
|
if ( /*global*/::config.engine.gc.enabled ) {
|
||||||
|
TIMER( /*global*/::config.engine.gc.every ) {
|
||||||
|
size_t collected = uf::instantiator::collect( /*global*/::config.engine.gc.mode );
|
||||||
|
if ( collected > 0 ) {
|
||||||
|
if ( /*global*/::config.engine.gc.announce ) UF_MSG_DEBUG("GC collected {} unused entities", (int) collected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if UF_THREAD_METRICS
|
||||||
|
// Mark the end of active work and the start of idle/sleep time
|
||||||
|
auto idleStart = std::chrono::high_resolution_clock::now();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !UF_ENV_DREAMCAST
|
||||||
|
if ( /*global*/::times.limiter > 0 ) {
|
||||||
|
static auto nextFrameTime = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
double limiterMs = /*global*/::times.limiter * 1000.0;
|
||||||
|
auto limiterDuration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(std::chrono::duration<double, std::milli>(limiterMs));
|
||||||
|
nextFrameTime += limiterDuration;
|
||||||
|
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
if ( now < nextFrameTime ) {
|
||||||
|
auto timeRemaining = nextFrameTime - now;
|
||||||
|
if ( timeRemaining > std::chrono::milliseconds(2) ) std::this_thread::sleep_for(timeRemaining - std::chrono::milliseconds(1));
|
||||||
|
while ( std::chrono::steady_clock::now() < nextFrameTime ) std::this_thread::yield();
|
||||||
|
} else {
|
||||||
|
nextFrameTime = std::chrono::steady_clock::now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& controller = uf::scene::getCurrentScene().getController();
|
||||||
|
if ( /*global*/::requestDedicatedRenderThread && controller.getName() == "Player" ) {
|
||||||
|
/*global*/::requestDedicatedRenderThread = false;
|
||||||
|
uf::renderer::settings::experimental::dedicatedThread = true;
|
||||||
|
UF_MSG_DEBUG("Dedicated render requested");
|
||||||
|
}
|
||||||
|
#if UF_USE_VULKAN
|
||||||
|
if ( /*global*/::requestDeferredCommandBufferSubmit && controller.getName() == "Player" ) {
|
||||||
|
/*global*/::requestDeferredCommandBufferSubmit = false;
|
||||||
|
uf::renderer::settings::defaultCommandBufferImmediate = false;
|
||||||
|
UF_MSG_DEBUG("Defer command buffer submit requested");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UF_THREAD_METRICS
|
||||||
|
auto tickEnd = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
std::chrono::duration<float, std::milli> activeTime = idleStart - activeStart;
|
||||||
|
std::chrono::duration<float, std::milli> idleTime = tickEnd - idleStart;
|
||||||
|
std::chrono::duration<float, std::milli> frameTime = tickEnd - activeStart;
|
||||||
|
|
||||||
|
threadMain.metrics.activeTimeMs.store(activeTime.count(), std::memory_order_relaxed);
|
||||||
|
threadMain.metrics.idleTimeMs.store(idleTime.count(), std::memory_order_relaxed);
|
||||||
|
threadMain.metrics.totalFrameTimeMs.store(frameTime.count(), std::memory_order_relaxed);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* FPS Print */ if ( /*global*/::config.engine.fps.print ) {
|
/* FPS Print */ if ( /*global*/::config.engine.fps.print ) {
|
||||||
++/*global*/::times.frames;
|
++/*global*/::times.frames;
|
||||||
++/*global*/::times.total.frames;
|
++/*global*/::times.total.frames;
|
||||||
@ -881,48 +937,6 @@ void UF_API uf::tick() {
|
|||||||
/*global*/::times.frames = 0;
|
/*global*/::times.frames = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& controller = uf::scene::getCurrentScene().getController();
|
|
||||||
|
|
||||||
// to-do: handle when the memory pool is disabled, because entities are NOT cleaned up at all
|
|
||||||
// should also handle entity deletion when GC is disabled
|
|
||||||
if ( /*global*/::config.engine.gc.enabled ) {
|
|
||||||
TIMER( /*global*/::config.engine.gc.every ) {
|
|
||||||
size_t collected = uf::instantiator::collect( /*global*/::config.engine.gc.mode );
|
|
||||||
if ( collected > 0 ) {
|
|
||||||
if ( /*global*/::config.engine.gc.announce ) UF_MSG_DEBUG("GC collected {} unused entities", (int) collected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if !UF_ENV_DREAMCAST
|
|
||||||
if ( /*global*/::times.limiter > 0 ) {
|
|
||||||
double limiter = /*global*/::times.limiter * 1000.0;
|
|
||||||
|
|
||||||
static uf::Timer<long long> timer(false);
|
|
||||||
if ( !timer.running() ) timer.start();
|
|
||||||
auto elapsed = timer.elapsed().asMilliseconds();
|
|
||||||
if ( elapsed < limiter ) {
|
|
||||||
std::chrono::duration<double, std::milli> delta(limiter - elapsed);
|
|
||||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(delta);
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(duration.count()));
|
|
||||||
}
|
|
||||||
timer.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( /*global*/::requestDedicatedRenderThread && controller.getName() == "Player" ) {
|
|
||||||
/*global*/::requestDedicatedRenderThread = false;
|
|
||||||
uf::renderer::settings::experimental::dedicatedThread = true;
|
|
||||||
UF_MSG_DEBUG("Dedicated render requested");
|
|
||||||
}
|
|
||||||
#if UF_USE_VULKAN
|
|
||||||
if ( /*global*/::requestDeferredCommandBufferSubmit && controller.getName() == "Player" ) {
|
|
||||||
/*global*/::requestDeferredCommandBufferSubmit = false;
|
|
||||||
uf::renderer::settings::defaultCommandBufferImmediate = false;
|
|
||||||
UF_MSG_DEBUG("Defer command buffer submit requested");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
void UF_API uf::render() {
|
void UF_API uf::render() {
|
||||||
if ( uf::scene::scenes.empty() ) return;
|
if ( uf::scene::scenes.empty() ) return;
|
||||||
|
|||||||
@ -66,7 +66,7 @@ bool ext::meshopt::optimize( uf::Mesh& mesh, float simplify, size_t o, bool verb
|
|||||||
uf::stl::vector<meshopt_Stream> streams;
|
uf::stl::vector<meshopt_Stream> streams;
|
||||||
for ( auto& attr : mesh.vertex.attributes ) {
|
for ( auto& attr : mesh.vertex.attributes ) {
|
||||||
const uint8_t* basePtr = (const uint8_t*)attr.pointer + srcVertexOffset * attr.stride;
|
const uint8_t* basePtr = (const uint8_t*)attr.pointer + srcVertexOffset * attr.stride;
|
||||||
streams.emplace_back({ basePtr, attr.descriptor.size, attr.stride });
|
streams.emplace_back(meshopt_Stream{ basePtr, attr.descriptor.size, attr.stride });
|
||||||
}
|
}
|
||||||
|
|
||||||
// deduplicate vertices
|
// deduplicate vertices
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user