store publish dt in snapshot

This commit is contained in:
jacob 2025-02-19 13:49:07 -06:00
parent a5bbdffbe3
commit cb05b707f0
3 changed files with 43 additions and 48 deletions

View File

@ -33,7 +33,7 @@
#define SPACE_CELL_BUCKETS_SQRT (256) #define SPACE_CELL_BUCKETS_SQRT (256)
#define SPACE_CELL_SIZE 1.0f #define SPACE_CELL_SIZE 1.0f
#define SIM_TICKS_PER_SECOND 50 #define SIM_TICKS_PER_SECOND 100
#define SIM_TIMESCALE 1 #define SIM_TIMESCALE 1
#define SIM_PHYSICS_SUBSTEPS 4 #define SIM_PHYSICS_SUBSTEPS 4
@ -52,7 +52,7 @@
/* How many ticks back in time should the user blend between? /* How many ticks back in time should the user blend between?
* <Delay ms> = <USER_INTERP_RATIO> * <Tick interval> * <Delay ms> = <USER_INTERP_RATIO> * <Tick interval>
* E.g: At 1.5, the user thread will render 75ms back in time (if sim thread runs at 50 TPS) * E.g: At 1.5, the user thread will render 75ms back in time if the sim runs at 50tps
*/ */
#define USER_INTERP_RATIO 1.5 #define USER_INTERP_RATIO 1.5
#define USER_INTERP_ENABLED 1 #define USER_INTERP_ENABLED 1
@ -73,4 +73,4 @@
#define AUDIO_ENABLED 0 #define AUDIO_ENABLED 0
#define VSYNC_ENABLED 0 #define VSYNC_ENABLED 0
#define USER_FRAME_LIMIT 300 #define USER_FPS_LIMIT 300

View File

@ -42,9 +42,11 @@ struct sim_snapshot {
struct arena arena; struct arena arena;
i64 published_at_ns; /* Time of local snapshot publish to user */
i64 publish_dt_ns;
i64 publish_time_ns;
/* Real time (increases with clock assuming no lag) */ /* Real time (guaranteed to increase by real_dt_ns each sim step) */
i64 real_dt_ns; i64 real_dt_ns;
i64 real_time_ns; i64 real_time_ns;

View File

@ -98,9 +98,9 @@ GLOBAL struct {
struct sim_snapshot_store *local_sim_ss_store; struct sim_snapshot_store *local_sim_ss_store;
/* Rolling window of local sim publish times */ /* Rolling window of local sim publish times */
i64 snapshot_publish_times_ns[50];
i64 snapshot_publish_times_index;
i64 last_snapshot_published_at_ns; i64 last_snapshot_published_at_ns;
i64 snapshot_publish_dts_ns[50];
i64 snapshot_publish_dts_index;
i64 average_snapshot_publish_dt_ns; i64 average_snapshot_publish_dt_ns;
/* Calculated from <last snapshot receive time + time since packet receive> */ /* Calculated from <last snapshot receive time + time since packet receive> */
@ -419,10 +419,10 @@ INTERNAL void user_update(void)
#if 0 #if 0
G.last_snapshot_received_at_ns = G.real_time_ns; G.last_snapshot_received_at_ns = G.real_time_ns;
#else #else
G.last_snapshot_published_at_ns = src->published_at_ns; G.last_snapshot_published_at_ns = src->publish_time_ns;
G.snapshot_publish_times_ns[G.snapshot_publish_times_index++] = src->published_at_ns; G.snapshot_publish_dts_ns[G.snapshot_publish_dts_index++] = src->publish_dt_ns;
if (G.snapshot_publish_times_index >= (i64)ARRAY_COUNT(G.snapshot_publish_times_ns)) { if (G.snapshot_publish_dts_index >= (i64)ARRAY_COUNT(G.snapshot_publish_dts_ns)) {
G.snapshot_publish_times_index = 0; G.snapshot_publish_dts_index = 0;
} }
#endif #endif
} }
@ -437,28 +437,13 @@ INTERNAL void user_update(void)
i64 average_publish_dt_ns = 0; i64 average_publish_dt_ns = 0;
{ {
i64 num_dts = 0; i64 num_dts = 0;
for (i64 offset = 0; offset < (i64)ARRAY_COUNT(G.snapshot_publish_times_ns); ++offset) { for (u64 i = 0; i < ARRAY_COUNT(G.snapshot_publish_dts_ns); ++i) {
i64 t0_index = G.snapshot_publish_times_index + offset - 1; i64 dt_ns = G.snapshot_publish_dts_ns[i];
if (t0_index < 0) { if (dt_ns != 0) {
t0_index += ARRAY_COUNT(G.snapshot_publish_times_ns); average_publish_dt_ns += dt_ns;
} else if (t0_index >= (i64)ARRAY_COUNT(G.snapshot_publish_times_ns)) {
t0_index -= ARRAY_COUNT(G.snapshot_publish_times_ns);
}
i64 t1_index = G.snapshot_publish_times_index + offset;
if (t1_index < 0) {
t1_index += ARRAY_COUNT(G.snapshot_publish_times_ns);
} else if (t1_index >= (i64)ARRAY_COUNT(G.snapshot_publish_times_ns)) {
t1_index -= ARRAY_COUNT(G.snapshot_publish_times_ns);
}
i64 t0 = G.snapshot_publish_times_ns[t0_index];
i64 t1 = G.snapshot_publish_times_ns[t1_index];
if (t0 != 0 && t1 != 0 && t1 > t0) {
i64 dt = t1 - t0;
average_publish_dt_ns += dt;
++num_dts; ++num_dts;
} else {
break;
} }
} }
if (num_dts > 0) { if (num_dts > 0) {
@ -534,7 +519,7 @@ INTERNAL void user_update(void)
} }
#else #else
/* Interp disabled, just copy latest snapshot */ /* Interp disabled, just copy latest snapshot */
G.render_time_target_ns = G.local_sim_predicted_time_ns; G.render_time_target_ns = newest_snapshot->real_time_ns;
G.render_time_ns = newest_snapshot->real_time_ns; G.render_time_ns = newest_snapshot->real_time_ns;
if (G.ss_blended->tick != newest_snapshot->tick) { if (G.ss_blended->tick != newest_snapshot->tick) {
if (G.ss_blended->valid) { if (G.ss_blended->valid) {
@ -1383,19 +1368,23 @@ INTERNAL void user_update(void)
switch (bind) { switch (bind) {
/* Movement */ /* Movement */
case USER_BIND_KIND_MOVE_UP: { case USER_BIND_KIND_MOVE_UP:
{
input_move_dir.y -= 1; input_move_dir.y -= 1;
} break; } break;
case USER_BIND_KIND_MOVE_DOWN: { case USER_BIND_KIND_MOVE_DOWN:
{
input_move_dir.y += 1; input_move_dir.y += 1;
} break; } break;
case USER_BIND_KIND_MOVE_LEFT: { case USER_BIND_KIND_MOVE_LEFT:
{
input_move_dir.x -= 1; input_move_dir.x -= 1;
} break; } break;
case USER_BIND_KIND_MOVE_RIGHT: { case USER_BIND_KIND_MOVE_RIGHT:
{
input_move_dir.x += 1; input_move_dir.x += 1;
} break; } break;
@ -1716,7 +1705,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg)
(UNUSED)arg; (UNUSED)arg;
i64 last_frame_ns = 0; i64 last_frame_ns = 0;
i64 target_dt_ns = NS_FROM_SECONDS(USER_FRAME_LIMIT > (0) ? (1.0 / USER_FRAME_LIMIT) : 0); i64 target_dt_ns = NS_FROM_SECONDS(USER_FPS_LIMIT > (0) ? (1.0 / USER_FPS_LIMIT) : 0);
while (!atomic_i32_eval(&G.user_thread_shutdown)) { while (!atomic_i32_eval(&G.user_thread_shutdown)) {
__profscope(user_update_w_sleep); __profscope(user_update_w_sleep);
@ -1749,8 +1738,9 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
struct sim_snapshot *prev_ss = sim_snapshot_nil(); struct sim_snapshot *prev_ss = sim_snapshot_nil();
i64 last_publish_ns = 0;
i64 last_tick_ns = 0; i64 last_tick_ns = 0;
i64 target_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND;; i64 target_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND;
while (!atomic_i32_eval(&G.local_sim_thread_shutdown)) { while (!atomic_i32_eval(&G.local_sim_thread_shutdown)) {
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
{ {
@ -1812,8 +1802,11 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
{ {
struct sys_lock lock = sys_mutex_lock_e(&G.local_sim_ss_mutex); struct sys_lock lock = sys_mutex_lock_e(&G.local_sim_ss_mutex);
struct sim_snapshot *pub_ss = sim_snapshot_alloc(G.local_sim_ss_store, ss, ss->tick); struct sim_snapshot *pub_ss = sim_snapshot_alloc(G.local_sim_ss_store, ss, ss->tick);
pub_ss->published_at_ns = sys_time_ns();
sim_snapshot_store_release_ticks_in_range(G.local_sim_ss_store, 0, pub_ss->tick - 1); sim_snapshot_store_release_ticks_in_range(G.local_sim_ss_store, 0, pub_ss->tick - 1);
i64 publish_ns = sys_time_ns();
pub_ss->publish_dt_ns = publish_ns - last_publish_ns;
pub_ss->publish_time_ns = publish_ns;
last_publish_ns = publish_ns;
sys_mutex_unlock(&lock); sys_mutex_unlock(&lock);
} }