Enhance RenderPass usability
This commit is contained in:
parent
4313ce8017
commit
cf4ff0e80e
|
@ -201,7 +201,7 @@ impl Renderer {
|
||||||
.for_each(|(pass_index, rp)| {
|
.for_each(|(pass_index, rp)| {
|
||||||
let mut phases_buf = Vec::new();
|
let mut phases_buf = Vec::new();
|
||||||
phases_buf.clear();
|
phases_buf.clear();
|
||||||
rp.begin_frame(frame_index, &mut phases_buf);
|
rp.begin_frame(frame_index, &mut phases_buf, &self.queue);
|
||||||
|
|
||||||
let mut passes = phase_passes.lock().unwrap();
|
let mut passes = phase_passes.lock().unwrap();
|
||||||
for phase in phases_buf.into_iter() {
|
for phase in phases_buf.into_iter() {
|
||||||
|
|
48
src/pass.rs
48
src/pass.rs
|
@ -1,7 +1,7 @@
|
||||||
//! Render pass data structures and interfaces.
|
//! Render pass data structures and interfaces.
|
||||||
|
|
||||||
use crate::phase::{Phase, PhaseKind};
|
use crate::phase::Phase;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub mod mesh;
|
pub mod mesh;
|
||||||
|
|
||||||
|
@ -30,6 +30,11 @@ pub trait RenderPass: Send + Sync {
|
||||||
/// A structure that contains a pass's per-frame data.
|
/// A structure that contains a pass's per-frame data.
|
||||||
type FrameData: Send + Sync;
|
type FrameData: Send + Sync;
|
||||||
|
|
||||||
|
/// Gets a short name for this pass.
|
||||||
|
fn get_name(&self) -> &str {
|
||||||
|
std::any::type_name::<Self>()
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets up a new instance of [Self::FrameData].
|
/// Sets up a new instance of [Self::FrameData].
|
||||||
///
|
///
|
||||||
/// Called when a render pass is added to [crate::Renderer].
|
/// Called when a render pass is added to [crate::Renderer].
|
||||||
|
@ -40,17 +45,24 @@ pub trait RenderPass: Send + Sync {
|
||||||
///
|
///
|
||||||
/// This is the only opportunity the render pass has to mutate this frame's
|
/// This is the only opportunity the render pass has to mutate this frame's
|
||||||
/// data this frame, so all setup for future phases should be done here.
|
/// data this frame, so all setup for future phases should be done here.
|
||||||
fn begin_frame(&self, data: &mut Self::FrameData, phases: &mut Vec<Phase>);
|
///
|
||||||
|
/// The render pass is also given access to the [queue][wgpu::Queue] this
|
||||||
|
/// frame will be submitted on, and can be used to transfer image or buffer
|
||||||
|
/// data to the GPU.
|
||||||
|
fn begin_frame(&self, data: &mut Self::FrameData, phases: &mut Vec<Phase>, queue: &wgpu::Queue);
|
||||||
|
|
||||||
fn record_commands(&self, data: PhaseData<&Self::FrameData>, cmds: &mut wgpu::CommandEncoder);
|
fn record_commands(&self, data: PhaseData<&Self::FrameData>, cmds: &mut wgpu::CommandEncoder) {}
|
||||||
|
|
||||||
fn record_compute<'a>(
|
fn record_compute<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
data: PhaseData<&Self::FrameData>,
|
data: PhaseData<&Self::FrameData>,
|
||||||
cmds: &mut wgpu::ComputePass<'a>,
|
cmds: &mut wgpu::ComputePass<'a>,
|
||||||
);
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
fn record_render(&self, data: PhaseData<&Self::FrameData>) -> Option<wgpu::RenderBundle>;
|
fn record_render(&self, data: PhaseData<&Self::FrameData>) -> Option<wgpu::RenderBundle> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The interface trait for [RenderPassBox], allowing use of a statically-sized
|
/// The interface trait for [RenderPassBox], allowing use of a statically-sized
|
||||||
|
@ -59,7 +71,7 @@ pub trait RenderPass: Send + Sync {
|
||||||
/// Functions on this trait map one-to-one with [RenderPass], except that
|
/// Functions on this trait map one-to-one with [RenderPass], except that
|
||||||
/// frame data is passed by index and not by reference.
|
/// frame data is passed by index and not by reference.
|
||||||
pub trait RenderPassBoxTrait: Send + Sync {
|
pub trait RenderPassBoxTrait: Send + Sync {
|
||||||
fn begin_frame(&mut self, data_index: usize, phases: &mut Vec<Phase>);
|
fn begin_frame(&mut self, data_index: usize, phases: &mut Vec<Phase>, queue: &wgpu::Queue);
|
||||||
|
|
||||||
fn record_commands(&self, data: IndexedPhaseData, cmds: &mut wgpu::CommandEncoder);
|
fn record_commands(&self, data: IndexedPhaseData, cmds: &mut wgpu::CommandEncoder);
|
||||||
|
|
||||||
|
@ -117,23 +129,35 @@ impl<T: RenderPass> RenderPassBox<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RenderPass> RenderPassBoxTrait for RenderPassBox<T> {
|
impl<T: RenderPass> RenderPassBoxTrait for RenderPassBox<T> {
|
||||||
fn begin_frame(&mut self, data_index: usize, phases: &mut Vec<Phase>) {
|
fn begin_frame(&mut self, data_index: usize, phases: &mut Vec<Phase>, queue: &wgpu::Queue) {
|
||||||
|
let rp = &self.render_pass;
|
||||||
|
let name = rp.get_name();
|
||||||
|
println!("{}::begin_frame()", name);
|
||||||
let frame_data = &mut self.frame_data[data_index];
|
let frame_data = &mut self.frame_data[data_index];
|
||||||
self.render_pass.begin_frame(frame_data, phases)
|
rp.begin_frame(frame_data, phases, queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_commands(&self, data: IndexedPhaseData, cmds: &mut wgpu::CommandEncoder) {
|
fn record_commands(&self, data: IndexedPhaseData, cmds: &mut wgpu::CommandEncoder) {
|
||||||
|
let rp = &self.render_pass;
|
||||||
|
let name = rp.get_name();
|
||||||
|
println!("{}::record_commands(phase: {:?})", name, data.phase);
|
||||||
let frame_data = self.get_frame_data(data);
|
let frame_data = self.get_frame_data(data);
|
||||||
self.render_pass.record_commands(frame_data, cmds)
|
rp.record_commands(frame_data, cmds)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_compute<'a>(&'a self, data: IndexedPhaseData, cmds: &mut wgpu::ComputePass<'a>) {
|
fn record_compute<'a>(&'a self, data: IndexedPhaseData, cmds: &mut wgpu::ComputePass<'a>) {
|
||||||
|
let rp = &self.render_pass;
|
||||||
|
let name = rp.get_name();
|
||||||
|
println!("{}::record_compute(phase: {:?})", name, data.phase);
|
||||||
let frame_data = self.get_frame_data(data);
|
let frame_data = self.get_frame_data(data);
|
||||||
self.render_pass.record_compute(frame_data, cmds)
|
rp.record_compute(frame_data, cmds)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_render(&self, data: IndexedPhaseData) -> Option<wgpu::RenderBundle> {
|
fn record_render(&self, data: IndexedPhaseData) -> Option<wgpu::RenderBundle> {
|
||||||
|
let rp = &self.render_pass;
|
||||||
|
let name = rp.get_name();
|
||||||
|
println!("{}::record_compute(phase: {:?})", name, data.phase);
|
||||||
let frame_data = self.get_frame_data(data);
|
let frame_data = self.get_frame_data(data);
|
||||||
self.render_pass.record_render(frame_data)
|
rp.record_render(frame_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ impl MeshPass {
|
||||||
|
|
||||||
let render_pipeline_layout =
|
let render_pipeline_layout =
|
||||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("Render Pipeline Layout"),
|
label: Some("MeshPass Pipeline Layout"),
|
||||||
bind_group_layouts: &[&layouts.bind_viewport],
|
bind_group_layouts: &[&layouts.bind_viewport],
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
});
|
});
|
||||||
|
@ -111,7 +111,7 @@ impl MeshPass {
|
||||||
let shader = device.create_shader_module(&wgpu::include_wgsl!("mesh_shader.wgsl"));
|
let shader = device.create_shader_module(&wgpu::include_wgsl!("mesh_shader.wgsl"));
|
||||||
|
|
||||||
let opaque_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
let opaque_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
label: Some("Render Pipeline"),
|
label: Some("Opaque MeshPass Pipeline"),
|
||||||
layout: Some(&render_pipeline_layout),
|
layout: Some(&render_pipeline_layout),
|
||||||
vertex: wgpu::VertexState {
|
vertex: wgpu::VertexState {
|
||||||
module: &shader,
|
module: &shader,
|
||||||
|
@ -167,7 +167,7 @@ impl RenderPass for MeshPass {
|
||||||
FrameData {}
|
FrameData {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn begin_frame(&self, data: &mut FrameData, phases: &mut Vec<Phase>) {
|
fn begin_frame(&self, data: &mut FrameData, phases: &mut Vec<Phase>, queue: &wgpu::Queue) {
|
||||||
println!("MeshPass::begin_frame()");
|
println!("MeshPass::begin_frame()");
|
||||||
|
|
||||||
phases.push(Phase::Upload);
|
phases.push(Phase::Upload);
|
||||||
|
@ -177,17 +177,12 @@ impl RenderPass for MeshPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_commands(&self, data: PhaseData<&FrameData>, cmds: &mut wgpu::CommandEncoder) {
|
fn record_commands(&self, data: PhaseData<&FrameData>, cmds: &mut wgpu::CommandEncoder) {
|
||||||
println!("MeshPass::record_commands(phase: {:?})", data.phase);
|
|
||||||
match data.phase {
|
match data.phase {
|
||||||
Phase::Upload => self.mesh_pool.flush(cmds),
|
Phase::Upload => self.mesh_pool.flush(cmds),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_compute(&self, data: PhaseData<&FrameData>, cmds: &mut wgpu::ComputePass) {
|
|
||||||
println!("MeshPass::record_compute(phase: {:?})", data.phase);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn record_render(&self, data: PhaseData<&FrameData>) -> Option<wgpu::RenderBundle> {
|
fn record_render(&self, data: PhaseData<&FrameData>) -> Option<wgpu::RenderBundle> {
|
||||||
println!("MeshPass::record_render(phase: {:?})", data.phase);
|
println!("MeshPass::record_render(phase: {:?})", data.phase);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue