diff --git a/vulkan-rs/src/commandbuffer.rs b/vulkan-rs/src/commandbuffer.rs index 1582b40..bca7df2 100644 --- a/vulkan-rs/src/commandbuffer.rs +++ b/vulkan-rs/src/commandbuffer.rs @@ -75,6 +75,7 @@ pub struct CommandBuffer { #[derive(Debug)] pub struct CommandBufferRecorder<'a> { device: Arc, + render_target: Option<&'a RenderTarget>, pipeline: Option>, calls: Arc, @@ -117,6 +118,7 @@ impl CommandBuffer { Ok(CommandBufferRecorder { device: self.device.clone(), + render_target: None, pipeline: None, calls: self.calls.clone(), @@ -327,6 +329,14 @@ impl<'a> CommandBufferRecorder<'a> { .cmd_begin_render_pass(self.buffer, &renderpass_begin_info, subpass_contents); } + pub(crate) fn set_render_target(&'a mut self, render_target: &'a RenderTarget) { + self.render_target = Some(render_target); + } + + pub(crate) fn clear_render_target(&'a mut self) { + self.render_target = None; + } + pub fn begin_render_pass_full( &mut self, render_pass: &Arc, @@ -366,11 +376,19 @@ impl<'a> CommandBufferRecorder<'a> { self.handles_lock.push(pipeline.clone()); match pipeline.pipeline_type() { - PipelineType::Graphics => self.device.cmd_bind_pipeline( - self.buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline.vk_handle(), - ), + PipelineType::Graphics => { + if cfg!(debug_assertions) { + if let Some(render_target) = &self.render_target { + assert_eq!(render_target.subpass_index(), pipeline.sub_pass()); + } + } + + self.device.cmd_bind_pipeline( + self.buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline.vk_handle(), + ); + } PipelineType::Compute => self.device.cmd_bind_pipeline( self.buffer, VK_PIPELINE_BIND_POINT_COMPUTE, diff --git a/vulkan-rs/src/pipeline.rs b/vulkan-rs/src/pipeline.rs index 61a19f5..462244f 100644 --- a/vulkan-rs/src/pipeline.rs +++ b/vulkan-rs/src/pipeline.rs @@ -19,6 +19,8 @@ pub struct Pipeline { pipeline_type: PipelineType, pipeline: VkPipeline, + + sub_pass: u32, } impl Pipeline { @@ -33,9 +35,20 @@ impl Pipeline { pipeline_layout, pipeline_type, pipeline, + sub_pass: u32::MAX, } } + pub(crate) fn set_sub_pass(mut self, subpass: u32) -> Self { + self.sub_pass = subpass; + + self + } + + pub(crate) fn sub_pass(&self) -> u32 { + self.sub_pass + } + pub fn new_graphics() -> GraphicsPipelineBuilder { GraphicsPipelineBuilder::default() } diff --git a/vulkan-rs/src/pipelines/graphics_pipeline.rs b/vulkan-rs/src/pipelines/graphics_pipeline.rs index 4c05077..c959589 100644 --- a/vulkan-rs/src/pipelines/graphics_pipeline.rs +++ b/vulkan-rs/src/pipelines/graphics_pipeline.rs @@ -416,12 +416,15 @@ impl GraphicsPipelineBuilder { &[pipeline_ci], )?[0]; - Ok(Arc::new(Pipeline::new( - device, - pipeline_layout.clone(), - PipelineType::Graphics, - pipeline, - ))) + Ok(Arc::new( + Pipeline::new( + device, + pipeline_layout.clone(), + PipelineType::Graphics, + pipeline, + ) + .set_sub_pass(subpass), + )) } } diff --git a/vulkan-rs/src/render_target/mod.rs b/vulkan-rs/src/render_target/mod.rs index e04e0d3..6b60fc7 100644 --- a/vulkan-rs/src/render_target/mod.rs +++ b/vulkan-rs/src/render_target/mod.rs @@ -1,6 +1,9 @@ use crate::prelude::*; use anyhow::Result; -use std::sync::Arc; +use std::sync::{ + atomic::{AtomicU32, AtomicUsize, Ordering::SeqCst}, + Arc, +}; pub mod sub_pass; use sub_pass::{AttachmentInfo, AttachmentInfoUsage, SubPass}; @@ -186,6 +189,9 @@ impl RenderTargetBuilder { extent, sub_passes: self.sub_passes, + + current_subpass: AtomicU32::new(0), + framebuffer_index: AtomicUsize::new(0), }) } @@ -224,6 +230,7 @@ struct SubPassAttachmentReferences { depth_stencil_attachment: Option, } +#[derive(Debug)] pub struct RenderTarget { render_pass: Arc, framebuffers: Vec>, @@ -232,6 +239,9 @@ pub struct RenderTarget { extent: VkExtent2D, sub_passes: Vec, + + current_subpass: AtomicU32, + framebuffer_index: AtomicUsize, } impl RenderTarget { @@ -261,9 +271,22 @@ impl RenderTarget { self.extent.height } - pub fn begin( - &self, - buffer_recorder: &CommandBufferRecorder<'_>, + pub(crate) fn subpass_index(&self) -> u32 { + self.current_subpass.load(SeqCst) + } + + pub fn inheritance_info(&self) -> VkCommandBufferInheritanceInfo { + CommandBuffer::inheritance_info( + Some(&self.render_pass), + Some(self.current_subpass.load(SeqCst)), + Some(self.framebuffer(self.framebuffer_index.load(SeqCst))), + None, + ) + } + + pub fn begin<'a>( + &'a self, + buffer_recorder: &'a mut CommandBufferRecorder<'a>, subpass_content: VkSubpassContents, framebuffer_index: usize, ) { @@ -278,6 +301,10 @@ impl RenderTarget { ); buffer_recorder.begin_render_pass(renderpass_begin, subpass_content); + buffer_recorder.set_render_target(self); + + self.framebuffer_index.store(framebuffer_index, SeqCst); + self.current_subpass.store(0, SeqCst); } pub fn next_subpass( @@ -286,10 +313,12 @@ impl RenderTarget { subpass_content: VkSubpassContents, ) { buffer_recorder.next_subpass(subpass_content); + self.current_subpass.fetch_add(1, SeqCst); } - pub fn end(&self, buffer_recorder: &CommandBufferRecorder<'_>) { + pub fn end<'a>(&self, buffer_recorder: &'a mut CommandBufferRecorder<'a>) { buffer_recorder.end_render_pass(); + buffer_recorder.clear_render_target(); } } diff --git a/vulkan-rs/src/render_target/sub_pass.rs b/vulkan-rs/src/render_target/sub_pass.rs index 1f6b42f..8fc90bb 100644 --- a/vulkan-rs/src/render_target/sub_pass.rs +++ b/vulkan-rs/src/render_target/sub_pass.rs @@ -157,6 +157,7 @@ impl<'a> From<&'a Vec>> for ResolveTarget { } } +#[derive(Debug)] pub struct InputAttachmentInfo { pub sub_pass_index: usize, pub input_indices: Vec, @@ -356,13 +357,14 @@ impl<'a> SubPassBuilder<'a> { } } -#[derive(Eq, PartialEq, Hash, Clone, Copy)] +#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)] pub enum AttachmentInfoUsage { Depth, Resolve, Output, } +#[derive(Debug)] pub struct AttachmentInfo { images: Vec>, pub(crate) clear_value: VkClearValue, @@ -383,6 +385,7 @@ impl AttachmentInfo { } } +#[derive(Debug)] pub struct SubPass { extent: VkExtent2D,