Add more lifetime fixes

This commit is contained in:
hodasemi 2024-03-29 07:01:22 +01:00
parent 5b42c076b3
commit c9b4dfc164
9 changed files with 89 additions and 67 deletions

View file

@ -125,7 +125,7 @@ impl AccelerationStructureBuilder {
pub fn build<'a>(
self,
device: &'a Device,
recorder: &mut CommandBufferRecorder<'_>,
recorder: &mut CommandBufferRecorder<'_, '_>,
) -> Result<AccelerationStructure<'a>> {
let build_flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR
| VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR;
@ -313,7 +313,7 @@ impl<'a> AccelerationStructure<'a> {
)
}
pub fn update(&self, buffer_recorder: &mut CommandBufferRecorder<'_>) -> Result<()> {
pub fn update(&self, buffer_recorder: &mut CommandBufferRecorder<'_, '_>) -> Result<()> {
*self.scratch_buffer.lock().unwrap() = Self::create_scratch_buffer(
&self.device,
self.update_scratch_buffer_size,
@ -332,7 +332,7 @@ impl<'a> AccelerationStructure<'a> {
fn generate(
&self,
buffer_recorder: &mut CommandBufferRecorder<'_>,
buffer_recorder: &mut CommandBufferRecorder<'_, '_>,
src: VkAccelerationStructureKHR,
mode: VkBuildAccelerationStructureModeKHR,
) -> Result<()> {

View file

@ -61,7 +61,7 @@ impl<'a, T: ReprC> BufferBuilder<'a, T> {
}
impl<'a, T: ReprC + Clone + Send + Sync + 'static> BufferBuilder<'a, T> {
pub fn build(self, device: &'a Device) -> Result<Buffer<'a, T>> {
pub fn build<'b>(self, device: &'b Device) -> Result<Buffer<'b, T>> {
let size = match self.data {
Some(data) => data.len() as VkDeviceSize,
None => self.size,
@ -150,9 +150,9 @@ impl<'a, T: ReprC + Clone + Send + Sync + 'static> Buffer<'a, T> {
self.memory.map(self.size)
}
pub fn into_device_local(
pub fn into_device_local<'b>(
&self,
buffer_recorder: &mut CommandBufferRecorder<'_>,
buffer_recorder: &mut CommandBufferRecorder<'a, 'b>,
access_mask: impl Into<VkAccessFlagBits>,
stage: impl Into<VkPipelineStageFlagBits>,
usage: impl Into<VkBufferUsageFlagBits>,

View file

@ -7,7 +7,7 @@ use crate::prelude::*;
use anyhow::Result;
use std::any::Any;
use std::sync::{Mutex, MutexGuard};
use std::sync::Mutex;
pub struct QueryEnable {
pub query_flags: VkQueryControlFlagBits,
@ -53,7 +53,7 @@ impl CommandBufferBuilder {
buffer: command_buffer,
calls: 0,
stored_handles: Mutex::new(Vec::new()),
stored_handles: Vec::new(),
})
}
}
@ -66,18 +66,18 @@ pub struct CommandBuffer<'a> {
buffer: VkCommandBuffer,
calls: usize,
stored_handles: Mutex<Vec<&'a (dyn Any + Send + Sync)>>,
stored_handles: Vec<&'a (dyn Any + Send + Sync)>,
}
#[derive(Debug)]
pub struct CommandBufferRecorder<'a> {
pub struct CommandBufferRecorder<'a, 'b> {
device: &'a Device,
sub_pass: u32,
pipeline: Option<&'a Pipeline<'a>>,
calls: &'a mut usize,
calls: &'b mut usize,
buffer: VkCommandBuffer,
handles_lock: MutexGuard<'a, Vec<&'a (dyn Any + Send + Sync)>>,
handles_lock: &'b mut Vec<&'a (dyn Any + Send + Sync)>,
}
impl_vk_handle!(CommandBuffer<'a>, VkCommandBuffer, buffer);
@ -105,15 +105,17 @@ impl<'a> CommandBuffer<'a> {
self.calls
}
pub fn begin(
&mut self,
pub fn begin<'b>(
&'a mut self,
begin_info: VkCommandBufferBeginInfo,
) -> Result<CommandBufferRecorder<'_>> {
) -> Result<CommandBufferRecorder<'a, 'b>>
where
'b: 'a,
'a: 'b,
{
self.device.begin_command_buffer(self.buffer, &begin_info)?;
let mut handles_lock = self.stored_handles.lock().unwrap();
handles_lock.clear();
self.stored_handles.clear();
self.calls = 0;
Ok(CommandBufferRecorder {
@ -123,7 +125,7 @@ impl<'a> CommandBuffer<'a> {
calls: &mut self.calls,
buffer: self.buffer,
handles_lock,
handles_lock: &mut self.stored_handles,
})
}
@ -186,9 +188,9 @@ impl<'a> CommandBuffer<'a> {
}
}
impl<'a> CommandBufferRecorder<'a> {
impl<'a, 'b> CommandBufferRecorder<'a, 'b> {
pub fn pipeline_barrier(
&self,
&mut self,
src_stage_mask: impl Into<VkPipelineStageFlagBits>,
dst_stage_mask: impl Into<VkPipelineStageFlagBits>,
dependency_flags: impl Into<VkDependencyFlagBits>,
@ -210,7 +212,7 @@ impl<'a> CommandBufferRecorder<'a> {
}
pub fn memory_barrier(
&self,
&mut self,
src_access_mask: impl Into<VkAccessFlagBits>,
src_stage: VkPipelineStageFlags,
dst_access_mask: impl Into<VkAccessFlagBits>,
@ -227,13 +229,15 @@ impl<'a> CommandBufferRecorder<'a> {
}
pub fn buffer_barrier<T: ReprC + Send + Sync + 'static>(
&mut self,
buffer: &Buffer<'a, T>,
&'a mut self,
buffer: &'b Buffer<'a, T>,
src_access_mask: impl Into<VkAccessFlagBits>,
src_stage: impl Into<VkPipelineStageFlagBits>,
dst_access_mask: impl Into<VkAccessFlagBits>,
dst_stage: impl Into<VkPipelineStageFlagBits>,
) {
) where
'b: 'a,
{
self.handles_lock.push(buffer);
self.pipeline_barrier(
@ -916,7 +920,7 @@ impl<'a> CommandBufferRecorder<'a> {
}
}
impl<'a> CommandBufferRecorder<'a> {
impl<'a, 'b> CommandBufferRecorder<'a, 'b> {
pub fn build_acceleration_structure_indirect(
&mut self,
infos: &[VkAccelerationStructureBuildGeometryInfoKHR],
@ -1062,7 +1066,7 @@ impl<'a> Drop for CommandBuffer<'a> {
}
}
impl<'a> Drop for CommandBufferRecorder<'a> {
impl<'a, 'b> Drop for CommandBufferRecorder<'a, 'b> {
fn drop(&mut self) {
self.device.end_command_buffer(self.buffer).unwrap()
}

View file

@ -2,16 +2,16 @@ use crate::prelude::*;
use anyhow::Result;
pub struct FramebufferBuilder<'a> {
render_pass: Option<&'a RenderPass<'a>>,
pub struct FramebufferBuilder<'a, 'b> {
render_pass: Option<&'b RenderPass<'a>>,
attachments: Vec<&'a Image<'a>>,
width: u32,
height: u32,
layers: u32,
}
impl<'a> FramebufferBuilder<'a> {
pub fn set_render_pass(mut self, render_pass: &'a RenderPass<'a>) -> Self {
impl<'a, 'b> FramebufferBuilder<'a, 'b> {
pub fn set_render_pass(mut self, render_pass: &'b RenderPass<'a>) -> Self {
self.render_pass = Some(render_pass);
self
@ -100,7 +100,7 @@ pub struct Framebuffer<'a> {
}
impl<'a> Framebuffer<'a> {
pub fn builder() -> FramebufferBuilder<'a> {
pub fn builder<'b>() -> FramebufferBuilder<'a, 'b> {
FramebufferBuilder {
render_pass: None,
attachments: Vec::new(),

View file

@ -829,10 +829,10 @@ impl<'a> Image<'a> {
.set_size((self.width * self.height * 4) as VkDeviceSize)
.build(self.device.clone())?;
let command_buffer =
let mut command_buffer =
CommandBuffer::new_primary().build(self.device.clone(), self.queue.clone())?;
SingleSubmit::builder(&command_buffer, &self.queue, |recorder| {
SingleSubmit::builder(&mut command_buffer, &self.queue, |recorder| {
// copy info for copying the content of the buffer into the image
let buffer_image_copy = VkBufferImageCopy {
bufferOffset: 0,
@ -1119,7 +1119,7 @@ fn copy_images_to_imagearray<'a>(
}
fn copy_image_to_image<'a>(
buffer_recorder: &mut CommandBufferRecorder<'_>,
buffer_recorder: &mut CommandBufferRecorder<'_, '_>,
src_image: &Image<'a>,
dst_image: &Image<'a>,
mip_level: u32,
@ -1181,7 +1181,7 @@ fn copy_image_to_image<'a>(
}
fn blit_mip_maps<'a>(
buffer_recorder: &mut CommandBufferRecorder<'_>,
buffer_recorder: &mut CommandBufferRecorder<'_, '_>,
image: &Image<'a>,
target_image_layout: VkImageLayout,
) {

View file

@ -192,6 +192,11 @@ impl ShaderBindingTableBuilder {
&shader_handle_storage,
);
let b = sbt_data
.into_iter()
.map(|u| RawBuffer { d: u })
.collect::<Vec<RawBuffer>>();
let sbt_buffer = Buffer::builder()
.set_usage(
VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR
@ -199,13 +204,7 @@ impl ShaderBindingTableBuilder {
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
)
.set_memory_usage(MemoryUsage::CpuToGpu)
.set_data(
sbt_data
.into_iter()
.map(|u| RawBuffer { d: u })
.collect::<Vec<RawBuffer>>()
.as_slice(),
)
.set_data(b.as_slice())
.build(device)?;
Ok(ShaderBindingTable::create(

View file

@ -182,9 +182,9 @@ impl<'a> RenderTargetBuilder<'a> {
})
}
fn create_framebuffers(
render_pass: &RenderPass<'a>,
sub_passes: &[SubPass<'a>],
fn create_framebuffers<'b>(
render_pass: &'b RenderPass<'a>,
sub_passes: &'b [SubPass<'a>],
) -> Result<Vec<Framebuffer<'a>>> {
let extent = sub_passes[0].extent();
@ -202,7 +202,7 @@ impl<'a> RenderTargetBuilder<'a> {
}
}
framebuffer_builder.build(render_pass.device().clone())
framebuffer_builder.build(render_pass.device())
})
.collect()
}
@ -309,7 +309,7 @@ impl<'a> RenderTarget<'a> {
pub fn begin(
&self,
buffer_recorder: &mut CommandBufferRecorder<'_>,
buffer_recorder: &mut CommandBufferRecorder<'_, '_>,
subpass_content: VkSubpassContents,
framebuffer_index: usize,
) {
@ -331,14 +331,14 @@ impl<'a> RenderTarget<'a> {
pub fn next_subpass(
&self,
buffer_recorder: &mut CommandBufferRecorder<'_>,
buffer_recorder: &mut CommandBufferRecorder<'_, '_>,
subpass_content: VkSubpassContents,
) {
buffer_recorder.next_subpass(subpass_content);
self.current_subpass.fetch_add(1, SeqCst);
}
pub fn end(&self, buffer_recorder: &mut CommandBufferRecorder<'_>) {
pub fn end(&self, buffer_recorder: &mut CommandBufferRecorder<'_, '_>) {
debug_assert_eq!(
self.current_subpass.load(SeqCst) as usize,
self.sub_passes.len() - 1
@ -375,15 +375,23 @@ mod test {
.collect::<Result<Vec<Image<'_>>>>()
.unwrap();
let width = target_images[0].width();
let height = target_images[0].height();
RenderTarget::builder()
.add_sub_pass(
SubPass::builder(target_images[0].width(), target_images[0].height())
.set_prepared_targets(target_images, 0, [0.0, 0.0, 0.0, 0.0], false)
SubPass::builder(width, height)
.set_prepared_targets(
target_images.iter().collect(),
0,
[0.0, 0.0, 0.0, 0.0],
false,
)
.build(&device)
.unwrap(),
)
.add_sub_pass(
SubPass::builder(target_images[0].width(), target_images[0].height())
SubPass::builder(width, height)
.add_target_info(CustomTarget {
usage: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT.into(),
format: VK_FORMAT_R8G8B8A8_UNORM,
@ -406,12 +414,17 @@ mod test {
.unwrap(),
)
.add_sub_pass(
SubPass::builder(target_images[0].width(), target_images[0].height())
SubPass::builder(width, height)
.set_input_attachment_info(InputAttachmentInfo {
sub_pass_index: 1,
input_indices: vec![1],
})
.set_prepared_targets(target_images, 0, [0.0, 0.0, 0.0, 0.0], false)
.set_prepared_targets(
target_images.iter().collect(),
0,
[0.0, 0.0, 0.0, 0.0],
false,
)
.build(&device)
.unwrap(),
)

View file

@ -197,7 +197,10 @@ pub struct InputAttachmentInfo {
pub input_indices: Vec<usize>,
}
pub struct SubPassBuilder<'a> {
pub struct SubPassBuilder<'a, 'b>
where
'b: 'a,
{
width: u32,
height: u32,
sample_count: VkSampleCountFlags,
@ -209,13 +212,16 @@ pub struct SubPassBuilder<'a> {
input_info: Option<InputAttachmentInfo>,
// (images, index, clear_color, clear_on_load)
prepared_targets: Option<(Vec<Image<'a>>, usize, [f32; 4], bool)>,
prepared_targets: Option<(Vec<&'b Image<'a>>, usize, [f32; 4], bool)>,
resolve_targets: Vec<ResolveTarget<'a>>,
output_usage: VkAccessFlagBits,
}
impl<'a> SubPassBuilder<'a> {
impl<'a, 'b> SubPassBuilder<'a, 'b>
where
'b: 'a,
{
pub fn set_sample_count(mut self, sample_count: VkSampleCountFlags) -> Self {
self.sample_count = sample_count;
@ -242,7 +248,7 @@ impl<'a> SubPassBuilder<'a> {
pub fn set_prepared_targets(
mut self,
prepared_targets: Vec<Image<'a>>,
prepared_targets: Vec<&'b Image<'a>>,
target_index: usize,
clear_color: impl Into<[f32; 4]>,
clear_on_load: bool,
@ -488,7 +494,7 @@ pub struct SubPass<'a> {
}
impl<'a> SubPass<'a> {
pub fn builder(width: u32, height: u32) -> SubPassBuilder<'a> {
pub fn builder<'b>(width: u32, height: u32) -> SubPassBuilder<'a, 'b> {
SubPassBuilder {
width,
height,

View file

@ -6,9 +6,9 @@ use std::time::Duration;
pub struct SingleSubmit<'a, F, T>
where
F: FnOnce(&mut CommandBufferRecorder<'_>) -> Result<T>,
F: FnOnce(&mut CommandBufferRecorder<'_, '_>) -> Result<T>,
{
command_buffer: &'a CommandBuffer<'a>,
command_buffer: &'a mut CommandBuffer<'a>,
queue: &'a Mutex<Queue<'a>>,
f: F,
@ -17,10 +17,10 @@ where
impl<'a, F, T> SingleSubmit<'a, F, T>
where
F: FnOnce(&mut CommandBufferRecorder<'_>) -> Result<T>,
F: FnOnce(&mut CommandBufferRecorder<'_, '_>) -> Result<T>,
{
pub fn builder(
command_buffer: &'a CommandBuffer<'a>,
command_buffer: &'a mut CommandBuffer<'a>,
queue: &'a Mutex<Queue<'a>>,
f: F,
) -> Self {
@ -39,7 +39,7 @@ where
self
}
pub fn submit(self) -> Result<T> {
pub fn submit(mut self) -> Result<T> {
let result = {
let mut buffer_recorder = self.command_buffer.begin(VkCommandBufferBeginInfo::new(
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
@ -48,12 +48,12 @@ where
(self.f)(&mut buffer_recorder)?
};
let submit = SubmitInfo::default().add_command_buffer(self.command_buffer);
let submit = SubmitInfo::default().add_command_buffer(&*self.command_buffer);
let queue_lock = self.queue.lock().unwrap();
match self.timeout {
Some(timeout) => {
let fence = Fence::builder().build(self.command_buffer.device().clone())?;
let fence = Fence::builder().build(self.command_buffer.device())?;
queue_lock.submit(Some(&fence), &[submit])?;