Second step

This commit is contained in:
hodasemi 2024-03-28 21:30:06 +01:00
parent 39c4fa2342
commit 5b42c076b3
27 changed files with 370 additions and 383 deletions

View file

@ -124,7 +124,7 @@ impl AccelerationStructureBuilder {
pub fn build<'a>( pub fn build<'a>(
self, self,
device: &Device, device: &'a Device,
recorder: &mut CommandBufferRecorder<'_>, recorder: &mut CommandBufferRecorder<'_>,
) -> Result<AccelerationStructure<'a>> { ) -> Result<AccelerationStructure<'a>> {
let build_flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR let build_flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR
@ -390,7 +390,7 @@ impl<'a> AccelerationStructure<'a> {
#[inline] #[inline]
fn create_scratch_buffer( fn create_scratch_buffer(
device: &Device, device: &'a Device,
size: VkDeviceSize, size: VkDeviceSize,
alignment: VkDeviceSize, alignment: VkDeviceSize,
) -> Result<Buffer<'a, RawBuffer>> { ) -> Result<Buffer<'a, RawBuffer>> {
@ -413,7 +413,7 @@ impl<'a> Drop for AccelerationStructure<'a> {
} }
impl_vk_handle!( impl_vk_handle!(
AccelerationStructure, AccelerationStructure<'a>,
VkAccelerationStructureKHR, VkAccelerationStructureKHR,
acceleration_structure acceleration_structure
); );

View file

@ -222,7 +222,7 @@ impl<'a, T: ReprC> VulkanDevice for Buffer<'a, T> {
} }
} }
impl_vk_handle_t!(Buffer[ReprC], VkBuffer, buffer); impl_vk_handle_t!(Buffer[ReprC]<'b>, VkBuffer, buffer);
impl<'a, T: ReprC> VkHandle<VkDeviceMemory> for Buffer<'a, T> { impl<'a, T: ReprC> VkHandle<VkDeviceMemory> for Buffer<'a, T> {
fn vk_handle(&self) -> VkDeviceMemory { fn vk_handle(&self) -> VkDeviceMemory {

View file

@ -7,10 +7,7 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::any::Any; use std::any::Any;
use std::sync::{ use std::sync::{Mutex, MutexGuard};
atomic::{AtomicUsize, Ordering::SeqCst},
Mutex, MutexGuard,
};
pub struct QueryEnable { pub struct QueryEnable {
pub query_flags: VkQueryControlFlagBits, pub query_flags: VkQueryControlFlagBits,
@ -33,7 +30,7 @@ impl CommandBufferBuilder {
self, self,
device: &'a Device, device: &'a Device,
queue: &'a Mutex<Queue<'a>>, queue: &'a Mutex<Queue<'a>>,
) -> Result<Arc<CommandBuffer<'a>>> { ) -> Result<CommandBuffer<'a>> {
let command_pool = self let command_pool = self
.pool_builder .pool_builder
.set_queue_family_index( .set_queue_family_index(
@ -49,15 +46,15 @@ impl CommandBufferBuilder {
let command_buffer = device.allocate_command_buffers(&command_buffer_ci)?[0]; let command_buffer = device.allocate_command_buffers(&command_buffer_ci)?[0];
Ok(Arc::new(CommandBuffer { Ok(CommandBuffer {
device, device,
pool: command_pool, pool: command_pool,
buffer: command_buffer, buffer: command_buffer,
calls: Arc::new(AtomicUsize::new(0)), calls: 0,
stored_handles: Mutex::new(Vec::new()), stored_handles: Mutex::new(Vec::new()),
})) })
} }
} }
@ -68,7 +65,7 @@ pub struct CommandBuffer<'a> {
buffer: VkCommandBuffer, buffer: VkCommandBuffer,
calls: Arc<AtomicUsize>, calls: usize,
stored_handles: Mutex<Vec<&'a (dyn Any + Send + Sync)>>, stored_handles: Mutex<Vec<&'a (dyn Any + Send + Sync)>>,
} }
@ -76,14 +73,14 @@ pub struct CommandBuffer<'a> {
pub struct CommandBufferRecorder<'a> { pub struct CommandBufferRecorder<'a> {
device: &'a Device, device: &'a Device,
sub_pass: u32, sub_pass: u32,
pipeline: Option<Arc<Pipeline>>, pipeline: Option<&'a Pipeline<'a>>,
calls: Arc<AtomicUsize>, calls: &'a mut usize,
buffer: VkCommandBuffer, buffer: VkCommandBuffer,
handles_lock: MutexGuard<'a, Vec<&'a (dyn Any + Send + Sync)>>, handles_lock: MutexGuard<'a, Vec<&'a (dyn Any + Send + Sync)>>,
} }
impl_vk_handle!(CommandBuffer, VkCommandBuffer, buffer); impl_vk_handle!(CommandBuffer<'a>, VkCommandBuffer, buffer);
impl<'a> CommandBuffer<'a> { impl<'a> CommandBuffer<'a> {
pub fn new_primary() -> CommandBufferBuilder { pub fn new_primary() -> CommandBufferBuilder {
@ -105,23 +102,26 @@ impl<'a> CommandBuffer<'a> {
} }
pub fn calls(&self) -> usize { pub fn calls(&self) -> usize {
self.calls.load(SeqCst) self.calls
} }
pub fn begin(&self, begin_info: VkCommandBufferBeginInfo) -> Result<CommandBufferRecorder<'_>> { pub fn begin(
&mut self,
begin_info: VkCommandBufferBeginInfo,
) -> Result<CommandBufferRecorder<'_>> {
self.device.begin_command_buffer(self.buffer, &begin_info)?; self.device.begin_command_buffer(self.buffer, &begin_info)?;
let mut handles_lock = self.stored_handles.lock().unwrap(); let mut handles_lock = self.stored_handles.lock().unwrap();
handles_lock.clear(); handles_lock.clear();
self.calls.store(0, SeqCst); self.calls = 0;
Ok(CommandBufferRecorder { Ok(CommandBufferRecorder {
device: self.device.clone(), device: self.device.clone(),
sub_pass: 0, sub_pass: 0,
pipeline: None, pipeline: None,
calls: self.calls.clone(), calls: &mut self.calls,
buffer: self.buffer, buffer: self.buffer,
handles_lock, handles_lock,
}) })
@ -161,9 +161,9 @@ impl<'a> CommandBuffer<'a> {
} }
pub fn inheritance_info( pub fn inheritance_info(
render_pass: Option<&Arc<RenderPass>>, render_pass: Option<&RenderPass<'a>>,
sub_pass: Option<u32>, sub_pass: Option<u32>,
framebuffer: Option<&Arc<Framebuffer>>, framebuffer: Option<&Framebuffer<'a>>,
query_enable: Option<QueryEnable>, query_enable: Option<QueryEnable>,
) -> VkCommandBufferInheritanceInfo { ) -> VkCommandBufferInheritanceInfo {
let mut info = VkCommandBufferInheritanceInfo::new( let mut info = VkCommandBufferInheritanceInfo::new(
@ -196,7 +196,7 @@ impl<'a> CommandBufferRecorder<'a> {
buffer_memory_barriers: &[VkBufferMemoryBarrier], buffer_memory_barriers: &[VkBufferMemoryBarrier],
image_memory_barriers: &[VkImageMemoryBarrier], image_memory_barriers: &[VkImageMemoryBarrier],
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.device.cmd_pipeline_barrier( self.device.cmd_pipeline_barrier(
self.buffer, self.buffer,
@ -228,13 +228,13 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn buffer_barrier<T: ReprC + Send + Sync + 'static>( pub fn buffer_barrier<T: ReprC + Send + Sync + 'static>(
&mut self, &mut self,
buffer: &Arc<Buffer<T>>, buffer: &Buffer<'a, T>,
src_access_mask: impl Into<VkAccessFlagBits>, src_access_mask: impl Into<VkAccessFlagBits>,
src_stage: impl Into<VkPipelineStageFlagBits>, src_stage: impl Into<VkPipelineStageFlagBits>,
dst_access_mask: impl Into<VkAccessFlagBits>, dst_access_mask: impl Into<VkAccessFlagBits>,
dst_stage: impl Into<VkPipelineStageFlagBits>, dst_stage: impl Into<VkPipelineStageFlagBits>,
) { ) {
self.handles_lock.push(buffer.clone()); self.handles_lock.push(buffer);
self.pipeline_barrier( self.pipeline_barrier(
src_stage, src_stage,
@ -256,7 +256,7 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn image_barrier( pub fn image_barrier(
&mut self, &mut self,
image: &Arc<Image>, image: &Image<'a>,
old_image_layout: VkImageLayout, old_image_layout: VkImageLayout,
src_stage: impl Into<VkPipelineStageFlagBits>, src_stage: impl Into<VkPipelineStageFlagBits>,
new_image_layout: VkImageLayout, new_image_layout: VkImageLayout,
@ -265,7 +265,7 @@ impl<'a> CommandBufferRecorder<'a> {
let src_access_mask = Image::src_layout_to_access(old_image_layout); let src_access_mask = Image::src_layout_to_access(old_image_layout);
let dst_access_mask = Image::dst_layout_to_access(new_image_layout); let dst_access_mask = Image::dst_layout_to_access(new_image_layout);
self.handles_lock.push(image.clone()); self.handles_lock.push(image);
self.pipeline_barrier( self.pipeline_barrier(
src_stage, src_stage,
@ -290,14 +290,14 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn image_barrier_auto_stage( pub fn image_barrier_auto_stage(
&mut self, &mut self,
image: &Arc<Image>, image: &Image<'a>,
old_image_layout: VkImageLayout, old_image_layout: VkImageLayout,
new_image_layout: VkImageLayout, new_image_layout: VkImageLayout,
) { ) {
let src_access_mask = Image::src_layout_to_access(old_image_layout); let src_access_mask = Image::src_layout_to_access(old_image_layout);
let dst_access_mask = Image::dst_layout_to_access(new_image_layout); let dst_access_mask = Image::dst_layout_to_access(new_image_layout);
self.handles_lock.push(image.clone()); self.handles_lock.push(image);
self.pipeline_barrier( self.pipeline_barrier(
CommandBuffer::access_to_stage(src_access_mask), CommandBuffer::access_to_stage(src_access_mask),
@ -333,8 +333,8 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn begin_render_pass_full( pub fn begin_render_pass_full(
&mut self, &mut self,
render_pass: &Arc<RenderPass>, render_pass: &RenderPass<'a>,
framebuffer: &Arc<Framebuffer>, framebuffer: &Framebuffer<'a>,
clear_values: &[VkClearValue], clear_values: &[VkClearValue],
subpass_contents: VkSubpassContents, subpass_contents: VkSubpassContents,
) { ) {
@ -369,8 +369,8 @@ impl<'a> CommandBufferRecorder<'a> {
self.device.cmd_end_render_pass(self.buffer); self.device.cmd_end_render_pass(self.buffer);
} }
pub fn bind_pipeline(&mut self, pipeline: &Arc<Pipeline>) -> Result<()> { pub fn bind_pipeline(&mut self, pipeline: &Pipeline<'a>) -> Result<()> {
self.handles_lock.push(pipeline.clone()); self.handles_lock.push(pipeline);
match pipeline.pipeline_type() { match pipeline.pipeline_type() {
PipelineType::Graphics => { PipelineType::Graphics => {
@ -400,7 +400,7 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn execute_commands(&self, command_buffers: &[&impl VkHandle<VkCommandBuffer>]) { pub fn execute_commands(&self, command_buffers: &[&impl VkHandle<VkCommandBuffer>]) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
let buffers: Vec<VkCommandBuffer> = let buffers: Vec<VkCommandBuffer> =
command_buffers.iter().map(|cb| cb.vk_handle()).collect(); command_buffers.iter().map(|cb| cb.vk_handle()).collect();
@ -409,8 +409,8 @@ impl<'a> CommandBufferRecorder<'a> {
.cmd_execute_commands(self.buffer, buffers.as_slice()); .cmd_execute_commands(self.buffer, buffers.as_slice());
} }
pub fn bind_descriptor_sets_minimal(&mut self, descriptor_sets: &[&Arc<DescriptorSet>]) { pub fn bind_descriptor_sets_minimal(&mut self, descriptor_sets: &[&DescriptorSet<'a>]) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
let (pipeline_bind_point, vk_layout) = { let (pipeline_bind_point, vk_layout) = {
let pipeline = match &self.pipeline { let pipeline = match &self.pipeline {
@ -429,7 +429,7 @@ impl<'a> CommandBufferRecorder<'a> {
let vk_descriptor_sets: Vec<VkDescriptorSet> = descriptor_sets let vk_descriptor_sets: Vec<VkDescriptorSet> = descriptor_sets
.iter() .iter()
.map(|ds: &&Arc<DescriptorSet>| { .map(|ds: &&DescriptorSet<'a>| {
self.handles_lock.push((*ds).clone()); self.handles_lock.push((*ds).clone());
ds.vk_handle() ds.vk_handle()
@ -446,13 +446,10 @@ impl<'a> CommandBufferRecorder<'a> {
); );
} }
pub fn bind_vertex_buffer<T: ReprC + Send + Sync + 'static>( pub fn bind_vertex_buffer<T: ReprC + Send + Sync + 'static>(&mut self, buffer: &Buffer<'a, T>) {
&mut self, *self.calls += 1;
buffer: &Arc<Buffer<T>>,
) {
self.calls.fetch_add(1, SeqCst);
self.handles_lock.push(buffer.clone()); self.handles_lock.push(buffer);
self.device self.device
.cmd_bind_vertex_buffers(self.buffer, 0, &[buffer.vk_handle()], &[0]); .cmd_bind_vertex_buffers(self.buffer, 0, &[buffer.vk_handle()], &[0]);
@ -460,13 +457,13 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn bind_vertex_buffers_minimal<T: ReprC + Send + Sync + 'static>( pub fn bind_vertex_buffers_minimal<T: ReprC + Send + Sync + 'static>(
&mut self, &mut self,
buffers: &[&Arc<Buffer<T>>], buffers: &[&Buffer<'a, T>],
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
let vk_buffers: Vec<VkBuffer> = buffers let vk_buffers: Vec<VkBuffer> = buffers
.iter() .iter()
.map(|b: &&Arc<Buffer<T>>| { .map(|b: &&Buffer<'a, T>| {
self.handles_lock.push((*b).clone()); self.handles_lock.push((*b).clone());
b.vk_handle() b.vk_handle()
@ -485,13 +482,13 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn bind_index_buffer<T: ReprC + Send + Sync + 'static>( pub fn bind_index_buffer<T: ReprC + Send + Sync + 'static>(
&mut self, &mut self,
buffer: &Arc<Buffer<T>>, buffer: &Buffer<'a, T>,
offset: VkDeviceSize, offset: VkDeviceSize,
index_type: VkIndexType, index_type: VkIndexType,
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.handles_lock.push(buffer.clone()); self.handles_lock.push(buffer);
self.device self.device
.cmd_bind_index_buffer(self.buffer, buffer.vk_handle(), offset, index_type); .cmd_bind_index_buffer(self.buffer, buffer.vk_handle(), offset, index_type);
@ -512,7 +509,7 @@ impl<'a> CommandBufferRecorder<'a> {
first_vertex: u32, first_vertex: u32,
first_instance: u32, first_instance: u32,
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.device.cmd_draw( self.device.cmd_draw(
self.buffer, self.buffer,
@ -524,7 +521,7 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn draw_complete_single_instance(&self, vertex_count: u32) { pub fn draw_complete_single_instance(&self, vertex_count: u32) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.device.cmd_draw(self.buffer, vertex_count, 1, 0, 0); self.device.cmd_draw(self.buffer, vertex_count, 1, 0, 0);
} }
@ -537,7 +534,7 @@ impl<'a> CommandBufferRecorder<'a> {
vertex_offset: i32, vertex_offset: i32,
first_instance: u32, first_instance: u32,
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.device.cmd_draw_indexed( self.device.cmd_draw_indexed(
self.buffer, self.buffer,
@ -550,14 +547,14 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn draw_indexed_complete_single_instance(&self, index_count: u32) { pub fn draw_indexed_complete_single_instance(&self, index_count: u32) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.device self.device
.cmd_draw_indexed(self.buffer, index_count, 1, 0, 0, 0); .cmd_draw_indexed(self.buffer, index_count, 1, 0, 0, 0);
} }
pub fn push_constants<U>(&self, stage_flags: impl Into<VkShaderStageFlagBits>, data: &U) { pub fn push_constants<U>(&self, stage_flags: impl Into<VkShaderStageFlagBits>, data: &U) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
let pipeline = match &self.pipeline { let pipeline = match &self.pipeline {
Some(pipeline) => pipeline, Some(pipeline) => pipeline,
@ -602,11 +599,11 @@ impl<'a> CommandBufferRecorder<'a> {
image.set_image_layout(new_image_layout); image.set_image_layout(new_image_layout);
} }
pub fn set_full_image_layout(&mut self, image: &Arc<Image>, new_image_layout: VkImageLayout) { pub fn set_full_image_layout(&mut self, image: &Image<'a>, new_image_layout: VkImageLayout) {
let src_access = Image::src_layout_to_access(image.image_layout()); let src_access = Image::src_layout_to_access(image.image_layout());
let dst_access = Image::dst_layout_to_access(new_image_layout); let dst_access = Image::dst_layout_to_access(new_image_layout);
self.handles_lock.push(image.clone()); self.handles_lock.push(image);
self.pipeline_barrier( self.pipeline_barrier(
CommandBuffer::access_to_stage(src_access), CommandBuffer::access_to_stage(src_access),
@ -667,7 +664,7 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn dispatch(&self, x: u32, y: u32, z: u32) { pub fn dispatch(&self, x: u32, y: u32, z: u32) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.device.cmd_dispatch(self.buffer, x, y, z); self.device.cmd_dispatch(self.buffer, x, y, z);
} }
@ -678,14 +675,14 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn copy_buffer<T: ReprC + Send + Sync + 'static, U: ReprC + Send + Sync + 'static>( pub fn copy_buffer<T: ReprC + Send + Sync + 'static, U: ReprC + Send + Sync + 'static>(
&mut self, &mut self,
src_buffer: &Arc<Buffer<T>>, src_buffer: &Buffer<'a, T>,
dst_buffer: &Arc<Buffer<U>>, dst_buffer: &Buffer<'a, U>,
regions: &[VkBufferCopy], regions: &[VkBufferCopy],
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.handles_lock.push(src_buffer.clone()); self.handles_lock.push(src_buffer);
self.handles_lock.push(dst_buffer.clone()); self.handles_lock.push(dst_buffer);
self.device.cmd_copy_buffer( self.device.cmd_copy_buffer(
self.buffer, self.buffer,
@ -697,16 +694,16 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn copy_image( pub fn copy_image(
&mut self, &mut self,
src_image: &Arc<Image>, src_image: &Image<'a>,
dst_image: &Arc<Image>, dst_image: &Image<'a>,
src_layout: VkImageLayout, src_layout: VkImageLayout,
dst_layout: VkImageLayout, dst_layout: VkImageLayout,
regions: &[VkImageCopy], regions: &[VkImageCopy],
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.handles_lock.push(src_image.clone()); self.handles_lock.push(src_image);
self.handles_lock.push(dst_image.clone()); self.handles_lock.push(dst_image);
self.device.cmd_copy_image( self.device.cmd_copy_image(
self.buffer, self.buffer,
@ -720,12 +717,12 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn blit_complete( pub fn blit_complete(
&mut self, &mut self,
src_image: &Arc<Image>, src_image: &Image<'a>,
dst_image: &Arc<Image>, dst_image: &Image<'a>,
filter: VkFilter, filter: VkFilter,
) { ) {
self.handles_lock.push(src_image.clone()); self.handles_lock.push(src_image);
self.handles_lock.push(dst_image.clone()); self.handles_lock.push(dst_image);
let image_blit = VkImageBlit { let image_blit = VkImageBlit {
srcSubresource: src_image.full_resource_layers(), srcSubresource: src_image.full_resource_layers(),
@ -767,7 +764,7 @@ impl<'a> CommandBufferRecorder<'a> {
regions: &[VkImageBlit], regions: &[VkImageBlit],
filter: VkFilter, filter: VkFilter,
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.handles_lock.push(src_image); self.handles_lock.push(src_image);
self.handles_lock.push(dst_image); self.handles_lock.push(dst_image);
@ -785,14 +782,14 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn copy_buffer_to_image<T: ReprC + Send + Sync + 'static>( pub fn copy_buffer_to_image<T: ReprC + Send + Sync + 'static>(
&mut self, &mut self,
src_buffer: &Arc<Buffer<'a, T>>, src_buffer: &Buffer<'a, T>,
dst_image: &Image<'a>, dst_image: &Image<'a>,
image_layout: VkImageLayout, image_layout: VkImageLayout,
regions: &[VkBufferImageCopy], regions: &[VkBufferImageCopy],
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.handles_lock.push(src_buffer.clone()); self.handles_lock.push(src_buffer);
self.handles_lock.push(dst_image); self.handles_lock.push(dst_image);
self.device.cmd_copy_buffer_to_image( self.device.cmd_copy_buffer_to_image(
@ -806,15 +803,15 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn copy_image_to_buffer<T: ReprC + Send + Sync + 'static>( pub fn copy_image_to_buffer<T: ReprC + Send + Sync + 'static>(
&mut self, &mut self,
src_image: &Arc<Image>, src_image: &Image<'a>,
image_layout: VkImageLayout, image_layout: VkImageLayout,
dst_buffer: &Arc<Buffer<T>>, dst_buffer: &Buffer<'a, T>,
regions: &[VkBufferImageCopy], regions: &[VkBufferImageCopy],
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.handles_lock.push(src_image.clone()); self.handles_lock.push(src_image);
self.handles_lock.push(dst_buffer.clone()); self.handles_lock.push(dst_buffer);
self.device.cmd_copy_image_to_buffer( self.device.cmd_copy_image_to_buffer(
self.buffer, self.buffer,
@ -833,10 +830,10 @@ impl<'a> CommandBufferRecorder<'a> {
unimplemented!(); unimplemented!();
} }
pub fn clear_color_image(&mut self, image: &Arc<Image>, clear_color: VkClearColorValue) { pub fn clear_color_image(&mut self, image: &Image<'a>, clear_color: VkClearColorValue) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.handles_lock.push(image.clone()); self.handles_lock.push(image);
self.device.cmd_clear_color_image( self.device.cmd_clear_color_image(
self.buffer, self.buffer,
@ -857,14 +854,14 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn resolve_image( pub fn resolve_image(
&mut self, &mut self,
src_image: &Arc<Image>, src_image: &Image<'a>,
dst_image: &Arc<Image>, dst_image: &Image<'a>,
regions: &[VkImageResolve], regions: &[VkImageResolve],
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.handles_lock.push(src_image.clone()); self.handles_lock.push(src_image);
self.handles_lock.push(dst_image.clone()); self.handles_lock.push(dst_image);
self.device.cmd_resolve_image( self.device.cmd_resolve_image(
self.buffer, self.buffer,
@ -902,13 +899,13 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn write_timestamp( pub fn write_timestamp(
&mut self, &mut self,
query_pool: &Arc<QueryPool>, query_pool: &QueryPool,
query: u32, query: u32,
pipeline_stage: impl Into<VkPipelineStageFlagBits>, pipeline_stage: impl Into<VkPipelineStageFlagBits>,
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.handles_lock.push(query_pool.clone()); self.handles_lock.push(query_pool);
self.device self.device
.cmd_write_timestamp(self.buffer, pipeline_stage, query_pool.vk_handle(), query); .cmd_write_timestamp(self.buffer, pipeline_stage, query_pool.vk_handle(), query);
@ -923,14 +920,14 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn build_acceleration_structure_indirect( pub fn build_acceleration_structure_indirect(
&mut self, &mut self,
infos: &[VkAccelerationStructureBuildGeometryInfoKHR], infos: &[VkAccelerationStructureBuildGeometryInfoKHR],
indirect_buffers: &[Arc<Buffer<impl ReprC + Send + Sync + 'static>>], indirect_buffers: &[Buffer<'a, impl ReprC + Send + Sync + 'static>],
indirect_strides: &[u32], indirect_strides: &[u32],
max_primitive_counts: &[&u32], max_primitive_counts: &[&u32],
) { ) {
let mut device_addresses: Vec<VkDeviceAddress> = Vec::with_capacity(indirect_buffers.len()); let mut device_addresses: Vec<VkDeviceAddress> = Vec::with_capacity(indirect_buffers.len());
for indirect_buffer in indirect_buffers.iter() { for indirect_buffer in indirect_buffers.iter() {
self.handles_lock.push(indirect_buffer.clone()); self.handles_lock.push(indirect_buffer);
device_addresses.push(indirect_buffer.device_address().into()); device_addresses.push(indirect_buffer.device_address().into());
} }
@ -954,12 +951,12 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn copy_acceleration_structure( pub fn copy_acceleration_structure(
&mut self, &mut self,
src: &Arc<AccelerationStructure>, src: &AccelerationStructure<'a>,
dst: &Arc<AccelerationStructure>, dst: &AccelerationStructure<'a>,
mode: VkCopyAccelerationStructureModeKHR, mode: VkCopyAccelerationStructureModeKHR,
) { ) {
self.handles_lock.push(src.clone()); self.handles_lock.push(src);
self.handles_lock.push(dst.clone()); self.handles_lock.push(dst);
let info = VkCopyAccelerationStructureInfoKHR::new(src.vk_handle(), dst.vk_handle(), mode); let info = VkCopyAccelerationStructureInfoKHR::new(src.vk_handle(), dst.vk_handle(), mode);
@ -969,11 +966,11 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn copy_acceleration_structure_to_memory( pub fn copy_acceleration_structure_to_memory(
&mut self, &mut self,
src: &Arc<AccelerationStructure>, src: &AccelerationStructure<'a>,
dst: VkDeviceOrHostAddressKHR, dst: VkDeviceOrHostAddressKHR,
mode: VkCopyAccelerationStructureModeKHR, mode: VkCopyAccelerationStructureModeKHR,
) { ) {
self.handles_lock.push(src.clone()); self.handles_lock.push(src);
let info = VkCopyAccelerationStructureToMemoryInfoKHR::new(src.vk_handle(), dst, mode); let info = VkCopyAccelerationStructureToMemoryInfoKHR::new(src.vk_handle(), dst, mode);
@ -984,10 +981,10 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn copy_memory_to_acceleration_structure( pub fn copy_memory_to_acceleration_structure(
&mut self, &mut self,
src: VkDeviceOrHostAddressConstKHR, src: VkDeviceOrHostAddressConstKHR,
dst: &Arc<AccelerationStructure>, dst: &AccelerationStructure<'a>,
mode: VkCopyAccelerationStructureModeKHR, mode: VkCopyAccelerationStructureModeKHR,
) { ) {
self.handles_lock.push(dst.clone()); self.handles_lock.push(dst);
let info = VkCopyMemoryToAccelerationStructureInfoKHR::new(src, dst.vk_handle(), mode); let info = VkCopyMemoryToAccelerationStructureInfoKHR::new(src, dst.vk_handle(), mode);
@ -997,10 +994,10 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn trace_rays_indirect( pub fn trace_rays_indirect(
&mut self, &mut self,
sbt: ShaderBindingTable, sbt: ShaderBindingTable<'a>,
buffer: Arc<Buffer<impl ReprC + Send + Sync + 'static>>, buffer: Buffer<'a, impl ReprC + Send + Sync + 'static>,
) { ) {
self.handles_lock.push(buffer.clone()); self.handles_lock.push(&buffer);
self.device.cmd_trace_rays_indirect( self.device.cmd_trace_rays_indirect(
self.buffer, self.buffer,
@ -1012,7 +1009,7 @@ impl<'a> CommandBufferRecorder<'a> {
) )
} }
pub fn trace_rays(&self, sbt: &ShaderBindingTable, width: u32, height: u32, depth: u32) { pub fn trace_rays(&self, sbt: &ShaderBindingTable<'a>, width: u32, height: u32, depth: u32) {
self.device.cmd_trace_rays( self.device.cmd_trace_rays(
self.buffer, self.buffer,
sbt.raygen_shader_binding_table(), sbt.raygen_shader_binding_table(),
@ -1027,12 +1024,12 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn write_acceleration_structure_properties( pub fn write_acceleration_structure_properties(
&mut self, &mut self,
acceleration_structures: &[&Arc<AccelerationStructure>], acceleration_structures: &[&AccelerationStructure<'a>],
query_type: VkQueryType, query_type: VkQueryType,
query_pool: &Arc<QueryPool>, query_pool: &QueryPool,
first_query: u32, first_query: u32,
) { ) {
self.handles_lock.push(query_pool.clone()); self.handles_lock.push(query_pool);
let as_handles: Vec<VkAccelerationStructureKHR> = acceleration_structures let as_handles: Vec<VkAccelerationStructureKHR> = acceleration_structures
.iter() .iter()
@ -1052,13 +1049,13 @@ impl<'a> CommandBufferRecorder<'a> {
} }
} }
impl VulkanDevice for CommandBuffer { impl<'a> VulkanDevice for CommandBuffer<'a> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl Drop for CommandBuffer { impl<'a> Drop for CommandBuffer<'a> {
fn drop(&mut self) { fn drop(&mut self) {
self.device self.device
.free_command_buffers(self.pool.vk_handle(), &[self.buffer]); .free_command_buffers(self.pool.vk_handle(), &[self.buffer]);
@ -1070,35 +1067,3 @@ impl<'a> Drop for CommandBufferRecorder<'a> {
self.device.end_command_buffer(self.buffer).unwrap() self.device.end_command_buffer(self.buffer).unwrap()
} }
} }
// ==========================================================================================
// ======================================== FFI =============================================
// ==========================================================================================
// use crate::{ffi::*, handle_ffi_result};
// #[no_mangle]
// pub extern "C" fn allocate_primary_buffer(
// flags: VkCommandPoolCreateFlagBits,
// device: *const Device,
// queue: *const Queue,
// ) -> *const CommandBuffer {
// handle_ffi_result!(CommandBuffer::new_primary()
// .set_flags(flags)
// .build(unsafe { Arc::from_raw(device) }, unsafe {
// Arc::from_raw(queue)
// }))
// }
// #[no_mangle]
// pub extern "C" fn allocate_secondary_buffer(
// flags: VkCommandPoolCreateFlagBits,
// device: *const Device,
// queue: *const Queue,
// ) -> *const CommandBuffer {
// handle_ffi_result!(CommandBuffer::new_secondary()
// .set_flags(flags)
// .build(unsafe { Arc::from_raw(device) }, unsafe {
// Arc::from_raw(queue)
// }))
// }

View file

@ -2,8 +2,6 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::Arc;
pub(crate) struct CommandPoolBuilder { pub(crate) struct CommandPoolBuilder {
flags: VkCommandPoolCreateFlagBits, flags: VkCommandPoolCreateFlagBits,
queue_family_index: u32, queue_family_index: u32,
@ -22,15 +20,15 @@ impl CommandPoolBuilder {
self self
} }
pub(crate) fn build<'a>(self, device: &'a Device) -> Result<Arc<CommandPool<'a>>> { pub(crate) fn build<'a>(self, device: &'a Device) -> Result<CommandPool<'a>> {
let command_pool_ci = VkCommandPoolCreateInfo::new(self.flags, self.queue_family_index); let command_pool_ci = VkCommandPoolCreateInfo::new(self.flags, self.queue_family_index);
let command_pool = device.create_command_pool(&command_pool_ci)?; let command_pool = device.create_command_pool(&command_pool_ci)?;
Ok(Arc::new(CommandPool { Ok(CommandPool {
device, device,
command_pool, command_pool,
})) })
} }
} }
@ -56,7 +54,7 @@ impl<'a> VulkanDevice for CommandPool<'a> {
} }
} }
impl_vk_handle!(CommandPool, VkCommandPool, command_pool); impl_vk_handle!(CommandPool<'a>, VkCommandPool, command_pool);
impl<'a> Drop for CommandPool<'a> { impl<'a> Drop for CommandPool<'a> {
fn drop(&mut self) { fn drop(&mut self) {

View file

@ -98,7 +98,7 @@ impl<'a> VulkanDevice for DescriptorPool<'a> {
} }
} }
impl_vk_handle!(DescriptorPool, VkDescriptorPool, descriptor_pool); impl_vk_handle!(DescriptorPool<'a>, VkDescriptorPool, descriptor_pool);
impl<'a> VkHandle<VkDescriptorSetLayout> for DescriptorPool<'a> { impl<'a> VkHandle<VkDescriptorSetLayout> for DescriptorPool<'a> {
fn vk_handle(&self) -> VkDescriptorSetLayout { fn vk_handle(&self) -> VkDescriptorSetLayout {

View file

@ -313,7 +313,7 @@ impl<'a> VulkanDevice for DescriptorSet<'a> {
} }
} }
impl_vk_handle!(DescriptorSet, VkDescriptorSet, descriptor_set); impl_vk_handle!(DescriptorSet<'a>, VkDescriptorSet, descriptor_set);
impl<'a> VkHandle<VkDescriptorSetLayout> for DescriptorSet<'a> { impl<'a> VkHandle<VkDescriptorSetLayout> for DescriptorSet<'a> {
fn vk_handle(&self) -> VkDescriptorSetLayout { fn vk_handle(&self) -> VkDescriptorSetLayout {

View file

@ -131,7 +131,7 @@ impl<'a> VulkanDevice for DescriptorSetLayout<'a> {
} }
impl_vk_handle!( impl_vk_handle!(
DescriptorSetLayout, DescriptorSetLayout<'a>,
VkDescriptorSetLayout, VkDescriptorSetLayout,
descriptor_set_layout descriptor_set_layout
); );

View file

@ -875,7 +875,7 @@ impl Device {
pub(crate) fn create_sampler_from_manager( pub(crate) fn create_sampler_from_manager(
&self, &self,
create_info: VkSamplerCreateInfo, create_info: VkSamplerCreateInfo,
) -> Result<Sampler> { ) -> Result<Arc<Sampler>> {
self.sampler_manager self.sampler_manager
.lock() .lock()
.unwrap() .unwrap()

View file

@ -56,7 +56,7 @@ impl<'a> VulkanDevice for Fence<'a> {
} }
} }
impl_vk_handle!(Fence, VkFence, fence); impl_vk_handle!(Fence<'a>, VkFence, fence);
impl<'a> Drop for Fence<'a> { impl<'a> Drop for Fence<'a> {
fn drop(&mut self) { fn drop(&mut self) {

View file

@ -2,10 +2,8 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::Arc;
pub struct FramebufferBuilder<'a> { pub struct FramebufferBuilder<'a> {
render_pass: Option<&'a Arc<RenderPass>>, render_pass: Option<&'a RenderPass<'a>>,
attachments: Vec<&'a Image<'a>>, attachments: Vec<&'a Image<'a>>,
width: u32, width: u32,
height: u32, height: u32,
@ -13,7 +11,7 @@ pub struct FramebufferBuilder<'a> {
} }
impl<'a> FramebufferBuilder<'a> { impl<'a> FramebufferBuilder<'a> {
pub fn set_render_pass(mut self, render_pass: &'a Arc<RenderPass>) -> Self { pub fn set_render_pass(mut self, render_pass: &'a RenderPass<'a>) -> Self {
self.render_pass = Some(render_pass); self.render_pass = Some(render_pass);
self self
@ -43,7 +41,7 @@ impl<'a> FramebufferBuilder<'a> {
self self
} }
pub fn build(mut self, device: Arc<Device>) -> Result<Framebuffer<'a>> { pub fn build(mut self, device: &'a Device) -> Result<Framebuffer<'a>> {
if self.attachments.is_empty() { if self.attachments.is_empty() {
panic!("no attachments added!"); panic!("no attachments added!");
} }
@ -93,7 +91,7 @@ impl<'a> FramebufferBuilder<'a> {
#[derive(Debug)] #[derive(Debug)]
pub struct Framebuffer<'a> { pub struct Framebuffer<'a> {
device: Arc<Device>, device: &'a Device,
framebuffer: VkFramebuffer, framebuffer: VkFramebuffer,
images: Vec<&'a Image<'a>>, images: Vec<&'a Image<'a>>,
@ -139,7 +137,7 @@ impl<'a> VulkanDevice for Framebuffer<'a> {
} }
} }
impl_vk_handle!(Framebuffer, VkFramebuffer, framebuffer); impl_vk_handle!(Framebuffer<'a>, VkFramebuffer, framebuffer);
impl<'a> Drop for Framebuffer<'a> { impl<'a> Drop for Framebuffer<'a> {
fn drop(&mut self) { fn drop(&mut self) {

View file

@ -75,7 +75,7 @@ pub struct ImageBuilder<'a> {
view_type: VkImageViewType, view_type: VkImageViewType,
subresource_range: VkImageSubresourceRange, subresource_range: VkImageSubresourceRange,
sampler: Option<Sampler>, sampler: Option<Arc<Sampler>>,
} }
impl<'a> ImageBuilder<'a> { impl<'a> ImageBuilder<'a> {
@ -308,7 +308,7 @@ impl<'a> ImageBuilder<'a> {
self self
} }
pub fn attach_sampler(mut self, sampler: Sampler) -> Self { pub fn attach_sampler(mut self, sampler: Arc<Sampler>) -> Self {
self.sampler = Some(sampler); self.sampler = Some(sampler);
if let ImageBuilderInternalType::NewImage(ref mut info) = self.builder_type { if let ImageBuilderInternalType::NewImage(ref mut info) = self.builder_type {
@ -384,10 +384,10 @@ impl<'a> ImageBuilder<'a> {
} }
fn create_from_source( fn create_from_source(
device: &Device, device: &'a Device,
queue: &Mutex<Queue<'a>>, queue: &Mutex<Queue<'a>>,
info: &ImageCreateInfo<'a>, info: &ImageCreateInfo<'a>,
sampler: Option<Sampler>, sampler: Option<Arc<Sampler>>,
mut view_ci: VkImageViewCreateInfo, mut view_ci: VkImageViewCreateInfo,
file_name: Option<AssetPath>, file_name: Option<AssetPath>,
) -> Result<Image<'a>> { ) -> Result<Image<'a>> {
@ -426,7 +426,7 @@ impl<'a> ImageBuilder<'a> {
} }
fn create_texture( fn create_texture(
device: &Device, device: &'a Device,
image_ci: &VkImageCreateInfo, image_ci: &VkImageCreateInfo,
) -> Result<(VkImage, Memory<'a, RawBuffer>)> { ) -> Result<(VkImage, Memory<'a, RawBuffer>)> {
let image = Self::create_image(device, image_ci)?; let image = Self::create_image(device, image_ci)?;
@ -439,7 +439,7 @@ impl<'a> ImageBuilder<'a> {
Ok((image, memory)) Ok((image, memory))
} }
fn create_image(device: &Device, image_ci: &VkImageCreateInfo) -> Result<VkImage> { fn create_image(device: &'a Device, image_ci: &VkImageCreateInfo) -> Result<VkImage> {
debug_assert_ne!(image_ci.extent.width, 0); debug_assert_ne!(image_ci.extent.width, 0);
debug_assert_ne!(image_ci.extent.height, 0); debug_assert_ne!(image_ci.extent.height, 0);
@ -447,7 +447,7 @@ impl<'a> ImageBuilder<'a> {
} }
fn optimize_fill( fn optimize_fill(
device: &Device, device: &'a Device,
queue: &Mutex<Queue<'a>>, queue: &Mutex<Queue<'a>>,
data: &[RawBuffer], data: &[RawBuffer],
image: &Image<'a>, image: &Image<'a>,
@ -487,7 +487,7 @@ pub struct Image<'a> {
// optional handles // optional handles
_memory: Option<Memory<'a, RawBuffer>>, _memory: Option<Memory<'a, RawBuffer>>,
sampler: Option<Sampler>, sampler: Option<Arc<Sampler>>,
// image information // image information
format: VkFormat, format: VkFormat,
@ -664,7 +664,7 @@ impl<'a> Image<'a> {
} }
pub fn check_configuration( pub fn check_configuration(
device: &Device, device: &'a Device,
tiling: VkImageTiling, tiling: VkImageTiling,
format: VkFormat, format: VkFormat,
usage: impl Into<VkImageUsageFlagBits>, usage: impl Into<VkImageUsageFlagBits>,
@ -697,7 +697,7 @@ impl<'a> Image<'a> {
self.format self.format
} }
pub fn sampler(&self) -> &Option<Sampler> { pub fn sampler(&self) -> &Option<Arc<Sampler>> {
&self.sampler &self.sampler
} }
@ -896,8 +896,8 @@ impl<'a> VulkanDevice for Image<'a> {
} }
} }
impl_vk_handle!(Image, VkImage, image); impl_vk_handle!(Image<'a>, VkImage, image);
impl_vk_handle!(Image, VkImageView, image_view); impl_vk_handle!(Image<'a>, VkImageView, image_view);
impl<'a> Drop for Image<'a> { impl<'a> Drop for Image<'a> {
fn drop(&mut self) { fn drop(&mut self) {
@ -911,7 +911,7 @@ impl<'a> Drop for Image<'a> {
fn into_layout<'a>(image: &Image<'a>, layout: VkImageLayout) -> Result<()> { fn into_layout<'a>(image: &Image<'a>, layout: VkImageLayout) -> Result<()> {
// create a new command buffer // create a new command buffer
let command_buffer = CommandBuffer::new_primary().build(image.device, image.queue)?; let mut command_buffer = CommandBuffer::new_primary().build(image.device, image.queue)?;
{ {
// begin recording into this command buffer // begin recording into this command buffer
@ -951,7 +951,7 @@ fn into_layout<'a>(image: &Image<'a>, layout: VkImageLayout) -> Result<()> {
fn copy_buffer_to_image<'a, T: ReprC + Send + Sync + 'static>( fn copy_buffer_to_image<'a, T: ReprC + Send + Sync + 'static>(
image: &Image<'a>, image: &Image<'a>,
device: &Device, device: &'a Device,
queue: &Mutex<Queue<'a>>, queue: &Mutex<Queue<'a>>,
buffer: &Buffer<'a, T>, buffer: &Buffer<'a, T>,
) -> Result<()> ) -> Result<()>
@ -959,7 +959,7 @@ where
T: Copy, T: Copy,
{ {
// create a new command buffer // create a new command buffer
let command_buffer = CommandBuffer::new_primary().build(device.clone(), queue.clone())?; let mut command_buffer = CommandBuffer::new_primary().build(device.clone(), queue.clone())?;
{ {
// begin recording into this command buffer // begin recording into this command buffer
@ -1045,13 +1045,13 @@ where
} }
fn copy_images_to_imagearray<'a>( fn copy_images_to_imagearray<'a>(
device: &Device, device: &'a Device,
queue: &Mutex<Queue<'a>>, queue: &Mutex<Queue<'a>>,
image_array: &Image<'a>, image_array: &Image<'a>,
images: &[Image<'a>], images: &[Image<'a>],
) -> Result<()> { ) -> Result<()> {
// create a new command buffer // create a new command buffer
let command_buffer = CommandBuffer::new_primary().build(device.clone(), queue.clone())?; let mut command_buffer = CommandBuffer::new_primary().build(device, queue)?;
{ {
// set command buffer buffer in recording state // set command buffer buffer in recording state

View file

@ -1,25 +1,25 @@
macro_rules! impl_vk_handle { macro_rules! impl_vk_handle {
($struct_name:ident $(<$( $lt:lifetime $(,)? )* $( $const:ident $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => { ($struct_name:ident $(<$( $lt:lifetime $(,)? )* $( $const:ident $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => {
impl$(<$( $const $name: $type, )*>)? VkHandle<$target_name> for $struct_name$(<$($lt, )* $($name,)?>)? { impl$(<$( $lt, )* $( $const $name: $type, )*>)? VkHandle<$target_name> for $struct_name$(<$($lt, )* $($name,)*>)? {
fn vk_handle(&self) -> $target_name { fn vk_handle(&self) -> $target_name {
self.$value self.$value
} }
} }
impl<'x $($(, $const $name: $type)*)?> VkHandle<$target_name> for &'x $struct_name$(<$($lt, )* $($name,)?>)? { impl<'x $($(, $lt )* $(, $const $name: $type)*)?> VkHandle<$target_name> for &'x $struct_name$(<$($lt, )* $($name,)*>)? {
fn vk_handle(&self) -> $target_name { fn vk_handle(&self) -> $target_name {
self.$value self.$value
} }
} }
}; };
($struct_name:ident $(<$( $lt:lifetime $(,)? )* $( $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => { ($struct_name:ident $(<$( $lt:lifetime $(,)? )* $( $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => {
impl$(<$( $lt, )* $( $name: $type, )*>)? VkHandle<$target_name> for $struct_name$(<$($lt, )* $($name,)?>)? { impl$(<$( $lt, )* $( $name: $type, )*>)? VkHandle<$target_name> for $struct_name$(<$($lt, )* $($name,)*>)? {
fn vk_handle(&self) -> $target_name { fn vk_handle(&self) -> $target_name {
self.$value self.$value
} }
} }
impl<'x $($(, $lt, )* $(, $name: $type)*)?> VkHandle<$target_name> for &'x $struct_name$(<$($lt, )* $($name,)?>)? { impl<'x $($(, $lt, )* $(, $name: $type)*)?> VkHandle<$target_name> for &'x $struct_name$(<$($lt, )* $($name,)*>)? {
fn vk_handle(&self) -> $target_name { fn vk_handle(&self) -> $target_name {
self.$value self.$value
} }
@ -28,14 +28,14 @@ macro_rules! impl_vk_handle {
} }
macro_rules! impl_vk_handle_t { macro_rules! impl_vk_handle_t {
($struct_name:ident $([$($t:ident $(,)? )* ])?, $target_name:ident, $value:ident) => { ($struct_name:ident $([$($t:ident $(,)? )* ])? $(<$( $lt:lifetime $(,)? )* $( $const:ident $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => {
impl<T $(: $($t,)* )?> VkHandle<$target_name> for $struct_name<T> { impl<$( $( $lt, )* $( $name: $type, )* )? T $(: $($t,)* )?> VkHandle<$target_name> for $struct_name<$( $($lt, )* $($name,)* )? T> {
fn vk_handle(&self) -> $target_name { fn vk_handle(&self) -> $target_name {
self.$value self.$value
} }
} }
impl<'a, T $(: $($t,)* )?> VkHandle<$target_name> for &'a $struct_name<T> { impl<'a, $( $( $lt, )* $( $name: $type, )* )? T $(: $($t,)* )?> VkHandle<$target_name> for &'a $struct_name<$( $($lt, )* $($name,)* )? T> {
fn vk_handle(&self) -> $target_name { fn vk_handle(&self) -> $target_name {
self.$value self.$value
} }

View file

@ -76,7 +76,7 @@ impl<'a, T: ReprC> Memory<'a, T> {
} }
pub(crate) fn image_memory( pub(crate) fn image_memory(
device: &Device, device: &'a Device,
image: VkImage, image: VkImage,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
) -> Result<Memory<'a, T>> { ) -> Result<Memory<'a, T>> {
@ -92,7 +92,7 @@ impl<'a, T: ReprC> Memory<'a, T> {
trait MemoryBinder<'a, T, K: ReprC> { trait MemoryBinder<'a, T, K: ReprC> {
fn create_and_bind( fn create_and_bind(
device: &Device, device: &'a Device,
memory_requirements: VkMemoryRequirements, memory_requirements: VkMemoryRequirements,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
argument: T, argument: T,
@ -101,7 +101,7 @@ trait MemoryBinder<'a, T, K: ReprC> {
impl<'a, K: ReprC> MemoryBinder<'a, (), K> for Memory<'a, K> { impl<'a, K: ReprC> MemoryBinder<'a, (), K> for Memory<'a, K> {
fn create_and_bind( fn create_and_bind(
device: &Device, device: &'a Device,
memory_requirements: VkMemoryRequirements, memory_requirements: VkMemoryRequirements,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
_: (), _: (),
@ -125,7 +125,7 @@ impl<'a, K: ReprC> MemoryBinder<'a, (), K> for Memory<'a, K> {
impl<'a, K: ReprC> MemoryBinder<'a, VkImage, K> for Memory<'a, K> { impl<'a, K: ReprC> MemoryBinder<'a, VkImage, K> for Memory<'a, K> {
fn create_and_bind( fn create_and_bind(
device: &Device, device: &'a Device,
memory_requirements: VkMemoryRequirements, memory_requirements: VkMemoryRequirements,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
image: VkImage, image: VkImage,
@ -149,7 +149,7 @@ impl<'a, K: ReprC> MemoryBinder<'a, VkImage, K> for Memory<'a, K> {
impl<'a, K: ReprC> MemoryBinder<'a, VkBuffer, K> for Memory<'a, K> { impl<'a, K: ReprC> MemoryBinder<'a, VkBuffer, K> for Memory<'a, K> {
fn create_and_bind( fn create_and_bind(
device: &Device, device: &'a Device,
memory_requirements: VkMemoryRequirements, memory_requirements: VkMemoryRequirements,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
buffer: VkBuffer, buffer: VkBuffer,

View file

@ -2,8 +2,6 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::Arc;
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub enum PipelineType { pub enum PipelineType {
Graphics, Graphics,
@ -12,9 +10,9 @@ pub enum PipelineType {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Pipeline { pub struct Pipeline<'a> {
device: Arc<Device>, device: &'a Device,
pipeline_layout: Arc<PipelineLayout>, pipeline_layout: PipelineLayout,
pipeline_type: PipelineType, pipeline_type: PipelineType,
@ -23,10 +21,10 @@ pub struct Pipeline {
sub_pass: u32, sub_pass: u32,
} }
impl Pipeline { impl<'a> Pipeline<'a> {
pub(crate) fn new( pub(crate) fn new(
device: Arc<Device>, device: &'a Device,
pipeline_layout: Arc<PipelineLayout>, pipeline_layout: PipelineLayout,
pipeline_type: PipelineType, pipeline_type: PipelineType,
pipeline: VkPipeline, pipeline: VkPipeline,
) -> Self { ) -> Self {
@ -49,15 +47,15 @@ impl Pipeline {
self.sub_pass self.sub_pass
} }
pub fn new_graphics() -> GraphicsPipelineBuilder { pub fn new_graphics() -> GraphicsPipelineBuilder<'a> {
GraphicsPipelineBuilder::default() GraphicsPipelineBuilder::default()
} }
pub fn new_compute<'a>() -> ComputePipelineBuilder<'a> { pub fn new_compute() -> ComputePipelineBuilder<'a> {
ComputePipelineBuilder::default() ComputePipelineBuilder::default()
} }
pub fn new_ray_tracing<'a>() -> RayTracingPipelineBuilder<'a> { pub fn new_ray_tracing() -> RayTracingPipelineBuilder<'a> {
RayTracingPipelineBuilder::default() RayTracingPipelineBuilder::default()
} }
@ -74,7 +72,7 @@ impl Pipeline {
.get_ray_tracing_shader_group_handles(self.pipeline, 0, group_count, handle_size) .get_ray_tracing_shader_group_handles(self.pipeline, 0, group_count, handle_size)
} }
pub fn pipeline_layout(&self) -> &Arc<PipelineLayout> { pub fn pipeline_layout(&self) -> &PipelineLayout {
&self.pipeline_layout &self.pipeline_layout
} }
@ -83,15 +81,15 @@ impl Pipeline {
} }
} }
impl VulkanDevice for Pipeline { impl<'a> VulkanDevice for Pipeline<'a> {
fn device(&self) -> &Device { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle!(Pipeline, VkPipeline, pipeline); impl_vk_handle!(Pipeline<'a>, VkPipeline, pipeline);
impl Drop for Pipeline { impl<'a> Drop for Pipeline<'a> {
fn drop(&mut self) { fn drop(&mut self) {
self.device.destroy_pipeline(self.pipeline); self.device.destroy_pipeline(self.pipeline);
} }

View file

@ -3,11 +3,9 @@ use anyhow::Result;
use crate::pipeline::PipelineType; use crate::pipeline::PipelineType;
use crate::prelude::*; use crate::prelude::*;
use std::sync::Arc;
pub struct ComputePipelineBuilder<'a> { pub struct ComputePipelineBuilder<'a> {
shader_module: Option<&'a Arc<ShaderModule<shader_type::Compute>>>, shader_module: Option<&'a ShaderModule<'a, shader_type::Compute>>,
pipeline_cache: Option<&'a Arc<PipelineCache>>, pipeline_cache: Option<PipelineCache>,
flags: VkPipelineCreateFlagBits, flags: VkPipelineCreateFlagBits,
} }
@ -15,7 +13,7 @@ impl<'a> ComputePipelineBuilder<'a> {
// TODO: add support for specialization constants // TODO: add support for specialization constants
pub fn set_shader_module( pub fn set_shader_module(
mut self, mut self,
shader_module: &'a Arc<ShaderModule<shader_type::Compute>>, shader_module: &'a ShaderModule<'a, shader_type::Compute>,
) -> Self { ) -> Self {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
if self.shader_module.is_some() { if self.shader_module.is_some() {
@ -28,7 +26,7 @@ impl<'a> ComputePipelineBuilder<'a> {
self self
} }
pub fn set_pipeline_cache(mut self, pipeline_cache: &'a Arc<PipelineCache>) -> Self { pub fn set_pipeline_cache(mut self, pipeline_cache: PipelineCache) -> Self {
self.pipeline_cache = Some(pipeline_cache); self.pipeline_cache = Some(pipeline_cache);
self self
@ -42,9 +40,9 @@ impl<'a> ComputePipelineBuilder<'a> {
pub fn build( pub fn build(
self, self,
device: &Arc<Device>, device: &'a Device,
pipeline_layout: &Arc<PipelineLayout>, pipeline_layout: PipelineLayout,
) -> Result<Arc<Pipeline>> { ) -> Result<Pipeline<'a>> {
let pipeline_ci = match self.shader_module { let pipeline_ci = match self.shader_module {
Some(module) => VkComputePipelineCreateInfo::new( Some(module) => VkComputePipelineCreateInfo::new(
self.flags, self.flags,
@ -63,12 +61,12 @@ impl<'a> ComputePipelineBuilder<'a> {
&[pipeline_ci], &[pipeline_ci],
)?[0]; )?[0];
Ok(Arc::new(Pipeline::new( Ok(Pipeline::new(
device.clone(), device,
pipeline_layout.clone(), pipeline_layout,
PipelineType::Compute, PipelineType::Compute,
pipeline, pipeline,
))) ))
} }
} }

View file

@ -5,28 +5,28 @@ use anyhow::Result;
use std::sync::Arc; use std::sync::Arc;
pub struct GraphicsPipelineBuilder { pub struct GraphicsPipelineBuilder<'a> {
flags: VkPipelineCreateFlagBits, flags: VkPipelineCreateFlagBits,
pipeline_cache: Option<Arc<PipelineCache>>, pipeline_cache: Option<Arc<PipelineCache>>,
amd_rasterization_order: Option<VkPipelineRasterizationStateRasterizationOrderAMD>, amd_rasterization_order: Option<VkPipelineRasterizationStateRasterizationOrderAMD>,
vertex_shader: Option<Arc<ShaderModule<shader_type::Vertex>>>, vertex_shader: Option<&'a ShaderModule<'a, shader_type::Vertex>>,
vertex_binding_description: Vec<VkVertexInputBindingDescription>, vertex_binding_description: Vec<VkVertexInputBindingDescription>,
vertex_attribute_description: Vec<VkVertexInputAttributeDescription>, vertex_attribute_description: Vec<VkVertexInputAttributeDescription>,
input_assembly: Option<VkPipelineInputAssemblyStateCreateInfo>, input_assembly: Option<VkPipelineInputAssemblyStateCreateInfo>,
tesselation_shader: Option<( tesselation_shader: Option<(
Arc<ShaderModule<shader_type::TesselationControl>>, &'a ShaderModule<'a, shader_type::TesselationControl>,
Arc<ShaderModule<shader_type::TesselationEvaluation>>, &'a ShaderModule<'a, shader_type::TesselationEvaluation>,
)>, )>,
patch_control_points: u32, patch_control_points: u32,
geometry_shader: Option<Arc<ShaderModule<shader_type::Geometry>>>, geometry_shader: Option<&'a ShaderModule<'a, shader_type::Geometry>>,
fragment_shader: Option<Arc<ShaderModule<shader_type::Fragment>>>, fragment_shader: Option<&'a ShaderModule<'a, shader_type::Fragment>>,
viewports: Vec<VkViewport>, viewports: Vec<VkViewport>,
scissors: Vec<VkRect2D>, scissors: Vec<VkRect2D>,
@ -41,11 +41,11 @@ pub struct GraphicsPipelineBuilder {
dynamic_states: Vec<VkDynamicState>, dynamic_states: Vec<VkDynamicState>,
} }
impl GraphicsPipelineBuilder { impl<'a> GraphicsPipelineBuilder<'a> {
// TODO: add support for specialization constants // TODO: add support for specialization constants
pub fn set_vertex_shader<T: VertexInputDescription>( pub fn set_vertex_shader<T: VertexInputDescription>(
mut self, mut self,
shader: Arc<ShaderModule<shader_type::Vertex>>, shader: &'a ShaderModule<'a, shader_type::Vertex>,
) -> Self { ) -> Self {
self.vertex_shader = Some(shader); self.vertex_shader = Some(shader);
self.vertex_binding_description = T::bindings(); self.vertex_binding_description = T::bindings();
@ -57,8 +57,8 @@ impl GraphicsPipelineBuilder {
// TODO: add support for specialization constants // TODO: add support for specialization constants
pub fn set_tesselation_shader( pub fn set_tesselation_shader(
mut self, mut self,
tesselation_control: Arc<ShaderModule<shader_type::TesselationControl>>, tesselation_control: &'a ShaderModule<'a, shader_type::TesselationControl>,
tesselation_evaluation: Arc<ShaderModule<shader_type::TesselationEvaluation>>, tesselation_evaluation: &'a ShaderModule<'a, shader_type::TesselationEvaluation>,
patch_control_points: u32, patch_control_points: u32,
) -> Self { ) -> Self {
self.tesselation_shader = Some((tesselation_control, tesselation_evaluation)); self.tesselation_shader = Some((tesselation_control, tesselation_evaluation));
@ -68,14 +68,20 @@ impl GraphicsPipelineBuilder {
} }
// TODO: add support for specialization constants // TODO: add support for specialization constants
pub fn set_geometry_shader(mut self, shader: Arc<ShaderModule<shader_type::Geometry>>) -> Self { pub fn set_geometry_shader(
mut self,
shader: &'a ShaderModule<'a, shader_type::Geometry>,
) -> Self {
self.geometry_shader = Some(shader); self.geometry_shader = Some(shader);
self self
} }
// TODO: add support for specialization constants // TODO: add support for specialization constants
pub fn set_fragment_shader(mut self, shader: Arc<ShaderModule<shader_type::Fragment>>) -> Self { pub fn set_fragment_shader(
mut self,
shader: &'a ShaderModule<'a, shader_type::Fragment>,
) -> Self {
self.fragment_shader = Some(shader); self.fragment_shader = Some(shader);
self self
@ -309,11 +315,11 @@ impl GraphicsPipelineBuilder {
pub fn build( pub fn build(
mut self, mut self,
device: Arc<Device>, device: &'a Device,
pipeline_layout: &Arc<PipelineLayout>, pipeline_layout: PipelineLayout,
render_pass: &Arc<RenderPass>, render_pass: &RenderPass<'a>,
subpass: u32, subpass: u32,
) -> Result<Arc<Pipeline>> { ) -> Result<Pipeline<'a>> {
let mut rasterization = self.rasterization.expect("rasterization state is required"); let mut rasterization = self.rasterization.expect("rasterization state is required");
if let Some(amd_rasterization_order) = &self.amd_rasterization_order { if let Some(amd_rasterization_order) = &self.amd_rasterization_order {
@ -393,19 +399,14 @@ impl GraphicsPipelineBuilder {
&[pipeline_ci], &[pipeline_ci],
)?[0]; )?[0];
Ok(Arc::new( Ok(
Pipeline::new( Pipeline::new(device, pipeline_layout, PipelineType::Graphics, pipeline)
device, .set_sub_pass(subpass),
pipeline_layout.clone(), )
PipelineType::Graphics,
pipeline,
)
.set_sub_pass(subpass),
))
} }
} }
impl Default for GraphicsPipelineBuilder { impl<'a> Default for GraphicsPipelineBuilder<'a> {
fn default() -> Self { fn default() -> Self {
GraphicsPipelineBuilder { GraphicsPipelineBuilder {
flags: 0.into(), flags: 0.into(),

View file

@ -8,18 +8,14 @@ use std::sync::Arc;
use super::shader_binding_table::ShaderBindingTableBuilder; use super::shader_binding_table::ShaderBindingTableBuilder;
pub struct Library<'a> { pub struct Library<'a> {
pipeline: &'a Arc<Pipeline>, pipeline: &'a Pipeline<'a>,
max_payload_size: u32, max_payload_size: u32,
max_attribute_size: u32, max_attribute_size: u32,
} }
impl<'a> Library<'a> { impl<'a> Library<'a> {
pub fn new( pub fn new(pipeline: &'a Pipeline<'a>, max_payload_size: u32, max_attribute_size: u32) -> Self {
pipeline: &'a Arc<Pipeline>,
max_payload_size: u32,
max_attribute_size: u32,
) -> Self {
Library { Library {
pipeline, pipeline,
@ -31,8 +27,8 @@ impl<'a> Library<'a> {
macro_rules! impl_from_shader_type { macro_rules! impl_from_shader_type {
($struct: ident, $shader_type: ident) => { ($struct: ident, $shader_type: ident) => {
impl From<Arc<ShaderModule<shader_type::$shader_type>>> for $struct { impl<'a> From<&'a ShaderModule<'a, shader_type::$shader_type>> for $struct<'a> {
fn from(value: Arc<ShaderModule<shader_type::$shader_type>>) -> Self { fn from(value: &'a ShaderModule<'a, shader_type::$shader_type>) -> Self {
Self::$shader_type(value) Self::$shader_type(value)
} }
} }
@ -40,12 +36,12 @@ macro_rules! impl_from_shader_type {
} }
#[derive(Clone)] #[derive(Clone)]
enum RaytracingShader { enum RaytracingShader<'a> {
RayGeneration(Arc<ShaderModule<shader_type::RayGeneration>>), RayGeneration(&'a ShaderModule<'a, shader_type::RayGeneration>),
ClosestHit(Arc<ShaderModule<shader_type::ClosestHit>>), ClosestHit(&'a ShaderModule<'a, shader_type::ClosestHit>),
Miss(Arc<ShaderModule<shader_type::Miss>>), Miss(&'a ShaderModule<'a, shader_type::Miss>),
AnyHit(Arc<ShaderModule<shader_type::AnyHit>>), AnyHit(&'a ShaderModule<'a, shader_type::AnyHit>),
Intersection(Arc<ShaderModule<shader_type::Intersection>>), Intersection(&'a ShaderModule<'a, shader_type::Intersection>),
} }
impl_from_shader_type!(RaytracingShader, RayGeneration); impl_from_shader_type!(RaytracingShader, RayGeneration);
@ -54,8 +50,8 @@ impl_from_shader_type!(RaytracingShader, Miss);
impl_from_shader_type!(RaytracingShader, AnyHit); impl_from_shader_type!(RaytracingShader, AnyHit);
impl_from_shader_type!(RaytracingShader, Intersection); impl_from_shader_type!(RaytracingShader, Intersection);
impl From<HitShader> for RaytracingShader { impl<'a> From<HitShader<'a>> for RaytracingShader<'a> {
fn from(value: HitShader) -> Self { fn from(value: HitShader<'a>) -> Self {
match value { match value {
HitShader::ClosestHit(s) => Self::ClosestHit(s), HitShader::ClosestHit(s) => Self::ClosestHit(s),
HitShader::AnyHit(s) => Self::AnyHit(s), HitShader::AnyHit(s) => Self::AnyHit(s),
@ -64,8 +60,8 @@ impl From<HitShader> for RaytracingShader {
} }
} }
impl From<OtherShader> for RaytracingShader { impl<'a> From<OtherShader<'a>> for RaytracingShader<'a> {
fn from(value: OtherShader) -> Self { fn from(value: OtherShader<'a>) -> Self {
match value { match value {
OtherShader::Miss(s) => Self::Miss(s), OtherShader::Miss(s) => Self::Miss(s),
OtherShader::RayGeneration(s) => Self::RayGeneration(s), OtherShader::RayGeneration(s) => Self::RayGeneration(s),
@ -74,10 +70,10 @@ impl From<OtherShader> for RaytracingShader {
} }
#[derive(Clone)] #[derive(Clone)]
pub enum HitShader { pub enum HitShader<'a> {
ClosestHit(Arc<ShaderModule<shader_type::ClosestHit>>), ClosestHit(&'a ShaderModule<'a, shader_type::ClosestHit>),
AnyHit(Arc<ShaderModule<shader_type::AnyHit>>), AnyHit(&'a ShaderModule<'a, shader_type::AnyHit>),
Intersection(Arc<ShaderModule<shader_type::Intersection>>), Intersection(&'a ShaderModule<'a, shader_type::Intersection>),
} }
impl_from_shader_type!(HitShader, ClosestHit); impl_from_shader_type!(HitShader, ClosestHit);
@ -85,16 +81,16 @@ impl_from_shader_type!(HitShader, AnyHit);
impl_from_shader_type!(HitShader, Intersection); impl_from_shader_type!(HitShader, Intersection);
#[derive(Clone)] #[derive(Clone)]
pub enum OtherShader { pub enum OtherShader<'a> {
RayGeneration(Arc<ShaderModule<shader_type::RayGeneration>>), RayGeneration(&'a ShaderModule<'a, shader_type::RayGeneration>),
Miss(Arc<ShaderModule<shader_type::Miss>>), Miss(&'a ShaderModule<'a, shader_type::Miss>),
} }
impl_from_shader_type!(OtherShader, RayGeneration); impl_from_shader_type!(OtherShader, RayGeneration);
impl_from_shader_type!(OtherShader, Miss); impl_from_shader_type!(OtherShader, Miss);
pub struct RayTracingPipelineBuilder<'a> { pub struct RayTracingPipelineBuilder<'a> {
shader_modules: Vec<(RaytracingShader, Option<SpecializationConstants>)>, shader_modules: Vec<(RaytracingShader<'a>, Option<SpecializationConstants>)>,
shader_groups: Vec<VkRayTracingShaderGroupCreateInfoKHR>, shader_groups: Vec<VkRayTracingShaderGroupCreateInfoKHR>,
@ -111,7 +107,7 @@ pub struct RayTracingPipelineBuilder<'a> {
} }
impl<'a> RayTracingPipelineBuilder<'a> { impl<'a> RayTracingPipelineBuilder<'a> {
pub fn check_max_recursion(device: &Arc<Device>, max_recursion: u32) -> u32 { pub fn check_max_recursion(device: &'a Device, max_recursion: u32) -> u32 {
max_recursion.min( max_recursion.min(
device device
.physical_device() .physical_device()
@ -146,7 +142,7 @@ impl<'a> RayTracingPipelineBuilder<'a> {
pub fn add_shader( pub fn add_shader(
mut self, mut self,
shader_module: impl Into<OtherShader>, shader_module: impl Into<OtherShader<'a>>,
data: Option<Vec<u8>>, data: Option<Vec<u8>>,
specialization_constants: Option<SpecializationConstants>, specialization_constants: Option<SpecializationConstants>,
) -> Self { ) -> Self {
@ -179,7 +175,7 @@ impl<'a> RayTracingPipelineBuilder<'a> {
pub fn add_hit_shaders( pub fn add_hit_shaders(
mut self, mut self,
shader_modules: impl IntoIterator<Item = (HitShader, Option<SpecializationConstants>)>, shader_modules: impl IntoIterator<Item = (HitShader<'a>, Option<SpecializationConstants>)>,
data: Option<Vec<u8>>, data: Option<Vec<u8>>,
) -> Self { ) -> Self {
let mut group = VkRayTracingShaderGroupCreateInfoKHR::new( let mut group = VkRayTracingShaderGroupCreateInfoKHR::new(
@ -243,9 +239,9 @@ impl<'a> RayTracingPipelineBuilder<'a> {
pub fn build( pub fn build(
mut self, mut self,
device: Arc<Device>, device: &'a Device,
pipeline_layout: &Arc<PipelineLayout>, pipeline_layout: PipelineLayout,
) -> Result<(Arc<Pipeline>, ShaderBindingTable<'a>)> { ) -> Result<(Pipeline<'a>, ShaderBindingTable<'a>)> {
let shader_stages: Vec<VkPipelineShaderStageCreateInfo> = self let shader_stages: Vec<VkPipelineShaderStageCreateInfo> = self
.shader_modules .shader_modules
.iter() .iter()
@ -267,7 +263,7 @@ impl<'a> RayTracingPipelineBuilder<'a> {
.collect(); .collect();
// check that we dont exceed the gpu's capabilities // check that we dont exceed the gpu's capabilities
let max_recursion = Self::check_max_recursion(&device, self.max_recursion); let max_recursion = Self::check_max_recursion(device, self.max_recursion);
let pipeline = { let pipeline = {
let mut libraries = Vec::with_capacity(self.libraries.len()); let mut libraries = Vec::with_capacity(self.libraries.len());
@ -306,12 +302,7 @@ impl<'a> RayTracingPipelineBuilder<'a> {
)?[0] )?[0]
}; };
let pipeline = Arc::new(Pipeline::new( let pipeline = Pipeline::new(device, pipeline_layout, PipelineType::RayTracing, pipeline);
device.clone(),
pipeline_layout.clone(),
PipelineType::RayTracing,
pipeline,
));
let sbt = self let sbt = self
.shader_binding_table_builder .shader_binding_table_builder

View file

@ -2,8 +2,6 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::Arc;
struct ShaderBindingTableEntry { struct ShaderBindingTableEntry {
group_index: u32, group_index: u32,
inline_data: Vec<u8>, inline_data: Vec<u8>,
@ -130,8 +128,8 @@ impl ShaderBindingTableBuilder {
pub(crate) fn build<'a>( pub(crate) fn build<'a>(
&mut self, &mut self,
device: &Arc<Device>, device: &'a Device,
pipeline: &Arc<Pipeline>, pipeline: &Pipeline<'a>,
) -> Result<ShaderBindingTable<'a>> { ) -> Result<ShaderBindingTable<'a>> {
let ray_tracing_properties = device.physical_device().ray_tracing_properties(); let ray_tracing_properties = device.physical_device().ray_tracing_properties();

View file

@ -2,11 +2,7 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::{ use std::{slice, sync::Mutex, time::Duration};
slice,
sync::{Arc, Mutex},
time::Duration,
};
pub struct QueueRequestInfo { pub struct QueueRequestInfo {
pub queue_create_info: VkDeviceQueueCreateInfo, pub queue_create_info: VkDeviceQueueCreateInfo,
@ -23,9 +19,9 @@ pub struct Queue<'a> {
} }
impl<'a> Queue<'a> { impl<'a> Queue<'a> {
pub fn create_presentable_request_info<'b>( pub fn create_presentable_request_info(
physical_device: &PhysicalDevice, physical_device: &PhysicalDevice,
surface: &Surface<'b>, surface: &Surface<'a>,
queue_type: impl Into<VkQueueFlagBits>, queue_type: impl Into<VkQueueFlagBits>,
) -> Result<QueueRequestInfo> { ) -> Result<QueueRequestInfo> {
let index = let index =
@ -93,11 +89,11 @@ impl<'a> Queue<'a> {
pub fn minimal_submit( pub fn minimal_submit(
&self, &self,
time_out: Duration, time_out: Duration,
command_buffers: &[Arc<CommandBuffer<'a>>], command_buffers: &[&CommandBuffer<'a>],
) -> Result<()> { ) -> Result<()> {
let mut submit = SubmitInfo::default(); let mut submit = SubmitInfo::default();
for command_buffer in command_buffers.iter() { for &command_buffer in command_buffers.iter() {
submit = submit.add_command_buffer(command_buffer); submit = submit.add_command_buffer(command_buffer);
} }
@ -146,7 +142,7 @@ impl<'a> VulkanDevice for Queue<'a> {
} }
} }
impl_vk_handle!(Queue, VkQueue, queue); impl_vk_handle!(Queue<'a>, VkQueue, queue);
impl<'a> Queue<'a> { impl<'a> Queue<'a> {
fn find_presentable_queue_index( fn find_presentable_queue_index(

View file

@ -1,15 +1,12 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::{ use std::sync::atomic::{AtomicU32, AtomicUsize, Ordering::SeqCst};
atomic::{AtomicU32, AtomicUsize, Ordering::SeqCst},
Arc,
};
pub mod sub_pass; pub mod sub_pass;
use sub_pass::{AttachmentInfo, AttachmentInfoUsage, SubPass}; use sub_pass::{AttachmentInfo, AttachmentInfoUsage, SubPass};
pub struct RenderTargetBuilder<'a> { pub struct RenderTargetBuilder<'a> {
old_render_target: Option<&'a RenderTarget<'a>>, old_render_target: Option<RenderTarget<'a>>,
sub_passes: Vec<SubPass<'a>>, sub_passes: Vec<SubPass<'a>>,
} }
@ -20,13 +17,13 @@ impl<'a> RenderTargetBuilder<'a> {
self self
} }
pub fn preserve_old_render_pass(mut self, render_target: &'a RenderTarget<'a>) -> Self { pub fn preserve_old_render_pass(mut self, render_target: RenderTarget<'a>) -> Self {
self.old_render_target = Some(render_target); self.old_render_target = Some(render_target);
self self
} }
pub fn build(self, device: &Arc<Device>) -> Result<RenderTarget<'a>> { pub fn build(self, device: &'a Device) -> Result<RenderTarget<'a>> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
// sub passes must not be empty // sub passes must not be empty
@ -55,7 +52,7 @@ impl<'a> RenderTargetBuilder<'a> {
)); ));
} }
old_render_target.render_pass.clone() old_render_target.render_pass
} }
None => { None => {
// gather attachment descriptions // gather attachment descriptions
@ -164,7 +161,7 @@ impl<'a> RenderTargetBuilder<'a> {
last_dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT.into(); last_dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT.into();
} }
RenderPass::new(device.clone(), &descriptions, &attachments, &dependencies)? RenderPass::new(device, &descriptions, &attachments, &dependencies)?
} }
}; };
@ -186,7 +183,7 @@ impl<'a> RenderTargetBuilder<'a> {
} }
fn create_framebuffers( fn create_framebuffers(
render_pass: &Arc<RenderPass>, render_pass: &RenderPass<'a>,
sub_passes: &[SubPass<'a>], sub_passes: &[SubPass<'a>],
) -> Result<Vec<Framebuffer<'a>>> { ) -> Result<Vec<Framebuffer<'a>>> {
let extent = sub_passes[0].extent(); let extent = sub_passes[0].extent();
@ -261,7 +258,7 @@ struct SubPassAttachmentReferences {
#[derive(Debug)] #[derive(Debug)]
pub struct RenderTarget<'a> { pub struct RenderTarget<'a> {
render_pass: Arc<RenderPass>, render_pass: RenderPass<'a>,
framebuffers: Vec<Framebuffer<'a>>, framebuffers: Vec<Framebuffer<'a>>,
clear_values: Vec<VkClearValue>, clear_values: Vec<VkClearValue>,
@ -281,7 +278,7 @@ impl<'a> RenderTarget<'a> {
} }
} }
pub fn render_pass(&self) -> &Arc<RenderPass> { pub fn render_pass(&self) -> &RenderPass<'a> {
&self.render_pass &self.render_pass
} }
@ -381,7 +378,7 @@ mod test {
RenderTarget::builder() RenderTarget::builder()
.add_sub_pass( .add_sub_pass(
SubPass::builder(target_images[0].width(), target_images[0].height()) 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) .set_prepared_targets(target_images, 0, [0.0, 0.0, 0.0, 0.0], false)
.build(&device) .build(&device)
.unwrap(), .unwrap(),
) )
@ -404,7 +401,7 @@ mod test {
false, false,
true, true,
)) ))
.use_queue(queue.clone()) .use_queue(&queue)
.build(&device) .build(&device)
.unwrap(), .unwrap(),
) )
@ -414,7 +411,7 @@ mod test {
sub_pass_index: 1, sub_pass_index: 1,
input_indices: vec![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, 0, [0.0, 0.0, 0.0, 0.0], false)
.build(&device) .build(&device)
.unwrap(), .unwrap(),
) )

View file

@ -1,6 +1,6 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::Mutex; use std::{ops::Index, sync::Mutex};
pub enum ClearValue { pub enum ClearValue {
Color([f32; 4]), Color([f32; 4]),
@ -56,8 +56,8 @@ impl CustomTarget {
fn to_attachment_info<'a>( fn to_attachment_info<'a>(
&self, &self,
device: &Device, device: &'a Device,
queue: &Mutex<Queue<'a>>, queue: &'a Mutex<Queue<'a>>,
width: u32, width: u32,
height: u32, height: u32,
sample_count: VkSampleCountFlags, sample_count: VkSampleCountFlags,
@ -159,7 +159,7 @@ impl CustomTarget {
} }
Ok(AttachmentInfo { Ok(AttachmentInfo {
images: vec![image], images: vec![image].into(),
clear_value, clear_value,
layout, layout,
description, description,
@ -209,7 +209,7 @@ pub struct SubPassBuilder<'a> {
input_info: Option<InputAttachmentInfo>, input_info: Option<InputAttachmentInfo>,
// (images, index, clear_color, clear_on_load) // (images, index, clear_color, clear_on_load)
prepared_targets: Option<(&'a [&'a Image<'a>], usize, [f32; 4], bool)>, prepared_targets: Option<(Vec<Image<'a>>, usize, [f32; 4], bool)>,
resolve_targets: Vec<ResolveTarget<'a>>, resolve_targets: Vec<ResolveTarget<'a>>,
output_usage: VkAccessFlagBits, output_usage: VkAccessFlagBits,
@ -242,7 +242,7 @@ impl<'a> SubPassBuilder<'a> {
pub fn set_prepared_targets( pub fn set_prepared_targets(
mut self, mut self,
prepared_targets: &'a [&'a Image<'a>], prepared_targets: Vec<Image<'a>>,
target_index: usize, target_index: usize,
clear_color: impl Into<[f32; 4]>, clear_color: impl Into<[f32; 4]>,
clear_on_load: bool, clear_on_load: bool,
@ -269,7 +269,7 @@ impl<'a> SubPassBuilder<'a> {
self self
} }
pub fn build(self, device: &Device) -> Result<SubPass<'a>> { pub fn build(self, device: &'a Device) -> Result<SubPass<'a>> {
Ok(SubPass { Ok(SubPass {
extent: VkExtent2D { extent: VkExtent2D {
width: self.width, width: self.width,
@ -284,7 +284,7 @@ impl<'a> SubPassBuilder<'a> {
} }
#[inline] #[inline]
fn create_images(self, device: &Device) -> Result<Vec<AttachmentInfo<'a>>> { fn create_images(self, device: &'a Device) -> Result<Vec<AttachmentInfo<'a>>> {
// check for correct sample count // check for correct sample count
let checked_sample_count = device.max_supported_sample_count(self.sample_count); let checked_sample_count = device.max_supported_sample_count(self.sample_count);
@ -314,7 +314,6 @@ impl<'a> SubPassBuilder<'a> {
attachment_infos.insert( attachment_infos.insert(
index, index,
AttachmentInfo { AttachmentInfo {
images: prepared_images.iter().map(|image| image.clone()).collect(),
clear_value: VkClearValue::color(VkClearColorValue::float32(clear_color)), clear_value: VkClearValue::color(VkClearColorValue::float32(clear_color)),
layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
description: VkAttachmentDescription::new( description: VkAttachmentDescription::new(
@ -329,6 +328,7 @@ impl<'a> SubPassBuilder<'a> {
prepared_images[0].image_layout(), prepared_images[0].image_layout(),
), ),
usage: AttachmentInfoUsage::Output, usage: AttachmentInfoUsage::Output,
images: prepared_images.into(),
}, },
); );
} }
@ -353,7 +353,6 @@ impl<'a> SubPassBuilder<'a> {
} }
ResolveTarget::PreparedTargets((prepared_targets, clear_on_load)) => { ResolveTarget::PreparedTargets((prepared_targets, clear_on_load)) => {
attachment_infos.push(AttachmentInfo { attachment_infos.push(AttachmentInfo {
images: prepared_targets.iter().map(|image| image.clone()).collect(),
clear_value: VkClearValue::color(VkClearColorValue::float32([ clear_value: VkClearValue::color(VkClearColorValue::float32([
0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0,
])), ])),
@ -370,6 +369,7 @@ impl<'a> SubPassBuilder<'a> {
prepared_targets[0].image_layout(), prepared_targets[0].image_layout(),
), ),
usage: AttachmentInfoUsage::Resolve, usage: AttachmentInfoUsage::Resolve,
images: prepared_targets.into(),
}); });
} }
} }
@ -404,9 +404,54 @@ pub enum AttachmentInfoUsage {
Output, Output,
} }
#[derive(Debug)]
pub enum AttachmentInfoImages<'a> {
Owned(Vec<Image<'a>>),
Ref(Vec<&'a Image<'a>>),
}
impl<'a> AttachmentInfoImages<'a> {
fn len(&self) -> usize {
match self {
AttachmentInfoImages::Owned(v) => v.len(),
AttachmentInfoImages::Ref(v) => v.len(),
}
}
fn is_empty(&self) -> bool {
match self {
AttachmentInfoImages::Owned(v) => v.is_empty(),
AttachmentInfoImages::Ref(v) => v.is_empty(),
}
}
}
impl<'a> From<Vec<Image<'a>>> for AttachmentInfoImages<'a> {
fn from(value: Vec<Image<'a>>) -> Self {
Self::Owned(value)
}
}
impl<'a> From<Vec<&'a Image<'a>>> for AttachmentInfoImages<'a> {
fn from(value: Vec<&'a Image<'a>>) -> Self {
Self::Ref(value)
}
}
impl<'a> Index<usize> for AttachmentInfoImages<'a> {
type Output = Image<'a>;
fn index(&self, index: usize) -> &Self::Output {
match self {
AttachmentInfoImages::Owned(v) => &v[index],
AttachmentInfoImages::Ref(v) => &v[index],
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct AttachmentInfo<'a> { pub struct AttachmentInfo<'a> {
images: Vec<&'a Image<'a>>, images: AttachmentInfoImages<'a>,
pub(crate) clear_value: VkClearValue, pub(crate) clear_value: VkClearValue,
pub(crate) layout: VkImageLayout, pub(crate) layout: VkImageLayout,
pub(crate) description: VkAttachmentDescription, pub(crate) description: VkAttachmentDescription,

View file

@ -2,21 +2,19 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::Arc;
#[derive(Debug)] #[derive(Debug)]
pub struct RenderPass { pub struct RenderPass<'a> {
device: Arc<Device>, device: &'a Device,
render_pass: VkRenderPass, render_pass: VkRenderPass,
} }
impl RenderPass { impl<'a> RenderPass<'a> {
pub fn new( pub fn new(
device: Arc<Device>, device: &'a Device,
sub_passes: &[VkSubpassDescription], sub_passes: &[VkSubpassDescription],
attachments: &[VkAttachmentDescription], attachments: &[VkAttachmentDescription],
dependencies: &[VkSubpassDependency], dependencies: &[VkSubpassDependency],
) -> Result<Arc<RenderPass>> { ) -> Result<RenderPass<'a>> {
let render_pass_ci = VkRenderPassCreateInfo::new( let render_pass_ci = VkRenderPassCreateInfo::new(
VK_RENDERPASS_CREATE_NULL_BIT, VK_RENDERPASS_CREATE_NULL_BIT,
attachments, attachments,
@ -26,22 +24,22 @@ impl RenderPass {
let render_pass = device.create_render_pass(&render_pass_ci)?; let render_pass = device.create_render_pass(&render_pass_ci)?;
Ok(Arc::new(RenderPass { Ok(RenderPass {
device, device,
render_pass, render_pass,
})) })
} }
} }
impl VulkanDevice for RenderPass { impl<'a> VulkanDevice for RenderPass<'a> {
fn device(&self) -> &Device { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle!(RenderPass, VkRenderPass, render_pass); impl_vk_handle!(RenderPass<'a>, VkRenderPass, render_pass);
impl Drop for RenderPass { impl<'a> Drop for RenderPass<'a> {
fn drop(&mut self) { fn drop(&mut self) {
self.device.destroy_render_pass(self.render_pass); self.device.destroy_render_pass(self.render_pass);
} }

View file

@ -78,7 +78,7 @@ impl SamplerBuilder {
self self
} }
pub fn build(self, device: &Device) -> Result<Sampler> { pub fn build(self, device: &Device) -> Result<Arc<Sampler>> {
device.create_sampler_from_manager(self.create_info) device.create_sampler_from_manager(self.create_info)
} }
} }

View file

@ -24,7 +24,7 @@ impl<'a> VulkanDevice for Semaphore<'a> {
} }
} }
impl_vk_handle!(Semaphore, VkSemaphore, semaphore); impl_vk_handle!(Semaphore<'a>, VkSemaphore, semaphore);
impl<'a> Drop for Semaphore<'a> { impl<'a> Drop for Semaphore<'a> {
fn drop(&mut self) { fn drop(&mut self) {

View file

@ -5,7 +5,6 @@ use anyhow::{Context, Result};
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::Arc;
pub mod shader_type { pub mod shader_type {
mod sealed { mod sealed {
@ -77,7 +76,7 @@ pub trait PipelineStageInfo {
macro_rules! impl_pipeline_stage_info { macro_rules! impl_pipeline_stage_info {
($func:ident, $type:ident) => { ($func:ident, $type:ident) => {
impl PipelineStageInfo for ShaderModule<$type> { impl<'a> PipelineStageInfo for ShaderModule<'a, $type> {
fn pipeline_stage_info(&self) -> VkPipelineShaderStageCreateInfo { fn pipeline_stage_info(&self) -> VkPipelineShaderStageCreateInfo {
VkPipelineShaderStageCreateInfo::$func(self.shader_module) VkPipelineShaderStageCreateInfo::$func(self.shader_module)
} }
@ -86,33 +85,30 @@ macro_rules! impl_pipeline_stage_info {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct ShaderModule<ShaderModuleType: ShaderType> { pub struct ShaderModule<'a, ShaderModuleType: ShaderType> {
t: PhantomData<ShaderModuleType>, t: PhantomData<ShaderModuleType>,
device: Arc<Device>, device: &'a Device,
shader_module: VkShaderModule, shader_module: VkShaderModule,
} }
impl<ShaderModuleType: ShaderType> ShaderModule<ShaderModuleType> { impl<'a, ShaderModuleType: ShaderType> ShaderModule<'a, ShaderModuleType> {
pub fn new(device: Arc<Device>, path: &str) -> Result<Arc<ShaderModule<ShaderModuleType>>> { pub fn new(device: &'a Device, path: &str) -> Result<Self> {
let code = Self::shader_code(path)?; let code = Self::shader_code(path)?;
Self::from_slice(device, code.as_slice()) Self::from_slice(device, code.as_slice())
} }
pub fn from_slice( pub fn from_slice(device: &'a Device, code: &[u8]) -> Result<Self> {
device: Arc<Device>,
code: &[u8],
) -> Result<Arc<ShaderModule<ShaderModuleType>>> {
let shader_module_ci = let shader_module_ci =
VkShaderModuleCreateInfo::new(VK_SHADER_MODULE_CREATE_NULL_BIT, code); VkShaderModuleCreateInfo::new(VK_SHADER_MODULE_CREATE_NULL_BIT, code);
let shader_module = device.create_shader_module(&shader_module_ci)?; let shader_module = device.create_shader_module(&shader_module_ci)?;
Ok(Arc::new(ShaderModule { Ok(ShaderModule {
t: PhantomData, t: PhantomData,
device, device,
shader_module, shader_module,
})) })
} }
fn shader_code(path: &str) -> Result<Vec<u8>> { fn shader_code(path: &str) -> Result<Vec<u8>> {
@ -143,15 +139,29 @@ impl_pipeline_stage_info!(closest_hit, ClosestHit);
impl_pipeline_stage_info!(ray_generation, RayGeneration); impl_pipeline_stage_info!(ray_generation, RayGeneration);
impl_pipeline_stage_info!(miss, Miss); impl_pipeline_stage_info!(miss, Miss);
impl<ShaderModuleType: ShaderType> VulkanDevice for ShaderModule<ShaderModuleType> { impl<'a, ShaderModuleType: ShaderType> VulkanDevice for ShaderModule<'a, ShaderModuleType> {
fn device(&self) -> &Device { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle!(ShaderModule<ShaderModuleType: ShaderType,>, VkShaderModule, shader_module); impl<'a, ShaderModuleType: ShaderType> VkHandle<VkShaderModule>
for ShaderModule<'a, ShaderModuleType>
{
fn vk_handle(&self) -> VkShaderModule {
self.shader_module
}
}
impl<ShaderModuleType: ShaderType> Drop for ShaderModule<ShaderModuleType> { impl<'a, ShaderModuleType: ShaderType> VkHandle<VkShaderModule>
for &'a ShaderModule<'a, ShaderModuleType>
{
fn vk_handle(&self) -> VkShaderModule {
self.shader_module
}
}
impl<'a, ShaderModuleType: ShaderType> Drop for ShaderModule<'a, ShaderModuleType> {
fn drop(&mut self) { fn drop(&mut self) {
self.device.destroy_shader_module(self.shader_module); self.device.destroy_shader_module(self.shader_module);
} }

View file

@ -2,8 +2,6 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::Arc;
const UNORM_FORMATS: [VkFormat; 2] = [VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM]; const UNORM_FORMATS: [VkFormat; 2] = [VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM];
#[derive(Debug)] #[derive(Debug)]
@ -17,7 +15,7 @@ impl<'a> Surface<'a> {
Self { instance, surface } Self { instance, surface }
} }
pub fn capabilities(&self, device: &Arc<Device>) -> Result<VkSurfaceCapabilitiesKHR> { pub fn capabilities(&self, device: &'a Device) -> Result<VkSurfaceCapabilitiesKHR> {
self.instance.physical_device_surface_capabilities( self.instance.physical_device_surface_capabilities(
device.physical_device().vk_handle(), device.physical_device().vk_handle(),
self.surface, self.surface,
@ -26,7 +24,7 @@ impl<'a> Surface<'a> {
pub fn format_colorspace( pub fn format_colorspace(
&self, &self,
device: &Arc<Device>, device: &'a Device,
prefered_format: VkFormat, prefered_format: VkFormat,
) -> Result<(VkFormat, VkColorSpaceKHR)> { ) -> Result<(VkFormat, VkColorSpaceKHR)> {
let surface_formats = self let surface_formats = self
@ -58,7 +56,7 @@ impl<'a> Surface<'a> {
Ok((surface_formats[0].format, surface_formats[0].colorSpace)) Ok((surface_formats[0].format, surface_formats[0].colorSpace))
} }
pub fn present_modes(&self, device: &Arc<Device>) -> Result<Vec<VkPresentModeKHR>> { pub fn present_modes(&self, device: &'a Device) -> Result<Vec<VkPresentModeKHR>> {
self.instance self.instance
.physical_device_present_modes(device.physical_device().vk_handle(), self.surface) .physical_device_present_modes(device.physical_device().vk_handle(), self.surface)
} }

View file

@ -3,10 +3,7 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::cmp; use std::cmp;
use std::sync::{ use std::sync::Mutex;
atomic::{AtomicU32, Ordering::SeqCst},
Mutex,
};
pub enum NextImageSynchronization<'a> { pub enum NextImageSynchronization<'a> {
Semaphore(&'a Semaphore<'a>), Semaphore(&'a Semaphore<'a>),
@ -113,23 +110,23 @@ impl<'a> Swapchain<'a> {
let swapchain = device.create_swapchain(&swapchain_ci)?; let swapchain = device.create_swapchain(&swapchain_ci)?;
Ok(Swapchain { Ok(Swapchain {
width: AtomicU32::new(extent.width), width: extent.width,
height: AtomicU32::new(extent.height), height: extent.height,
usage: swapchain_ci.imageUsage, usage: swapchain_ci.imageUsage,
index: AtomicU32::new(0), index: 0,
device, device,
surface, surface,
create_info: Mutex::new(swapchain_ci), create_info: swapchain_ci,
swapchain: Mutex::new(swapchain), swapchain,
raw: false, raw: false,
}) })
} }
pub fn from_ci(device: &Device, swapchain_ci: &VkSwapchainCreateInfoKHR) -> Result<Self> { pub fn from_ci(device: &'a Device, swapchain_ci: &VkSwapchainCreateInfoKHR) -> Result<Self> {
Ok(Swapchain { Ok(Swapchain {
width: swapchain_ci.imageExtent.width, width: swapchain_ci.imageExtent.width,
height: swapchain_ci.imageExtent.height, height: swapchain_ci.imageExtent.height,
@ -174,11 +171,11 @@ impl<'a> Swapchain<'a> {
} }
} }
pub fn recreate(&self) -> Result<()> { pub fn recreate(&mut self) -> Result<()> {
// wait for the device to get idle // wait for the device to get idle
self.device.wait_idle()?; self.device.wait_idle()?;
let surface_caps = self.surface.capabilities(&self.device)?; let surface_caps = self.surface.capabilities(self.device)?;
let extent = if surface_caps.currentExtent.width == u32::max_value() let extent = if surface_caps.currentExtent.width == u32::max_value()
|| surface_caps.currentExtent.height == u32::max_value() || surface_caps.currentExtent.height == u32::max_value()
@ -194,9 +191,9 @@ impl<'a> Swapchain<'a> {
} }
}; };
let mut swapchain_ci = self.create_info.lock().unwrap(); let mut swapchain_ci = self.create_info.clone();
swapchain_ci.imageExtent = extent; swapchain_ci.imageExtent = extent;
swapchain_ci.set_old_swapchain(*self.swapchain.lock().unwrap()); swapchain_ci.set_old_swapchain(self.swapchain);
let swapchain = self.device.create_swapchain(&swapchain_ci)?; let swapchain = self.device.create_swapchain(&swapchain_ci)?;
@ -204,24 +201,24 @@ impl<'a> Swapchain<'a> {
self.destroy(); self.destroy();
// replace swapchain // replace swapchain
*self.swapchain.lock().unwrap() = swapchain; self.swapchain = swapchain;
// set new surface size // set new surface size
self.width.store(extent.width, SeqCst); self.width = extent.width;
self.height.store(extent.height, SeqCst); self.height = extent.height;
Ok(()) Ok(())
} }
pub fn acquire_next_image<'b>( pub fn acquire_next_image<'b>(
&self, &mut self,
time_out: u64, time_out: u64,
synchro: impl Into<NextImageSynchronization<'b>>, synchro: impl Into<NextImageSynchronization<'b>>,
) -> Result<OutOfDate<u32>> { ) -> Result<OutOfDate<u32>> {
let synchro = synchro.into(); let synchro = synchro.into();
let res = self.device.acquire_next_image( let res = self.device.acquire_next_image(
*self.swapchain.lock().unwrap(), self.swapchain,
time_out, time_out,
match synchro { match synchro {
NextImageSynchronization::Semaphore(semaphore) => Some(semaphore.vk_handle()), NextImageSynchronization::Semaphore(semaphore) => Some(semaphore.vk_handle()),
@ -235,7 +232,7 @@ impl<'a> Swapchain<'a> {
if let Ok(r) = &res { if let Ok(r) = &res {
if let OutOfDate::Ok(i) = r { if let OutOfDate::Ok(i) = r {
self.index.store(*i, SeqCst); self.index = *i;
} }
} }
@ -244,23 +241,22 @@ impl<'a> Swapchain<'a> {
/// set current /// set current
/// only use when externally acquired next index !!! /// only use when externally acquired next index !!!
pub unsafe fn set_image_index(&self, index: u32) { pub unsafe fn set_image_index(&mut self, index: u32) {
self.index.store(index, SeqCst); self.index = index;
} }
pub fn current_index(&self) -> u32 { pub fn current_index(&self) -> u32 {
self.index.load(SeqCst) self.index
} }
pub fn vk_images(&self) -> Result<Vec<VkImage>> { pub fn vk_images(&self) -> Result<Vec<VkImage>> {
self.device self.device.swapchain_images(self.swapchain)
.swapchain_images(*self.swapchain.lock().unwrap())
} }
pub fn wrap_images( pub fn wrap_images(
&self, &self,
images: &[VkImage], images: &[VkImage],
queue: &Mutex<Queue<'a>>, queue: &'a Mutex<Queue<'a>>,
assume_layout: bool, assume_layout: bool,
) -> Result<Vec<Image<'a>>> { ) -> Result<Vec<Image<'a>>> {
let format = self.format(); let format = self.format();