aboutsummaryrefslogtreecommitdiff
path: root/stockton-skeleton/src/draw_passes
diff options
context:
space:
mode:
authortcmal <me@aria.rip>2024-08-25 17:44:23 +0100
committertcmal <me@aria.rip>2024-08-25 17:44:23 +0100
commit0353181306702c40ad0fe482b5c2b159b46794a4 (patch)
tree33acc6a9e8ea4705884cf93b78cf869008f71832 /stockton-skeleton/src/draw_passes
parent664f0b0777ba96298b29f0c753d52a81cbb233f1 (diff)
refactor(all): rename some crates
Diffstat (limited to 'stockton-skeleton/src/draw_passes')
-rw-r--r--stockton-skeleton/src/draw_passes/cons.rs66
-rw-r--r--stockton-skeleton/src/draw_passes/mod.rs47
-rw-r--r--stockton-skeleton/src/draw_passes/util.rs41
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()
+ }
+}