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>(
self,
device: &Device,
device: &'a Device,
recorder: &mut CommandBufferRecorder<'_>,
) -> Result<AccelerationStructure<'a>> {
let build_flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR
@ -390,7 +390,7 @@ impl<'a> AccelerationStructure<'a> {
#[inline]
fn create_scratch_buffer(
device: &Device,
device: &'a Device,
size: VkDeviceSize,
alignment: VkDeviceSize,
) -> Result<Buffer<'a, RawBuffer>> {
@ -413,7 +413,7 @@ impl<'a> Drop for AccelerationStructure<'a> {
}
impl_vk_handle!(
AccelerationStructure,
AccelerationStructure<'a>,
VkAccelerationStructureKHR,
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> {
fn vk_handle(&self) -> VkDeviceMemory {

View file

@ -7,10 +7,7 @@ use crate::prelude::*;
use anyhow::Result;
use std::any::Any;
use std::sync::{
atomic::{AtomicUsize, Ordering::SeqCst},
Mutex, MutexGuard,
};
use std::sync::{Mutex, MutexGuard};
pub struct QueryEnable {
pub query_flags: VkQueryControlFlagBits,
@ -33,7 +30,7 @@ impl CommandBufferBuilder {
self,
device: &'a Device,
queue: &'a Mutex<Queue<'a>>,
) -> Result<Arc<CommandBuffer<'a>>> {
) -> Result<CommandBuffer<'a>> {
let command_pool = self
.pool_builder
.set_queue_family_index(
@ -49,15 +46,15 @@ impl CommandBufferBuilder {
let command_buffer = device.allocate_command_buffers(&command_buffer_ci)?[0];
Ok(Arc::new(CommandBuffer {
Ok(CommandBuffer {
device,
pool: command_pool,
buffer: command_buffer,
calls: Arc::new(AtomicUsize::new(0)),
calls: 0,
stored_handles: Mutex::new(Vec::new()),
}))
})
}
}
@ -68,7 +65,7 @@ pub struct CommandBuffer<'a> {
buffer: VkCommandBuffer,
calls: Arc<AtomicUsize>,
calls: usize,
stored_handles: Mutex<Vec<&'a (dyn Any + Send + Sync)>>,
}
@ -76,14 +73,14 @@ pub struct CommandBuffer<'a> {
pub struct CommandBufferRecorder<'a> {
device: &'a Device,
sub_pass: u32,
pipeline: Option<Arc<Pipeline>>,
pipeline: Option<&'a Pipeline<'a>>,
calls: Arc<AtomicUsize>,
calls: &'a mut usize,
buffer: VkCommandBuffer,
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> {
pub fn new_primary() -> CommandBufferBuilder {
@ -105,23 +102,26 @@ impl<'a> CommandBuffer<'a> {
}
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)?;
let mut handles_lock = self.stored_handles.lock().unwrap();
handles_lock.clear();
self.calls.store(0, SeqCst);
self.calls = 0;
Ok(CommandBufferRecorder {
device: self.device.clone(),
sub_pass: 0,
pipeline: None,
calls: self.calls.clone(),
calls: &mut self.calls,
buffer: self.buffer,
handles_lock,
})
@ -161,9 +161,9 @@ impl<'a> CommandBuffer<'a> {
}
pub fn inheritance_info(
render_pass: Option<&Arc<RenderPass>>,
render_pass: Option<&RenderPass<'a>>,
sub_pass: Option<u32>,
framebuffer: Option<&Arc<Framebuffer>>,
framebuffer: Option<&Framebuffer<'a>>,
query_enable: Option<QueryEnable>,
) -> VkCommandBufferInheritanceInfo {
let mut info = VkCommandBufferInheritanceInfo::new(
@ -196,7 +196,7 @@ impl<'a> CommandBufferRecorder<'a> {
buffer_memory_barriers: &[VkBufferMemoryBarrier],
image_memory_barriers: &[VkImageMemoryBarrier],
) {
self.calls.fetch_add(1, SeqCst);
*self.calls += 1;
self.device.cmd_pipeline_barrier(
self.buffer,
@ -228,13 +228,13 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn buffer_barrier<T: ReprC + Send + Sync + 'static>(
&mut self,
buffer: &Arc<Buffer<T>>,
buffer: &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>,
) {
self.handles_lock.push(buffer.clone());
self.handles_lock.push(buffer);
self.pipeline_barrier(
src_stage,
@ -256,7 +256,7 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn image_barrier(
&mut self,
image: &Arc<Image>,
image: &Image<'a>,
old_image_layout: VkImageLayout,
src_stage: impl Into<VkPipelineStageFlagBits>,
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 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(
src_stage,
@ -290,14 +290,14 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn image_barrier_auto_stage(
&mut self,
image: &Arc<Image>,
image: &Image<'a>,
old_image_layout: VkImageLayout,
new_image_layout: VkImageLayout,
) {
let src_access_mask = Image::src_layout_to_access(old_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(
CommandBuffer::access_to_stage(src_access_mask),
@ -333,8 +333,8 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn begin_render_pass_full(
&mut self,
render_pass: &Arc<RenderPass>,
framebuffer: &Arc<Framebuffer>,
render_pass: &RenderPass<'a>,
framebuffer: &Framebuffer<'a>,
clear_values: &[VkClearValue],
subpass_contents: VkSubpassContents,
) {
@ -369,8 +369,8 @@ impl<'a> CommandBufferRecorder<'a> {
self.device.cmd_end_render_pass(self.buffer);
}
pub fn bind_pipeline(&mut self, pipeline: &Arc<Pipeline>) -> Result<()> {
self.handles_lock.push(pipeline.clone());
pub fn bind_pipeline(&mut self, pipeline: &Pipeline<'a>) -> Result<()> {
self.handles_lock.push(pipeline);
match pipeline.pipeline_type() {
PipelineType::Graphics => {
@ -400,7 +400,7 @@ impl<'a> CommandBufferRecorder<'a> {
}
pub fn execute_commands(&self, command_buffers: &[&impl VkHandle<VkCommandBuffer>]) {
self.calls.fetch_add(1, SeqCst);
*self.calls += 1;
let buffers: Vec<VkCommandBuffer> =
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());
}
pub fn bind_descriptor_sets_minimal(&mut self, descriptor_sets: &[&Arc<DescriptorSet>]) {
self.calls.fetch_add(1, SeqCst);
pub fn bind_descriptor_sets_minimal(&mut self, descriptor_sets: &[&DescriptorSet<'a>]) {
*self.calls += 1;
let (pipeline_bind_point, vk_layout) = {
let pipeline = match &self.pipeline {
@ -429,7 +429,7 @@ impl<'a> CommandBufferRecorder<'a> {
let vk_descriptor_sets: Vec<VkDescriptorSet> = descriptor_sets
.iter()
.map(|ds: &&Arc<DescriptorSet>| {
.map(|ds: &&DescriptorSet<'a>| {
self.handles_lock.push((*ds).clone());
ds.vk_handle()
@ -446,13 +446,10 @@ impl<'a> CommandBufferRecorder<'a> {
);
}
pub fn bind_vertex_buffer<T: ReprC + Send + Sync + 'static>(
&mut self,
buffer: &Arc<Buffer<T>>,
) {
self.calls.fetch_add(1, SeqCst);
pub fn bind_vertex_buffer<T: ReprC + Send + Sync + 'static>(&mut self, buffer: &Buffer<'a, T>) {
*self.calls += 1;
self.handles_lock.push(buffer.clone());
self.handles_lock.push(buffer);
self.device
.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>(
&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
.iter()
.map(|b: &&Arc<Buffer<T>>| {
.map(|b: &&Buffer<'a, T>| {
self.handles_lock.push((*b).clone());
b.vk_handle()
@ -485,13 +482,13 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn bind_index_buffer<T: ReprC + Send + Sync + 'static>(
&mut self,
buffer: &Arc<Buffer<T>>,
buffer: &Buffer<'a, T>,
offset: VkDeviceSize,
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
.cmd_bind_index_buffer(self.buffer, buffer.vk_handle(), offset, index_type);
@ -512,7 +509,7 @@ impl<'a> CommandBufferRecorder<'a> {
first_vertex: u32,
first_instance: u32,
) {
self.calls.fetch_add(1, SeqCst);
*self.calls += 1;
self.device.cmd_draw(
self.buffer,
@ -524,7 +521,7 @@ impl<'a> CommandBufferRecorder<'a> {
}
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);
}
@ -537,7 +534,7 @@ impl<'a> CommandBufferRecorder<'a> {
vertex_offset: i32,
first_instance: u32,
) {
self.calls.fetch_add(1, SeqCst);
*self.calls += 1;
self.device.cmd_draw_indexed(
self.buffer,
@ -550,14 +547,14 @@ impl<'a> CommandBufferRecorder<'a> {
}
pub fn draw_indexed_complete_single_instance(&self, index_count: u32) {
self.calls.fetch_add(1, SeqCst);
*self.calls += 1;
self.device
.cmd_draw_indexed(self.buffer, index_count, 1, 0, 0, 0);
}
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 {
Some(pipeline) => pipeline,
@ -602,11 +599,11 @@ impl<'a> CommandBufferRecorder<'a> {
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 dst_access = Image::dst_layout_to_access(new_image_layout);
self.handles_lock.push(image.clone());
self.handles_lock.push(image);
self.pipeline_barrier(
CommandBuffer::access_to_stage(src_access),
@ -667,7 +664,7 @@ impl<'a> CommandBufferRecorder<'a> {
}
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);
}
@ -678,14 +675,14 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn copy_buffer<T: ReprC + Send + Sync + 'static, U: ReprC + Send + Sync + 'static>(
&mut self,
src_buffer: &Arc<Buffer<T>>,
dst_buffer: &Arc<Buffer<U>>,
src_buffer: &Buffer<'a, T>,
dst_buffer: &Buffer<'a, U>,
regions: &[VkBufferCopy],
) {
self.calls.fetch_add(1, SeqCst);
*self.calls += 1;
self.handles_lock.push(src_buffer.clone());
self.handles_lock.push(dst_buffer.clone());
self.handles_lock.push(src_buffer);
self.handles_lock.push(dst_buffer);
self.device.cmd_copy_buffer(
self.buffer,
@ -697,16 +694,16 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn copy_image(
&mut self,
src_image: &Arc<Image>,
dst_image: &Arc<Image>,
src_image: &Image<'a>,
dst_image: &Image<'a>,
src_layout: VkImageLayout,
dst_layout: VkImageLayout,
regions: &[VkImageCopy],
) {
self.calls.fetch_add(1, SeqCst);
*self.calls += 1;
self.handles_lock.push(src_image.clone());
self.handles_lock.push(dst_image.clone());
self.handles_lock.push(src_image);
self.handles_lock.push(dst_image);
self.device.cmd_copy_image(
self.buffer,
@ -720,12 +717,12 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn blit_complete(
&mut self,
src_image: &Arc<Image>,
dst_image: &Arc<Image>,
src_image: &Image<'a>,
dst_image: &Image<'a>,
filter: VkFilter,
) {
self.handles_lock.push(src_image.clone());
self.handles_lock.push(dst_image.clone());
self.handles_lock.push(src_image);
self.handles_lock.push(dst_image);
let image_blit = VkImageBlit {
srcSubresource: src_image.full_resource_layers(),
@ -767,7 +764,7 @@ impl<'a> CommandBufferRecorder<'a> {
regions: &[VkImageBlit],
filter: VkFilter,
) {
self.calls.fetch_add(1, SeqCst);
*self.calls += 1;
self.handles_lock.push(src_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>(
&mut self,
src_buffer: &Arc<Buffer<'a, T>>,
src_buffer: &Buffer<'a, T>,
dst_image: &Image<'a>,
image_layout: VkImageLayout,
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.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>(
&mut self,
src_image: &Arc<Image>,
src_image: &Image<'a>,
image_layout: VkImageLayout,
dst_buffer: &Arc<Buffer<T>>,
dst_buffer: &Buffer<'a, T>,
regions: &[VkBufferImageCopy],
) {
self.calls.fetch_add(1, SeqCst);
*self.calls += 1;
self.handles_lock.push(src_image.clone());
self.handles_lock.push(dst_buffer.clone());
self.handles_lock.push(src_image);
self.handles_lock.push(dst_buffer);
self.device.cmd_copy_image_to_buffer(
self.buffer,
@ -833,10 +830,10 @@ impl<'a> CommandBufferRecorder<'a> {
unimplemented!();
}
pub fn clear_color_image(&mut self, image: &Arc<Image>, clear_color: VkClearColorValue) {
self.calls.fetch_add(1, SeqCst);
pub fn clear_color_image(&mut self, image: &Image<'a>, clear_color: VkClearColorValue) {
*self.calls += 1;
self.handles_lock.push(image.clone());
self.handles_lock.push(image);
self.device.cmd_clear_color_image(
self.buffer,
@ -857,14 +854,14 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn resolve_image(
&mut self,
src_image: &Arc<Image>,
dst_image: &Arc<Image>,
src_image: &Image<'a>,
dst_image: &Image<'a>,
regions: &[VkImageResolve],
) {
self.calls.fetch_add(1, SeqCst);
*self.calls += 1;
self.handles_lock.push(src_image.clone());
self.handles_lock.push(dst_image.clone());
self.handles_lock.push(src_image);
self.handles_lock.push(dst_image);
self.device.cmd_resolve_image(
self.buffer,
@ -902,13 +899,13 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn write_timestamp(
&mut self,
query_pool: &Arc<QueryPool>,
query_pool: &QueryPool,
query: u32,
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
.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(
&mut self,
infos: &[VkAccelerationStructureBuildGeometryInfoKHR],
indirect_buffers: &[Arc<Buffer<impl ReprC + Send + Sync + 'static>>],
indirect_buffers: &[Buffer<'a, impl ReprC + Send + Sync + 'static>],
indirect_strides: &[u32],
max_primitive_counts: &[&u32],
) {
let mut device_addresses: Vec<VkDeviceAddress> = Vec::with_capacity(indirect_buffers.len());
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());
}
@ -954,12 +951,12 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn copy_acceleration_structure(
&mut self,
src: &Arc<AccelerationStructure>,
dst: &Arc<AccelerationStructure>,
src: &AccelerationStructure<'a>,
dst: &AccelerationStructure<'a>,
mode: VkCopyAccelerationStructureModeKHR,
) {
self.handles_lock.push(src.clone());
self.handles_lock.push(dst.clone());
self.handles_lock.push(src);
self.handles_lock.push(dst);
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(
&mut self,
src: &Arc<AccelerationStructure>,
src: &AccelerationStructure<'a>,
dst: VkDeviceOrHostAddressKHR,
mode: VkCopyAccelerationStructureModeKHR,
) {
self.handles_lock.push(src.clone());
self.handles_lock.push(src);
let info = VkCopyAccelerationStructureToMemoryInfoKHR::new(src.vk_handle(), dst, mode);
@ -984,10 +981,10 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn copy_memory_to_acceleration_structure(
&mut self,
src: VkDeviceOrHostAddressConstKHR,
dst: &Arc<AccelerationStructure>,
dst: &AccelerationStructure<'a>,
mode: VkCopyAccelerationStructureModeKHR,
) {
self.handles_lock.push(dst.clone());
self.handles_lock.push(dst);
let info = VkCopyMemoryToAccelerationStructureInfoKHR::new(src, dst.vk_handle(), mode);
@ -997,10 +994,10 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn trace_rays_indirect(
&mut self,
sbt: ShaderBindingTable,
buffer: Arc<Buffer<impl ReprC + Send + Sync + 'static>>,
sbt: ShaderBindingTable<'a>,
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.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.buffer,
sbt.raygen_shader_binding_table(),
@ -1027,12 +1024,12 @@ impl<'a> CommandBufferRecorder<'a> {
pub fn write_acceleration_structure_properties(
&mut self,
acceleration_structures: &[&Arc<AccelerationStructure>],
acceleration_structures: &[&AccelerationStructure<'a>],
query_type: VkQueryType,
query_pool: &Arc<QueryPool>,
query_pool: &QueryPool,
first_query: u32,
) {
self.handles_lock.push(query_pool.clone());
self.handles_lock.push(query_pool);
let as_handles: Vec<VkAccelerationStructureKHR> = acceleration_structures
.iter()
@ -1052,13 +1049,13 @@ impl<'a> CommandBufferRecorder<'a> {
}
}
impl VulkanDevice for CommandBuffer {
fn device(&self) -> &Arc<Device> {
impl<'a> VulkanDevice for CommandBuffer<'a> {
fn device(&self) -> &Device {
&self.device
}
}
impl Drop for CommandBuffer {
impl<'a> Drop for CommandBuffer<'a> {
fn drop(&mut self) {
self.device
.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()
}
}
// ==========================================================================================
// ======================================== 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 std::sync::Arc;
pub(crate) struct CommandPoolBuilder {
flags: VkCommandPoolCreateFlagBits,
queue_family_index: u32,
@ -22,15 +20,15 @@ impl CommandPoolBuilder {
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 = device.create_command_pool(&command_pool_ci)?;
Ok(Arc::new(CommandPool {
Ok(CommandPool {
device,
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> {
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> {
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> {
fn vk_handle(&self) -> VkDescriptorSetLayout {

View file

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

View file

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

View file

@ -2,10 +2,8 @@ use crate::prelude::*;
use anyhow::Result;
use std::sync::Arc;
pub struct FramebufferBuilder<'a> {
render_pass: Option<&'a Arc<RenderPass>>,
render_pass: Option<&'a RenderPass<'a>>,
attachments: Vec<&'a Image<'a>>,
width: u32,
height: u32,
@ -13,7 +11,7 @@ pub struct 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
@ -43,7 +41,7 @@ impl<'a> FramebufferBuilder<'a> {
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() {
panic!("no attachments added!");
}
@ -93,7 +91,7 @@ impl<'a> FramebufferBuilder<'a> {
#[derive(Debug)]
pub struct Framebuffer<'a> {
device: Arc<Device>,
device: &'a Device,
framebuffer: VkFramebuffer,
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> {
fn drop(&mut self) {

View file

@ -75,7 +75,7 @@ pub struct ImageBuilder<'a> {
view_type: VkImageViewType,
subresource_range: VkImageSubresourceRange,
sampler: Option<Sampler>,
sampler: Option<Arc<Sampler>>,
}
impl<'a> ImageBuilder<'a> {
@ -308,7 +308,7 @@ impl<'a> ImageBuilder<'a> {
self
}
pub fn attach_sampler(mut self, sampler: Sampler) -> Self {
pub fn attach_sampler(mut self, sampler: Arc<Sampler>) -> Self {
self.sampler = Some(sampler);
if let ImageBuilderInternalType::NewImage(ref mut info) = self.builder_type {
@ -384,10 +384,10 @@ impl<'a> ImageBuilder<'a> {
}
fn create_from_source(
device: &Device,
device: &'a Device,
queue: &Mutex<Queue<'a>>,
info: &ImageCreateInfo<'a>,
sampler: Option<Sampler>,
sampler: Option<Arc<Sampler>>,
mut view_ci: VkImageViewCreateInfo,
file_name: Option<AssetPath>,
) -> Result<Image<'a>> {
@ -426,7 +426,7 @@ impl<'a> ImageBuilder<'a> {
}
fn create_texture(
device: &Device,
device: &'a Device,
image_ci: &VkImageCreateInfo,
) -> Result<(VkImage, Memory<'a, RawBuffer>)> {
let image = Self::create_image(device, image_ci)?;
@ -439,7 +439,7 @@ impl<'a> ImageBuilder<'a> {
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.height, 0);
@ -447,7 +447,7 @@ impl<'a> ImageBuilder<'a> {
}
fn optimize_fill(
device: &Device,
device: &'a Device,
queue: &Mutex<Queue<'a>>,
data: &[RawBuffer],
image: &Image<'a>,
@ -487,7 +487,7 @@ pub struct Image<'a> {
// optional handles
_memory: Option<Memory<'a, RawBuffer>>,
sampler: Option<Sampler>,
sampler: Option<Arc<Sampler>>,
// image information
format: VkFormat,
@ -664,7 +664,7 @@ impl<'a> Image<'a> {
}
pub fn check_configuration(
device: &Device,
device: &'a Device,
tiling: VkImageTiling,
format: VkFormat,
usage: impl Into<VkImageUsageFlagBits>,
@ -697,7 +697,7 @@ impl<'a> Image<'a> {
self.format
}
pub fn sampler(&self) -> &Option<Sampler> {
pub fn sampler(&self) -> &Option<Arc<Sampler>> {
&self.sampler
}
@ -896,8 +896,8 @@ impl<'a> VulkanDevice for Image<'a> {
}
}
impl_vk_handle!(Image, VkImage, image);
impl_vk_handle!(Image, VkImageView, image_view);
impl_vk_handle!(Image<'a>, VkImage, image);
impl_vk_handle!(Image<'a>, VkImageView, image_view);
impl<'a> Drop for Image<'a> {
fn drop(&mut self) {
@ -911,7 +911,7 @@ impl<'a> Drop for Image<'a> {
fn into_layout<'a>(image: &Image<'a>, layout: VkImageLayout) -> Result<()> {
// 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
@ -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>(
image: &Image<'a>,
device: &Device,
device: &'a Device,
queue: &Mutex<Queue<'a>>,
buffer: &Buffer<'a, T>,
) -> Result<()>
@ -959,7 +959,7 @@ where
T: Copy,
{
// 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
@ -1045,13 +1045,13 @@ where
}
fn copy_images_to_imagearray<'a>(
device: &Device,
device: &'a Device,
queue: &Mutex<Queue<'a>>,
image_array: &Image<'a>,
images: &[Image<'a>],
) -> Result<()> {
// 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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,11 +2,7 @@ use crate::prelude::*;
use anyhow::Result;
use std::{
slice,
sync::{Arc, Mutex},
time::Duration,
};
use std::{slice, sync::Mutex, time::Duration};
pub struct QueueRequestInfo {
pub queue_create_info: VkDeviceQueueCreateInfo,
@ -23,9 +19,9 @@ pub struct Queue<'a> {
}
impl<'a> Queue<'a> {
pub fn create_presentable_request_info<'b>(
pub fn create_presentable_request_info(
physical_device: &PhysicalDevice,
surface: &Surface<'b>,
surface: &Surface<'a>,
queue_type: impl Into<VkQueueFlagBits>,
) -> Result<QueueRequestInfo> {
let index =
@ -93,11 +89,11 @@ impl<'a> Queue<'a> {
pub fn minimal_submit(
&self,
time_out: Duration,
command_buffers: &[Arc<CommandBuffer<'a>>],
command_buffers: &[&CommandBuffer<'a>],
) -> Result<()> {
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);
}
@ -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> {
fn find_presentable_queue_index(

View file

@ -1,15 +1,12 @@
use crate::prelude::*;
use anyhow::Result;
use std::sync::{
atomic::{AtomicU32, AtomicUsize, Ordering::SeqCst},
Arc,
};
use std::sync::atomic::{AtomicU32, AtomicUsize, Ordering::SeqCst};
pub mod sub_pass;
use sub_pass::{AttachmentInfo, AttachmentInfoUsage, SubPass};
pub struct RenderTargetBuilder<'a> {
old_render_target: Option<&'a RenderTarget<'a>>,
old_render_target: Option<RenderTarget<'a>>,
sub_passes: Vec<SubPass<'a>>,
}
@ -20,13 +17,13 @@ impl<'a> RenderTargetBuilder<'a> {
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
}
pub fn build(self, device: &Arc<Device>) -> Result<RenderTarget<'a>> {
pub fn build(self, device: &'a Device) -> Result<RenderTarget<'a>> {
#[cfg(debug_assertions)]
{
// 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 => {
// gather attachment descriptions
@ -164,7 +161,7 @@ impl<'a> RenderTargetBuilder<'a> {
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(
render_pass: &Arc<RenderPass>,
render_pass: &RenderPass<'a>,
sub_passes: &[SubPass<'a>],
) -> Result<Vec<Framebuffer<'a>>> {
let extent = sub_passes[0].extent();
@ -261,7 +258,7 @@ struct SubPassAttachmentReferences {
#[derive(Debug)]
pub struct RenderTarget<'a> {
render_pass: Arc<RenderPass>,
render_pass: RenderPass<'a>,
framebuffers: Vec<Framebuffer<'a>>,
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
}
@ -381,7 +378,7 @@ mod test {
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)
.set_prepared_targets(target_images, 0, [0.0, 0.0, 0.0, 0.0], false)
.build(&device)
.unwrap(),
)
@ -404,7 +401,7 @@ mod test {
false,
true,
))
.use_queue(queue.clone())
.use_queue(&queue)
.build(&device)
.unwrap(),
)
@ -414,7 +411,7 @@ mod test {
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, 0, [0.0, 0.0, 0.0, 0.0], false)
.build(&device)
.unwrap(),
)

View file

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

View file

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

View file

@ -78,7 +78,7 @@ impl SamplerBuilder {
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)
}
}

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> {
fn drop(&mut self) {

View file

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

View file

@ -2,8 +2,6 @@ use crate::prelude::*;
use anyhow::Result;
use std::sync::Arc;
const UNORM_FORMATS: [VkFormat; 2] = [VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM];
#[derive(Debug)]
@ -17,7 +15,7 @@ impl<'a> Surface<'a> {
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(
device.physical_device().vk_handle(),
self.surface,
@ -26,7 +24,7 @@ impl<'a> Surface<'a> {
pub fn format_colorspace(
&self,
device: &Arc<Device>,
device: &'a Device,
prefered_format: VkFormat,
) -> Result<(VkFormat, VkColorSpaceKHR)> {
let surface_formats = self
@ -58,7 +56,7 @@ impl<'a> Surface<'a> {
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
.physical_device_present_modes(device.physical_device().vk_handle(), self.surface)
}

View file

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