Wait on a Fence now takes a Option<Duration>

This commit is contained in:
Pierre Krieger 2017-05-10 19:50:10 +02:00
parent b81d204df9
commit be12333d6f
5 changed files with 26 additions and 18 deletions

View File

@ -97,7 +97,7 @@ impl<'a> SubmitCommandBufferBuilder<'a> {
/// builder.submit(&queue).unwrap();
///
/// // We must not destroy the fence before it is signaled.
/// fence.wait(Duration::from_secs(5)).unwrap();
/// fence.wait(Some(Duration::from_secs(5))).unwrap();
/// }
/// ```
///
@ -324,7 +324,7 @@ mod tests {
builder.set_fence_signal(&fence);
builder.submit(&queue).unwrap();
fence.wait(Duration::from_secs(10)).unwrap();
fence.wait(Some(Duration::from_secs(5))).unwrap();
assert!(fence.ready().unwrap());
}
}

View File

@ -268,6 +268,7 @@ impl Swapchain {
// TODO: has to make sure vkQueuePresent is called, because calling acquire_next_image many
// times in a row is an error
// TODO: swapchain must not have been replaced by being passed as the VkSwapchainCreateInfoKHR::oldSwapchain value to vkCreateSwapchainKHR
// TODO: change timeout to `Option<Duration>`.
pub fn acquire_next_image(&self, timeout: Duration) -> Result<(usize, SwapchainAcquireFuture), AcquireError> {
unsafe {
let stale = self.stale.lock().unwrap();

View File

@ -100,16 +100,21 @@ impl<D> Fence<D> where D: SafeDeref<Target = Device> {
}
}
/// Waits until the fence is signaled, or at least until the number of nanoseconds of the
/// timeout has elapsed.
/// Waits until the fence is signaled, or at least until the timeout duration has elapsed.
///
/// Returns `Ok` if the fence is now signaled. Returns `Err` if the timeout was reached instead.
pub fn wait(&self, timeout: Duration) -> Result<(), FenceWaitError> {
///
/// If you pass a duration of 0, then the function will return without blocking.
pub fn wait(&self, timeout: Option<Duration>) -> Result<(), FenceWaitError> {
unsafe {
if self.signaled.load(Ordering::Relaxed) { return Ok(()); }
let timeout_ns = timeout.as_secs().saturating_mul(1_000_000_000)
.saturating_add(timeout.subsec_nanos() as u64);
let timeout_ns = if let Some(timeout) = timeout {
timeout.as_secs().saturating_mul(1_000_000_000)
.saturating_add(timeout.subsec_nanos() as u64)
} else {
u64::max_value()
};
let vk = self.device.pointers();
let r = try!(check_errors(vk.WaitForFences(self.device.internal_object(), 1,
@ -133,7 +138,7 @@ impl<D> Fence<D> where D: SafeDeref<Target = Device> {
/// # Panic
///
/// Panics if not all fences belong to the same device.
pub fn multi_wait<'a, I>(iter: I, timeout: Duration) -> Result<(), FenceWaitError>
pub fn multi_wait<'a, I>(iter: I, timeout: Option<Duration>) -> Result<(), FenceWaitError>
where I: IntoIterator<Item = &'a Fence<D>>, D: 'a
{
let mut device: Option<&Device> = None;
@ -153,8 +158,12 @@ impl<D> Fence<D> where D: SafeDeref<Target = Device> {
}
}).collect();
let timeout_ns = timeout.as_secs().saturating_mul(1_000_000_000)
.saturating_add(timeout.subsec_nanos() as u64);
let timeout_ns = if let Some(timeout) = timeout {
timeout.as_secs().saturating_mul(1_000_000_000)
.saturating_add(timeout.subsec_nanos() as u64)
} else {
u64::max_value()
};
let r = if let Some(device) = device {
unsafe {
@ -319,7 +328,7 @@ mod tests {
let (device, _) = gfx_dev_and_queue!();
let fence = Fence::signaled(device.clone()).unwrap();
fence.wait(Duration::new(0, 10)).unwrap();
fence.wait(Some(Duration::new(0, 10))).unwrap();
}
#[test]
@ -340,7 +349,7 @@ mod tests {
let fence1 = Fence::signaled(device1.clone()).unwrap();
let fence2 = Fence::signaled(device2.clone()).unwrap();
let _ = Fence::multi_wait([&fence1, &fence2].iter().cloned(), Duration::new(0, 10));
let _ = Fence::multi_wait([&fence1, &fence2].iter().cloned(), Some(Duration::new(0, 10)));
}
#[test]

View File

@ -51,7 +51,7 @@ pub enum FenceSignalFutureBehavior {
/// Wait for the fence to be signalled before submitting any further operation.
Block {
/// How long to block the current thread.
timeout: Duration
timeout: Option<Duration>
},
}
@ -98,7 +98,7 @@ impl<F> FenceSignalFuture<F> where F: GpuFuture {
match *state {
FenceSignalFutureState::Flushed(_, ref fence) => {
match fence.wait(Duration::from_secs(0)) {
match fence.wait(Some(Duration::from_secs(0))) {
Ok(()) => (),
Err(_) => return,
}
@ -331,9 +331,8 @@ impl<F> Drop for FenceSignalFuture<F> where F: GpuFuture {
match mem::replace(&mut *state, FenceSignalFutureState::Cleaned) {
FenceSignalFutureState::Flushed(previous, fence) => {
// This is a normal situation. Submitting worked.
// TODO: arbitrary timeout?
// TODO: handle errors?
fence.wait(Duration::from_secs(600)).unwrap();
fence.wait(None).unwrap();
unsafe { previous.signal_finished(); }
},
FenceSignalFutureState::Cleaned => {

View File

@ -9,7 +9,6 @@
use std::error::Error;
use std::sync::Arc;
use std::time::Duration;
use buffer::BufferAccess;
use command_buffer::CommandBuffer;
@ -190,7 +189,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
#[inline]
fn then_signal_fence(self) -> FenceSignalFuture<Self> where Self: Sized {
fence_signal::then_signal_fence(self, FenceSignalFutureBehavior::Block {
timeout: Duration::from_millis(600) // TODO: arbitrary duration
timeout: None
})
}