Compare commits
25 commits
lifetime-t
...
master
Author | SHA1 | Date | |
---|---|---|---|
260051b42c | |||
51232b431d | |||
6e44e0adf8 | |||
c61dcfc70e | |||
219c4eff1a | |||
4b67acf84f | |||
93d2705427 | |||
6d7c889fe9 | |||
62c36e3906 | |||
4c00f52ac2 | |||
f5e9b6941c | |||
29c596150e | |||
779e9ae50a | |||
1f124e5b09 | |||
49a4fe96f5 | |||
|
6724885f0a | ||
a5460ebd81 | |||
65e480681f | |||
fe666addd2 | |||
add24bacf3 | |||
43fef690b3 | |||
3a00ab1820 | |||
2fa0276bed | |||
|
1fb136bed9 | ||
d57137d798 |
41 changed files with 1489 additions and 958 deletions
|
@ -5,4 +5,5 @@ members = [
|
|||
"vulkan-rs",
|
||||
"vulkan-sys",
|
||||
"library_loader",
|
||||
]
|
||||
]
|
||||
resolver = "2"
|
|
@ -7,4 +7,4 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
serde = { version = "1.0.203", features = ["derive"] }
|
||||
|
|
|
@ -9,7 +9,7 @@ build = "build.rs"
|
|||
|
||||
[dependencies]
|
||||
vulkan-sys = { path = "../vulkan-sys" }
|
||||
anyhow = { version = "1.0.81", features = ["backtrace"] }
|
||||
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0.90"
|
||||
cc = "1.0.104"
|
|
@ -5,9 +5,9 @@ authors = ["hodasemi <superschneider@t-online.de>"]
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
image = "0.25.0"
|
||||
image = "0.25.1"
|
||||
vulkan-sys = { path = "../vulkan-sys" }
|
||||
vma-rs = { path = "../vma-rs" }
|
||||
anyhow = { version = "1.0.81", features = ["backtrace"] }
|
||||
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
||||
assetpath = { path = "../assetpath" }
|
||||
utilities = { git = "https://gavania.de/hodasemi/utilities.git" }
|
||||
|
|
|
@ -37,9 +37,9 @@ pub struct AccelerationStructureBuilder {
|
|||
}
|
||||
|
||||
impl AccelerationStructureBuilder {
|
||||
pub fn add_instance<'device>(
|
||||
pub fn add_instance(
|
||||
mut self,
|
||||
blas: &AccelerationStructure<'device>,
|
||||
blas: &Arc<AccelerationStructure>,
|
||||
transform: Option<Matrix4<f32>>,
|
||||
instance_flags: impl Into<VkGeometryInstanceFlagBitsKHR>,
|
||||
) -> Self {
|
||||
|
@ -70,10 +70,10 @@ impl AccelerationStructureBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn add_vertices<'a, T: ReprC + Send + Sync + 'static>(
|
||||
pub fn add_vertices<T: ReprC + Send + Sync + 'static>(
|
||||
mut self,
|
||||
vertex_buffer: &Arc<Buffer<'a, T>>,
|
||||
transform: Option<Arc<Buffer<'a, Transform>>>,
|
||||
vertex_buffer: &Arc<Buffer<T>>,
|
||||
transform: Option<Arc<Buffer<Transform>>>,
|
||||
flags: impl Into<VkGeometryFlagBitsKHR>,
|
||||
) -> Self {
|
||||
match &mut self.data {
|
||||
|
@ -122,11 +122,11 @@ impl AccelerationStructureBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn build<'device, 'pipeline, 'cbuffer>(
|
||||
pub fn build(
|
||||
self,
|
||||
device: &'device Device,
|
||||
recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
|
||||
) -> Result<AccelerationStructure<'device>> {
|
||||
device: Arc<Device>,
|
||||
recorder: &mut CommandBufferRecorder<'_>,
|
||||
) -> Result<Arc<AccelerationStructure>> {
|
||||
let build_flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR
|
||||
| VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR;
|
||||
|
||||
|
@ -140,7 +140,7 @@ impl AccelerationStructureBuilder {
|
|||
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
|
||||
)
|
||||
.set_memory_usage(MemoryUsage::CpuToGpu)
|
||||
.build(device)?;
|
||||
.build(device.clone())?;
|
||||
|
||||
let device_address: VkDeviceOrHostAddressConstKHR =
|
||||
instances_buffer.device_address().into();
|
||||
|
@ -239,8 +239,8 @@ impl AccelerationStructureBuilder {
|
|||
}
|
||||
};
|
||||
|
||||
let acceleration_structure = AccelerationStructure {
|
||||
device,
|
||||
let acceleration_structure = Arc::new(AccelerationStructure {
|
||||
device: device.clone(),
|
||||
|
||||
acceleration_structure,
|
||||
|
||||
|
@ -258,7 +258,7 @@ impl AccelerationStructureBuilder {
|
|||
|
||||
generation_data,
|
||||
build_flags,
|
||||
};
|
||||
});
|
||||
|
||||
acceleration_structure.generate(
|
||||
recorder,
|
||||
|
@ -270,21 +270,21 @@ impl AccelerationStructureBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct AccelerationStructure<'device> {
|
||||
device: &'device Device,
|
||||
pub struct AccelerationStructure {
|
||||
device: Arc<Device>,
|
||||
|
||||
acceleration_structure: VkAccelerationStructureKHR,
|
||||
|
||||
result_buffer: Buffer<'device, RawBuffer>,
|
||||
scratch_buffer: Mutex<Buffer<'device, RawBuffer>>,
|
||||
result_buffer: Arc<Buffer<RawBuffer>>,
|
||||
scratch_buffer: Mutex<Arc<Buffer<RawBuffer>>>,
|
||||
|
||||
update_scratch_buffer_size: VkDeviceSize,
|
||||
|
||||
generation_data: AccelerationStructureGenerationData<'device>,
|
||||
generation_data: AccelerationStructureGenerationData,
|
||||
build_flags: VkBuildAccelerationStructureFlagBitsKHR,
|
||||
}
|
||||
|
||||
impl<'device> AccelerationStructure<'device> {
|
||||
impl AccelerationStructure {
|
||||
pub fn bottom_level() -> AccelerationStructureBuilder {
|
||||
AccelerationStructureBuilder {
|
||||
flags: 0.into(),
|
||||
|
@ -303,7 +303,7 @@ impl<'device> AccelerationStructure<'device> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn result_buffer(&self) -> &Buffer<'device, RawBuffer> {
|
||||
pub fn result_buffer(&self) -> &Arc<Buffer<RawBuffer>> {
|
||||
&self.result_buffer
|
||||
}
|
||||
|
||||
|
@ -313,10 +313,7 @@ impl<'device> AccelerationStructure<'device> {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn update<'pipeline, 'cbuffer>(
|
||||
&self,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
|
||||
) -> Result<()> {
|
||||
pub fn update(&self, buffer_recorder: &mut CommandBufferRecorder<'_>) -> Result<()> {
|
||||
*self.scratch_buffer.lock().unwrap() = Self::create_scratch_buffer(
|
||||
&self.device,
|
||||
self.update_scratch_buffer_size,
|
||||
|
@ -333,9 +330,9 @@ impl<'device> AccelerationStructure<'device> {
|
|||
)
|
||||
}
|
||||
|
||||
fn generate<'pipeline, 'cbuffer>(
|
||||
fn generate(
|
||||
&self,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||
src: VkAccelerationStructureKHR,
|
||||
mode: VkBuildAccelerationStructureModeKHR,
|
||||
) -> Result<()> {
|
||||
|
@ -393,10 +390,10 @@ impl<'device> AccelerationStructure<'device> {
|
|||
|
||||
#[inline]
|
||||
fn create_scratch_buffer(
|
||||
device: &'device Device,
|
||||
device: &Arc<Device>,
|
||||
size: VkDeviceSize,
|
||||
alignment: VkDeviceSize,
|
||||
) -> Result<Buffer<'device, RawBuffer>> {
|
||||
) -> Result<Arc<Buffer<RawBuffer>>> {
|
||||
Buffer::builder()
|
||||
.set_usage(
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
|
||||
|
@ -404,11 +401,11 @@ impl<'device> AccelerationStructure<'device> {
|
|||
.set_memory_usage(MemoryUsage::GpuOnly)
|
||||
.set_size(size)
|
||||
.force_alignment(alignment)
|
||||
.build(device)
|
||||
.build(device.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for AccelerationStructure<'a> {
|
||||
impl Drop for AccelerationStructure {
|
||||
fn drop(&mut self) {
|
||||
self.device
|
||||
.destroy_acceleration_structure(self.acceleration_structure, None);
|
||||
|
@ -416,16 +413,16 @@ impl<'a> Drop for AccelerationStructure<'a> {
|
|||
}
|
||||
|
||||
impl_vk_handle!(
|
||||
AccelerationStructure<'a>,
|
||||
AccelerationStructure,
|
||||
VkAccelerationStructureKHR,
|
||||
acceleration_structure
|
||||
);
|
||||
|
||||
enum AccelerationStructureGenerationData<'device> {
|
||||
enum AccelerationStructureGenerationData {
|
||||
TopLevel(
|
||||
Vec<VkAccelerationStructureInstanceKHR>,
|
||||
VkAccelerationStructureGeometryKHR,
|
||||
Buffer<'device, VkAccelerationStructureInstanceKHR>,
|
||||
Arc<Buffer<VkAccelerationStructureInstanceKHR>>,
|
||||
),
|
||||
BottomLevel(
|
||||
Vec<VkAccelerationStructureGeometryKHR>,
|
||||
|
@ -433,26 +430,26 @@ enum AccelerationStructureGenerationData<'device> {
|
|||
),
|
||||
}
|
||||
|
||||
impl<'device>
|
||||
impl
|
||||
From<(
|
||||
Vec<VkAccelerationStructureInstanceKHR>,
|
||||
VkAccelerationStructureGeometryKHR,
|
||||
Buffer<'device, VkAccelerationStructureInstanceKHR>,
|
||||
)> for AccelerationStructureGenerationData<'device>
|
||||
Arc<Buffer<VkAccelerationStructureInstanceKHR>>,
|
||||
)> for AccelerationStructureGenerationData
|
||||
{
|
||||
fn from(
|
||||
(instances, geometry, buffer): (
|
||||
Vec<VkAccelerationStructureInstanceKHR>,
|
||||
VkAccelerationStructureGeometryKHR,
|
||||
Buffer<'device, VkAccelerationStructureInstanceKHR>,
|
||||
Arc<Buffer<VkAccelerationStructureInstanceKHR>>,
|
||||
),
|
||||
) -> Self {
|
||||
Self::TopLevel(instances, geometry, buffer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'device> From<(Vec<VkAccelerationStructureGeometryKHR>, Vec<u32>)>
|
||||
for AccelerationStructureGenerationData<'device>
|
||||
impl From<(Vec<VkAccelerationStructureGeometryKHR>, Vec<u32>)>
|
||||
for AccelerationStructureGenerationData
|
||||
{
|
||||
fn from(
|
||||
(geometries, primitive_counts): (Vec<VkAccelerationStructureGeometryKHR>, Vec<u32>),
|
||||
|
|
|
@ -4,6 +4,7 @@ use anyhow::Result;
|
|||
|
||||
use std;
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct BufferBuilder<'a, T: ReprC> {
|
||||
flags: VkBufferCreateFlagBits,
|
||||
|
@ -61,7 +62,7 @@ impl<'a, T: ReprC> BufferBuilder<'a, T> {
|
|||
}
|
||||
|
||||
impl<'a, T: ReprC + Clone + Send + Sync + 'static> BufferBuilder<'a, T> {
|
||||
pub fn build<'b>(self, device: &'b Device) -> Result<Buffer<'b, T>> {
|
||||
pub fn build(self, device: Arc<Device>) -> Result<Arc<Buffer<T>>> {
|
||||
let size = match self.data {
|
||||
Some(data) => data.len() as VkDeviceSize,
|
||||
None => self.size,
|
||||
|
@ -89,18 +90,18 @@ impl<'a, T: ReprC + Clone + Send + Sync + 'static> BufferBuilder<'a, T> {
|
|||
memory_requirements.alignment = alignment;
|
||||
|
||||
Memory::forced_requirements(
|
||||
device,
|
||||
&device,
|
||||
memory_requirements,
|
||||
buffer,
|
||||
MemoryUsage::into_vma(self.memory_usage),
|
||||
)?
|
||||
}
|
||||
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 = Buffer {
|
||||
let buffer = Arc::new(Buffer {
|
||||
device,
|
||||
buffer,
|
||||
memory,
|
||||
|
@ -110,7 +111,7 @@ impl<'a, T: ReprC + Clone + Send + Sync + 'static> BufferBuilder<'a, T> {
|
|||
_sharing_mode: self.sharing_mode,
|
||||
|
||||
size,
|
||||
};
|
||||
});
|
||||
|
||||
if let Some(data) = self.data {
|
||||
buffer.fill(data)?;
|
||||
|
@ -121,11 +122,11 @@ impl<'a, T: ReprC + Clone + Send + Sync + 'static> BufferBuilder<'a, T> {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Buffer<'device, T: ReprC> {
|
||||
device: &'device Device,
|
||||
pub struct Buffer<T: ReprC> {
|
||||
device: Arc<Device>,
|
||||
buffer: VkBuffer,
|
||||
|
||||
memory: Memory<'device, T>,
|
||||
memory: Arc<Memory<T>>,
|
||||
|
||||
_usage: VkBufferUsageFlagBits,
|
||||
|
||||
|
@ -133,7 +134,7 @@ pub struct Buffer<'device, T: ReprC> {
|
|||
size: VkDeviceSize,
|
||||
}
|
||||
|
||||
impl<'device, T: ReprC + Clone + Send + Sync + 'static> Buffer<'device, T> {
|
||||
impl<T: ReprC + Clone + Send + Sync + 'static> Buffer<T> {
|
||||
pub fn fill(&self, data: &[T]) -> Result<()> {
|
||||
let mut buffer_map = self.map(data.len() as VkDeviceSize)?;
|
||||
|
||||
|
@ -150,20 +151,20 @@ impl<'device, T: ReprC + Clone + Send + Sync + 'static> Buffer<'device, T> {
|
|||
self.memory.map(self.size)
|
||||
}
|
||||
|
||||
pub fn into_device_local<'pipeline, 'cbuffer>(
|
||||
&self,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
|
||||
pub fn into_device_local(
|
||||
self: &Arc<Buffer<T>>,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||
access_mask: impl Into<VkAccessFlagBits>,
|
||||
stage: impl Into<VkPipelineStageFlagBits>,
|
||||
usage: impl Into<VkBufferUsageFlagBits>,
|
||||
) -> Result<Buffer<'device, T>> {
|
||||
) -> Result<Arc<Buffer<T>>> {
|
||||
let new_usage = usage.into() | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
let device_local_buffer = Buffer::builder()
|
||||
.set_memory_usage(MemoryUsage::GpuOnly)
|
||||
.set_usage(new_usage)
|
||||
.set_size(self.size)
|
||||
.build(self.device)?;
|
||||
.build(self.device.clone())?;
|
||||
|
||||
// copy complete buffer
|
||||
buffer_recorder.copy_buffer(
|
||||
|
@ -189,8 +190,8 @@ impl<'device, T: ReprC + Clone + Send + Sync + 'static> Buffer<'device, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ReprC> Buffer<'a, T> {
|
||||
pub fn builder() -> BufferBuilder<'a, T> {
|
||||
impl<T: ReprC> Buffer<T> {
|
||||
pub fn builder<'a>() -> BufferBuilder<'a, T> {
|
||||
BufferBuilder {
|
||||
flags: 0u32.into(),
|
||||
usage: 0u32.into(),
|
||||
|
@ -216,28 +217,72 @@ impl<'a, T: ReprC> Buffer<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ReprC> VulkanDevice for Buffer<'a, T> {
|
||||
fn device(&self) -> &Device {
|
||||
impl<T: ReprC> VulkanDevice for Buffer<T> {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle_t!(Buffer[ReprC]<'b>, VkBuffer, buffer);
|
||||
impl_vk_handle_t!(Buffer[ReprC], VkBuffer, buffer);
|
||||
|
||||
impl<'a, T: ReprC> VkHandle<VkDeviceMemory> for Buffer<'a, T> {
|
||||
impl<T: ReprC> VkHandle<VkDeviceMemory> for Buffer<T> {
|
||||
fn vk_handle(&self) -> VkDeviceMemory {
|
||||
self.memory.vk_handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ReprC> VkHandle<VkDeviceMemory> for &'a Buffer<'a, T> {
|
||||
impl<'a, T: ReprC> VkHandle<VkDeviceMemory> for &'a Buffer<T> {
|
||||
fn vk_handle(&self) -> VkDeviceMemory {
|
||||
self.memory.vk_handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ReprC> Drop for Buffer<'a, T> {
|
||||
impl<T: ReprC> VkHandle<VkDeviceMemory> for Arc<Buffer<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) {
|
||||
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()
|
||||
}
|
||||
|
|
|
@ -6,7 +6,11 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use std::sync::Mutex;
|
||||
use std::any::Any;
|
||||
use std::sync::{
|
||||
atomic::{AtomicUsize, Ordering::SeqCst},
|
||||
Arc, Mutex, MutexGuard,
|
||||
};
|
||||
|
||||
pub struct QueryEnable {
|
||||
pub query_flags: VkQueryControlFlagBits,
|
||||
|
@ -25,11 +29,11 @@ impl CommandBufferBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn build<'a>(
|
||||
pub fn build(
|
||||
self,
|
||||
device: &'a Device,
|
||||
queue: &'a Mutex<Queue<'a>>,
|
||||
) -> Result<CommandBuffer<'a>> {
|
||||
device: Arc<Device>,
|
||||
queue: Arc<Mutex<Queue>>,
|
||||
) -> Result<Arc<CommandBuffer>> {
|
||||
let command_pool = self
|
||||
.pool_builder
|
||||
.set_queue_family_index(
|
||||
|
@ -38,47 +42,50 @@ impl CommandBufferBuilder {
|
|||
.map_err(|_| anyhow::Error::msg("Failed locking vulkan queue"))?
|
||||
.family_index(),
|
||||
)
|
||||
.build(device)?;
|
||||
.build(device.clone())?;
|
||||
|
||||
let command_buffer_ci =
|
||||
VkCommandBufferAllocateInfo::new(command_pool.vk_handle(), self.buffer_level, 1);
|
||||
|
||||
let command_buffer = device.allocate_command_buffers(&command_buffer_ci)?[0];
|
||||
|
||||
Ok(CommandBuffer {
|
||||
Ok(Arc::new(CommandBuffer {
|
||||
device,
|
||||
pool: command_pool,
|
||||
|
||||
buffer: command_buffer,
|
||||
|
||||
calls: 0,
|
||||
})
|
||||
calls: Arc::new(AtomicUsize::new(0)),
|
||||
stored_handles: Mutex::new(Vec::new()),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CommandBuffer<'device> {
|
||||
device: &'device Device,
|
||||
pool: CommandPool<'device>,
|
||||
pub struct CommandBuffer {
|
||||
device: Arc<Device>,
|
||||
pool: Arc<CommandPool>,
|
||||
|
||||
buffer: VkCommandBuffer,
|
||||
|
||||
calls: usize,
|
||||
calls: Arc<AtomicUsize>,
|
||||
stored_handles: Mutex<Vec<Arc<dyn Any + Send + Sync>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CommandBufferRecorder<'device, 'pipeline, 'cbuffer> {
|
||||
device: &'device Device,
|
||||
pub struct CommandBufferRecorder<'a> {
|
||||
device: Arc<Device>,
|
||||
sub_pass: u32,
|
||||
pipeline: Option<&'pipeline Pipeline<'device>>,
|
||||
pipeline: Option<Arc<Pipeline>>,
|
||||
|
||||
calls: &'cbuffer mut usize,
|
||||
calls: Arc<AtomicUsize>,
|
||||
buffer: VkCommandBuffer,
|
||||
handles_lock: MutexGuard<'a, Vec<Arc<dyn Any + Send + Sync>>>,
|
||||
}
|
||||
|
||||
impl_vk_handle!(CommandBuffer<'a>, VkCommandBuffer, buffer);
|
||||
impl_vk_handle!(CommandBuffer, VkCommandBuffer, buffer);
|
||||
|
||||
impl<'device> CommandBuffer<'device> {
|
||||
impl CommandBuffer {
|
||||
pub fn new_primary() -> CommandBufferBuilder {
|
||||
CommandBufferBuilder {
|
||||
buffer_level: VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
|
@ -98,24 +105,25 @@ impl<'device> CommandBuffer<'device> {
|
|||
}
|
||||
|
||||
pub fn calls(&self) -> usize {
|
||||
self.calls
|
||||
self.calls.load(SeqCst)
|
||||
}
|
||||
|
||||
pub fn begin<'pipeline, 'cbuffer>(
|
||||
&'cbuffer mut self,
|
||||
begin_info: VkCommandBufferBeginInfo,
|
||||
) -> Result<CommandBufferRecorder<'device, 'pipeline, 'cbuffer>> {
|
||||
pub fn begin(&self, begin_info: VkCommandBufferBeginInfo) -> Result<CommandBufferRecorder<'_>> {
|
||||
self.device.begin_command_buffer(self.buffer, &begin_info)?;
|
||||
|
||||
self.calls = 0;
|
||||
let mut handles_lock = self.stored_handles.lock().unwrap();
|
||||
handles_lock.clear();
|
||||
|
||||
self.calls.store(0, SeqCst);
|
||||
|
||||
Ok(CommandBufferRecorder {
|
||||
device: self.device.clone(),
|
||||
sub_pass: 0,
|
||||
pipeline: None,
|
||||
|
||||
calls: &mut self.calls,
|
||||
calls: self.calls.clone(),
|
||||
buffer: self.buffer,
|
||||
handles_lock,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -152,10 +160,10 @@ impl<'device> CommandBuffer<'device> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn inheritance_info<'image>(
|
||||
render_pass: Option<&RenderPass<'device>>,
|
||||
pub fn inheritance_info(
|
||||
render_pass: Option<&Arc<RenderPass>>,
|
||||
sub_pass: Option<u32>,
|
||||
framebuffer: Option<&Framebuffer<'device, 'image>>,
|
||||
framebuffer: Option<&Arc<Framebuffer>>,
|
||||
query_enable: Option<QueryEnable>,
|
||||
) -> VkCommandBufferInheritanceInfo {
|
||||
let mut info = VkCommandBufferInheritanceInfo::new(
|
||||
|
@ -178,12 +186,9 @@ impl<'device> CommandBuffer<'device> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'handle, 'me, 'device, 'pipeline, 'cbuffer> CommandBufferRecorder<'device, 'pipeline, 'cbuffer>
|
||||
where
|
||||
'handle: 'me,
|
||||
{
|
||||
impl<'a> CommandBufferRecorder<'a> {
|
||||
pub fn pipeline_barrier(
|
||||
&'me mut self,
|
||||
&self,
|
||||
src_stage_mask: impl Into<VkPipelineStageFlagBits>,
|
||||
dst_stage_mask: impl Into<VkPipelineStageFlagBits>,
|
||||
dependency_flags: impl Into<VkDependencyFlagBits>,
|
||||
|
@ -191,7 +196,7 @@ where
|
|||
buffer_memory_barriers: &[VkBufferMemoryBarrier],
|
||||
image_memory_barriers: &[VkImageMemoryBarrier],
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.device.cmd_pipeline_barrier(
|
||||
self.buffer,
|
||||
|
@ -205,7 +210,7 @@ where
|
|||
}
|
||||
|
||||
pub fn memory_barrier(
|
||||
&'me mut self,
|
||||
&self,
|
||||
src_access_mask: impl Into<VkAccessFlagBits>,
|
||||
src_stage: VkPipelineStageFlags,
|
||||
dst_access_mask: impl Into<VkAccessFlagBits>,
|
||||
|
@ -222,13 +227,15 @@ where
|
|||
}
|
||||
|
||||
pub fn buffer_barrier<T: ReprC + Send + Sync + 'static>(
|
||||
&'me mut self,
|
||||
buffer: &'handle Buffer<'device, T>,
|
||||
&mut self,
|
||||
buffer: &Arc<Buffer<T>>,
|
||||
src_access_mask: impl Into<VkAccessFlagBits>,
|
||||
src_stage: impl Into<VkPipelineStageFlagBits>,
|
||||
dst_access_mask: impl Into<VkAccessFlagBits>,
|
||||
dst_stage: impl Into<VkPipelineStageFlagBits>,
|
||||
) {
|
||||
self.handles_lock.push(buffer.clone());
|
||||
|
||||
self.pipeline_barrier(
|
||||
src_stage,
|
||||
dst_stage,
|
||||
|
@ -248,18 +255,18 @@ where
|
|||
}
|
||||
|
||||
pub fn image_barrier(
|
||||
&'me mut self,
|
||||
image: &'handle Image<'device>,
|
||||
&mut self,
|
||||
image: &Arc<Image>,
|
||||
old_image_layout: VkImageLayout,
|
||||
src_stage: impl Into<VkPipelineStageFlagBits>,
|
||||
new_image_layout: VkImageLayout,
|
||||
dst_stage: impl Into<VkPipelineStageFlagBits>,
|
||||
) where
|
||||
'handle: 'me,
|
||||
{
|
||||
) {
|
||||
let src_access_mask = Image::src_layout_to_access(old_image_layout);
|
||||
let dst_access_mask = Image::dst_layout_to_access(new_image_layout);
|
||||
|
||||
self.handles_lock.push(image.clone());
|
||||
|
||||
self.pipeline_barrier(
|
||||
src_stage,
|
||||
dst_stage,
|
||||
|
@ -282,14 +289,16 @@ where
|
|||
}
|
||||
|
||||
pub fn image_barrier_auto_stage(
|
||||
&'me mut self,
|
||||
image: &'handle Image<'device>,
|
||||
&mut self,
|
||||
image: &Arc<Image>,
|
||||
old_image_layout: VkImageLayout,
|
||||
new_image_layout: VkImageLayout,
|
||||
) {
|
||||
let src_access_mask = Image::src_layout_to_access(old_image_layout);
|
||||
let dst_access_mask = Image::dst_layout_to_access(new_image_layout);
|
||||
|
||||
self.handles_lock.push(image.clone());
|
||||
|
||||
self.pipeline_barrier(
|
||||
CommandBuffer::access_to_stage(src_access_mask),
|
||||
CommandBuffer::access_to_stage(dst_access_mask),
|
||||
|
@ -312,7 +321,7 @@ where
|
|||
}
|
||||
|
||||
pub fn begin_render_pass(
|
||||
&'me mut self,
|
||||
&mut self,
|
||||
renderpass_begin_info: VkRenderPassBeginInfo,
|
||||
subpass_contents: VkSubpassContents,
|
||||
) {
|
||||
|
@ -322,13 +331,16 @@ where
|
|||
.cmd_begin_render_pass(self.buffer, &renderpass_begin_info, subpass_contents);
|
||||
}
|
||||
|
||||
pub fn begin_render_pass_full<'image>(
|
||||
&'me mut self,
|
||||
render_pass: &'handle RenderPass<'device>,
|
||||
framebuffer: &'handle Framebuffer<'device, 'image>,
|
||||
pub fn begin_render_pass_full(
|
||||
&mut self,
|
||||
render_pass: &Arc<RenderPass>,
|
||||
framebuffer: &Arc<Framebuffer>,
|
||||
clear_values: &[VkClearValue],
|
||||
subpass_contents: VkSubpassContents,
|
||||
) {
|
||||
self.handles_lock.push(render_pass.clone());
|
||||
self.handles_lock.push(framebuffer.clone());
|
||||
|
||||
self.sub_pass = 0;
|
||||
|
||||
let render_pass_begin_info = VkRenderPassBeginInfo::new(
|
||||
|
@ -348,16 +360,18 @@ where
|
|||
.cmd_begin_render_pass(self.buffer, &render_pass_begin_info, subpass_contents);
|
||||
}
|
||||
|
||||
pub fn next_subpass(&'me mut self, subpass_contents: VkSubpassContents) {
|
||||
pub fn next_subpass(&mut self, subpass_contents: VkSubpassContents) {
|
||||
self.sub_pass += 1;
|
||||
self.device.cmd_next_subpass(self.buffer, subpass_contents);
|
||||
}
|
||||
|
||||
pub fn end_render_pass(&'me self) {
|
||||
pub fn end_render_pass(&self) {
|
||||
self.device.cmd_end_render_pass(self.buffer);
|
||||
}
|
||||
|
||||
pub fn bind_pipeline(&'me mut self, pipeline: &'pipeline Pipeline<'device>) -> Result<()> {
|
||||
pub fn bind_pipeline(&mut self, pipeline: &Arc<Pipeline>) -> Result<()> {
|
||||
self.handles_lock.push(pipeline.clone());
|
||||
|
||||
match pipeline.pipeline_type() {
|
||||
PipelineType::Graphics => {
|
||||
debug_assert_eq!(self.sub_pass, pipeline.sub_pass());
|
||||
|
@ -380,16 +394,13 @@ where
|
|||
),
|
||||
}
|
||||
|
||||
self.pipeline = Some(pipeline);
|
||||
self.pipeline = Some(pipeline.clone());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn execute_commands(
|
||||
&'me mut self,
|
||||
command_buffers: &[&'handle impl VkHandle<VkCommandBuffer>],
|
||||
) {
|
||||
*self.calls += 1;
|
||||
pub fn execute_commands(&self, command_buffers: &[&impl VkHandle<VkCommandBuffer>]) {
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
let buffers: Vec<VkCommandBuffer> =
|
||||
command_buffers.iter().map(|cb| cb.vk_handle()).collect();
|
||||
|
@ -398,11 +409,8 @@ where
|
|||
.cmd_execute_commands(self.buffer, buffers.as_slice());
|
||||
}
|
||||
|
||||
pub fn bind_descriptor_sets_minimal<'a>(
|
||||
&'me mut self,
|
||||
descriptor_sets: &[&'handle DescriptorSet<'device, 'a>],
|
||||
) {
|
||||
*self.calls += 1;
|
||||
pub fn bind_descriptor_sets_minimal(&mut self, descriptor_sets: &[&Arc<DescriptorSet>]) {
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
let (pipeline_bind_point, vk_layout) = {
|
||||
let pipeline = match &self.pipeline {
|
||||
|
@ -421,7 +429,11 @@ where
|
|||
|
||||
let vk_descriptor_sets: Vec<VkDescriptorSet> = descriptor_sets
|
||||
.iter()
|
||||
.map(|ds: &&DescriptorSet<'device, 'a>| ds.vk_handle())
|
||||
.map(|ds: &&Arc<DescriptorSet>| {
|
||||
self.handles_lock.push((*ds).clone());
|
||||
|
||||
ds.vk_handle()
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.device.cmd_bind_descriptor_sets(
|
||||
|
@ -435,24 +447,30 @@ where
|
|||
}
|
||||
|
||||
pub fn bind_vertex_buffer<T: ReprC + Send + Sync + 'static>(
|
||||
&'me mut self,
|
||||
buffer: &'handle Buffer<'device, T>,
|
||||
&mut self,
|
||||
buffer: &Arc<Buffer<T>>,
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.handles_lock.push(buffer.clone());
|
||||
|
||||
self.device
|
||||
.cmd_bind_vertex_buffers(self.buffer, 0, &[buffer.vk_handle()], &[0]);
|
||||
}
|
||||
|
||||
pub fn bind_vertex_buffers_minimal<T: ReprC + Send + Sync + 'static>(
|
||||
&'me mut self,
|
||||
buffers: &[&'handle Buffer<'device, T>],
|
||||
&mut self,
|
||||
buffers: &[&Arc<Buffer<T>>],
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
let vk_buffers: Vec<VkBuffer> = buffers
|
||||
.iter()
|
||||
.map(|b: &&Buffer<'device, T>| b.vk_handle())
|
||||
.map(|b: &&Arc<Buffer<T>>| {
|
||||
self.handles_lock.push((*b).clone());
|
||||
|
||||
b.vk_handle()
|
||||
})
|
||||
.collect();
|
||||
|
||||
let offsets = vec![0; vk_buffers.len()];
|
||||
|
@ -466,33 +484,39 @@ where
|
|||
}
|
||||
|
||||
pub fn bind_index_buffer<T: ReprC + Send + Sync + 'static>(
|
||||
&'me mut self,
|
||||
buffer: &'handle Buffer<'device, T>,
|
||||
&mut self,
|
||||
buffer: &Arc<Buffer<T>>,
|
||||
offset: VkDeviceSize,
|
||||
index_type: VkIndexType,
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.handles_lock.push(buffer.clone());
|
||||
|
||||
self.device
|
||||
.cmd_bind_index_buffer(self.buffer, buffer.vk_handle(), offset, index_type);
|
||||
}
|
||||
|
||||
pub fn set_viewport(&'me self, viewports: &[VkViewport]) {
|
||||
pub fn set_viewport(&self, viewports: &[VkViewport]) {
|
||||
self.device.cmd_set_viewport(self.buffer, 0, viewports);
|
||||
}
|
||||
|
||||
pub fn set_scissor(&'me self, scissors: &[VkRect2D]) {
|
||||
pub fn set_scissor(&self, scissors: &[VkRect2D]) {
|
||||
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(
|
||||
&'me mut self,
|
||||
&self,
|
||||
vertex_count: u32,
|
||||
instance_count: u32,
|
||||
first_vertex: u32,
|
||||
first_instance: u32,
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.device.cmd_draw(
|
||||
self.buffer,
|
||||
|
@ -503,21 +527,21 @@ where
|
|||
);
|
||||
}
|
||||
|
||||
pub fn draw_complete_single_instance(&'me mut self, vertex_count: u32) {
|
||||
*self.calls += 1;
|
||||
pub fn draw_complete_single_instance(&self, vertex_count: u32) {
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.device.cmd_draw(self.buffer, vertex_count, 1, 0, 0);
|
||||
}
|
||||
|
||||
pub fn draw_indexed(
|
||||
&'me mut self,
|
||||
&self,
|
||||
index_count: u32,
|
||||
instance_count: u32,
|
||||
first_index: u32,
|
||||
vertex_offset: i32,
|
||||
first_instance: u32,
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.device.cmd_draw_indexed(
|
||||
self.buffer,
|
||||
|
@ -529,19 +553,15 @@ where
|
|||
);
|
||||
}
|
||||
|
||||
pub fn draw_indexed_complete_single_instance(&'me mut self, index_count: u32) {
|
||||
*self.calls += 1;
|
||||
pub fn draw_indexed_complete_single_instance(&self, index_count: u32) {
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.device
|
||||
.cmd_draw_indexed(self.buffer, index_count, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
pub fn push_constants<U>(
|
||||
&'me mut self,
|
||||
stage_flags: impl Into<VkShaderStageFlagBits>,
|
||||
data: &U,
|
||||
) {
|
||||
*self.calls += 1;
|
||||
pub fn push_constants<U>(&self, stage_flags: impl Into<VkShaderStageFlagBits>, data: &U) {
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
let pipeline = match &self.pipeline {
|
||||
Some(pipeline) => pipeline,
|
||||
|
@ -555,14 +575,16 @@ where
|
|||
}
|
||||
|
||||
pub fn set_image_layout(
|
||||
&'me mut self,
|
||||
image: &'handle Image<'device>,
|
||||
&mut self,
|
||||
image: &Arc<Image>,
|
||||
new_image_layout: VkImageLayout,
|
||||
subresource_range: VkImageSubresourceRange,
|
||||
) {
|
||||
let src_access = Image::src_layout_to_access(image.image_layout());
|
||||
let dst_access = Image::dst_layout_to_access(new_image_layout);
|
||||
|
||||
self.handles_lock.push(image.clone());
|
||||
|
||||
self.pipeline_barrier(
|
||||
CommandBuffer::access_to_stage(src_access),
|
||||
CommandBuffer::access_to_stage(dst_access),
|
||||
|
@ -584,14 +606,12 @@ where
|
|||
image.set_image_layout(new_image_layout);
|
||||
}
|
||||
|
||||
pub fn set_full_image_layout(
|
||||
&'me mut self,
|
||||
image: &'handle Image<'device>,
|
||||
new_image_layout: VkImageLayout,
|
||||
) {
|
||||
pub fn set_full_image_layout(&mut self, image: &Arc<Image>, new_image_layout: VkImageLayout) {
|
||||
let src_access = Image::src_layout_to_access(image.image_layout());
|
||||
let dst_access = Image::dst_layout_to_access(new_image_layout);
|
||||
|
||||
self.handles_lock.push(image.clone());
|
||||
|
||||
self.pipeline_barrier(
|
||||
CommandBuffer::access_to_stage(src_access),
|
||||
CommandBuffer::access_to_stage(dst_access),
|
||||
|
@ -614,59 +634,62 @@ where
|
|||
}
|
||||
|
||||
// TODO:
|
||||
pub fn set_line_width(&'me self) {
|
||||
pub fn set_line_width(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn set_depth_bias(&'me self) {
|
||||
pub fn set_depth_bias(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn set_blend_constants(&'me self) {
|
||||
pub fn set_blend_constants(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn set_depth_bounds(&'me self) {
|
||||
pub fn set_depth_bounds(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn set_stencil_compare_mask(&'me self) {
|
||||
pub fn set_stencil_compare_mask(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn set_stencil_write_mask(&'me self) {
|
||||
pub fn set_stencil_write_mask(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn set_stencil_reference(&'me self) {
|
||||
pub fn set_stencil_reference(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn draw_indirect(&'me self) {
|
||||
pub fn draw_indirect(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn draw_indexed_indirect(&'me self) {
|
||||
pub fn draw_indexed_indirect(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn dispatch(&'me mut self, x: u32, y: u32, z: u32) {
|
||||
*self.calls += 1;
|
||||
pub fn dispatch(&self, x: u32, y: u32, z: u32) {
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.device.cmd_dispatch(self.buffer, x, y, z);
|
||||
}
|
||||
|
||||
pub fn dispatch_indirect(&'me self) {
|
||||
pub fn dispatch_indirect(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn copy_buffer<T: ReprC + Send + Sync + 'static, U: ReprC + Send + Sync + 'static>(
|
||||
&'me mut self,
|
||||
src_buffer: &'handle Buffer<'device, T>,
|
||||
dst_buffer: &'handle Buffer<'device, U>,
|
||||
&mut self,
|
||||
src_buffer: &Arc<Buffer<T>>,
|
||||
dst_buffer: &Arc<Buffer<U>>,
|
||||
regions: &[VkBufferCopy],
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.handles_lock.push(src_buffer.clone());
|
||||
self.handles_lock.push(dst_buffer.clone());
|
||||
|
||||
self.device.cmd_copy_buffer(
|
||||
self.buffer,
|
||||
|
@ -677,14 +700,17 @@ where
|
|||
}
|
||||
|
||||
pub fn copy_image(
|
||||
&'me mut self,
|
||||
src_image: &'handle Image<'device>,
|
||||
dst_image: &'handle Image<'device>,
|
||||
&mut self,
|
||||
src_image: &Arc<Image>,
|
||||
dst_image: &Arc<Image>,
|
||||
src_layout: VkImageLayout,
|
||||
dst_layout: VkImageLayout,
|
||||
regions: &[VkImageCopy],
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.handles_lock.push(src_image.clone());
|
||||
self.handles_lock.push(dst_image.clone());
|
||||
|
||||
self.device.cmd_copy_image(
|
||||
self.buffer,
|
||||
|
@ -697,11 +723,14 @@ where
|
|||
}
|
||||
|
||||
pub fn blit_complete(
|
||||
&'me mut self,
|
||||
src_image: &'handle Image<'device>,
|
||||
dst_image: &'handle Image<'device>,
|
||||
&mut self,
|
||||
src_image: &Arc<Image>,
|
||||
dst_image: &Arc<Image>,
|
||||
filter: VkFilter,
|
||||
) {
|
||||
self.handles_lock.push(src_image.clone());
|
||||
self.handles_lock.push(dst_image.clone());
|
||||
|
||||
let image_blit = VkImageBlit {
|
||||
srcSubresource: src_image.full_resource_layers(),
|
||||
srcOffsets: [
|
||||
|
@ -734,15 +763,18 @@ where
|
|||
}
|
||||
|
||||
pub fn blit_image(
|
||||
&'me mut self,
|
||||
src_image: &'handle Image<'device>,
|
||||
dst_image: &'handle Image<'device>,
|
||||
&mut self,
|
||||
src_image: &Arc<Image>,
|
||||
dst_image: &Arc<Image>,
|
||||
src_layout: VkImageLayout,
|
||||
dst_layout: VkImageLayout,
|
||||
regions: &[VkImageBlit],
|
||||
filter: VkFilter,
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.handles_lock.push(src_image.clone());
|
||||
self.handles_lock.push(dst_image.clone());
|
||||
|
||||
self.device.cmd_blit_image(
|
||||
self.buffer,
|
||||
|
@ -756,13 +788,16 @@ where
|
|||
}
|
||||
|
||||
pub fn copy_buffer_to_image<T: ReprC + Send + Sync + 'static>(
|
||||
&'me mut self,
|
||||
src_buffer: &'handle Buffer<'device, T>,
|
||||
dst_image: &'handle Image<'device>,
|
||||
&mut self,
|
||||
src_buffer: &Arc<Buffer<T>>,
|
||||
dst_image: &Arc<Image>,
|
||||
image_layout: VkImageLayout,
|
||||
regions: &[VkBufferImageCopy],
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.handles_lock.push(src_buffer.clone());
|
||||
self.handles_lock.push(dst_image.clone());
|
||||
|
||||
self.device.cmd_copy_buffer_to_image(
|
||||
self.buffer,
|
||||
|
@ -774,13 +809,16 @@ where
|
|||
}
|
||||
|
||||
pub fn copy_image_to_buffer<T: ReprC + Send + Sync + 'static>(
|
||||
&'me mut self,
|
||||
src_image: &'handle Image<'device>,
|
||||
&mut self,
|
||||
src_image: &Arc<Image>,
|
||||
image_layout: VkImageLayout,
|
||||
dst_buffer: &'handle Buffer<'device, T>,
|
||||
dst_buffer: &Arc<Buffer<T>>,
|
||||
regions: &[VkBufferImageCopy],
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.handles_lock.push(src_image.clone());
|
||||
self.handles_lock.push(dst_buffer.clone());
|
||||
|
||||
self.device.cmd_copy_image_to_buffer(
|
||||
self.buffer,
|
||||
|
@ -791,20 +829,18 @@ where
|
|||
)
|
||||
}
|
||||
|
||||
pub fn update_buffer(&'me self) {
|
||||
pub fn update_buffer(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn fill_buffer(&'me self) {
|
||||
pub fn fill_buffer(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn clear_color_image(
|
||||
&'me mut self,
|
||||
image: &Image<'device>,
|
||||
clear_color: VkClearColorValue,
|
||||
) {
|
||||
*self.calls += 1;
|
||||
pub fn clear_color_image(&mut self, image: &Arc<Image>, clear_color: VkClearColorValue) {
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.handles_lock.push(image.clone());
|
||||
|
||||
self.device.cmd_clear_color_image(
|
||||
self.buffer,
|
||||
|
@ -815,21 +851,24 @@ where
|
|||
);
|
||||
}
|
||||
|
||||
pub fn clear_depth_stencil_image(&'me self) {
|
||||
pub fn clear_depth_stencil_image(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn clear_attachments(&'me self) {
|
||||
pub fn clear_attachments(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn resolve_image(
|
||||
&'me mut self,
|
||||
src_image: &'handle Image<'device>,
|
||||
dst_image: &'handle Image<'device>,
|
||||
&mut self,
|
||||
src_image: &Arc<Image>,
|
||||
dst_image: &Arc<Image>,
|
||||
regions: &[VkImageResolve],
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.handles_lock.push(src_image.clone());
|
||||
self.handles_lock.push(dst_image.clone());
|
||||
|
||||
self.device.cmd_resolve_image(
|
||||
self.buffer,
|
||||
|
@ -841,61 +880,61 @@ where
|
|||
);
|
||||
}
|
||||
|
||||
pub fn set_event(&'me self) {
|
||||
pub fn set_event(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn reset_event(&'me self) {
|
||||
pub fn reset_event(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn wait_events(&'me self) {
|
||||
pub fn wait_events(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn begin_query(&'me self) {
|
||||
pub fn begin_query(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn end_query(&'me self) {
|
||||
pub fn end_query(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn reset_query_pool(&'me self) {
|
||||
pub fn reset_query_pool(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn write_timestamp(
|
||||
&'me mut self,
|
||||
query_pool: &'handle QueryPool,
|
||||
&mut self,
|
||||
query_pool: &Arc<QueryPool>,
|
||||
query: u32,
|
||||
pipeline_stage: impl Into<VkPipelineStageFlagBits>,
|
||||
) {
|
||||
*self.calls += 1;
|
||||
self.calls.fetch_add(1, SeqCst);
|
||||
|
||||
self.handles_lock.push(query_pool.clone());
|
||||
|
||||
self.device
|
||||
.cmd_write_timestamp(self.buffer, pipeline_stage, query_pool.vk_handle(), query);
|
||||
}
|
||||
|
||||
pub fn copy_query_pool_results(&'me self) {
|
||||
pub fn copy_query_pool_results(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'me, 'handle, 'device, 'pipeline, 'cbuffer> CommandBufferRecorder<'device, 'pipeline, 'cbuffer>
|
||||
where
|
||||
'handle: 'me,
|
||||
{
|
||||
impl<'a> CommandBufferRecorder<'a> {
|
||||
pub fn build_acceleration_structure_indirect(
|
||||
&'me mut self,
|
||||
&mut self,
|
||||
infos: &[VkAccelerationStructureBuildGeometryInfoKHR],
|
||||
indirect_buffers: &[Buffer<'device, impl ReprC + Send + Sync + 'static>],
|
||||
indirect_buffers: &[Arc<Buffer<impl ReprC + Send + Sync + 'static>>],
|
||||
indirect_strides: &[u32],
|
||||
max_primitive_counts: &[&u32],
|
||||
) {
|
||||
let mut device_addresses: Vec<VkDeviceAddress> = Vec::with_capacity(indirect_buffers.len());
|
||||
|
||||
for indirect_buffer in indirect_buffers.iter() {
|
||||
self.handles_lock.push(indirect_buffer.clone());
|
||||
device_addresses.push(indirect_buffer.device_address().into());
|
||||
}
|
||||
|
||||
|
@ -909,7 +948,7 @@ where
|
|||
}
|
||||
|
||||
pub fn build_acceleration_structures(
|
||||
&'me self,
|
||||
&self,
|
||||
infos: &[VkAccelerationStructureBuildGeometryInfoKHR],
|
||||
range_infos: &[&[VkAccelerationStructureBuildRangeInfoKHR]],
|
||||
) {
|
||||
|
@ -918,11 +957,14 @@ where
|
|||
}
|
||||
|
||||
pub fn copy_acceleration_structure(
|
||||
&'me mut self,
|
||||
src: &'handle AccelerationStructure<'device>,
|
||||
dst: &'handle AccelerationStructure<'device>,
|
||||
&mut self,
|
||||
src: &Arc<AccelerationStructure>,
|
||||
dst: &Arc<AccelerationStructure>,
|
||||
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);
|
||||
|
||||
self.device
|
||||
|
@ -930,11 +972,13 @@ where
|
|||
}
|
||||
|
||||
pub fn copy_acceleration_structure_to_memory(
|
||||
&'me mut self,
|
||||
src: &'handle AccelerationStructure<'device>,
|
||||
&mut self,
|
||||
src: &Arc<AccelerationStructure>,
|
||||
dst: VkDeviceOrHostAddressKHR,
|
||||
mode: VkCopyAccelerationStructureModeKHR,
|
||||
) {
|
||||
self.handles_lock.push(src.clone());
|
||||
|
||||
let info = VkCopyAccelerationStructureToMemoryInfoKHR::new(src.vk_handle(), dst, mode);
|
||||
|
||||
self.device
|
||||
|
@ -942,11 +986,13 @@ where
|
|||
}
|
||||
|
||||
pub fn copy_memory_to_acceleration_structure(
|
||||
&'me mut self,
|
||||
&mut self,
|
||||
src: VkDeviceOrHostAddressConstKHR,
|
||||
dst: &'handle AccelerationStructure<'device>,
|
||||
dst: &Arc<AccelerationStructure>,
|
||||
mode: VkCopyAccelerationStructureModeKHR,
|
||||
) {
|
||||
self.handles_lock.push(dst.clone());
|
||||
|
||||
let info = VkCopyMemoryToAccelerationStructureInfoKHR::new(src, dst.vk_handle(), mode);
|
||||
|
||||
self.device
|
||||
|
@ -954,10 +1000,12 @@ where
|
|||
}
|
||||
|
||||
pub fn trace_rays_indirect(
|
||||
&'me mut self,
|
||||
sbt: &'handle ShaderBindingTable<'device>,
|
||||
buffer: &'handle Buffer<'device, impl ReprC + Send + Sync + 'static>,
|
||||
&mut self,
|
||||
sbt: ShaderBindingTable,
|
||||
buffer: Arc<Buffer<impl ReprC + Send + Sync + 'static>>,
|
||||
) {
|
||||
self.handles_lock.push(buffer.clone());
|
||||
|
||||
self.device.cmd_trace_rays_indirect(
|
||||
self.buffer,
|
||||
sbt.raygen_shader_binding_table(),
|
||||
|
@ -968,13 +1016,7 @@ where
|
|||
)
|
||||
}
|
||||
|
||||
pub fn trace_rays(
|
||||
&'me self,
|
||||
sbt: &'handle ShaderBindingTable<'device>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
depth: u32,
|
||||
) {
|
||||
pub fn trace_rays(&self, sbt: &ShaderBindingTable, width: u32, height: u32, depth: u32) {
|
||||
self.device.cmd_trace_rays(
|
||||
self.buffer,
|
||||
sbt.raygen_shader_binding_table(),
|
||||
|
@ -988,15 +1030,20 @@ where
|
|||
}
|
||||
|
||||
pub fn write_acceleration_structure_properties(
|
||||
&'me mut self,
|
||||
acceleration_structures: &[&'handle AccelerationStructure<'device>],
|
||||
&mut self,
|
||||
acceleration_structures: &[&Arc<AccelerationStructure>],
|
||||
query_type: VkQueryType,
|
||||
query_pool: &'handle QueryPool,
|
||||
query_pool: &Arc<QueryPool>,
|
||||
first_query: u32,
|
||||
) {
|
||||
self.handles_lock.push(query_pool.clone());
|
||||
|
||||
let as_handles: Vec<VkAccelerationStructureKHR> = acceleration_structures
|
||||
.iter()
|
||||
.map(|a| a.vk_handle())
|
||||
.map(|a| {
|
||||
self.handles_lock.push((*a).clone());
|
||||
a.vk_handle()
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.device.cmd_write_acceleration_structure_properties(
|
||||
|
@ -1009,21 +1056,53 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'device> VulkanDevice for CommandBuffer<'device> {
|
||||
fn device(&self) -> &'device Device {
|
||||
impl VulkanDevice for CommandBuffer {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<'device> Drop for CommandBuffer<'device> {
|
||||
impl Drop for CommandBuffer {
|
||||
fn drop(&mut self) {
|
||||
self.device
|
||||
.free_command_buffers(self.pool.vk_handle(), &[self.buffer]);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'device, 'pipeline, 'cbuffer> Drop for CommandBufferRecorder<'device, 'pipeline, 'cbuffer> {
|
||||
impl<'a> Drop for CommandBufferRecorder<'a> {
|
||||
fn drop(&mut self) {
|
||||
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)
|
||||
// }))
|
||||
// }
|
||||
|
|
|
@ -2,6 +2,8 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub(crate) struct CommandPoolBuilder {
|
||||
flags: VkCommandPoolCreateFlagBits,
|
||||
queue_family_index: u32,
|
||||
|
@ -20,25 +22,25 @@ impl CommandPoolBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub(crate) fn build<'a>(self, device: &'a Device) -> Result<CommandPool<'a>> {
|
||||
pub(crate) fn build(self, device: Arc<Device>) -> Result<Arc<CommandPool>> {
|
||||
let command_pool_ci = VkCommandPoolCreateInfo::new(self.flags, self.queue_family_index);
|
||||
|
||||
let command_pool = device.create_command_pool(&command_pool_ci)?;
|
||||
|
||||
Ok(CommandPool {
|
||||
Ok(Arc::new(CommandPool {
|
||||
device,
|
||||
command_pool,
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct CommandPool<'a> {
|
||||
device: &'a Device,
|
||||
pub(crate) struct CommandPool {
|
||||
device: Arc<Device>,
|
||||
command_pool: VkCommandPool,
|
||||
}
|
||||
|
||||
impl<'a> CommandPool<'a> {
|
||||
impl CommandPool {
|
||||
pub(crate) fn builder() -> CommandPoolBuilder {
|
||||
CommandPoolBuilder {
|
||||
flags: VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
|
||||
|
@ -48,16 +50,39 @@ impl<'a> CommandPool<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> VulkanDevice for CommandPool<'a> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for CommandPool {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle!(CommandPool<'a>, VkCommandPool, command_pool);
|
||||
impl_vk_handle!(CommandPool, VkCommandPool, command_pool);
|
||||
|
||||
impl<'a> Drop for CommandPool<'a> {
|
||||
impl Drop for CommandPool {
|
||||
fn drop(&mut self) {
|
||||
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) };
|
||||
// }
|
||||
|
|
|
@ -2,13 +2,15 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
pub struct DescriptorPoolBuilder<'a> {
|
||||
layout: Option<&'a DescriptorSetLayout<'a>>,
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct DescriptorPoolBuilder {
|
||||
layout: Option<Arc<DescriptorSetLayout>>,
|
||||
descriptor_count: u32,
|
||||
flags: VkDescriptorPoolCreateFlagBits,
|
||||
}
|
||||
|
||||
impl<'a> DescriptorPoolBuilder<'a> {
|
||||
impl DescriptorPoolBuilder {
|
||||
pub fn set_flags(mut self, flags: impl Into<VkDescriptorPoolCreateFlagBits>) -> Self {
|
||||
self.flags |= flags.into();
|
||||
|
||||
|
@ -21,13 +23,13 @@ impl<'a> DescriptorPoolBuilder<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn set_layout(mut self, layout: &'a DescriptorSetLayout<'a>) -> Self {
|
||||
pub fn set_layout(mut self, layout: Arc<DescriptorSetLayout>) -> Self {
|
||||
self.layout = Some(layout);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self, device: &'a Device) -> Result<DescriptorPool<'a>> {
|
||||
pub fn build(self, device: Arc<Device>) -> Result<Arc<DescriptorPool>> {
|
||||
if cfg!(debug_assertions) {
|
||||
if self.layout.is_none() {
|
||||
panic!("no layout set!");
|
||||
|
@ -58,23 +60,23 @@ impl<'a> DescriptorPoolBuilder<'a> {
|
|||
|
||||
let descriptor_pool = device.create_descriptor_pool(&descriptor_pool_ci)?;
|
||||
|
||||
Ok(DescriptorPool {
|
||||
Ok(Arc::new(DescriptorPool {
|
||||
device,
|
||||
descriptor_pool,
|
||||
descriptor_set_layout: layout,
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DescriptorPool<'device> {
|
||||
device: &'device Device,
|
||||
pub struct DescriptorPool {
|
||||
device: Arc<Device>,
|
||||
descriptor_pool: VkDescriptorPool,
|
||||
pub(crate) descriptor_set_layout: &'device DescriptorSetLayout<'device>,
|
||||
pub(crate) descriptor_set_layout: Arc<DescriptorSetLayout>,
|
||||
}
|
||||
|
||||
impl<'device> DescriptorPool<'device> {
|
||||
pub fn builder() -> DescriptorPoolBuilder<'device> {
|
||||
impl DescriptorPool {
|
||||
pub fn builder() -> DescriptorPoolBuilder {
|
||||
DescriptorPoolBuilder {
|
||||
layout: None,
|
||||
descriptor_count: 1,
|
||||
|
@ -87,33 +89,83 @@ impl<'device> DescriptorPool<'device> {
|
|||
.reset_descriptor_pool(self.descriptor_pool, VK_DESCRIPTOR_POOL_RESET_NULL_BIT)
|
||||
}
|
||||
|
||||
pub fn prepare_set(&'device self) -> DescriptorSetBuilder<'device> {
|
||||
DescriptorSet::builder(self.device, self)
|
||||
pub fn prepare_set(self: &Arc<Self>) -> DescriptorSetBuilder {
|
||||
DescriptorSet::builder(self.device.clone(), self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VulkanDevice for DescriptorPool<'a> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for DescriptorPool {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle!(DescriptorPool<'a>, VkDescriptorPool, descriptor_pool);
|
||||
impl_vk_handle!(DescriptorPool, VkDescriptorPool, descriptor_pool);
|
||||
|
||||
impl<'a> VkHandle<VkDescriptorSetLayout> for DescriptorPool<'a> {
|
||||
impl VkHandle<VkDescriptorSetLayout> for DescriptorPool {
|
||||
fn vk_handle(&self) -> VkDescriptorSetLayout {
|
||||
self.descriptor_set_layout.vk_handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VkHandle<VkDescriptorSetLayout> for &'a DescriptorPool<'a> {
|
||||
impl<'a> VkHandle<VkDescriptorSetLayout> for &'a DescriptorPool {
|
||||
fn vk_handle(&self) -> VkDescriptorSetLayout {
|
||||
self.descriptor_set_layout.vk_handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for DescriptorPool<'a> {
|
||||
impl VkHandle<VkDescriptorSetLayout> for Arc<DescriptorPool> {
|
||||
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) {
|
||||
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) };
|
||||
}
|
||||
|
|
|
@ -2,15 +2,17 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::slice;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DescriptorWrite<'handle> {
|
||||
lifetime: &'handle PhantomData<()>,
|
||||
pub struct DescriptorWrite {
|
||||
binding: u32,
|
||||
descriptor_type: VkDescriptorType,
|
||||
inner: InnerWrite,
|
||||
handles: Vec<Arc<dyn Any + Send + Sync>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -25,10 +27,10 @@ enum InnerWrite {
|
|||
),
|
||||
}
|
||||
|
||||
impl<'device, 'handle> DescriptorWrite<'handle> {
|
||||
impl DescriptorWrite {
|
||||
pub fn uniform_buffers<T: ReprC + Send + Sync + 'static>(
|
||||
binding: u32,
|
||||
buffers: &[&'handle Buffer<'device, T>],
|
||||
buffers: &[&Arc<Buffer<T>>],
|
||||
) -> Self {
|
||||
DescriptorWrite {
|
||||
binding,
|
||||
|
@ -43,13 +45,16 @@ impl<'device, 'handle> DescriptorWrite<'handle> {
|
|||
})
|
||||
.collect(),
|
||||
),
|
||||
lifetime: &PhantomData,
|
||||
handles: buffers
|
||||
.iter()
|
||||
.map(|b| (*b).clone() as Arc<dyn Any + Send + Sync>)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn storage_buffers<T: ReprC + Send + Sync + 'static>(
|
||||
binding: u32,
|
||||
buffers: &[&'handle Buffer<'device, T>],
|
||||
buffers: &[&Arc<Buffer<T>>],
|
||||
) -> Self {
|
||||
DescriptorWrite {
|
||||
binding,
|
||||
|
@ -64,11 +69,14 @@ impl<'device, 'handle> DescriptorWrite<'handle> {
|
|||
})
|
||||
.collect(),
|
||||
),
|
||||
lifetime: &PhantomData,
|
||||
handles: buffers
|
||||
.iter()
|
||||
.map(|b| (*b).clone() as Arc<dyn Any + Send + Sync>)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn combined_samplers(binding: u32, images: &[&'handle Image<'device>]) -> Self {
|
||||
pub fn combined_samplers(binding: u32, images: &[&Arc<Image>]) -> Self {
|
||||
DescriptorWrite {
|
||||
binding,
|
||||
descriptor_type: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
|
@ -86,11 +94,14 @@ impl<'device, 'handle> DescriptorWrite<'handle> {
|
|||
})
|
||||
.collect(),
|
||||
),
|
||||
lifetime: &PhantomData,
|
||||
handles: images
|
||||
.iter()
|
||||
.map(|i| (*i).clone() as Arc<dyn Any + Send + Sync>)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn storage_images(binding: u32, images: &[&'handle Image<'device>]) -> Self {
|
||||
pub fn storage_images(binding: u32, images: &[&Arc<Image>]) -> Self {
|
||||
DescriptorWrite {
|
||||
binding,
|
||||
descriptor_type: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
|
@ -104,11 +115,14 @@ impl<'device, 'handle> DescriptorWrite<'handle> {
|
|||
})
|
||||
.collect(),
|
||||
),
|
||||
lifetime: &PhantomData,
|
||||
handles: images
|
||||
.iter()
|
||||
.map(|i| (*i).clone() as Arc<dyn Any + Send + Sync>)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn input_attachments(binding: u32, images: &[&'handle Image<'device>]) -> Self {
|
||||
pub fn input_attachments(binding: u32, images: &[&Arc<Image>]) -> Self {
|
||||
DescriptorWrite {
|
||||
binding,
|
||||
descriptor_type: VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
|
||||
|
@ -122,13 +136,16 @@ impl<'device, 'handle> DescriptorWrite<'handle> {
|
|||
})
|
||||
.collect(),
|
||||
),
|
||||
lifetime: &PhantomData,
|
||||
handles: images
|
||||
.iter()
|
||||
.map(|i| (*i).clone() as Arc<dyn Any + Send + Sync>)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn acceleration_structures(
|
||||
binding: u32,
|
||||
acceleration_structures: &[&'handle AccelerationStructure<'device>],
|
||||
acceleration_structures: &[&Arc<AccelerationStructure>],
|
||||
) -> Self {
|
||||
let vk_as: Vec<VkAccelerationStructureKHR> = acceleration_structures
|
||||
.iter()
|
||||
|
@ -142,7 +159,10 @@ impl<'device, 'handle> DescriptorWrite<'handle> {
|
|||
VkWriteDescriptorSetAccelerationStructureKHR::default(),
|
||||
vk_as,
|
||||
)),
|
||||
lifetime: &PhantomData,
|
||||
handles: acceleration_structures
|
||||
.iter()
|
||||
.map(|a| (*a).clone() as Arc<dyn Any + Send + Sync>)
|
||||
.collect(),
|
||||
};
|
||||
|
||||
if let InnerWrite::AS((vk_write_as, vk_as)) = &mut write.inner {
|
||||
|
@ -178,21 +198,21 @@ impl<'device, 'handle> DescriptorWrite<'handle> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct DescriptorSetBuilder<'a> {
|
||||
device: &'a Device,
|
||||
descriptor_pool: &'a DescriptorPool<'a>,
|
||||
pub struct DescriptorSetBuilder {
|
||||
device: Arc<Device>,
|
||||
descriptor_pool: Arc<DescriptorPool>,
|
||||
variable_desc_counts: Vec<u32>,
|
||||
variable_descriptor_count: VkDescriptorSetVariableDescriptorCountAllocateInfoEXT,
|
||||
}
|
||||
|
||||
impl<'a> DescriptorSetBuilder<'a> {
|
||||
impl DescriptorSetBuilder {
|
||||
pub fn set_variable_descriptor_counts(mut self, descriptor_counts: &[u32]) -> Self {
|
||||
self.variable_desc_counts = descriptor_counts.to_vec();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn allocate<'handle>(mut self) -> Result<DescriptorSet<'a, 'handle>> {
|
||||
pub fn allocate(mut self) -> Result<Arc<DescriptorSet>> {
|
||||
let layout = self.descriptor_pool.vk_handle();
|
||||
|
||||
let mut descriptor_set_ci = VkDescriptorSetAllocateInfo::new(
|
||||
|
@ -208,30 +228,30 @@ impl<'a> DescriptorSetBuilder<'a> {
|
|||
|
||||
let descriptor_set = self.device.allocate_descriptor_sets(&descriptor_set_ci)?[0];
|
||||
|
||||
Ok(DescriptorSet {
|
||||
Ok(Arc::new(DescriptorSet {
|
||||
device: self.device,
|
||||
pool: self.descriptor_pool,
|
||||
descriptor_set,
|
||||
|
||||
lifetimes: &PhantomData,
|
||||
})
|
||||
handles: Mutex::new(HashMap::new()),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DescriptorSet<'device, 'handle> {
|
||||
device: &'device Device,
|
||||
pool: &'device DescriptorPool<'device>,
|
||||
pub struct DescriptorSet {
|
||||
device: Arc<Device>,
|
||||
pool: Arc<DescriptorPool>,
|
||||
descriptor_set: VkDescriptorSet,
|
||||
|
||||
lifetimes: &'handle PhantomData<()>,
|
||||
handles: Mutex<HashMap<u32, Vec<Arc<dyn Any + Send + Sync>>>>,
|
||||
}
|
||||
|
||||
impl<'device, 'handle> DescriptorSet<'device, 'handle> {
|
||||
impl DescriptorSet {
|
||||
pub(crate) fn builder(
|
||||
device: &'device Device,
|
||||
descriptor_pool: &'device DescriptorPool<'device>,
|
||||
) -> DescriptorSetBuilder<'device> {
|
||||
device: Arc<Device>,
|
||||
descriptor_pool: Arc<DescriptorPool>,
|
||||
) -> DescriptorSetBuilder {
|
||||
DescriptorSetBuilder {
|
||||
device,
|
||||
descriptor_pool,
|
||||
|
@ -243,7 +263,7 @@ impl<'device, 'handle> DescriptorSet<'device, 'handle> {
|
|||
}
|
||||
|
||||
// TODO: add update function for VkCopyDescriptorSet
|
||||
pub fn update(&self, writes: &[DescriptorWrite<'handle>]) -> Result<()> {
|
||||
pub fn update(&self, writes: &[DescriptorWrite]) -> Result<()> {
|
||||
debug_assert!(!writes.is_empty());
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -258,6 +278,7 @@ impl<'device, 'handle> DescriptorSet<'device, 'handle> {
|
|||
}
|
||||
|
||||
let mut vk_writes = Vec::new();
|
||||
let mut handles_lock = self.handles.lock().unwrap();
|
||||
|
||||
for write in writes {
|
||||
let mut write_desc = VkWriteDescriptorSet::new(
|
||||
|
@ -270,6 +291,13 @@ impl<'device, 'handle> DescriptorSet<'device, 'handle> {
|
|||
write.vk_write(&mut 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
|
||||
|
@ -279,31 +307,39 @@ impl<'device, 'handle> DescriptorSet<'device, 'handle> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'device, 'handle> VulkanDevice for DescriptorSet<'device, 'handle> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for DescriptorSet {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle!(
|
||||
DescriptorSet<'device, 'handle>,
|
||||
VkDescriptorSet,
|
||||
descriptor_set
|
||||
);
|
||||
impl_vk_handle!(DescriptorSet, VkDescriptorSet, descriptor_set);
|
||||
|
||||
impl<'device, 'handle> VkHandle<VkDescriptorSetLayout> for DescriptorSet<'device, 'handle> {
|
||||
impl VkHandle<VkDescriptorSetLayout> for DescriptorSet {
|
||||
fn vk_handle(&self) -> VkDescriptorSetLayout {
|
||||
self.pool.vk_handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'device, 'handle> VkHandle<VkDescriptorSetLayout> for &'a DescriptorSet<'device, 'handle> {
|
||||
impl<'a> VkHandle<VkDescriptorSetLayout> for &'a DescriptorSet {
|
||||
fn vk_handle(&self) -> VkDescriptorSetLayout {
|
||||
self.pool.vk_handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'device, 'handle> Drop for DescriptorSet<'device, 'handle> {
|
||||
impl VkHandle<VkDescriptorSetLayout> for Arc<DescriptorSet> {
|
||||
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) {
|
||||
if let Err(error) = self
|
||||
.device
|
||||
|
@ -319,6 +355,8 @@ mod test {
|
|||
use crate::prelude::*;
|
||||
use anyhow::Result;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[test]
|
||||
fn create_multiple_sets_from_one_pool() -> Result<()> {
|
||||
const DESCRIPTOR_COUNT: u32 = 2;
|
||||
|
@ -332,14 +370,14 @@ mod test {
|
|||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0,
|
||||
)
|
||||
.build(&device)?;
|
||||
.build(device.clone())?;
|
||||
|
||||
let descriptor_pool = DescriptorPool::builder()
|
||||
.set_layout(&descriptor_layout)
|
||||
.set_layout(descriptor_layout.clone())
|
||||
.set_descriptor_set_count(DESCRIPTOR_COUNT)
|
||||
.build(&device)?;
|
||||
.build(device.clone())?;
|
||||
|
||||
let descriptors: Vec<DescriptorSet<'_, '_>> = (0..DESCRIPTOR_COUNT)
|
||||
let descriptors: Vec<Arc<DescriptorSet>> = (0..DESCRIPTOR_COUNT)
|
||||
.map(|_| {
|
||||
let set = descriptor_pool.prepare_set().allocate();
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ impl DescriptorSetLayoutBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn build<'a>(self, device: &'a Device) -> Result<Arc<DescriptorSetLayout<'a>>> {
|
||||
pub fn build(self, device: Arc<Device>) -> Result<Arc<DescriptorSetLayout>> {
|
||||
let mut descriptor_set_ci =
|
||||
VkDescriptorSetLayoutCreateInfo::new(self.flags, &self.layout_bindings);
|
||||
let binding_flags_ci =
|
||||
|
@ -98,15 +98,15 @@ impl DescriptorSetLayoutBuilder {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DescriptorSetLayout<'a> {
|
||||
device: &'a Device,
|
||||
pub struct DescriptorSetLayout {
|
||||
device: Arc<Device>,
|
||||
descriptor_set_layout: VkDescriptorSetLayout,
|
||||
pool_sizes: Vec<VkDescriptorPoolSize>,
|
||||
|
||||
bindings: Vec<DescriptorLayoutBinding>,
|
||||
}
|
||||
|
||||
impl<'a> DescriptorSetLayout<'a> {
|
||||
impl DescriptorSetLayout {
|
||||
pub fn builder() -> DescriptorSetLayoutBuilder {
|
||||
DescriptorSetLayoutBuilder {
|
||||
layout_bindings: Vec::new(),
|
||||
|
@ -124,19 +124,19 @@ impl<'a> DescriptorSetLayout<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> VulkanDevice for DescriptorSetLayout<'a> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for DescriptorSetLayout {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle!(
|
||||
DescriptorSetLayout<'a>,
|
||||
DescriptorSetLayout,
|
||||
VkDescriptorSetLayout,
|
||||
descriptor_set_layout
|
||||
);
|
||||
|
||||
impl<'a> Drop for DescriptorSetLayout<'a> {
|
||||
impl Drop for DescriptorSetLayout {
|
||||
fn drop(&mut self) {
|
||||
self.device
|
||||
.destroy_descriptor_set_layout(self.descriptor_set_layout);
|
||||
|
|
|
@ -53,7 +53,7 @@ pub struct Device {
|
|||
|
||||
enabled_extensions: DeviceExtensions,
|
||||
|
||||
physical_device: PhysicalDevice,
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
device: VkDevice,
|
||||
|
||||
memory_allocator: Allocator,
|
||||
|
@ -65,9 +65,9 @@ impl Device {
|
|||
pub fn preinitialized(
|
||||
device: VkDevice,
|
||||
proc_addr: PFN_vkGetDeviceProcAddr,
|
||||
physical_device: PhysicalDevice,
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
extensions: &[VkString],
|
||||
) -> Result<Device> {
|
||||
) -> Result<Arc<Device>> {
|
||||
let device_functions = DeviceFunctions::load(|name| {
|
||||
proc_addr(device, name.as_ptr()) as *const std::ffi::c_void
|
||||
});
|
||||
|
@ -133,7 +133,7 @@ impl Device {
|
|||
physical_device.instance().api_version(),
|
||||
)?;
|
||||
|
||||
Ok(Device {
|
||||
Ok(Arc::new(Device {
|
||||
memory_allocator,
|
||||
|
||||
device_functions,
|
||||
|
@ -151,15 +151,15 @@ impl Device {
|
|||
device,
|
||||
|
||||
sampler_manager: SamplerManager::new(),
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
physical_device: PhysicalDevice,
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
mut extensions: DeviceExtensions,
|
||||
queue_infos: &[VkDeviceQueueCreateInfo],
|
||||
requested_device_features: DeviceFeatures,
|
||||
) -> Result<Device> {
|
||||
) -> Result<Arc<Device>> {
|
||||
// buffer device address is required in the current library implementation
|
||||
extensions.buffer_device_address = true;
|
||||
|
||||
|
@ -285,7 +285,7 @@ impl Device {
|
|||
physical_device.instance().api_version(),
|
||||
)?;
|
||||
|
||||
Ok(Device {
|
||||
Ok(Arc::new(Device {
|
||||
memory_allocator,
|
||||
|
||||
device_functions,
|
||||
|
@ -303,7 +303,7 @@ impl Device {
|
|||
device,
|
||||
|
||||
sampler_manager: SamplerManager::new(),
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
fn verify_vma_vk_functions(fns: &VmaVulkanFunctions) -> Result<()> {
|
||||
|
@ -348,22 +348,26 @@ impl Device {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_queue<'a>(&'a self, queue_family_index: u32, queue_index: u32) -> Mutex<Queue<'a>> {
|
||||
pub fn get_queue(
|
||||
self: &Arc<Self>,
|
||||
queue_family_index: u32,
|
||||
queue_index: u32,
|
||||
) -> Arc<Mutex<Queue>> {
|
||||
Queue::new(
|
||||
self,
|
||||
self.clone(),
|
||||
self.get_device_queue(queue_family_index, queue_index),
|
||||
queue_family_index,
|
||||
queue_index,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn physical_device(&self) -> &PhysicalDevice {
|
||||
pub fn physical_device(&self) -> &Arc<PhysicalDevice> {
|
||||
&self.physical_device
|
||||
}
|
||||
|
||||
pub fn wait_for_fences<'a>(
|
||||
pub fn wait_for_fences(
|
||||
&self,
|
||||
fences: &[&Fence<'a>],
|
||||
fences: &[&Arc<Fence>],
|
||||
wait_all: bool,
|
||||
timeout: Duration,
|
||||
) -> Result<()> {
|
||||
|
@ -1860,6 +1864,14 @@ 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]
|
||||
pub fn cmd_set_depth_bias(
|
||||
&self,
|
||||
|
|
|
@ -15,7 +15,7 @@ impl FenceBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn build<'a>(self, device: &'a Device) -> Result<Arc<Fence<'a>>> {
|
||||
pub fn build(self, device: Arc<Device>) -> Result<Arc<Fence>> {
|
||||
let flag: VkFenceCreateFlagBits = if self.signaled {
|
||||
VK_FENCE_CREATE_SIGNALED_BIT.into()
|
||||
} else {
|
||||
|
@ -31,12 +31,12 @@ impl FenceBuilder {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Fence<'a> {
|
||||
device: &'a Device,
|
||||
pub struct Fence {
|
||||
device: Arc<Device>,
|
||||
fence: VkFence,
|
||||
}
|
||||
|
||||
impl<'a> Fence<'a> {
|
||||
impl Fence {
|
||||
pub fn builder() -> FenceBuilder {
|
||||
FenceBuilder { signaled: false }
|
||||
}
|
||||
|
@ -50,16 +50,39 @@ impl<'a> Fence<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> VulkanDevice for Fence<'a> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for Fence {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle!(Fence<'a>, VkFence, fence);
|
||||
impl_vk_handle!(Fence, VkFence, fence);
|
||||
|
||||
impl<'a> Drop for Fence<'a> {
|
||||
impl Drop for Fence {
|
||||
fn drop(&mut self) {
|
||||
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) };
|
||||
}
|
||||
|
|
70
vulkan-rs/src/ffi.rs
Normal file
70
vulkan-rs/src/ffi.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
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
|
||||
}
|
|
@ -2,22 +2,24 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
pub struct FramebufferBuilder<'device, 'renderpass, 'image> {
|
||||
render_pass: Option<&'renderpass RenderPass<'device>>,
|
||||
attachments: Vec<&'image Image<'device>>,
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct FramebufferBuilder<'a> {
|
||||
render_pass: Option<&'a Arc<RenderPass>>,
|
||||
attachments: Vec<&'a Arc<Image>>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
layers: u32,
|
||||
}
|
||||
|
||||
impl<'device, 'renderpass, 'image> FramebufferBuilder<'device, 'renderpass, 'image> {
|
||||
pub fn set_render_pass(mut self, render_pass: &'renderpass RenderPass<'device>) -> Self {
|
||||
impl<'a> FramebufferBuilder<'a> {
|
||||
pub fn set_render_pass(mut self, render_pass: &'a Arc<RenderPass>) -> Self {
|
||||
self.render_pass = Some(render_pass);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_attachment(mut self, image: &'image Image<'device>) -> Self {
|
||||
pub fn add_attachment(mut self, image: &'a Arc<Image>) -> Self {
|
||||
self.attachments.push(image);
|
||||
|
||||
self
|
||||
|
@ -41,7 +43,7 @@ impl<'device, 'renderpass, 'image> FramebufferBuilder<'device, 'renderpass, 'ima
|
|||
self
|
||||
}
|
||||
|
||||
pub fn build(mut self, device: &'device Device) -> Result<Framebuffer<'device, 'image>> {
|
||||
pub fn build(mut self, device: Arc<Device>) -> Result<Arc<Framebuffer>> {
|
||||
if self.attachments.is_empty() {
|
||||
panic!("no attachments added!");
|
||||
}
|
||||
|
@ -78,29 +80,29 @@ impl<'device, 'renderpass, 'image> FramebufferBuilder<'device, 'renderpass, 'ima
|
|||
|
||||
let framebuffer = device.create_framebuffer(&framebuffer_ci)?;
|
||||
|
||||
Ok(Framebuffer {
|
||||
Ok(Arc::new(Framebuffer {
|
||||
device,
|
||||
framebuffer,
|
||||
images,
|
||||
|
||||
width: self.width,
|
||||
height: self.height,
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Framebuffer<'device, 'image> {
|
||||
device: &'device Device,
|
||||
pub struct Framebuffer {
|
||||
device: Arc<Device>,
|
||||
framebuffer: VkFramebuffer,
|
||||
images: Vec<&'image Image<'device>>,
|
||||
images: Vec<Arc<Image>>,
|
||||
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
impl<'device, 'image> Framebuffer<'device, 'image> {
|
||||
pub fn builder<'renderpass>() -> FramebufferBuilder<'device, 'renderpass, 'image> {
|
||||
impl Framebuffer {
|
||||
pub fn builder<'a>() -> FramebufferBuilder<'a> {
|
||||
FramebufferBuilder {
|
||||
render_pass: None,
|
||||
attachments: Vec::new(),
|
||||
|
@ -118,11 +120,11 @@ impl<'device, 'image> Framebuffer<'device, 'image> {
|
|||
self.height
|
||||
}
|
||||
|
||||
pub fn attachments(&self) -> &[&'image Image<'device>] {
|
||||
pub fn attachments(&self) -> &[Arc<Image>] {
|
||||
&self.images
|
||||
}
|
||||
|
||||
pub fn image(&self, index: usize) -> &Image<'device> {
|
||||
pub fn image(&self, index: usize) -> &Arc<Image> {
|
||||
&self.images[index]
|
||||
}
|
||||
|
||||
|
@ -131,15 +133,15 @@ impl<'device, 'image> Framebuffer<'device, 'image> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'device, 'image> VulkanDevice for Framebuffer<'device, 'image> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for Framebuffer {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle!(Framebuffer<'device, 'image>, VkFramebuffer, framebuffer);
|
||||
impl_vk_handle!(Framebuffer, VkFramebuffer, framebuffer);
|
||||
|
||||
impl<'device, 'image> Drop for Framebuffer<'device, 'image> {
|
||||
impl Drop for Framebuffer {
|
||||
fn drop(&mut self) {
|
||||
self.device.destroy_framebuffer(self.framebuffer);
|
||||
}
|
||||
|
|
|
@ -9,20 +9,20 @@ use std::path::Path;
|
|||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
||||
enum ImageSourceType<'a> {
|
||||
enum ImageSourceType {
|
||||
Empty,
|
||||
Raw(Vec<u8>),
|
||||
Array(Vec<Image<'a>>),
|
||||
Array(Vec<Arc<Image>>),
|
||||
}
|
||||
|
||||
struct ImageCreateInfo<'a> {
|
||||
struct ImageCreateInfo {
|
||||
vk_image_create_info: VkImageCreateInfo,
|
||||
|
||||
source_type: ImageSourceType<'a>,
|
||||
source_type: ImageSourceType,
|
||||
}
|
||||
|
||||
impl<'a> ImageCreateInfo<'a> {
|
||||
fn default(source_type: ImageSourceType<'a>) -> Self {
|
||||
impl ImageCreateInfo {
|
||||
fn default(source_type: ImageSourceType) -> Self {
|
||||
ImageCreateInfo {
|
||||
vk_image_create_info: VkImageCreateInfo::new(
|
||||
0,
|
||||
|
@ -62,15 +62,15 @@ struct PreinitializedImage {
|
|||
assume_layout: bool,
|
||||
}
|
||||
|
||||
enum ImageBuilderInternalType<'a> {
|
||||
enum ImageBuilderInternalType {
|
||||
PreinitializedImage(PreinitializedImage),
|
||||
NewImage(ImageCreateInfo<'a>),
|
||||
NewImage(ImageCreateInfo),
|
||||
}
|
||||
|
||||
/// Implements the builder pattern for Image
|
||||
pub struct ImageBuilder<'a> {
|
||||
pub struct ImageBuilder {
|
||||
file_name: Option<AssetPath>,
|
||||
builder_type: ImageBuilderInternalType<'a>,
|
||||
builder_type: ImageBuilderInternalType,
|
||||
components: VkComponentMapping,
|
||||
view_type: VkImageViewType,
|
||||
subresource_range: VkImageSubresourceRange,
|
||||
|
@ -78,9 +78,9 @@ pub struct ImageBuilder<'a> {
|
|||
sampler: Option<Arc<Sampler>>,
|
||||
}
|
||||
|
||||
impl<'a> ImageBuilder<'a> {
|
||||
impl ImageBuilder {
|
||||
/// Sets up the ImageBuilder for further use
|
||||
fn new(internal_type: ImageBuilderInternalType<'a>) -> Self {
|
||||
fn new(internal_type: ImageBuilderInternalType) -> Self {
|
||||
ImageBuilder {
|
||||
file_name: None,
|
||||
builder_type: internal_type,
|
||||
|
@ -98,7 +98,7 @@ impl<'a> ImageBuilder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn build(self, device: &'a Device, queue: &'a Mutex<Queue<'a>>) -> Result<Image<'a>> {
|
||||
pub fn build(self, device: &Arc<Device>, queue: &Arc<Mutex<Queue>>) -> Result<Arc<Image>> {
|
||||
let mut image_view_ci = self.vk_image_view_create_info();
|
||||
|
||||
match self.builder_type {
|
||||
|
@ -107,9 +107,9 @@ impl<'a> ImageBuilder<'a> {
|
|||
|
||||
let image_view = device.create_image_view(&image_view_ci)?;
|
||||
|
||||
let image = Image {
|
||||
device,
|
||||
queue,
|
||||
let image = Arc::new(Image {
|
||||
device: device.clone(),
|
||||
queue: queue.clone(),
|
||||
|
||||
image: preinitialized_image.image,
|
||||
image_view,
|
||||
|
@ -130,7 +130,7 @@ impl<'a> ImageBuilder<'a> {
|
|||
levels: 1,
|
||||
sample_count: preinitialized_image.sample_count,
|
||||
usage: preinitialized_image.usage,
|
||||
};
|
||||
});
|
||||
|
||||
// TODO: check necessity
|
||||
if !preinitialized_image.assume_layout {
|
||||
|
@ -384,13 +384,13 @@ impl<'a> ImageBuilder<'a> {
|
|||
}
|
||||
|
||||
fn create_from_source(
|
||||
device: &'a Device,
|
||||
queue: &'a Mutex<Queue<'a>>,
|
||||
info: &ImageCreateInfo<'a>,
|
||||
device: &Arc<Device>,
|
||||
queue: &Arc<Mutex<Queue>>,
|
||||
info: &ImageCreateInfo,
|
||||
sampler: Option<Arc<Sampler>>,
|
||||
mut view_ci: VkImageViewCreateInfo,
|
||||
file_name: Option<AssetPath>,
|
||||
) -> Result<Image<'a>> {
|
||||
) -> Result<Arc<Image>> {
|
||||
let format = view_ci.format;
|
||||
|
||||
let (image, memory) = Self::create_texture(device, &info.vk_image_create_info)?;
|
||||
|
@ -399,9 +399,9 @@ impl<'a> ImageBuilder<'a> {
|
|||
|
||||
let image_view = device.create_image_view(&view_ci)?;
|
||||
|
||||
Ok(Image {
|
||||
device,
|
||||
queue,
|
||||
Ok(Arc::new(Image {
|
||||
device: device.clone(),
|
||||
queue: queue.clone(),
|
||||
|
||||
image,
|
||||
image_view,
|
||||
|
@ -422,13 +422,13 @@ impl<'a> ImageBuilder<'a> {
|
|||
levels: info.vk_image_create_info.mipLevels,
|
||||
sample_count: info.vk_image_create_info.samples,
|
||||
usage: info.vk_image_create_info.usage,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
fn create_texture(
|
||||
device: &'a Device,
|
||||
device: &Arc<Device>,
|
||||
image_ci: &VkImageCreateInfo,
|
||||
) -> Result<(VkImage, Memory<'a, RawBuffer>)> {
|
||||
) -> Result<(VkImage, Arc<Memory<RawBuffer>>)> {
|
||||
let image = Self::create_image(device, image_ci)?;
|
||||
let memory = Memory::image_memory(
|
||||
device,
|
||||
|
@ -439,7 +439,7 @@ impl<'a> ImageBuilder<'a> {
|
|||
Ok((image, memory))
|
||||
}
|
||||
|
||||
fn create_image(device: &'a Device, image_ci: &VkImageCreateInfo) -> Result<VkImage> {
|
||||
fn create_image(device: &Arc<Device>, image_ci: &VkImageCreateInfo) -> Result<VkImage> {
|
||||
debug_assert_ne!(image_ci.extent.width, 0);
|
||||
debug_assert_ne!(image_ci.extent.height, 0);
|
||||
|
||||
|
@ -447,18 +447,18 @@ impl<'a> ImageBuilder<'a> {
|
|||
}
|
||||
|
||||
fn optimize_fill(
|
||||
device: &'a Device,
|
||||
queue: &'a Mutex<Queue<'a>>,
|
||||
device: &Arc<Device>,
|
||||
queue: &Arc<Mutex<Queue>>,
|
||||
data: &[RawBuffer],
|
||||
image: &Image<'a>,
|
||||
image: &Arc<Image>,
|
||||
) -> Result<()> {
|
||||
let staging_buffer = Buffer::builder()
|
||||
.set_usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT)
|
||||
.set_memory_usage(MemoryUsage::CpuToGpu)
|
||||
.set_data(data)
|
||||
.build(device)?;
|
||||
.build(device.clone())?;
|
||||
|
||||
copy_buffer_to_image(image, device, queue, &staging_buffer)?;
|
||||
copy_buffer_to_image(device, queue, &staging_buffer, image)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -469,12 +469,12 @@ impl<'a> ImageBuilder<'a> {
|
|||
/// handles VkImage, VkSampler, VkDeviceSize and VkImageView internally
|
||||
/// just as you set it up to
|
||||
#[derive(Debug)]
|
||||
pub struct Image<'a> {
|
||||
pub struct Image {
|
||||
// device handle
|
||||
device: &'a Device,
|
||||
device: Arc<Device>,
|
||||
|
||||
// queue handle
|
||||
queue: &'a Mutex<Queue<'a>>,
|
||||
queue: Arc<Mutex<Queue>>,
|
||||
|
||||
file_name: Option<AssetPath>,
|
||||
|
||||
|
@ -486,7 +486,7 @@ pub struct Image<'a> {
|
|||
image_view: VkImageView,
|
||||
|
||||
// optional handles
|
||||
_memory: Option<Memory<'a, RawBuffer>>,
|
||||
_memory: Option<Arc<Memory<RawBuffer>>>,
|
||||
sampler: Option<Arc<Sampler>>,
|
||||
|
||||
// image information
|
||||
|
@ -502,7 +502,7 @@ pub struct Image<'a> {
|
|||
usage: VkImageUsageFlagBits,
|
||||
}
|
||||
|
||||
impl<'a> Image<'a> {
|
||||
impl Image {
|
||||
/// Creates an `ImageBuilder` where you can define the image for your needs
|
||||
///
|
||||
/// For example, this is used to wrap swapchain images
|
||||
|
@ -519,7 +519,7 @@ impl<'a> Image<'a> {
|
|||
layout: VkImageLayout,
|
||||
usage: impl Into<VkImageUsageFlagBits>,
|
||||
assume_layout: bool,
|
||||
) -> ImageBuilder<'a> {
|
||||
) -> ImageBuilder {
|
||||
ImageBuilder::new(ImageBuilderInternalType::PreinitializedImage(
|
||||
PreinitializedImage {
|
||||
image,
|
||||
|
@ -545,7 +545,7 @@ impl<'a> Image<'a> {
|
|||
/// * `source` - The color information for the image
|
||||
/// * `width` - The target width of the image
|
||||
/// * `height` - The target height of the image
|
||||
pub fn from_raw(source: Vec<u8>, width: u32, height: u32) -> ImageBuilder<'a> {
|
||||
pub fn from_raw(source: Vec<u8>, width: u32, height: u32) -> ImageBuilder {
|
||||
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.height = height;
|
||||
|
@ -563,7 +563,7 @@ impl<'a> Image<'a> {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `file` - The path to the file
|
||||
pub fn from_file(file: AssetPath) -> Result<ImageBuilder<'a>> {
|
||||
pub fn from_file(file: AssetPath) -> Result<ImageBuilder> {
|
||||
let texture = match image::open(&file.full_path()) {
|
||||
Ok(i) => i.to_rgba8(),
|
||||
Err(err) => return Err(anyhow::Error::new(err).context(file.full_path())),
|
||||
|
@ -591,7 +591,7 @@ impl<'a> Image<'a> {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `slice` - Slice of bytes
|
||||
pub fn from_slice(data: &[u8]) -> Result<ImageBuilder<'a>> {
|
||||
pub fn from_slice(data: &[u8]) -> Result<ImageBuilder> {
|
||||
let texture = image::load_from_memory(data)?.to_rgba8();
|
||||
|
||||
let (width, height) = texture.dimensions();
|
||||
|
@ -607,7 +607,7 @@ impl<'a> Image<'a> {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `array` - Source images
|
||||
pub fn from_array(array: Vec<Image<'a>>) -> ImageBuilder<'a> {
|
||||
pub fn from_array(array: Vec<Arc<Image>>) -> ImageBuilder {
|
||||
debug_assert!(array.is_empty(), "images array must not be empty");
|
||||
|
||||
let width = array[0].width();
|
||||
|
@ -652,7 +652,7 @@ impl<'a> Image<'a> {
|
|||
height: u32,
|
||||
usage: impl Into<VkImageUsageFlagBits>,
|
||||
sample_count: VkSampleCountFlags,
|
||||
) -> ImageBuilder<'a> {
|
||||
) -> ImageBuilder {
|
||||
let mut create_info = ImageCreateInfo::default(ImageSourceType::Empty);
|
||||
create_info.vk_image_create_info.samples = sample_count.into();
|
||||
create_info.vk_image_create_info.extent.width = width;
|
||||
|
@ -664,7 +664,7 @@ impl<'a> Image<'a> {
|
|||
}
|
||||
|
||||
pub fn check_configuration(
|
||||
device: &'a Device,
|
||||
device: &Arc<Device>,
|
||||
tiling: VkImageTiling,
|
||||
format: VkFormat,
|
||||
usage: impl Into<VkImageUsageFlagBits>,
|
||||
|
@ -677,11 +677,11 @@ impl<'a> Image<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn device(&self) -> &Device {
|
||||
pub fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
|
||||
pub fn queue(&self) -> &Mutex<Queue<'a>> {
|
||||
pub fn queue(&self) -> &Arc<Mutex<Queue>> {
|
||||
&self.queue
|
||||
}
|
||||
|
||||
|
@ -689,7 +689,7 @@ impl<'a> Image<'a> {
|
|||
self.file_name.as_ref()
|
||||
}
|
||||
|
||||
pub fn convert_layout(&self, target_layout: VkImageLayout) -> Result<()> {
|
||||
pub fn convert_layout(self: &Arc<Self>, target_layout: VkImageLayout) -> Result<()> {
|
||||
into_layout(self, target_layout)
|
||||
}
|
||||
|
||||
|
@ -788,7 +788,7 @@ impl<'a> Image<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn to_file(&self, path: impl AsRef<Path>) -> Result<()> {
|
||||
pub fn to_file(self: &Arc<Image>, path: impl AsRef<Path>) -> Result<()> {
|
||||
// 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 {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
@ -815,9 +815,9 @@ impl<'a> Image<'a> {
|
|||
}
|
||||
|
||||
pub fn copy_image_to_buffer(
|
||||
&self,
|
||||
self: &Arc<Image>,
|
||||
extra_buffer_flags: impl Into<Option<VkBufferUsageFlagBits>>,
|
||||
) -> Result<Buffer<'a, RawBuffer>> {
|
||||
) -> Result<Arc<Buffer<RawBuffer>>> {
|
||||
let usage = match extra_buffer_flags.into() {
|
||||
Some(flags) => VK_BUFFER_USAGE_TRANSFER_DST_BIT | flags,
|
||||
None => VK_BUFFER_USAGE_TRANSFER_DST_BIT.into(),
|
||||
|
@ -829,10 +829,10 @@ impl<'a> Image<'a> {
|
|||
.set_size((self.width * self.height * 4) as VkDeviceSize)
|
||||
.build(self.device.clone())?;
|
||||
|
||||
let mut command_buffer =
|
||||
let command_buffer =
|
||||
CommandBuffer::new_primary().build(self.device.clone(), self.queue.clone())?;
|
||||
|
||||
SingleSubmit::builder(&mut command_buffer, &self.queue, |recorder| {
|
||||
SingleSubmit::builder(&command_buffer, &self.queue, |recorder| {
|
||||
// copy info for copying the content of the buffer into the image
|
||||
let buffer_image_copy = VkBufferImageCopy {
|
||||
bufferOffset: 0,
|
||||
|
@ -885,21 +885,21 @@ impl<'a> Image<'a> {
|
|||
Ok(buffer)
|
||||
}
|
||||
|
||||
pub fn copy_buffer_to_image(&self, buffer: &Arc<Buffer<'a, RawBuffer>>) -> Result<()> {
|
||||
copy_buffer_to_image(self, &self.device, &self.queue, &buffer)
|
||||
pub fn copy_buffer_to_image(self: &Arc<Image>, buffer: &Arc<Buffer<RawBuffer>>) -> Result<()> {
|
||||
copy_buffer_to_image(&self.device, &self.queue, &buffer, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VulkanDevice for Image<'a> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for Image {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle!(Image<'a>, VkImage, image);
|
||||
impl_vk_handle!(Image<'a>, VkImageView, image_view);
|
||||
impl_vk_handle!(Image, VkImage, image);
|
||||
impl_vk_handle!(Image, VkImageView, image_view);
|
||||
|
||||
impl<'a> Drop for Image<'a> {
|
||||
impl Drop for Image {
|
||||
fn drop(&mut self) {
|
||||
self.device.destroy_image_view(self.image_view);
|
||||
|
||||
|
@ -909,9 +909,10 @@ impl<'a> Drop for Image<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn into_layout<'a>(image: &Image<'a>, layout: VkImageLayout) -> Result<()> {
|
||||
fn into_layout(image: &Arc<Image>, layout: VkImageLayout) -> Result<()> {
|
||||
// create a new command buffer
|
||||
let mut command_buffer = CommandBuffer::new_primary().build(image.device, image.queue)?;
|
||||
let command_buffer =
|
||||
CommandBuffer::new_primary().build(image.device.clone(), image.queue.clone())?;
|
||||
|
||||
{
|
||||
// begin recording into this command buffer
|
||||
|
@ -949,17 +950,17 @@ fn into_layout<'a>(image: &Image<'a>, layout: VkImageLayout) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn copy_buffer_to_image<'a, T: ReprC + Send + Sync + 'static>(
|
||||
image: &Image<'a>,
|
||||
device: &'a Device,
|
||||
queue: &'a Mutex<Queue<'a>>,
|
||||
buffer: &Buffer<'a, T>,
|
||||
fn copy_buffer_to_image<T: ReprC + Send + Sync + 'static>(
|
||||
device: &Arc<Device>,
|
||||
queue: &Arc<Mutex<Queue>>,
|
||||
buffer: &Arc<Buffer<T>>,
|
||||
image: &Arc<Image>,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
// create a new command buffer
|
||||
let mut command_buffer = CommandBuffer::new_primary().build(device, queue)?;
|
||||
let command_buffer = CommandBuffer::new_primary().build(device.clone(), queue.clone())?;
|
||||
|
||||
{
|
||||
// begin recording into this command buffer
|
||||
|
@ -1044,14 +1045,14 @@ where
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn copy_images_to_imagearray<'a>(
|
||||
device: &'a Device,
|
||||
queue: &'a Mutex<Queue<'a>>,
|
||||
image_array: &Image<'a>,
|
||||
images: &[Image<'a>],
|
||||
fn copy_images_to_imagearray(
|
||||
device: &Arc<Device>,
|
||||
queue: &Arc<Mutex<Queue>>,
|
||||
image_array: &Arc<Image>,
|
||||
images: &[Arc<Image>],
|
||||
) -> Result<()> {
|
||||
// create a new command buffer
|
||||
let mut command_buffer = CommandBuffer::new_primary().build(device, queue)?;
|
||||
let command_buffer = CommandBuffer::new_primary().build(device.clone(), queue.clone())?;
|
||||
|
||||
{
|
||||
// set command buffer buffer in recording state
|
||||
|
@ -1118,10 +1119,10 @@ fn copy_images_to_imagearray<'a>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn copy_image_to_image<'device, 'pipeline, 'cbuffer>(
|
||||
buffer_recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
|
||||
src_image: &Image<'device>,
|
||||
dst_image: &Image<'device>,
|
||||
fn copy_image_to_image(
|
||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||
src_image: &Arc<Image>,
|
||||
dst_image: &Arc<Image>,
|
||||
mip_level: u32,
|
||||
dst_layer: u32,
|
||||
) {
|
||||
|
@ -1180,9 +1181,9 @@ fn copy_image_to_image<'device, 'pipeline, 'cbuffer>(
|
|||
);
|
||||
}
|
||||
|
||||
fn blit_mip_maps<'device, 'pipeline, 'cbuffer>(
|
||||
buffer_recorder: &mut CommandBufferRecorder<'device, 'pipeline, 'cbuffer>,
|
||||
image: &Image<'device>,
|
||||
fn blit_mip_maps(
|
||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||
image: &Arc<Image>,
|
||||
target_image_layout: VkImageLayout,
|
||||
) {
|
||||
let mut mip_width = image.width();
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::collections::HashSet;
|
|||
use std::fmt;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use std::os::raw::c_char;
|
||||
use std::os::raw::c_void;
|
||||
|
@ -103,7 +104,7 @@ impl Instance {
|
|||
proc_addr: PFN_vkGetInstanceProcAddr,
|
||||
extensions: &[VkString],
|
||||
api_version: Option<u32>,
|
||||
) -> Result<Instance> {
|
||||
) -> Result<Arc<Instance>> {
|
||||
let static_functions = StaticFunctions {
|
||||
_lib: None,
|
||||
vkGetInstanceProcAddr: proc_addr,
|
||||
|
@ -121,7 +122,7 @@ impl Instance {
|
|||
|
||||
let instance_extensions = InstanceExtensions::from_list(extensions);
|
||||
|
||||
let instance = Instance {
|
||||
let instance = Arc::new(Instance {
|
||||
_static_functions: static_functions,
|
||||
_entry_functions: None,
|
||||
instance_functions,
|
||||
|
@ -137,7 +138,7 @@ impl Instance {
|
|||
debug_report: None,
|
||||
|
||||
api_version: api_version.unwrap_or(VK_MAKE_VERSION(1, 0, 0)),
|
||||
};
|
||||
});
|
||||
|
||||
Ok(instance)
|
||||
}
|
||||
|
@ -146,7 +147,7 @@ impl Instance {
|
|||
app_info: VkApplicationInfo<'_>,
|
||||
debug_info: VulkanDebugInfo,
|
||||
mut extensions: InstanceExtensions,
|
||||
) -> Result<Instance> {
|
||||
) -> Result<Arc<Instance>> {
|
||||
// required in physical device
|
||||
extensions.physical_device_properties2 = true;
|
||||
|
||||
|
@ -266,7 +267,7 @@ impl Instance {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(instance)
|
||||
Ok(Arc::new(instance))
|
||||
}
|
||||
|
||||
pub(crate) fn api_version(&self) -> u32 {
|
||||
|
|
|
@ -39,6 +39,8 @@ pub mod shadermodule;
|
|||
pub mod surface;
|
||||
pub mod swapchain;
|
||||
|
||||
pub mod ffi;
|
||||
|
||||
mod sampler_manager;
|
||||
mod single_submit;
|
||||
|
||||
|
@ -54,11 +56,13 @@ pub trait VkHandle<T> {
|
|||
}
|
||||
|
||||
pub trait VulkanDevice {
|
||||
fn device(&self) -> &device::Device;
|
||||
fn device(&self) -> &std::sync::Arc<device::Device>;
|
||||
}
|
||||
|
||||
pub fn create_vk_handles<'a>(
|
||||
) -> anyhow::Result<(prelude::Device, std::sync::Mutex<prelude::Queue<'a>>)> {
|
||||
pub fn create_vk_handles() -> anyhow::Result<(
|
||||
std::sync::Arc<prelude::Device>,
|
||||
std::sync::Arc<std::sync::Mutex<prelude::Queue>>,
|
||||
)> {
|
||||
use crate::prelude::*;
|
||||
|
||||
let instance = Instance::new(
|
||||
|
|
|
@ -1,25 +1,49 @@
|
|||
macro_rules! impl_vk_handle {
|
||||
($struct_name:ident $(<$( $lt:lifetime $(,)? )* $( $const:ident $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => {
|
||||
impl$(<$( $lt, )* $( $const $name: $type, )*>)? VkHandle<$target_name> for $struct_name$(<$($lt, )* $($name,)*>)? {
|
||||
($struct_name:ident $(<$( $const:ident $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => {
|
||||
impl$(<$( $const $name: $type, )*>)? VkHandle<$target_name> for $struct_name$(<$($name,)?>)? {
|
||||
fn vk_handle(&self) -> $target_name {
|
||||
self.$value
|
||||
}
|
||||
}
|
||||
|
||||
impl<'x $($(, $lt )* $(, $const $name: $type)*)?> VkHandle<$target_name> for &'x $struct_name$(<$($lt, )* $($name,)*>)? {
|
||||
impl<'a $($(, $const $name: $type)*)?> VkHandle<$target_name> for &'a $struct_name$(<$($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 {
|
||||
self.$value
|
||||
}
|
||||
}
|
||||
};
|
||||
($struct_name:ident $(<$( $lt:lifetime $(,)? )* $( $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => {
|
||||
impl$(<$( $lt, )* $( $name: $type, )*>)? VkHandle<$target_name> for $struct_name$(<$($lt, )* $($name,)*>)? {
|
||||
($struct_name:ident $(<$( $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => {
|
||||
impl$(<$( $name: $type, )*>)? VkHandle<$target_name> for $struct_name$(<$($name,)?>)? {
|
||||
fn vk_handle(&self) -> $target_name {
|
||||
self.$value
|
||||
}
|
||||
}
|
||||
|
||||
impl<'x $($(, $lt, )* $(, $name: $type)*)?> VkHandle<$target_name> for &'x $struct_name$(<$($lt, )* $($name,)*>)? {
|
||||
impl<'a $($(, $name: $type)*)?> VkHandle<$target_name> for &'a $struct_name$(<$($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 {
|
||||
self.$value
|
||||
}
|
||||
|
@ -28,14 +52,26 @@ macro_rules! impl_vk_handle {
|
|||
}
|
||||
|
||||
macro_rules! impl_vk_handle_t {
|
||||
($struct_name:ident $([$($t:ident $(,)? )* ])? $(<$( $lt:lifetime $(,)? )* $( $const:ident $name:ident: $type:ident, )*>)?, $target_name:ident, $value:ident) => {
|
||||
impl<$( $( $lt, )* $( $name: $type, )* )? T $(: $($t,)* )?> VkHandle<$target_name> for $struct_name<$( $($lt, )* $($name,)* )? T> {
|
||||
($struct_name:ident $([$($t:ident $(,)? )* ])?, $target_name:ident, $value:ident) => {
|
||||
impl<T $(: $($t,)* )?> VkHandle<$target_name> for $struct_name<T> {
|
||||
fn vk_handle(&self) -> $target_name {
|
||||
self.$value
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, $( $( $lt, )* $( $name: $type, )* )? T $(: $($t,)* )?> VkHandle<$target_name> for &'a $struct_name<$( $($lt, )* $($name,)* )? T> {
|
||||
impl<'a, T $(: $($t,)* )?> VkHandle<$target_name> for &'a $struct_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 {
|
||||
self.$value
|
||||
}
|
||||
|
|
|
@ -6,12 +6,13 @@ use utilities::impl_reprc;
|
|||
use vma_rs::prelude::*;
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
||||
impl_reprc!(
|
||||
#[derive(Debug, Copy)]
|
||||
pub struct RawBuffer {
|
||||
#[assume_reprc]
|
||||
d: u8,
|
||||
pub d: u8,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -44,42 +45,45 @@ impl Into<VmaMemoryUsage> for MemoryUsage {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Memory<'a, T: ReprC> {
|
||||
device: &'a Device,
|
||||
pub struct Memory<T: ReprC> {
|
||||
device: Arc<Device>,
|
||||
|
||||
allocation: Allocation,
|
||||
|
||||
data_type: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: ReprC> Memory<'a, T> {
|
||||
impl<T: ReprC> Memory<T> {
|
||||
pub(crate) fn forced_requirements(
|
||||
device: &'a Device,
|
||||
device: &Arc<Device>,
|
||||
memory_requirements: VkMemoryRequirements,
|
||||
buffer: VkBuffer,
|
||||
memory_usage: VmaMemoryUsage,
|
||||
) -> Result<Memory<'a, T>> {
|
||||
) -> Result<Arc<Memory<T>>> {
|
||||
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)
|
||||
}
|
||||
|
||||
pub(crate) fn buffer_memory(
|
||||
device: &'a Device,
|
||||
device: &Arc<Device>,
|
||||
buffer: VkBuffer,
|
||||
memory_usage: VmaMemoryUsage,
|
||||
) -> Result<Memory<'a, T>> {
|
||||
) -> Result<Arc<Memory<T>>> {
|
||||
let memory_requirements = device.buffer_memory_requirements(buffer);
|
||||
|
||||
Self::create_and_bind(device, memory_requirements, memory_usage, buffer)
|
||||
}
|
||||
|
||||
pub(crate) fn image_memory(
|
||||
device: &'a Device,
|
||||
device: &Arc<Device>,
|
||||
image: VkImage,
|
||||
memory_usage: VmaMemoryUsage,
|
||||
) -> Result<Memory<'a, T>> {
|
||||
) -> Result<Arc<Memory<T>>> {
|
||||
let memory_requirements = device.image_memory_requirements(image);
|
||||
|
||||
Self::create_and_bind(device, memory_requirements, memory_usage, image)
|
||||
|
@ -90,22 +94,22 @@ impl<'a, T: ReprC> Memory<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
trait MemoryBinder<'a, T, K: ReprC> {
|
||||
trait MemoryBinder<T, K: ReprC> {
|
||||
fn create_and_bind(
|
||||
device: &'a Device,
|
||||
device: &Arc<Device>,
|
||||
memory_requirements: VkMemoryRequirements,
|
||||
memory_usage: VmaMemoryUsage,
|
||||
argument: T,
|
||||
) -> Result<Memory<'a, K>>;
|
||||
) -> Result<Arc<Memory<K>>>;
|
||||
}
|
||||
|
||||
impl<'a, K: ReprC> MemoryBinder<'a, (), K> for Memory<'a, K> {
|
||||
impl<K: ReprC> MemoryBinder<(), K> for Memory<K> {
|
||||
fn create_and_bind(
|
||||
device: &'a Device,
|
||||
device: &Arc<Device>,
|
||||
memory_requirements: VkMemoryRequirements,
|
||||
memory_usage: VmaMemoryUsage,
|
||||
_: (),
|
||||
) -> Result<Memory<'a, K>> {
|
||||
) -> Result<Arc<Memory<K>>> {
|
||||
let allocation = device
|
||||
.allocator()
|
||||
.allocate()
|
||||
|
@ -113,23 +117,23 @@ impl<'a, K: ReprC> MemoryBinder<'a, (), K> for Memory<'a, K> {
|
|||
.set_memory_type_bits(memory_requirements.memoryTypeBits.into())
|
||||
.build(&memory_requirements)?;
|
||||
|
||||
Ok(Memory {
|
||||
device,
|
||||
Ok(Arc::new(Memory {
|
||||
device: device.clone(),
|
||||
|
||||
allocation,
|
||||
|
||||
data_type: PhantomData,
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: ReprC> MemoryBinder<'a, VkImage, K> for Memory<'a, K> {
|
||||
impl<K: ReprC> MemoryBinder<VkImage, K> for Memory<K> {
|
||||
fn create_and_bind(
|
||||
device: &'a Device,
|
||||
device: &Arc<Device>,
|
||||
memory_requirements: VkMemoryRequirements,
|
||||
memory_usage: VmaMemoryUsage,
|
||||
image: VkImage,
|
||||
) -> Result<Memory<'a, K>> {
|
||||
) -> Result<Arc<Memory<K>>> {
|
||||
let allocation = device
|
||||
.allocator()
|
||||
.allocate()
|
||||
|
@ -137,23 +141,23 @@ impl<'a, K: ReprC> MemoryBinder<'a, VkImage, K> for Memory<'a, K> {
|
|||
.set_memory_type_bits(memory_requirements.memoryTypeBits.into())
|
||||
.build(image)?;
|
||||
|
||||
Ok(Memory {
|
||||
device,
|
||||
Ok(Arc::new(Memory {
|
||||
device: device.clone(),
|
||||
|
||||
allocation,
|
||||
|
||||
data_type: PhantomData,
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: ReprC> MemoryBinder<'a, VkBuffer, K> for Memory<'a, K> {
|
||||
impl<K: ReprC> MemoryBinder<VkBuffer, K> for Memory<K> {
|
||||
fn create_and_bind(
|
||||
device: &'a Device,
|
||||
device: &Arc<Device>,
|
||||
memory_requirements: VkMemoryRequirements,
|
||||
memory_usage: VmaMemoryUsage,
|
||||
buffer: VkBuffer,
|
||||
) -> Result<Memory<'a, K>> {
|
||||
) -> Result<Arc<Memory<K>>> {
|
||||
let allocation = device
|
||||
.allocator()
|
||||
.allocate()
|
||||
|
@ -161,23 +165,23 @@ impl<'a, K: ReprC> MemoryBinder<'a, VkBuffer, K> for Memory<'a, K> {
|
|||
.set_memory_type_bits(memory_requirements.memoryTypeBits.into())
|
||||
.build(buffer)?;
|
||||
|
||||
Ok(Memory {
|
||||
device,
|
||||
Ok(Arc::new(Memory {
|
||||
device: device.clone(),
|
||||
|
||||
allocation,
|
||||
|
||||
data_type: PhantomData,
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ReprC> VulkanDevice for Memory<'a, T> {
|
||||
fn device(&self) -> &Device {
|
||||
impl<T: ReprC> VulkanDevice for Memory<T> {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ReprC + Clone> Memory<'a, T> {
|
||||
impl<T: ReprC + Clone> Memory<T> {
|
||||
pub fn map(&self, length: VkDeviceSize) -> Result<VkMappedMemory<'_, T>> {
|
||||
self.allocation.map(length)
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use std::ptr;
|
||||
use std::{ptr, sync::Arc};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PhysicalDevice {
|
||||
instance: Instance,
|
||||
instance: Arc<Instance>,
|
||||
physical_device: VkPhysicalDevice,
|
||||
properties: VkPhysicalDeviceProperties,
|
||||
features: VkPhysicalDeviceFeatures,
|
||||
|
@ -26,7 +26,7 @@ pub struct PhysicalDevice {
|
|||
}
|
||||
|
||||
impl PhysicalDevice {
|
||||
pub fn new(instance: Instance) -> Result<PhysicalDevice> {
|
||||
pub fn new(instance: Arc<Instance>) -> Result<Arc<PhysicalDevice>> {
|
||||
let physical_devices = instance.enumerate_physical_devices()?;
|
||||
|
||||
let (mut physical_device, mut device_properties) = PhysicalDevice::find_phys_dev(
|
||||
|
@ -57,19 +57,19 @@ impl PhysicalDevice {
|
|||
}
|
||||
|
||||
pub fn from_raw(
|
||||
instance: Instance,
|
||||
instance: Arc<Instance>,
|
||||
physical_device: VkPhysicalDevice,
|
||||
) -> Result<PhysicalDevice> {
|
||||
) -> Result<Arc<PhysicalDevice>> {
|
||||
let properties = instance.physical_device_properties(physical_device);
|
||||
|
||||
Self::internal_new(instance, physical_device, properties)
|
||||
}
|
||||
|
||||
fn internal_new(
|
||||
instance: Instance,
|
||||
instance: Arc<Instance>,
|
||||
physical_device: VkPhysicalDevice,
|
||||
properties: VkPhysicalDeviceProperties,
|
||||
) -> Result<PhysicalDevice> {
|
||||
) -> Result<Arc<PhysicalDevice>> {
|
||||
let device_features = instance.physical_device_features(physical_device);
|
||||
|
||||
let device_memory_properties = instance.physical_device_memory_properties(physical_device);
|
||||
|
@ -134,7 +134,7 @@ impl PhysicalDevice {
|
|||
patch
|
||||
);
|
||||
|
||||
Ok(PhysicalDevice {
|
||||
Ok(Arc::new(PhysicalDevice {
|
||||
instance,
|
||||
physical_device,
|
||||
properties,
|
||||
|
@ -151,13 +151,13 @@ impl PhysicalDevice {
|
|||
descriptor_indexing_features,
|
||||
|
||||
buffer_device_address_features,
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// getter
|
||||
impl PhysicalDevice {
|
||||
pub fn instance(&self) -> &Instance {
|
||||
pub fn instance(&self) -> &Arc<Instance> {
|
||||
&self.instance
|
||||
}
|
||||
|
||||
|
@ -305,7 +305,7 @@ impl_vk_handle!(PhysicalDevice, VkPhysicalDevice, physical_device);
|
|||
// private
|
||||
impl PhysicalDevice {
|
||||
fn find_phys_dev(
|
||||
instance: &Instance,
|
||||
instance: &Arc<Instance>,
|
||||
physical_devices: &[VkPhysicalDevice],
|
||||
device_type: VkPhysicalDeviceType,
|
||||
) -> (Option<VkPhysicalDevice>, Option<VkPhysicalDeviceProperties>) {
|
||||
|
@ -321,7 +321,7 @@ impl PhysicalDevice {
|
|||
}
|
||||
|
||||
fn query_extensions(
|
||||
instance: &Instance,
|
||||
instance: &Arc<Instance>,
|
||||
physical_device: VkPhysicalDevice,
|
||||
) -> Result<Vec<VkString>> {
|
||||
let extensions = instance.enumerate_device_extensions(physical_device)?;
|
||||
|
|
|
@ -2,6 +2,8 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum PipelineType {
|
||||
Graphics,
|
||||
|
@ -10,9 +12,9 @@ pub enum PipelineType {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Pipeline<'a> {
|
||||
device: &'a Device,
|
||||
pipeline_layout: PipelineLayout,
|
||||
pub struct Pipeline {
|
||||
device: Arc<Device>,
|
||||
pipeline_layout: Arc<PipelineLayout>,
|
||||
|
||||
pipeline_type: PipelineType,
|
||||
|
||||
|
@ -21,10 +23,10 @@ pub struct Pipeline<'a> {
|
|||
sub_pass: u32,
|
||||
}
|
||||
|
||||
impl<'a> Pipeline<'a> {
|
||||
impl Pipeline {
|
||||
pub(crate) fn new(
|
||||
device: &'a Device,
|
||||
pipeline_layout: PipelineLayout,
|
||||
device: Arc<Device>,
|
||||
pipeline_layout: Arc<PipelineLayout>,
|
||||
pipeline_type: PipelineType,
|
||||
pipeline: VkPipeline,
|
||||
) -> Self {
|
||||
|
@ -47,15 +49,15 @@ impl<'a> Pipeline<'a> {
|
|||
self.sub_pass
|
||||
}
|
||||
|
||||
pub fn new_graphics() -> GraphicsPipelineBuilder<'a> {
|
||||
pub fn new_graphics() -> GraphicsPipelineBuilder {
|
||||
GraphicsPipelineBuilder::default()
|
||||
}
|
||||
|
||||
pub fn new_compute() -> ComputePipelineBuilder<'a> {
|
||||
pub fn new_compute<'a>() -> ComputePipelineBuilder<'a> {
|
||||
ComputePipelineBuilder::default()
|
||||
}
|
||||
|
||||
pub fn new_ray_tracing() -> RayTracingPipelineBuilder<'a> {
|
||||
pub fn new_ray_tracing<'a>() -> RayTracingPipelineBuilder<'a> {
|
||||
RayTracingPipelineBuilder::default()
|
||||
}
|
||||
|
||||
|
@ -72,7 +74,7 @@ impl<'a> Pipeline<'a> {
|
|||
.get_ray_tracing_shader_group_handles(self.pipeline, 0, group_count, handle_size)
|
||||
}
|
||||
|
||||
pub fn pipeline_layout(&self) -> &PipelineLayout {
|
||||
pub fn pipeline_layout(&self) -> &Arc<PipelineLayout> {
|
||||
&self.pipeline_layout
|
||||
}
|
||||
|
||||
|
@ -81,15 +83,15 @@ impl<'a> Pipeline<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> VulkanDevice for Pipeline<'a> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for Pipeline {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle!(Pipeline<'a>, VkPipeline, pipeline);
|
||||
impl_vk_handle!(Pipeline, VkPipeline, pipeline);
|
||||
|
||||
impl<'a> Drop for Pipeline<'a> {
|
||||
impl Drop for Pipeline {
|
||||
fn drop(&mut self) {
|
||||
self.device.destroy_pipeline(self.pipeline);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ impl PipelineCache {
|
|||
}
|
||||
|
||||
impl VulkanDevice for PipelineCache {
|
||||
fn device(&self) -> &Device {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ impl PipelineLayout {
|
|||
}
|
||||
|
||||
impl VulkanDevice for PipelineLayout {
|
||||
fn device(&self) -> &Device {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,11 @@ use anyhow::Result;
|
|||
use crate::pipeline::PipelineType;
|
||||
use crate::prelude::*;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct ComputePipelineBuilder<'a> {
|
||||
shader_module: Option<&'a ShaderModule<'a, shader_type::Compute>>,
|
||||
pipeline_cache: Option<PipelineCache>,
|
||||
shader_module: Option<&'a Arc<ShaderModule<shader_type::Compute>>>,
|
||||
pipeline_cache: Option<&'a Arc<PipelineCache>>,
|
||||
flags: VkPipelineCreateFlagBits,
|
||||
}
|
||||
|
||||
|
@ -13,7 +15,7 @@ impl<'a> ComputePipelineBuilder<'a> {
|
|||
// TODO: add support for specialization constants
|
||||
pub fn set_shader_module(
|
||||
mut self,
|
||||
shader_module: &'a ShaderModule<'a, shader_type::Compute>,
|
||||
shader_module: &'a Arc<ShaderModule<shader_type::Compute>>,
|
||||
) -> Self {
|
||||
if cfg!(debug_assertions) {
|
||||
if self.shader_module.is_some() {
|
||||
|
@ -26,7 +28,7 @@ impl<'a> ComputePipelineBuilder<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn set_pipeline_cache(mut self, pipeline_cache: PipelineCache) -> Self {
|
||||
pub fn set_pipeline_cache(mut self, pipeline_cache: &'a Arc<PipelineCache>) -> Self {
|
||||
self.pipeline_cache = Some(pipeline_cache);
|
||||
|
||||
self
|
||||
|
@ -40,9 +42,9 @@ impl<'a> ComputePipelineBuilder<'a> {
|
|||
|
||||
pub fn build(
|
||||
self,
|
||||
device: &'a Device,
|
||||
pipeline_layout: PipelineLayout,
|
||||
) -> Result<Pipeline<'a>> {
|
||||
device: &Arc<Device>,
|
||||
pipeline_layout: &Arc<PipelineLayout>,
|
||||
) -> Result<Arc<Pipeline>> {
|
||||
let pipeline_ci = match self.shader_module {
|
||||
Some(module) => VkComputePipelineCreateInfo::new(
|
||||
self.flags,
|
||||
|
@ -61,12 +63,12 @@ impl<'a> ComputePipelineBuilder<'a> {
|
|||
&[pipeline_ci],
|
||||
)?[0];
|
||||
|
||||
Ok(Pipeline::new(
|
||||
device,
|
||||
pipeline_layout,
|
||||
Ok(Arc::new(Pipeline::new(
|
||||
device.clone(),
|
||||
pipeline_layout.clone(),
|
||||
PipelineType::Compute,
|
||||
pipeline,
|
||||
))
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,28 +5,28 @@ use anyhow::Result;
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct GraphicsPipelineBuilder<'a> {
|
||||
pub struct GraphicsPipelineBuilder {
|
||||
flags: VkPipelineCreateFlagBits,
|
||||
|
||||
pipeline_cache: Option<Arc<PipelineCache>>,
|
||||
|
||||
amd_rasterization_order: Option<VkPipelineRasterizationStateRasterizationOrderAMD>,
|
||||
|
||||
vertex_shader: Option<&'a ShaderModule<'a, shader_type::Vertex>>,
|
||||
vertex_shader: Option<Arc<ShaderModule<shader_type::Vertex>>>,
|
||||
vertex_binding_description: Vec<VkVertexInputBindingDescription>,
|
||||
vertex_attribute_description: Vec<VkVertexInputAttributeDescription>,
|
||||
|
||||
input_assembly: Option<VkPipelineInputAssemblyStateCreateInfo>,
|
||||
|
||||
tesselation_shader: Option<(
|
||||
&'a ShaderModule<'a, shader_type::TesselationControl>,
|
||||
&'a ShaderModule<'a, shader_type::TesselationEvaluation>,
|
||||
Arc<ShaderModule<shader_type::TesselationControl>>,
|
||||
Arc<ShaderModule<shader_type::TesselationEvaluation>>,
|
||||
)>,
|
||||
patch_control_points: u32,
|
||||
|
||||
geometry_shader: Option<&'a ShaderModule<'a, shader_type::Geometry>>,
|
||||
geometry_shader: Option<Arc<ShaderModule<shader_type::Geometry>>>,
|
||||
|
||||
fragment_shader: Option<&'a ShaderModule<'a, shader_type::Fragment>>,
|
||||
fragment_shader: Option<Arc<ShaderModule<shader_type::Fragment>>>,
|
||||
|
||||
viewports: Vec<VkViewport>,
|
||||
scissors: Vec<VkRect2D>,
|
||||
|
@ -41,11 +41,11 @@ pub struct GraphicsPipelineBuilder<'a> {
|
|||
dynamic_states: Vec<VkDynamicState>,
|
||||
}
|
||||
|
||||
impl<'a> GraphicsPipelineBuilder<'a> {
|
||||
impl GraphicsPipelineBuilder {
|
||||
// TODO: add support for specialization constants
|
||||
pub fn set_vertex_shader<T: VertexInputDescription>(
|
||||
mut self,
|
||||
shader: &'a ShaderModule<'a, shader_type::Vertex>,
|
||||
shader: Arc<ShaderModule<shader_type::Vertex>>,
|
||||
) -> Self {
|
||||
self.vertex_shader = Some(shader);
|
||||
self.vertex_binding_description = T::bindings();
|
||||
|
@ -57,8 +57,8 @@ impl<'a> GraphicsPipelineBuilder<'a> {
|
|||
// TODO: add support for specialization constants
|
||||
pub fn set_tesselation_shader(
|
||||
mut self,
|
||||
tesselation_control: &'a ShaderModule<'a, shader_type::TesselationControl>,
|
||||
tesselation_evaluation: &'a ShaderModule<'a, shader_type::TesselationEvaluation>,
|
||||
tesselation_control: Arc<ShaderModule<shader_type::TesselationControl>>,
|
||||
tesselation_evaluation: Arc<ShaderModule<shader_type::TesselationEvaluation>>,
|
||||
patch_control_points: u32,
|
||||
) -> Self {
|
||||
self.tesselation_shader = Some((tesselation_control, tesselation_evaluation));
|
||||
|
@ -68,20 +68,14 @@ impl<'a> GraphicsPipelineBuilder<'a> {
|
|||
}
|
||||
|
||||
// TODO: add support for specialization constants
|
||||
pub fn set_geometry_shader(
|
||||
mut self,
|
||||
shader: &'a ShaderModule<'a, shader_type::Geometry>,
|
||||
) -> Self {
|
||||
pub fn set_geometry_shader(mut self, shader: Arc<ShaderModule<shader_type::Geometry>>) -> Self {
|
||||
self.geometry_shader = Some(shader);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
// TODO: add support for specialization constants
|
||||
pub fn set_fragment_shader(
|
||||
mut self,
|
||||
shader: &'a ShaderModule<'a, shader_type::Fragment>,
|
||||
) -> Self {
|
||||
pub fn set_fragment_shader(mut self, shader: Arc<ShaderModule<shader_type::Fragment>>) -> Self {
|
||||
self.fragment_shader = Some(shader);
|
||||
|
||||
self
|
||||
|
@ -315,11 +309,11 @@ impl<'a> GraphicsPipelineBuilder<'a> {
|
|||
|
||||
pub fn build(
|
||||
mut self,
|
||||
device: &'a Device,
|
||||
pipeline_layout: PipelineLayout,
|
||||
render_pass: &RenderPass<'a>,
|
||||
device: Arc<Device>,
|
||||
pipeline_layout: &Arc<PipelineLayout>,
|
||||
render_pass: &Arc<RenderPass>,
|
||||
subpass: u32,
|
||||
) -> Result<Pipeline<'a>> {
|
||||
) -> Result<Arc<Pipeline>> {
|
||||
let mut rasterization = self.rasterization.expect("rasterization state is required");
|
||||
|
||||
if let Some(amd_rasterization_order) = &self.amd_rasterization_order {
|
||||
|
@ -399,14 +393,19 @@ impl<'a> GraphicsPipelineBuilder<'a> {
|
|||
&[pipeline_ci],
|
||||
)?[0];
|
||||
|
||||
Ok(
|
||||
Pipeline::new(device, pipeline_layout, PipelineType::Graphics, pipeline)
|
||||
.set_sub_pass(subpass),
|
||||
)
|
||||
Ok(Arc::new(
|
||||
Pipeline::new(
|
||||
device,
|
||||
pipeline_layout.clone(),
|
||||
PipelineType::Graphics,
|
||||
pipeline,
|
||||
)
|
||||
.set_sub_pass(subpass),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Default for GraphicsPipelineBuilder<'a> {
|
||||
impl Default for GraphicsPipelineBuilder {
|
||||
fn default() -> Self {
|
||||
GraphicsPipelineBuilder {
|
||||
flags: 0.into(),
|
||||
|
|
|
@ -8,14 +8,18 @@ use std::sync::Arc;
|
|||
use super::shader_binding_table::ShaderBindingTableBuilder;
|
||||
|
||||
pub struct Library<'a> {
|
||||
pipeline: &'a Pipeline<'a>,
|
||||
pipeline: &'a Arc<Pipeline>,
|
||||
|
||||
max_payload_size: u32,
|
||||
max_attribute_size: u32,
|
||||
}
|
||||
|
||||
impl<'a> Library<'a> {
|
||||
pub fn new(pipeline: &'a Pipeline<'a>, max_payload_size: u32, max_attribute_size: u32) -> Self {
|
||||
pub fn new(
|
||||
pipeline: &'a Arc<Pipeline>,
|
||||
max_payload_size: u32,
|
||||
max_attribute_size: u32,
|
||||
) -> Self {
|
||||
Library {
|
||||
pipeline,
|
||||
|
||||
|
@ -27,8 +31,8 @@ impl<'a> Library<'a> {
|
|||
|
||||
macro_rules! impl_from_shader_type {
|
||||
($struct: ident, $shader_type: ident) => {
|
||||
impl<'a> From<&'a ShaderModule<'a, shader_type::$shader_type>> for $struct<'a> {
|
||||
fn from(value: &'a ShaderModule<'a, shader_type::$shader_type>) -> Self {
|
||||
impl From<Arc<ShaderModule<shader_type::$shader_type>>> for $struct {
|
||||
fn from(value: Arc<ShaderModule<shader_type::$shader_type>>) -> Self {
|
||||
Self::$shader_type(value)
|
||||
}
|
||||
}
|
||||
|
@ -36,12 +40,12 @@ macro_rules! impl_from_shader_type {
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
enum RaytracingShader<'a> {
|
||||
RayGeneration(&'a ShaderModule<'a, shader_type::RayGeneration>),
|
||||
ClosestHit(&'a ShaderModule<'a, shader_type::ClosestHit>),
|
||||
Miss(&'a ShaderModule<'a, shader_type::Miss>),
|
||||
AnyHit(&'a ShaderModule<'a, shader_type::AnyHit>),
|
||||
Intersection(&'a ShaderModule<'a, shader_type::Intersection>),
|
||||
enum RaytracingShader {
|
||||
RayGeneration(Arc<ShaderModule<shader_type::RayGeneration>>),
|
||||
ClosestHit(Arc<ShaderModule<shader_type::ClosestHit>>),
|
||||
Miss(Arc<ShaderModule<shader_type::Miss>>),
|
||||
AnyHit(Arc<ShaderModule<shader_type::AnyHit>>),
|
||||
Intersection(Arc<ShaderModule<shader_type::Intersection>>),
|
||||
}
|
||||
|
||||
impl_from_shader_type!(RaytracingShader, RayGeneration);
|
||||
|
@ -50,8 +54,8 @@ impl_from_shader_type!(RaytracingShader, Miss);
|
|||
impl_from_shader_type!(RaytracingShader, AnyHit);
|
||||
impl_from_shader_type!(RaytracingShader, Intersection);
|
||||
|
||||
impl<'a> From<HitShader<'a>> for RaytracingShader<'a> {
|
||||
fn from(value: HitShader<'a>) -> Self {
|
||||
impl From<HitShader> for RaytracingShader {
|
||||
fn from(value: HitShader) -> Self {
|
||||
match value {
|
||||
HitShader::ClosestHit(s) => Self::ClosestHit(s),
|
||||
HitShader::AnyHit(s) => Self::AnyHit(s),
|
||||
|
@ -60,8 +64,8 @@ impl<'a> From<HitShader<'a>> for RaytracingShader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<OtherShader<'a>> for RaytracingShader<'a> {
|
||||
fn from(value: OtherShader<'a>) -> Self {
|
||||
impl From<OtherShader> for RaytracingShader {
|
||||
fn from(value: OtherShader) -> Self {
|
||||
match value {
|
||||
OtherShader::Miss(s) => Self::Miss(s),
|
||||
OtherShader::RayGeneration(s) => Self::RayGeneration(s),
|
||||
|
@ -70,10 +74,10 @@ impl<'a> From<OtherShader<'a>> for RaytracingShader<'a> {
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum HitShader<'a> {
|
||||
ClosestHit(&'a ShaderModule<'a, shader_type::ClosestHit>),
|
||||
AnyHit(&'a ShaderModule<'a, shader_type::AnyHit>),
|
||||
Intersection(&'a ShaderModule<'a, shader_type::Intersection>),
|
||||
pub enum HitShader {
|
||||
ClosestHit(Arc<ShaderModule<shader_type::ClosestHit>>),
|
||||
AnyHit(Arc<ShaderModule<shader_type::AnyHit>>),
|
||||
Intersection(Arc<ShaderModule<shader_type::Intersection>>),
|
||||
}
|
||||
|
||||
impl_from_shader_type!(HitShader, ClosestHit);
|
||||
|
@ -81,16 +85,16 @@ impl_from_shader_type!(HitShader, AnyHit);
|
|||
impl_from_shader_type!(HitShader, Intersection);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum OtherShader<'a> {
|
||||
RayGeneration(&'a ShaderModule<'a, shader_type::RayGeneration>),
|
||||
Miss(&'a ShaderModule<'a, shader_type::Miss>),
|
||||
pub enum OtherShader {
|
||||
RayGeneration(Arc<ShaderModule<shader_type::RayGeneration>>),
|
||||
Miss(Arc<ShaderModule<shader_type::Miss>>),
|
||||
}
|
||||
|
||||
impl_from_shader_type!(OtherShader, RayGeneration);
|
||||
impl_from_shader_type!(OtherShader, Miss);
|
||||
|
||||
pub struct RayTracingPipelineBuilder<'a> {
|
||||
shader_modules: Vec<(RaytracingShader<'a>, Option<SpecializationConstants>)>,
|
||||
shader_modules: Vec<(RaytracingShader, Option<SpecializationConstants>)>,
|
||||
|
||||
shader_groups: Vec<VkRayTracingShaderGroupCreateInfoKHR>,
|
||||
|
||||
|
@ -107,7 +111,7 @@ pub struct RayTracingPipelineBuilder<'a> {
|
|||
}
|
||||
|
||||
impl<'a> RayTracingPipelineBuilder<'a> {
|
||||
pub fn check_max_recursion(device: &'a Device, max_recursion: u32) -> u32 {
|
||||
pub fn check_max_recursion(device: &Arc<Device>, max_recursion: u32) -> u32 {
|
||||
max_recursion.min(
|
||||
device
|
||||
.physical_device()
|
||||
|
@ -142,7 +146,7 @@ impl<'a> RayTracingPipelineBuilder<'a> {
|
|||
|
||||
pub fn add_shader(
|
||||
mut self,
|
||||
shader_module: impl Into<OtherShader<'a>>,
|
||||
shader_module: impl Into<OtherShader>,
|
||||
data: Option<Vec<u8>>,
|
||||
specialization_constants: Option<SpecializationConstants>,
|
||||
) -> Self {
|
||||
|
@ -175,7 +179,7 @@ impl<'a> RayTracingPipelineBuilder<'a> {
|
|||
|
||||
pub fn add_hit_shaders(
|
||||
mut self,
|
||||
shader_modules: impl IntoIterator<Item = (HitShader<'a>, Option<SpecializationConstants>)>,
|
||||
shader_modules: impl IntoIterator<Item = (HitShader, Option<SpecializationConstants>)>,
|
||||
data: Option<Vec<u8>>,
|
||||
) -> Self {
|
||||
let mut group = VkRayTracingShaderGroupCreateInfoKHR::new(
|
||||
|
@ -239,9 +243,9 @@ impl<'a> RayTracingPipelineBuilder<'a> {
|
|||
|
||||
pub fn build(
|
||||
mut self,
|
||||
device: &'a Device,
|
||||
pipeline_layout: PipelineLayout,
|
||||
) -> Result<(Pipeline<'a>, ShaderBindingTable<'a>)> {
|
||||
device: Arc<Device>,
|
||||
pipeline_layout: &Arc<PipelineLayout>,
|
||||
) -> Result<(Arc<Pipeline>, ShaderBindingTable)> {
|
||||
let shader_stages: Vec<VkPipelineShaderStageCreateInfo> = self
|
||||
.shader_modules
|
||||
.iter()
|
||||
|
@ -263,7 +267,7 @@ impl<'a> RayTracingPipelineBuilder<'a> {
|
|||
.collect();
|
||||
|
||||
// check that we dont exceed the gpu's capabilities
|
||||
let max_recursion = Self::check_max_recursion(device, self.max_recursion);
|
||||
let max_recursion = Self::check_max_recursion(&device, self.max_recursion);
|
||||
|
||||
let pipeline = {
|
||||
let mut libraries = Vec::with_capacity(self.libraries.len());
|
||||
|
@ -302,7 +306,12 @@ impl<'a> RayTracingPipelineBuilder<'a> {
|
|||
)?[0]
|
||||
};
|
||||
|
||||
let pipeline = Pipeline::new(device, pipeline_layout, PipelineType::RayTracing, pipeline);
|
||||
let pipeline = Arc::new(Pipeline::new(
|
||||
device.clone(),
|
||||
pipeline_layout.clone(),
|
||||
PipelineType::RayTracing,
|
||||
pipeline,
|
||||
));
|
||||
|
||||
let sbt = self
|
||||
.shader_binding_table_builder
|
||||
|
|
|
@ -2,6 +2,8 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
struct ShaderBindingTableEntry {
|
||||
group_index: u32,
|
||||
inline_data: Vec<u8>,
|
||||
|
@ -12,8 +14,8 @@ pub(crate) struct ShaderBindingTableBuilder {
|
|||
hit_group_entries: Vec<ShaderBindingTableEntry>,
|
||||
}
|
||||
|
||||
pub struct ShaderBindingTable<'device> {
|
||||
_sbt_buffer: Buffer<'device, RawBuffer>,
|
||||
pub struct ShaderBindingTable {
|
||||
_sbt_buffer: Arc<Buffer<RawBuffer>>,
|
||||
|
||||
raygen_shader_binding_table: VkStridedDeviceAddressRegionKHR,
|
||||
miss_shader_binding_table: VkStridedDeviceAddressRegionKHR,
|
||||
|
@ -21,7 +23,7 @@ pub struct ShaderBindingTable<'device> {
|
|||
callable_shader_binding_table: VkStridedDeviceAddressRegionKHR,
|
||||
}
|
||||
|
||||
impl<'device> ShaderBindingTable<'device> {
|
||||
impl ShaderBindingTable {
|
||||
pub fn raygen_shader_binding_table(&self) -> &VkStridedDeviceAddressRegionKHR {
|
||||
&self.raygen_shader_binding_table
|
||||
}
|
||||
|
@ -39,7 +41,7 @@ impl<'device> ShaderBindingTable<'device> {
|
|||
}
|
||||
|
||||
fn create(
|
||||
sbt_buffer: Buffer<'device, RawBuffer>,
|
||||
sbt_buffer: Arc<Buffer<RawBuffer>>,
|
||||
ray_gen_entry_size: VkDeviceSize,
|
||||
ray_gen_entry_count: VkDeviceSize,
|
||||
miss_offset: VkDeviceSize,
|
||||
|
@ -126,11 +128,11 @@ impl ShaderBindingTableBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub(crate) fn build<'a>(
|
||||
pub(crate) fn build(
|
||||
&mut self,
|
||||
device: &'a Device,
|
||||
pipeline: &Pipeline<'a>,
|
||||
) -> Result<ShaderBindingTable<'a>> {
|
||||
device: &Arc<Device>,
|
||||
pipeline: &Arc<Pipeline>,
|
||||
) -> Result<ShaderBindingTable> {
|
||||
let ray_tracing_properties = device.physical_device().ray_tracing_properties();
|
||||
|
||||
let prog_id_size = ray_tracing_properties.shaderGroupHandleSize;
|
||||
|
@ -192,11 +194,6 @@ impl ShaderBindingTableBuilder {
|
|||
&shader_handle_storage,
|
||||
);
|
||||
|
||||
let b = sbt_data
|
||||
.into_iter()
|
||||
.map(|u| RawBuffer { d: u })
|
||||
.collect::<Vec<RawBuffer>>();
|
||||
|
||||
let sbt_buffer = Buffer::builder()
|
||||
.set_usage(
|
||||
VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR
|
||||
|
@ -204,8 +201,14 @@ impl ShaderBindingTableBuilder {
|
|||
| VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
|
||||
)
|
||||
.set_memory_usage(MemoryUsage::CpuToGpu)
|
||||
.set_data(b.as_slice())
|
||||
.build(device)?;
|
||||
.set_data(
|
||||
sbt_data
|
||||
.into_iter()
|
||||
.map(|u| RawBuffer { d: u })
|
||||
.collect::<Vec<RawBuffer>>()
|
||||
.as_slice(),
|
||||
)
|
||||
.build(device.clone())?;
|
||||
|
||||
Ok(ShaderBindingTable::create(
|
||||
sbt_buffer,
|
||||
|
|
|
@ -52,7 +52,7 @@ impl QueryPool {
|
|||
}
|
||||
|
||||
impl VulkanDevice for QueryPool {
|
||||
fn device(&self) -> &Device {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,11 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use std::{slice, sync::Mutex, time::Duration};
|
||||
use std::{
|
||||
slice,
|
||||
sync::{Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
pub struct QueueRequestInfo {
|
||||
pub queue_create_info: VkDeviceQueueCreateInfo,
|
||||
|
@ -11,17 +15,17 @@ pub struct QueueRequestInfo {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Queue<'a> {
|
||||
device: &'a Device,
|
||||
pub struct Queue {
|
||||
device: Arc<Device>,
|
||||
queue: VkQueue,
|
||||
family_index: u32,
|
||||
queue_index: u32,
|
||||
}
|
||||
|
||||
impl<'a> Queue<'a> {
|
||||
impl Queue {
|
||||
pub fn create_presentable_request_info(
|
||||
physical_device: &PhysicalDevice,
|
||||
surface: &Surface<'a>,
|
||||
physical_device: &Arc<PhysicalDevice>,
|
||||
surface: &Arc<Surface>,
|
||||
queue_type: impl Into<VkQueueFlagBits>,
|
||||
) -> Result<QueueRequestInfo> {
|
||||
let index =
|
||||
|
@ -37,7 +41,7 @@ impl<'a> Queue<'a> {
|
|||
}
|
||||
|
||||
pub fn create_non_presentable_request_info(
|
||||
physical_device: &PhysicalDevice,
|
||||
physical_device: &Arc<PhysicalDevice>,
|
||||
queue_type: impl Into<VkQueueFlagBits>,
|
||||
) -> Result<QueueRequestInfo> {
|
||||
let index = Self::find_non_presentable_queue_index(physical_device, queue_type.into())?;
|
||||
|
@ -52,17 +56,17 @@ impl<'a> Queue<'a> {
|
|||
}
|
||||
|
||||
pub fn new(
|
||||
device: &'a Device,
|
||||
device: Arc<Device>,
|
||||
queue: VkQueue,
|
||||
family_index: u32,
|
||||
queue_index: u32,
|
||||
) -> Mutex<Queue<'a>> {
|
||||
Mutex::new(Queue {
|
||||
) -> Arc<Mutex<Queue>> {
|
||||
Arc::new(Mutex::new(Queue {
|
||||
device,
|
||||
queue,
|
||||
family_index,
|
||||
queue_index,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn family_index(&self) -> u32 {
|
||||
|
@ -74,7 +78,7 @@ impl<'a> Queue<'a> {
|
|||
}
|
||||
|
||||
/// really expensiv call, since its locks the queue until it is idle
|
||||
pub fn submit(&self, fence: Option<&Fence<'a>>, submits: &[SubmitInfo]) -> Result<()> {
|
||||
pub fn submit(&self, fence: Option<&Arc<Fence>>, submits: &[SubmitInfo]) -> Result<()> {
|
||||
let submit_infos: Vec<VkSubmitInfo> = submits.iter().map(|s| s.as_vk_submit()).collect();
|
||||
|
||||
let fence = match fence {
|
||||
|
@ -89,15 +93,15 @@ impl<'a> Queue<'a> {
|
|||
pub fn minimal_submit(
|
||||
&self,
|
||||
time_out: Duration,
|
||||
command_buffers: &[&CommandBuffer<'a>],
|
||||
command_buffers: &[Arc<CommandBuffer>],
|
||||
) -> Result<()> {
|
||||
let mut submit = SubmitInfo::default();
|
||||
|
||||
for &command_buffer in command_buffers.iter() {
|
||||
for command_buffer in command_buffers.iter() {
|
||||
submit = submit.add_command_buffer(command_buffer);
|
||||
}
|
||||
|
||||
let fence = Fence::builder().build(self.device)?;
|
||||
let fence = Fence::builder().build(self.device.clone())?;
|
||||
|
||||
self.submit(Some(&fence), slice::from_ref(&submit))?;
|
||||
|
||||
|
@ -109,9 +113,9 @@ impl<'a> Queue<'a> {
|
|||
|
||||
pub fn present(
|
||||
&self,
|
||||
swapchains: &[&Swapchain<'a>],
|
||||
swapchains: &[&Arc<Swapchain>],
|
||||
image_indices: &[u32],
|
||||
wait_semaphores: &[&Semaphore<'a>],
|
||||
wait_semaphores: &[&Arc<Semaphore>],
|
||||
) -> Result<OutOfDate<()>> {
|
||||
let wait_semaphores: Vec<VkSemaphore> =
|
||||
wait_semaphores.iter().map(|sem| sem.vk_handle()).collect();
|
||||
|
@ -136,18 +140,18 @@ impl<'a> Queue<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> VulkanDevice for Queue<'a> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for Queue {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle!(Queue<'a>, VkQueue, queue);
|
||||
impl_vk_handle!(Queue, VkQueue, queue);
|
||||
|
||||
impl<'a> Queue<'a> {
|
||||
impl Queue {
|
||||
fn find_presentable_queue_index(
|
||||
physical_device: &PhysicalDevice,
|
||||
surface: &Surface<'a>,
|
||||
physical_device: &Arc<PhysicalDevice>,
|
||||
surface: &Arc<Surface>,
|
||||
flags: VkQueueFlagBits,
|
||||
) -> Result<u32> {
|
||||
let surface = surface.vk_handle();
|
||||
|
@ -175,7 +179,7 @@ impl<'a> Queue<'a> {
|
|||
}
|
||||
|
||||
fn find_non_presentable_queue_index(
|
||||
physical_device: &PhysicalDevice,
|
||||
physical_device: &Arc<PhysicalDevice>,
|
||||
flags: VkQueueFlagBits,
|
||||
) -> Result<u32> {
|
||||
let vk_physical_device = physical_device.vk_handle();
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
use crate::prelude::*;
|
||||
use anyhow::Result;
|
||||
use std::sync::atomic::{AtomicU32, AtomicUsize, Ordering::SeqCst};
|
||||
use std::sync::{
|
||||
atomic::{AtomicU32, AtomicUsize, Ordering::SeqCst},
|
||||
Arc,
|
||||
};
|
||||
|
||||
pub mod sub_pass;
|
||||
use sub_pass::{AttachmentInfo, AttachmentInfoUsage, SubPass};
|
||||
|
||||
pub struct RenderTargetBuilder<'device, 'image> {
|
||||
old_render_target: Option<RenderTarget<'device, 'image>>,
|
||||
sub_passes: Vec<SubPass<'device>>,
|
||||
pub struct RenderTargetBuilder<'a> {
|
||||
old_render_target: Option<&'a RenderTarget>,
|
||||
sub_passes: Vec<SubPass>,
|
||||
}
|
||||
|
||||
impl<'device, 'image> RenderTargetBuilder<'device, 'image> {
|
||||
pub fn add_sub_pass(mut self, sub_pass: SubPass<'device>) -> Self {
|
||||
impl<'a> RenderTargetBuilder<'a> {
|
||||
pub fn add_sub_pass(mut self, sub_pass: SubPass) -> Self {
|
||||
self.sub_passes.push(sub_pass);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn preserve_old_render_pass(
|
||||
mut self,
|
||||
render_target: RenderTarget<'device, 'image>,
|
||||
) -> Self {
|
||||
pub fn preserve_old_render_pass(mut self, render_target: &'a RenderTarget) -> Self {
|
||||
self.old_render_target = Some(render_target);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self, device: &'device Device) -> Result<RenderTarget<'device, 'image>> {
|
||||
pub fn build(self, device: &Arc<Device>) -> Result<RenderTarget> {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
// sub passes must not be empty
|
||||
|
@ -55,7 +55,7 @@ impl<'device, 'image> RenderTargetBuilder<'device, 'image> {
|
|||
));
|
||||
}
|
||||
|
||||
old_render_target.render_pass
|
||||
old_render_target.render_pass.clone()
|
||||
}
|
||||
None => {
|
||||
// gather attachment descriptions
|
||||
|
@ -164,7 +164,7 @@ impl<'device, 'image> RenderTargetBuilder<'device, 'image> {
|
|||
last_dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT.into();
|
||||
}
|
||||
|
||||
RenderPass::new(device, &descriptions, &attachments, &dependencies)?
|
||||
RenderPass::new(device.clone(), &descriptions, &attachments, &dependencies)?
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -185,10 +185,10 @@ impl<'device, 'image> RenderTargetBuilder<'device, 'image> {
|
|||
})
|
||||
}
|
||||
|
||||
fn create_framebuffers<'handle>(
|
||||
render_pass: &'handle RenderPass<'device>,
|
||||
sub_passes: &'handle [SubPass<'device>],
|
||||
) -> Result<Vec<Framebuffer<'device, 'image>>> {
|
||||
fn create_framebuffers(
|
||||
render_pass: &Arc<RenderPass>,
|
||||
sub_passes: &[SubPass],
|
||||
) -> Result<Vec<Arc<Framebuffer>>> {
|
||||
let extent = sub_passes[0].extent();
|
||||
|
||||
(0..Self::max_images(sub_passes))
|
||||
|
@ -205,13 +205,13 @@ impl<'device, 'image> RenderTargetBuilder<'device, 'image> {
|
|||
}
|
||||
}
|
||||
|
||||
framebuffer_builder.build(render_pass.device())
|
||||
framebuffer_builder.build(render_pass.device().clone())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn max_images(sub_passes: &[SubPass<'device>]) -> usize {
|
||||
fn max_images(sub_passes: &[SubPass]) -> usize {
|
||||
let mut max_images = 0;
|
||||
|
||||
for sub_pass in sub_passes.iter() {
|
||||
|
@ -221,10 +221,7 @@ impl<'device, 'image> RenderTargetBuilder<'device, 'image> {
|
|||
max_images
|
||||
}
|
||||
|
||||
fn verify_setups(
|
||||
old_sub_passes: &[SubPass<'device>],
|
||||
new_sub_passes: &[SubPass<'device>],
|
||||
) -> bool {
|
||||
fn verify_setups(old_sub_passes: &[SubPass], new_sub_passes: &[SubPass]) -> bool {
|
||||
if old_sub_passes.len() != new_sub_passes.len() {
|
||||
return false;
|
||||
}
|
||||
|
@ -239,9 +236,9 @@ impl<'device, 'image> RenderTargetBuilder<'device, 'image> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn map_attachment<'handle, F>(&'handle self, mut f: F)
|
||||
fn map_attachment<'b, F>(&'b self, mut f: F)
|
||||
where
|
||||
F: FnMut(&'handle AttachmentInfo<'device>) -> (),
|
||||
F: FnMut(&'b AttachmentInfo) -> (),
|
||||
{
|
||||
for sub_pass in self.sub_passes.iter() {
|
||||
for attachment in sub_pass.attachments().iter() {
|
||||
|
@ -263,36 +260,36 @@ struct SubPassAttachmentReferences {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RenderTarget<'device, 'image> {
|
||||
render_pass: RenderPass<'device>,
|
||||
framebuffers: Vec<Framebuffer<'device, 'image>>,
|
||||
pub struct RenderTarget {
|
||||
render_pass: Arc<RenderPass>,
|
||||
framebuffers: Vec<Arc<Framebuffer>>,
|
||||
clear_values: Vec<VkClearValue>,
|
||||
|
||||
extent: VkExtent2D,
|
||||
|
||||
sub_passes: Vec<SubPass<'device>>,
|
||||
sub_passes: Vec<SubPass>,
|
||||
|
||||
current_subpass: AtomicU32,
|
||||
framebuffer_index: AtomicUsize,
|
||||
}
|
||||
|
||||
impl<'device, 'image> RenderTarget<'device, 'image> {
|
||||
pub fn builder() -> RenderTargetBuilder<'device, 'image> {
|
||||
impl RenderTarget {
|
||||
pub fn builder<'a>() -> RenderTargetBuilder<'a> {
|
||||
RenderTargetBuilder {
|
||||
old_render_target: None,
|
||||
sub_passes: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_pass(&self) -> &RenderPass<'device> {
|
||||
pub fn render_pass(&self) -> &Arc<RenderPass> {
|
||||
&self.render_pass
|
||||
}
|
||||
|
||||
pub fn framebuffer(&self, index: usize) -> &Framebuffer<'device, 'image> {
|
||||
pub fn framebuffer(&self, index: usize) -> &Arc<Framebuffer> {
|
||||
&self.framebuffers[index]
|
||||
}
|
||||
|
||||
pub fn sub_pass(&self, index: usize) -> &SubPass<'device> {
|
||||
pub fn sub_pass(&self, index: usize) -> &SubPass {
|
||||
&self.sub_passes[index]
|
||||
}
|
||||
|
||||
|
@ -315,7 +312,7 @@ impl<'device, 'image> RenderTarget<'device, 'image> {
|
|||
|
||||
pub fn begin(
|
||||
&self,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'device, '_, '_>,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||
subpass_content: VkSubpassContents,
|
||||
framebuffer_index: usize,
|
||||
) {
|
||||
|
@ -337,14 +334,14 @@ impl<'device, 'image> RenderTarget<'device, 'image> {
|
|||
|
||||
pub fn next_subpass(
|
||||
&self,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'device, '_, '_>,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||
subpass_content: VkSubpassContents,
|
||||
) {
|
||||
buffer_recorder.next_subpass(subpass_content);
|
||||
self.current_subpass.fetch_add(1, SeqCst);
|
||||
}
|
||||
|
||||
pub fn end(&self, buffer_recorder: &mut CommandBufferRecorder<'device, '_, '_>) {
|
||||
pub fn end(&self, buffer_recorder: &mut CommandBufferRecorder<'_>) {
|
||||
debug_assert_eq!(
|
||||
self.current_subpass.load(SeqCst) as usize,
|
||||
self.sub_passes.len() - 1
|
||||
|
@ -356,14 +353,48 @@ impl<'device, 'image> RenderTarget<'device, 'image> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{create_vk_handles, prelude::*};
|
||||
use crate::prelude::*;
|
||||
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]
|
||||
fn test_render_target() {
|
||||
let (device, queue) = create_vk_handles().unwrap();
|
||||
|
||||
let target_images: Vec<Image<'_>> = (0..2)
|
||||
let target_images: Vec<Arc<Image>> = (0..2)
|
||||
.map(|_| {
|
||||
let image = Image::empty(
|
||||
1920,
|
||||
|
@ -378,26 +409,18 @@ mod test {
|
|||
|
||||
Ok(image)
|
||||
})
|
||||
.collect::<Result<Vec<Image<'_>>>>()
|
||||
.collect::<Result<Vec<Arc<Image>>>>()
|
||||
.unwrap();
|
||||
|
||||
let width = target_images[0].width();
|
||||
let height = target_images[0].height();
|
||||
|
||||
RenderTarget::builder()
|
||||
.add_sub_pass(
|
||||
SubPass::builder(width, height)
|
||||
.set_prepared_targets(
|
||||
target_images.iter().collect(),
|
||||
0,
|
||||
[0.0, 0.0, 0.0, 0.0],
|
||||
false,
|
||||
)
|
||||
SubPass::builder(target_images[0].width(), target_images[0].height())
|
||||
.set_prepared_targets(&target_images, 0, [0.0, 0.0, 0.0, 0.0], false)
|
||||
.build(&device)
|
||||
.unwrap(),
|
||||
)
|
||||
.add_sub_pass(
|
||||
SubPass::builder(width, height)
|
||||
SubPass::builder(target_images[0].width(), target_images[0].height())
|
||||
.add_target_info(CustomTarget {
|
||||
usage: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT.into(),
|
||||
format: VK_FORMAT_R8G8B8A8_UNORM,
|
||||
|
@ -415,22 +438,17 @@ mod test {
|
|||
false,
|
||||
true,
|
||||
))
|
||||
.use_queue(&queue)
|
||||
.use_queue(queue.clone())
|
||||
.build(&device)
|
||||
.unwrap(),
|
||||
)
|
||||
.add_sub_pass(
|
||||
SubPass::builder(width, height)
|
||||
SubPass::builder(target_images[0].width(), target_images[0].height())
|
||||
.set_input_attachment_info(InputAttachmentInfo {
|
||||
sub_pass_index: 1,
|
||||
input_indices: vec![1],
|
||||
})
|
||||
.set_prepared_targets(
|
||||
target_images.iter().collect(),
|
||||
0,
|
||||
[0.0, 0.0, 0.0, 0.0],
|
||||
false,
|
||||
)
|
||||
.set_prepared_targets(&target_images, 0, [0.0, 0.0, 0.0, 0.0], false)
|
||||
.build(&device)
|
||||
.unwrap(),
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::prelude::*;
|
||||
use anyhow::Result;
|
||||
use std::{ops::Index, sync::Mutex};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
pub enum ClearValue {
|
||||
Color([f32; 4]),
|
||||
|
@ -54,14 +54,14 @@ impl CustomTarget {
|
|||
}
|
||||
}
|
||||
|
||||
fn to_attachment_info<'a>(
|
||||
fn to_attachment_info(
|
||||
&self,
|
||||
device: &'a Device,
|
||||
queue: &'a Mutex<Queue<'a>>,
|
||||
device: &Arc<Device>,
|
||||
queue: &Arc<Mutex<Queue>>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
sample_count: VkSampleCountFlags,
|
||||
) -> Result<AttachmentInfo<'a>> {
|
||||
) -> Result<AttachmentInfo> {
|
||||
let clear_operation = SubPassBuilder::clear_op(if self.use_as_input {
|
||||
false
|
||||
} else {
|
||||
|
@ -159,7 +159,7 @@ impl CustomTarget {
|
|||
}
|
||||
|
||||
Ok(AttachmentInfo {
|
||||
images: vec![image].into(),
|
||||
images: vec![image],
|
||||
clear_value,
|
||||
layout,
|
||||
description,
|
||||
|
@ -168,25 +168,25 @@ impl CustomTarget {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum ResolveTarget<'a> {
|
||||
pub enum ResolveTarget {
|
||||
CustomTarget(CustomTarget),
|
||||
PreparedTargets((Vec<&'a Image<'a>>, bool)),
|
||||
PreparedTargets((Vec<Arc<Image>>, bool)),
|
||||
}
|
||||
|
||||
impl<'a> From<CustomTarget> for ResolveTarget<'a> {
|
||||
impl From<CustomTarget> for ResolveTarget {
|
||||
fn from(custom_target: CustomTarget) -> Self {
|
||||
Self::CustomTarget(custom_target)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<(Vec<&'a Image<'a>>, bool)> for ResolveTarget<'a> {
|
||||
fn from((prepared_targets, clear_on_load): (Vec<&'a Image<'a>>, bool)) -> Self {
|
||||
impl From<(Vec<Arc<Image>>, bool)> for ResolveTarget {
|
||||
fn from((prepared_targets, clear_on_load): (Vec<Arc<Image>>, bool)) -> Self {
|
||||
Self::PreparedTargets((prepared_targets, clear_on_load))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<(&'a Vec<&'a Image<'a>>, bool)> for ResolveTarget<'a> {
|
||||
fn from((prepared_targets, clear_on_load): (&'a Vec<&'a Image<'a>>, bool)) -> Self {
|
||||
impl<'a> From<(&'a Vec<Arc<Image>>, bool)> for ResolveTarget {
|
||||
fn from((prepared_targets, clear_on_load): (&'a Vec<Arc<Image>>, bool)) -> Self {
|
||||
Self::PreparedTargets((prepared_targets.clone(), clear_on_load))
|
||||
}
|
||||
}
|
||||
|
@ -197,31 +197,25 @@ pub struct InputAttachmentInfo {
|
|||
pub input_indices: Vec<usize>,
|
||||
}
|
||||
|
||||
pub struct SubPassBuilder<'a, 'b>
|
||||
where
|
||||
'b: 'a,
|
||||
{
|
||||
pub struct SubPassBuilder<'a> {
|
||||
width: u32,
|
||||
height: u32,
|
||||
sample_count: VkSampleCountFlags,
|
||||
|
||||
queue: Option<&'a Mutex<Queue<'a>>>,
|
||||
queue: Option<Arc<Mutex<Queue>>>,
|
||||
|
||||
target_infos: Vec<CustomTarget>,
|
||||
|
||||
input_info: Option<InputAttachmentInfo>,
|
||||
|
||||
// (images, index, clear_color, clear_on_load)
|
||||
prepared_targets: Option<(Vec<&'b Image<'a>>, usize, [f32; 4], bool)>,
|
||||
resolve_targets: Vec<ResolveTarget<'a>>,
|
||||
prepared_targets: Option<(&'a [Arc<Image>], usize, [f32; 4], bool)>,
|
||||
resolve_targets: Vec<ResolveTarget>,
|
||||
|
||||
output_usage: VkAccessFlagBits,
|
||||
}
|
||||
|
||||
impl<'a, 'b> SubPassBuilder<'a, 'b>
|
||||
where
|
||||
'b: 'a,
|
||||
{
|
||||
impl<'a> SubPassBuilder<'a> {
|
||||
pub fn set_sample_count(mut self, sample_count: VkSampleCountFlags) -> Self {
|
||||
self.sample_count = sample_count;
|
||||
|
||||
|
@ -248,7 +242,7 @@ where
|
|||
|
||||
pub fn set_prepared_targets(
|
||||
mut self,
|
||||
prepared_targets: Vec<&'b Image<'a>>,
|
||||
prepared_targets: &'a [Arc<Image>],
|
||||
target_index: usize,
|
||||
clear_color: impl Into<[f32; 4]>,
|
||||
clear_on_load: bool,
|
||||
|
@ -263,19 +257,19 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
pub fn add_resolve_targets(mut self, resolve_target: impl Into<ResolveTarget<'a>>) -> Self {
|
||||
pub fn add_resolve_targets(mut self, resolve_target: impl Into<ResolveTarget>) -> Self {
|
||||
self.resolve_targets.push(resolve_target.into());
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn use_queue(mut self, queue: &'a Mutex<Queue<'a>>) -> Self {
|
||||
pub fn use_queue(mut self, queue: Arc<Mutex<Queue>>) -> Self {
|
||||
self.queue = Some(queue);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self, device: &'a Device) -> Result<SubPass<'a>> {
|
||||
pub fn build(self, device: &Arc<Device>) -> Result<SubPass> {
|
||||
Ok(SubPass {
|
||||
extent: VkExtent2D {
|
||||
width: self.width,
|
||||
|
@ -290,7 +284,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn create_images(self, device: &'a Device) -> Result<Vec<AttachmentInfo<'a>>> {
|
||||
fn create_images(self, device: &Arc<Device>) -> Result<Vec<AttachmentInfo>> {
|
||||
// check for correct sample count
|
||||
let checked_sample_count = device.max_supported_sample_count(self.sample_count);
|
||||
|
||||
|
@ -320,6 +314,7 @@ where
|
|||
attachment_infos.insert(
|
||||
index,
|
||||
AttachmentInfo {
|
||||
images: prepared_images.iter().map(|image| image.clone()).collect(),
|
||||
clear_value: VkClearValue::color(VkClearColorValue::float32(clear_color)),
|
||||
layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
description: VkAttachmentDescription::new(
|
||||
|
@ -334,7 +329,6 @@ where
|
|||
prepared_images[0].image_layout(),
|
||||
),
|
||||
usage: AttachmentInfoUsage::Output,
|
||||
images: prepared_images.into(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -359,6 +353,7 @@ where
|
|||
}
|
||||
ResolveTarget::PreparedTargets((prepared_targets, clear_on_load)) => {
|
||||
attachment_infos.push(AttachmentInfo {
|
||||
images: prepared_targets.iter().map(|image| image.clone()).collect(),
|
||||
clear_value: VkClearValue::color(VkClearColorValue::float32([
|
||||
0.0, 0.0, 0.0, 1.0,
|
||||
])),
|
||||
|
@ -375,7 +370,6 @@ where
|
|||
prepared_targets[0].image_layout(),
|
||||
),
|
||||
usage: AttachmentInfoUsage::Resolve,
|
||||
images: prepared_targets.into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -411,61 +405,16 @@ pub enum AttachmentInfoUsage {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AttachmentInfoImages<'device> {
|
||||
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 struct AttachmentInfo {
|
||||
images: Vec<Arc<Image>>,
|
||||
pub(crate) clear_value: VkClearValue,
|
||||
pub(crate) layout: VkImageLayout,
|
||||
pub(crate) description: VkAttachmentDescription,
|
||||
pub(crate) usage: AttachmentInfoUsage,
|
||||
}
|
||||
|
||||
impl<'a> AttachmentInfo<'a> {
|
||||
pub fn image(&self, mut index: usize) -> &Image<'a> {
|
||||
impl AttachmentInfo {
|
||||
pub fn image(&self, mut index: usize) -> &Arc<Image> {
|
||||
debug_assert!(!self.images.is_empty());
|
||||
|
||||
if index >= self.images.len() {
|
||||
|
@ -484,17 +433,17 @@ impl<'a> AttachmentInfo<'a> {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SubPass<'device> {
|
||||
pub struct SubPass {
|
||||
extent: VkExtent2D,
|
||||
|
||||
input_info: Option<InputAttachmentInfo>,
|
||||
attachments: Vec<AttachmentInfo<'device>>,
|
||||
attachments: Vec<AttachmentInfo>,
|
||||
|
||||
output_usage: VkAccessFlagBits,
|
||||
}
|
||||
|
||||
impl<'device> SubPass<'device> {
|
||||
pub fn builder<'b>(width: u32, height: u32) -> SubPassBuilder<'device, 'b> {
|
||||
impl SubPass {
|
||||
pub fn builder<'a>(width: u32, height: u32) -> SubPassBuilder<'a> {
|
||||
SubPassBuilder {
|
||||
width,
|
||||
height,
|
||||
|
@ -526,7 +475,7 @@ impl<'device> SubPass<'device> {
|
|||
self.extent
|
||||
}
|
||||
|
||||
pub fn attachments(&self) -> &[AttachmentInfo<'device>] {
|
||||
pub fn attachments(&self) -> &[AttachmentInfo] {
|
||||
&self.attachments
|
||||
}
|
||||
|
||||
|
|
|
@ -2,19 +2,21 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RenderPass<'a> {
|
||||
device: &'a Device,
|
||||
pub struct RenderPass {
|
||||
device: Arc<Device>,
|
||||
render_pass: VkRenderPass,
|
||||
}
|
||||
|
||||
impl<'a> RenderPass<'a> {
|
||||
impl RenderPass {
|
||||
pub fn new(
|
||||
device: &'a Device,
|
||||
device: Arc<Device>,
|
||||
sub_passes: &[VkSubpassDescription],
|
||||
attachments: &[VkAttachmentDescription],
|
||||
dependencies: &[VkSubpassDependency],
|
||||
) -> Result<RenderPass<'a>> {
|
||||
) -> Result<Arc<RenderPass>> {
|
||||
let render_pass_ci = VkRenderPassCreateInfo::new(
|
||||
VK_RENDERPASS_CREATE_NULL_BIT,
|
||||
attachments,
|
||||
|
@ -24,22 +26,22 @@ impl<'a> RenderPass<'a> {
|
|||
|
||||
let render_pass = device.create_render_pass(&render_pass_ci)?;
|
||||
|
||||
Ok(RenderPass {
|
||||
Ok(Arc::new(RenderPass {
|
||||
device,
|
||||
render_pass,
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VulkanDevice for RenderPass<'a> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for RenderPass {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle!(RenderPass<'a>, VkRenderPass, render_pass);
|
||||
impl_vk_handle!(RenderPass, VkRenderPass, render_pass);
|
||||
|
||||
impl<'a> Drop for RenderPass<'a> {
|
||||
impl Drop for RenderPass {
|
||||
fn drop(&mut self) {
|
||||
self.device.destroy_render_pass(self.render_pass);
|
||||
}
|
||||
|
|
|
@ -2,32 +2,48 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Semaphore<'a> {
|
||||
device: &'a Device,
|
||||
pub struct Semaphore {
|
||||
device: Arc<Device>,
|
||||
semaphore: VkSemaphore,
|
||||
}
|
||||
|
||||
impl<'a> Semaphore<'a> {
|
||||
pub fn new(device: &'a Device) -> Result<Semaphore<'a>> {
|
||||
impl Semaphore {
|
||||
pub fn new(device: Arc<Device>) -> Result<Arc<Semaphore>> {
|
||||
let semaphore_ci = VkSemaphoreCreateInfo::new(VK_SEMAPHORE_CREATE_NULL_BIT);
|
||||
|
||||
let semaphore = device.create_semaphore(&semaphore_ci)?;
|
||||
|
||||
Ok(Semaphore { device, semaphore })
|
||||
Ok(Arc::new(Semaphore { device, semaphore }))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VulkanDevice for Semaphore<'a> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for Semaphore {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl_vk_handle!(Semaphore<'a>, VkSemaphore, semaphore);
|
||||
impl_vk_handle!(Semaphore, VkSemaphore, semaphore);
|
||||
|
||||
impl<'a> Drop for Semaphore<'a> {
|
||||
impl Drop for Semaphore {
|
||||
fn drop(&mut self) {
|
||||
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) };
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ use anyhow::{Context, Result};
|
|||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub mod shader_type {
|
||||
mod sealed {
|
||||
|
@ -76,7 +77,7 @@ pub trait PipelineStageInfo {
|
|||
|
||||
macro_rules! impl_pipeline_stage_info {
|
||||
($func:ident, $type:ident) => {
|
||||
impl<'a> PipelineStageInfo for ShaderModule<'a, $type> {
|
||||
impl PipelineStageInfo for ShaderModule<$type> {
|
||||
fn pipeline_stage_info(&self) -> VkPipelineShaderStageCreateInfo {
|
||||
VkPipelineShaderStageCreateInfo::$func(self.shader_module)
|
||||
}
|
||||
|
@ -85,30 +86,33 @@ macro_rules! impl_pipeline_stage_info {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ShaderModule<'a, ShaderModuleType: ShaderType> {
|
||||
pub struct ShaderModule<ShaderModuleType: ShaderType> {
|
||||
t: PhantomData<ShaderModuleType>,
|
||||
device: &'a Device,
|
||||
device: Arc<Device>,
|
||||
shader_module: VkShaderModule,
|
||||
}
|
||||
|
||||
impl<'a, ShaderModuleType: ShaderType> ShaderModule<'a, ShaderModuleType> {
|
||||
pub fn new(device: &'a Device, path: &str) -> Result<Self> {
|
||||
impl<ShaderModuleType: ShaderType> ShaderModule<ShaderModuleType> {
|
||||
pub fn new(device: Arc<Device>, path: &str) -> Result<Arc<ShaderModule<ShaderModuleType>>> {
|
||||
let code = Self::shader_code(path)?;
|
||||
|
||||
Self::from_slice(device, code.as_slice())
|
||||
}
|
||||
|
||||
pub fn from_slice(device: &'a Device, code: &[u8]) -> Result<Self> {
|
||||
pub fn from_slice(
|
||||
device: Arc<Device>,
|
||||
code: &[u8],
|
||||
) -> Result<Arc<ShaderModule<ShaderModuleType>>> {
|
||||
let shader_module_ci =
|
||||
VkShaderModuleCreateInfo::new(VK_SHADER_MODULE_CREATE_NULL_BIT, code);
|
||||
|
||||
let shader_module = device.create_shader_module(&shader_module_ci)?;
|
||||
|
||||
Ok(ShaderModule {
|
||||
Ok(Arc::new(ShaderModule {
|
||||
t: PhantomData,
|
||||
device,
|
||||
shader_module,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
fn shader_code(path: &str) -> Result<Vec<u8>> {
|
||||
|
@ -139,29 +143,15 @@ impl_pipeline_stage_info!(closest_hit, ClosestHit);
|
|||
impl_pipeline_stage_info!(ray_generation, RayGeneration);
|
||||
impl_pipeline_stage_info!(miss, Miss);
|
||||
|
||||
impl<'a, ShaderModuleType: ShaderType> VulkanDevice for ShaderModule<'a, ShaderModuleType> {
|
||||
fn device(&self) -> &Device {
|
||||
impl<ShaderModuleType: ShaderType> VulkanDevice for ShaderModule<ShaderModuleType> {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, ShaderModuleType: ShaderType> VkHandle<VkShaderModule>
|
||||
for ShaderModule<'a, ShaderModuleType>
|
||||
{
|
||||
fn vk_handle(&self) -> VkShaderModule {
|
||||
self.shader_module
|
||||
}
|
||||
}
|
||||
impl_vk_handle!(ShaderModule<ShaderModuleType: ShaderType,>, VkShaderModule, shader_module);
|
||||
|
||||
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> {
|
||||
impl<ShaderModuleType: ShaderType> Drop for ShaderModule<ShaderModuleType> {
|
||||
fn drop(&mut self) {
|
||||
self.device.destroy_shader_module(self.shader_module);
|
||||
}
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
use crate::prelude::*;
|
||||
use anyhow::Result;
|
||||
|
||||
use std::sync::Mutex;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct SingleSubmit<'device, 'a, F, T>
|
||||
pub struct SingleSubmit<'a, F, T>
|
||||
where
|
||||
F: FnOnce(&mut CommandBufferRecorder<'device, '_, '_>) -> Result<T>,
|
||||
F: FnOnce(&mut CommandBufferRecorder<'_>) -> Result<T>,
|
||||
{
|
||||
command_buffer: &'a mut CommandBuffer<'device>,
|
||||
queue: &'a Mutex<Queue<'device>>,
|
||||
command_buffer: &'a Arc<CommandBuffer>,
|
||||
queue: &'a Arc<Mutex<Queue>>,
|
||||
f: F,
|
||||
|
||||
timeout: Option<Duration>,
|
||||
}
|
||||
|
||||
impl<'device, 'a, F, T> SingleSubmit<'device, 'a, F, T>
|
||||
impl<'a, F, T> SingleSubmit<'a, F, T>
|
||||
where
|
||||
F: FnOnce(&mut CommandBufferRecorder<'device, '_, '_>) -> Result<T>,
|
||||
F: FnOnce(&mut CommandBufferRecorder<'_>) -> Result<T>,
|
||||
{
|
||||
pub fn builder(
|
||||
command_buffer: &'a mut CommandBuffer<'device>,
|
||||
queue: &'a Mutex<Queue<'device>>,
|
||||
command_buffer: &'a Arc<CommandBuffer>,
|
||||
queue: &'a Arc<Mutex<Queue>>,
|
||||
f: F,
|
||||
) -> Self {
|
||||
SingleSubmit {
|
||||
|
@ -48,12 +48,12 @@ where
|
|||
(self.f)(&mut buffer_recorder)?
|
||||
};
|
||||
|
||||
let submit = SubmitInfo::default().add_command_buffer(&*self.command_buffer);
|
||||
let submit = SubmitInfo::default().add_command_buffer(self.command_buffer);
|
||||
let queue_lock = self.queue.lock().unwrap();
|
||||
|
||||
match self.timeout {
|
||||
Some(timeout) => {
|
||||
let fence = Fence::builder().build(self.command_buffer.device())?;
|
||||
let fence = Fence::builder().build(self.command_buffer.device().clone())?;
|
||||
|
||||
queue_lock.submit(Some(&fence), &[submit])?;
|
||||
|
||||
|
|
|
@ -2,20 +2,25 @@ use crate::prelude::*;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
const UNORM_FORMATS: [VkFormat; 2] = [VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM];
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Surface<'a> {
|
||||
instance: &'a Instance,
|
||||
pub struct Surface {
|
||||
instance: Arc<Instance>,
|
||||
surface: VkSurfaceKHR,
|
||||
}
|
||||
|
||||
impl<'a> Surface<'a> {
|
||||
pub fn from_vk_surface(surface: VkSurfaceKHR, instance: &'a Instance) -> Self {
|
||||
Self { instance, surface }
|
||||
impl Surface {
|
||||
pub fn from_vk_surface(surface: VkSurfaceKHR, instance: &Arc<Instance>) -> Arc<Surface> {
|
||||
Arc::new(Surface {
|
||||
instance: instance.clone(),
|
||||
surface,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn capabilities(&self, device: &'a Device) -> Result<VkSurfaceCapabilitiesKHR> {
|
||||
pub fn capabilities(&self, device: &Arc<Device>) -> Result<VkSurfaceCapabilitiesKHR> {
|
||||
self.instance.physical_device_surface_capabilities(
|
||||
device.physical_device().vk_handle(),
|
||||
self.surface,
|
||||
|
@ -24,7 +29,7 @@ impl<'a> Surface<'a> {
|
|||
|
||||
pub fn format_colorspace(
|
||||
&self,
|
||||
device: &'a Device,
|
||||
device: &Arc<Device>,
|
||||
prefered_format: VkFormat,
|
||||
) -> Result<(VkFormat, VkColorSpaceKHR)> {
|
||||
let surface_formats = self
|
||||
|
@ -56,25 +61,15 @@ impl<'a> Surface<'a> {
|
|||
Ok((surface_formats[0].format, surface_formats[0].colorSpace))
|
||||
}
|
||||
|
||||
pub fn present_modes(&self, device: &'a Device) -> Result<Vec<VkPresentModeKHR>> {
|
||||
pub fn present_modes(&self, device: &Arc<Device>) -> Result<Vec<VkPresentModeKHR>> {
|
||||
self.instance
|
||||
.physical_device_present_modes(device.physical_device().vk_handle(), self.surface)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VkHandle<VkSurfaceKHR> for Surface<'a> {
|
||||
fn vk_handle(&self) -> VkSurfaceKHR {
|
||||
self.surface
|
||||
}
|
||||
}
|
||||
impl_vk_handle!(Surface, VkSurfaceKHR, surface);
|
||||
|
||||
impl<'a> VkHandle<VkSurfaceKHR> for &'a Surface<'a> {
|
||||
fn vk_handle(&self) -> VkSurfaceKHR {
|
||||
self.surface
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for Surface<'a> {
|
||||
impl Drop for Surface {
|
||||
fn drop(&mut self) {
|
||||
self.instance.destroy_surface(self.surface)
|
||||
}
|
||||
|
|
|
@ -3,55 +3,62 @@ use crate::prelude::*;
|
|||
use anyhow::Result;
|
||||
|
||||
use std::cmp;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::{
|
||||
atomic::{AtomicU32, Ordering::SeqCst},
|
||||
Arc, Mutex,
|
||||
};
|
||||
|
||||
pub enum NextImageSynchronization<'a> {
|
||||
Semaphore(&'a Semaphore<'a>),
|
||||
Fence(&'a Fence<'a>),
|
||||
Semaphore(&'a Arc<Semaphore>),
|
||||
Fence(&'a Arc<Fence>),
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Semaphore<'a>> for NextImageSynchronization<'a> {
|
||||
fn from(value: &'a Semaphore<'a>) -> Self {
|
||||
impl<'a> From<&'a Arc<Semaphore>> for NextImageSynchronization<'a> {
|
||||
fn from(value: &'a Arc<Semaphore>) -> Self {
|
||||
Self::Semaphore(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Fence<'a>> for NextImageSynchronization<'a> {
|
||||
fn from(value: &'a Fence<'a>) -> Self {
|
||||
impl<'a> From<&'a Arc<Fence>> for NextImageSynchronization<'a> {
|
||||
fn from(value: &'a Arc<Fence>) -> Self {
|
||||
Self::Fence(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Swapchain<'a> {
|
||||
width: u32,
|
||||
height: u32,
|
||||
index: u32,
|
||||
pub struct Swapchain {
|
||||
width: AtomicU32,
|
||||
height: AtomicU32,
|
||||
index: AtomicU32,
|
||||
|
||||
device: &'a Device,
|
||||
surface: Surface<'a>,
|
||||
device: Arc<Device>,
|
||||
surface: Arc<Surface>,
|
||||
|
||||
create_info: VkSwapchainCreateInfoKHR,
|
||||
swapchain: VkSwapchainKHR,
|
||||
create_info: Mutex<VkSwapchainCreateInfoKHR>,
|
||||
swapchain: Mutex<VkSwapchainKHR>,
|
||||
usage: VkImageUsageFlagBits,
|
||||
|
||||
raw: bool,
|
||||
}
|
||||
|
||||
impl<'a> Swapchain<'a> {
|
||||
impl Swapchain {
|
||||
pub fn new(
|
||||
device: &'a Device,
|
||||
surface: Surface<'a>,
|
||||
device: Arc<Device>,
|
||||
surface: &Arc<Surface>,
|
||||
vsync: bool,
|
||||
image_count: u32,
|
||||
image_usage: impl Into<VkImageUsageFlagBits>,
|
||||
prefered_format: VkFormat,
|
||||
array_layers: u32,
|
||||
) -> Result<Swapchain<'a>> {
|
||||
window_size: (u32, u32),
|
||||
) -> Result<Arc<Swapchain>> {
|
||||
let surface_caps = surface.capabilities(&device)?;
|
||||
|
||||
let extent = if surface_caps.currentExtent.width == u32::max_value() {
|
||||
return Err(anyhow::Error::msg("Surface has no extent"));
|
||||
VkExtent2D {
|
||||
width: window_size.0,
|
||||
height: window_size.1,
|
||||
}
|
||||
} else {
|
||||
VkExtent2D {
|
||||
width: surface_caps.currentExtent.width,
|
||||
|
@ -109,54 +116,57 @@ impl<'a> Swapchain<'a> {
|
|||
|
||||
let swapchain = device.create_swapchain(&swapchain_ci)?;
|
||||
|
||||
Ok(Swapchain {
|
||||
width: extent.width,
|
||||
height: extent.height,
|
||||
Ok(Arc::new(Swapchain {
|
||||
width: AtomicU32::new(extent.width),
|
||||
height: AtomicU32::new(extent.height),
|
||||
usage: swapchain_ci.imageUsage,
|
||||
index: 0,
|
||||
index: AtomicU32::new(0),
|
||||
|
||||
device,
|
||||
surface,
|
||||
surface: surface.clone(),
|
||||
|
||||
create_info: swapchain_ci,
|
||||
create_info: Mutex::new(swapchain_ci),
|
||||
|
||||
swapchain,
|
||||
swapchain: Mutex::new(swapchain),
|
||||
|
||||
raw: false,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn from_ci(device: &'a Device, swapchain_ci: &VkSwapchainCreateInfoKHR) -> Result<Self> {
|
||||
Ok(Swapchain {
|
||||
width: swapchain_ci.imageExtent.width,
|
||||
height: swapchain_ci.imageExtent.height,
|
||||
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: 0,
|
||||
index: AtomicU32::new(0),
|
||||
|
||||
surface: Surface::from_vk_surface(
|
||||
swapchain_ci.surface,
|
||||
device.physical_device().instance(),
|
||||
),
|
||||
|
||||
create_info: swapchain_ci.clone(),
|
||||
create_info: Mutex::new(swapchain_ci.clone()),
|
||||
|
||||
swapchain: device.create_swapchain(swapchain_ci)?,
|
||||
swapchain: Mutex::new(device.create_swapchain(swapchain_ci)?),
|
||||
device,
|
||||
|
||||
raw: false,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn from_raw(
|
||||
device: &'a Device,
|
||||
device: Arc<Device>,
|
||||
swapchain_ci: &VkSwapchainCreateInfoKHR,
|
||||
swapchain: VkSwapchainKHR,
|
||||
) -> Self {
|
||||
Swapchain {
|
||||
width: swapchain_ci.imageExtent.width,
|
||||
height: swapchain_ci.imageExtent.height,
|
||||
) -> Arc<Self> {
|
||||
Arc::new(Swapchain {
|
||||
width: AtomicU32::new(swapchain_ci.imageExtent.width),
|
||||
height: AtomicU32::new(swapchain_ci.imageExtent.height),
|
||||
usage: swapchain_ci.imageUsage,
|
||||
index: 0,
|
||||
index: AtomicU32::new(0),
|
||||
|
||||
surface: Surface::from_vk_surface(
|
||||
swapchain_ci.surface,
|
||||
|
@ -164,23 +174,27 @@ impl<'a> Swapchain<'a> {
|
|||
),
|
||||
device,
|
||||
|
||||
create_info: swapchain_ci.clone(),
|
||||
swapchain,
|
||||
create_info: Mutex::new(swapchain_ci.clone()),
|
||||
|
||||
swapchain: Mutex::new(swapchain),
|
||||
|
||||
raw: true,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn recreate(&mut self) -> Result<()> {
|
||||
pub fn recreate(&self, window_size: (u32, u32)) -> Result<()> {
|
||||
// wait for the device to get idle
|
||||
self.device.wait_idle()?;
|
||||
|
||||
let surface_caps = self.surface.capabilities(self.device)?;
|
||||
let surface_caps = self.surface.capabilities(&self.device)?;
|
||||
|
||||
let extent = if surface_caps.currentExtent.width == u32::max_value()
|
||||
|| surface_caps.currentExtent.height == u32::max_value()
|
||||
{
|
||||
return Err(anyhow::Error::msg("Surface has no extent"));
|
||||
VkExtent2D {
|
||||
width: window_size.0,
|
||||
height: window_size.1,
|
||||
}
|
||||
} else if surface_caps.currentExtent.width == 0 || surface_caps.currentExtent.height == 0 {
|
||||
// don't recreate swapchain
|
||||
return Ok(());
|
||||
|
@ -191,9 +205,9 @@ impl<'a> Swapchain<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
let mut swapchain_ci = self.create_info.clone();
|
||||
let mut swapchain_ci = self.create_info.lock().unwrap();
|
||||
swapchain_ci.imageExtent = extent;
|
||||
swapchain_ci.set_old_swapchain(self.swapchain);
|
||||
swapchain_ci.set_old_swapchain(*self.swapchain.lock().unwrap());
|
||||
|
||||
let swapchain = self.device.create_swapchain(&swapchain_ci)?;
|
||||
|
||||
|
@ -201,24 +215,24 @@ impl<'a> Swapchain<'a> {
|
|||
self.destroy();
|
||||
|
||||
// replace swapchain
|
||||
self.swapchain = swapchain;
|
||||
*self.swapchain.lock().unwrap() = swapchain;
|
||||
|
||||
// set new surface size
|
||||
self.width = extent.width;
|
||||
self.height = extent.height;
|
||||
self.width.store(extent.width, SeqCst);
|
||||
self.height.store(extent.height, SeqCst);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn acquire_next_image<'b>(
|
||||
&mut self,
|
||||
pub fn acquire_next_image<'a>(
|
||||
&self,
|
||||
time_out: u64,
|
||||
synchro: impl Into<NextImageSynchronization<'b>>,
|
||||
synchro: impl Into<NextImageSynchronization<'a>>,
|
||||
) -> Result<OutOfDate<u32>> {
|
||||
let synchro = synchro.into();
|
||||
|
||||
let res = self.device.acquire_next_image(
|
||||
self.swapchain,
|
||||
*self.swapchain.lock().unwrap(),
|
||||
time_out,
|
||||
match synchro {
|
||||
NextImageSynchronization::Semaphore(semaphore) => Some(semaphore.vk_handle()),
|
||||
|
@ -232,7 +246,7 @@ impl<'a> Swapchain<'a> {
|
|||
|
||||
if let Ok(r) = &res {
|
||||
if let OutOfDate::Ok(i) = r {
|
||||
self.index = *i;
|
||||
self.index.store(*i, SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,24 +255,25 @@ impl<'a> Swapchain<'a> {
|
|||
|
||||
/// set current
|
||||
/// only use when externally acquired next index !!!
|
||||
pub unsafe fn set_image_index(&mut self, index: u32) {
|
||||
self.index = index;
|
||||
pub unsafe fn set_image_index(&self, index: u32) {
|
||||
self.index.store(index, SeqCst);
|
||||
}
|
||||
|
||||
pub fn current_index(&self) -> u32 {
|
||||
self.index
|
||||
self.index.load(SeqCst)
|
||||
}
|
||||
|
||||
pub fn vk_images(&self) -> Result<Vec<VkImage>> {
|
||||
self.device.swapchain_images(self.swapchain)
|
||||
self.device
|
||||
.swapchain_images(*self.swapchain.lock().unwrap())
|
||||
}
|
||||
|
||||
pub fn wrap_images(
|
||||
&self,
|
||||
images: &[VkImage],
|
||||
queue: &'a Mutex<Queue<'a>>,
|
||||
queue: &Arc<Mutex<Queue>>,
|
||||
assume_layout: bool,
|
||||
) -> Result<Vec<Image<'a>>> {
|
||||
) -> Result<Vec<Arc<Image>>> {
|
||||
let format = self.format();
|
||||
let tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
|
||||
|
@ -282,7 +297,7 @@ impl<'a> Swapchain<'a> {
|
|||
self.usage,
|
||||
assume_layout,
|
||||
)
|
||||
.attach_sampler(Sampler::nearest_sampler().build(self.device)?)
|
||||
.attach_sampler(Sampler::nearest_sampler().build(&self.device)?)
|
||||
.build(&self.device, queue)?,
|
||||
);
|
||||
}
|
||||
|
@ -291,42 +306,55 @@ impl<'a> Swapchain<'a> {
|
|||
}
|
||||
|
||||
pub fn width(&self) -> u32 {
|
||||
self.width
|
||||
self.width.load(SeqCst)
|
||||
}
|
||||
|
||||
pub fn height(&self) -> u32 {
|
||||
self.height
|
||||
self.height.load(SeqCst)
|
||||
}
|
||||
|
||||
pub fn format(&self) -> VkFormat {
|
||||
self.create_info.imageFormat
|
||||
self.create_info.lock().unwrap().imageFormat
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn destroy(&self) {
|
||||
self.device.destroy_swapchain(self.swapchain)
|
||||
self.device
|
||||
.destroy_swapchain(*self.swapchain.lock().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VulkanDevice for Swapchain<'a> {
|
||||
fn device(&self) -> &Device {
|
||||
impl VulkanDevice for Swapchain {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VkHandle<VkSwapchainKHR> for Swapchain<'a> {
|
||||
impl VkHandle<VkSwapchainKHR> for Swapchain {
|
||||
fn vk_handle(&self) -> VkSwapchainKHR {
|
||||
self.swapchain
|
||||
*self.swapchain.lock().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VkHandle<VkSwapchainKHR> for &'a Swapchain<'a> {
|
||||
impl<'a> VkHandle<VkSwapchainKHR> for &'a Swapchain {
|
||||
fn vk_handle(&self) -> VkSwapchainKHR {
|
||||
self.swapchain
|
||||
*self.swapchain.lock().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for Swapchain<'a> {
|
||||
impl VkHandle<VkSwapchainKHR> for Arc<Swapchain> {
|
||||
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) {
|
||||
if !self.raw {
|
||||
self.destroy();
|
||||
|
|
|
@ -6,7 +6,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
library_loader = { path = "../library_loader" }
|
||||
paste = "1.0.14"
|
||||
paste = "1.0.15"
|
||||
shared_library = "0.1.9"
|
||||
anyhow = { version = "1.0.81", features = ["backtrace"] }
|
||||
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
||||
utilities = { git = "https://gavania.de/hodasemi/utilities.git" }
|
||||
|
|
|
@ -12,11 +12,130 @@ pub enum VkDynamicState {
|
|||
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6,
|
||||
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7,
|
||||
VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8,
|
||||
VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1_000_087_000,
|
||||
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1_000_099_000,
|
||||
VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1_000_143_000,
|
||||
VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1_000_164_004,
|
||||
VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1_000_164_006,
|
||||
VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1_000_205_001,
|
||||
VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR = 1_000_347_000,
|
||||
// Provided by VK_VERSION_1_3
|
||||
VK_DYNAMIC_STATE_CULL_MODE = 1000267000,
|
||||
// Provided by VK_VERSION_1_3
|
||||
VK_DYNAMIC_STATE_FRONT_FACE = 1000267001,
|
||||
// Provided by VK_VERSION_1_3
|
||||
VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = 1000267002,
|
||||
// Provided by VK_VERSION_1_3
|
||||
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,
|
||||
}
|
||||
|
|
|
@ -399,6 +399,11 @@ load_function_ptrs!(DeviceFunctions, {
|
|||
pScissors: *const VkRect2D
|
||||
) -> (),
|
||||
|
||||
vkCmdSetCullMode(
|
||||
commandBuffer: VkCommandBuffer,
|
||||
cullMode: VkCullModeFlags
|
||||
) -> (),
|
||||
|
||||
vkCmdSetLineWidth(commandBuffer: VkCommandBuffer, lineWidth: f32) -> (),
|
||||
|
||||
vkCmdSetDepthBias(
|
||||
|
|
Loading…
Reference in a new issue