diff options
Diffstat (limited to 'src/command_buffer/submit/queue_present.rs')
-rw-r--r-- | src/command_buffer/submit/queue_present.rs | 279 |
1 files changed, 0 insertions, 279 deletions
diff --git a/src/command_buffer/submit/queue_present.rs b/src/command_buffer/submit/queue_present.rs deleted file mode 100644 index 28f4229..0000000 --- a/src/command_buffer/submit/queue_present.rs +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright (c) 2017 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 smallvec::SmallVec; -use std::error; -use std::fmt; -use std::marker::PhantomData; -use std::ptr; - -use crate::device::DeviceOwned; -use crate::device::Queue; -use crate::swapchain::PresentRegion; -use crate::swapchain::Swapchain; -use crate::sync::Semaphore; - -use crate::check_errors; -use crate::Error; -use crate::OomError; -use crate::SynchronizedVulkanObject; -use crate::VulkanObject; - -/// Prototype for a submission that presents a swapchain on the screen. -// TODO: example here -pub struct SubmitPresentBuilder<'a> { - wait_semaphores: SmallVec<[ash::vk::Semaphore; 8]>, - swapchains: SmallVec<[ash::vk::SwapchainKHR; 4]>, - image_indices: SmallVec<[u32; 4]>, - present_regions: SmallVec<[ash::vk::PresentRegionKHR; 4]>, - rect_layers: SmallVec<[ash::vk::RectLayerKHR; 4]>, - marker: PhantomData<&'a ()>, -} - -impl<'a> SubmitPresentBuilder<'a> { - /// Builds a new empty `SubmitPresentBuilder`. - #[inline] - pub fn new() -> SubmitPresentBuilder<'a> { - SubmitPresentBuilder { - wait_semaphores: SmallVec::new(), - swapchains: SmallVec::new(), - image_indices: SmallVec::new(), - present_regions: SmallVec::new(), - rect_layers: SmallVec::new(), - marker: PhantomData, - } - } - - /// Adds a semaphore to be waited upon before the presents are executed. - /// - /// # Safety - /// - /// - If you submit this builder, the semaphore must be kept alive until you are guaranteed - /// that the GPU has presented the swapchains. - /// - /// - If you submit this builder, no other queue must be waiting on these semaphores. In other - /// words, each semaphore signal can only correspond to one semaphore wait. - /// - /// - If you submit this builder, the semaphores must be signaled when the queue execution - /// reaches this submission, or there must be one or more submissions in queues that are - /// going to signal these semaphores. In other words, you must not block the queue with - /// semaphores that can't get signaled. - /// - /// - The swapchains and semaphores must all belong to the same device. - /// - #[inline] - pub unsafe fn add_wait_semaphore(&mut self, semaphore: &'a Semaphore) { - self.wait_semaphores.push(semaphore.internal_object()); - } - - /// Adds an image of a swapchain to be presented. - /// - /// Allows to specify a present region. - /// Areas outside the present region *can* be ignored by the Vulkan implementation for - /// optimizations purposes. - /// - /// If `VK_KHR_incremental_present` is not enabled, the `present_region` parameter is ignored. - /// - /// # Safety - /// - /// - If you submit this builder, the swapchain must be kept alive until you are - /// guaranteed that the GPU has finished presenting. - /// - /// - The swapchains and semaphores must all belong to the same device. - /// - #[inline] - pub unsafe fn add_swapchain<W>( - &mut self, - swapchain: &'a Swapchain<W>, - image_num: u32, - present_region: Option<&'a PresentRegion>, - ) { - debug_assert!(image_num < swapchain.num_images()); - - if swapchain - .device() - .enabled_extensions() - .khr_incremental_present - { - let vk_present_region = match present_region { - Some(present_region) => { - assert!(present_region.is_compatible_with(swapchain)); - for rectangle in &present_region.rectangles { - self.rect_layers.push(rectangle.into()); - } - ash::vk::PresentRegionKHR { - rectangle_count: present_region.rectangles.len() as u32, - // Set this to null for now; in submit fill it with self.rect_layers - p_rectangles: ptr::null(), - } - } - None => ash::vk::PresentRegionKHR { - rectangle_count: 0, - p_rectangles: ptr::null(), - }, - }; - self.present_regions.push(vk_present_region); - } - - self.swapchains.push(swapchain.internal_object()); - self.image_indices.push(image_num); - } - - /// Submits the command. Calls `vkQueuePresentKHR`. - /// - /// # Panic - /// - /// Panics if no swapchain image has been added to the builder. - /// - pub fn submit(mut self, queue: &Queue) -> Result<(), SubmitPresentError> { - unsafe { - debug_assert_eq!(self.swapchains.len(), self.image_indices.len()); - assert!( - !self.swapchains.is_empty(), - "Tried to submit a present command without any swapchain" - ); - - let present_regions = { - if !self.present_regions.is_empty() { - debug_assert!(queue.device().enabled_extensions().khr_incremental_present); - debug_assert_eq!(self.swapchains.len(), self.present_regions.len()); - let mut current_index = 0; - for present_region in &mut self.present_regions { - present_region.p_rectangles = self.rect_layers[current_index..].as_ptr(); - current_index += present_region.rectangle_count as usize; - } - Some(ash::vk::PresentRegionsKHR { - swapchain_count: self.present_regions.len() as u32, - p_regions: self.present_regions.as_ptr(), - ..Default::default() - }) - } else { - None - } - }; - - let mut results = vec![ash::vk::Result::SUCCESS; self.swapchains.len()]; - - let fns = queue.device().fns(); - let queue = queue.internal_object_guard(); - - let infos = ash::vk::PresentInfoKHR { - p_next: present_regions - .as_ref() - .map(|pr| pr as *const ash::vk::PresentRegionsKHR as *const _) - .unwrap_or(ptr::null()), - wait_semaphore_count: self.wait_semaphores.len() as u32, - p_wait_semaphores: self.wait_semaphores.as_ptr(), - swapchain_count: self.swapchains.len() as u32, - p_swapchains: self.swapchains.as_ptr(), - p_image_indices: self.image_indices.as_ptr(), - p_results: results.as_mut_ptr(), - ..Default::default() - }; - - check_errors(fns.khr_swapchain.queue_present_khr(*queue, &infos))?; - - for result in results { - check_errors(result)?; - } - - Ok(()) - } - } -} - -impl<'a> fmt::Debug for SubmitPresentBuilder<'a> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { - fmt.debug_struct("SubmitPresentBuilder") - .field("wait_semaphores", &self.wait_semaphores) - .field("swapchains", &self.swapchains) - .field("image_indices", &self.image_indices) - .finish() - } -} - -/// Error that can happen when submitting the present prototype. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[repr(u32)] -pub enum SubmitPresentError { - /// Not enough memory. - OomError(OomError), - - /// The connection to the device has been lost. - DeviceLost, - - /// The surface is no longer accessible and must be recreated. - SurfaceLost, - - /// The swapchain has lost or doesn't have fullscreen exclusivity possibly for - /// implementation-specific reasons outside of the application’s control. - FullscreenExclusiveLost, - - /// The surface has changed in a way that makes the swapchain unusable. You must query the - /// surface's new properties and recreate a new swapchain if you want to continue drawing. - OutOfDate, -} - -impl error::Error for SubmitPresentError { - #[inline] - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - match *self { - SubmitPresentError::OomError(ref err) => Some(err), - _ => None, - } - } -} - -impl fmt::Display for SubmitPresentError { - #[inline] - fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!( - fmt, - "{}", - match *self { - SubmitPresentError::OomError(_) => "not enough memory", - SubmitPresentError::DeviceLost => "the connection to the device has been lost", - SubmitPresentError::SurfaceLost => - "the surface of this swapchain is no longer valid", - SubmitPresentError::OutOfDate => "the swapchain needs to be recreated", - SubmitPresentError::FullscreenExclusiveLost => { - "the swapchain no longer has fullscreen exclusivity" - } - } - ) - } -} - -impl From<Error> for SubmitPresentError { - #[inline] - fn from(err: Error) -> SubmitPresentError { - match err { - err @ Error::OutOfHostMemory => SubmitPresentError::OomError(OomError::from(err)), - err @ Error::OutOfDeviceMemory => SubmitPresentError::OomError(OomError::from(err)), - Error::DeviceLost => SubmitPresentError::DeviceLost, - Error::SurfaceLost => SubmitPresentError::SurfaceLost, - Error::OutOfDate => SubmitPresentError::OutOfDate, - Error::FullscreenExclusiveLost => SubmitPresentError::FullscreenExclusiveLost, - _ => panic!("unexpected error: {:?}", err), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn no_swapchain_added() { - let (_, queue) = gfx_dev_and_queue!(); - assert_should_panic!("Tried to submit a present command without any swapchain", { - let _ = SubmitPresentBuilder::new().submit(&queue); - }); - } -} |