Skip to content

Commit

Permalink
Refactor out renderer shader
Browse files Browse the repository at this point in the history
Create examples folder and dedicated builder crate
  • Loading branch information
tombh committed Jun 30, 2022
1 parent 86bda52 commit 6d5e01b
Show file tree
Hide file tree
Showing 27 changed files with 665 additions and 576 deletions.
575 changes: 278 additions & 297 deletions Cargo.lock

Large diffs are not rendered by default.

71 changes: 21 additions & 50 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,53 +1,24 @@
[package]
name = "wrach"
version = "0.0.0"
authors = []
edition = "2018"
resolver = "2"

[features]
default = ["use-compiled-tools"]
use-installed-tools = ["spirv-builder/use-installed-tools"]
use-compiled-tools = ["spirv-builder/use-compiled-tools"]

[dependencies]
shaders = { path = "shaders" }
futures = { version = "0.3", default-features = false, features = ["std", "executor"] }
wgpu = { version = "0.11.0", features = ["spirv"] }
wgpu-hal = "=0.11.2"
winit = { version = "0.25", features = ["web-sys"] }
bytemuck = "1.7.2"
crevice = { version = "0.8.0", features = ["glam"] }
rand = "0.7.2"
cgmath = "0.18.0"
env_logger = "0.9.0"
async-executor = "1.4.1"
pollster = "0.2.4"
log = "0.4.14"
cfg-if = "1.0.0"


[build-dependencies]
spirv-std = { git = "https://github.com/EmbarkStudios/rust-gpu", rev = "0866cf59", features = [ "glam" ] }
spirv-builder = { git = "https://github.com/EmbarkStudios/rust-gpu", rev = "0866cf59", default-features = false }

[workspace]
members = ["shaders"]

# Compile build-dependencies in release mode with
# the same settings as regular dependencies.
resolver = "2"
members = [
"shaders/rust-gpu-compiler",
"shaders/physics",
"shaders/renderer",
"runners/wgpu",
"examples/basic"
]

# Enable incremental by default in release mode.
[profile.release]
incremental = true
# HACK(eddyb) this is the default but without explicitly specifying it, Cargo
# will treat the identical settings in `[profile.release.build-override]` below
# as different sets of `rustc` flags and will not reuse artifacts between them.
codegen-units = 256

# Compile build-dependencies in release mode with the same settings
# as regular dependencies (including the incremental enabled above).
[profile.release.build-override]
opt-level = 3
codegen-units = 16

# HACK(eddyb) also compile debug mode's build-dependencies with optimizations,
# because otherwise `rustc_codegen_spirv` (esspecially its linker) is too slow.
# Also `spirv-opt` *alone* takes (just) over an hour to run, though this only
# brings it down only to 10 minutes, so I've disabled it below, for now.
[profile.dev.build-override]
opt-level = 3

# HACK(eddyb) don't optimize the shader crate, to avoid `spirv-opt` taking
# a long time (10 minutes if itself was optimized, over an hour otherwise).
[profile.release.package."shaders"]
opt-level = 0
incremental = true
codegen-units = 256
14 changes: 0 additions & 14 deletions build.rs

This file was deleted.

11 changes: 11 additions & 0 deletions examples/basic/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "wrach-physics-example"
version = "0.0.0"
authors = []
edition = "2018"

[dependencies]
wrach-physics-shaders = { path = "../../shaders/physics" }
wrach-renderer-shader = { path = "../../shaders/renderer" }
wrach-wgpu = { path = "../../runners/wgpu" }

145 changes: 145 additions & 0 deletions examples/basic/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
use wgpu::util::DeviceExt;
use wrach_physics_shaders as physics;
use wrach_wgpu::event_loop::event_loop::{EventLoop, Renderer};
use wrach_wgpu::pipeline::builder::Builder;
use wrach_wgpu::{bytemuck, gpu_manager, wgpu};

struct SquareVertex {
pipeline: wgpu::RenderPipeline,
vertices: wgpu::Buffer,
}

impl SquareVertex {
fn init_render_pipeline(
shader_module: &wgpu::ShaderModule,
manager: &gpu_manager::GPUManager,
) -> wgpu::RenderPipeline {
let render_pipeline_layout =
manager
.device
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("render"),
bind_group_layouts: &[],
push_constant_ranges: &[],
});

let particle_array_stride =
std::mem::size_of::<physics::particle::Std140ParticleBasic>() as u64;

let fragment = wgpu::FragmentState {
module: shader_module,
entry_point: "main_fs",
targets: &[manager.config.format.into()],
};

let pipeline_descriptor = wgpu::RenderPipelineDescriptor {
label: None,
layout: Some(&render_pipeline_layout),
vertex: wgpu::VertexState {
module: shader_module,
entry_point: "main_vs",
buffers: &[
wgpu::VertexBufferLayout {
array_stride: particle_array_stride,
step_mode: wgpu::VertexStepMode::Instance,
attributes: &wgpu::vertex_attr_array![
0 => Float32x4, 1 => Float32x2, 2 => Float32x2, 3 => Float32x2
],
},
wgpu::VertexBufferLayout {
array_stride: 1 * 8,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &wgpu::vertex_attr_array![4 => Float32x2],
},
],
},
fragment: Some(fragment),
primitive: wgpu::PrimitiveState::default(),
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
};

manager.device.create_render_pipeline(&pipeline_descriptor)
}

fn init_vertices_buffer(manager: &gpu_manager::GPUManager) -> wgpu::Buffer {
// A square made of 1 triangles
#[rustfmt::skip]
let vertex_buffer_data: Vec<f32> = [
// First triangle ----------------------
-1, -1, -1, 1, 1, 1,
// Second triangle ----------------------
-1, -1, 1, 1, 1, -1,
]
.iter()
.map(|x| 0.5 * physics::particle::PIXEL_SIZE * (*x as f32))
.collect();
let mut square = [0.0; 12];
for i in 0..12 {
square[i] = vertex_buffer_data[i];
}
manager
.device
.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Vertex Buffer"),
contents: bytemuck::bytes_of(&square),
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
})
}

fn init_render_pass<'a>(
command_encoder: &'a mut wgpu::CommandEncoder,
view: &'a wgpu::TextureView,
) -> wgpu::RenderPass<'a> {
let color_attachments = [wgpu::RenderPassColorAttachment {
view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
store: true,
},
}];

let render_pass_descriptor = wgpu::RenderPassDescriptor {
label: None,
color_attachments: &color_attachments,
depth_stencil_attachment: None,
};

command_encoder.begin_render_pass(&render_pass_descriptor)
}
}

impl Renderer for SquareVertex {
fn new(manager: &gpu_manager::GPUManager) -> Self {
let shader_module = Builder::shader(&manager.device, "shaders/renderer");
Self {
pipeline: Self::init_render_pipeline(&shader_module, manager),
vertices: Self::init_vertices_buffer(manager),
}
}

fn render_pass<'a, T: Renderer>(
&self,
event_loop: &mut EventLoop<'_, T>,
command_encoder: &'a mut wgpu::CommandEncoder,
view: &'a wgpu::TextureView,
) {
let index = event_loop.bind_group_index_toggled();
let particle_buffer = event_loop.manager.pipeline.particle_buffers[index].slice(..);

command_encoder.push_debug_group("render pixels");
{
let mut rpass = Self::init_render_pass(command_encoder, view);
rpass.set_pipeline(&self.pipeline);
rpass.set_vertex_buffer(0, particle_buffer);
rpass.set_vertex_buffer(1, self.vertices.slice(..));
rpass.draw(0..6, 0..physics::world::NUM_PARTICLES as u32);
}
command_encoder.pop_debug_group();
}
}

fn main() {
EventLoop::<SquareVertex>::start()
}
23 changes: 23 additions & 0 deletions runners/wgpu/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "wrach-wgpu"
version = "0.0.0"
authors = []
edition = "2018"

[dependencies]
wrach-physics-shaders = { path = "../../shaders/physics" }
rust-gpu-compiler = { path = "../../shaders/rust-gpu-compiler" }
futures = { version = "0.3", default-features = false, features = ["std", "executor"] }
wgpu = { version = "0.11.0", features = ["spirv"] }
wgpu-hal = "=0.11.2"
winit = { version = "0.25", features = ["web-sys"] }
bytemuck = "1.7.2"
crevice = { version = "0.8.0", features = ["glam"] }
rand = "0.7.2"
cgmath = "0.18.0"
env_logger = "0.9.0"
async-executor = "1.4.1"
pollster = "0.2.4"
log = "0.4.14"
cfg-if = "1.0.0"

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use winit::platform::run_return::EventLoopExtRunReturn;

use super::spawner;
use crate::gpu_manager;

use wrach_physics_shaders as physics;
pub struct EventLoop<'instance, T: Renderer> {
pub manager: gpu_manager::GPUManager,
renderer: &'instance T,
Expand All @@ -20,6 +20,8 @@ pub struct EventLoop<'instance, T: Renderer> {
}

pub trait Renderer {
fn new(_manager: &gpu_manager::GPUManager) -> Self;

fn render_pass<T: Renderer>(
&self,
_event_loop: &mut EventLoop<T>,
Expand All @@ -30,8 +32,17 @@ pub trait Renderer {
}

impl<'instance, T: Renderer> EventLoop<'instance, T> {
pub fn run(renderer: &'instance T) {
pub fn start() {
let (manager, event_loop) = pollster::block_on(gpu_manager::GPUManager::setup());
let renderer = T::new(&manager);
EventLoop::run(manager, &renderer, event_loop);
}

fn run(
manager: gpu_manager::GPUManager,
renderer: &'instance T,
event_loop: winit::event_loop::EventLoop<()>,
) {
let instance = Self {
manager,
renderer,
Expand All @@ -46,7 +57,7 @@ impl<'instance, T: Renderer> EventLoop<'instance, T> {
instance.enter(event_loop)
}

pub fn enter(mut self, mut event_loop: winit::event_loop::EventLoop<()>) {
fn enter(mut self, mut event_loop: winit::event_loop::EventLoop<()>) {
log::info!("Entering render loop...");
event_loop.run_return(move |event, _, control_flow| {
// Only captured so they're droppped
Expand Down Expand Up @@ -216,7 +227,7 @@ impl<'instance, T: Renderer> EventLoop<'instance, T> {
self.pre_compute_pass(command_encoder);
command_encoder.push_debug_group("compute");
{
for _ in 0..shaders::particle::DEFAULT_NUM_SOLVER_SUBSTEPS {
for _ in 0..physics::particle::DEFAULT_NUM_SOLVER_SUBSTEPS {
self.compute_pass_stage(command_encoder, 0);
self.compute_pass_stage(command_encoder, 1);
self.compute_pass_stage(command_encoder, 2);
Expand All @@ -243,7 +254,7 @@ impl<'instance, T: Renderer> EventLoop<'instance, T> {
cpass.set_bind_group(0, bind_groups, &[]);
cpass.set_pipeline(&self.manager.pipeline.compute_pipeline);

let ps = shaders::compute::Params { stage };
let ps = physics::compute::Params { stage };
cpass.set_push_constants(0, bytemuck::bytes_of(&ps.as_std140()));
cpass.dispatch(self.manager.pipeline.work_group_count, 1, 1);
}
Expand Down
File renamed without changes.
File renamed without changes.
8 changes: 5 additions & 3 deletions src/gpu_manager.rs → runners/wgpu/src/gpu_manager.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::pipeline::pipeline;
use winit;

use wrach_physics_shaders as physics;

pub struct GPUManager {
pub window: winit::window::Window,
pub instance: wgpu::Instance,
Expand All @@ -22,8 +24,8 @@ impl GPUManager {
builder = builder
.with_title("Wrach")
.with_inner_size(winit::dpi::PhysicalSize::new(
shaders::world::MAP_WIDTH * shaders::world::WINDOW_ZOOM,
shaders::world::MAP_HEIGHT * shaders::world::WINDOW_ZOOM,
physics::world::MAP_WIDTH * physics::world::WINDOW_ZOOM,
physics::world::MAP_HEIGHT * physics::world::WINDOW_ZOOM,
));
let window = builder.build(&event_loop).unwrap();

Expand Down Expand Up @@ -97,7 +99,7 @@ impl GPUManager {
};

surface.configure(&device, &config);
let pipeline = pipeline::Pipeline::init(&config, &device);
let pipeline = pipeline::Pipeline::init(&device);

let manager = Self {
window,
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs → runners/wgpu/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
pub use bytemuck;
pub use wgpu;

pub mod event_loop;
pub mod gpu_manager;
pub mod pipeline;
Loading

0 comments on commit 6d5e01b

Please sign in to comment.