Skip to content

Commit

Permalink
Genericized naming conventions and placed demos and their pipelines i…
Browse files Browse the repository at this point in the history
…nto their own folder. (#75)

* genericized demo naming and seperated them into their own folder

* changed shaderbuilder to accept user defined folders

* renamed pipeline to program

* renamed instances of program to pipeline
  • Loading branch information
rydb authored Oct 26, 2024
1 parent 21bf07a commit b8180ad
Show file tree
Hide file tree
Showing 19 changed files with 205 additions and 193 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ This syntax follows the bevy preprocessor syntax, which is roughly supported by

### Using the template

The project comes with a `Program` trait. Hopefully it should be enough for your needs. You just need to replace the current implementation with yours in `lib/lib.rs`: `pub use crate::demo::DemoProgram as CurrentProgram;`.
The project comes with a `PipelineFuncs` trait. Hopefully it should be enough for your needs. You just need to replace the current implementation with yours in `lib/lib.rs`: `demo_pipelines::demo::Pipeline as CurrentPipeline;`.


---
Expand All @@ -83,8 +83,8 @@ Note that they cannot be generic. Example:

```rust
#[no_mangle]
pub fn get_program_name(program: &CurrentProgram) -> String {
program.get_name().to_owned()
pub fn get_pipeline_name(pipeline: &CurrentPipeline) -> String {
pipeline.get_name().to_owned()
}
```

Expand Down
43 changes: 22 additions & 21 deletions lib/src/demo_boids.rs → lib/src/demo_pipelines/boids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use nanorand::{Rng, WyRand};
use wgpu::util::DeviceExt;

use crate::frame_rate::FrameRate;
use crate::program::{Program, ProgramError};
use crate::shader_builder::ShaderBuilder;
use crate::pipeline::{PipelineError, PipelineFuncs};
use crate::ShaderBuilderForLibrary;

const NUM_PARTICLES: u32 = 1500;
const PARTICLES_PER_GROUP: u32 = 64;
Expand All @@ -30,7 +30,7 @@ struct RenderPass {

#[repr(C)]
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
struct DemoBoidsSettings {
struct BoidsSettings {
delta_t: f32, // cohesion
rule1_distance: f32, // separation
rule2_distance: f32, // alignment
Expand All @@ -41,7 +41,7 @@ struct DemoBoidsSettings {
speed: f32,
}

impl DemoBoidsSettings {
impl BoidsSettings {
pub fn new() -> Self {
Self {
delta_t: 0.04f32,
Expand All @@ -61,15 +61,15 @@ impl DemoBoidsSettings {
}

/// Example struct holds references to wgpu resources and frame persistent data
pub struct DemoBoidsProgram {
settings: DemoBoidsSettings,
pub struct Pipeline {
settings: BoidsSettings,
compute_pass: ComputePass,
render_pass: RenderPass,
frame_rate: FrameRate,
last_update: web_time::Instant,
}

impl Program for DemoBoidsProgram {
impl PipelineFuncs for Pipeline {
fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities {
wgpu::DownlevelCapabilities {
flags: wgpu::DownlevelFlags::COMPUTE_SHADERS,
Expand All @@ -82,9 +82,9 @@ impl Program for DemoBoidsProgram {
wgpu::Limits::downlevel_defaults()
}

/// Get program name.
/// Get pipeline name.
fn get_name() -> &'static str {
"Demo boids"
"demo boids"
}

/// constructs initial instance of Example struct
Expand All @@ -93,12 +93,12 @@ impl Program for DemoBoidsProgram {
device: &wgpu::Device,
adapter: &wgpu::Adapter,
_surface_configuration: &wgpu::SurfaceConfiguration,
) -> Result<Self, ProgramError> {
let settings = DemoBoidsSettings::new();
) -> Result<Self, PipelineError> {
let settings = BoidsSettings::new();

let (compute_pass, render_pass) = Self::create_passes(surface, device, adapter)?;

Ok(DemoBoidsProgram {
Ok(Pipeline {
settings,
compute_pass,
render_pass,
Expand All @@ -113,7 +113,7 @@ impl Program for DemoBoidsProgram {
surface: &wgpu::Surface,
device: &wgpu::Device,
adapter: &wgpu::Adapter,
) -> Result<(), ProgramError> {
) -> Result<(), PipelineError> {
self.compute_pass.compute_pipeline =
Self::create_compute_pipeline(device, &self.compute_pass.bind_group_layout)?;
self.render_pass.render_pipeline = Self::create_render_pipeline(surface, device, adapter)?;
Expand Down Expand Up @@ -239,12 +239,13 @@ impl Program for DemoBoidsProgram {
}
}

impl DemoBoidsProgram {
impl Pipeline {
fn create_compute_pipeline(
device: &wgpu::Device,
compute_bind_group_layout: &wgpu::BindGroupLayout,
) -> Result<wgpu::ComputePipeline, ProgramError> {
let compute_shader = ShaderBuilder::create_module(device, "demo_boids/compute.wgsl")?;
) -> Result<wgpu::ComputePipeline, PipelineError> {
let compute_shader =
ShaderBuilderForLibrary::create_module(device, "demos/boids/compute.wgsl")?;

let compute_pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
Expand All @@ -269,8 +270,8 @@ impl DemoBoidsProgram {
surface: &wgpu::Surface,
device: &wgpu::Device,
adapter: &wgpu::Adapter,
) -> Result<wgpu::RenderPipeline, ProgramError> {
let draw_shader = ShaderBuilder::create_module(device, "demo_boids/draw.wgsl")?;
) -> Result<wgpu::RenderPipeline, PipelineError> {
let draw_shader = ShaderBuilderForLibrary::create_module(device, "demos/boids/draw.wgsl")?;

let swapchain_capabilities = surface.get_capabilities(adapter);
let swapchain_format = swapchain_capabilities.formats[0];
Expand Down Expand Up @@ -322,11 +323,11 @@ impl DemoBoidsProgram {
surface: &wgpu::Surface,
device: &wgpu::Device,
adapter: &wgpu::Adapter,
) -> Result<(ComputePass, RenderPass), ProgramError> {
) -> Result<(ComputePass, RenderPass), PipelineError> {
let sim_param_buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Simulation Parameter Buffer"),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
size: DemoBoidsSettings::get_size(),
size: BoidsSettings::get_size(),
mapped_at_creation: false,
});

Expand Down Expand Up @@ -361,7 +362,7 @@ impl DemoBoidsProgram {
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: wgpu::BufferSize::new(DemoBoidsSettings::get_size()),
min_binding_size: wgpu::BufferSize::new(BoidsSettings::get_size()),
},
count: None,
},
Expand Down
5 changes: 5 additions & 0 deletions lib/src/demo_pipelines/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//! pipelines for demo shaders.
pub mod boids;
pub mod polygon;
pub mod raymarching;
51 changes: 26 additions & 25 deletions lib/src/demo_polygon.rs → lib/src/demo_pipelines/polygon.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::frame_rate::FrameRate;
use crate::program::{Program, ProgramError};
use crate::shader_builder::ShaderBuilder;
use crate::pipeline::{PipelineError, PipelineFuncs};
use crate::ShaderBuilderForLibrary;

/// A simple struct to store a wgpu pass with a uniform buffer.
#[derive(Debug)]
Expand All @@ -13,12 +13,12 @@ pub struct Pass {
pub uniform_buf: wgpu::Buffer,
}

/// Settings for the `DemoProgram`
/// `polygon_edge_count` is not exposed in ui on purpose for demo purposes
/// Settings for the `PipelineFuncs`
/// `polygon_edge_count` is not exposed in ui on purpose for purposes
/// change it in the code with hot-reload enable to see it working.
#[repr(C)]
#[derive(Clone, Copy, Debug, bytemuck::Pod, bytemuck::Zeroable)]
pub struct DemoPolygonSettings {
pub struct PolygonSettings {
// elapsed take the speed into consideration
elapsed: f32,
/// polygon radius in window, between 0 and 1
Expand All @@ -29,7 +29,7 @@ pub struct DemoPolygonSettings {
speed: f32, // exposed in ui
}

impl DemoPolygonSettings {
impl PolygonSettings {
pub fn new() -> Self {
Self {
elapsed: 0.0,
Expand All @@ -43,42 +43,43 @@ impl DemoPolygonSettings {
std::mem::size_of::<Self>() as _
}
}
/// Demo Program rotation a regular polygon showcasing the three type of live updates
/// Pipeline showcasing the three type of live updates via the rotation of a regular polygon
///
/// shader: `draw.wgsl`
/// rust: `polygon_edge_count` in `DemoProgram::update`
/// rust: `polygon_edge_count` in [`PipelineFuncs::update`]
/// ui: `size` and `speed`
#[derive(Debug)]
pub struct DemoPolygonProgram {
pub struct Pipeline {
render_pass: Pass,
_start_time: web_time::Instant, // std::time::Instant is not compatible with wasm
last_update: web_time::Instant,
settings: DemoPolygonSettings,
settings: PolygonSettings,
frame_rate: FrameRate,
}

impl Program for DemoPolygonProgram {
/// Create program.
impl PipelineFuncs for Pipeline {
/// Create pipeline.
/// Assume the `render_pipeline` will be properly initialized.
fn init(
surface: &wgpu::Surface,
device: &wgpu::Device,
adapter: &wgpu::Adapter,
_surface_configuration: &wgpu::SurfaceConfiguration,
) -> Result<Self, ProgramError> {
) -> Result<Self, PipelineError> {
let render_pass = Self::create_render_pass(surface, device, adapter)?;

Ok(Self {
render_pass,
_start_time: web_time::Instant::now(),
last_update: web_time::Instant::now(),
settings: DemoPolygonSettings::new(),
settings: PolygonSettings::new(),
frame_rate: FrameRate::default(),
})
}

/// Get program name.
/// Get pipeline name.
fn get_name() -> &'static str {
"Demo polygon"
"demo polygon"
}

/// Recreate render pass.
Expand All @@ -87,7 +88,7 @@ impl Program for DemoPolygonProgram {
surface: &wgpu::Surface,
device: &wgpu::Device,
adapter: &wgpu::Adapter,
) -> Result<(), ProgramError> {
) -> Result<(), PipelineError> {
self.render_pass = Self::create_render_pass(surface, device, adapter)?;
Ok(())
}
Expand All @@ -101,7 +102,7 @@ impl Program for DemoPolygonProgram {
) {
}

/// Update program before rendering.
/// Update pipeline before rendering.
fn update(&mut self, queue: &wgpu::Queue) {
// Set the edge count of the regular polygon.
// This is not exposed in the ui on purpose to demonstrate the rust hot reload.
Expand All @@ -119,7 +120,7 @@ impl Program for DemoPolygonProgram {
);
}

/// Render program.
/// Render pipeline.
fn render(&self, view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue) {
// We draw a regular polygon with n edges
// by drawing the n triangles starting from the center and with two adjacent vertices
Expand Down Expand Up @@ -169,17 +170,17 @@ impl Program for DemoPolygonProgram {
}
}

impl DemoPolygonProgram {
impl Pipeline {
/// Create render pipeline.
/// In debug mode it will return a `ProgramError` if it failed compiling a shader
/// In debug mode it will return a `PipelineError` if it failed compiling a shader
/// In release/wasm, il will crash since wgpu does not return errors in such situations.
fn create_render_pipeline(
surface: &wgpu::Surface,
device: &wgpu::Device,
adapter: &wgpu::Adapter,
uniforms_bind_group_layout: &wgpu::BindGroupLayout,
) -> Result<wgpu::RenderPipeline, ProgramError> {
let shader = ShaderBuilder::create_module(device, "demo_polygon/draw.wgsl")?;
) -> Result<wgpu::RenderPipeline, PipelineError> {
let shader = ShaderBuilderForLibrary::create_module(device, "demos/polygon/draw.wgsl")?;
// let shader = ShaderBuilder::create_module(device, "test_preprocessor/draw.wgsl")?; // uncomment to test preprocessor

let swapchain_capabilities = surface.get_capabilities(adapter);
Expand Down Expand Up @@ -222,11 +223,11 @@ impl DemoPolygonProgram {
surface: &wgpu::Surface,
device: &wgpu::Device,
adapter: &wgpu::Adapter,
) -> Result<Pass, ProgramError> {
) -> Result<Pass, PipelineError> {
// create uniform buffer.
let uniforms = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Uniforms Buffer"),
size: DemoPolygonSettings::get_size(),
size: PolygonSettings::get_size(),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
});
Expand Down
Loading

0 comments on commit b8180ad

Please sign in to comment.