diff --git a/code2/host/host.odin b/code2/host/host.odin index 1ad97af..c899b1d 100644 --- a/code2/host/host.odin +++ b/code2/host/host.odin @@ -114,7 +114,7 @@ main :: proc() host_memory.tick_running = true host_memory.tick_lanes = THREAD_TICK_LANES barrier_init(& host_memory.lane_sync, THREAD_TICK_LANES) - if THREAD_TICK_LANES > 1 { + when THREAD_TICK_LANES > 1 { for id in 1 ..= (THREAD_TICK_LANES - 1) { launch_tick_lane_thread(cast(WorkerID) id) } @@ -184,7 +184,7 @@ host_tick_lane :: proc() { profile("Host Tick") - running: b64 = host_memory.client_api.tick_lane( duration_seconds(delta_ns), delta_ns ) == false + running: b64 = host_memory.client_api.tick_lane(duration_seconds(delta_ns), delta_ns) == false if thread_memory.id == .Master_Prepper { sync_store(& host_memory.tick_running, running, .Release) } @@ -218,10 +218,17 @@ host_job_worker_entrypoint :: proc(worker_thread: ^SysThread) host_memory.client_api.tick_lane_startup(& thread_memory) grime_set_profiler_thread_buffer(& thread_memory.spall_buffer) } + delta_ns: Duration + host_tick := time_tick_now() for ; sync_load(& host_memory.job_system.running, .Relaxed); { profile("Host Job Tick") - host_memory.client_api.jobsys_worker_tick() + + host_memory.client_api.jobsys_worker_tick(duration_seconds(delta_ns), delta_ns) + + delta_ns = time_tick_lap_time( & host_tick ) + host_tick = time_tick_now() + if sync_load(& host_memory.client_api_hot_reloaded, .Acquire) { // Signals to main hread when all jobs have drained. leader :=barrier_wait(& host_memory.job_hot_reload_sync) diff --git a/code2/sectr/engine/client_api.odin b/code2/sectr/engine/client_api.odin index ddc1b18..47588f1 100644 --- a/code2/sectr/engine/client_api.odin +++ b/code2/sectr/engine/client_api.odin @@ -41,6 +41,44 @@ startup :: proc(host_mem: ^ProcessMemory, thread_mem: ^ThreadMemory) grime_set_profiler_module_context(& memory.spall_context) grime_set_profiler_thread_buffer(& thread.spall_buffer) profile(#procedure) + + using memory.client_memory + + // Configuration Load + // TODO(Ed): Make this actually load from an ini + { + using config + resolution_width = 1000 + resolution_height = 600 + refresh_rate = 0 + + cam_min_zoom = 0.001 + cam_max_zoom = 5.0 + cam_zoom_mode = .Smooth + cam_zoom_smooth_snappiness = 4.0 + cam_zoom_sensitivity_smooth = 0.5 + cam_zoom_sensitivity_digital = 0.25 + cam_zoom_scroll_delta_scale = 0.25 + + engine_refresh_hz = 240 + + timing_fps_moving_avg_alpha = 0.9 + + ui_resize_border_width = 5 + + // color_theme = App_Thm_Dusk + + text_snap_glyph_shape_position = false + text_snap_glyph_render_height = false + text_size_screen_scalar = 1.4 + text_size_canvas_scalar = 1.4 + text_alpha_sharpen = 0.1 + } + + Desired_OS_Scheduler_MS :: 1 + sleep_is_granular = set__scheduler_granularity( Desired_OS_Scheduler_MS ) + + } /* @@ -130,7 +168,7 @@ tick_lane :: proc(host_delta_time_ms: f64, host_delta_ns: Duration) -> (should_c @static timer: f64 if thread.id == .Master_Prepper { timer += host_delta_time_ms - sync_store(& should_close, timer > EXIT_TIME, .Release) + // sync_store(& should_close, timer > EXIT_TIME, .Release) } // profile_end() @@ -145,20 +183,21 @@ tick_lane :: proc(host_delta_time_ms: f64, host_delta_ns: Duration) -> (should_c job_dispatch_single(& memory.job_exit[job_id], .Normal) } } + client_tick := tick_now() profile_end() // profile_begin("sokol_app: post_client_tick") // profile_end() - tick_lane_frametime() + tick_lane_frametime(& client_tick, host_delta_time_ms, host_delta_ns) return sync_load(& should_close, .Acquire) } @export -jobsys_worker_tick :: proc() +jobsys_worker_tick :: proc(host_delta_time_ms: f64, host_delta_ns: Duration) { - profile("Worker Tick") + // profile("Worker Tick") ORDERED_PRIORITIES :: [len(JobPriority)]JobPriority{.High, .Normal, .Low} block: for priority in ORDERED_PRIORITIES @@ -166,6 +205,7 @@ jobsys_worker_tick :: proc() if memory.job_system.job_lists[priority].head == nil do continue if sync_mutex_try_lock(& memory.job_system.job_lists[priority].mutex) { + profile("Executing Job") if job := memory.job_system.job_lists[priority].head; job != nil { if int(thread.id) in job.ignored { @@ -185,6 +225,12 @@ jobsys_worker_tick :: proc() sync_mutex_unlock(& memory.job_system.job_lists[priority].mutex) } } + + // Updating worker frametime + { + // TODO(Ed): Setup + + } } TestJobInfo :: struct { @@ -199,22 +245,20 @@ test_job :: proc(data: rawptr) Frametime_High_Perf_Threshold_MS :: 1 / 240.0 -tick_lane_frametime :: proc() +tick_lane_frametime :: proc(client_tick: ^Tick, host_delta_time_ms: f64, host_delta_ns: Duration, can_sleep := true) { profile(#procedure) config := app_config() - frametime := get_frametime() + frametime := & memory.client_memory.frametime // context.allocator = frame_slab_allocator() // context.temp_allocator = transient_allocator() - profile("Client tick timing processing") - if thread.id == .Master_Prepper { frametime.target_ms = 1.0 / f64(config.engine_refresh_hz) * S_To_MS sub_ms_granularity_required := frametime.target_ms <= Frametime_High_Perf_Threshold_MS - frametime.delta_ns = time_tick_lap_time( client_tick ) + frametime.delta_ns = tick_lap_time( client_tick ) frametime.delta_ms = duration_ms( frametime.delta_ns ) frametime.delta_seconds = duration_seconds( host_delta_ns ) frametime.elapsed_ms = frametime.delta_ms + host_delta_time_ms @@ -222,14 +266,14 @@ tick_lane_frametime :: proc() if frametime.elapsed_ms < frametime.target_ms { sleep_ms := frametime.target_ms - frametime.elapsed_ms - pre_sleep_tick := time_tick_now() + pre_sleep_tick := tick_now() if can_sleep && sleep_ms > 0 { // thread_sleep( cast(Duration) sleep_ms * MS_To_NS ) // thread__highres_wait( sleep_ms ) } - sleep_delta_ns := time_tick_lap_time( & pre_sleep_tick) + sleep_delta_ns := tick_lap_time( & pre_sleep_tick) sleep_delta_ms := duration_ms( sleep_delta_ns ) if sleep_delta_ms < sleep_ms { @@ -238,7 +282,7 @@ tick_lane_frametime :: proc() frametime.elapsed_ms += sleep_delta_ms for ; frametime.elapsed_ms < frametime.target_ms; { - sleep_delta_ns = time_tick_lap_time( & pre_sleep_tick) + sleep_delta_ns = tick_lap_time( & pre_sleep_tick) sleep_delta_ms = duration_ms( sleep_delta_ns ) frametime.elapsed_ms += sleep_delta_ms @@ -258,7 +302,6 @@ tick_lane_frametime :: proc() else { // Non-main thread tick lane timing (since they are in lock-step this should be minimal delta) - } } diff --git a/code2/sectr/math.odin b/code2/sectr/math.odin index a9e80e6..1ea65ec 100644 --- a/code2/sectr/math.odin +++ b/code2/sectr/math.odin @@ -13,6 +13,8 @@ import "base:intrinsics" import "core:math" import la "core:math/linalg" +@private IS_NUMERIC :: intrinsics.type_is_numeric + Axis2 :: enum i32 { Invalid = -1, X = 0, @@ -48,7 +50,7 @@ is_power_of_two_u32 :: #force_inline proc "contextless" (value: u32) -> b32 { re mov_avg_exp_f32 := #force_inline proc "contextless" (alpha, delta_interval, last_value: f32) -> f32 { return (delta_interval * alpha) + (delta_interval * (1.0 - alpha)) } mov_avg_exp_f64 := #force_inline proc "contextless" (alpha, delta_interval, last_value: f64) -> f64 { return (delta_interval * alpha) + (delta_interval * (1.0 - alpha)) } -Q_F4 :: quaternion128 +Quat_F4 :: quaternion128 V2_S4 :: [2]i32 V3_S4 :: [3]i32 @@ -68,10 +70,25 @@ sub_r2f4 :: #force_inline proc "contextless" (a, b: R2_F4) -> R2_F4 { return r equal_r2f4 :: #force_inline proc "contextless" (a, b: R2_F4) -> b32 { result := a.p0 == b.p0 && a.p1 == b.p1; return b32(result) } // Will resolve the largest range possible given a & b. -join_r2f4 :: #force_inline proc "contextless" (a, b: R2_F4) -> (joined : R2_F4) { joined.p0 = min( a.min, b.min ); joined.p1 = max( a.max, b.max ); return } -size_range2 :: #force_inline proc "contextless" (value: R2_F4) -> V2_F4 { return { abs( value.p1.x - value.p0.x ), abs( value.p0.y - value.p1.y ) } } +join_r2f4 :: #force_inline proc "contextless" (a, b: R2_F4) -> (joined : R2_F4) { joined.p0 = min(a.p0, b.p0); joined.p1 = max(a.p1, b.p1); return } +size_r2f4 :: #force_inline proc "contextless" (value: R2_F4) -> V2_F4 { return {abs(value.p1.x - value.p0.x), abs(value.p0.y - value.p1.y) }} -cross_s :: la.scalar_cross +min :: la.min +max :: la.max + +sqrt :: la.sqrt + +sdot :: la.scalar_dot +vdot :: la.vector_dot +qdot_f2 :: la.quaternion64_dot +qdot_f4 :: la.quaternion128_dot +qdot_f8 :: la.quaternion256_dot +inner_product :: dot +outer_product :: intrinsics.outer_product + +cross_s :: la.scalar_cross +cross_v2 :: la.vector_cross2 +cross_v3 :: la.vector_cross3 /* V2_F2: 2D Vector (4-Byte Float) 4D Extension (x, y, z : 0, w : 0) @@ -92,24 +109,6 @@ v2f4_from_scalar :: #force_inline proc "contextless" (scalar: f32 ) -> V2_F4 { v2f4_from_v2s4 :: #force_inline proc "contextless" (v2i: V2_S4) -> V2_F4 { return {f32(v2i.x), f32(v2i.y)}} v2s4_from_v2f4 :: #force_inline proc "contextless" (v2: V2_F4) -> V2_S4 { return {i32(v2.x), i32(v2.y) }} -// vec2_64_from_vec2 :: #force_inline proc "contextless" ( v2 : Vec2 ) -> Vec2_64 { return { f64(v2.x), f64(v2.y) }} - -// dot_v2f4 :: #force_inline proc "contextless" (a, b: V2_F4) -> (s: f32) { -// x := a.x * b.x -// y := a.y + b.y -// s = x + y -// return -// } -sdot :: la.scalar_dot -vdot :: la.vector_dot -qdot_f2 :: la.quaternion64_dot -qdot_f4 :: la.quaternion128_dot -qdot_f8 :: la.quaternion256_dot -inner_product :: dot -outer_product :: intrinsics.outer_product - -cross_v2 :: la.vector_cross2 - /* PointFlat2 : CGA: 2D flat point (x, y, z) Line : PGA: 2D line (x, y, z) @@ -119,9 +118,6 @@ P2_F4 :: distinct V2_F4 PF2_F4 :: distinct V3_F4 L2_F4 :: distinct V3_F4 -//endregion PGA 2 - -//region PGA 3 /* V3_F4: 3D Vector (x, y, z) (3x1) 4D Expression : (x, y, z, 0) BiV3_F4: 3D Bivector (yz, zx, xy) (3x1) @@ -165,31 +161,29 @@ v3f4_via_f32s :: #force_inline proc "contextless" (x, y, z: f32) -> V3_F4 { retu // complement_vec3 :: #force_inline proc "contextless" ( v : Vec3 ) -> Bivec3 {return transmute(Bivec3) v} -cross_v3 :: la.vector_cross3 - inverse_mag_v3f4 :: #force_inline proc "contextless" (v: V3_F4) -> (result : f32) { square := pow2_v3f4(v); result = inverse_sqrt_f32( square ); return } magnitude_v3f4 :: #force_inline proc "contextless" (v: V3_F4) -> (mag: f32) { square := pow2_v3f4(v); mag = sqrt(square); return } -normalize_v3f4 :: #force_inline proc "contextless" (v: V3_F4) -> (unit_v: UV3_F4) { unit_v = transmute(UnitVec3) (v * inverse_mag_v3f4(v)); return } +normalize_v3f4 :: #force_inline proc "contextless" (v: V3_F4) -> (unit_v: UV3_F4) { unit_v = transmute(UV3_F4) (v * inverse_mag_v3f4(v)); return } -pow2_v3f4 :: #force_inline proc "contextless" (v: V3_F4) -> (s: f32) { return dot_v3f4(v, v) } +pow2_v3f4 :: #force_inline proc "contextless" (v: V3_F4) -> (s: f32) { return vdot(v, v) } -project_v3f4 :: proc "contextless" (a, b: V3_F4) -> (a_to_b: V3_F4) { panic_contextless("not implemented"); return } -reject_v3f4 :: proc "contextless" (a, b: V3_F4 ) -> (a_from_b: V3_F4) { panic_contextless("not implemented"); return } +project_v3f4 :: proc "contextless" (a, b: V3_F4) -> (a_to_b: V3_F4) { panic_contextless("not implemented") } +reject_v3f4 :: proc "contextless" (a, b: V3_F4 ) -> (a_from_b: V3_F4) { panic_contextless("not implemented") } -project_v3f4_uv3f4 :: #force_inline proc "contextless" (v: V3_F4, u: UV3_F4) -> (v_to_u: V3_F4) { inner := dot_v3f4(v, u); v_to_u = (transmute(V3_F4) u) * inner; return } -project_uv3f4_v3f4 :: #force_inline proc "contextless" (u : UV3_F4, v : V3_F4) -> (u_to_v: V3_F4) { inner := dot_v3f4(u, v); u_to_v = v * inner; return } +project_v3f4_uv3f4 :: #force_inline proc "contextless" (v: V3_F4, u: UV3_F4) -> (v_to_u: V3_F4) { inner := vdot(v, v3(u)); v_to_u = v3(u) * inner; return } +project_uv3f4_v3f4 :: #force_inline proc "contextless" (u: UV3_F4, v: V3_F4) -> (u_to_v: V3_F4) { inner := vdot(v3(u), v); u_to_v = v * inner; return } // Anti-wedge of vectors regress_v3f4 :: #force_inline proc "contextless" (a, b : V3_F4) -> f32 { return a.x * b.y - a.y * b.x } -reject_v3f4_uv3f4 :: #force_inline proc "contextless" (v: V3_F4, u: UV3_F4) -> ( v_from_u: V3_F4) { inner := dot_v3f4(v, u); v_from_u = (v - (transmute(Vec3) u)) * inner; return } -reject_uv3f4_v3f4 :: #force_inline proc "contextless" (v: V3_F4, u: UV3_F4) -> ( u_from_v: V3_F4) { inner := dot_v3f4(u, v); u_from_v = ((transmute(Vec3) u) - v) * inner; return } +reject_v3f4_uv3f4 :: #force_inline proc "contextless" (v: V3_F4, u: UV3_F4) -> ( v_from_u: V3_F4) { inner := vdot(v, v3(u)); v_from_u = (v - v3(u)) * inner; return } +reject_uv3f4_v3f4 :: #force_inline proc "contextless" (v: V3_F4, u: UV3_F4) -> ( u_from_v: V3_F4) { inner := vdot(v3(u), v); u_from_v = (v3(u) - v) * inner; return } // Combines the deimensions that are present in a & b wedge_v3f4 :: #force_inline proc "contextless" (a, b: V3_F4) -> (bv : BiV3_F4) { yzx_zxy := a.yzx * b.zxy zxy_yzx := a.zxy * b.yzx - bv = transmute(Bivec3) (yzx_zxy - zxy_yzx) + bv = transmute(BiV3_F4) (yzx_zxy - zxy_yzx) return } @@ -198,7 +192,7 @@ wedge_v3f4 :: #force_inline proc "contextless" (a, b: V3_F4) -> (bv : BiV3_F4) { //region Bivec3 biv3f4_via_f32s :: #force_inline proc "contextless" (yz, zx, xy : f32) -> BiV3_F4 {return { xyz = {yz, zx, xy} }} -complement_biv3f4 :: #force_inline proc "contextless" (b : BiV3_F4) -> BiV3_F4 {return transmute(BiV3_F4) b.xyz} +complement_biv3f4 :: #force_inline proc "contextless" (b : BiV3_F4) -> BiV3_F4 {return transmute(BiV3_F4) b.xyz} // TODO(Ed): Review this. //region Operations isomoprhic to vectors negate_biv3f4 :: #force_inline proc "contextless" (b : BiV3_F4) -> BiV3_F4 {return transmute(BiV3_F4) -b.xyz} @@ -208,10 +202,10 @@ mul_biv3f4 :: #force_inline proc "contextless" (a, b: BiV3_F4) mul_biv3f4_f32 :: #force_inline proc "contextless" (b: BiV3_F4, s: f32) -> BiV3_F4 {return transmute(BiV3_F4) (b.xyz * s)} mul_f32_biv3f4 :: #force_inline proc "contextless" (s: f32, b: BiV3_F4) -> BiV3_F4 {return transmute(BiV3_F4) (s * b.xyz)} div_biv3f4_f32 :: #force_inline proc "contextless" (b: BiV3_F4, s: f32) -> BiV3_F4 {return transmute(BiV3_F4) (b.xyz / s)} -inverse_mag_biv3f4 :: #force_inline proc "contextless" (b: BiV3_F4) -> f32 {return inverse_mag_vec3(b.xyz)} -magnitude_biv3f4 :: #force_inline proc "contextless" (b: BiV3_F4) -> f32 {return magnitude_vec3 (b.xyz)} -normalize_biv3f4 :: #force_inline proc "contextless" (b: BiV3_F4) -> UBiV3_F4 {return transmute(UBiV3_F4) normalize_vec3(b.xyz)} -squared_mag_biv3f4 :: #force_inline proc "contextless" (b: BiV3_F4) -> f32 {return pow2_vec3(b.xyz)} +inverse_mag_biv3f4 :: #force_inline proc "contextless" (b: BiV3_F4) -> f32 {return inverse_mag_v3f4(b.xyz)} +magnitude_biv3f4 :: #force_inline proc "contextless" (b: BiV3_F4) -> f32 {return magnitude_v3f4 (b.xyz)} +normalize_biv3f4 :: #force_inline proc "contextless" (b: BiV3_F4) -> UBiV3_F4 {return transmute(UBiV3_F4) normalize_v3f4(b.xyz)} +squared_mag_biv3f4 :: #force_inline proc "contextless" (b: BiV3_F4) -> f32 {return pow2_v3f4(b.xyz)} //endregion Operations isomoprhic to vectors // The wedge of a bi-vector in 3D vector space results in a Trivector represented as a scalar. @@ -219,23 +213,23 @@ squared_mag_biv3f4 :: #force_inline proc "contextless" (b: BiV3_F4) wedge_biv3f4 :: #force_inline proc "contextless" (a, b: BiV3_F4) -> f32 { s := a.yz + b.yz + a.zx + b.zx + a.xy + b.xy; return s } // anti-wedge (Combines dimensions that are absent from a & b) -regress_biv3f4 :: #force_inline proc "contextless" (a, b: BiV3_F4) -> V3_F4 {return wedge_vec3(vec3(a), vec3(b))} -regress_biv3f4_v3f4 :: #force_inline proc "contextless" (b: BiV3_F4, v: V3_F4) -> f32 {return regress_vec3(b.xyz, v)} -regress_v3_biv3f4 :: #force_inline proc "contextless" (v: V3_F4, b: BiV3_F4) -> f32 {return regress_vec3(b.xyz, v)} +regress_biv3f4 :: #force_inline proc "contextless" (a, b: BiV3_F4) -> V3_F4 {return wedge_v3f4(v3(a), v3(b))} +regress_biv3f4_v3f4 :: #force_inline proc "contextless" (b: BiV3_F4, v: V3_F4) -> f32 {return regress_v3f4(b.xyz, v)} +regress_v3_biv3f4 :: #force_inline proc "contextless" (v: V3_F4, b: BiV3_F4) -> f32 {return regress_v3f4(b.xyz, v)} //endregion biv3f4 //region Rotor3 -rotor3f4_via_comps_f4 :: proc "contextless" (yz, zx, xy, scalar : f32) -> Rotor3_F4 { return Rotor3 {biv3f4_via_f32s(yz, zx, xy), scalar} } +rotor3f4_via_comps_f4 :: proc "contextless" (yz, zx, xy, scalar : f32) -> Rotor3_F4 { return Rotor3_F4 {biv3f4_via_f32s(yz, zx, xy), scalar} } -rotor3f4_via_bv_s_f4 :: #force_inline proc "contextless" (bv: BiV3_F4, scalar: f32) -> (rotor : Rotor3_F4) { return Rotor3_F4 {bv, scalar} } +rotor3f4_via_bv_s_f4 :: #force_inline proc "contextless" (bv: BiV3_F4, scalar: f32) -> (rotor : Rotor3_F4) { return Rotor3_F4 {bv, scalar} } // rotor3f4_via_from_to_v3f4 :: #force_inline proc "contextless" (from, to: V3_F4) -> (rotor : Rotor3_F4) { rotor.scalar := 1 + dot( from, to ); return } -inverse_mag_rotor3f4 :: proc "contextless" (rotor : Rotor3_F4) -> (s : f32) { panic("not implemented"); return } -magnitude_rotor3f4 :: proc "contextless" (rotor : Rotor3_F4) -> (s : f32) { panic("not implemented"); return } -squared_mag_f4 :: proc "contextless" (rotor : Rotor3_F4) -> (s : f32) { panic("not implemented"); return } -reverse_rotor3_f4 :: proc "contextless" (rotor : Rotor3_F4) -> (reversed : Rotor3_F4) { reversed = { negate_biv3f4(rotor.bv), rotor.s }; return } +inverse_mag_rotor3f4 :: #force_inline proc "contextless" (rotor : Rotor3_F4) -> (s : f32) { panic_contextless("not implemented") } +magnitude_rotor3f4 :: #force_inline proc "contextless" (rotor : Rotor3_F4) -> (s : f32) { panic_contextless("not implemented") } +squared_mag_f4 :: #force_inline proc "contextless" (rotor : Rotor3_F4) -> (s : f32) { panic_contextless("not implemented") } +reverse_rotor3_f4 :: #force_inline proc "contextless" (rotor : Rotor3_F4) -> (reversed : Rotor3_F4) { reversed = { negate_biv3f4(rotor.bv), rotor.s }; return } //endregion Rotor3 @@ -243,26 +237,26 @@ reverse_rotor3_f4 :: proc "contextless" (rotor : Rotor3_F4) -> (reversed : Ro Point3_F4 :: distinct V3_F4 PointFlat3_F4 :: distinct V4_F4 -Line3_F4 :: struct { - weight : V3_F4, - bulk : BiV3_F4, +Line3_F4 :: struct { + weight: V3_F4, + bulk: BiV3_F4, } Plane3_F4 :: distinct V4_F4 // 4D Anti-vector // aka: wedge operation for points join_point3_f4 :: proc "contextless" (p, q : Point3_F4) -> (l : Line3_F4) { - weight := sub(q, p) - bulk := wedge(vec3(p), vec3(q)) + weight := v3(q) - v3(p) + bulk := wedge(v3(p), v3(q)) l = {weight, bulk} return } join_pointflat3_f4 :: proc "contextless" (p, q : PointFlat3_F4) -> (l : Line3_F4) { - weight := vec3( + weight := v3f4( p.w * q.x - p.x * q.w, p.w * q.y - p.y * q.w, p.w * q.z - p.z * q.w ) - bulk := wedge(vec3(p), vec3(q)) + bulk := wedge(v3(p), v3(q)) l = { weight, bulk} return } @@ -272,10 +266,10 @@ sub_point3_f4 :: #force_inline proc "contextless" (a, b : Point3_F4) -> (v : V3_ //region Rational Trig -quadrance :: proc "contextless" (a, b : Point3_F4) -> (q : f32) { q = pow2( sub(a, b)); return } +quadrance :: #force_inline proc "contextless" (a, b: Point3_F4) -> (q : f32) { q = pow2_v3f4(v3(a) - v3(b)); return } // Assumes the weight component is normalized. -spread :: proc "contextless" (l, m : Line3_F4) -> (s : f32) { s = dot(l.weight, m.weight); return } +spread :: #force_inline proc "contextless" (l, m: Line3_F4) -> (s : f32) { s = vdot(l.weight, m.weight); return } //endregion Rational Trig @@ -283,23 +277,23 @@ spread :: proc "contextless" (l, m : Line3_F4) -> (s : f32) { s = dot(l.weight, // A dump of equivalent symbol generatioon (because the toolchain can't do it yet) // Symbol alias tables are in grim.odin -v3f4_to_biv3f4 :: #force_inline proc "contextless" (v: V3_F4) -> BiV3_F4 {return transmute(Bivec3) v } -biv3f4_to_v3f4 :: #force_inline proc "contextless" (bv: BiV3_F4) -> V3_F4 {return transmute(Vec3) bv } -quatf4_from_rotor3f4 :: #force_inline proc "contextless" (rotor: Rotor3_F4) -> Q_F4 {return transmute(Quat128) rotor} -uv3f4_to_v3f4 :: #force_inline proc "contextless" (v: UV3_F4) -> V3_F4 {return transmute(Vec3) v } -uv4f4_to_v4f4 :: #force_inline proc "contextless" (v: UV4_F4) -> V4_F4 {return transmute(Vec4) v } +v3f4_to_biv3f4 :: #force_inline proc "contextless" (v: V3_F4) -> BiV3_F4 {return transmute(BiV3_F4) v } +biv3f4_to_v3f4 :: #force_inline proc "contextless" (bv: BiV3_F4) -> V3_F4 {return transmute(V3_F4) bv } +quatf4_from_rotor3f4 :: #force_inline proc "contextless" (rotor: Rotor3_F4) -> Quat_F4 {return transmute(Quat_F4) rotor } +uv3f4_to_v3f4 :: #force_inline proc "contextless" (v: UV3_F4) -> V3_F4 {return transmute(V3_F4) v } +uv4f4_to_v4f4 :: #force_inline proc "contextless" (v: UV4_F4) -> V4_F4 {return transmute(V4_F4) v } // plane_to_v4f4 :: #force_inline proc "contextless" (p : Plane3_F4) -> V4_F4 {return transmute(V4_F4) p} -point3f4_to_v3f4 :: #force_inline proc "contextless" (p: Point3_F4) -> V3_F4 {return transmute(Vec3) p} -pointflat3f4_to_v3f4 :: #force_inline proc "contextless" (p: PointFlat3_F4) -> V3_F4 {return { p.x, p.y, p.z }} -v3f4_to_point3f4 :: #force_inline proc "contextless" (v: V3_F4) -> Point3_F4 {return transmute(Point3) v} +point3f4_to_v3f4 :: #force_inline proc "contextless" (p: Point3_F4) -> V3_F4 {return {p.x, p.y, p.z} } +pointflat3f4_to_v3f4 :: #force_inline proc "contextless" (p: PointFlat3_F4) -> V3_F4 {return {p.x, p.y, p.z} } +v3f4_to_point3f4 :: #force_inline proc "contextless" (v: V3_F4) -> Point3_F4 {return {v.x, v.y, v.z} } -cross_v3f4_uv3f4 :: #force_inline proc "contextless" (v: V3_F4, u: UV3_F4) -> V3_F4 {return cross_v3f4(v, transmute(Vec3) u)} -cross_u3f4_v3f4 :: #force_inline proc "contextless" (u: UV3_F4, v: V3_F4) -> V3_F4 {return cross_v3f4(transmute(Vec3) u, v)} +cross_v3f4_uv3f4 :: #force_inline proc "contextless" (v: V3_F4, u: UV3_F4) -> V3_F4 {return cross_v3(v, transmute(V3_F4) u)} +cross_u3f4_v3f4 :: #force_inline proc "contextless" (u: UV3_F4, v: V3_F4) -> V3_F4 {return cross_v3(transmute(V3_F4) u, v)} -dot_v3f4_uv3f4 :: #force_inline proc "contextless" (v: V3_F4, unit_v: UV3_F4) -> f32 {return dot_v3f4(v, transmute(Vec3) unit_v)} -dot_uv3f4_vs :: #force_inline proc "contextless" (unit_v: UV3_F4, v: V3_F4) -> f32 {return dot_v3f4(v, transmute(Vec3) unit_v)} +dot_v3f4_uv3f4 :: #force_inline proc "contextless" (v: V3_F4, unit_v: UV3_F4) -> f32 {return vdot(v, transmute(V3_F4) unit_v)} +dot_uv3f4_v3f4 :: #force_inline proc "contextless" (unit_v: UV3_F4, v: V3_F4) -> f32 {return vdot(v, transmute(V3_F4) unit_v)} -wedge_v3f4_uv3f4 :: #force_inline proc "contextless" (v : V3_F4, unit_v: UV3_F4) -> BiV3_F4 {return wedge_v3f4(v, transmute(Vec3) unit_v)} -wedge_uv3f4_vs :: #force_inline proc "contextless" (unit_v: UV3_F4, v: V3_F4) -> BiV3_F4 {return wedge_v3f4(transmute(Vec3) unit_v, v)} +wedge_v3f4_uv3f4 :: #force_inline proc "contextless" (v : V3_F4, unit_v: UV3_F4) -> BiV3_F4 {return wedge_v3f4(v, v3(unit_v))} +wedge_uv3f4_vs :: #force_inline proc "contextless" (unit_v: UV3_F4, v: V3_F4) -> BiV3_F4 {return wedge_v3f4(v3(unit_v), v)} //endregion Grime diff --git a/code2/sectr/pkg_mappings.odin b/code2/sectr/pkg_mappings.odin index b8249d5..f45846e 100644 --- a/code2/sectr/pkg_mappings.odin +++ b/code2/sectr/pkg_mappings.odin @@ -47,9 +47,14 @@ import threading "core:thread" thread_start :: threading.start import "core:time" - Millisecond :: time.Millisecond - Duration :: time.Duration - thread_sleep :: time.sleep + Millisecond :: time.Millisecond + Duration :: time.Duration + Tick :: time.Tick + duration_ms :: time.duration_milliseconds + duration_seconds :: time.duration_seconds + thread_sleep :: time.sleep + tick_lap_time :: time.tick_lap_time + tick_now :: time.tick_now import "codebase:grime" Logger :: grime.Logger @@ -57,6 +62,8 @@ import "codebase:grime" grime_set_profiler_module_context :: grime.set_profiler_module_context grime_set_profiler_thread_buffer :: grime.set_profiler_thread_buffer + set__scheduler_granularity :: grime.set__scheduler_granularity + Kilo :: 1024 Mega :: Kilo * 1024 Giga :: Mega * 1024 @@ -123,10 +130,11 @@ profile_end :: #force_inline proc "contextless" () { spall._buffer_end( & memory.spall_context, & thread.spall_buffer) } - +// Procedure Mappings add :: proc { add_r2f4, + add_biv3f4, } biv3f4 :: proc { @@ -139,6 +147,13 @@ cross :: proc { cross_s, cross_v2, cross_v3, + + cross_v3f4_uv3f4, + cross_u3f4_v3f4, +} + +div :: proc { + div_biv3f4_f32, } dot :: proc { @@ -147,6 +162,13 @@ dot :: proc { qdot_f2, qdot_f4, qdot_f8, + + dot_v3f4_uv3f4, + dot_uv3f4_v3f4, +} + +equal :: proc { + equal_r2f4, } is_power_of_two :: proc { @@ -159,6 +181,12 @@ mov_avg_exp :: proc { mov_avg_exp_f64, } +mul :: proc { + mul_biv3f4, + mul_biv3f4_f32, + mul_f32_biv3f4, +} + join :: proc { join_r2f4, } @@ -167,17 +195,18 @@ inverse_sqrt :: proc { inverse_sqrt_f32, } -sub :: proc { - sub_r2f4, - sub_biv3f4, - join_point3_f4, - join_pointflat3_f4, +point3 :: proc { + v3f4_to_point3f4, } pow2 :: proc { pow2_v3f4, } +quatf4 :: proc { + quatf4_from_rotor3f4, +} + regress :: proc { regress_biv3f4, } @@ -188,8 +217,15 @@ rotor3 :: proc { // rotor3f4_via_from_to_v3f4, } -quatf4 :: proc { - quatf4_from_rotor3f4, +size :: proc { + size_r2f4, +} + +sub :: proc { + sub_r2f4, + sub_biv3f4, + // join_point3_f4, + // join_pointflat3_f4, } v2f4 :: proc { diff --git a/code2/sectr/state.odin b/code2/sectr/state.odin index a0f9e6f..eb19e00 100644 --- a/code2/sectr/state.odin +++ b/code2/sectr/state.odin @@ -70,9 +70,13 @@ State :: struct { } ThreadState :: struct { + + + // Frametime delta_seconds: f64, delta_ms: f64, delta_ns: Duration, + target_ms: f64, // NOTE(Ed): This can only be used on job worker threads. elapsed_ms: f64, avg_ms: f64, }