diff options
author | tcmal <me@aria.rip> | 2024-08-25 17:44:23 +0100 |
---|---|---|
committer | tcmal <me@aria.rip> | 2024-08-25 17:44:23 +0100 |
commit | 0353181306702c40ad0fe482b5c2b159b46794a4 (patch) | |
tree | 33acc6a9e8ea4705884cf93b78cf869008f71832 /stockton-skeleton/src/draw_passes | |
parent | 664f0b0777ba96298b29f0c753d52a81cbb233f1 (diff) |
refactor(all): rename some crates
Diffstat (limited to 'stockton-skeleton/src/draw_passes')
-rw-r--r-- | stockton-skeleton/src/draw_passes/cons.rs | 66 | ||||
-rw-r--r-- | stockton-skeleton/src/draw_passes/mod.rs | 47 | ||||
-rw-r--r-- | stockton-skeleton/src/draw_passes/util.rs | 41 |
3 files changed, 154 insertions, 0 deletions
diff --git a/stockton-skeleton/src/draw_passes/cons.rs b/stockton-skeleton/src/draw_passes/cons.rs new file mode 100644 index 0000000..ad94b1c --- /dev/null +++ b/stockton-skeleton/src/draw_passes/cons.rs @@ -0,0 +1,66 @@ +//! Code for using multiple draw passes in place of just one +//! Note that this can be extended to an arbitrary amount of draw passes. + +use super::{DrawPass, IntoDrawPass}; +use crate::{context::RenderingContext, queue_negotiator::QueueNegotiator, types::*}; +use stockton_types::Session; + +use anyhow::Result; + +/// One draw pass, then another. +pub struct ConsDrawPass<A: DrawPass, B: DrawPass> { + pub a: A, + pub b: B, +} + +impl<A: DrawPass, B: DrawPass> DrawPass for ConsDrawPass<A, B> { + fn queue_draw( + &mut self, + session: &Session, + img_view: &ImageViewT, + cmd_buffer: &mut CommandBufferT, + ) -> Result<()> { + self.a.queue_draw(session, img_view, cmd_buffer)?; + self.b.queue_draw(session, img_view, cmd_buffer)?; + + Ok(()) + } + + fn deactivate(self, context: &mut RenderingContext) -> Result<()> { + self.a.deactivate(context)?; + self.b.deactivate(context) + } + + fn handle_surface_change( + &mut self, + session: &Session, + context: &mut RenderingContext, + ) -> Result<()> { + self.a.handle_surface_change(session, context)?; + self.b.handle_surface_change(session, context) + } +} + +impl<A: DrawPass, B: DrawPass, IA: IntoDrawPass<A>, IB: IntoDrawPass<B>> + IntoDrawPass<ConsDrawPass<A, B>> for (IA, IB) +{ + fn init( + self, + session: &mut Session, + context: &mut RenderingContext, + ) -> Result<ConsDrawPass<A, B>> { + Ok(ConsDrawPass { + a: self.0.init(session, context)?, + b: self.1.init(session, context)?, + }) + } + + fn find_aux_queues<'a>( + adapter: &'a Adapter, + queue_negotiator: &mut QueueNegotiator, + ) -> Result<Vec<(&'a QueueFamilyT, Vec<f32>)>> { + let mut v = IA::find_aux_queues(adapter, queue_negotiator)?; + v.extend(IB::find_aux_queues(adapter, queue_negotiator)?); + Ok(v) + } +} diff --git a/stockton-skeleton/src/draw_passes/mod.rs b/stockton-skeleton/src/draw_passes/mod.rs new file mode 100644 index 0000000..a0dbba5 --- /dev/null +++ b/stockton-skeleton/src/draw_passes/mod.rs @@ -0,0 +1,47 @@ +//! Traits and common draw passes. +use super::{queue_negotiator::QueueNegotiator, RenderingContext}; +use crate::types::*; +use stockton_types::Session; + +use anyhow::Result; + +mod cons; +pub mod util; + +pub use cons::ConsDrawPass; + +/// One of several 'passes' that draw on each frame. +pub trait DrawPass { + /// Queue any necessary draw commands to cmd_buffer + /// This should assume the command buffer isn't in the middle of a renderpass, and should leave it as such. + fn queue_draw( + &mut self, + session: &Session, + img_view: &ImageViewT, + cmd_buffer: &mut CommandBufferT, + ) -> Result<()>; + + /// Called just after the surface changes (probably a resize). + fn handle_surface_change( + &mut self, + session: &Session, + context: &mut RenderingContext, + ) -> Result<()>; + + /// Deactivate any vulkan parts that need to be deactivated + fn deactivate(self, context: &mut RenderingContext) -> Result<()>; +} + +/// A type that can be made into a specific draw pass type. +/// This allows extra data to be used in initialisation without the Renderer needing to worry about it. +pub trait IntoDrawPass<T: DrawPass> { + fn init(self, session: &mut Session, context: &mut RenderingContext) -> Result<T>; + + /// This function should ask the queue negotatior to find families for any auxilary operations this draw pass needs to perform + /// For example, .find(&TexLoadQueue) + /// It should return then call .family_spec for each queue type negotiated and return the results. + fn find_aux_queues<'a>( + adapter: &'a Adapter, + queue_negotiator: &mut QueueNegotiator, + ) -> Result<Vec<(&'a QueueFamilyT, Vec<f32>)>>; +} diff --git a/stockton-skeleton/src/draw_passes/util.rs b/stockton-skeleton/src/draw_passes/util.rs new file mode 100644 index 0000000..7e82209 --- /dev/null +++ b/stockton-skeleton/src/draw_passes/util.rs @@ -0,0 +1,41 @@ +//! Utility structs & functions + +use anyhow::Result; + +/// Keeps a given resource for each swapchain image +pub struct TargetSpecificResources<T> { + elements: Vec<T>, + next_idx: usize, +} + +impl<T> TargetSpecificResources<T> { + /// Create a new set of resources, given a function to generate them and the count + /// In most cases, count should be swapchain_properties.image_count + pub fn new<F>(mut generator: F, count: usize) -> Result<Self> + where + F: FnMut() -> Result<T>, + { + let mut elements = Vec::with_capacity(count); + for _ in 0..count { + elements.push(generator()?); + } + + Ok(TargetSpecificResources { + elements, + next_idx: 0, + }) + } + + /// Get the next resource, wrapping around if necessary. + pub fn get_next(&mut self) -> &T { + let el = &self.elements[self.next_idx]; + self.next_idx = (self.next_idx + 1) % self.elements.len(); + el + } + + /// Dissolve the resource set, returning an iterator over each item. + /// In most cases, each item will need deactivated. + pub fn dissolve(self) -> impl Iterator<Item = T> { + self.elements.into_iter() + } +} |