aboutsummaryrefslogtreecommitdiff
path: root/src/sync/semaphore/semaphore.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sync/semaphore/semaphore.rs')
-rw-r--r--src/sync/semaphore/semaphore.rs355
1 files changed, 0 insertions, 355 deletions
diff --git a/src/sync/semaphore/semaphore.rs b/src/sync/semaphore/semaphore.rs
deleted file mode 100644
index 29c9952..0000000
--- a/src/sync/semaphore/semaphore.rs
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright (c) 2016 The vulkano developers
-// Licensed under the Apache License, Version 2.0
-// <LICENSE-APACHE or
-// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
-// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
-// at your option. All files in the project carrying such
-// notice may not be copied, modified, or distributed except
-// according to those terms.
-
-use crate::check_errors;
-use crate::device::Device;
-use crate::device::DeviceOwned;
-use crate::Error;
-use crate::OomError;
-use crate::SafeDeref;
-use crate::VulkanObject;
-use std::fmt;
-#[cfg(target_os = "linux")]
-use std::fs::File;
-use std::mem::MaybeUninit;
-#[cfg(target_os = "linux")]
-use std::os::unix::io::FromRawFd;
-use std::ptr;
-use std::sync::Arc;
-
-use crate::sync::semaphore::ExternalSemaphoreHandleType;
-
-/// Used to provide synchronization between command buffers during their execution.
-///
-/// It is similar to a fence, except that it is purely on the GPU side. The CPU can't query a
-/// semaphore's status or wait for it to be signaled.
-#[derive(Debug)]
-pub struct Semaphore<D = Arc<Device>>
-where
- D: SafeDeref<Target = Device>,
-{
- semaphore: ash::vk::Semaphore,
- device: D,
- must_put_in_pool: bool,
-}
-
-// TODO: Add support for VkExportSemaphoreWin32HandleInfoKHR
-// TODO: Add suport for importable semaphores
-pub struct SemaphoreBuilder<D = Arc<Device>>
-where
- D: SafeDeref<Target = Device>,
-{
- device: D,
- export_info: Option<ash::vk::ExportSemaphoreCreateInfo>,
- create: ash::vk::SemaphoreCreateInfo,
- must_put_in_pool: bool,
-}
-
-impl<D> SemaphoreBuilder<D>
-where
- D: SafeDeref<Target = Device>,
-{
- pub fn new(device: D) -> Self {
- let create = ash::vk::SemaphoreCreateInfo::default();
-
- Self {
- device,
- export_info: None,
- create,
- must_put_in_pool: false,
- }
- }
- /// Configures the semaphore to be added to the semaphore pool once it is destroyed.
- pub(crate) fn in_pool(mut self) -> Self {
- self.must_put_in_pool = true;
- self
- }
-
- /// Sets an optional field for exportable allocations in the `SemaphoreBuilder`.
- ///
- /// # Panic
- ///
- /// - Panics if the export info has already been set.
- pub fn export_info(mut self, handle_types: ExternalSemaphoreHandleType) -> Self {
- assert!(self.export_info.is_none());
- let export_info = ash::vk::ExportSemaphoreCreateInfo {
- handle_types: handle_types.into(),
- ..Default::default()
- };
-
- self.export_info = Some(export_info);
- self.create.p_next = unsafe { std::mem::transmute(&export_info) };
-
- self
- }
-
- pub fn build(self) -> Result<Semaphore<D>, SemaphoreError> {
- if self.export_info.is_some()
- && !self
- .device
- .instance()
- .enabled_extensions()
- .khr_external_semaphore_capabilities
- {
- Err(SemaphoreError::MissingExtension(
- "khr_external_semaphore_capabilities",
- ))
- } else {
- let semaphore = unsafe {
- let fns = self.device.fns();
- let mut output = MaybeUninit::uninit();
- check_errors(fns.v1_0.create_semaphore(
- self.device.internal_object(),
- &self.create,
- ptr::null(),
- output.as_mut_ptr(),
- ))?;
- output.assume_init()
- };
-
- Ok(Semaphore {
- device: self.device,
- semaphore,
- must_put_in_pool: self.must_put_in_pool,
- })
- }
- }
-}
-
-impl<D> Semaphore<D>
-where
- D: SafeDeref<Target = Device>,
-{
- /// Takes a semaphore from the vulkano-provided semaphore pool.
- /// If the pool is empty, a new semaphore will be allocated.
- /// Upon `drop`, the semaphore is put back into the pool.
- ///
- /// For most applications, using the pool should be preferred,
- /// in order to avoid creating new semaphores every frame.
- pub fn from_pool(device: D) -> Result<Semaphore<D>, SemaphoreError> {
- let maybe_raw_sem = device.semaphore_pool().lock().unwrap().pop();
- match maybe_raw_sem {
- Some(raw_sem) => Ok(Semaphore {
- device,
- semaphore: raw_sem,
- must_put_in_pool: true,
- }),
- None => {
- // Pool is empty, alloc new semaphore
- SemaphoreBuilder::new(device).in_pool().build()
- }
- }
- }
-
- /// Builds a new semaphore.
- #[inline]
- pub fn alloc(device: D) -> Result<Semaphore<D>, SemaphoreError> {
- SemaphoreBuilder::new(device).build()
- }
-
- /// Same as `alloc`, but allows exportable opaque file descriptor on Linux
- #[inline]
- #[cfg(target_os = "linux")]
- pub fn alloc_with_exportable_fd(device: D) -> Result<Semaphore<D>, SemaphoreError> {
- SemaphoreBuilder::new(device)
- .export_info(ExternalSemaphoreHandleType::posix())
- .build()
- }
-
- #[cfg(target_os = "linux")]
- pub fn export_opaque_fd(&self) -> Result<File, SemaphoreError> {
- let fns = self.device.fns();
-
- assert!(self.device.enabled_extensions().khr_external_semaphore);
- assert!(self.device.enabled_extensions().khr_external_semaphore_fd);
-
- let fd = unsafe {
- let info = ash::vk::SemaphoreGetFdInfoKHR {
- semaphore: self.semaphore,
- handle_type: ash::vk::ExternalSemaphoreHandleTypeFlagsKHR::OPAQUE_FD,
- ..Default::default()
- };
-
- let mut output = MaybeUninit::uninit();
- check_errors(fns.khr_external_semaphore_fd.get_semaphore_fd_khr(
- self.device.internal_object(),
- &info,
- output.as_mut_ptr(),
- ))?;
- output.assume_init()
- };
- let file = unsafe { File::from_raw_fd(fd) };
- Ok(file)
- }
-}
-
-unsafe impl DeviceOwned for Semaphore {
- #[inline]
- fn device(&self) -> &Arc<Device> {
- &self.device
- }
-}
-
-unsafe impl<D> VulkanObject for Semaphore<D>
-where
- D: SafeDeref<Target = Device>,
-{
- type Object = ash::vk::Semaphore;
-
- #[inline]
- fn internal_object(&self) -> ash::vk::Semaphore {
- self.semaphore
- }
-}
-
-impl<D> Drop for Semaphore<D>
-where
- D: SafeDeref<Target = Device>,
-{
- #[inline]
- fn drop(&mut self) {
- unsafe {
- if self.must_put_in_pool {
- let raw_sem = self.semaphore;
- self.device.semaphore_pool().lock().unwrap().push(raw_sem);
- } else {
- let fns = self.device.fns();
- fns.v1_0.destroy_semaphore(
- self.device.internal_object(),
- self.semaphore,
- ptr::null(),
- );
- }
- }
- }
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum SemaphoreError {
- /// Not enough memory available.
- OomError(OomError),
- /// An extensions is missing.
- MissingExtension(&'static str),
-}
-
-impl fmt::Display for SemaphoreError {
- fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- match *self {
- SemaphoreError::OomError(_) => write!(fmt, "not enough memory available"),
- SemaphoreError::MissingExtension(s) => {
- write!(fmt, "Missing the following extension: {}", s)
- }
- }
- }
-}
-
-impl From<Error> for SemaphoreError {
- #[inline]
- fn from(err: Error) -> SemaphoreError {
- match err {
- e @ Error::OutOfHostMemory | e @ Error::OutOfDeviceMemory => {
- SemaphoreError::OomError(e.into())
- }
- _ => panic!("unexpected error: {:?}", err),
- }
- }
-}
-
-impl std::error::Error for SemaphoreError {
- #[inline]
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- match *self {
- SemaphoreError::OomError(ref err) => Some(err),
- _ => None,
- }
- }
-}
-
-impl From<OomError> for SemaphoreError {
- #[inline]
- fn from(err: OomError) -> SemaphoreError {
- SemaphoreError::OomError(err)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use crate::device::physical::PhysicalDevice;
- use crate::device::{Device, DeviceExtensions};
- use crate::instance::{Instance, InstanceExtensions};
- use crate::VulkanObject;
- use crate::{sync::Semaphore, Version};
-
- #[test]
- fn semaphore_create() {
- let (device, _) = gfx_dev_and_queue!();
- let _ = Semaphore::alloc(device.clone());
- }
-
- #[test]
- fn semaphore_pool() {
- let (device, _) = gfx_dev_and_queue!();
-
- assert_eq!(device.semaphore_pool().lock().unwrap().len(), 0);
- let sem1_internal_obj = {
- let sem = Semaphore::from_pool(device.clone()).unwrap();
- assert_eq!(device.semaphore_pool().lock().unwrap().len(), 0);
- sem.internal_object()
- };
-
- assert_eq!(device.semaphore_pool().lock().unwrap().len(), 1);
- let sem2 = Semaphore::from_pool(device.clone()).unwrap();
- assert_eq!(device.semaphore_pool().lock().unwrap().len(), 0);
- assert_eq!(sem2.internal_object(), sem1_internal_obj);
- }
-
- #[test]
- #[cfg(target_os = "linux")]
- fn semaphore_export() {
- let supported_ext = InstanceExtensions::supported_by_core().unwrap();
- if supported_ext.khr_get_display_properties2
- && supported_ext.khr_external_semaphore_capabilities
- {
- let instance = Instance::new(
- None,
- Version::V1_1,
- &InstanceExtensions {
- khr_get_physical_device_properties2: true,
- khr_external_semaphore_capabilities: true,
- ..InstanceExtensions::none()
- },
- None,
- )
- .unwrap();
-
- let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
-
- let queue_family = physical.queue_families().next().unwrap();
-
- let device_ext = DeviceExtensions {
- khr_external_semaphore: true,
- khr_external_semaphore_fd: true,
- ..DeviceExtensions::none()
- };
- let (device, _) = Device::new(
- physical,
- physical.supported_features(),
- &device_ext,
- [(queue_family, 0.5)].iter().cloned(),
- )
- .unwrap();
-
- let supported_ext = physical.supported_extensions();
- if supported_ext.khr_external_semaphore && supported_ext.khr_external_semaphore_fd {
- let sem = Semaphore::alloc_with_exportable_fd(device.clone()).unwrap();
- let fd = sem.export_opaque_fd().unwrap();
- }
- }
- }
-}