-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from druskus20/refactor
feat: heavy refactor, compute_base to be shared across demos
Showing
12 changed files
with
549 additions
and
524 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
use bytemuck::{Pod, Zeroable}; | ||
use wgpu::util::DeviceExt; | ||
|
||
use crate::{camera::Camera, rendering_context::Context, state::State}; | ||
|
||
/// Base struct for every compute pipeline | ||
#[derive(Debug)] | ||
pub struct ComputeBase { | ||
// Layouts are needed to create the pipeline | ||
pub output_texture_layout: wgpu::BindGroupLayout, | ||
pub camera_layout: wgpu::BindGroupLayout, | ||
pub debug_matrix_layout: wgpu::BindGroupLayout, | ||
|
||
// Groups are passed to the pipeline | ||
pub debug_matrix_group: wgpu::BindGroup, | ||
pub camera_group: wgpu::BindGroup, | ||
pub output_texture_group: wgpu::BindGroup, | ||
|
||
camera_buffer: wgpu::Buffer, | ||
} | ||
|
||
pub const DESC_OUTPUT_TEXTURE: wgpu::BindGroupLayoutDescriptor<'static> = | ||
wgpu::BindGroupLayoutDescriptor { | ||
label: Some("Storage Texture Layour"), | ||
entries: &[wgpu::BindGroupLayoutEntry { | ||
binding: 0, | ||
visibility: wgpu::ShaderStages::COMPUTE, | ||
ty: wgpu::BindingType::StorageTexture { | ||
access: wgpu::StorageTextureAccess::WriteOnly, | ||
format: wgpu::TextureFormat::Rgba8Unorm, | ||
view_dimension: wgpu::TextureViewDimension::D2, | ||
}, | ||
count: None, | ||
}], | ||
}; | ||
|
||
pub const DESC_DEBUG_MATRIX: wgpu::BindGroupLayoutDescriptor<'static> = | ||
wgpu::BindGroupLayoutDescriptor { | ||
label: Some("Storage Texture Layour"), | ||
entries: &[wgpu::BindGroupLayoutEntry { | ||
binding: 0, | ||
visibility: wgpu::ShaderStages::COMPUTE, | ||
ty: wgpu::BindingType::StorageTexture { | ||
access: wgpu::StorageTextureAccess::WriteOnly, | ||
format: wgpu::TextureFormat::Rgba8Unorm, | ||
view_dimension: wgpu::TextureViewDimension::D2, | ||
}, | ||
count: None, | ||
}], | ||
}; | ||
|
||
pub const DESC_CAMERA_UNIFORMS: wgpu::BindGroupLayoutDescriptor<'static> = | ||
wgpu::BindGroupLayoutDescriptor { | ||
label: Some("Camera layout"), | ||
entries: &[wgpu::BindGroupLayoutEntry { | ||
binding: 0, | ||
visibility: wgpu::ShaderStages::COMPUTE, | ||
ty: wgpu::BindingType::Buffer { | ||
ty: wgpu::BufferBindingType::Uniform, | ||
has_dynamic_offset: false, | ||
min_binding_size: None, | ||
}, | ||
count: None, | ||
}], | ||
}; | ||
|
||
impl ComputeBase { | ||
pub fn new(ctx: &Context, state: &State, output_texture_view: &wgpu::TextureView) -> Self { | ||
let camera_layout = ctx.device.create_bind_group_layout(&DESC_CAMERA_UNIFORMS); | ||
let debug_matrix_layout = ctx.device.create_bind_group_layout(&DESC_DEBUG_MATRIX); | ||
let output_texture_layout = ctx.device.create_bind_group_layout(&DESC_OUTPUT_TEXTURE); | ||
|
||
let uniforms: CameraUniforms = CameraUniforms::from(&state.camera); | ||
|
||
let camera_buffer = ctx | ||
.device | ||
.create_buffer_init(&wgpu::util::BufferInitDescriptor { | ||
label: Some("Camera Buffer"), | ||
contents: bytemuck::cast_slice(&[uniforms]), | ||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, | ||
}); | ||
|
||
let camera_group = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { | ||
layout: &camera_layout, | ||
entries: &[wgpu::BindGroupEntry { | ||
binding: 0, | ||
resource: camera_buffer.as_entire_binding(), | ||
}], | ||
label: Some("camera_bind_group"), | ||
}); | ||
|
||
let debug_matrix_texture = ctx.device.create_texture(&wgpu::TextureDescriptor { | ||
label: Some("Debug Matrix Texture"), | ||
size: wgpu::Extent3d { | ||
width: ctx.surface_config.width, | ||
height: ctx.surface_config.height, | ||
depth_or_array_layers: 1, | ||
}, | ||
mip_level_count: 1, | ||
sample_count: 1, | ||
dimension: wgpu::TextureDimension::D2, | ||
format: wgpu::TextureFormat::Rgba8Unorm, | ||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::STORAGE_BINDING, | ||
view_formats: &[], | ||
}); | ||
|
||
let debug_matrix_group = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { | ||
label: Some("Debug Matrix Bind Group"), | ||
layout: &debug_matrix_layout, | ||
entries: &[wgpu::BindGroupEntry { | ||
binding: 0, | ||
resource: wgpu::BindingResource::TextureView( | ||
&debug_matrix_texture.create_view(&wgpu::TextureViewDescriptor::default()), | ||
), | ||
}], | ||
}); | ||
|
||
let output_texture_group = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { | ||
label: Some("Compute Output Texture Bind Group"), | ||
layout: &output_texture_layout, | ||
entries: &[wgpu::BindGroupEntry { | ||
binding: 0, | ||
resource: wgpu::BindingResource::TextureView(output_texture_view), | ||
}], | ||
}); | ||
Self { | ||
camera_layout, | ||
debug_matrix_group, | ||
output_texture_layout, | ||
camera_group, | ||
debug_matrix_layout, | ||
output_texture_group, | ||
camera_buffer, | ||
} | ||
} | ||
|
||
pub fn update(&self, ctx: &Context, state: &State) { | ||
let uniforms = CameraUniforms::from(&state.camera); | ||
ctx.queue | ||
.write_buffer(&self.camera_buffer, 0, bytemuck::cast_slice(&[uniforms])); | ||
} | ||
} | ||
|
||
#[repr(C, align(16))] | ||
#[derive(Debug, Copy, Clone, Pod, Zeroable)] | ||
pub struct CameraUniforms { | ||
view_matrix: [[f32; 4]; 4], | ||
projection_matrix: [[f32; 4]; 4], | ||
camera_position: [f32; 3], | ||
_padding: f32, | ||
} | ||
|
||
impl From<&Camera> for CameraUniforms { | ||
fn from(camera: &Camera) -> Self { | ||
CameraUniforms { | ||
view_matrix: camera.view_matrix().into(), | ||
projection_matrix: camera.projection_matrix().into(), | ||
camera_position: camera.position.into(), | ||
_padding: 0.0, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
use crate::context; | ||
use crate::rendering_context::Context; | ||
use crate::state::State; | ||
use crate::Result; | ||
|
||
pub mod compute_base; | ||
pub mod simple; | ||
|
||
pub trait RenderingDemo: Sized { | ||
fn init(ctx: &mut context::Context) -> Result<Self>; | ||
fn compute(&self, ctx: &mut context::Context) -> Result<()>; | ||
pub trait Demo: Sized { | ||
fn init(ctx: &Context, state: &State, output_texture_view: &wgpu::TextureView) -> Result<Self>; | ||
fn update_gpu_state(&self, ctx: &Context, state: &State) -> Result<()>; | ||
fn compute_pass(&self, ctx: &Context) -> Result<()>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// lib.rs | ||
use winit::window::Window; | ||
|
||
use crate::Result; | ||
|
||
#[derive(Debug)] | ||
pub struct Context<'a> { | ||
pub surface: wgpu::Surface<'a>, | ||
pub device: wgpu::Device, | ||
pub queue: wgpu::Queue, | ||
pub surface_config: wgpu::SurfaceConfiguration, | ||
pub size: winit::dpi::PhysicalSize<u32>, | ||
pub window: &'a Window, | ||
} | ||
|
||
impl<'a> Context<'a> { | ||
// Creating some of the wgpu types requires async code | ||
pub async fn new(window: &'a Window) -> Result<Context<'a>> { | ||
let instance = wgpu::Instance::default(); | ||
let surface = instance.create_surface(window).unwrap(); | ||
let adapter = instance | ||
.request_adapter(&wgpu::RequestAdapterOptions { | ||
power_preference: wgpu::PowerPreference::default(), | ||
compatible_surface: Some(&surface), | ||
force_fallback_adapter: false, | ||
}) | ||
.await | ||
.unwrap(); | ||
|
||
let (device, queue) = adapter | ||
.request_device(&wgpu::DeviceDescriptor::default(), None) | ||
.await | ||
.unwrap(); | ||
|
||
let surface_caps = surface.get_capabilities(&adapter); | ||
let surface_format = surface_caps | ||
.formats | ||
.iter() | ||
.find(|f| f.is_srgb()) | ||
.copied() | ||
.unwrap_or(surface_caps.formats[0]); | ||
|
||
let size = window.inner_size(); | ||
let config = wgpu::SurfaceConfiguration { | ||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT, | ||
format: surface_format, | ||
width: size.width, | ||
height: size.height, | ||
present_mode: surface_caps.present_modes[0], | ||
alpha_mode: surface_caps.alpha_modes[0], | ||
view_formats: vec![], | ||
desired_maximum_frame_latency: 2, | ||
}; | ||
|
||
//let pipelines = Pipelines::new_from_demo(&simple::Simple, &device, &config)?; | ||
|
||
Ok(Self { | ||
window, | ||
surface, | ||
device, | ||
queue, | ||
surface_config: config, | ||
size, | ||
}) | ||
} | ||
|
||
pub fn window(&self) -> &Window { | ||
self.window | ||
} | ||
|
||
pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) { | ||
if new_size.width > 0 && new_size.height > 0 { | ||
self.size = new_size; | ||
self.surface_config.width = new_size.width; | ||
self.surface_config.height = new_size.height; | ||
self.surface.configure(&self.device, &self.surface_config); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
use tracing::debug; | ||
use winit::event::{ElementState, MouseButton, WindowEvent}; | ||
|
||
use crate::camera::{Camera, CameraController}; | ||
|
||
#[derive(Debug)] | ||
pub struct State { | ||
pub camera: Camera, | ||
pub camera_controller: CameraController, | ||
mouse_pressed: bool, | ||
last_mouse_position: Option<(f64, f64)>, | ||
} | ||
|
||
impl State { | ||
pub fn new(aspect: f32) -> Self { | ||
let camera = crate::camera::Camera::new(aspect); | ||
Self { | ||
camera, | ||
camera_controller: CameraController::new(0.2, 0.2), | ||
mouse_pressed: false, | ||
last_mouse_position: None, | ||
} | ||
} | ||
|
||
pub fn process_input(&mut self, event: &WindowEvent) -> bool { | ||
let r = match event { | ||
//WindowEvent::KeyboardInput { | ||
// event: | ||
// KeyEvent { | ||
// physical_key: PhysicalKey::Code(key), | ||
// state, | ||
// .. | ||
// }, | ||
// .. | ||
//} => self.camera_controller.process_keyboard(*key, *state), | ||
WindowEvent::CursorMoved { position, .. } => { | ||
if self.mouse_pressed { | ||
let current_pos = (position.x, position.y); | ||
|
||
// Calculate delta movement when mouse is pressed | ||
if let Some(last_pos) = self.last_mouse_position { | ||
let dx = current_pos.0 - last_pos.0; | ||
let dy = current_pos.1 - last_pos.1; | ||
|
||
// Use the existing process_mouse method | ||
self.camera_controller.process_mouse(dx, dy); | ||
} | ||
|
||
// Update last mouse position | ||
self.last_mouse_position = Some(current_pos); | ||
} | ||
true | ||
} | ||
WindowEvent::MouseWheel { delta, .. } => { | ||
self.camera_controller.process_scroll(delta); | ||
true | ||
} | ||
WindowEvent::MouseInput { | ||
button: MouseButton::Left, | ||
state, | ||
.. | ||
} => { | ||
self.mouse_pressed = *state == ElementState::Pressed; | ||
true | ||
} | ||
_ => false, | ||
}; | ||
|
||
if r { | ||
debug!(target = "input", "Processed event: {:?}", event); | ||
} | ||
r | ||
} | ||
|
||
pub fn update(&mut self) { | ||
self.camera_controller.update_camera(&mut self.camera); | ||
} | ||
} |