diff --git a/ppswap/pp_sim.swp.swp b/ppswap/pp_sim.swp.swp index 29844c32..b9d1d1b5 100644 Binary files a/ppswap/pp_sim.swp.swp and b/ppswap/pp_sim.swp.swp differ diff --git a/ppswap/pp_vis.swp.swp b/ppswap/pp_vis.swp.swp index 1590521d..991ada60 100644 Binary files a/ppswap/pp_vis.swp.swp and b/ppswap/pp_vis.swp.swp differ diff --git a/src/pp/pp_vis/pp_vis.lay b/src/pp/pp_vis/pp_vis.lay index 3ac65331..9d1e3335 100644 --- a/src/pp/pp_vis/pp_vis.lay +++ b/src/pp/pp_vis/pp_vis.lay @@ -15,6 +15,8 @@ @EmbedDir V_Resources pp_vis_res +@ComputeShader V_ClearDecalsCS +@ComputeShader V_ClearParticlesCS @ComputeShader V_BackdropCS @VertexShader V_DQuadVS @PixelShader V_DQuadPS diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 74b11673..8126d5b1 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -311,7 +311,8 @@ void V_TickForever(WaveLaneCtx *lane) Vec2I32 tiles_dims = VEC2I32(S_TilesPitch, S_TilesPitch); Vec2I32 decals_dims = VEC2I32(V_PixelsPerMeter * S_WorldPitch, V_PixelsPerMeter * S_WorldPitch); - u32 max_particles = Kibi(128); + // u32 max_particles = Kibi(128); + u32 max_particles = Mebi(1); // Init gpu state G_ResourceHandle gpu_state = Zi; @@ -2350,6 +2351,8 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Process vis commands + b32 should_clear_decals = !TweakBool("Persist decals", 0); + b32 should_clear_particles = 0; for (V_CmdNode *cmd_node = frame->first_cmd_node; cmd_node; cmd_node = cmd_node->next) { String cmd_name = cmd_node->cmd.name; @@ -2486,6 +2489,16 @@ void V_TickForever(WaveLaneCtx *lane) ent->exists = 0; } } break; + + case V_CmdKind_clear_decals: + { + should_clear_decals = 1; + } break; + + case V_CmdKind_clear_particles: + { + should_clear_particles = 1; + } break; } } @@ -2652,7 +2665,9 @@ void V_TickForever(WaveLaneCtx *lane) V_EmitterNode *first_emitter_node = 0; V_EmitterNode *last_emitter_node = 0; - // Spawn test emitters + // Spawn test emitter + + if (frame->held_buttons[Button_F]) { V_Emitter *emitter = 0; { @@ -2663,16 +2678,16 @@ void V_TickForever(WaveLaneCtx *lane) } emitter->particle_kind = V_ParticleKind_Test; - Vec2 dir = VEC2(0, 1); + Vec2 dir = frame->look; emitter->pos = frame->world_cursor; emitter->angle = AngleFromVec2(dir); emitter->count = 1000; - emitter->speed = 4; + emitter->speed = 10; emitter->seed = RandU64FromState(&frame->rand); emitter->speed_spread = 1; - emitter->angle_spread = Tau; + emitter->angle_spread = 1; } // Flatten emitters list @@ -2759,6 +2774,22 @@ void V_TickForever(WaveLaneCtx *lane) // Sync G_DumbGlobalMemorySync(frame->cl); + ////////////////////////////// + //- Utility pass + + // Clear decals + if (should_clear_decals) + { + G_Compute(frame->cl, V_ClearDecalsCS, V_ThreadGroupSizeFromTexSize(decals_dims)); + } + // Clear particles + if (should_clear_particles) + { + G_Compute(frame->cl, V_ClearParticlesCS, V_ThreadGroupSizeFromBufferSize(max_particles)); + } + + G_DumbGlobalMemorySync(frame->cl); + ////////////////////////////// //- Discard pass @@ -2770,7 +2801,7 @@ void V_TickForever(WaveLaneCtx *lane) G_DumbMemoryLayoutSync(frame->cl, draw_target, G_Layout_DirectQueue_ShaderReadWrite); { - G_Compute(frame->cl, V_BackdropCS, V_BackdropCSThreadSizeFromTexSize(frame->draw_dims)); + G_Compute(frame->cl, V_BackdropCS, V_ThreadGroupSizeFromTexSize(frame->draw_dims)); } ////////////////////////////// @@ -2789,6 +2820,19 @@ void V_TickForever(WaveLaneCtx *lane) ); } + ////////////////////////////// + //- Particle simulation pass + + { + // Emit particles + G_Compute(frame->cl, V_EmitParticlesCS, V_ThreadGroupSizeFromBufferSize(emitters_count)); + + G_DumbMemorySync(frame->cl, gpu_particles); + + // Simulate particles + G_Compute(frame->cl, V_SimParticlesCS, V_ThreadGroupSizeFromBufferSize(max_particles)); + } + ////////////////////////////// //- Overlay pass @@ -2803,19 +2847,6 @@ void V_TickForever(WaveLaneCtx *lane) ); } - ////////////////////////////// - //- Particle simulation pass - - { - // Emit particles - G_Compute(frame->cl, V_EmitParticlesCS, VEC3I32((emitters_count + 63) / 64, 1, 1)); - - G_DumbMemorySync(frame->cl, gpu_particles); - - // Simulate particles - G_Compute(frame->cl, V_SimParticlesCS, VEC3I32((max_particles + 63) / 64, 1, 1)); - } - ////////////////////////////// //- Finalize draw target diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index ca24f3e4..421ffa97 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -15,6 +15,8 @@ X(spawn, Spawn/Teleport Player, V_CmdDescFlag_None, V_HOTKEY( Button_T ), ) \ X(spawn_dummy, Spawn Dummy, V_CmdDescFlag_None, V_HOTKEY( Button_R ), ) \ X(delete, Delete entity at cursor, V_CmdDescFlag_None, V_HOTKEY( Button_M2 ), ) \ + X(clear_decals, Clear decals, V_CmdDescFlag_None, V_HOTKEY( Button_C ), ) \ + X(clear_particles, Clear particles, V_CmdDescFlag_None, V_HOTKEY( Button_C, .alt = 1 ), ) \ /* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ //////////////////////////////////////////////////////////// diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index fd47c77a..85db275a 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -1,3 +1,31 @@ +//////////////////////////////////////////////////////////// +//~ Utility shaders + +//- Clear decals +ComputeShader2D(V_ClearDecalsCS, 8, 8) +{ + V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; + RWTexture2D decals = G_Dereference(params.decals); + Vec2 decal_idx = SV_DispatchThreadID; + if (decal_idx.x < countof(decals).x && decal_idx.y < countof(decals).y) + { + decals[decal_idx] = V_ParticleKind_None; + } +} + +//- Clear particles +ComputeShader(V_ClearParticlesCS, 64) +{ + V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; + RWStructuredBuffer particles = G_Dereference(params.particles); + u32 particle_idx = SV_DispatchThreadID; + if (particle_idx < params.max_particles) + { + particles[particle_idx].kind = V_ParticleKind_None; + } +} + + //////////////////////////////////////////////////////////// //~ Backdrop shader @@ -197,53 +225,6 @@ ComputeShader(V_EmitParticlesCS, 64) particles_created_count += 1; } } - - - - // V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; - // RWStructuredBuffer state_buff = G_Dereference(V_ShaderConst_State); - // StructuredBuffer emitters = G_Dereference(params.emitters); - // RWStructuredBuffer particles = G_Dereference(params.particles); - // Texture3D noise3d = G_Dereference(params.noise); - - // u32 emitter_idx = SV_DispatchThreadID; - // if (emitter_idx < params.emitters_count) - // { - // V_Emitter emitter = emitters[emitter_idx]; - - // u32 first_particle_seq; - // InterlockedAdd(state_buff[0].particle_seq, emitter.count, first_particle_seq); - // u32 last_particle_seq = first_particle_seq + emitter.count; - - // Vec2U32 speed_noise_coord; - // Vec2U32 angle_noise_coord; - // { - // speed_noise_coord.x = ((emitter.speed_seed >> 0) & 0xFFFF) % countof(noise3d).x; - // speed_noise_coord.y = ((emitter.speed_seed >> 16) & 0xFFFF) % countof(noise3d).y; - // angle_noise_coord.x = ((emitter.angle_seed >> 0) & 0xFFFF) % countof(noise3d).x; - // angle_noise_coord.y = ((emitter.angle_seed >> 16) & 0xFFFF) % countof(noise3d).y; - // } - - // u64 base_seed = - // for (u32 particle_seq = first_particle_seq; particle_seq < last_particle_seq; ++particle_seq) - // { - // V_Particle particle; - // { - // u32 speed_noise = noise3d.Load(Vec4U32(speed_noise_coord.xy, particle_seq % countof(noise3d).z, 0)); - // u32 angle_noise = noise3d.Load(Vec4U32(angle_noise_coord.xy, particle_seq % countof(noise3d).z, 0)); - // f32 speed_rand = speed_noise / (f32)0xFFFF; - // f32 angle_rand = angle_noise / (f32)0xFFFF; - // f32 speed = emitter.speed + ((speed_rand * 2 - 1) * emitter.speed_spread); - // f32 angle = emitter.angle + ((angle_rand * 2 - 1) * emitter.angle_spread); - - // particle.kind = emitter.particle_kind; - // particle.pos = emitter.pos; - // particle.velocity = Vec2(cos(angle), sin(angle)) * speed; - // } - // particles[particle_seq % params.max_particles] = particle; - // } - - // } } ////////////////////////////// @@ -295,6 +276,11 @@ ComputeShader(V_SimParticlesCS, 64) // FIXME: Atomic write decals[floor(decal_pos)] = particle.kind; } + else + { + // Prune out of bounds particle + particle.kind = V_ParticleKind_None; + } } particles[particle_idx] = particle; } @@ -418,6 +404,7 @@ PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input) if (decal == V_ParticleKind_Test) { result = Color_Yellow; + // result = LinearFromSrgb(Vec4(0.5, 0.1, 0.1, 1)); } } diff --git a/src/pp/pp_vis/pp_vis_gpu.gh b/src/pp/pp_vis/pp_vis_gpu.gh index dd473b41..7cb0155b 100644 --- a/src/pp/pp_vis/pp_vis_gpu.gh +++ b/src/pp/pp_vis/pp_vis_gpu.gh @@ -43,6 +43,10 @@ Struct(V_OverlayPSOutput) //////////////////////////////////////////////////////////// //~ Shaders +//- Utility shaders +ComputeShader2D(V_ClearDecalsCS, 8, 8); +ComputeShader(V_ClearParticlesCS, 64); + //- Backdrop shader ComputeShader2D(V_BackdropCS, 8, 8); diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index cb49ba70..bbab70da 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -4,8 +4,8 @@ //////////////////////////////////////////////////////////// //~ Constant types -G_DeclConstant(G_RWStructuredBufferRef, V_ShaderConst_State, 0); -G_DeclConstant(G_StructuredBufferRef, V_ShaderConst_Params, 1); +G_DeclConstant(G_RWStructuredBufferRef, V_ShaderConst_State, 0); +G_DeclConstant(G_StructuredBufferRef, V_ShaderConst_Params, 1); Enum(V_SelectionMode) { @@ -39,7 +39,9 @@ Struct(V_GpuState) Struct(V_GpuParams) { + // TODO: Use simulation dt f32 dt; + Vec2 target_size; G_Texture2DRef target_ro; G_RWTexture2DRef target_rw; @@ -117,11 +119,6 @@ Struct(V_Particle) }; #endif -//////////////////////////////////////////////////////////// -//~ Backdrop shader types - -#define V_BackdropCSThreadSizeFromTexSize(tex_size) VEC3I32((tex_size.x + 7) / 8, (tex_size.y + 7) / 8, 1) - //////////////////////////////////////////////////////////// //~ Quad types @@ -144,3 +141,10 @@ Struct(V_DVert) Vec2 pos; Vec4 color_lin; }; + + +//////////////////////////////////////////////////////////// +//~ Helpers + +#define V_ThreadGroupSizeFromBufferSize(buffer_size) VEC3I32((((buffer_size) + 63) / 64), 1, 1) +#define V_ThreadGroupSizeFromTexSize(tex_size) VEC3I32(((tex_size).x + 7) / 8, ((tex_size).y + 7) / 8, 1)