mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2025-02-27 22:43:04 +00:00
Merge pull request #473 from tomaka/fence-future-wait
Add FenceSignalFuture::wait()
This commit is contained in:
commit
7c70dd7e01
@ -58,6 +58,35 @@ pub enum FenceSignalFutureBehavior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a fence being signaled after a previous event.
|
/// Represents a fence being signaled after a previous event.
|
||||||
|
///
|
||||||
|
/// Contrary to most other future types, it is possible to block the current thread until the event
|
||||||
|
/// happens. This is done by calling the `wait()` function.
|
||||||
|
///
|
||||||
|
/// Also note that the `GpuFuture` trait is implemented on `Arc<FenceSignalFuture<_>>`.
|
||||||
|
/// This means that you can put this future in an `Arc` and keep a copy of it somewhere in order
|
||||||
|
/// to know when the execution reached that point.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::sync::Arc;
|
||||||
|
/// use vulkano::sync::GpuFuture;
|
||||||
|
///
|
||||||
|
/// # let future: Box<GpuFuture> = return;
|
||||||
|
/// // Assuming you have a chain of operations, like this:
|
||||||
|
/// // let future = ...
|
||||||
|
/// // .then_execute(foo)
|
||||||
|
/// // .then_execute(bar)
|
||||||
|
///
|
||||||
|
/// // You can signal a fence at this point of the chain, and put the future in an `Arc`.
|
||||||
|
/// let fence_signal = Arc::new(future.then_signal_fence());
|
||||||
|
///
|
||||||
|
/// // And then continue the chain:
|
||||||
|
/// // fence_signal.clone()
|
||||||
|
/// // .then_execute(baz)
|
||||||
|
/// // .then_execute(qux)
|
||||||
|
///
|
||||||
|
/// // Later you can wait until you reach the point of `fence_signal`:
|
||||||
|
/// fence_signal.wait(None).unwrap();
|
||||||
|
/// ```
|
||||||
#[must_use = "Dropping this object will immediately block the thread until the GPU has finished processing the submission"]
|
#[must_use = "Dropping this object will immediately block the thread until the GPU has finished processing the submission"]
|
||||||
pub struct FenceSignalFuture<F> where F: GpuFuture {
|
pub struct FenceSignalFuture<F> where F: GpuFuture {
|
||||||
// Current state. See the docs of `FenceSignalFutureState`.
|
// Current state. See the docs of `FenceSignalFutureState`.
|
||||||
@ -91,6 +120,32 @@ enum FenceSignalFutureState<F> {
|
|||||||
Poisonned,
|
Poisonned,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F> FenceSignalFuture<F> where F: GpuFuture {
|
||||||
|
/// Blocks the current thread until the fence is signaled by the GPU. Performs a flush if
|
||||||
|
/// necessary.
|
||||||
|
///
|
||||||
|
/// If `timeout` is `None`, then the wait is infinite. Otherwise the thread will unblock after
|
||||||
|
/// the specified timeout has elapsed and an error will be returned.
|
||||||
|
///
|
||||||
|
/// If the wait is successful, this function also cleans any resource locked by previous
|
||||||
|
/// submissions.
|
||||||
|
pub fn wait(&self, timeout: Option<Duration>) -> Result<(), FlushError> {
|
||||||
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
|
self.flush_impl(&mut state)?;
|
||||||
|
|
||||||
|
match mem::replace(&mut *state, FenceSignalFutureState::Cleaned) {
|
||||||
|
FenceSignalFutureState::Flushed(previous, fence) => {
|
||||||
|
fence.wait(timeout)?;
|
||||||
|
unsafe { previous.signal_finished(); }
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
FenceSignalFutureState::Cleaned => Ok(()),
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<F> FenceSignalFuture<F> where F: GpuFuture {
|
impl<F> FenceSignalFuture<F> where F: GpuFuture {
|
||||||
// Implementation of `cleanup_finished`, but takes a `&self` instead of a `&mut self`.
|
// Implementation of `cleanup_finished`, but takes a `&self` instead of a `&mut self`.
|
||||||
// This is an external function so that we can also call it from an `Arc<FenceSignalFuture>`.
|
// This is an external function so that we can also call it from an `Arc<FenceSignalFuture>`.
|
||||||
|
Loading…
Reference in New Issue
Block a user