diff --git a/src/config.h b/src/config.h index 2361b294..18ecb807 100644 --- a/src/config.h +++ b/src/config.h @@ -6,10 +6,6 @@ #define SIM_TICKS_PER_SECOND 64 #define SIM_TICK_INTERVAL_NS (NsFromSeconds(1) / SIM_TICKS_PER_SECOND) -// Like USER_INTERP_RATIO, but applies to snapshots received by the local sim from the -// master sim (how far back in time should the client render the server's state) -// #define SIM_CLIENT_INTERP_RATIO 2.0 - #define GPU_NAMES IsRtcEnabled @@ -30,4 +26,6 @@ // TODO: Move these to user-configurable settings #define AUDIO_ENABLED 0 -#define FPS_LIMIT 300 + +// #define FPS_LIMIT 60 +#define FPS_LIMIT 0 diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.c b/src/gpu/gpu_dx12/gpu_dx12_core.c index 393ab128..936ee407 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.c +++ b/src/gpu/gpu_dx12/gpu_dx12_core.c @@ -2556,14 +2556,14 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) G_D12_Resource *resource = G_D12_ResourceFromTextureRef(cmd->barrier.texture); if (resource) { - if (cmd->barrier.release) - { - G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, resource->texture_mips, G_D12_TrackedUsageKind_Release, cmd); - } - else - { - G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, resource->texture_mips, G_D12_TrackedUsageKind_Acquire, cmd); - } + G_D12_UpdateTrackedUsage( + scratch.arena, + batch, + resource, + resource->texture_mips, + cmd->barrier.release ? G_D12_TrackedUsageKind_Release : G_D12_TrackedUsageKind_Acquire, + cmd + ); } } else @@ -2651,9 +2651,9 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) u64 slotted_constants[G_NumConstants]; u64 bound_compute_constants[G_NumConstants]; u64 bound_graphics_constants[G_NumConstants]; - for (i32 i = 0; i < countof(slotted_constants); ++i) { slotted_constants[i] = 0; } // Zero-initialize all slots - for (i32 i = 0; i < countof(bound_compute_constants); ++i) { bound_compute_constants[i] = U64Max; } - for (i32 i = 0; i < countof(bound_graphics_constants); ++i) { bound_graphics_constants[i] = U64Max; } + for (i32 slot = 0; slot < countof(slotted_constants); ++slot) { slotted_constants[slot] = 0; } // Zero-initialize all slots + for (i32 slot = 0; slot < countof(bound_compute_constants); ++slot) { bound_compute_constants[slot] = U64Max; } + for (i32 slot = 0; slot < countof(bound_graphics_constants); ++slot) { bound_graphics_constants[slot] = U64Max; } // Fill built-in constants if (!G_IsRefNil(queue->print_buffer)) @@ -2675,8 +2675,8 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) u64 bound_render_target_uids[G_MaxRenderTargets] = Zi; u64 bound_render_clear_target_uid = 0; - // Shader-visible heaps - ID3D12DescriptorHeap *heaps[] = { + // Shader-visible descriptor heaps + ID3D12DescriptorHeap *descriptor_heaps[] = { G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav].d3d_heap, G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_Sampler].d3d_heap, }; @@ -2898,7 +2898,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) // Set descriptor heaps if (!descriptor_heaps_set) { - ID3D12GraphicsCommandList_SetDescriptorHeaps(d3d_cl, countof(heaps), heaps); + ID3D12GraphicsCommandList_SetDescriptorHeaps(d3d_cl, countof(descriptor_heaps), descriptor_heaps); descriptor_heaps_set = 1; } @@ -2961,18 +2961,18 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) { pipeline_desc.is_wireframe = 1; } - for (u32 i = 0; i < countof(cmd->draw.render_target_descs); ++i) + for (u32 rt_idx = 0; rt_idx < countof(cmd->draw.render_target_descs); ++rt_idx) { - G_RenderTargetDesc desc = cmd->draw.render_target_descs[i]; + G_RenderTargetDesc desc = cmd->draw.render_target_descs[rt_idx]; G_D12_Resource *rt = G_D12_ResourceFromTextureRef(desc.texture); if (rt) { - pipeline_desc.render_target_formats[i] = rt->texture_format; - pipeline_desc.render_target_blend_modes[i] = desc.blend; + pipeline_desc.render_target_formats[rt_idx] = rt->texture_format; + pipeline_desc.render_target_blend_modes[rt_idx] = desc.blend; } else { - pipeline_desc.render_target_formats[i] = G_Format_Unknown; + pipeline_desc.render_target_formats[rt_idx] = G_Format_Unknown; } } pipeline = G_D12_PipelineFromDesc(pipeline_desc); @@ -3009,7 +3009,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) // Set descriptor heaps if (!descriptor_heaps_set) { - ID3D12GraphicsCommandList_SetDescriptorHeaps(d3d_cl, countof(heaps), heaps); + ID3D12GraphicsCommandList_SetDescriptorHeaps(d3d_cl, countof(descriptor_heaps), descriptor_heaps); descriptor_heaps_set = 1; } @@ -3104,18 +3104,18 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) { b32 om_dirty = 0; u32 rtvs_count = 0; - for (u32 i = 0; i < countof(cmd->draw.render_target_descs); ++i) + for (u32 rt_idx = 0; rt_idx < countof(cmd->draw.render_target_descs); ++rt_idx) { - G_RenderTargetDesc desc = cmd->draw.render_target_descs[i]; + G_RenderTargetDesc desc = cmd->draw.render_target_descs[rt_idx]; G_D12_Resource *rt = G_D12_ResourceFromTextureRef(desc.texture); if (rt) { Assert(AnyBit(rt->d3d_desc.Flags, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)); - if (bound_render_target_uids[i] != rt->uid + desc.mip) + if (bound_render_target_uids[rt_idx] != rt->uid + desc.mip) { - G_D12_Descriptor *rtv_descriptor = rcl->rtv_descriptors[i]; + G_D12_Descriptor *rtv_descriptor = rcl->rtv_descriptors[rt_idx]; G_D12_InitRtvDescriptor(rtv_descriptor, rt, desc.mip); - bound_render_target_uids[i] = rt->uid + desc.mip; + bound_render_target_uids[rt_idx] = rt->uid + desc.mip; om_dirty = 1; } ++rtvs_count; @@ -3128,9 +3128,9 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) if (om_dirty) { D3D12_CPU_DESCRIPTOR_HANDLE rtv_handles[G_MaxRenderTargets] = Zi; - for (u32 i = 0; i < rtvs_count; ++i) + for (u32 rt_idx = 0; rt_idx < rtvs_count; ++rt_idx) { - rtv_handles[i] = rcl->rtv_descriptors[i]->d3d_handle; + rtv_handles[rt_idx] = rcl->rtv_descriptors[rt_idx]->d3d_handle; } ID3D12GraphicsCommandList_OMSetRenderTargets(d3d_cl, rtvs_count, rtv_handles, 0, 0); } @@ -3805,9 +3805,9 @@ G_BackbufferHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_For } // Release backbuffers - for (u32 i = 0; i < countof(swapchain->backbuffers); ++i) + for (u32 backbuffer_idx = 0; backbuffer_idx < countof(swapchain->backbuffers); ++backbuffer_idx) { - G_D12_Backbuffer *backbuffer = &swapchain->backbuffers[i]; + G_D12_Backbuffer *backbuffer = &swapchain->backbuffers[backbuffer_idx]; if (backbuffer->d3d_resource) { ID3D12Resource_Release(backbuffer->d3d_resource); diff --git a/src/meta/meta.c b/src/meta/meta.c index 7c4a67f6..def3ba16 100644 --- a/src/meta/meta.c +++ b/src/meta/meta.c @@ -569,6 +569,7 @@ void M_BuildEntryPoint(WaveLaneCtx *lane) PushStringToList(perm, &cp.flags_dxc, Lit("-O3")); PushStringToList(perm, &cp.flags_dxc, Lit("-HV 202x")); // 202x makes numeric literals less weird PushStringToList(perm, &cp.flags_dxc, Lit("-Ges")); // Strict mode + PushStringToList(perm, &cp.flags_dxc, Lit("-res_may_alias")); // TODO: Export debug info separately for release builds PushStringToList(perm, &cp.flags_dxc, Lit("-Zi -Qembed_debug")); diff --git a/src/pp/pp.c b/src/pp/pp.c index b205160c..ff8e71c0 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -1951,11 +1951,8 @@ void P_SpawnEntsFromList(P_Frame *frame, P_EntList ents) } dst->created_at_ns = frame->time_ns; dst->created_at_tick = frame->tick; + dst->sim = !P_tl.is_predicting; ++frame->ents_count; - if (!P_tl.is_predicting) - { - dst->sim = 1; - } } } } @@ -2192,25 +2189,42 @@ void P_StepFrame(P_Frame *frame) P_Ent *local_player = P_EntFromKey(frame, P_tl.local_player); P_Ent *local_guy = P_EntFromKey(frame, local_player->guy); + + + ////////////////////////////// //- Mark simulated ents if (is_predicting) { + P_EntKey local_player_key = local_player->key; + P_EntKey local_guy_key = local_guy->key; + P_EntKey local_weapon_key = local_guy->weapon; + + // Mark player/guy/weapon ents for (P_Ent *ent = P_FirstEnt(frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) { P_EntKey key = ent->key; b32 sim = 0; if ( - P_MatchEntKey(key, local_player->key) || - P_MatchEntKey(key, local_guy->key) || - P_MatchEntKey(key, local_guy->weapon) + P_MatchEntKey(key, local_player_key) || + P_MatchEntKey(key, local_guy_key) || + P_MatchEntKey(key, local_weapon_key) ) { sim = 1; } ent->sim = sim; } + + // Mark child ents + for (P_Ent *ent = P_FirstEnt(frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) + { + if (!ent->sim) + { + ent->sim = P_EntFromKey(frame, ent->source)->sim; + } + } } ////////////////////////////// @@ -3055,6 +3069,7 @@ void P_StepFrame(P_Frame *frame) bullet->source = weapon->key; bullet->damage_attribution = firer->source; + bullet->sim = weapon->sim; } } weapon->last_fire_ns = frame->time_ns; @@ -3095,6 +3110,7 @@ void P_StepFrame(P_Frame *frame) f32 spread = Tau * 0.05; // f32 spread = Tau * 0.01; + // f32 spread = 0; b32 should_ricochet = 0; @@ -3137,7 +3153,6 @@ void P_StepFrame(P_Frame *frame) if (is_first_bullet_tick) { - Vec2 fire_pos = Zi; Vec2 fire_dir = Zi; Vec2 fire_base0 = Zi; @@ -3185,9 +3200,9 @@ void P_StepFrame(P_Frame *frame) wep_pix_to_world_af = MulAffine(ent_to_world_af, wep_pix_to_ent_af); } - SPR_Ray fire_ray = wep.rays[SPR_RayKind_Ap]; - fire_pos = MulAffineVec2(wep_pix_to_world_af, fire_ray.pos); - fire_dir = NormVec2(MulAffineBasisVec2(wep_pix_to_world_af, fire_ray.dir)); + SPR_Ray muzzle_ray = wep.rays[SPR_RayKind_Ap]; + fire_pos = MulAffineVec2(wep_pix_to_world_af, muzzle_ray.pos); + fire_dir = NormVec2(MulAffineBasisVec2(wep_pix_to_world_af, muzzle_ray.dir)); fire_base0 = MulVec2(PerpVec2(NegVec2(firer->xf.r)), WedgeVec2(firer->xf.r, SubVec2(firer->xf.t, fire_pos))); fire_base0 = AddVec2(fire_base0, firer->xf.t); @@ -3203,10 +3218,12 @@ void P_StepFrame(P_Frame *frame) P_DebugDrawPoint(fire_base1, Color_Green); P_DebugDrawPoint(fire_pos, Color_Red); - bullet->xf.t = fire_pos; - bullet->xf.r = NormVec2(fire_dir); + Vec2 bullet_dir = RotateVec2Angle(fire_dir, spread * (Norm24(MixU64s(bullet->key.v, P_BulletSpreadBasis)) - 0.5)); - bullet->v = MulVec2(NormVec2(fire_dir), initial_speed); + bullet->xf.t = fire_pos; + bullet->xf.r = NormVec2(bullet_dir); + + bullet->v = MulVec2(NormVec2(bullet_dir), initial_speed); bullet->v = AddVec2(bullet->v, firer->v); } @@ -3352,7 +3369,7 @@ void P_StepFrame(P_Frame *frame) bullet->v = MulVec2(bullet->v, 1.0 - SaturateF32(speed_falloff * sim_dt)); // TODO: Remove this - if (!P_IsEntNil(victim)) + if (!is_predicting && !P_IsEntNil(victim)) { if (damager->is_player) { @@ -3582,6 +3599,7 @@ void P_StepFrame(P_Frame *frame) killer->kills += 1; } guy->exists = 0; + guy->continuity_gen += 1; } } } diff --git a/src/pp/pp.h b/src/pp/pp.h index e615159b..274738a7 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -6,7 +6,8 @@ #define P_NilEntKey ((P_EntKey) { 0 }) #define P_NilConstraintKey ((P_EntKey) { 0 }) -#define P_WallShapeIDBasis 0x40d501b4cf6d4f0cull +#define P_WallShapeIDBasis 0x40d501b4cf6d4f0cull +#define P_BulletSpreadBasis 0xc3b72fe38ca5a1d6ull Struct(P_EntKey) { diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 3331a018..9ffb7e21 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -555,6 +555,7 @@ void V_TickForever(WaveLaneCtx *lane) { shutdown = Atomic32Fetch(&V.shutdown); P_tl.debug_draw_enabled = TweakBool("Vis debug draw", 0); + i64 begin_time_ns = TimeNs(); ////////////////////////////// //- Begin frame @@ -624,7 +625,7 @@ void V_TickForever(WaveLaneCtx *lane) if (frame->tick == 1) { - frame->timeline.show = 1; + // frame->timeline.show = 1; frame->timeline.locked = 1; } @@ -1697,7 +1698,10 @@ void V_TickForever(WaveLaneCtx *lane) // TODO: Extract information that occurred between first & last prediction, like bullet hits etc? - V_PushTimelineMarker(predict_frame->tick, Color_Purple, 1); + // V_PushTimelineMarker(predict_frame->tick, Color_Purple, 1); + + V_PushTimelineMarker(CeilF64(frame->predict_tick_accum), Color_White, 1); + V_PushTimelineMarker(frame->predict_tick_accum, Color_Purple, 1); } @@ -1844,7 +1848,6 @@ void V_TickForever(WaveLaneCtx *lane) for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) { - // if (ent->sim) P_Ent *left = ent; P_Ent *right = ent; f32 blend_t = 0; @@ -5381,6 +5384,15 @@ void V_TickForever(WaveLaneCtx *lane) { LogInfoF("Time to first frame: %Fs", FmtFloat(SecondsFromNs(TimeNs()), .p = 3)); } + + ////////////////////////////// + //- Sleep + + if (!shutdown && FPS_LIMIT > 0) + { + i64 step_dt_ns = FPS_LIMIT > 0 ? NsFromSeconds(1) / FPS_LIMIT : 0; + PLT_SleepFrame(begin_time_ns, step_dt_ns); + } } FetchAddFence(&V.shutdown_complete, 1); diff --git a/src/ui/ui_shared.cgh b/src/ui/ui_shared.cgh index 686b2c5a..699cfa16 100644 --- a/src/ui/ui_shared.cgh +++ b/src/ui/ui_shared.cgh @@ -1,3 +1,9 @@ +//////////////////////////////////////////////////////////// +//~ Constant types + +G_DeclConstant(G_BufferRef, UI_GpuConst_Frame, 0); +G_DeclConstant(b32, UI_GpuConst_DebugDraw, 1); + //////////////////////////////////////////////////////////// //~ Rect types @@ -23,9 +29,6 @@ Struct(UI_GpuRect) //////////////////////////////////////////////////////////// //~ State types -G_DeclConstant(G_BufferRef, UI_GpuConst_Frame, 0); -G_DeclConstant(b32, UI_GpuConst_DebugDraw, 1); - Struct(UI_GpuFrame) { f32 anti_aliasing;