use super::device::DeviceInner;
use super::{Device, Error, Result, check};
use crate::raw::bindings::*;
use std::sync::Arc;
pub struct Fence {
pub(crate) handle: VkFence,
pub(crate) device: Arc<DeviceInner>,
}
impl Fence {
pub fn new(device: &Device) -> Result<Self> {
let create = device
.inner
.dispatch
.vkCreateFence
.ok_or(Error::MissingFunction("vkCreateFence"))?;
let info = VkFenceCreateInfo {
sType: VkStructureType::STRUCTURE_TYPE_FENCE_CREATE_INFO,
..Default::default()
};
let mut handle: VkFence = 0;
check(unsafe { create(device.inner.handle, &info, std::ptr::null(), &mut handle) })?;
Ok(Self {
handle,
device: Arc::clone(&device.inner),
})
}
pub fn raw(&self) -> VkFence {
self.handle
}
pub fn wait(&self, timeout_nanos: u64) -> Result<()> {
let wait = self
.device
.dispatch
.vkWaitForFences
.ok_or(Error::MissingFunction("vkWaitForFences"))?;
check(unsafe {
wait(
self.device.handle,
1,
&self.handle,
1, timeout_nanos,
)
})
}
pub fn reset(&self) -> Result<()> {
let reset = self
.device
.dispatch
.vkResetFences
.ok_or(Error::MissingFunction("vkResetFences"))?;
check(unsafe { reset(self.device.handle, 1, &self.handle) })
}
}
impl Drop for Fence {
fn drop(&mut self) {
if let Some(destroy) = self.device.dispatch.vkDestroyFence {
unsafe { destroy(self.device.handle, self.handle, std::ptr::null()) };
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SemaphoreKind {
Binary,
Timeline,
}
pub struct Semaphore {
pub(crate) handle: VkSemaphore,
pub(crate) device: Arc<DeviceInner>,
pub(crate) kind: SemaphoreKind,
}
impl Semaphore {
pub fn binary(device: &Device) -> Result<Self> {
let create = device
.inner
.dispatch
.vkCreateSemaphore
.ok_or(Error::MissingFunction("vkCreateSemaphore"))?;
let info = VkSemaphoreCreateInfo {
sType: VkStructureType::STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
..Default::default()
};
let mut handle: VkSemaphore = 0;
check(unsafe { create(device.inner.handle, &info, std::ptr::null(), &mut handle) })?;
Ok(Self {
handle,
device: Arc::clone(&device.inner),
kind: SemaphoreKind::Binary,
})
}
pub fn timeline(device: &Device, initial_value: u64) -> Result<Self> {
if device.inner.dispatch.vkGetSemaphoreCounterValue.is_none() {
return Err(Error::MissingFunction("vkGetSemaphoreCounterValue"));
}
let create = device
.inner
.dispatch
.vkCreateSemaphore
.ok_or(Error::MissingFunction("vkCreateSemaphore"))?;
let mut chain = crate::safe::PNextChain::new();
chain.push(VkSemaphoreTypeCreateInfo {
sType: VkStructureType::STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
semaphoreType: VkSemaphoreType::SEMAPHORE_TYPE_TIMELINE,
initialValue: initial_value,
..Default::default()
});
let info = VkSemaphoreCreateInfo {
sType: VkStructureType::STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
pNext: chain.head(),
..Default::default()
};
let mut handle: VkSemaphore = 0;
check(unsafe { create(device.inner.handle, &info, std::ptr::null(), &mut handle) })?;
drop(chain);
Ok(Self {
handle,
device: Arc::clone(&device.inner),
kind: SemaphoreKind::Timeline,
})
}
pub fn raw(&self) -> VkSemaphore {
self.handle
}
pub fn kind(&self) -> SemaphoreKind {
self.kind
}
pub fn current_value(&self) -> Result<u64> {
if self.kind != SemaphoreKind::Timeline {
return Err(Error::MissingFunction("current_value on binary semaphore"));
}
let get = self
.device
.dispatch
.vkGetSemaphoreCounterValue
.ok_or(Error::MissingFunction("vkGetSemaphoreCounterValue"))?;
let mut v: u64 = 0;
check(unsafe { get(self.device.handle, self.handle, &mut v) })?;
Ok(v)
}
pub fn signal_value(&self, value: u64) -> Result<()> {
if self.kind != SemaphoreKind::Timeline {
return Err(Error::MissingFunction("signal_value on binary semaphore"));
}
let signal = self
.device
.dispatch
.vkSignalSemaphore
.ok_or(Error::MissingFunction("vkSignalSemaphore"))?;
let info = VkSemaphoreSignalInfo {
sType: VkStructureType::STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,
semaphore: self.handle,
value,
..Default::default()
};
check(unsafe { signal(self.device.handle, &info) })
}
pub fn wait_value(&self, value: u64, timeout_nanos: u64) -> Result<()> {
if self.kind != SemaphoreKind::Timeline {
return Err(Error::MissingFunction("wait_value on binary semaphore"));
}
let wait = self
.device
.dispatch
.vkWaitSemaphores
.ok_or(Error::MissingFunction("vkWaitSemaphores"))?;
let info = VkSemaphoreWaitInfo {
sType: VkStructureType::STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
semaphoreCount: 1,
pSemaphores: &self.handle,
pValues: &value,
..Default::default()
};
check(unsafe { wait(self.device.handle, &info, timeout_nanos) })
}
}
impl Drop for Semaphore {
fn drop(&mut self) {
if let Some(destroy) = self.device.dispatch.vkDestroySemaphore {
unsafe { destroy(self.device.handle, self.handle, std::ptr::null()) };
}
}
}