1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
//! Command queues.
//!
//! Queues are the execution paths of the graphical processing units. These process
//! submitted commands buffers.
//!
//! There are different types of queues, which can only handle associated command buffers.
//! `CommandQueue<B, C>` has the capability defined by `C`: graphics, compute and transfer.

pub mod family;

use crate::{
    device::OutOfMemory,
    pso,
    window::{PresentError, PresentationSurface, Suboptimal},
    Backend,
};
use std::{any::Any, fmt};

pub use self::family::{QueueFamily, QueueFamilyId, QueueGroup};

/// The type of the queue, an enum encompassing `queue::Capability`
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum QueueType {
    /// Supports all operations.
    General,
    /// Only supports graphics and transfer operations.
    Graphics,
    /// Only supports compute and transfer operations.
    Compute,
    /// Only supports transfer operations.
    Transfer,
}

impl QueueType {
    /// Returns true if the queue supports graphics operations.
    pub fn supports_graphics(&self) -> bool {
        match *self {
            QueueType::General | QueueType::Graphics => true,
            QueueType::Compute | QueueType::Transfer => false,
        }
    }
    /// Returns true if the queue supports compute operations.
    pub fn supports_compute(&self) -> bool {
        match *self {
            QueueType::General | QueueType::Graphics | QueueType::Compute => true,
            QueueType::Transfer => false,
        }
    }
    /// Returns true if the queue supports transfer operations.
    pub fn supports_transfer(&self) -> bool {
        true
    }
}

/// Scheduling hint for devices about the priority of a queue.  Values range from `0.0` (low) to
/// `1.0` (high).
pub type QueuePriority = f32;

/// Abstraction for an internal GPU execution engine.
///
/// Commands are executed on the the device by submitting
/// [command buffers][crate::command::CommandBuffer].
///
/// Queues can also be used for presenting to a surface
/// (that is, flip the front buffer with the next one in the chain).
pub trait CommandQueue<B: Backend>: fmt::Debug + Any + Send + Sync {
    /// Submit command buffers to queue for execution.
    ///
    /// # Arguments
    ///
    /// * `command_buffers` - command buffers to submit.
    /// * `wait_semaphores` - semaphores to wait being signalled before submission.
    /// * `signal_semaphores` - semaphores to signal after all command buffers
    ///   in the submission have finished execution.
    /// * `fence` - must be in unsignaled state, and will be signaled after
    ///   all command buffers in the submission have finished execution.
    ///
    /// # Safety
    ///
    /// It's not checked that the queue can process the submitted command buffers.
    ///
    /// For example, trying to submit compute commands to a graphics queue
    /// will result in undefined behavior.
    unsafe fn submit<'a, Ic, Iw, Is>(
        &mut self,
        command_buffers: Ic,
        wait_semaphores: Iw,
        signal_semaphores: Is,
        fence: Option<&mut B::Fence>,
    ) where
        Ic: Iterator<Item = &'a B::CommandBuffer>,
        Iw: Iterator<Item = (&'a B::Semaphore, pso::PipelineStage)>,
        Is: Iterator<Item = &'a B::Semaphore>;

    /// Present a swapchain image directly to a surface, after waiting on `wait_semaphore`.
    ///
    /// # Safety
    ///
    /// Unsafe for the same reasons as [`submit`][CommandQueue::submit].
    /// No checks are performed to verify that this queue supports present operations.
    unsafe fn present(
        &mut self,
        surface: &mut B::Surface,
        image: <B::Surface as PresentationSurface<B>>::SwapchainImage,
        wait_semaphore: Option<&mut B::Semaphore>,
    ) -> Result<Option<Suboptimal>, PresentError>;

    /// Wait for the queue to be idle.
    fn wait_idle(&mut self) -> Result<(), OutOfMemory>;
}