Compare commits

..

4 commits

Author SHA1 Message Date
hodasemi
913d25cd82 Refine more lifetimes 2024-03-29 08:43:44 +01:00
hodasemi
c9b4dfc164 Add more lifetime fixes 2024-03-29 07:01:22 +01:00
hodasemi
5b42c076b3 Second step 2024-03-28 21:30:06 +01:00
hodasemi
39c4fa2342 First try to convert to lifetimes 2024-03-28 18:28:52 +01:00
41 changed files with 985 additions and 1516 deletions

View file

@ -5,5 +5,4 @@ members = [
"vulkan-rs", "vulkan-rs",
"vulkan-sys", "vulkan-sys",
"library_loader", "library_loader",
] ]
resolver = "2"

View file

@ -7,4 +7,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
serde = { version = "1.0.203", features = ["derive"] } serde = { version = "1.0.197", features = ["derive"] }

View file

@ -9,7 +9,7 @@ build = "build.rs"
[dependencies] [dependencies]
vulkan-sys = { path = "../vulkan-sys" } vulkan-sys = { path = "../vulkan-sys" }
anyhow = { version = "1.0.86", features = ["backtrace"] } anyhow = { version = "1.0.81", features = ["backtrace"] }
[build-dependencies] [build-dependencies]
cc = "1.0.104" cc = "1.0.90"

View file

@ -5,9 +5,9 @@ authors = ["hodasemi <superschneider@t-online.de>"]
edition = "2021" edition = "2021"
[dependencies] [dependencies]
image = "0.25.1" image = "0.25.0"
vulkan-sys = { path = "../vulkan-sys" } vulkan-sys = { path = "../vulkan-sys" }
vma-rs = { path = "../vma-rs" } vma-rs = { path = "../vma-rs" }
anyhow = { version = "1.0.86", features = ["backtrace"] } anyhow = { version = "1.0.81", features = ["backtrace"] }
assetpath = { path = "../assetpath" } assetpath = { path = "../assetpath" }
utilities = { git = "https://gavania.de/hodasemi/utilities.git" } utilities = { git = "https://gavania.de/hodasemi/utilities.git" }

View file

@ -37,9 +37,9 @@ pub struct AccelerationStructureBuilder {
} }
impl AccelerationStructureBuilder { impl AccelerationStructureBuilder {
pub fn add_instance( pub fn add_instance<'device>(
mut self, mut self,
blas: &Arc<AccelerationStructure>, blas: &AccelerationStructure<'device>,
transform: Option<Matrix4<f32>>, transform: Option<Matrix4<f32>>,
instance_flags: impl Into<VkGeometryInstanceFlagBitsKHR>, instance_flags: impl Into<VkGeometryInstanceFlagBitsKHR>,
) -> Self { ) -> Self {
@ -70,10 +70,10 @@ impl AccelerationStructureBuilder {
self self
} }
pub fn add_vertices<T: ReprC + Send + Sync + 'static>( pub fn add_vertices<'a, T: ReprC + Send + Sync + 'static>(
mut self, mut self,
vertex_buffer: &Arc<Buffer<T>>, vertex_buffer: &Arc<Buffer<'a, T>>,
transform: Option<Arc<Buffer<Transform>>>, transform: Option<Arc<Buffer<'a, Transform>>>,
flags: impl Into<VkGeometryFlagBitsKHR>, flags: impl Into<VkGeometryFlagBitsKHR>,
) -> Self { ) -> Self {
match &mut self.data { match &mut self.data {
@ -122,11 +122,11 @@ impl AccelerationStructureBuilder {
self self
} }
pub fn build( pub fn build<'device, 'pipeline, 'cbuffer>(
self, self,
device: Arc<Device>, device: &'device Device,
recorder: &mut CommandBufferRecorder<'_>, recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
) -> Result<Arc<AccelerationStructure>> { ) -> Result<AccelerationStructure<'device>> {
let build_flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR let build_flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR
| VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR; | VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR;
@ -140,7 +140,7 @@ impl AccelerationStructureBuilder {
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
) )
.set_memory_usage(MemoryUsage::CpuToGpu) .set_memory_usage(MemoryUsage::CpuToGpu)
.build(device.clone())?; .build(device)?;
let device_address: VkDeviceOrHostAddressConstKHR = let device_address: VkDeviceOrHostAddressConstKHR =
instances_buffer.device_address().into(); instances_buffer.device_address().into();
@ -239,8 +239,8 @@ impl AccelerationStructureBuilder {
} }
}; };
let acceleration_structure = Arc::new(AccelerationStructure { let acceleration_structure = AccelerationStructure {
device: device.clone(), device,
acceleration_structure, acceleration_structure,
@ -258,7 +258,7 @@ impl AccelerationStructureBuilder {
generation_data, generation_data,
build_flags, build_flags,
}); };
acceleration_structure.generate( acceleration_structure.generate(
recorder, recorder,
@ -270,21 +270,21 @@ impl AccelerationStructureBuilder {
} }
} }
pub struct AccelerationStructure { pub struct AccelerationStructure<'device> {
device: Arc<Device>, device: &'device Device,
acceleration_structure: VkAccelerationStructureKHR, acceleration_structure: VkAccelerationStructureKHR,
result_buffer: Arc<Buffer<RawBuffer>>, result_buffer: Buffer<'device, RawBuffer>,
scratch_buffer: Mutex<Arc<Buffer<RawBuffer>>>, scratch_buffer: Mutex<Buffer<'device, RawBuffer>>,
update_scratch_buffer_size: VkDeviceSize, update_scratch_buffer_size: VkDeviceSize,
generation_data: AccelerationStructureGenerationData, generation_data: AccelerationStructureGenerationData<'device>,
build_flags: VkBuildAccelerationStructureFlagBitsKHR, build_flags: VkBuildAccelerationStructureFlagBitsKHR,
} }
impl AccelerationStructure { impl<'device> AccelerationStructure<'device> {
pub fn bottom_level() -> AccelerationStructureBuilder { pub fn bottom_level() -> AccelerationStructureBuilder {
AccelerationStructureBuilder { AccelerationStructureBuilder {
flags: 0.into(), flags: 0.into(),
@ -303,7 +303,7 @@ impl AccelerationStructure {
} }
} }
pub fn result_buffer(&self) -> &Arc<Buffer<RawBuffer>> { pub fn result_buffer(&self) -> &Buffer<'device, RawBuffer> {
&self.result_buffer &self.result_buffer
} }
@ -313,7 +313,10 @@ impl AccelerationStructure {
) )
} }
pub fn update(&self, buffer_recorder: &mut CommandBufferRecorder<'_>) -> Result<()> { pub fn update<'pipeline, 'cbuffer>(
&self,
buffer_recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
) -> Result<()> {
*self.scratch_buffer.lock().unwrap() = Self::create_scratch_buffer( *self.scratch_buffer.lock().unwrap() = Self::create_scratch_buffer(
&self.device, &self.device,
self.update_scratch_buffer_size, self.update_scratch_buffer_size,
@ -330,9 +333,9 @@ impl AccelerationStructure {
) )
} }
fn generate( fn generate<'pipeline, 'cbuffer>(
&self, &self,
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
src: VkAccelerationStructureKHR, src: VkAccelerationStructureKHR,
mode: VkBuildAccelerationStructureModeKHR, mode: VkBuildAccelerationStructureModeKHR,
) -> Result<()> { ) -> Result<()> {
@ -390,10 +393,10 @@ impl AccelerationStructure {
#[inline] #[inline]
fn create_scratch_buffer( fn create_scratch_buffer(
device: &Arc<Device>, device: &'device Device,
size: VkDeviceSize, size: VkDeviceSize,
alignment: VkDeviceSize, alignment: VkDeviceSize,
) -> Result<Arc<Buffer<RawBuffer>>> { ) -> Result<Buffer<'device, RawBuffer>> {
Buffer::builder() Buffer::builder()
.set_usage( .set_usage(
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
@ -401,11 +404,11 @@ impl AccelerationStructure {
.set_memory_usage(MemoryUsage::GpuOnly) .set_memory_usage(MemoryUsage::GpuOnly)
.set_size(size) .set_size(size)
.force_alignment(alignment) .force_alignment(alignment)
.build(device.clone()) .build(device)
} }
} }
impl Drop for AccelerationStructure { impl<'a> Drop for AccelerationStructure<'a> {
fn drop(&mut self) { fn drop(&mut self) {
self.device self.device
.destroy_acceleration_structure(self.acceleration_structure, None); .destroy_acceleration_structure(self.acceleration_structure, None);
@ -413,16 +416,16 @@ impl Drop for AccelerationStructure {
} }
impl_vk_handle!( impl_vk_handle!(
AccelerationStructure, AccelerationStructure<'a>,
VkAccelerationStructureKHR, VkAccelerationStructureKHR,
acceleration_structure acceleration_structure
); );
enum AccelerationStructureGenerationData { enum AccelerationStructureGenerationData<'device> {
TopLevel( TopLevel(
Vec<VkAccelerationStructureInstanceKHR>, Vec<VkAccelerationStructureInstanceKHR>,
VkAccelerationStructureGeometryKHR, VkAccelerationStructureGeometryKHR,
Arc<Buffer<VkAccelerationStructureInstanceKHR>>, Buffer<'device, VkAccelerationStructureInstanceKHR>,
), ),
BottomLevel( BottomLevel(
Vec<VkAccelerationStructureGeometryKHR>, Vec<VkAccelerationStructureGeometryKHR>,
@ -430,26 +433,26 @@ enum AccelerationStructureGenerationData {
), ),
} }
impl impl<'device>
From<( From<(
Vec<VkAccelerationStructureInstanceKHR>, Vec<VkAccelerationStructureInstanceKHR>,
VkAccelerationStructureGeometryKHR, VkAccelerationStructureGeometryKHR,
Arc<Buffer<VkAccelerationStructureInstanceKHR>>, Buffer<'device, VkAccelerationStructureInstanceKHR>,
)> for AccelerationStructureGenerationData )> for AccelerationStructureGenerationData<'device>
{ {
fn from( fn from(
(instances, geometry, buffer): ( (instances, geometry, buffer): (
Vec<VkAccelerationStructureInstanceKHR>, Vec<VkAccelerationStructureInstanceKHR>,
VkAccelerationStructureGeometryKHR, VkAccelerationStructureGeometryKHR,
Arc<Buffer<VkAccelerationStructureInstanceKHR>>, Buffer<'device, VkAccelerationStructureInstanceKHR>,
), ),
) -> Self { ) -> Self {
Self::TopLevel(instances, geometry, buffer) Self::TopLevel(instances, geometry, buffer)
} }
} }
impl From<(Vec<VkAccelerationStructureGeometryKHR>, Vec<u32>)> impl<'device> From<(Vec<VkAccelerationStructureGeometryKHR>, Vec<u32>)>
for AccelerationStructureGenerationData for AccelerationStructureGenerationData<'device>
{ {
fn from( fn from(
(geometries, primitive_counts): (Vec<VkAccelerationStructureGeometryKHR>, Vec<u32>), (geometries, primitive_counts): (Vec<VkAccelerationStructureGeometryKHR>, Vec<u32>),

View file

@ -4,7 +4,6 @@ use anyhow::Result;
use std; use std;
use std::mem; use std::mem;
use std::sync::Arc;
pub struct BufferBuilder<'a, T: ReprC> { pub struct BufferBuilder<'a, T: ReprC> {
flags: VkBufferCreateFlagBits, flags: VkBufferCreateFlagBits,
@ -62,7 +61,7 @@ impl<'a, T: ReprC> BufferBuilder<'a, T> {
} }
impl<'a, T: ReprC + Clone + Send + Sync + 'static> BufferBuilder<'a, T> { impl<'a, T: ReprC + Clone + Send + Sync + 'static> BufferBuilder<'a, T> {
pub fn build(self, device: Arc<Device>) -> Result<Arc<Buffer<T>>> { pub fn build<'b>(self, device: &'b Device) -> Result<Buffer<'b, T>> {
let size = match self.data { let size = match self.data {
Some(data) => data.len() as VkDeviceSize, Some(data) => data.len() as VkDeviceSize,
None => self.size, None => self.size,
@ -90,18 +89,18 @@ impl<'a, T: ReprC + Clone + Send + Sync + 'static> BufferBuilder<'a, T> {
memory_requirements.alignment = alignment; memory_requirements.alignment = alignment;
Memory::forced_requirements( Memory::forced_requirements(
&device, device,
memory_requirements, memory_requirements,
buffer, buffer,
MemoryUsage::into_vma(self.memory_usage), MemoryUsage::into_vma(self.memory_usage),
)? )?
} }
None => { None => {
Memory::buffer_memory(&device, buffer, MemoryUsage::into_vma(self.memory_usage))? Memory::buffer_memory(device, buffer, MemoryUsage::into_vma(self.memory_usage))?
} }
}; };
let buffer = Arc::new(Buffer { let buffer = Buffer {
device, device,
buffer, buffer,
memory, memory,
@ -111,7 +110,7 @@ impl<'a, T: ReprC + Clone + Send + Sync + 'static> BufferBuilder<'a, T> {
_sharing_mode: self.sharing_mode, _sharing_mode: self.sharing_mode,
size, size,
}); };
if let Some(data) = self.data { if let Some(data) = self.data {
buffer.fill(data)?; buffer.fill(data)?;
@ -122,11 +121,11 @@ impl<'a, T: ReprC + Clone + Send + Sync + 'static> BufferBuilder<'a, T> {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Buffer<T: ReprC> { pub struct Buffer<'device, T: ReprC> {
device: Arc<Device>, device: &'device Device,
buffer: VkBuffer, buffer: VkBuffer,
memory: Arc<Memory<T>>, memory: Memory<'device, T>,
_usage: VkBufferUsageFlagBits, _usage: VkBufferUsageFlagBits,
@ -134,7 +133,7 @@ pub struct Buffer<T: ReprC> {
size: VkDeviceSize, size: VkDeviceSize,
} }
impl<T: ReprC + Clone + Send + Sync + 'static> Buffer<T> { impl<'device, T: ReprC + Clone + Send + Sync + 'static> Buffer<'device, T> {
pub fn fill(&self, data: &[T]) -> Result<()> { pub fn fill(&self, data: &[T]) -> Result<()> {
let mut buffer_map = self.map(data.len() as VkDeviceSize)?; let mut buffer_map = self.map(data.len() as VkDeviceSize)?;
@ -151,20 +150,20 @@ impl<T: ReprC + Clone + Send + Sync + 'static> Buffer<T> {
self.memory.map(self.size) self.memory.map(self.size)
} }
pub fn into_device_local( pub fn into_device_local<'pipeline, 'cbuffer>(
self: &Arc<Buffer<T>>, &self,
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
access_mask: impl Into<VkAccessFlagBits>, access_mask: impl Into<VkAccessFlagBits>,
stage: impl Into<VkPipelineStageFlagBits>, stage: impl Into<VkPipelineStageFlagBits>,
usage: impl Into<VkBufferUsageFlagBits>, usage: impl Into<VkBufferUsageFlagBits>,
) -> Result<Arc<Buffer<T>>> { ) -> Result<Buffer<'device, T>> {
let new_usage = usage.into() | VK_BUFFER_USAGE_TRANSFER_DST_BIT; let new_usage = usage.into() | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
let device_local_buffer = Buffer::builder() let device_local_buffer = Buffer::builder()
.set_memory_usage(MemoryUsage::GpuOnly) .set_memory_usage(MemoryUsage::GpuOnly)
.set_usage(new_usage) .set_usage(new_usage)
.set_size(self.size) .set_size(self.size)
.build(self.device.clone())?; .build(self.device)?;
// copy complete buffer // copy complete buffer
buffer_recorder.copy_buffer( buffer_recorder.copy_buffer(
@ -190,8 +189,8 @@ impl<T: ReprC + Clone + Send + Sync + 'static> Buffer<T> {
} }
} }
impl<T: ReprC> Buffer<T> { impl<'a, T: ReprC> Buffer<'a, T> {
pub fn builder<'a>() -> BufferBuilder<'a, T> { pub fn builder() -> BufferBuilder<'a, T> {
BufferBuilder { BufferBuilder {
flags: 0u32.into(), flags: 0u32.into(),
usage: 0u32.into(), usage: 0u32.into(),
@ -217,72 +216,28 @@ impl<T: ReprC> Buffer<T> {
} }
} }
impl<T: ReprC> VulkanDevice for Buffer<T> { impl<'a, T: ReprC> VulkanDevice for Buffer<'a, T> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle_t!(Buffer[ReprC], VkBuffer, buffer); impl_vk_handle_t!(Buffer[ReprC]<'b>, VkBuffer, buffer);
impl<T: ReprC> VkHandle<VkDeviceMemory> for Buffer<T> { impl<'a, T: ReprC> VkHandle<VkDeviceMemory> for Buffer<'a, T> {
fn vk_handle(&self) -> VkDeviceMemory { fn vk_handle(&self) -> VkDeviceMemory {
self.memory.vk_handle() self.memory.vk_handle()
} }
} }
impl<'a, T: ReprC> VkHandle<VkDeviceMemory> for &'a Buffer<T> { impl<'a, T: ReprC> VkHandle<VkDeviceMemory> for &'a Buffer<'a, T> {
fn vk_handle(&self) -> VkDeviceMemory { fn vk_handle(&self) -> VkDeviceMemory {
self.memory.vk_handle() self.memory.vk_handle()
} }
} }
impl<T: ReprC> VkHandle<VkDeviceMemory> for Arc<Buffer<T>> { impl<'a, T: ReprC> Drop for Buffer<'a, T> {
fn vk_handle(&self) -> VkDeviceMemory {
self.memory.vk_handle()
}
}
impl<'a, T: ReprC> VkHandle<VkDeviceMemory> for &'a Arc<Buffer<T>> {
fn vk_handle(&self) -> VkDeviceMemory {
self.memory.vk_handle()
}
}
impl<T: ReprC> Drop for Buffer<T> {
fn drop(&mut self) { fn drop(&mut self) {
self.device.destroy_buffer(self.buffer); self.device.destroy_buffer(self.buffer);
} }
} }
// use crate::{ffi::*, handle_ffi_result};
impl<T: ReprC> FFIBufferTrait for Buffer<T> {
fn byte_size(&self) -> VkDeviceSize {
self.byte_size()
}
}
pub trait FFIBufferTrait {
fn byte_size(&self) -> VkDeviceSize;
}
pub struct FFIBuffer {
trait_obj: Box<dyn FFIBufferTrait>,
}
impl FFIBuffer {
fn byte_size(&self) -> VkDeviceSize {
self.trait_obj.byte_size()
}
}
#[no_mangle]
pub extern "C" fn create_buffer(_device: *const Device) -> *const FFIBuffer {
todo!()
}
#[no_mangle]
pub extern "C" fn byte_size(buffer: *const FFIBuffer) -> VkDeviceSize {
unsafe { &*buffer }.byte_size()
}

View file

@ -6,11 +6,7 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::any::Any; use std::sync::Mutex;
use std::sync::{
atomic::{AtomicUsize, Ordering::SeqCst},
Arc, Mutex, MutexGuard,
};
pub struct QueryEnable { pub struct QueryEnable {
pub query_flags: VkQueryControlFlagBits, pub query_flags: VkQueryControlFlagBits,
@ -29,11 +25,11 @@ impl CommandBufferBuilder {
self self
} }
pub fn build( pub fn build<'a>(
self, self,
device: Arc<Device>, device: &'a Device,
queue: Arc<Mutex<Queue>>, queue: &'a Mutex<Queue<'a>>,
) -> Result<Arc<CommandBuffer>> { ) -> Result<CommandBuffer<'a>> {
let command_pool = self let command_pool = self
.pool_builder .pool_builder
.set_queue_family_index( .set_queue_family_index(
@ -42,50 +38,47 @@ impl CommandBufferBuilder {
.map_err(|_| anyhow::Error::msg("Failed locking vulkan queue"))? .map_err(|_| anyhow::Error::msg("Failed locking vulkan queue"))?
.family_index(), .family_index(),
) )
.build(device.clone())?; .build(device)?;
let command_buffer_ci = let command_buffer_ci =
VkCommandBufferAllocateInfo::new(command_pool.vk_handle(), self.buffer_level, 1); VkCommandBufferAllocateInfo::new(command_pool.vk_handle(), self.buffer_level, 1);
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()), })
}))
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct CommandBuffer { pub struct CommandBuffer<'device> {
device: Arc<Device>, device: &'device Device,
pool: Arc<CommandPool>, pool: CommandPool<'device>,
buffer: VkCommandBuffer, buffer: VkCommandBuffer,
calls: Arc<AtomicUsize>, calls: usize,
stored_handles: Mutex<Vec<Arc<dyn Any + Send + Sync>>>,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct CommandBufferRecorder<'a> { pub struct CommandBufferRecorder<'device, 'pipeline, 'cbuffer> {
device: Arc<Device>, device: &'device Device,
sub_pass: u32, sub_pass: u32,
pipeline: Option<Arc<Pipeline>>, pipeline: Option<&'pipeline Pipeline<'device>>,
calls: Arc<AtomicUsize>, calls: &'cbuffer mut usize,
buffer: VkCommandBuffer, buffer: VkCommandBuffer,
handles_lock: MutexGuard<'a, Vec<Arc<dyn Any + Send + Sync>>>,
} }
impl_vk_handle!(CommandBuffer, VkCommandBuffer, buffer); impl_vk_handle!(CommandBuffer<'a>, VkCommandBuffer, buffer);
impl CommandBuffer { impl<'device> CommandBuffer<'device> {
pub fn new_primary() -> CommandBufferBuilder { pub fn new_primary() -> CommandBufferBuilder {
CommandBufferBuilder { CommandBufferBuilder {
buffer_level: VK_COMMAND_BUFFER_LEVEL_PRIMARY, buffer_level: VK_COMMAND_BUFFER_LEVEL_PRIMARY,
@ -105,25 +98,24 @@ impl CommandBuffer {
} }
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<'pipeline, 'cbuffer>(
&'cbuffer mut self,
begin_info: VkCommandBufferBeginInfo,
) -> Result<CommandBufferRecorder<'device, 'pipeline, 'cbuffer>> {
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(); self.calls = 0;
handles_lock.clear();
self.calls.store(0, SeqCst);
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,
}) })
} }
@ -160,10 +152,10 @@ impl CommandBuffer {
} }
} }
pub fn inheritance_info( pub fn inheritance_info<'image>(
render_pass: Option<&Arc<RenderPass>>, render_pass: Option<&RenderPass<'device>>,
sub_pass: Option<u32>, sub_pass: Option<u32>,
framebuffer: Option<&Arc<Framebuffer>>, framebuffer: Option<&Framebuffer<'device, 'image>>,
query_enable: Option<QueryEnable>, query_enable: Option<QueryEnable>,
) -> VkCommandBufferInheritanceInfo { ) -> VkCommandBufferInheritanceInfo {
let mut info = VkCommandBufferInheritanceInfo::new( let mut info = VkCommandBufferInheritanceInfo::new(
@ -186,9 +178,12 @@ impl CommandBuffer {
} }
} }
impl<'a> CommandBufferRecorder<'a> { impl<'handle, 'me, 'device, 'pipeline, 'cbuffer> CommandBufferRecorder<'device, 'pipeline, 'cbuffer>
where
'handle: 'me,
{
pub fn pipeline_barrier( pub fn pipeline_barrier(
&self, &'me mut self,
src_stage_mask: impl Into<VkPipelineStageFlagBits>, src_stage_mask: impl Into<VkPipelineStageFlagBits>,
dst_stage_mask: impl Into<VkPipelineStageFlagBits>, dst_stage_mask: impl Into<VkPipelineStageFlagBits>,
dependency_flags: impl Into<VkDependencyFlagBits>, dependency_flags: impl Into<VkDependencyFlagBits>,
@ -196,7 +191,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,
@ -210,7 +205,7 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn memory_barrier( pub fn memory_barrier(
&self, &'me mut self,
src_access_mask: impl Into<VkAccessFlagBits>, src_access_mask: impl Into<VkAccessFlagBits>,
src_stage: VkPipelineStageFlags, src_stage: VkPipelineStageFlags,
dst_access_mask: impl Into<VkAccessFlagBits>, dst_access_mask: impl Into<VkAccessFlagBits>,
@ -227,15 +222,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, &'me mut self,
buffer: &Arc<Buffer<T>>, buffer: &'handle Buffer<'device, 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.pipeline_barrier( self.pipeline_barrier(
src_stage, src_stage,
dst_stage, dst_stage,
@ -255,18 +248,18 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn image_barrier( pub fn image_barrier(
&mut self, &'me mut self,
image: &Arc<Image>, image: &'handle Image<'device>,
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,
dst_stage: impl Into<VkPipelineStageFlagBits>, dst_stage: impl Into<VkPipelineStageFlagBits>,
) { ) where
'handle: 'me,
{
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.pipeline_barrier( self.pipeline_barrier(
src_stage, src_stage,
dst_stage, dst_stage,
@ -289,16 +282,14 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn image_barrier_auto_stage( pub fn image_barrier_auto_stage(
&mut self, &'me mut self,
image: &Arc<Image>, image: &'handle Image<'device>,
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.pipeline_barrier( self.pipeline_barrier(
CommandBuffer::access_to_stage(src_access_mask), CommandBuffer::access_to_stage(src_access_mask),
CommandBuffer::access_to_stage(dst_access_mask), CommandBuffer::access_to_stage(dst_access_mask),
@ -321,7 +312,7 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn begin_render_pass( pub fn begin_render_pass(
&mut self, &'me mut self,
renderpass_begin_info: VkRenderPassBeginInfo, renderpass_begin_info: VkRenderPassBeginInfo,
subpass_contents: VkSubpassContents, subpass_contents: VkSubpassContents,
) { ) {
@ -331,16 +322,13 @@ impl<'a> CommandBufferRecorder<'a> {
.cmd_begin_render_pass(self.buffer, &renderpass_begin_info, subpass_contents); .cmd_begin_render_pass(self.buffer, &renderpass_begin_info, subpass_contents);
} }
pub fn begin_render_pass_full( pub fn begin_render_pass_full<'image>(
&mut self, &'me mut self,
render_pass: &Arc<RenderPass>, render_pass: &'handle RenderPass<'device>,
framebuffer: &Arc<Framebuffer>, framebuffer: &'handle Framebuffer<'device, 'image>,
clear_values: &[VkClearValue], clear_values: &[VkClearValue],
subpass_contents: VkSubpassContents, subpass_contents: VkSubpassContents,
) { ) {
self.handles_lock.push(render_pass.clone());
self.handles_lock.push(framebuffer.clone());
self.sub_pass = 0; self.sub_pass = 0;
let render_pass_begin_info = VkRenderPassBeginInfo::new( let render_pass_begin_info = VkRenderPassBeginInfo::new(
@ -360,18 +348,16 @@ impl<'a> CommandBufferRecorder<'a> {
.cmd_begin_render_pass(self.buffer, &render_pass_begin_info, subpass_contents); .cmd_begin_render_pass(self.buffer, &render_pass_begin_info, subpass_contents);
} }
pub fn next_subpass(&mut self, subpass_contents: VkSubpassContents) { pub fn next_subpass(&'me mut self, subpass_contents: VkSubpassContents) {
self.sub_pass += 1; self.sub_pass += 1;
self.device.cmd_next_subpass(self.buffer, subpass_contents); self.device.cmd_next_subpass(self.buffer, subpass_contents);
} }
pub fn end_render_pass(&self) { pub fn end_render_pass(&'me self) {
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(&'me mut self, pipeline: &'pipeline Pipeline<'device>) -> Result<()> {
self.handles_lock.push(pipeline.clone());
match pipeline.pipeline_type() { match pipeline.pipeline_type() {
PipelineType::Graphics => { PipelineType::Graphics => {
debug_assert_eq!(self.sub_pass, pipeline.sub_pass()); debug_assert_eq!(self.sub_pass, pipeline.sub_pass());
@ -394,13 +380,16 @@ impl<'a> CommandBufferRecorder<'a> {
), ),
} }
self.pipeline = Some(pipeline.clone()); self.pipeline = Some(pipeline);
Ok(()) Ok(())
} }
pub fn execute_commands(&self, command_buffers: &[&impl VkHandle<VkCommandBuffer>]) { pub fn execute_commands(
self.calls.fetch_add(1, SeqCst); &'me mut self,
command_buffers: &[&'handle impl VkHandle<VkCommandBuffer>],
) {
*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 +398,11 @@ 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<'a>(
self.calls.fetch_add(1, SeqCst); &'me mut self,
descriptor_sets: &[&'handle DescriptorSet<'device, 'a>],
) {
*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,11 +421,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<'device, 'a>| ds.vk_handle())
self.handles_lock.push((*ds).clone());
ds.vk_handle()
})
.collect(); .collect();
self.device.cmd_bind_descriptor_sets( self.device.cmd_bind_descriptor_sets(
@ -447,30 +435,24 @@ 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, &'me mut self,
buffer: &Arc<Buffer<T>>, buffer: &'handle Buffer<'device, T>,
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.handles_lock.push(buffer.clone());
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]);
} }
pub fn bind_vertex_buffers_minimal<T: ReprC + Send + Sync + 'static>( pub fn bind_vertex_buffers_minimal<T: ReprC + Send + Sync + 'static>(
&mut self, &'me mut self,
buffers: &[&Arc<Buffer<T>>], buffers: &[&'handle Buffer<'device, 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<'device, T>| b.vk_handle())
self.handles_lock.push((*b).clone());
b.vk_handle()
})
.collect(); .collect();
let offsets = vec![0; vk_buffers.len()]; let offsets = vec![0; vk_buffers.len()];
@ -484,39 +466,33 @@ 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, &'me mut self,
buffer: &Arc<Buffer<T>>, buffer: &'handle Buffer<'device, 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.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);
} }
pub fn set_viewport(&self, viewports: &[VkViewport]) { pub fn set_viewport(&'me self, viewports: &[VkViewport]) {
self.device.cmd_set_viewport(self.buffer, 0, viewports); self.device.cmd_set_viewport(self.buffer, 0, viewports);
} }
pub fn set_scissor(&self, scissors: &[VkRect2D]) { pub fn set_scissor(&'me self, scissors: &[VkRect2D]) {
self.device.cmd_set_scissor(self.buffer, 0, scissors); self.device.cmd_set_scissor(self.buffer, 0, scissors);
} }
pub fn set_cull_mode(&self, cull_mode: VkCullModeFlags) {
self.device.cmd_set_cull_mode(self.buffer, cull_mode.into());
}
pub fn draw( pub fn draw(
&self, &'me mut self,
vertex_count: u32, vertex_count: u32,
instance_count: u32, instance_count: u32,
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,
@ -527,21 +503,21 @@ impl<'a> CommandBufferRecorder<'a> {
); );
} }
pub fn draw_complete_single_instance(&self, vertex_count: u32) { pub fn draw_complete_single_instance(&'me mut 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);
} }
pub fn draw_indexed( pub fn draw_indexed(
&self, &'me mut self,
index_count: u32, index_count: u32,
instance_count: u32, instance_count: u32,
first_index: u32, first_index: u32,
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,
@ -553,15 +529,19 @@ impl<'a> CommandBufferRecorder<'a> {
); );
} }
pub fn draw_indexed_complete_single_instance(&self, index_count: u32) { pub fn draw_indexed_complete_single_instance(&'me mut 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.calls.fetch_add(1, SeqCst); &'me mut self,
stage_flags: impl Into<VkShaderStageFlagBits>,
data: &U,
) {
*self.calls += 1;
let pipeline = match &self.pipeline { let pipeline = match &self.pipeline {
Some(pipeline) => pipeline, Some(pipeline) => pipeline,
@ -575,16 +555,14 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn set_image_layout( pub fn set_image_layout(
&mut self, &'me mut self,
image: &Arc<Image>, image: &'handle Image<'device>,
new_image_layout: VkImageLayout, new_image_layout: VkImageLayout,
subresource_range: VkImageSubresourceRange, subresource_range: VkImageSubresourceRange,
) { ) {
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.pipeline_barrier( self.pipeline_barrier(
CommandBuffer::access_to_stage(src_access), CommandBuffer::access_to_stage(src_access),
CommandBuffer::access_to_stage(dst_access), CommandBuffer::access_to_stage(dst_access),
@ -606,12 +584,14 @@ 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(
&'me mut self,
image: &'handle Image<'device>,
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.pipeline_barrier( self.pipeline_barrier(
CommandBuffer::access_to_stage(src_access), CommandBuffer::access_to_stage(src_access),
CommandBuffer::access_to_stage(dst_access), CommandBuffer::access_to_stage(dst_access),
@ -634,62 +614,59 @@ impl<'a> CommandBufferRecorder<'a> {
} }
// TODO: // TODO:
pub fn set_line_width(&self) { pub fn set_line_width(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn set_depth_bias(&self) { pub fn set_depth_bias(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn set_blend_constants(&self) { pub fn set_blend_constants(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn set_depth_bounds(&self) { pub fn set_depth_bounds(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn set_stencil_compare_mask(&self) { pub fn set_stencil_compare_mask(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn set_stencil_write_mask(&self) { pub fn set_stencil_write_mask(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn set_stencil_reference(&self) { pub fn set_stencil_reference(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn draw_indirect(&self) { pub fn draw_indirect(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn draw_indexed_indirect(&self) { pub fn draw_indexed_indirect(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn dispatch(&self, x: u32, y: u32, z: u32) { pub fn dispatch(&'me mut 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);
} }
pub fn dispatch_indirect(&self) { pub fn dispatch_indirect(&'me self) {
unimplemented!(); unimplemented!();
} }
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, &'me mut self,
src_buffer: &Arc<Buffer<T>>, src_buffer: &'handle Buffer<'device, T>,
dst_buffer: &Arc<Buffer<U>>, dst_buffer: &'handle Buffer<'device, 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(dst_buffer.clone());
self.device.cmd_copy_buffer( self.device.cmd_copy_buffer(
self.buffer, self.buffer,
@ -700,17 +677,14 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn copy_image( pub fn copy_image(
&mut self, &'me mut self,
src_image: &Arc<Image>, src_image: &'handle Image<'device>,
dst_image: &Arc<Image>, dst_image: &'handle Image<'device>,
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(dst_image.clone());
self.device.cmd_copy_image( self.device.cmd_copy_image(
self.buffer, self.buffer,
@ -723,14 +697,11 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn blit_complete( pub fn blit_complete(
&mut self, &'me mut self,
src_image: &Arc<Image>, src_image: &'handle Image<'device>,
dst_image: &Arc<Image>, dst_image: &'handle Image<'device>,
filter: VkFilter, filter: VkFilter,
) { ) {
self.handles_lock.push(src_image.clone());
self.handles_lock.push(dst_image.clone());
let image_blit = VkImageBlit { let image_blit = VkImageBlit {
srcSubresource: src_image.full_resource_layers(), srcSubresource: src_image.full_resource_layers(),
srcOffsets: [ srcOffsets: [
@ -763,18 +734,15 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn blit_image( pub fn blit_image(
&mut self, &'me mut self,
src_image: &Arc<Image>, src_image: &'handle Image<'device>,
dst_image: &Arc<Image>, dst_image: &'handle Image<'device>,
src_layout: VkImageLayout, src_layout: VkImageLayout,
dst_layout: VkImageLayout, dst_layout: VkImageLayout,
regions: &[VkImageBlit], regions: &[VkImageBlit],
filter: VkFilter, filter: VkFilter,
) { ) {
self.calls.fetch_add(1, SeqCst); *self.calls += 1;
self.handles_lock.push(src_image.clone());
self.handles_lock.push(dst_image.clone());
self.device.cmd_blit_image( self.device.cmd_blit_image(
self.buffer, self.buffer,
@ -788,16 +756,13 @@ 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, &'me mut self,
src_buffer: &Arc<Buffer<T>>, src_buffer: &'handle Buffer<'device, T>,
dst_image: &Arc<Image>, dst_image: &'handle Image<'device>,
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(dst_image.clone());
self.device.cmd_copy_buffer_to_image( self.device.cmd_copy_buffer_to_image(
self.buffer, self.buffer,
@ -809,16 +774,13 @@ 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, &'me mut self,
src_image: &Arc<Image>, src_image: &'handle Image<'device>,
image_layout: VkImageLayout, image_layout: VkImageLayout,
dst_buffer: &Arc<Buffer<T>>, dst_buffer: &'handle Buffer<'device, 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(dst_buffer.clone());
self.device.cmd_copy_image_to_buffer( self.device.cmd_copy_image_to_buffer(
self.buffer, self.buffer,
@ -829,18 +791,20 @@ impl<'a> CommandBufferRecorder<'a> {
) )
} }
pub fn update_buffer(&self) { pub fn update_buffer(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn fill_buffer(&self) { pub fn fill_buffer(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn clear_color_image(&mut self, image: &Arc<Image>, clear_color: VkClearColorValue) { pub fn clear_color_image(
self.calls.fetch_add(1, SeqCst); &'me mut self,
image: &Image<'device>,
self.handles_lock.push(image.clone()); clear_color: VkClearColorValue,
) {
*self.calls += 1;
self.device.cmd_clear_color_image( self.device.cmd_clear_color_image(
self.buffer, self.buffer,
@ -851,24 +815,21 @@ impl<'a> CommandBufferRecorder<'a> {
); );
} }
pub fn clear_depth_stencil_image(&self) { pub fn clear_depth_stencil_image(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn clear_attachments(&self) { pub fn clear_attachments(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn resolve_image( pub fn resolve_image(
&mut self, &'me mut self,
src_image: &Arc<Image>, src_image: &'handle Image<'device>,
dst_image: &Arc<Image>, dst_image: &'handle Image<'device>,
regions: &[VkImageResolve], 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.device.cmd_resolve_image( self.device.cmd_resolve_image(
self.buffer, self.buffer,
@ -880,61 +841,61 @@ impl<'a> CommandBufferRecorder<'a> {
); );
} }
pub fn set_event(&self) { pub fn set_event(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn reset_event(&self) { pub fn reset_event(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn wait_events(&self) { pub fn wait_events(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn begin_query(&self) { pub fn begin_query(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn end_query(&self) { pub fn end_query(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn reset_query_pool(&self) { pub fn reset_query_pool(&'me self) {
unimplemented!(); unimplemented!();
} }
pub fn write_timestamp( pub fn write_timestamp(
&mut self, &'me mut self,
query_pool: &Arc<QueryPool>, query_pool: &'handle 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.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);
} }
pub fn copy_query_pool_results(&self) { pub fn copy_query_pool_results(&'me self) {
unimplemented!(); unimplemented!();
} }
} }
impl<'a> CommandBufferRecorder<'a> { impl<'me, 'handle, 'device, 'pipeline, 'cbuffer> CommandBufferRecorder<'device, 'pipeline, 'cbuffer>
where
'handle: 'me,
{
pub fn build_acceleration_structure_indirect( pub fn build_acceleration_structure_indirect(
&mut self, &'me mut self,
infos: &[VkAccelerationStructureBuildGeometryInfoKHR], infos: &[VkAccelerationStructureBuildGeometryInfoKHR],
indirect_buffers: &[Arc<Buffer<impl ReprC + Send + Sync + 'static>>], indirect_buffers: &[Buffer<'device, 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());
device_addresses.push(indirect_buffer.device_address().into()); device_addresses.push(indirect_buffer.device_address().into());
} }
@ -948,7 +909,7 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn build_acceleration_structures( pub fn build_acceleration_structures(
&self, &'me self,
infos: &[VkAccelerationStructureBuildGeometryInfoKHR], infos: &[VkAccelerationStructureBuildGeometryInfoKHR],
range_infos: &[&[VkAccelerationStructureBuildRangeInfoKHR]], range_infos: &[&[VkAccelerationStructureBuildRangeInfoKHR]],
) { ) {
@ -957,14 +918,11 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn copy_acceleration_structure( pub fn copy_acceleration_structure(
&mut self, &'me mut self,
src: &Arc<AccelerationStructure>, src: &'handle AccelerationStructure<'device>,
dst: &Arc<AccelerationStructure>, dst: &'handle AccelerationStructure<'device>,
mode: VkCopyAccelerationStructureModeKHR, mode: VkCopyAccelerationStructureModeKHR,
) { ) {
self.handles_lock.push(src.clone());
self.handles_lock.push(dst.clone());
let info = VkCopyAccelerationStructureInfoKHR::new(src.vk_handle(), dst.vk_handle(), mode); let info = VkCopyAccelerationStructureInfoKHR::new(src.vk_handle(), dst.vk_handle(), mode);
self.device self.device
@ -972,13 +930,11 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn copy_acceleration_structure_to_memory( pub fn copy_acceleration_structure_to_memory(
&mut self, &'me mut self,
src: &Arc<AccelerationStructure>, src: &'handle AccelerationStructure<'device>,
dst: VkDeviceOrHostAddressKHR, dst: VkDeviceOrHostAddressKHR,
mode: VkCopyAccelerationStructureModeKHR, mode: VkCopyAccelerationStructureModeKHR,
) { ) {
self.handles_lock.push(src.clone());
let info = VkCopyAccelerationStructureToMemoryInfoKHR::new(src.vk_handle(), dst, mode); let info = VkCopyAccelerationStructureToMemoryInfoKHR::new(src.vk_handle(), dst, mode);
self.device self.device
@ -986,13 +942,11 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn copy_memory_to_acceleration_structure( pub fn copy_memory_to_acceleration_structure(
&mut self, &'me mut self,
src: VkDeviceOrHostAddressConstKHR, src: VkDeviceOrHostAddressConstKHR,
dst: &Arc<AccelerationStructure>, dst: &'handle AccelerationStructure<'device>,
mode: VkCopyAccelerationStructureModeKHR, mode: VkCopyAccelerationStructureModeKHR,
) { ) {
self.handles_lock.push(dst.clone());
let info = VkCopyMemoryToAccelerationStructureInfoKHR::new(src, dst.vk_handle(), mode); let info = VkCopyMemoryToAccelerationStructureInfoKHR::new(src, dst.vk_handle(), mode);
self.device self.device
@ -1000,12 +954,10 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn trace_rays_indirect( pub fn trace_rays_indirect(
&mut self, &'me mut self,
sbt: ShaderBindingTable, sbt: &'handle ShaderBindingTable<'device>,
buffer: Arc<Buffer<impl ReprC + Send + Sync + 'static>>, buffer: &'handle Buffer<'device, impl ReprC + Send + Sync + 'static>,
) { ) {
self.handles_lock.push(buffer.clone());
self.device.cmd_trace_rays_indirect( self.device.cmd_trace_rays_indirect(
self.buffer, self.buffer,
sbt.raygen_shader_binding_table(), sbt.raygen_shader_binding_table(),
@ -1016,7 +968,13 @@ impl<'a> CommandBufferRecorder<'a> {
) )
} }
pub fn trace_rays(&self, sbt: &ShaderBindingTable, width: u32, height: u32, depth: u32) { pub fn trace_rays(
&'me self,
sbt: &'handle ShaderBindingTable<'device>,
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(),
@ -1030,20 +988,15 @@ impl<'a> CommandBufferRecorder<'a> {
} }
pub fn write_acceleration_structure_properties( pub fn write_acceleration_structure_properties(
&mut self, &'me mut self,
acceleration_structures: &[&Arc<AccelerationStructure>], acceleration_structures: &[&'handle AccelerationStructure<'device>],
query_type: VkQueryType, query_type: VkQueryType,
query_pool: &Arc<QueryPool>, query_pool: &'handle QueryPool,
first_query: u32, first_query: u32,
) { ) {
self.handles_lock.push(query_pool.clone());
let as_handles: Vec<VkAccelerationStructureKHR> = acceleration_structures let as_handles: Vec<VkAccelerationStructureKHR> = acceleration_structures
.iter() .iter()
.map(|a| { .map(|a| a.vk_handle())
self.handles_lock.push((*a).clone());
a.vk_handle()
})
.collect(); .collect();
self.device.cmd_write_acceleration_structure_properties( self.device.cmd_write_acceleration_structure_properties(
@ -1056,53 +1009,21 @@ impl<'a> CommandBufferRecorder<'a> {
} }
} }
impl VulkanDevice for CommandBuffer { impl<'device> VulkanDevice for CommandBuffer<'device> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &'device Device {
&self.device &self.device
} }
} }
impl Drop for CommandBuffer { impl<'device> Drop for CommandBuffer<'device> {
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]);
} }
} }
impl<'a> Drop for CommandBufferRecorder<'a> { impl<'device, 'pipeline, 'cbuffer> Drop for CommandBufferRecorder<'device, 'pipeline, 'cbuffer> {
fn drop(&mut self) { fn drop(&mut self) {
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,25 +20,25 @@ impl CommandPoolBuilder {
self self
} }
pub(crate) fn build(self, device: Arc<Device>) -> Result<Arc<CommandPool>> { 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,
})) })
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct CommandPool { pub(crate) struct CommandPool<'a> {
device: Arc<Device>, device: &'a Device,
command_pool: VkCommandPool, command_pool: VkCommandPool,
} }
impl CommandPool { impl<'a> CommandPool<'a> {
pub(crate) fn builder() -> CommandPoolBuilder { pub(crate) fn builder() -> CommandPoolBuilder {
CommandPoolBuilder { CommandPoolBuilder {
flags: VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flags: VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
@ -50,39 +48,16 @@ impl CommandPool {
} }
} }
impl VulkanDevice for CommandPool { impl<'a> VulkanDevice for CommandPool<'a> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle!(CommandPool, VkCommandPool, command_pool); impl_vk_handle!(CommandPool<'a>, VkCommandPool, command_pool);
impl Drop for CommandPool { impl<'a> Drop for CommandPool<'a> {
fn drop(&mut self) { fn drop(&mut self) {
self.device.destroy_command_pool(self.command_pool); self.device.destroy_command_pool(self.command_pool);
} }
} }
// use crate::{ffi::*, handle_ffi_result};
// #[no_mangle]
// pub extern "C" fn create_command_pool(
// flags: VkCommandPoolCreateFlagBits,
// queue_family_index: u32,
// device: *const Device,
// ) -> *const CommandPool {
// let device = unsafe { Arc::from_raw(device) };
// let pool_res = CommandPool::builder()
// .set_flags(flags)
// .set_queue_family_index(queue_family_index)
// .build(device);
// handle_ffi_result!(pool_res)
// }
// #[no_mangle]
// pub extern "C" fn destroy_command_pool(command_pool: *const CommandPool) {
// let _pool = unsafe { Arc::from_raw(command_pool) };
// }

View file

@ -2,15 +2,13 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::Arc; pub struct DescriptorPoolBuilder<'a> {
layout: Option<&'a DescriptorSetLayout<'a>>,
pub struct DescriptorPoolBuilder {
layout: Option<Arc<DescriptorSetLayout>>,
descriptor_count: u32, descriptor_count: u32,
flags: VkDescriptorPoolCreateFlagBits, flags: VkDescriptorPoolCreateFlagBits,
} }
impl DescriptorPoolBuilder { impl<'a> DescriptorPoolBuilder<'a> {
pub fn set_flags(mut self, flags: impl Into<VkDescriptorPoolCreateFlagBits>) -> Self { pub fn set_flags(mut self, flags: impl Into<VkDescriptorPoolCreateFlagBits>) -> Self {
self.flags |= flags.into(); self.flags |= flags.into();
@ -23,13 +21,13 @@ impl DescriptorPoolBuilder {
self self
} }
pub fn set_layout(mut self, layout: Arc<DescriptorSetLayout>) -> Self { pub fn set_layout(mut self, layout: &'a DescriptorSetLayout<'a>) -> Self {
self.layout = Some(layout); self.layout = Some(layout);
self self
} }
pub fn build(self, device: Arc<Device>) -> Result<Arc<DescriptorPool>> { pub fn build(self, device: &'a Device) -> Result<DescriptorPool<'a>> {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
if self.layout.is_none() { if self.layout.is_none() {
panic!("no layout set!"); panic!("no layout set!");
@ -60,23 +58,23 @@ impl DescriptorPoolBuilder {
let descriptor_pool = device.create_descriptor_pool(&descriptor_pool_ci)?; let descriptor_pool = device.create_descriptor_pool(&descriptor_pool_ci)?;
Ok(Arc::new(DescriptorPool { Ok(DescriptorPool {
device, device,
descriptor_pool, descriptor_pool,
descriptor_set_layout: layout, descriptor_set_layout: layout,
})) })
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct DescriptorPool { pub struct DescriptorPool<'device> {
device: Arc<Device>, device: &'device Device,
descriptor_pool: VkDescriptorPool, descriptor_pool: VkDescriptorPool,
pub(crate) descriptor_set_layout: Arc<DescriptorSetLayout>, pub(crate) descriptor_set_layout: &'device DescriptorSetLayout<'device>,
} }
impl DescriptorPool { impl<'device> DescriptorPool<'device> {
pub fn builder() -> DescriptorPoolBuilder { pub fn builder() -> DescriptorPoolBuilder<'device> {
DescriptorPoolBuilder { DescriptorPoolBuilder {
layout: None, layout: None,
descriptor_count: 1, descriptor_count: 1,
@ -89,83 +87,33 @@ impl DescriptorPool {
.reset_descriptor_pool(self.descriptor_pool, VK_DESCRIPTOR_POOL_RESET_NULL_BIT) .reset_descriptor_pool(self.descriptor_pool, VK_DESCRIPTOR_POOL_RESET_NULL_BIT)
} }
pub fn prepare_set(self: &Arc<Self>) -> DescriptorSetBuilder { pub fn prepare_set(&'device self) -> DescriptorSetBuilder<'device> {
DescriptorSet::builder(self.device.clone(), self.clone()) DescriptorSet::builder(self.device, self)
} }
} }
impl VulkanDevice for DescriptorPool { impl<'a> VulkanDevice for DescriptorPool<'a> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle!(DescriptorPool, VkDescriptorPool, descriptor_pool); impl_vk_handle!(DescriptorPool<'a>, VkDescriptorPool, descriptor_pool);
impl VkHandle<VkDescriptorSetLayout> for DescriptorPool { impl<'a> VkHandle<VkDescriptorSetLayout> for DescriptorPool<'a> {
fn vk_handle(&self) -> VkDescriptorSetLayout { fn vk_handle(&self) -> VkDescriptorSetLayout {
self.descriptor_set_layout.vk_handle() self.descriptor_set_layout.vk_handle()
} }
} }
impl<'a> VkHandle<VkDescriptorSetLayout> for &'a DescriptorPool { impl<'a> VkHandle<VkDescriptorSetLayout> for &'a DescriptorPool<'a> {
fn vk_handle(&self) -> VkDescriptorSetLayout { fn vk_handle(&self) -> VkDescriptorSetLayout {
self.descriptor_set_layout.vk_handle() self.descriptor_set_layout.vk_handle()
} }
} }
impl VkHandle<VkDescriptorSetLayout> for Arc<DescriptorPool> { impl<'a> Drop for DescriptorPool<'a> {
fn vk_handle(&self) -> VkDescriptorSetLayout {
self.descriptor_set_layout.vk_handle()
}
}
impl<'a> VkHandle<VkDescriptorSetLayout> for &'a Arc<DescriptorPool> {
fn vk_handle(&self) -> VkDescriptorSetLayout {
self.descriptor_set_layout.vk_handle()
}
}
impl Drop for DescriptorPool {
fn drop(&mut self) { fn drop(&mut self) {
self.device.destroy_descriptor_pool(self.descriptor_pool); self.device.destroy_descriptor_pool(self.descriptor_pool);
} }
} }
use crate::{ffi::*, handle_ffi_result};
#[no_mangle]
pub extern "C" fn create_descriptor_pool(
flags: VkDescriptorPoolCreateFlagBits,
descriptor_set_layout: *const DescriptorSetLayout,
device: *const Device,
) -> *const DescriptorPool {
let device = unsafe { Arc::from_raw(device) };
let layout = unsafe { Arc::from_raw(descriptor_set_layout) };
let pool_res = DescriptorPool::builder()
.set_flags(flags)
.set_layout(layout)
.build(device);
handle_ffi_result!(pool_res)
}
#[no_mangle]
pub extern "C" fn reset_descriptor_pool(descriptor_pool: *const DescriptorPool) -> bool {
let pool = unsafe { Arc::from_raw(descriptor_pool) };
match pool.reset() {
Ok(_) => true,
Err(err) => {
update_last_error(err);
false
}
}
}
#[no_mangle]
pub extern "C" fn destroy_descriptor_pool(descriptor_pool: *const DescriptorPool) {
let _pool = unsafe { Arc::from_raw(descriptor_pool) };
}

View file

@ -2,17 +2,15 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::any::Any; use std::marker::PhantomData;
use std::collections::HashMap;
use std::slice; use std::slice;
use std::sync::{Arc, Mutex};
#[derive(Debug)] #[derive(Debug)]
pub struct DescriptorWrite { pub struct DescriptorWrite<'handle> {
lifetime: &'handle PhantomData<()>,
binding: u32, binding: u32,
descriptor_type: VkDescriptorType, descriptor_type: VkDescriptorType,
inner: InnerWrite, inner: InnerWrite,
handles: Vec<Arc<dyn Any + Send + Sync>>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -27,10 +25,10 @@ enum InnerWrite {
), ),
} }
impl DescriptorWrite { impl<'device, 'handle> DescriptorWrite<'handle> {
pub fn uniform_buffers<T: ReprC + Send + Sync + 'static>( pub fn uniform_buffers<T: ReprC + Send + Sync + 'static>(
binding: u32, binding: u32,
buffers: &[&Arc<Buffer<T>>], buffers: &[&'handle Buffer<'device, T>],
) -> Self { ) -> Self {
DescriptorWrite { DescriptorWrite {
binding, binding,
@ -45,16 +43,13 @@ impl DescriptorWrite {
}) })
.collect(), .collect(),
), ),
handles: buffers lifetime: &PhantomData,
.iter()
.map(|b| (*b).clone() as Arc<dyn Any + Send + Sync>)
.collect(),
} }
} }
pub fn storage_buffers<T: ReprC + Send + Sync + 'static>( pub fn storage_buffers<T: ReprC + Send + Sync + 'static>(
binding: u32, binding: u32,
buffers: &[&Arc<Buffer<T>>], buffers: &[&'handle Buffer<'device, T>],
) -> Self { ) -> Self {
DescriptorWrite { DescriptorWrite {
binding, binding,
@ -69,14 +64,11 @@ impl DescriptorWrite {
}) })
.collect(), .collect(),
), ),
handles: buffers lifetime: &PhantomData,
.iter()
.map(|b| (*b).clone() as Arc<dyn Any + Send + Sync>)
.collect(),
} }
} }
pub fn combined_samplers(binding: u32, images: &[&Arc<Image>]) -> Self { pub fn combined_samplers(binding: u32, images: &[&'handle Image<'device>]) -> Self {
DescriptorWrite { DescriptorWrite {
binding, binding,
descriptor_type: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, descriptor_type: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
@ -94,14 +86,11 @@ impl DescriptorWrite {
}) })
.collect(), .collect(),
), ),
handles: images lifetime: &PhantomData,
.iter()
.map(|i| (*i).clone() as Arc<dyn Any + Send + Sync>)
.collect(),
} }
} }
pub fn storage_images(binding: u32, images: &[&Arc<Image>]) -> Self { pub fn storage_images(binding: u32, images: &[&'handle Image<'device>]) -> Self {
DescriptorWrite { DescriptorWrite {
binding, binding,
descriptor_type: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptor_type: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
@ -115,14 +104,11 @@ impl DescriptorWrite {
}) })
.collect(), .collect(),
), ),
handles: images lifetime: &PhantomData,
.iter()
.map(|i| (*i).clone() as Arc<dyn Any + Send + Sync>)
.collect(),
} }
} }
pub fn input_attachments(binding: u32, images: &[&Arc<Image>]) -> Self { pub fn input_attachments(binding: u32, images: &[&'handle Image<'device>]) -> Self {
DescriptorWrite { DescriptorWrite {
binding, binding,
descriptor_type: VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, descriptor_type: VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
@ -136,16 +122,13 @@ impl DescriptorWrite {
}) })
.collect(), .collect(),
), ),
handles: images lifetime: &PhantomData,
.iter()
.map(|i| (*i).clone() as Arc<dyn Any + Send + Sync>)
.collect(),
} }
} }
pub fn acceleration_structures( pub fn acceleration_structures(
binding: u32, binding: u32,
acceleration_structures: &[&Arc<AccelerationStructure>], acceleration_structures: &[&'handle AccelerationStructure<'device>],
) -> Self { ) -> Self {
let vk_as: Vec<VkAccelerationStructureKHR> = acceleration_structures let vk_as: Vec<VkAccelerationStructureKHR> = acceleration_structures
.iter() .iter()
@ -159,10 +142,7 @@ impl DescriptorWrite {
VkWriteDescriptorSetAccelerationStructureKHR::default(), VkWriteDescriptorSetAccelerationStructureKHR::default(),
vk_as, vk_as,
)), )),
handles: acceleration_structures lifetime: &PhantomData,
.iter()
.map(|a| (*a).clone() as Arc<dyn Any + Send + Sync>)
.collect(),
}; };
if let InnerWrite::AS((vk_write_as, vk_as)) = &mut write.inner { if let InnerWrite::AS((vk_write_as, vk_as)) = &mut write.inner {
@ -198,21 +178,21 @@ impl DescriptorWrite {
} }
} }
pub struct DescriptorSetBuilder { pub struct DescriptorSetBuilder<'a> {
device: Arc<Device>, device: &'a Device,
descriptor_pool: Arc<DescriptorPool>, descriptor_pool: &'a DescriptorPool<'a>,
variable_desc_counts: Vec<u32>, variable_desc_counts: Vec<u32>,
variable_descriptor_count: VkDescriptorSetVariableDescriptorCountAllocateInfoEXT, variable_descriptor_count: VkDescriptorSetVariableDescriptorCountAllocateInfoEXT,
} }
impl DescriptorSetBuilder { impl<'a> DescriptorSetBuilder<'a> {
pub fn set_variable_descriptor_counts(mut self, descriptor_counts: &[u32]) -> Self { pub fn set_variable_descriptor_counts(mut self, descriptor_counts: &[u32]) -> Self {
self.variable_desc_counts = descriptor_counts.to_vec(); self.variable_desc_counts = descriptor_counts.to_vec();
self self
} }
pub fn allocate(mut self) -> Result<Arc<DescriptorSet>> { pub fn allocate<'handle>(mut self) -> Result<DescriptorSet<'a, 'handle>> {
let layout = self.descriptor_pool.vk_handle(); let layout = self.descriptor_pool.vk_handle();
let mut descriptor_set_ci = VkDescriptorSetAllocateInfo::new( let mut descriptor_set_ci = VkDescriptorSetAllocateInfo::new(
@ -228,30 +208,30 @@ impl DescriptorSetBuilder {
let descriptor_set = self.device.allocate_descriptor_sets(&descriptor_set_ci)?[0]; let descriptor_set = self.device.allocate_descriptor_sets(&descriptor_set_ci)?[0];
Ok(Arc::new(DescriptorSet { Ok(DescriptorSet {
device: self.device, device: self.device,
pool: self.descriptor_pool, pool: self.descriptor_pool,
descriptor_set, descriptor_set,
handles: Mutex::new(HashMap::new()), lifetimes: &PhantomData,
})) })
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct DescriptorSet { pub struct DescriptorSet<'device, 'handle> {
device: Arc<Device>, device: &'device Device,
pool: Arc<DescriptorPool>, pool: &'device DescriptorPool<'device>,
descriptor_set: VkDescriptorSet, descriptor_set: VkDescriptorSet,
handles: Mutex<HashMap<u32, Vec<Arc<dyn Any + Send + Sync>>>>, lifetimes: &'handle PhantomData<()>,
} }
impl DescriptorSet { impl<'device, 'handle> DescriptorSet<'device, 'handle> {
pub(crate) fn builder( pub(crate) fn builder(
device: Arc<Device>, device: &'device Device,
descriptor_pool: Arc<DescriptorPool>, descriptor_pool: &'device DescriptorPool<'device>,
) -> DescriptorSetBuilder { ) -> DescriptorSetBuilder<'device> {
DescriptorSetBuilder { DescriptorSetBuilder {
device, device,
descriptor_pool, descriptor_pool,
@ -263,7 +243,7 @@ impl DescriptorSet {
} }
// TODO: add update function for VkCopyDescriptorSet // TODO: add update function for VkCopyDescriptorSet
pub fn update(&self, writes: &[DescriptorWrite]) -> Result<()> { pub fn update(&self, writes: &[DescriptorWrite<'handle>]) -> Result<()> {
debug_assert!(!writes.is_empty()); debug_assert!(!writes.is_empty());
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
@ -278,7 +258,6 @@ impl DescriptorSet {
} }
let mut vk_writes = Vec::new(); let mut vk_writes = Vec::new();
let mut handles_lock = self.handles.lock().unwrap();
for write in writes { for write in writes {
let mut write_desc = VkWriteDescriptorSet::new( let mut write_desc = VkWriteDescriptorSet::new(
@ -291,13 +270,6 @@ impl DescriptorSet {
write.vk_write(&mut write_desc); write.vk_write(&mut write_desc);
vk_writes.push(write_desc); vk_writes.push(write_desc);
match handles_lock.get_mut(&write.binding) {
Some(val) => *val = write.handles.clone(),
None => {
handles_lock.insert(write.binding, write.handles.clone());
}
}
} }
self.device self.device
@ -307,39 +279,31 @@ impl DescriptorSet {
} }
} }
impl VulkanDevice for DescriptorSet { impl<'device, 'handle> VulkanDevice for DescriptorSet<'device, 'handle> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle!(DescriptorSet, VkDescriptorSet, descriptor_set); impl_vk_handle!(
DescriptorSet<'device, 'handle>,
VkDescriptorSet,
descriptor_set
);
impl VkHandle<VkDescriptorSetLayout> for DescriptorSet { impl<'device, 'handle> VkHandle<VkDescriptorSetLayout> for DescriptorSet<'device, 'handle> {
fn vk_handle(&self) -> VkDescriptorSetLayout { fn vk_handle(&self) -> VkDescriptorSetLayout {
self.pool.vk_handle() self.pool.vk_handle()
} }
} }
impl<'a> VkHandle<VkDescriptorSetLayout> for &'a DescriptorSet { impl<'a, 'device, 'handle> VkHandle<VkDescriptorSetLayout> for &'a DescriptorSet<'device, 'handle> {
fn vk_handle(&self) -> VkDescriptorSetLayout { fn vk_handle(&self) -> VkDescriptorSetLayout {
self.pool.vk_handle() self.pool.vk_handle()
} }
} }
impl VkHandle<VkDescriptorSetLayout> for Arc<DescriptorSet> { impl<'device, 'handle> Drop for DescriptorSet<'device, 'handle> {
fn vk_handle(&self) -> VkDescriptorSetLayout {
self.pool.vk_handle()
}
}
impl<'a> VkHandle<VkDescriptorSetLayout> for &'a Arc<DescriptorSet> {
fn vk_handle(&self) -> VkDescriptorSetLayout {
self.pool.vk_handle()
}
}
impl Drop for DescriptorSet {
fn drop(&mut self) { fn drop(&mut self) {
if let Err(error) = self if let Err(error) = self
.device .device
@ -355,8 +319,6 @@ mod test {
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::Arc;
#[test] #[test]
fn create_multiple_sets_from_one_pool() -> Result<()> { fn create_multiple_sets_from_one_pool() -> Result<()> {
const DESCRIPTOR_COUNT: u32 = 2; const DESCRIPTOR_COUNT: u32 = 2;
@ -370,14 +332,14 @@ mod test {
VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_STAGE_FRAGMENT_BIT,
0, 0,
) )
.build(device.clone())?; .build(&device)?;
let descriptor_pool = DescriptorPool::builder() let descriptor_pool = DescriptorPool::builder()
.set_layout(descriptor_layout.clone()) .set_layout(&descriptor_layout)
.set_descriptor_set_count(DESCRIPTOR_COUNT) .set_descriptor_set_count(DESCRIPTOR_COUNT)
.build(device.clone())?; .build(&device)?;
let descriptors: Vec<Arc<DescriptorSet>> = (0..DESCRIPTOR_COUNT) let descriptors: Vec<DescriptorSet<'_, '_>> = (0..DESCRIPTOR_COUNT)
.map(|_| { .map(|_| {
let set = descriptor_pool.prepare_set().allocate(); let set = descriptor_pool.prepare_set().allocate();

View file

@ -48,7 +48,7 @@ impl DescriptorSetLayoutBuilder {
self self
} }
pub fn build(self, device: Arc<Device>) -> Result<Arc<DescriptorSetLayout>> { pub fn build<'a>(self, device: &'a Device) -> Result<Arc<DescriptorSetLayout<'a>>> {
let mut descriptor_set_ci = let mut descriptor_set_ci =
VkDescriptorSetLayoutCreateInfo::new(self.flags, &self.layout_bindings); VkDescriptorSetLayoutCreateInfo::new(self.flags, &self.layout_bindings);
let binding_flags_ci = let binding_flags_ci =
@ -98,15 +98,15 @@ impl DescriptorSetLayoutBuilder {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct DescriptorSetLayout { pub struct DescriptorSetLayout<'a> {
device: Arc<Device>, device: &'a Device,
descriptor_set_layout: VkDescriptorSetLayout, descriptor_set_layout: VkDescriptorSetLayout,
pool_sizes: Vec<VkDescriptorPoolSize>, pool_sizes: Vec<VkDescriptorPoolSize>,
bindings: Vec<DescriptorLayoutBinding>, bindings: Vec<DescriptorLayoutBinding>,
} }
impl DescriptorSetLayout { impl<'a> DescriptorSetLayout<'a> {
pub fn builder() -> DescriptorSetLayoutBuilder { pub fn builder() -> DescriptorSetLayoutBuilder {
DescriptorSetLayoutBuilder { DescriptorSetLayoutBuilder {
layout_bindings: Vec::new(), layout_bindings: Vec::new(),
@ -124,19 +124,19 @@ impl DescriptorSetLayout {
} }
} }
impl VulkanDevice for DescriptorSetLayout { impl<'a> VulkanDevice for DescriptorSetLayout<'a> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle!( impl_vk_handle!(
DescriptorSetLayout, DescriptorSetLayout<'a>,
VkDescriptorSetLayout, VkDescriptorSetLayout,
descriptor_set_layout descriptor_set_layout
); );
impl Drop for DescriptorSetLayout { impl<'a> Drop for DescriptorSetLayout<'a> {
fn drop(&mut self) { fn drop(&mut self) {
self.device self.device
.destroy_descriptor_set_layout(self.descriptor_set_layout); .destroy_descriptor_set_layout(self.descriptor_set_layout);

View file

@ -53,7 +53,7 @@ pub struct Device {
enabled_extensions: DeviceExtensions, enabled_extensions: DeviceExtensions,
physical_device: Arc<PhysicalDevice>, physical_device: PhysicalDevice,
device: VkDevice, device: VkDevice,
memory_allocator: Allocator, memory_allocator: Allocator,
@ -65,9 +65,9 @@ impl Device {
pub fn preinitialized( pub fn preinitialized(
device: VkDevice, device: VkDevice,
proc_addr: PFN_vkGetDeviceProcAddr, proc_addr: PFN_vkGetDeviceProcAddr,
physical_device: Arc<PhysicalDevice>, physical_device: PhysicalDevice,
extensions: &[VkString], extensions: &[VkString],
) -> Result<Arc<Device>> { ) -> Result<Device> {
let device_functions = DeviceFunctions::load(|name| { let device_functions = DeviceFunctions::load(|name| {
proc_addr(device, name.as_ptr()) as *const std::ffi::c_void proc_addr(device, name.as_ptr()) as *const std::ffi::c_void
}); });
@ -133,7 +133,7 @@ impl Device {
physical_device.instance().api_version(), physical_device.instance().api_version(),
)?; )?;
Ok(Arc::new(Device { Ok(Device {
memory_allocator, memory_allocator,
device_functions, device_functions,
@ -151,15 +151,15 @@ impl Device {
device, device,
sampler_manager: SamplerManager::new(), sampler_manager: SamplerManager::new(),
})) })
} }
pub fn new( pub fn new(
physical_device: Arc<PhysicalDevice>, physical_device: PhysicalDevice,
mut extensions: DeviceExtensions, mut extensions: DeviceExtensions,
queue_infos: &[VkDeviceQueueCreateInfo], queue_infos: &[VkDeviceQueueCreateInfo],
requested_device_features: DeviceFeatures, requested_device_features: DeviceFeatures,
) -> Result<Arc<Device>> { ) -> Result<Device> {
// buffer device address is required in the current library implementation // buffer device address is required in the current library implementation
extensions.buffer_device_address = true; extensions.buffer_device_address = true;
@ -285,7 +285,7 @@ impl Device {
physical_device.instance().api_version(), physical_device.instance().api_version(),
)?; )?;
Ok(Arc::new(Device { Ok(Device {
memory_allocator, memory_allocator,
device_functions, device_functions,
@ -303,7 +303,7 @@ impl Device {
device, device,
sampler_manager: SamplerManager::new(), sampler_manager: SamplerManager::new(),
})) })
} }
fn verify_vma_vk_functions(fns: &VmaVulkanFunctions) -> Result<()> { fn verify_vma_vk_functions(fns: &VmaVulkanFunctions) -> Result<()> {
@ -348,26 +348,22 @@ impl Device {
Ok(()) Ok(())
} }
pub fn get_queue( pub fn get_queue<'a>(&'a self, queue_family_index: u32, queue_index: u32) -> Mutex<Queue<'a>> {
self: &Arc<Self>,
queue_family_index: u32,
queue_index: u32,
) -> Arc<Mutex<Queue>> {
Queue::new( Queue::new(
self.clone(), self,
self.get_device_queue(queue_family_index, queue_index), self.get_device_queue(queue_family_index, queue_index),
queue_family_index, queue_family_index,
queue_index, queue_index,
) )
} }
pub fn physical_device(&self) -> &Arc<PhysicalDevice> { pub fn physical_device(&self) -> &PhysicalDevice {
&self.physical_device &self.physical_device
} }
pub fn wait_for_fences( pub fn wait_for_fences<'a>(
&self, &self,
fences: &[&Arc<Fence>], fences: &[&Fence<'a>],
wait_all: bool, wait_all: bool,
timeout: Duration, timeout: Duration,
) -> Result<()> { ) -> Result<()> {
@ -1864,14 +1860,6 @@ impl Device {
} }
} }
#[inline]
pub fn cmd_set_cull_mode(&self, command_buffer: VkCommandBuffer, cull_mode: VkCullModeFlags) {
unsafe {
self.device_functions
.vkCmdSetCullMode(command_buffer, cull_mode)
}
}
#[inline] #[inline]
pub fn cmd_set_depth_bias( pub fn cmd_set_depth_bias(
&self, &self,

View file

@ -15,7 +15,7 @@ impl FenceBuilder {
self self
} }
pub fn build(self, device: Arc<Device>) -> Result<Arc<Fence>> { pub fn build<'a>(self, device: &'a Device) -> Result<Arc<Fence<'a>>> {
let flag: VkFenceCreateFlagBits = if self.signaled { let flag: VkFenceCreateFlagBits = if self.signaled {
VK_FENCE_CREATE_SIGNALED_BIT.into() VK_FENCE_CREATE_SIGNALED_BIT.into()
} else { } else {
@ -31,12 +31,12 @@ impl FenceBuilder {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Fence { pub struct Fence<'a> {
device: Arc<Device>, device: &'a Device,
fence: VkFence, fence: VkFence,
} }
impl Fence { impl<'a> Fence<'a> {
pub fn builder() -> FenceBuilder { pub fn builder() -> FenceBuilder {
FenceBuilder { signaled: false } FenceBuilder { signaled: false }
} }
@ -50,39 +50,16 @@ impl Fence {
} }
} }
impl VulkanDevice for Fence { impl<'a> VulkanDevice for Fence<'a> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle!(Fence, VkFence, fence); impl_vk_handle!(Fence<'a>, VkFence, fence);
impl Drop for Fence { impl<'a> Drop for Fence<'a> {
fn drop(&mut self) { fn drop(&mut self) {
self.device.destroy_fence(self.fence); self.device.destroy_fence(self.fence);
} }
} }
use crate::{ffi::*, handle_ffi_result};
#[no_mangle]
pub extern "C" fn create_fence(signaled: bool, device: *const Device) -> *const Fence {
let device = unsafe { Arc::from_raw(device) };
let fence_res = Fence::builder().set_signaled(signaled).build(device);
handle_ffi_result!(fence_res)
}
#[no_mangle]
pub extern "C" fn reset_fence(fence: *const Fence) -> bool {
let fence = unsafe { Arc::from_raw(fence) };
fence.reset()
}
#[no_mangle]
pub extern "C" fn destroy_fence(fence: *const Fence) {
let _fence = unsafe { Arc::from_raw(fence) };
}

View file

@ -1,70 +0,0 @@
use std::cell::RefCell;
use std::os::raw::{c_char, c_int};
#[macro_export]
macro_rules! handle_ffi_result {
($result: expr) => {
match $result {
Ok(value) => Arc::into_raw(value),
Err(error) => {
update_last_error(error);
std::ptr::null()
}
}
};
}
thread_local! {
static LAST_ERROR:RefCell<Option<Box<String>>> = RefCell::new(None);
}
pub(crate) fn update_last_error(err: anyhow::Error) {
LAST_ERROR.with(|prev| {
*prev.borrow_mut() = Some(Box::new(format!("{:?}", err)));
});
}
pub(crate) fn take_last_error() -> Option<Box<String>> {
LAST_ERROR.with(|prev| prev.borrow_mut().take())
}
#[no_mangle]
pub extern "C" fn last_error_length() -> c_int {
LAST_ERROR.with(|prev| match *prev.borrow() {
Some(ref err) => err.to_string().len() as c_int + 1,
None => 0,
})
}
#[no_mangle]
pub unsafe extern "C" fn last_error_message(buffer: *mut c_char, length: c_int) -> c_int {
if buffer.is_null() {
return -1;
}
let last_error = match take_last_error() {
Some(err) => err,
None => return 0,
};
let error_message = last_error.to_string();
let buffer = std::slice::from_raw_parts_mut(buffer as *mut u8, length as usize);
if error_message.len() >= buffer.len() {
return -1;
}
std::ptr::copy_nonoverlapping(
error_message.as_ptr(),
buffer.as_mut_ptr(),
error_message.len(),
);
// Add a trailing null so people using the string as a `char *` don't
// accidentally read into garbage.
buffer[error_message.len()] = 0;
error_message.len() as c_int
}

View file

@ -2,24 +2,22 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::Arc; pub struct FramebufferBuilder<'device, 'renderpass, 'image> {
render_pass: Option<&'renderpass RenderPass<'device>>,
pub struct FramebufferBuilder<'a> { attachments: Vec<&'image Image<'device>>,
render_pass: Option<&'a Arc<RenderPass>>,
attachments: Vec<&'a Arc<Image>>,
width: u32, width: u32,
height: u32, height: u32,
layers: u32, layers: u32,
} }
impl<'a> FramebufferBuilder<'a> { impl<'device, 'renderpass, 'image> FramebufferBuilder<'device, 'renderpass, 'image> {
pub fn set_render_pass(mut self, render_pass: &'a Arc<RenderPass>) -> Self { pub fn set_render_pass(mut self, render_pass: &'renderpass RenderPass<'device>) -> Self {
self.render_pass = Some(render_pass); self.render_pass = Some(render_pass);
self self
} }
pub fn add_attachment(mut self, image: &'a Arc<Image>) -> Self { pub fn add_attachment(mut self, image: &'image Image<'device>) -> Self {
self.attachments.push(image); self.attachments.push(image);
self self
@ -43,7 +41,7 @@ impl<'a> FramebufferBuilder<'a> {
self self
} }
pub fn build(mut self, device: Arc<Device>) -> Result<Arc<Framebuffer>> { pub fn build(mut self, device: &'device Device) -> Result<Framebuffer<'device, 'image>> {
if self.attachments.is_empty() { if self.attachments.is_empty() {
panic!("no attachments added!"); panic!("no attachments added!");
} }
@ -80,29 +78,29 @@ impl<'a> FramebufferBuilder<'a> {
let framebuffer = device.create_framebuffer(&framebuffer_ci)?; let framebuffer = device.create_framebuffer(&framebuffer_ci)?;
Ok(Arc::new(Framebuffer { Ok(Framebuffer {
device, device,
framebuffer, framebuffer,
images, images,
width: self.width, width: self.width,
height: self.height, height: self.height,
})) })
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Framebuffer { pub struct Framebuffer<'device, 'image> {
device: Arc<Device>, device: &'device Device,
framebuffer: VkFramebuffer, framebuffer: VkFramebuffer,
images: Vec<Arc<Image>>, images: Vec<&'image Image<'device>>,
width: u32, width: u32,
height: u32, height: u32,
} }
impl Framebuffer { impl<'device, 'image> Framebuffer<'device, 'image> {
pub fn builder<'a>() -> FramebufferBuilder<'a> { pub fn builder<'renderpass>() -> FramebufferBuilder<'device, 'renderpass, 'image> {
FramebufferBuilder { FramebufferBuilder {
render_pass: None, render_pass: None,
attachments: Vec::new(), attachments: Vec::new(),
@ -120,11 +118,11 @@ impl Framebuffer {
self.height self.height
} }
pub fn attachments(&self) -> &[Arc<Image>] { pub fn attachments(&self) -> &[&'image Image<'device>] {
&self.images &self.images
} }
pub fn image(&self, index: usize) -> &Arc<Image> { pub fn image(&self, index: usize) -> &Image<'device> {
&self.images[index] &self.images[index]
} }
@ -133,15 +131,15 @@ impl Framebuffer {
} }
} }
impl VulkanDevice for Framebuffer { impl<'device, 'image> VulkanDevice for Framebuffer<'device, 'image> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle!(Framebuffer, VkFramebuffer, framebuffer); impl_vk_handle!(Framebuffer<'device, 'image>, VkFramebuffer, framebuffer);
impl Drop for Framebuffer { impl<'device, 'image> Drop for Framebuffer<'device, 'image> {
fn drop(&mut self) { fn drop(&mut self) {
self.device.destroy_framebuffer(self.framebuffer); self.device.destroy_framebuffer(self.framebuffer);
} }

View file

@ -9,20 +9,20 @@ use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::Duration; use std::time::Duration;
enum ImageSourceType { enum ImageSourceType<'a> {
Empty, Empty,
Raw(Vec<u8>), Raw(Vec<u8>),
Array(Vec<Arc<Image>>), Array(Vec<Image<'a>>),
} }
struct ImageCreateInfo { struct ImageCreateInfo<'a> {
vk_image_create_info: VkImageCreateInfo, vk_image_create_info: VkImageCreateInfo,
source_type: ImageSourceType, source_type: ImageSourceType<'a>,
} }
impl ImageCreateInfo { impl<'a> ImageCreateInfo<'a> {
fn default(source_type: ImageSourceType) -> Self { fn default(source_type: ImageSourceType<'a>) -> Self {
ImageCreateInfo { ImageCreateInfo {
vk_image_create_info: VkImageCreateInfo::new( vk_image_create_info: VkImageCreateInfo::new(
0, 0,
@ -62,15 +62,15 @@ struct PreinitializedImage {
assume_layout: bool, assume_layout: bool,
} }
enum ImageBuilderInternalType { enum ImageBuilderInternalType<'a> {
PreinitializedImage(PreinitializedImage), PreinitializedImage(PreinitializedImage),
NewImage(ImageCreateInfo), NewImage(ImageCreateInfo<'a>),
} }
/// Implements the builder pattern for Image /// Implements the builder pattern for Image
pub struct ImageBuilder { pub struct ImageBuilder<'a> {
file_name: Option<AssetPath>, file_name: Option<AssetPath>,
builder_type: ImageBuilderInternalType, builder_type: ImageBuilderInternalType<'a>,
components: VkComponentMapping, components: VkComponentMapping,
view_type: VkImageViewType, view_type: VkImageViewType,
subresource_range: VkImageSubresourceRange, subresource_range: VkImageSubresourceRange,
@ -78,9 +78,9 @@ pub struct ImageBuilder {
sampler: Option<Arc<Sampler>>, sampler: Option<Arc<Sampler>>,
} }
impl ImageBuilder { impl<'a> ImageBuilder<'a> {
/// Sets up the ImageBuilder for further use /// Sets up the ImageBuilder for further use
fn new(internal_type: ImageBuilderInternalType) -> Self { fn new(internal_type: ImageBuilderInternalType<'a>) -> Self {
ImageBuilder { ImageBuilder {
file_name: None, file_name: None,
builder_type: internal_type, builder_type: internal_type,
@ -98,7 +98,7 @@ impl ImageBuilder {
} }
} }
pub fn build(self, device: &Arc<Device>, queue: &Arc<Mutex<Queue>>) -> Result<Arc<Image>> { pub fn build(self, device: &'a Device, queue: &'a Mutex<Queue<'a>>) -> Result<Image<'a>> {
let mut image_view_ci = self.vk_image_view_create_info(); let mut image_view_ci = self.vk_image_view_create_info();
match self.builder_type { match self.builder_type {
@ -107,9 +107,9 @@ impl ImageBuilder {
let image_view = device.create_image_view(&image_view_ci)?; let image_view = device.create_image_view(&image_view_ci)?;
let image = Arc::new(Image { let image = Image {
device: device.clone(), device,
queue: queue.clone(), queue,
image: preinitialized_image.image, image: preinitialized_image.image,
image_view, image_view,
@ -130,7 +130,7 @@ impl ImageBuilder {
levels: 1, levels: 1,
sample_count: preinitialized_image.sample_count, sample_count: preinitialized_image.sample_count,
usage: preinitialized_image.usage, usage: preinitialized_image.usage,
}); };
// TODO: check necessity // TODO: check necessity
if !preinitialized_image.assume_layout { if !preinitialized_image.assume_layout {
@ -384,13 +384,13 @@ impl ImageBuilder {
} }
fn create_from_source( fn create_from_source(
device: &Arc<Device>, device: &'a Device,
queue: &Arc<Mutex<Queue>>, queue: &'a Mutex<Queue<'a>>,
info: &ImageCreateInfo, info: &ImageCreateInfo<'a>,
sampler: Option<Arc<Sampler>>, sampler: Option<Arc<Sampler>>,
mut view_ci: VkImageViewCreateInfo, mut view_ci: VkImageViewCreateInfo,
file_name: Option<AssetPath>, file_name: Option<AssetPath>,
) -> Result<Arc<Image>> { ) -> Result<Image<'a>> {
let format = view_ci.format; let format = view_ci.format;
let (image, memory) = Self::create_texture(device, &info.vk_image_create_info)?; let (image, memory) = Self::create_texture(device, &info.vk_image_create_info)?;
@ -399,9 +399,9 @@ impl ImageBuilder {
let image_view = device.create_image_view(&view_ci)?; let image_view = device.create_image_view(&view_ci)?;
Ok(Arc::new(Image { Ok(Image {
device: device.clone(), device,
queue: queue.clone(), queue,
image, image,
image_view, image_view,
@ -422,13 +422,13 @@ impl ImageBuilder {
levels: info.vk_image_create_info.mipLevels, levels: info.vk_image_create_info.mipLevels,
sample_count: info.vk_image_create_info.samples, sample_count: info.vk_image_create_info.samples,
usage: info.vk_image_create_info.usage, usage: info.vk_image_create_info.usage,
})) })
} }
fn create_texture( fn create_texture(
device: &Arc<Device>, device: &'a Device,
image_ci: &VkImageCreateInfo, image_ci: &VkImageCreateInfo,
) -> Result<(VkImage, Arc<Memory<RawBuffer>>)> { ) -> Result<(VkImage, Memory<'a, RawBuffer>)> {
let image = Self::create_image(device, image_ci)?; let image = Self::create_image(device, image_ci)?;
let memory = Memory::image_memory( let memory = Memory::image_memory(
device, device,
@ -439,7 +439,7 @@ impl ImageBuilder {
Ok((image, memory)) Ok((image, memory))
} }
fn create_image(device: &Arc<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,18 +447,18 @@ impl ImageBuilder {
} }
fn optimize_fill( fn optimize_fill(
device: &Arc<Device>, device: &'a Device,
queue: &Arc<Mutex<Queue>>, queue: &'a Mutex<Queue<'a>>,
data: &[RawBuffer], data: &[RawBuffer],
image: &Arc<Image>, image: &Image<'a>,
) -> Result<()> { ) -> Result<()> {
let staging_buffer = Buffer::builder() let staging_buffer = Buffer::builder()
.set_usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT) .set_usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT)
.set_memory_usage(MemoryUsage::CpuToGpu) .set_memory_usage(MemoryUsage::CpuToGpu)
.set_data(data) .set_data(data)
.build(device.clone())?; .build(device)?;
copy_buffer_to_image(device, queue, &staging_buffer, image)?; copy_buffer_to_image(image, device, queue, &staging_buffer)?;
Ok(()) Ok(())
} }
@ -469,12 +469,12 @@ impl ImageBuilder {
/// handles VkImage, VkSampler, VkDeviceSize and VkImageView internally /// handles VkImage, VkSampler, VkDeviceSize and VkImageView internally
/// just as you set it up to /// just as you set it up to
#[derive(Debug)] #[derive(Debug)]
pub struct Image { pub struct Image<'a> {
// device handle // device handle
device: Arc<Device>, device: &'a Device,
// queue handle // queue handle
queue: Arc<Mutex<Queue>>, queue: &'a Mutex<Queue<'a>>,
file_name: Option<AssetPath>, file_name: Option<AssetPath>,
@ -486,7 +486,7 @@ pub struct Image {
image_view: VkImageView, image_view: VkImageView,
// optional handles // optional handles
_memory: Option<Arc<Memory<RawBuffer>>>, _memory: Option<Memory<'a, RawBuffer>>,
sampler: Option<Arc<Sampler>>, sampler: Option<Arc<Sampler>>,
// image information // image information
@ -502,7 +502,7 @@ pub struct Image {
usage: VkImageUsageFlagBits, usage: VkImageUsageFlagBits,
} }
impl Image { impl<'a> Image<'a> {
/// Creates an `ImageBuilder` where you can define the image for your needs /// Creates an `ImageBuilder` where you can define the image for your needs
/// ///
/// For example, this is used to wrap swapchain images /// For example, this is used to wrap swapchain images
@ -519,7 +519,7 @@ impl Image {
layout: VkImageLayout, layout: VkImageLayout,
usage: impl Into<VkImageUsageFlagBits>, usage: impl Into<VkImageUsageFlagBits>,
assume_layout: bool, assume_layout: bool,
) -> ImageBuilder { ) -> ImageBuilder<'a> {
ImageBuilder::new(ImageBuilderInternalType::PreinitializedImage( ImageBuilder::new(ImageBuilderInternalType::PreinitializedImage(
PreinitializedImage { PreinitializedImage {
image, image,
@ -545,7 +545,7 @@ impl Image {
/// * `source` - The color information for the image /// * `source` - The color information for the image
/// * `width` - The target width of the image /// * `width` - The target width of the image
/// * `height` - The target height of the image /// * `height` - The target height of the image
pub fn from_raw(source: Vec<u8>, width: u32, height: u32) -> ImageBuilder { pub fn from_raw(source: Vec<u8>, width: u32, height: u32) -> ImageBuilder<'a> {
let mut create_info = ImageCreateInfo::default(ImageSourceType::Raw(source)); let mut create_info = ImageCreateInfo::default(ImageSourceType::Raw(source));
create_info.vk_image_create_info.extent.width = width; create_info.vk_image_create_info.extent.width = width;
create_info.vk_image_create_info.extent.height = height; create_info.vk_image_create_info.extent.height = height;
@ -563,7 +563,7 @@ impl Image {
/// # Arguments /// # Arguments
/// ///
/// * `file` - The path to the file /// * `file` - The path to the file
pub fn from_file(file: AssetPath) -> Result<ImageBuilder> { pub fn from_file(file: AssetPath) -> Result<ImageBuilder<'a>> {
let texture = match image::open(&file.full_path()) { let texture = match image::open(&file.full_path()) {
Ok(i) => i.to_rgba8(), Ok(i) => i.to_rgba8(),
Err(err) => return Err(anyhow::Error::new(err).context(file.full_path())), Err(err) => return Err(anyhow::Error::new(err).context(file.full_path())),
@ -591,7 +591,7 @@ impl Image {
/// # Arguments /// # Arguments
/// ///
/// * `slice` - Slice of bytes /// * `slice` - Slice of bytes
pub fn from_slice(data: &[u8]) -> Result<ImageBuilder> { pub fn from_slice(data: &[u8]) -> Result<ImageBuilder<'a>> {
let texture = image::load_from_memory(data)?.to_rgba8(); let texture = image::load_from_memory(data)?.to_rgba8();
let (width, height) = texture.dimensions(); let (width, height) = texture.dimensions();
@ -607,7 +607,7 @@ impl Image {
/// # Arguments /// # Arguments
/// ///
/// * `array` - Source images /// * `array` - Source images
pub fn from_array(array: Vec<Arc<Image>>) -> ImageBuilder { pub fn from_array(array: Vec<Image<'a>>) -> ImageBuilder<'a> {
debug_assert!(array.is_empty(), "images array must not be empty"); debug_assert!(array.is_empty(), "images array must not be empty");
let width = array[0].width(); let width = array[0].width();
@ -652,7 +652,7 @@ impl Image {
height: u32, height: u32,
usage: impl Into<VkImageUsageFlagBits>, usage: impl Into<VkImageUsageFlagBits>,
sample_count: VkSampleCountFlags, sample_count: VkSampleCountFlags,
) -> ImageBuilder { ) -> ImageBuilder<'a> {
let mut create_info = ImageCreateInfo::default(ImageSourceType::Empty); let mut create_info = ImageCreateInfo::default(ImageSourceType::Empty);
create_info.vk_image_create_info.samples = sample_count.into(); create_info.vk_image_create_info.samples = sample_count.into();
create_info.vk_image_create_info.extent.width = width; create_info.vk_image_create_info.extent.width = width;
@ -664,7 +664,7 @@ impl Image {
} }
pub fn check_configuration( pub fn check_configuration(
device: &Arc<Device>, device: &'a Device,
tiling: VkImageTiling, tiling: VkImageTiling,
format: VkFormat, format: VkFormat,
usage: impl Into<VkImageUsageFlagBits>, usage: impl Into<VkImageUsageFlagBits>,
@ -677,11 +677,11 @@ impl Image {
} }
} }
pub fn device(&self) -> &Arc<Device> { pub fn device(&self) -> &Device {
&self.device &self.device
} }
pub fn queue(&self) -> &Arc<Mutex<Queue>> { pub fn queue(&self) -> &Mutex<Queue<'a>> {
&self.queue &self.queue
} }
@ -689,7 +689,7 @@ impl Image {
self.file_name.as_ref() self.file_name.as_ref()
} }
pub fn convert_layout(self: &Arc<Self>, target_layout: VkImageLayout) -> Result<()> { pub fn convert_layout(&self, target_layout: VkImageLayout) -> Result<()> {
into_layout(self, target_layout) into_layout(self, target_layout)
} }
@ -788,7 +788,7 @@ impl Image {
} }
} }
pub fn to_file(self: &Arc<Image>, path: impl AsRef<Path>) -> Result<()> { pub fn to_file(&self, path: impl AsRef<Path>) -> Result<()> {
// check if image is created with correct usage flag that allows transfering data from it // check if image is created with correct usage flag that allows transfering data from it
if (self.usage | VK_IMAGE_USAGE_TRANSFER_SRC_BIT) == 0 { if (self.usage | VK_IMAGE_USAGE_TRANSFER_SRC_BIT) == 0 {
return Err(anyhow::anyhow!( return Err(anyhow::anyhow!(
@ -815,9 +815,9 @@ impl Image {
} }
pub fn copy_image_to_buffer( pub fn copy_image_to_buffer(
self: &Arc<Image>, &self,
extra_buffer_flags: impl Into<Option<VkBufferUsageFlagBits>>, extra_buffer_flags: impl Into<Option<VkBufferUsageFlagBits>>,
) -> Result<Arc<Buffer<RawBuffer>>> { ) -> Result<Buffer<'a, RawBuffer>> {
let usage = match extra_buffer_flags.into() { let usage = match extra_buffer_flags.into() {
Some(flags) => VK_BUFFER_USAGE_TRANSFER_DST_BIT | flags, Some(flags) => VK_BUFFER_USAGE_TRANSFER_DST_BIT | flags,
None => VK_BUFFER_USAGE_TRANSFER_DST_BIT.into(), None => VK_BUFFER_USAGE_TRANSFER_DST_BIT.into(),
@ -829,10 +829,10 @@ impl Image {
.set_size((self.width * self.height * 4) as VkDeviceSize) .set_size((self.width * self.height * 4) as VkDeviceSize)
.build(self.device.clone())?; .build(self.device.clone())?;
let command_buffer = let mut command_buffer =
CommandBuffer::new_primary().build(self.device.clone(), self.queue.clone())?; CommandBuffer::new_primary().build(self.device.clone(), self.queue.clone())?;
SingleSubmit::builder(&command_buffer, &self.queue, |recorder| { SingleSubmit::builder(&mut command_buffer, &self.queue, |recorder| {
// copy info for copying the content of the buffer into the image // copy info for copying the content of the buffer into the image
let buffer_image_copy = VkBufferImageCopy { let buffer_image_copy = VkBufferImageCopy {
bufferOffset: 0, bufferOffset: 0,
@ -885,21 +885,21 @@ impl Image {
Ok(buffer) Ok(buffer)
} }
pub fn copy_buffer_to_image(self: &Arc<Image>, buffer: &Arc<Buffer<RawBuffer>>) -> Result<()> { pub fn copy_buffer_to_image(&self, buffer: &Arc<Buffer<'a, RawBuffer>>) -> Result<()> {
copy_buffer_to_image(&self.device, &self.queue, &buffer, self) copy_buffer_to_image(self, &self.device, &self.queue, &buffer)
} }
} }
impl VulkanDevice for Image { impl<'a> VulkanDevice for Image<'a> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
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 Drop for Image { impl<'a> Drop for Image<'a> {
fn drop(&mut self) { fn drop(&mut self) {
self.device.destroy_image_view(self.image_view); self.device.destroy_image_view(self.image_view);
@ -909,10 +909,9 @@ impl Drop for Image {
} }
} }
fn into_layout(image: &Arc<Image>, 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 = let mut command_buffer = CommandBuffer::new_primary().build(image.device, image.queue)?;
CommandBuffer::new_primary().build(image.device.clone(), image.queue.clone())?;
{ {
// begin recording into this command buffer // begin recording into this command buffer
@ -950,17 +949,17 @@ fn into_layout(image: &Arc<Image>, layout: VkImageLayout) -> Result<()> {
Ok(()) Ok(())
} }
fn copy_buffer_to_image<T: ReprC + Send + Sync + 'static>( fn copy_buffer_to_image<'a, T: ReprC + Send + Sync + 'static>(
device: &Arc<Device>, image: &Image<'a>,
queue: &Arc<Mutex<Queue>>, device: &'a Device,
buffer: &Arc<Buffer<T>>, queue: &'a Mutex<Queue<'a>>,
image: &Arc<Image>, buffer: &Buffer<'a, T>,
) -> Result<()> ) -> Result<()>
where 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, queue)?;
{ {
// begin recording into this command buffer // begin recording into this command buffer
@ -1045,14 +1044,14 @@ where
Ok(()) Ok(())
} }
fn copy_images_to_imagearray( fn copy_images_to_imagearray<'a>(
device: &Arc<Device>, device: &'a Device,
queue: &Arc<Mutex<Queue>>, queue: &'a Mutex<Queue<'a>>,
image_array: &Arc<Image>, image_array: &Image<'a>,
images: &[Arc<Image>], 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
@ -1119,10 +1118,10 @@ fn copy_images_to_imagearray(
Ok(()) Ok(())
} }
fn copy_image_to_image( fn copy_image_to_image<'device, 'pipeline, 'cbuffer>(
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
src_image: &Arc<Image>, src_image: &Image<'device>,
dst_image: &Arc<Image>, dst_image: &Image<'device>,
mip_level: u32, mip_level: u32,
dst_layer: u32, dst_layer: u32,
) { ) {
@ -1181,9 +1180,9 @@ fn copy_image_to_image(
); );
} }
fn blit_mip_maps( fn blit_mip_maps<'device, 'pipeline, 'cbuffer>(
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
image: &Arc<Image>, image: &Image<'device>,
target_image_layout: VkImageLayout, target_image_layout: VkImageLayout,
) { ) {
let mut mip_width = image.width(); let mut mip_width = image.width();

View file

@ -6,7 +6,6 @@ use std::collections::HashSet;
use std::fmt; use std::fmt;
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use std::ptr; use std::ptr;
use std::sync::Arc;
use std::os::raw::c_char; use std::os::raw::c_char;
use std::os::raw::c_void; use std::os::raw::c_void;
@ -104,7 +103,7 @@ impl Instance {
proc_addr: PFN_vkGetInstanceProcAddr, proc_addr: PFN_vkGetInstanceProcAddr,
extensions: &[VkString], extensions: &[VkString],
api_version: Option<u32>, api_version: Option<u32>,
) -> Result<Arc<Instance>> { ) -> Result<Instance> {
let static_functions = StaticFunctions { let static_functions = StaticFunctions {
_lib: None, _lib: None,
vkGetInstanceProcAddr: proc_addr, vkGetInstanceProcAddr: proc_addr,
@ -122,7 +121,7 @@ impl Instance {
let instance_extensions = InstanceExtensions::from_list(extensions); let instance_extensions = InstanceExtensions::from_list(extensions);
let instance = Arc::new(Instance { let instance = Instance {
_static_functions: static_functions, _static_functions: static_functions,
_entry_functions: None, _entry_functions: None,
instance_functions, instance_functions,
@ -138,7 +137,7 @@ impl Instance {
debug_report: None, debug_report: None,
api_version: api_version.unwrap_or(VK_MAKE_VERSION(1, 0, 0)), api_version: api_version.unwrap_or(VK_MAKE_VERSION(1, 0, 0)),
}); };
Ok(instance) Ok(instance)
} }
@ -147,7 +146,7 @@ impl Instance {
app_info: VkApplicationInfo<'_>, app_info: VkApplicationInfo<'_>,
debug_info: VulkanDebugInfo, debug_info: VulkanDebugInfo,
mut extensions: InstanceExtensions, mut extensions: InstanceExtensions,
) -> Result<Arc<Instance>> { ) -> Result<Instance> {
// required in physical device // required in physical device
extensions.physical_device_properties2 = true; extensions.physical_device_properties2 = true;
@ -267,7 +266,7 @@ impl Instance {
} }
} }
Ok(Arc::new(instance)) Ok(instance)
} }
pub(crate) fn api_version(&self) -> u32 { pub(crate) fn api_version(&self) -> u32 {

View file

@ -39,8 +39,6 @@ pub mod shadermodule;
pub mod surface; pub mod surface;
pub mod swapchain; pub mod swapchain;
pub mod ffi;
mod sampler_manager; mod sampler_manager;
mod single_submit; mod single_submit;
@ -56,13 +54,11 @@ pub trait VkHandle<T> {
} }
pub trait VulkanDevice { pub trait VulkanDevice {
fn device(&self) -> &std::sync::Arc<device::Device>; fn device(&self) -> &device::Device;
} }
pub fn create_vk_handles() -> anyhow::Result<( pub fn create_vk_handles<'a>(
std::sync::Arc<prelude::Device>, ) -> anyhow::Result<(prelude::Device, std::sync::Mutex<prelude::Queue<'a>>)> {
std::sync::Arc<std::sync::Mutex<prelude::Queue>>,
)> {
use crate::prelude::*; use crate::prelude::*;
let instance = Instance::new( let instance = Instance::new(

View file

@ -1,49 +1,25 @@
macro_rules! impl_vk_handle { macro_rules! impl_vk_handle {
($struct_name:ident $(<$( $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$(<$($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<'a $($(, $const $name: $type)*)?> VkHandle<$target_name> for &'a $struct_name$(<$($name,)?>)? { impl<'x $($(, $lt )* $(, $const $name: $type)*)?> VkHandle<$target_name> for &'x $struct_name$(<$($lt, )* $($name,)*>)? {
fn vk_handle(&self) -> $target_name {
self.$value
}
}
impl$(<$( $const $name: $type, )*>)? VkHandle<$target_name> for Arc<$struct_name$(<$($name,)?>)?> {
fn vk_handle(&self) -> $target_name {
self.$value
}
}
impl<'a $($(, $const $name: $type)*)?> VkHandle<$target_name> for &'a Arc<$struct_name$(<$($name,)?>)?> {
fn vk_handle(&self) -> $target_name { fn vk_handle(&self) -> $target_name {
self.$value self.$value
} }
} }
}; };
($struct_name:ident $(<$( $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => { ($struct_name:ident $(<$( $lt:lifetime $(,)? )* $( $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => {
impl$(<$( $name: $type, )*>)? VkHandle<$target_name> for $struct_name$(<$($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<'a $($(, $name: $type)*)?> VkHandle<$target_name> for &'a $struct_name$(<$($name,)?>)? { impl<'x $($(, $lt, )* $(, $name: $type)*)?> VkHandle<$target_name> for &'x $struct_name$(<$($lt, )* $($name,)*>)? {
fn vk_handle(&self) -> $target_name {
self.$value
}
}
impl$(<$( $name: $type, )*>)? VkHandle<$target_name> for Arc<$struct_name$(<$($name,)?>)?> {
fn vk_handle(&self) -> $target_name {
self.$value
}
}
impl<'a $($(, $name: $type)*)?> VkHandle<$target_name> for &'a Arc<$struct_name$(<$($name,)?>)?> {
fn vk_handle(&self) -> $target_name { fn vk_handle(&self) -> $target_name {
self.$value self.$value
} }
@ -52,26 +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 {
self.$value
}
}
impl<T $(: $($t,)* )?> VkHandle<$target_name> for Arc<$struct_name<T>> {
fn vk_handle(&self) -> $target_name {
self.$value
}
}
impl<'a, T $(: $($t,)* )?> VkHandle<$target_name> for &'a Arc<$struct_name<T>> {
fn vk_handle(&self) -> $target_name { fn vk_handle(&self) -> $target_name {
self.$value self.$value
} }

View file

@ -6,13 +6,12 @@ use utilities::impl_reprc;
use vma_rs::prelude::*; use vma_rs::prelude::*;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::Arc;
impl_reprc!( impl_reprc!(
#[derive(Debug, Copy)] #[derive(Debug, Copy)]
pub struct RawBuffer { pub struct RawBuffer {
#[assume_reprc] #[assume_reprc]
pub d: u8, d: u8,
} }
); );
@ -45,45 +44,42 @@ impl Into<VmaMemoryUsage> for MemoryUsage {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Memory<T: ReprC> { pub struct Memory<'a, T: ReprC> {
device: Arc<Device>, device: &'a Device,
allocation: Allocation, allocation: Allocation,
data_type: PhantomData<T>, data_type: PhantomData<T>,
} }
impl<T: ReprC> Memory<T> { impl<'a, T: ReprC> Memory<'a, T> {
pub(crate) fn forced_requirements( pub(crate) fn forced_requirements(
device: &Arc<Device>, device: &'a Device,
memory_requirements: VkMemoryRequirements, memory_requirements: VkMemoryRequirements,
buffer: VkBuffer, buffer: VkBuffer,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
) -> Result<Arc<Memory<T>>> { ) -> Result<Memory<'a, T>> {
let mut memory = Self::create_and_bind(device, memory_requirements, memory_usage, ())?; let mut memory = Self::create_and_bind(device, memory_requirements, memory_usage, ())?;
memory.allocation.bind_buffer_memory(buffer)?;
if let Some(mut_memory) = Arc::get_mut(&mut memory) {
mut_memory.allocation.bind_buffer_memory(buffer)?;
}
Ok(memory) Ok(memory)
} }
pub(crate) fn buffer_memory( pub(crate) fn buffer_memory(
device: &Arc<Device>, device: &'a Device,
buffer: VkBuffer, buffer: VkBuffer,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
) -> Result<Arc<Memory<T>>> { ) -> Result<Memory<'a, T>> {
let memory_requirements = device.buffer_memory_requirements(buffer); let memory_requirements = device.buffer_memory_requirements(buffer);
Self::create_and_bind(device, memory_requirements, memory_usage, buffer) Self::create_and_bind(device, memory_requirements, memory_usage, buffer)
} }
pub(crate) fn image_memory( pub(crate) fn image_memory(
device: &Arc<Device>, device: &'a Device,
image: VkImage, image: VkImage,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
) -> Result<Arc<Memory<T>>> { ) -> Result<Memory<'a, T>> {
let memory_requirements = device.image_memory_requirements(image); let memory_requirements = device.image_memory_requirements(image);
Self::create_and_bind(device, memory_requirements, memory_usage, image) Self::create_and_bind(device, memory_requirements, memory_usage, image)
@ -94,22 +90,22 @@ impl<T: ReprC> Memory<T> {
} }
} }
trait MemoryBinder<T, K: ReprC> { trait MemoryBinder<'a, T, K: ReprC> {
fn create_and_bind( fn create_and_bind(
device: &Arc<Device>, device: &'a Device,
memory_requirements: VkMemoryRequirements, memory_requirements: VkMemoryRequirements,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
argument: T, argument: T,
) -> Result<Arc<Memory<K>>>; ) -> Result<Memory<'a, K>>;
} }
impl<K: ReprC> MemoryBinder<(), K> for Memory<K> { impl<'a, K: ReprC> MemoryBinder<'a, (), K> for Memory<'a, K> {
fn create_and_bind( fn create_and_bind(
device: &Arc<Device>, device: &'a Device,
memory_requirements: VkMemoryRequirements, memory_requirements: VkMemoryRequirements,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
_: (), _: (),
) -> Result<Arc<Memory<K>>> { ) -> Result<Memory<'a, K>> {
let allocation = device let allocation = device
.allocator() .allocator()
.allocate() .allocate()
@ -117,23 +113,23 @@ impl<K: ReprC> MemoryBinder<(), K> for Memory<K> {
.set_memory_type_bits(memory_requirements.memoryTypeBits.into()) .set_memory_type_bits(memory_requirements.memoryTypeBits.into())
.build(&memory_requirements)?; .build(&memory_requirements)?;
Ok(Arc::new(Memory { Ok(Memory {
device: device.clone(), device,
allocation, allocation,
data_type: PhantomData, data_type: PhantomData,
})) })
} }
} }
impl<K: ReprC> MemoryBinder<VkImage, K> for Memory<K> { impl<'a, K: ReprC> MemoryBinder<'a, VkImage, K> for Memory<'a, K> {
fn create_and_bind( fn create_and_bind(
device: &Arc<Device>, device: &'a Device,
memory_requirements: VkMemoryRequirements, memory_requirements: VkMemoryRequirements,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
image: VkImage, image: VkImage,
) -> Result<Arc<Memory<K>>> { ) -> Result<Memory<'a, K>> {
let allocation = device let allocation = device
.allocator() .allocator()
.allocate() .allocate()
@ -141,23 +137,23 @@ impl<K: ReprC> MemoryBinder<VkImage, K> for Memory<K> {
.set_memory_type_bits(memory_requirements.memoryTypeBits.into()) .set_memory_type_bits(memory_requirements.memoryTypeBits.into())
.build(image)?; .build(image)?;
Ok(Arc::new(Memory { Ok(Memory {
device: device.clone(), device,
allocation, allocation,
data_type: PhantomData, data_type: PhantomData,
})) })
} }
} }
impl<K: ReprC> MemoryBinder<VkBuffer, K> for Memory<K> { impl<'a, K: ReprC> MemoryBinder<'a, VkBuffer, K> for Memory<'a, K> {
fn create_and_bind( fn create_and_bind(
device: &Arc<Device>, device: &'a Device,
memory_requirements: VkMemoryRequirements, memory_requirements: VkMemoryRequirements,
memory_usage: VmaMemoryUsage, memory_usage: VmaMemoryUsage,
buffer: VkBuffer, buffer: VkBuffer,
) -> Result<Arc<Memory<K>>> { ) -> Result<Memory<'a, K>> {
let allocation = device let allocation = device
.allocator() .allocator()
.allocate() .allocate()
@ -165,23 +161,23 @@ impl<K: ReprC> MemoryBinder<VkBuffer, K> for Memory<K> {
.set_memory_type_bits(memory_requirements.memoryTypeBits.into()) .set_memory_type_bits(memory_requirements.memoryTypeBits.into())
.build(buffer)?; .build(buffer)?;
Ok(Arc::new(Memory { Ok(Memory {
device: device.clone(), device,
allocation, allocation,
data_type: PhantomData, data_type: PhantomData,
})) })
} }
} }
impl<T: ReprC> VulkanDevice for Memory<T> { impl<'a, T: ReprC> VulkanDevice for Memory<'a, T> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl<T: ReprC + Clone> Memory<T> { impl<'a, T: ReprC + Clone> Memory<'a, T> {
pub fn map(&self, length: VkDeviceSize) -> Result<VkMappedMemory<'_, T>> { pub fn map(&self, length: VkDeviceSize) -> Result<VkMappedMemory<'_, T>> {
self.allocation.map(length) self.allocation.map(length)
} }

View file

@ -2,11 +2,11 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::{ptr, sync::Arc}; use std::ptr;
#[derive(Debug)] #[derive(Debug)]
pub struct PhysicalDevice { pub struct PhysicalDevice {
instance: Arc<Instance>, instance: Instance,
physical_device: VkPhysicalDevice, physical_device: VkPhysicalDevice,
properties: VkPhysicalDeviceProperties, properties: VkPhysicalDeviceProperties,
features: VkPhysicalDeviceFeatures, features: VkPhysicalDeviceFeatures,
@ -26,7 +26,7 @@ pub struct PhysicalDevice {
} }
impl PhysicalDevice { impl PhysicalDevice {
pub fn new(instance: Arc<Instance>) -> Result<Arc<PhysicalDevice>> { pub fn new(instance: Instance) -> Result<PhysicalDevice> {
let physical_devices = instance.enumerate_physical_devices()?; let physical_devices = instance.enumerate_physical_devices()?;
let (mut physical_device, mut device_properties) = PhysicalDevice::find_phys_dev( let (mut physical_device, mut device_properties) = PhysicalDevice::find_phys_dev(
@ -57,19 +57,19 @@ impl PhysicalDevice {
} }
pub fn from_raw( pub fn from_raw(
instance: Arc<Instance>, instance: Instance,
physical_device: VkPhysicalDevice, physical_device: VkPhysicalDevice,
) -> Result<Arc<PhysicalDevice>> { ) -> Result<PhysicalDevice> {
let properties = instance.physical_device_properties(physical_device); let properties = instance.physical_device_properties(physical_device);
Self::internal_new(instance, physical_device, properties) Self::internal_new(instance, physical_device, properties)
} }
fn internal_new( fn internal_new(
instance: Arc<Instance>, instance: Instance,
physical_device: VkPhysicalDevice, physical_device: VkPhysicalDevice,
properties: VkPhysicalDeviceProperties, properties: VkPhysicalDeviceProperties,
) -> Result<Arc<PhysicalDevice>> { ) -> Result<PhysicalDevice> {
let device_features = instance.physical_device_features(physical_device); let device_features = instance.physical_device_features(physical_device);
let device_memory_properties = instance.physical_device_memory_properties(physical_device); let device_memory_properties = instance.physical_device_memory_properties(physical_device);
@ -134,7 +134,7 @@ impl PhysicalDevice {
patch patch
); );
Ok(Arc::new(PhysicalDevice { Ok(PhysicalDevice {
instance, instance,
physical_device, physical_device,
properties, properties,
@ -151,13 +151,13 @@ impl PhysicalDevice {
descriptor_indexing_features, descriptor_indexing_features,
buffer_device_address_features, buffer_device_address_features,
})) })
} }
} }
// getter // getter
impl PhysicalDevice { impl PhysicalDevice {
pub fn instance(&self) -> &Arc<Instance> { pub fn instance(&self) -> &Instance {
&self.instance &self.instance
} }
@ -305,7 +305,7 @@ impl_vk_handle!(PhysicalDevice, VkPhysicalDevice, physical_device);
// private // private
impl PhysicalDevice { impl PhysicalDevice {
fn find_phys_dev( fn find_phys_dev(
instance: &Arc<Instance>, instance: &Instance,
physical_devices: &[VkPhysicalDevice], physical_devices: &[VkPhysicalDevice],
device_type: VkPhysicalDeviceType, device_type: VkPhysicalDeviceType,
) -> (Option<VkPhysicalDevice>, Option<VkPhysicalDeviceProperties>) { ) -> (Option<VkPhysicalDevice>, Option<VkPhysicalDeviceProperties>) {
@ -321,7 +321,7 @@ impl PhysicalDevice {
} }
fn query_extensions( fn query_extensions(
instance: &Arc<Instance>, instance: &Instance,
physical_device: VkPhysicalDevice, physical_device: VkPhysicalDevice,
) -> Result<Vec<VkString>> { ) -> Result<Vec<VkString>> {
let extensions = instance.enumerate_device_extensions(physical_device)?; let extensions = instance.enumerate_device_extensions(physical_device)?;

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) -> &Arc<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

@ -38,7 +38,7 @@ impl PipelineCache {
} }
impl VulkanDevice for PipelineCache { impl VulkanDevice for PipelineCache {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }

View file

@ -59,7 +59,7 @@ impl PipelineLayout {
} }
impl VulkanDevice for PipelineLayout { impl VulkanDevice for PipelineLayout {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }

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)> { ) -> 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>,
@ -14,8 +12,8 @@ pub(crate) struct ShaderBindingTableBuilder {
hit_group_entries: Vec<ShaderBindingTableEntry>, hit_group_entries: Vec<ShaderBindingTableEntry>,
} }
pub struct ShaderBindingTable { pub struct ShaderBindingTable<'device> {
_sbt_buffer: Arc<Buffer<RawBuffer>>, _sbt_buffer: Buffer<'device, RawBuffer>,
raygen_shader_binding_table: VkStridedDeviceAddressRegionKHR, raygen_shader_binding_table: VkStridedDeviceAddressRegionKHR,
miss_shader_binding_table: VkStridedDeviceAddressRegionKHR, miss_shader_binding_table: VkStridedDeviceAddressRegionKHR,
@ -23,7 +21,7 @@ pub struct ShaderBindingTable {
callable_shader_binding_table: VkStridedDeviceAddressRegionKHR, callable_shader_binding_table: VkStridedDeviceAddressRegionKHR,
} }
impl ShaderBindingTable { impl<'device> ShaderBindingTable<'device> {
pub fn raygen_shader_binding_table(&self) -> &VkStridedDeviceAddressRegionKHR { pub fn raygen_shader_binding_table(&self) -> &VkStridedDeviceAddressRegionKHR {
&self.raygen_shader_binding_table &self.raygen_shader_binding_table
} }
@ -41,7 +39,7 @@ impl ShaderBindingTable {
} }
fn create( fn create(
sbt_buffer: Arc<Buffer<RawBuffer>>, sbt_buffer: Buffer<'device, RawBuffer>,
ray_gen_entry_size: VkDeviceSize, ray_gen_entry_size: VkDeviceSize,
ray_gen_entry_count: VkDeviceSize, ray_gen_entry_count: VkDeviceSize,
miss_offset: VkDeviceSize, miss_offset: VkDeviceSize,
@ -128,11 +126,11 @@ impl ShaderBindingTableBuilder {
self self
} }
pub(crate) fn build( pub(crate) fn build<'a>(
&mut self, &mut self,
device: &Arc<Device>, device: &'a Device,
pipeline: &Arc<Pipeline>, pipeline: &Pipeline<'a>,
) -> Result<ShaderBindingTable> { ) -> Result<ShaderBindingTable<'a>> {
let ray_tracing_properties = device.physical_device().ray_tracing_properties(); let ray_tracing_properties = device.physical_device().ray_tracing_properties();
let prog_id_size = ray_tracing_properties.shaderGroupHandleSize; let prog_id_size = ray_tracing_properties.shaderGroupHandleSize;
@ -194,6 +192,11 @@ impl ShaderBindingTableBuilder {
&shader_handle_storage, &shader_handle_storage,
); );
let b = sbt_data
.into_iter()
.map(|u| RawBuffer { d: u })
.collect::<Vec<RawBuffer>>();
let sbt_buffer = Buffer::builder() let sbt_buffer = Buffer::builder()
.set_usage( .set_usage(
VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR
@ -201,14 +204,8 @@ impl ShaderBindingTableBuilder {
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
) )
.set_memory_usage(MemoryUsage::CpuToGpu) .set_memory_usage(MemoryUsage::CpuToGpu)
.set_data( .set_data(b.as_slice())
sbt_data .build(device)?;
.into_iter()
.map(|u| RawBuffer { d: u })
.collect::<Vec<RawBuffer>>()
.as_slice(),
)
.build(device.clone())?;
Ok(ShaderBindingTable::create( Ok(ShaderBindingTable::create(
sbt_buffer, sbt_buffer,

View file

@ -52,7 +52,7 @@ impl QueryPool {
} }
impl VulkanDevice for QueryPool { impl VulkanDevice for QueryPool {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }

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,
@ -15,17 +11,17 @@ pub struct QueueRequestInfo {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Queue { pub struct Queue<'a> {
device: Arc<Device>, device: &'a Device,
queue: VkQueue, queue: VkQueue,
family_index: u32, family_index: u32,
queue_index: u32, queue_index: u32,
} }
impl Queue { impl<'a> Queue<'a> {
pub fn create_presentable_request_info( pub fn create_presentable_request_info(
physical_device: &Arc<PhysicalDevice>, physical_device: &PhysicalDevice,
surface: &Arc<Surface>, surface: &Surface<'a>,
queue_type: impl Into<VkQueueFlagBits>, queue_type: impl Into<VkQueueFlagBits>,
) -> Result<QueueRequestInfo> { ) -> Result<QueueRequestInfo> {
let index = let index =
@ -41,7 +37,7 @@ impl Queue {
} }
pub fn create_non_presentable_request_info( pub fn create_non_presentable_request_info(
physical_device: &Arc<PhysicalDevice>, physical_device: &PhysicalDevice,
queue_type: impl Into<VkQueueFlagBits>, queue_type: impl Into<VkQueueFlagBits>,
) -> Result<QueueRequestInfo> { ) -> Result<QueueRequestInfo> {
let index = Self::find_non_presentable_queue_index(physical_device, queue_type.into())?; let index = Self::find_non_presentable_queue_index(physical_device, queue_type.into())?;
@ -56,17 +52,17 @@ impl Queue {
} }
pub fn new( pub fn new(
device: Arc<Device>, device: &'a Device,
queue: VkQueue, queue: VkQueue,
family_index: u32, family_index: u32,
queue_index: u32, queue_index: u32,
) -> Arc<Mutex<Queue>> { ) -> Mutex<Queue<'a>> {
Arc::new(Mutex::new(Queue { Mutex::new(Queue {
device, device,
queue, queue,
family_index, family_index,
queue_index, queue_index,
})) })
} }
pub fn family_index(&self) -> u32 { pub fn family_index(&self) -> u32 {
@ -78,7 +74,7 @@ impl Queue {
} }
/// really expensiv call, since its locks the queue until it is idle /// really expensiv call, since its locks the queue until it is idle
pub fn submit(&self, fence: Option<&Arc<Fence>>, submits: &[SubmitInfo]) -> Result<()> { pub fn submit(&self, fence: Option<&Fence<'a>>, submits: &[SubmitInfo]) -> Result<()> {
let submit_infos: Vec<VkSubmitInfo> = submits.iter().map(|s| s.as_vk_submit()).collect(); let submit_infos: Vec<VkSubmitInfo> = submits.iter().map(|s| s.as_vk_submit()).collect();
let fence = match fence { let fence = match fence {
@ -93,15 +89,15 @@ impl Queue {
pub fn minimal_submit( pub fn minimal_submit(
&self, &self,
time_out: Duration, time_out: Duration,
command_buffers: &[Arc<CommandBuffer>], 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);
} }
let fence = Fence::builder().build(self.device.clone())?; let fence = Fence::builder().build(self.device)?;
self.submit(Some(&fence), slice::from_ref(&submit))?; self.submit(Some(&fence), slice::from_ref(&submit))?;
@ -113,9 +109,9 @@ impl Queue {
pub fn present( pub fn present(
&self, &self,
swapchains: &[&Arc<Swapchain>], swapchains: &[&Swapchain<'a>],
image_indices: &[u32], image_indices: &[u32],
wait_semaphores: &[&Arc<Semaphore>], wait_semaphores: &[&Semaphore<'a>],
) -> Result<OutOfDate<()>> { ) -> Result<OutOfDate<()>> {
let wait_semaphores: Vec<VkSemaphore> = let wait_semaphores: Vec<VkSemaphore> =
wait_semaphores.iter().map(|sem| sem.vk_handle()).collect(); wait_semaphores.iter().map(|sem| sem.vk_handle()).collect();
@ -140,18 +136,18 @@ impl Queue {
} }
} }
impl VulkanDevice for Queue { impl<'a> VulkanDevice for Queue<'a> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle!(Queue, VkQueue, queue); impl_vk_handle!(Queue<'a>, VkQueue, queue);
impl Queue { impl<'a> Queue<'a> {
fn find_presentable_queue_index( fn find_presentable_queue_index(
physical_device: &Arc<PhysicalDevice>, physical_device: &PhysicalDevice,
surface: &Arc<Surface>, surface: &Surface<'a>,
flags: VkQueueFlagBits, flags: VkQueueFlagBits,
) -> Result<u32> { ) -> Result<u32> {
let surface = surface.vk_handle(); let surface = surface.vk_handle();
@ -179,7 +175,7 @@ impl Queue {
} }
fn find_non_presentable_queue_index( fn find_non_presentable_queue_index(
physical_device: &Arc<PhysicalDevice>, physical_device: &PhysicalDevice,
flags: VkQueueFlagBits, flags: VkQueueFlagBits,
) -> Result<u32> { ) -> Result<u32> {
let vk_physical_device = physical_device.vk_handle(); let vk_physical_device = physical_device.vk_handle();

View file

@ -1,32 +1,32 @@
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<'device, 'image> {
old_render_target: Option<&'a RenderTarget>, old_render_target: Option<RenderTarget<'device, 'image>>,
sub_passes: Vec<SubPass>, sub_passes: Vec<SubPass<'device>>,
} }
impl<'a> RenderTargetBuilder<'a> { impl<'device, 'image> RenderTargetBuilder<'device, 'image> {
pub fn add_sub_pass(mut self, sub_pass: SubPass) -> Self { pub fn add_sub_pass(mut self, sub_pass: SubPass<'device>) -> Self {
self.sub_passes.push(sub_pass); self.sub_passes.push(sub_pass);
self self
} }
pub fn preserve_old_render_pass(mut self, render_target: &'a RenderTarget) -> Self { pub fn preserve_old_render_pass(
mut self,
render_target: RenderTarget<'device, 'image>,
) -> 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> { pub fn build(self, device: &'device Device) -> Result<RenderTarget<'device, 'image>> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
// sub passes must not be empty // sub passes must not be empty
@ -55,7 +55,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 +164,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)?
} }
}; };
@ -185,10 +185,10 @@ impl<'a> RenderTargetBuilder<'a> {
}) })
} }
fn create_framebuffers( fn create_framebuffers<'handle>(
render_pass: &Arc<RenderPass>, render_pass: &'handle RenderPass<'device>,
sub_passes: &[SubPass], sub_passes: &'handle [SubPass<'device>],
) -> Result<Vec<Arc<Framebuffer>>> { ) -> Result<Vec<Framebuffer<'device, 'image>>> {
let extent = sub_passes[0].extent(); let extent = sub_passes[0].extent();
(0..Self::max_images(sub_passes)) (0..Self::max_images(sub_passes))
@ -205,13 +205,13 @@ impl<'a> RenderTargetBuilder<'a> {
} }
} }
framebuffer_builder.build(render_pass.device().clone()) framebuffer_builder.build(render_pass.device())
}) })
.collect() .collect()
} }
#[inline] #[inline]
fn max_images(sub_passes: &[SubPass]) -> usize { fn max_images(sub_passes: &[SubPass<'device>]) -> usize {
let mut max_images = 0; let mut max_images = 0;
for sub_pass in sub_passes.iter() { for sub_pass in sub_passes.iter() {
@ -221,7 +221,10 @@ impl<'a> RenderTargetBuilder<'a> {
max_images max_images
} }
fn verify_setups(old_sub_passes: &[SubPass], new_sub_passes: &[SubPass]) -> bool { fn verify_setups(
old_sub_passes: &[SubPass<'device>],
new_sub_passes: &[SubPass<'device>],
) -> bool {
if old_sub_passes.len() != new_sub_passes.len() { if old_sub_passes.len() != new_sub_passes.len() {
return false; return false;
} }
@ -236,9 +239,9 @@ impl<'a> RenderTargetBuilder<'a> {
} }
#[inline] #[inline]
fn map_attachment<'b, F>(&'b self, mut f: F) fn map_attachment<'handle, F>(&'handle self, mut f: F)
where where
F: FnMut(&'b AttachmentInfo) -> (), F: FnMut(&'handle AttachmentInfo<'device>) -> (),
{ {
for sub_pass in self.sub_passes.iter() { for sub_pass in self.sub_passes.iter() {
for attachment in sub_pass.attachments().iter() { for attachment in sub_pass.attachments().iter() {
@ -260,36 +263,36 @@ struct SubPassAttachmentReferences {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct RenderTarget { pub struct RenderTarget<'device, 'image> {
render_pass: Arc<RenderPass>, render_pass: RenderPass<'device>,
framebuffers: Vec<Arc<Framebuffer>>, framebuffers: Vec<Framebuffer<'device, 'image>>,
clear_values: Vec<VkClearValue>, clear_values: Vec<VkClearValue>,
extent: VkExtent2D, extent: VkExtent2D,
sub_passes: Vec<SubPass>, sub_passes: Vec<SubPass<'device>>,
current_subpass: AtomicU32, current_subpass: AtomicU32,
framebuffer_index: AtomicUsize, framebuffer_index: AtomicUsize,
} }
impl RenderTarget { impl<'device, 'image> RenderTarget<'device, 'image> {
pub fn builder<'a>() -> RenderTargetBuilder<'a> { pub fn builder() -> RenderTargetBuilder<'device, 'image> {
RenderTargetBuilder { RenderTargetBuilder {
old_render_target: None, old_render_target: None,
sub_passes: Vec::new(), sub_passes: Vec::new(),
} }
} }
pub fn render_pass(&self) -> &Arc<RenderPass> { pub fn render_pass(&self) -> &RenderPass<'device> {
&self.render_pass &self.render_pass
} }
pub fn framebuffer(&self, index: usize) -> &Arc<Framebuffer> { pub fn framebuffer(&self, index: usize) -> &Framebuffer<'device, 'image> {
&self.framebuffers[index] &self.framebuffers[index]
} }
pub fn sub_pass(&self, index: usize) -> &SubPass { pub fn sub_pass(&self, index: usize) -> &SubPass<'device> {
&self.sub_passes[index] &self.sub_passes[index]
} }
@ -312,7 +315,7 @@ impl RenderTarget {
pub fn begin( pub fn begin(
&self, &self,
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'device, '_, '_>,
subpass_content: VkSubpassContents, subpass_content: VkSubpassContents,
framebuffer_index: usize, framebuffer_index: usize,
) { ) {
@ -334,14 +337,14 @@ impl RenderTarget {
pub fn next_subpass( pub fn next_subpass(
&self, &self,
buffer_recorder: &mut CommandBufferRecorder<'_>, buffer_recorder: &mut CommandBufferRecorder<'device, '_, '_>,
subpass_content: VkSubpassContents, subpass_content: VkSubpassContents,
) { ) {
buffer_recorder.next_subpass(subpass_content); buffer_recorder.next_subpass(subpass_content);
self.current_subpass.fetch_add(1, SeqCst); self.current_subpass.fetch_add(1, SeqCst);
} }
pub fn end(&self, buffer_recorder: &mut CommandBufferRecorder<'_>) { pub fn end(&self, buffer_recorder: &mut CommandBufferRecorder<'device, '_, '_>) {
debug_assert_eq!( debug_assert_eq!(
self.current_subpass.load(SeqCst) as usize, self.current_subpass.load(SeqCst) as usize,
self.sub_passes.len() - 1 self.sub_passes.len() - 1
@ -353,48 +356,14 @@ impl RenderTarget {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::prelude::*; use crate::{create_vk_handles, prelude::*};
use anyhow::Result; use anyhow::Result;
use std::sync::{Arc, Mutex};
fn create_vk_handles() -> Result<(Arc<Device>, Arc<Mutex<Queue>>)> {
let instance = Instance::new(
VkApplicationInfo::new(
&VkString::new("Test"),
1,
&VkString::new("no name"),
1,
VK_MAKE_VERSION(1, 3, 0),
),
VulkanDebugInfo::default(),
InstanceExtensions::default(),
)?;
let physical_device = PhysicalDevice::new(instance)?;
let queue_info = Queue::create_non_presentable_request_info(
&physical_device,
VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT,
)?;
let device = Device::new(
physical_device,
DeviceExtensions::default(),
&[queue_info.queue_create_info],
DeviceFeatures::default(),
)?;
let queue = device.get_queue(queue_info.queue_family_index, queue_info.queue_index);
Ok((device, queue))
}
#[test] #[test]
fn test_render_target() { fn test_render_target() {
let (device, queue) = create_vk_handles().unwrap(); let (device, queue) = create_vk_handles().unwrap();
let target_images: Vec<Arc<Image>> = (0..2) let target_images: Vec<Image<'_>> = (0..2)
.map(|_| { .map(|_| {
let image = Image::empty( let image = Image::empty(
1920, 1920,
@ -409,18 +378,26 @@ mod test {
Ok(image) Ok(image)
}) })
.collect::<Result<Vec<Arc<Image>>>>() .collect::<Result<Vec<Image<'_>>>>()
.unwrap(); .unwrap();
let width = target_images[0].width();
let height = target_images[0].height();
RenderTarget::builder() RenderTarget::builder()
.add_sub_pass( .add_sub_pass(
SubPass::builder(target_images[0].width(), target_images[0].height()) SubPass::builder(width, height)
.set_prepared_targets(&target_images, 0, [0.0, 0.0, 0.0, 0.0], false) .set_prepared_targets(
target_images.iter().collect(),
0,
[0.0, 0.0, 0.0, 0.0],
false,
)
.build(&device) .build(&device)
.unwrap(), .unwrap(),
) )
.add_sub_pass( .add_sub_pass(
SubPass::builder(target_images[0].width(), target_images[0].height()) SubPass::builder(width, height)
.add_target_info(CustomTarget { .add_target_info(CustomTarget {
usage: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT.into(), usage: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT.into(),
format: VK_FORMAT_R8G8B8A8_UNORM, format: VK_FORMAT_R8G8B8A8_UNORM,
@ -438,17 +415,22 @@ mod test {
false, false,
true, true,
)) ))
.use_queue(queue.clone()) .use_queue(&queue)
.build(&device) .build(&device)
.unwrap(), .unwrap(),
) )
.add_sub_pass( .add_sub_pass(
SubPass::builder(target_images[0].width(), target_images[0].height()) SubPass::builder(width, height)
.set_input_attachment_info(InputAttachmentInfo { .set_input_attachment_info(InputAttachmentInfo {
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.iter().collect(),
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::{Arc, Mutex}; use std::{ops::Index, sync::Mutex};
pub enum ClearValue { pub enum ClearValue {
Color([f32; 4]), Color([f32; 4]),
@ -54,14 +54,14 @@ impl CustomTarget {
} }
} }
fn to_attachment_info( fn to_attachment_info<'a>(
&self, &self,
device: &Arc<Device>, device: &'a Device,
queue: &Arc<Mutex<Queue>>, queue: &'a Mutex<Queue<'a>>,
width: u32, width: u32,
height: u32, height: u32,
sample_count: VkSampleCountFlags, sample_count: VkSampleCountFlags,
) -> Result<AttachmentInfo> { ) -> Result<AttachmentInfo<'a>> {
let clear_operation = SubPassBuilder::clear_op(if self.use_as_input { let clear_operation = SubPassBuilder::clear_op(if self.use_as_input {
false false
} else { } else {
@ -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,
@ -168,25 +168,25 @@ impl CustomTarget {
} }
} }
pub enum ResolveTarget { pub enum ResolveTarget<'a> {
CustomTarget(CustomTarget), CustomTarget(CustomTarget),
PreparedTargets((Vec<Arc<Image>>, bool)), PreparedTargets((Vec<&'a Image<'a>>, bool)),
} }
impl From<CustomTarget> for ResolveTarget { impl<'a> From<CustomTarget> for ResolveTarget<'a> {
fn from(custom_target: CustomTarget) -> Self { fn from(custom_target: CustomTarget) -> Self {
Self::CustomTarget(custom_target) Self::CustomTarget(custom_target)
} }
} }
impl From<(Vec<Arc<Image>>, bool)> for ResolveTarget { impl<'a> From<(Vec<&'a Image<'a>>, bool)> for ResolveTarget<'a> {
fn from((prepared_targets, clear_on_load): (Vec<Arc<Image>>, bool)) -> Self { fn from((prepared_targets, clear_on_load): (Vec<&'a Image<'a>>, bool)) -> Self {
Self::PreparedTargets((prepared_targets, clear_on_load)) Self::PreparedTargets((prepared_targets, clear_on_load))
} }
} }
impl<'a> From<(&'a Vec<Arc<Image>>, bool)> for ResolveTarget { impl<'a> From<(&'a Vec<&'a Image<'a>>, bool)> for ResolveTarget<'a> {
fn from((prepared_targets, clear_on_load): (&'a Vec<Arc<Image>>, bool)) -> Self { fn from((prepared_targets, clear_on_load): (&'a Vec<&'a Image<'a>>, bool)) -> Self {
Self::PreparedTargets((prepared_targets.clone(), clear_on_load)) Self::PreparedTargets((prepared_targets.clone(), clear_on_load))
} }
} }
@ -197,25 +197,31 @@ pub struct InputAttachmentInfo {
pub input_indices: Vec<usize>, pub input_indices: Vec<usize>,
} }
pub struct SubPassBuilder<'a> { pub struct SubPassBuilder<'a, 'b>
where
'b: 'a,
{
width: u32, width: u32,
height: u32, height: u32,
sample_count: VkSampleCountFlags, sample_count: VkSampleCountFlags,
queue: Option<Arc<Mutex<Queue>>>, queue: Option<&'a Mutex<Queue<'a>>>,
target_infos: Vec<CustomTarget>, target_infos: Vec<CustomTarget>,
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 [Arc<Image>], usize, [f32; 4], bool)>, prepared_targets: Option<(Vec<&'b Image<'a>>, usize, [f32; 4], bool)>,
resolve_targets: Vec<ResolveTarget>, resolve_targets: Vec<ResolveTarget<'a>>,
output_usage: VkAccessFlagBits, output_usage: VkAccessFlagBits,
} }
impl<'a> SubPassBuilder<'a> { impl<'a, 'b> SubPassBuilder<'a, 'b>
where
'b: 'a,
{
pub fn set_sample_count(mut self, sample_count: VkSampleCountFlags) -> Self { pub fn set_sample_count(mut self, sample_count: VkSampleCountFlags) -> Self {
self.sample_count = sample_count; self.sample_count = sample_count;
@ -242,7 +248,7 @@ impl<'a> SubPassBuilder<'a> {
pub fn set_prepared_targets( pub fn set_prepared_targets(
mut self, mut self,
prepared_targets: &'a [Arc<Image>], prepared_targets: Vec<&'b 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,
@ -257,19 +263,19 @@ impl<'a> SubPassBuilder<'a> {
self self
} }
pub fn add_resolve_targets(mut self, resolve_target: impl Into<ResolveTarget>) -> Self { pub fn add_resolve_targets(mut self, resolve_target: impl Into<ResolveTarget<'a>>) -> Self {
self.resolve_targets.push(resolve_target.into()); self.resolve_targets.push(resolve_target.into());
self self
} }
pub fn use_queue(mut self, queue: Arc<Mutex<Queue>>) -> Self { pub fn use_queue(mut self, queue: &'a Mutex<Queue<'a>>) -> Self {
self.queue = Some(queue); self.queue = Some(queue);
self self
} }
pub fn build(self, device: &Arc<Device>) -> Result<SubPass> { 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 +290,7 @@ impl<'a> SubPassBuilder<'a> {
} }
#[inline] #[inline]
fn create_images(self, device: &Arc<Device>) -> Result<Vec<AttachmentInfo>> { 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 +320,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 +334,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 +359,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 +375,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(),
}); });
} }
} }
@ -405,16 +411,61 @@ pub enum AttachmentInfoUsage {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct AttachmentInfo { pub enum AttachmentInfoImages<'device> {
images: Vec<Arc<Image>>, Owned(Vec<Image<'device>>),
Ref(Vec<&'device Image<'device>>),
}
impl<'device> AttachmentInfoImages<'device> {
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<'device> From<Vec<Image<'device>>> for AttachmentInfoImages<'device> {
fn from(value: Vec<Image<'device>>) -> Self {
Self::Owned(value)
}
}
impl<'device> From<Vec<&'device Image<'device>>> for AttachmentInfoImages<'device> {
fn from(value: Vec<&'device Image<'device>>) -> Self {
Self::Ref(value)
}
}
impl<'device> Index<usize> for AttachmentInfoImages<'device> {
type Output = Image<'device>;
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: 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,
pub(crate) usage: AttachmentInfoUsage, pub(crate) usage: AttachmentInfoUsage,
} }
impl AttachmentInfo { impl<'a> AttachmentInfo<'a> {
pub fn image(&self, mut index: usize) -> &Arc<Image> { pub fn image(&self, mut index: usize) -> &Image<'a> {
debug_assert!(!self.images.is_empty()); debug_assert!(!self.images.is_empty());
if index >= self.images.len() { if index >= self.images.len() {
@ -433,17 +484,17 @@ impl AttachmentInfo {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct SubPass { pub struct SubPass<'device> {
extent: VkExtent2D, extent: VkExtent2D,
input_info: Option<InputAttachmentInfo>, input_info: Option<InputAttachmentInfo>,
attachments: Vec<AttachmentInfo>, attachments: Vec<AttachmentInfo<'device>>,
output_usage: VkAccessFlagBits, output_usage: VkAccessFlagBits,
} }
impl SubPass { impl<'device> SubPass<'device> {
pub fn builder<'a>(width: u32, height: u32) -> SubPassBuilder<'a> { pub fn builder<'b>(width: u32, height: u32) -> SubPassBuilder<'device, 'b> {
SubPassBuilder { SubPassBuilder {
width, width,
height, height,
@ -475,7 +526,7 @@ impl SubPass {
self.extent self.extent
} }
pub fn attachments(&self) -> &[AttachmentInfo] { pub fn attachments(&self) -> &[AttachmentInfo<'device>] {
&self.attachments &self.attachments
} }

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) -> &Arc<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

@ -2,48 +2,32 @@ use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::Arc;
#[derive(Debug)] #[derive(Debug)]
pub struct Semaphore { pub struct Semaphore<'a> {
device: Arc<Device>, device: &'a Device,
semaphore: VkSemaphore, semaphore: VkSemaphore,
} }
impl Semaphore { impl<'a> Semaphore<'a> {
pub fn new(device: Arc<Device>) -> Result<Arc<Semaphore>> { pub fn new(device: &'a Device) -> Result<Semaphore<'a>> {
let semaphore_ci = VkSemaphoreCreateInfo::new(VK_SEMAPHORE_CREATE_NULL_BIT); let semaphore_ci = VkSemaphoreCreateInfo::new(VK_SEMAPHORE_CREATE_NULL_BIT);
let semaphore = device.create_semaphore(&semaphore_ci)?; let semaphore = device.create_semaphore(&semaphore_ci)?;
Ok(Arc::new(Semaphore { device, semaphore })) Ok(Semaphore { device, semaphore })
} }
} }
impl VulkanDevice for Semaphore { impl<'a> VulkanDevice for Semaphore<'a> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl_vk_handle!(Semaphore, VkSemaphore, semaphore); impl_vk_handle!(Semaphore<'a>, VkSemaphore, semaphore);
impl Drop for Semaphore { impl<'a> Drop for Semaphore<'a> {
fn drop(&mut self) { fn drop(&mut self) {
self.device.destroy_semaphore(self.semaphore); self.device.destroy_semaphore(self.semaphore);
} }
} }
use crate::{ffi::*, handle_ffi_result};
#[no_mangle]
pub extern "C" fn create_semaphore(device: *const Device) -> *const Semaphore {
let device = unsafe { Arc::from_raw(device) };
handle_ffi_result!(Semaphore::new(device))
}
#[no_mangle]
pub extern "C" fn destroy_semaphore(semaphore: *const Semaphore) {
let _semaphore = unsafe { Arc::from_raw(semaphore) };
}

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) -> &Arc<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

@ -1,27 +1,27 @@
use crate::prelude::*; use crate::prelude::*;
use anyhow::Result; use anyhow::Result;
use std::sync::{Arc, Mutex}; use std::sync::Mutex;
use std::time::Duration; use std::time::Duration;
pub struct SingleSubmit<'a, F, T> pub struct SingleSubmit<'device, 'a, F, T>
where where
F: FnOnce(&mut CommandBufferRecorder<'_>) -> Result<T>, F: FnOnce(&mut CommandBufferRecorder<'device, '_, '_>) -> Result<T>,
{ {
command_buffer: &'a Arc<CommandBuffer>, command_buffer: &'a mut CommandBuffer<'device>,
queue: &'a Arc<Mutex<Queue>>, queue: &'a Mutex<Queue<'device>>,
f: F, f: F,
timeout: Option<Duration>, timeout: Option<Duration>,
} }
impl<'a, F, T> SingleSubmit<'a, F, T> impl<'device, 'a, F, T> SingleSubmit<'device, 'a, F, T>
where where
F: FnOnce(&mut CommandBufferRecorder<'_>) -> Result<T>, F: FnOnce(&mut CommandBufferRecorder<'device, '_, '_>) -> Result<T>,
{ {
pub fn builder( pub fn builder(
command_buffer: &'a Arc<CommandBuffer>, command_buffer: &'a mut CommandBuffer<'device>,
queue: &'a Arc<Mutex<Queue>>, queue: &'a Mutex<Queue<'device>>,
f: F, f: F,
) -> Self { ) -> Self {
SingleSubmit { SingleSubmit {
@ -48,12 +48,12 @@ where
(self.f)(&mut buffer_recorder)? (self.f)(&mut buffer_recorder)?
}; };
let submit = SubmitInfo::default().add_command_buffer(self.command_buffer); let submit = SubmitInfo::default().add_command_buffer(&*self.command_buffer);
let queue_lock = self.queue.lock().unwrap(); let queue_lock = self.queue.lock().unwrap();
match self.timeout { match self.timeout {
Some(timeout) => { Some(timeout) => {
let fence = Fence::builder().build(self.command_buffer.device().clone())?; let fence = Fence::builder().build(self.command_buffer.device())?;
queue_lock.submit(Some(&fence), &[submit])?; queue_lock.submit(Some(&fence), &[submit])?;

View file

@ -2,25 +2,20 @@ 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)]
pub struct Surface { pub struct Surface<'a> {
instance: Arc<Instance>, instance: &'a Instance,
surface: VkSurfaceKHR, surface: VkSurfaceKHR,
} }
impl Surface { impl<'a> Surface<'a> {
pub fn from_vk_surface(surface: VkSurfaceKHR, instance: &Arc<Instance>) -> Arc<Surface> { pub fn from_vk_surface(surface: VkSurfaceKHR, instance: &'a Instance) -> Self {
Arc::new(Surface { Self { instance, surface }
instance: instance.clone(),
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,
@ -29,7 +24,7 @@ impl Surface {
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
@ -61,15 +56,25 @@ impl Surface {
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)
} }
} }
impl_vk_handle!(Surface, VkSurfaceKHR, surface); impl<'a> VkHandle<VkSurfaceKHR> for Surface<'a> {
fn vk_handle(&self) -> VkSurfaceKHR {
self.surface
}
}
impl Drop for Surface { impl<'a> VkHandle<VkSurfaceKHR> for &'a Surface<'a> {
fn vk_handle(&self) -> VkSurfaceKHR {
self.surface
}
}
impl<'a> Drop for Surface<'a> {
fn drop(&mut self) { fn drop(&mut self) {
self.instance.destroy_surface(self.surface) self.instance.destroy_surface(self.surface)
} }

View file

@ -3,62 +3,55 @@ 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},
Arc, Mutex,
};
pub enum NextImageSynchronization<'a> { pub enum NextImageSynchronization<'a> {
Semaphore(&'a Arc<Semaphore>), Semaphore(&'a Semaphore<'a>),
Fence(&'a Arc<Fence>), Fence(&'a Fence<'a>),
} }
impl<'a> From<&'a Arc<Semaphore>> for NextImageSynchronization<'a> { impl<'a> From<&'a Semaphore<'a>> for NextImageSynchronization<'a> {
fn from(value: &'a Arc<Semaphore>) -> Self { fn from(value: &'a Semaphore<'a>) -> Self {
Self::Semaphore(value) Self::Semaphore(value)
} }
} }
impl<'a> From<&'a Arc<Fence>> for NextImageSynchronization<'a> { impl<'a> From<&'a Fence<'a>> for NextImageSynchronization<'a> {
fn from(value: &'a Arc<Fence>) -> Self { fn from(value: &'a Fence<'a>) -> Self {
Self::Fence(value) Self::Fence(value)
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Swapchain { pub struct Swapchain<'a> {
width: AtomicU32, width: u32,
height: AtomicU32, height: u32,
index: AtomicU32, index: u32,
device: Arc<Device>, device: &'a Device,
surface: Arc<Surface>, surface: Surface<'a>,
create_info: Mutex<VkSwapchainCreateInfoKHR>, create_info: VkSwapchainCreateInfoKHR,
swapchain: Mutex<VkSwapchainKHR>, swapchain: VkSwapchainKHR,
usage: VkImageUsageFlagBits, usage: VkImageUsageFlagBits,
raw: bool, raw: bool,
} }
impl Swapchain { impl<'a> Swapchain<'a> {
pub fn new( pub fn new(
device: Arc<Device>, device: &'a Device,
surface: &Arc<Surface>, surface: Surface<'a>,
vsync: bool, vsync: bool,
image_count: u32, image_count: u32,
image_usage: impl Into<VkImageUsageFlagBits>, image_usage: impl Into<VkImageUsageFlagBits>,
prefered_format: VkFormat, prefered_format: VkFormat,
array_layers: u32, array_layers: u32,
window_size: (u32, u32), ) -> Result<Swapchain<'a>> {
) -> Result<Arc<Swapchain>> {
let surface_caps = surface.capabilities(&device)?; let surface_caps = surface.capabilities(&device)?;
let extent = if surface_caps.currentExtent.width == u32::max_value() { let extent = if surface_caps.currentExtent.width == u32::max_value() {
VkExtent2D { return Err(anyhow::Error::msg("Surface has no extent"));
width: window_size.0,
height: window_size.1,
}
} else { } else {
VkExtent2D { VkExtent2D {
width: surface_caps.currentExtent.width, width: surface_caps.currentExtent.width,
@ -116,85 +109,78 @@ impl Swapchain {
let swapchain = device.create_swapchain(&swapchain_ci)?; let swapchain = device.create_swapchain(&swapchain_ci)?;
Ok(Arc::new(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.clone(), 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: Arc<Device>,
swapchain_ci: &VkSwapchainCreateInfoKHR,
) -> Result<Arc<Self>> {
Ok(Arc::new(Swapchain {
width: AtomicU32::new(swapchain_ci.imageExtent.width),
height: AtomicU32::new(swapchain_ci.imageExtent.height),
usage: swapchain_ci.imageUsage,
index: AtomicU32::new(0),
surface: Surface::from_vk_surface(
swapchain_ci.surface,
device.physical_device().instance(),
),
create_info: Mutex::new(swapchain_ci.clone()),
swapchain: Mutex::new(device.create_swapchain(swapchain_ci)?),
device,
raw: false,
}))
}
pub fn from_raw(
device: Arc<Device>,
swapchain_ci: &VkSwapchainCreateInfoKHR,
swapchain: VkSwapchainKHR,
) -> Arc<Self> {
Arc::new(Swapchain {
width: AtomicU32::new(swapchain_ci.imageExtent.width),
height: AtomicU32::new(swapchain_ci.imageExtent.height),
usage: swapchain_ci.imageUsage,
index: AtomicU32::new(0),
surface: Surface::from_vk_surface(
swapchain_ci.surface,
device.physical_device().instance(),
),
device,
create_info: Mutex::new(swapchain_ci.clone()),
swapchain: Mutex::new(swapchain),
raw: true,
}) })
} }
pub fn recreate(&self, window_size: (u32, u32)) -> Result<()> { pub fn from_ci(device: &'a Device, swapchain_ci: &VkSwapchainCreateInfoKHR) -> Result<Self> {
Ok(Swapchain {
width: swapchain_ci.imageExtent.width,
height: swapchain_ci.imageExtent.height,
usage: swapchain_ci.imageUsage,
index: 0,
surface: Surface::from_vk_surface(
swapchain_ci.surface,
device.physical_device().instance(),
),
create_info: swapchain_ci.clone(),
swapchain: device.create_swapchain(swapchain_ci)?,
device,
raw: false,
})
}
pub fn from_raw(
device: &'a Device,
swapchain_ci: &VkSwapchainCreateInfoKHR,
swapchain: VkSwapchainKHR,
) -> Self {
Swapchain {
width: swapchain_ci.imageExtent.width,
height: swapchain_ci.imageExtent.height,
usage: swapchain_ci.imageUsage,
index: 0,
surface: Surface::from_vk_surface(
swapchain_ci.surface,
device.physical_device().instance(),
),
device,
create_info: swapchain_ci.clone(),
swapchain,
raw: true,
}
}
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()
{ {
VkExtent2D { return Err(anyhow::Error::msg("Surface has no extent"));
width: window_size.0,
height: window_size.1,
}
} else if surface_caps.currentExtent.width == 0 || surface_caps.currentExtent.height == 0 { } else if surface_caps.currentExtent.width == 0 || surface_caps.currentExtent.height == 0 {
// don't recreate swapchain // don't recreate swapchain
return Ok(()); return Ok(());
@ -205,9 +191,9 @@ impl Swapchain {
} }
}; };
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)?;
@ -215,24 +201,24 @@ impl Swapchain {
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<'a>( pub fn acquire_next_image<'b>(
&self, &mut self,
time_out: u64, time_out: u64,
synchro: impl Into<NextImageSynchronization<'a>>, 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()),
@ -246,7 +232,7 @@ impl Swapchain {
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;
} }
} }
@ -255,25 +241,24 @@ impl Swapchain {
/// 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: &Arc<Mutex<Queue>>, queue: &'a Mutex<Queue<'a>>,
assume_layout: bool, assume_layout: bool,
) -> Result<Vec<Arc<Image>>> { ) -> Result<Vec<Image<'a>>> {
let format = self.format(); let format = self.format();
let tiling = VK_IMAGE_TILING_OPTIMAL; let tiling = VK_IMAGE_TILING_OPTIMAL;
@ -297,7 +282,7 @@ impl Swapchain {
self.usage, self.usage,
assume_layout, assume_layout,
) )
.attach_sampler(Sampler::nearest_sampler().build(&self.device)?) .attach_sampler(Sampler::nearest_sampler().build(self.device)?)
.build(&self.device, queue)?, .build(&self.device, queue)?,
); );
} }
@ -306,55 +291,42 @@ impl Swapchain {
} }
pub fn width(&self) -> u32 { pub fn width(&self) -> u32 {
self.width.load(SeqCst) self.width
} }
pub fn height(&self) -> u32 { pub fn height(&self) -> u32 {
self.height.load(SeqCst) self.height
} }
pub fn format(&self) -> VkFormat { pub fn format(&self) -> VkFormat {
self.create_info.lock().unwrap().imageFormat self.create_info.imageFormat
} }
#[inline] #[inline]
fn destroy(&self) { fn destroy(&self) {
self.device self.device.destroy_swapchain(self.swapchain)
.destroy_swapchain(*self.swapchain.lock().unwrap())
} }
} }
impl VulkanDevice for Swapchain { impl<'a> VulkanDevice for Swapchain<'a> {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Device {
&self.device &self.device
} }
} }
impl VkHandle<VkSwapchainKHR> for Swapchain { impl<'a> VkHandle<VkSwapchainKHR> for Swapchain<'a> {
fn vk_handle(&self) -> VkSwapchainKHR { fn vk_handle(&self) -> VkSwapchainKHR {
*self.swapchain.lock().unwrap() self.swapchain
} }
} }
impl<'a> VkHandle<VkSwapchainKHR> for &'a Swapchain { impl<'a> VkHandle<VkSwapchainKHR> for &'a Swapchain<'a> {
fn vk_handle(&self) -> VkSwapchainKHR { fn vk_handle(&self) -> VkSwapchainKHR {
*self.swapchain.lock().unwrap() self.swapchain
} }
} }
impl VkHandle<VkSwapchainKHR> for Arc<Swapchain> { impl<'a> Drop for Swapchain<'a> {
fn vk_handle(&self) -> VkSwapchainKHR {
*self.swapchain.lock().unwrap()
}
}
impl<'a> VkHandle<VkSwapchainKHR> for &'a Arc<Swapchain> {
fn vk_handle(&self) -> VkSwapchainKHR {
*self.swapchain.lock().unwrap()
}
}
impl Drop for Swapchain {
fn drop(&mut self) { fn drop(&mut self) {
if !self.raw { if !self.raw {
self.destroy(); self.destroy();

View file

@ -6,7 +6,7 @@ edition = "2021"
[dependencies] [dependencies]
library_loader = { path = "../library_loader" } library_loader = { path = "../library_loader" }
paste = "1.0.15" paste = "1.0.14"
shared_library = "0.1.9" shared_library = "0.1.9"
anyhow = { version = "1.0.86", features = ["backtrace"] } anyhow = { version = "1.0.81", features = ["backtrace"] }
utilities = { git = "https://gavania.de/hodasemi/utilities.git" } utilities = { git = "https://gavania.de/hodasemi/utilities.git" }

View file

@ -12,130 +12,11 @@ pub enum VkDynamicState {
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6,
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7,
VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8,
// Provided by VK_VERSION_1_3 VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1_000_087_000,
VK_DYNAMIC_STATE_CULL_MODE = 1000267000, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1_000_099_000,
// Provided by VK_VERSION_1_3 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1_000_143_000,
VK_DYNAMIC_STATE_FRONT_FACE = 1000267001, VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1_000_164_004,
// Provided by VK_VERSION_1_3 VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1_000_164_006,
VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = 1000267002, VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1_000_205_001,
// Provided by VK_VERSION_1_3 VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR = 1_000_347_000,
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT = 1000267003,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT = 1000267004,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE = 1000267005,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE = 1000267006,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE = 1000267007,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_DEPTH_COMPARE_OP = 1000267008,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE = 1000267009,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE = 1000267010,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_STENCIL_OP = 1000267011,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE = 1000377001,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE = 1000377002,
// Provided by VK_VERSION_1_3
VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004,
// Provided by VK_NV_clip_space_w_scaling
VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000,
// Provided by VK_EXT_discard_rectangles
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000,
// Provided by VK_EXT_discard_rectangles
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT = 1000099001,
// Provided by VK_EXT_discard_rectangles
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT = 1000099002,
// Provided by VK_EXT_sample_locations
VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000,
// Provided by VK_KHR_ray_tracing_pipeline
VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR = 1000347000,
// Provided by VK_NV_shading_rate_image
VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1000164004,
// Provided by VK_NV_shading_rate_image
VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006,
// Provided by VK_NV_scissor_exclusive
VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV = 1000205000,
// Provided by VK_NV_scissor_exclusive
VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001,
// Provided by VK_KHR_fragment_shading_rate
VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR = 1000226000,
// Provided by VK_EXT_vertex_input_dynamic_state
VK_DYNAMIC_STATE_VERTEX_INPUT_EXT = 1000352000,
// Provided by VK_EXT_extended_dynamic_state2
VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT = 1000377000,
// Provided by VK_EXT_extended_dynamic_state2
VK_DYNAMIC_STATE_LOGIC_OP_EXT = 1000377003,
// Provided by VK_EXT_color_write_enable
VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT = 1000381000,
// Provided by VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT = 1000455003,
// Provided by VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_POLYGON_MODE_EXT = 1000455004,
// Provided by VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT = 1000455005,
// Provided by VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_SAMPLE_MASK_EXT = 1000455006,
// Provided by VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT = 1000455007,
// Provided by VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT = 1000455008,
// Provided by VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT = 1000455009,
// Provided by VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT = 1000455010,
// Provided by VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT = 1000455011,
// Provided by VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT = 1000455012,
// Provided by VK_EXT_extended_dynamic_state3 with VK_KHR_maintenance2 or
VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT = 1000455002,
// Provided by VK_EXT_extended_dynamic_state3 with VK_EXT_transform_feedback
VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT = 1000455013,
// Provided by VK_EXT_conservative_rasterization with VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT = 1000455014,
// Provided by VK_EXT_conservative_rasterization with VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT = 1000455015,
// Provided by VK_EXT_depth_clip_enable with VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT = 1000455016,
// Provided by VK_EXT_extended_dynamic_state3 with VK_EXT_sample_locations
VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT = 1000455017,
// Provided by VK_EXT_blend_operation_advanced with VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT = 1000455018,
// Provided by VK_EXT_extended_dynamic_state3 with VK_EXT_provoking_vertex
VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT = 1000455019,
// Provided by VK_EXT_extended_dynamic_state3 with VK_EXT_line_rasterization
VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT = 1000455020,
// Provided by VK_EXT_extended_dynamic_state3 with VK_EXT_line_rasterization
VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT = 1000455021,
// Provided by VK_EXT_depth_clip_control with VK_EXT_extended_dynamic_state3
VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT = 1000455022,
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_clip_space_w_scaling
VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV = 1000455023,
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_viewport_swizzle
VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV = 1000455024,
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_fragment_coverage_to_color
VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV = 1000455025,
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_fragment_coverage_to_color
VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV = 1000455026,
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_framebuffer_mixed_samples
VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV = 1000455027,
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_framebuffer_mixed_samples
VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV = 1000455028,
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_framebuffer_mixed_samples
VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV = 1000455029,
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_shading_rate_image
VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV = 1000455030,
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_representative_fragment_test
VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV = 1000455031,
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_coverage_reduction_mode
VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV = 1000455032,
// Provided by VK_EXT_attachment_feedback_loop_dynamic_state
VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT = 1000524000,
// Provided by VK_KHR_line_rasterization
VK_DYNAMIC_STATE_LINE_STIPPLE_KHR = 1000259000,
} }

View file

@ -399,11 +399,6 @@ load_function_ptrs!(DeviceFunctions, {
pScissors: *const VkRect2D pScissors: *const VkRect2D
) -> (), ) -> (),
vkCmdSetCullMode(
commandBuffer: VkCommandBuffer,
cullMode: VkCullModeFlags
) -> (),
vkCmdSetLineWidth(commandBuffer: VkCommandBuffer, lineWidth: f32) -> (), vkCmdSetLineWidth(commandBuffer: VkCommandBuffer, lineWidth: f32) -> (),
vkCmdSetDepthBias( vkCmdSetDepthBias(