mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 06:45:23 +00:00
Allow Surface to reference an external window object (#848)
* Allow Surface to reference an external window object This makes the Surface struct generic across a Window type, so that a surface can own (or reference, if W is an Arc) an external window object. This also updates vulkano-win to take advantage of this. There is no longer a dedicated Window struct in vulkano-win. Instead, the Surface is simply passed ownership of the winit::Window. This fixes #844 * Update examples for new surface API * Update Changelog * Remove unnecessary send/sync bounds * Update swapchain docs for new Surface behavior
This commit is contained in:
parent
aa6ce2f977
commit
e9104208c4
@ -2,6 +2,7 @@
|
||||
|
||||
- Changed `ShaderInterfaceMismatchError` to be more verbose.
|
||||
- Allow depth/stencil images to be used with `AutoCommandBufferBuilder::copy_image_to_buffer()`
|
||||
- Allow `Surface` to own the window it references.
|
||||
- Clear value validation for `AutoCommandBufferBuilder::begin_render_pass()`
|
||||
- Fix occasional truncation of glslang_validator when glsl-to-spirv is rebuilt
|
||||
- Fix linking against MoltenVK >= 0.19.0
|
||||
|
@ -37,12 +37,12 @@ fn main() {
|
||||
println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
|
||||
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
let window = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
let surface = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
|
||||
let mut dimensions;
|
||||
|
||||
let queue = physical.queue_families().find(|&q| q.supports_graphics() &&
|
||||
window.surface().is_supported(q).unwrap_or(false))
|
||||
surface.is_supported(q).unwrap_or(false))
|
||||
.expect("couldn't find a graphical queue family");
|
||||
|
||||
let device_ext = vulkano::device::DeviceExtensions {
|
||||
@ -55,14 +55,14 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, mut images) = {
|
||||
let caps = window.surface().capabilities(physical).expect("failed to get surface capabilities");
|
||||
let caps = surface.capabilities(physical).expect("failed to get surface capabilities");
|
||||
|
||||
dimensions = caps.current_extent.unwrap_or([1024, 768]);
|
||||
let usage = caps.supported_usage_flags;
|
||||
let alpha = caps.supported_composite_alpha.iter().next().unwrap();
|
||||
let format = caps.supported_formats[0].0;
|
||||
|
||||
vulkano::swapchain::Swapchain::new(device.clone(), window.surface().clone(), caps.min_image_count,
|
||||
vulkano::swapchain::Swapchain::new(device.clone(), surface.clone(), caps.min_image_count,
|
||||
format, dimensions, 1,
|
||||
usage, &queue, vulkano::swapchain::SurfaceTransform::Identity,
|
||||
alpha,
|
||||
@ -149,7 +149,7 @@ fn main() {
|
||||
previous_frame_end.cleanup_finished();
|
||||
if recreate_swapchain {
|
||||
|
||||
dimensions = window.surface().capabilities(physical)
|
||||
dimensions = surface.capabilities(physical)
|
||||
.expect("failed to get surface capabilities")
|
||||
.current_extent.unwrap_or([1024, 768]);
|
||||
|
||||
|
@ -73,7 +73,7 @@ fn main() {
|
||||
.next()
|
||||
.expect("no graphics device");
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
let window = winit::WindowBuilder::new()
|
||||
let surface = winit::WindowBuilder::new()
|
||||
.with_decorations(false)
|
||||
.with_title("particle storm")
|
||||
.build_vk_surface(&events_loop, instance.clone())
|
||||
@ -81,7 +81,7 @@ fn main() {
|
||||
let (graphics_device, mut queues) = {
|
||||
let graphical_queue_family = physical
|
||||
.queue_families()
|
||||
.find(|&q| q.supports_graphics() && window.surface().is_supported(q).unwrap_or(false))
|
||||
.find(|&q| q.supports_graphics() && surface.is_supported(q).unwrap_or(false))
|
||||
.expect("couldn't find a graphic queue family");
|
||||
let device_ext = DeviceExtensions {
|
||||
khr_swapchain: true,
|
||||
@ -97,7 +97,7 @@ fn main() {
|
||||
let graphics_queue = queues.next().unwrap();
|
||||
|
||||
let (swapchain, images) = {
|
||||
let caps = window.surface()
|
||||
let caps = surface
|
||||
.capabilities(graphics_device.physical_device())
|
||||
.expect("failure to get surface capabilities");
|
||||
let format = caps.supported_formats[0].0;
|
||||
@ -107,7 +107,7 @@ fn main() {
|
||||
|
||||
Swapchain::new(
|
||||
graphics_device.clone(),
|
||||
window.surface().clone(),
|
||||
surface.clone(),
|
||||
caps.min_image_count,
|
||||
format,
|
||||
dimensions,
|
||||
|
@ -38,12 +38,12 @@ fn main() {
|
||||
println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
|
||||
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
let window = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
let surface = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
|
||||
let mut dimensions;
|
||||
|
||||
let queue = physical.queue_families().find(|&q| q.supports_graphics() &&
|
||||
window.surface().is_supported(q).unwrap_or(false))
|
||||
surface.is_supported(q).unwrap_or(false))
|
||||
.expect("couldn't find a graphical queue family");
|
||||
|
||||
let device_ext = vulkano::device::DeviceExtensions {
|
||||
@ -57,7 +57,7 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, mut images) = {
|
||||
let caps = window.surface().capabilities(physical).expect("failed to get surface capabilities");
|
||||
let caps = surface.capabilities(physical).expect("failed to get surface capabilities");
|
||||
|
||||
dimensions = caps.current_extent.unwrap_or([1024, 768]);
|
||||
|
||||
@ -65,7 +65,7 @@ fn main() {
|
||||
let format = caps.supported_formats[0].0;
|
||||
let alpha = caps.supported_composite_alpha.iter().next().unwrap();
|
||||
|
||||
vulkano::swapchain::Swapchain::new(device.clone(), window.surface().clone(), caps.min_image_count, format, dimensions, 1,
|
||||
vulkano::swapchain::Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format, dimensions, 1,
|
||||
usage, &queue, vulkano::swapchain::SurfaceTransform::Identity,
|
||||
alpha,
|
||||
vulkano::swapchain::PresentMode::Fifo, true, None).expect("failed to create swapchain")
|
||||
@ -143,7 +143,7 @@ fn main() {
|
||||
|
||||
if recreate_swapchain {
|
||||
|
||||
dimensions = window.surface().capabilities(physical)
|
||||
dimensions = surface.capabilities(physical)
|
||||
.expect("failed to get surface capabilities")
|
||||
.current_extent.unwrap_or([1024, 768]);
|
||||
|
||||
|
@ -102,10 +102,10 @@ fn main() {
|
||||
// ever get an error about `build_vk_surface` being undefined in one of your projects, this
|
||||
// probably means that you forgot to import this trait.
|
||||
//
|
||||
// This returns a `vulkano_win::Window` object that contains both a cross-platform winit
|
||||
// This returns a `vulkano::swapchain::Surface` object that contains both a cross-platform winit
|
||||
// window and a cross-platform Vulkan surface that represents the surface of the window.
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
let window = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
let surface = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
|
||||
// The next step is to choose which GPU queue will execute our draw commands.
|
||||
//
|
||||
@ -119,7 +119,7 @@ fn main() {
|
||||
// We have to choose which queues to use early on, because we will need this info very soon.
|
||||
let queue = physical.queue_families().find(|&q| {
|
||||
// We take the first queue that supports drawing to our window.
|
||||
q.supports_graphics() && window.surface().is_supported(q).unwrap_or(false)
|
||||
q.supports_graphics() && surface.is_supported(q).unwrap_or(false)
|
||||
}).expect("couldn't find a graphical queue family");
|
||||
|
||||
// Now initializing the device. This is probably the most important object of Vulkan.
|
||||
@ -166,7 +166,7 @@ fn main() {
|
||||
let (mut swapchain, mut images) = {
|
||||
// Querying the capabilities of the surface. When we create the swapchain we can only
|
||||
// pass values that are allowed by the capabilities.
|
||||
let caps = window.surface().capabilities(physical)
|
||||
let caps = surface.capabilities(physical)
|
||||
.expect("failed to get surface capabilities");
|
||||
|
||||
dimensions = caps.current_extent.unwrap_or([1024, 768]);
|
||||
@ -183,7 +183,7 @@ fn main() {
|
||||
let format = caps.supported_formats[0].0;
|
||||
|
||||
// Please take a look at the docs for the meaning of the parameters we didn't mention.
|
||||
Swapchain::new(device.clone(), window.surface().clone(), caps.min_image_count, format,
|
||||
Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format,
|
||||
dimensions, 1, caps.supported_usage_flags, &queue,
|
||||
SurfaceTransform::Identity, alpha, PresentMode::Fifo, true,
|
||||
None).expect("failed to create swapchain")
|
||||
@ -337,7 +337,7 @@ void main() {
|
||||
// If the swapchain needs to be recreated, recreate it
|
||||
if recreate_swapchain {
|
||||
// Get the new dimensions for the viewport/framebuffers.
|
||||
dimensions = window.surface().capabilities(physical)
|
||||
dimensions = surface.capabilities(physical)
|
||||
.expect("failed to get surface capabilities")
|
||||
.current_extent.unwrap();
|
||||
|
||||
|
@ -55,36 +55,14 @@ pub fn required_extensions() -> InstanceExtensions {
|
||||
|
||||
pub trait VkSurfaceBuild {
|
||||
fn build_vk_surface(self, events_loop: &EventsLoop, instance: Arc<Instance>)
|
||||
-> Result<Window, CreationError>;
|
||||
-> Result<Arc<Surface<winit::Window>>, CreationError>;
|
||||
}
|
||||
|
||||
impl VkSurfaceBuild for WindowBuilder {
|
||||
fn build_vk_surface(self, events_loop: &EventsLoop, instance: Arc<Instance>)
|
||||
-> Result<Window, CreationError> {
|
||||
-> Result<Arc<Surface<winit::Window>>, CreationError> {
|
||||
let window = self.build(events_loop)?;
|
||||
let surface = unsafe { winit_to_surface(instance, &window) }?;
|
||||
|
||||
Ok(Window {
|
||||
window: window,
|
||||
surface: surface,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Window {
|
||||
window: winit::Window,
|
||||
surface: Arc<Surface>,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
#[inline]
|
||||
pub fn window(&self) -> &winit::Window {
|
||||
&self.window
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn surface(&self) -> &Arc<Surface> {
|
||||
&self.surface
|
||||
Ok(unsafe { winit_to_surface(instance, window) }?)
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,46 +115,52 @@ impl From<WindowCreationError> for CreationError {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
unsafe fn winit_to_surface(instance: Arc<Instance>, win: &winit::Window)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
unsafe fn winit_to_surface(instance: Arc<Instance>, win: winit::Window)
|
||||
-> Result<Arc<Surface<winit::Window>>, SurfaceCreationError> {
|
||||
use winit::os::android::WindowExt;
|
||||
Surface::from_anativewindow(instance, win.get_native_window())
|
||||
Surface::from_anativewindow(instance, win.get_native_window(), win)
|
||||
}
|
||||
|
||||
#[cfg(all(unix, not(target_os = "android"), not(target_os = "macos")))]
|
||||
unsafe fn winit_to_surface(instance: Arc<Instance>, win: &winit::Window)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
unsafe fn winit_to_surface(instance: Arc<Instance>, win: winit::Window)
|
||||
-> Result<Arc<Surface<winit::Window>>, SurfaceCreationError> {
|
||||
use winit::os::unix::WindowExt;
|
||||
match (win.get_wayland_display(), win.get_wayland_surface()) {
|
||||
(Some(display), Some(surface)) => Surface::from_wayland(instance, display, surface),
|
||||
(Some(display), Some(surface)) => Surface::from_wayland(instance,
|
||||
display,
|
||||
surface,
|
||||
win),
|
||||
_ => {
|
||||
// No wayland display found, check if we can use xlib.
|
||||
// If not, we use xcb.
|
||||
if instance.loaded_extensions().khr_xlib_surface {
|
||||
Surface::from_xlib(instance,
|
||||
win.get_xlib_display().unwrap(),
|
||||
win.get_xlib_window().unwrap() as _)
|
||||
win.get_xlib_window().unwrap() as _,
|
||||
win)
|
||||
} else {
|
||||
Surface::from_xcb(instance,
|
||||
win.get_xcb_connection().unwrap(),
|
||||
win.get_xlib_window().unwrap() as _)
|
||||
win.get_xlib_window().unwrap() as _,
|
||||
win)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
unsafe fn winit_to_surface(instance: Arc<Instance>, win: &winit::Window)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
unsafe fn winit_to_surface(instance: Arc<Instance>, win: winit::Window)
|
||||
-> Result<Arc<Surface<winit::Window>>, SurfaceCreationError> {
|
||||
use winit::os::windows::WindowExt;
|
||||
Surface::from_hwnd(instance,
|
||||
ptr::null() as *const (), // FIXME
|
||||
win.get_hwnd())
|
||||
win.get_hwnd(),
|
||||
win)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
unsafe fn winit_to_surface(instance: Arc<Instance>, win: &winit::Window)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
unsafe fn winit_to_surface(instance: Arc<Instance>, win: winit::Window)
|
||||
-> Result<Arc<Surface<winit::Window>>, SurfaceCreationError> {
|
||||
use winit::os::macos::WindowExt;
|
||||
|
||||
let wnd: cocoa_id = mem::transmute(win.get_nswindow());
|
||||
@ -193,5 +177,5 @@ unsafe fn winit_to_surface(instance: Arc<Instance>, win: &winit::Window)
|
||||
view.setLayer(mem::transmute(layer.0)); // Bombs here with out of memory
|
||||
view.setWantsLayer(YES);
|
||||
|
||||
Surface::from_macos_moltenvk(instance, win.get_nsview() as *const ())
|
||||
Surface::from_macos_moltenvk(instance, win.get_nsview() as *const (), win)
|
||||
}
|
||||
|
@ -90,8 +90,8 @@ impl<'a> SubmitPresentBuilder<'a> {
|
||||
/// - The swapchains and semaphores must all belong to the same device.
|
||||
///
|
||||
#[inline]
|
||||
pub unsafe fn add_swapchain(&mut self, swapchain: &'a Swapchain, image_num: u32,
|
||||
present_region: Option<&'a PresentRegion>) {
|
||||
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
|
||||
|
@ -41,18 +41,18 @@ use OomError;
|
||||
/// the screen. Once an image has been presented, it can no longer be used unless it is acquired
|
||||
/// again.
|
||||
// TODO: #[derive(Debug)]
|
||||
pub struct SwapchainImage {
|
||||
swapchain: Arc<Swapchain>,
|
||||
pub struct SwapchainImage<W> {
|
||||
swapchain: Arc<Swapchain<W>>,
|
||||
image_offset: usize,
|
||||
view: UnsafeImageView,
|
||||
}
|
||||
|
||||
impl SwapchainImage {
|
||||
impl<W> SwapchainImage<W> {
|
||||
/// Builds a `SwapchainImage` from raw components.
|
||||
///
|
||||
/// This is an internal method that you shouldn't call.
|
||||
pub unsafe fn from_raw(swapchain: Arc<Swapchain>, id: usize)
|
||||
-> Result<Arc<SwapchainImage>, OomError> {
|
||||
pub unsafe fn from_raw(swapchain: Arc<Swapchain<W>>, id: usize)
|
||||
-> Result<Arc<SwapchainImage<W>>, OomError> {
|
||||
let image = swapchain.raw_image(id).unwrap();
|
||||
let view = UnsafeImageView::raw(&image.image, ViewType::Dim2d, 0 .. 1, 0 .. 1)?;
|
||||
|
||||
@ -74,7 +74,7 @@ impl SwapchainImage {
|
||||
|
||||
/// Returns the swapchain this image belongs to.
|
||||
#[inline]
|
||||
pub fn swapchain(&self) -> &Arc<Swapchain> {
|
||||
pub fn swapchain(&self) -> &Arc<Swapchain<W>> {
|
||||
&self.swapchain
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ impl SwapchainImage {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl ImageAccess for SwapchainImage {
|
||||
unsafe impl<W> ImageAccess for SwapchainImage<W> {
|
||||
#[inline]
|
||||
fn inner(&self) -> ImageInner {
|
||||
self.my_image()
|
||||
@ -131,21 +131,21 @@ unsafe impl ImageAccess for SwapchainImage {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl ImageClearValue<<Format as FormatDesc>::ClearValue> for SwapchainImage {
|
||||
unsafe impl<W> ImageClearValue<<Format as FormatDesc>::ClearValue> for SwapchainImage<W> {
|
||||
#[inline]
|
||||
fn decode(&self, value: <Format as FormatDesc>::ClearValue) -> Option<ClearValue> {
|
||||
Some(self.swapchain.format().decode_clear_value(value))
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<P> ImageContent<P> for SwapchainImage {
|
||||
unsafe impl<P,W> ImageContent<P> for SwapchainImage<W> {
|
||||
#[inline]
|
||||
fn matches_format(&self) -> bool {
|
||||
true // FIXME:
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl ImageViewAccess for SwapchainImage {
|
||||
unsafe impl<W> ImageViewAccess for SwapchainImage<W> {
|
||||
#[inline]
|
||||
fn parent(&self) -> &ImageAccess {
|
||||
self
|
||||
|
@ -47,8 +47,10 @@
|
||||
//! Trying to use one of these functions without enabling the proper extension will result in an
|
||||
//! error.
|
||||
//!
|
||||
//! **Note that the `Surface` object is unsafe**. It is your responsibility to keep the window
|
||||
//! alive for at least as long as the surface exists.
|
||||
//! **Note that the `Surface` object is potentially unsafe**. It is your responsibility to
|
||||
//! keep the window alive for at least as long as the surface exists. In many cases Surface
|
||||
//! may be able to do this for you, if you pass it ownership of your Window (or a
|
||||
//! reference-counting container for it).
|
||||
//!
|
||||
//! ### Example
|
||||
//!
|
||||
@ -71,11 +73,17 @@
|
||||
//! }
|
||||
//! };
|
||||
//!
|
||||
//! # fn build_window() -> *const u32 { ptr::null() }
|
||||
//! # use std::sync::Arc;
|
||||
//! # struct Window(*const u32);
|
||||
//! # impl Window {
|
||||
//! # fn hwnd(&self) -> *const u32 { self.0 }
|
||||
//! # }
|
||||
//! #
|
||||
//! # fn build_window() -> Arc<Window> { Arc::new(Window(ptr::null())) }
|
||||
//! let window = build_window(); // Third-party function, not provided by vulkano
|
||||
//! let _surface = unsafe {
|
||||
//! let hinstance: *const () = ptr::null(); // Windows-specific object
|
||||
//! Surface::from_hwnd(instance.clone(), hinstance, window).unwrap()
|
||||
//! Surface::from_hwnd(instance.clone(), hinstance, window.hwnd(), Arc::clone(&window)).unwrap()
|
||||
//! };
|
||||
//! ```
|
||||
//!
|
||||
@ -129,7 +137,7 @@
|
||||
//! # use vulkano::device::Device;
|
||||
//! # use vulkano::swapchain::Surface;
|
||||
//! # use std::cmp::{max, min};
|
||||
//! # fn choose_caps(device: Arc<Device>, surface: Arc<Surface>) -> Result<(), Box<std::error::Error>> {
|
||||
//! # fn choose_caps(device: Arc<Device>, surface: Arc<Surface<()>>) -> Result<(), Box<std::error::Error>> {
|
||||
//! let caps = surface.capabilities(device.physical_device())?;
|
||||
//!
|
||||
//! // Use the current window size or some fixed resolution.
|
||||
@ -157,7 +165,7 @@
|
||||
//! # use vulkano::format::Format;
|
||||
//! # use vulkano::swapchain::{Surface, Swapchain, SurfaceTransform, PresentMode, CompositeAlpha};
|
||||
//! # fn create_swapchain(
|
||||
//! # device: Arc<Device>, surface: Arc<Surface>, present_queue: Arc<Queue>,
|
||||
//! # device: Arc<Device>, surface: Arc<Surface<()>>, present_queue: Arc<Queue>,
|
||||
//! # buffers_count: u32, format: Format, dimensions: [u32; 2],
|
||||
//! # surface_transform: SurfaceTransform, composite_alpha: CompositeAlpha, present_mode: PresentMode
|
||||
//! # ) -> Result<(), Box<std::error::Error>> {
|
||||
@ -248,7 +256,7 @@
|
||||
//! use vulkano::sync::GpuFuture;
|
||||
//!
|
||||
//! // let mut swapchain = Swapchain::new(...);
|
||||
//! # let mut swapchain: (::std::sync::Arc<::vulkano::swapchain::Swapchain>, _) = return;
|
||||
//! # let mut swapchain: (::std::sync::Arc<::vulkano::swapchain::Swapchain<()>>, _) = return;
|
||||
//! # let queue: ::std::sync::Arc<::vulkano::device::Queue> = return;
|
||||
//! let mut recreate_swapchain = false;
|
||||
//!
|
||||
|
@ -20,7 +20,7 @@ pub struct PresentRegion {
|
||||
|
||||
impl PresentRegion {
|
||||
/// Returns true if this present region is compatible with swapchain.
|
||||
pub fn is_compatible_with(&self, swapchain: &Swapchain) -> bool {
|
||||
pub fn is_compatible_with<W>(&self, swapchain: &Swapchain<W>) -> bool {
|
||||
self.rectangles
|
||||
.iter()
|
||||
.all(|rect| rect.is_compatible_with(swapchain))
|
||||
@ -42,7 +42,7 @@ pub struct RectangleLayer {
|
||||
|
||||
impl RectangleLayer {
|
||||
/// Returns true if this rectangle layer is compatible with swapchain.
|
||||
pub fn is_compatible_with(&self, swapchain: &Swapchain) -> bool {
|
||||
pub fn is_compatible_with<W>(&self, swapchain: &Swapchain<W>) -> bool {
|
||||
// FIXME negative offset is not disallowed by spec, but semantically should not be possible
|
||||
debug_assert!(self.offset[0] >= 0);
|
||||
debug_assert!(self.offset[1] >= 0);
|
||||
|
@ -35,7 +35,8 @@ use vk;
|
||||
/// Represents a surface on the screen.
|
||||
///
|
||||
/// Creating a `Surface` is platform-specific.
|
||||
pub struct Surface {
|
||||
pub struct Surface<W> {
|
||||
window: W,
|
||||
instance: Arc<Instance>,
|
||||
surface: vk::SurfaceKHR,
|
||||
|
||||
@ -44,13 +45,16 @@ pub struct Surface {
|
||||
has_swapchain: AtomicBool,
|
||||
}
|
||||
|
||||
impl Surface {
|
||||
impl<W> Surface<W> {
|
||||
/// Creates a `Surface` given the raw handler.
|
||||
///
|
||||
/// Be careful when using it
|
||||
///
|
||||
pub unsafe fn from_raw_surface(instance: Arc<Instance>, surface: vk::SurfaceKHR) -> Surface {
|
||||
pub unsafe fn from_raw_surface(instance: Arc<Instance>, surface: vk::SurfaceKHR,
|
||||
win: W)
|
||||
-> Surface<W> {
|
||||
Surface {
|
||||
window: win,
|
||||
instance: instance,
|
||||
surface: surface,
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
@ -65,7 +69,7 @@ impl Surface {
|
||||
/// - Panics if `plane` doesn't support the display of `display_mode`.
|
||||
///
|
||||
pub fn from_display_mode(display_mode: &DisplayMode, plane: &DisplayPlane)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
-> Result<Arc<Surface<()>>, SurfaceCreationError> {
|
||||
if !display_mode
|
||||
.display()
|
||||
.physical_device()
|
||||
@ -110,6 +114,7 @@ impl Surface {
|
||||
};
|
||||
|
||||
Ok(Arc::new(Surface {
|
||||
window: (),
|
||||
instance: instance.clone(),
|
||||
surface: surface,
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
@ -123,9 +128,11 @@ impl Surface {
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that the `hinstance` and the `hwnd` are both correct and stay
|
||||
/// alive for the entire lifetime of the surface.
|
||||
pub unsafe fn from_hwnd<T, U>(instance: Arc<Instance>, hinstance: *const T, hwnd: *const U)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
/// alive for the entire lifetime of the surface. The `win` parameter can be used to ensure this.
|
||||
|
||||
pub unsafe fn from_hwnd<T, U>(instance: Arc<Instance>, hinstance: *const T, hwnd: *const U,
|
||||
win: W)
|
||||
-> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
let vk = instance.pointers();
|
||||
|
||||
if !instance.loaded_extensions().khr_win32_surface {
|
||||
@ -150,6 +157,7 @@ impl Surface {
|
||||
};
|
||||
|
||||
Ok(Arc::new(Surface {
|
||||
window: win,
|
||||
instance: instance.clone(),
|
||||
surface: surface,
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
@ -163,9 +171,10 @@ impl Surface {
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that the `connection` and the `window` are both correct and stay
|
||||
/// alive for the entire lifetime of the surface.
|
||||
pub unsafe fn from_xcb<C>(instance: Arc<Instance>, connection: *const C, window: u32)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
/// alive for the entire lifetime of the surface. The `win` parameter can be used to ensure this.
|
||||
pub unsafe fn from_xcb<C>(instance: Arc<Instance>, connection: *const C, window: u32,
|
||||
win: W)
|
||||
-> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
let vk = instance.pointers();
|
||||
|
||||
if !instance.loaded_extensions().khr_xcb_surface {
|
||||
@ -190,6 +199,7 @@ impl Surface {
|
||||
};
|
||||
|
||||
Ok(Arc::new(Surface {
|
||||
window: win,
|
||||
instance: instance.clone(),
|
||||
surface: surface,
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
@ -203,9 +213,10 @@ impl Surface {
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that the `display` and the `window` are both correct and stay
|
||||
/// alive for the entire lifetime of the surface.
|
||||
pub unsafe fn from_xlib<D>(instance: Arc<Instance>, display: *const D, window: c_ulong)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
/// alive for the entire lifetime of the surface. The `win` parameter can be used to ensure this.
|
||||
pub unsafe fn from_xlib<D>(instance: Arc<Instance>, display: *const D, window: c_ulong,
|
||||
win: W)
|
||||
-> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
let vk = instance.pointers();
|
||||
|
||||
if !instance.loaded_extensions().khr_xlib_surface {
|
||||
@ -230,6 +241,7 @@ impl Surface {
|
||||
};
|
||||
|
||||
Ok(Arc::new(Surface {
|
||||
window: win,
|
||||
instance: instance.clone(),
|
||||
surface: surface,
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
@ -243,10 +255,11 @@ impl Surface {
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that the `display` and the `surface` are both correct and stay
|
||||
/// alive for the entire lifetime of the surface.
|
||||
/// alive for the entire lifetime of the surface. The `win` parameter can be used to ensure this.
|
||||
pub unsafe fn from_wayland<D, S>(instance: Arc<Instance>, display: *const D,
|
||||
surface: *const S)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
surface: *const S,
|
||||
win: W)
|
||||
-> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
let vk = instance.pointers();
|
||||
|
||||
if !instance.loaded_extensions().khr_wayland_surface {
|
||||
@ -271,6 +284,7 @@ impl Surface {
|
||||
};
|
||||
|
||||
Ok(Arc::new(Surface {
|
||||
window: win,
|
||||
instance: instance.clone(),
|
||||
surface: surface,
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
@ -285,9 +299,11 @@ impl Surface {
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that the `connection` and the `surface` are both correct and stay
|
||||
/// alive for the entire lifetime of the surface.
|
||||
pub unsafe fn from_mir<C, S>(instance: Arc<Instance>, connection: *const C, surface: *const S)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
/// alive for the entire lifetime of the surface. The `win` parameter can be used to ensure this.
|
||||
pub unsafe fn from_mir<C, S>(instance: Arc<Instance>, connection: *const C,
|
||||
surface: *const S,
|
||||
win: W)
|
||||
-> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
let vk = instance.pointers();
|
||||
|
||||
if !instance.loaded_extensions().khr_mir_surface {
|
||||
@ -312,6 +328,7 @@ impl Surface {
|
||||
};
|
||||
|
||||
Ok(Arc::new(Surface {
|
||||
window: win,
|
||||
instance: instance.clone(),
|
||||
surface: surface,
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
@ -323,9 +340,10 @@ impl Surface {
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that the `window` is correct and stays alive for the entire
|
||||
/// lifetime of the surface.
|
||||
pub unsafe fn from_anativewindow<T>(instance: Arc<Instance>, window: *const T)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
/// lifetime of the surface. The `win` parameter can be used to ensure this.
|
||||
pub unsafe fn from_anativewindow<T>(instance: Arc<Instance>, window: *const T,
|
||||
win: W)
|
||||
-> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
let vk = instance.pointers();
|
||||
|
||||
if !instance.loaded_extensions().khr_android_surface {
|
||||
@ -349,6 +367,7 @@ impl Surface {
|
||||
};
|
||||
|
||||
Ok(Arc::new(Surface {
|
||||
window: win,
|
||||
instance: instance.clone(),
|
||||
surface: surface,
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
@ -360,10 +379,11 @@ impl Surface {
|
||||
/// # Safety
|
||||
///
|
||||
/// - The caller must ensure that the `view` is correct and stays alive for the entire
|
||||
/// lifetime of the surface.
|
||||
/// lifetime of the surface. The win parameter can be used to ensure this.
|
||||
/// - The `UIView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
|
||||
pub unsafe fn from_ios_moltenvk<T>(instance: Arc<Instance>, view: *const T)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
pub unsafe fn from_ios_moltenvk<T>(instance: Arc<Instance>, view: *const T,
|
||||
win: W)
|
||||
-> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
let vk = instance.pointers();
|
||||
|
||||
if !instance.loaded_extensions().mvk_ios_surface {
|
||||
@ -387,6 +407,7 @@ impl Surface {
|
||||
};
|
||||
|
||||
Ok(Arc::new(Surface {
|
||||
window: win,
|
||||
instance: instance.clone(),
|
||||
surface: surface,
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
@ -398,10 +419,11 @@ impl Surface {
|
||||
/// # Safety
|
||||
///
|
||||
/// - The caller must ensure that the `view` is correct and stays alive for the entire
|
||||
/// lifetime of the surface.
|
||||
/// lifetime of the surface. The `win` parameter can be used to ensure this.
|
||||
/// - The `NSView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
|
||||
pub unsafe fn from_macos_moltenvk<T>(instance: Arc<Instance>, view: *const T)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
pub unsafe fn from_macos_moltenvk<T>(instance: Arc<Instance>, view: *const T,
|
||||
win: W)
|
||||
-> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
let vk = instance.pointers();
|
||||
|
||||
if !instance.loaded_extensions().mvk_macos_surface {
|
||||
@ -425,6 +447,7 @@ impl Surface {
|
||||
};
|
||||
|
||||
Ok(Arc::new(Surface {
|
||||
window: win,
|
||||
instance: instance.clone(),
|
||||
surface: surface,
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
@ -436,9 +459,10 @@ impl Surface {
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that the `window` is correct and stays alive for the entire
|
||||
/// lifetime of the surface.
|
||||
pub unsafe fn from_vi_surface<T>(instance: Arc<Instance>, window: *const T)
|
||||
-> Result<Arc<Surface>, SurfaceCreationError> {
|
||||
/// lifetime of the surface. The `win` parameter can be used to ensure this.
|
||||
pub unsafe fn from_vi_surface<T>(instance: Arc<Instance>, window: *const T,
|
||||
win: W)
|
||||
-> Result<Arc<Surface<W>>, SurfaceCreationError> {
|
||||
let vk = instance.pointers();
|
||||
|
||||
if !instance.loaded_extensions().nn_vi_surface {
|
||||
@ -462,6 +486,7 @@ impl Surface {
|
||||
};
|
||||
|
||||
Ok(Arc::new(Surface {
|
||||
window: win,
|
||||
instance: instance.clone(),
|
||||
surface: surface,
|
||||
has_swapchain: AtomicBool::new(false),
|
||||
@ -574,6 +599,12 @@ impl Surface {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn window(&self) -> &W {
|
||||
&self.window
|
||||
}
|
||||
|
||||
|
||||
/// Returns the instance this surface was created with.
|
||||
#[inline]
|
||||
pub fn instance(&self) -> &Arc<Instance> {
|
||||
@ -581,14 +612,14 @@ impl Surface {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl SurfaceSwapchainLock for Surface {
|
||||
unsafe impl <W> SurfaceSwapchainLock for Surface<W> {
|
||||
#[inline]
|
||||
fn flag(&self) -> &AtomicBool {
|
||||
&self.has_swapchain
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl VulkanObject for Surface {
|
||||
unsafe impl <W> VulkanObject for Surface<W> {
|
||||
type Object = vk::SurfaceKHR;
|
||||
|
||||
const TYPE: vk::DebugReportObjectTypeEXT = vk::DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT;
|
||||
@ -599,14 +630,14 @@ unsafe impl VulkanObject for Surface {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Surface {
|
||||
impl <W> fmt::Debug for Surface<W> {
|
||||
#[inline]
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
write!(fmt, "<Vulkan surface {:?}>", self.surface)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Surface {
|
||||
impl <W> Drop for Surface<W> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
@ -737,7 +768,7 @@ mod tests {
|
||||
#[test]
|
||||
fn khr_win32_surface_ext_missing() {
|
||||
let instance = instance!();
|
||||
match unsafe { Surface::from_hwnd(instance, ptr::null::<u8>(), ptr::null::<u8>()) } {
|
||||
match unsafe { Surface::from_hwnd(instance, ptr::null::<u8>(), ptr::null::<u8>(), ()) } {
|
||||
Err(SurfaceCreationError::MissingExtension { .. }) => (),
|
||||
_ => panic!(),
|
||||
}
|
||||
@ -746,7 +777,7 @@ mod tests {
|
||||
#[test]
|
||||
fn khr_xcb_surface_ext_missing() {
|
||||
let instance = instance!();
|
||||
match unsafe { Surface::from_xcb(instance, ptr::null::<u8>(), 0) } {
|
||||
match unsafe { Surface::from_xcb(instance, ptr::null::<u8>(), 0, ()) } {
|
||||
Err(SurfaceCreationError::MissingExtension { .. }) => (),
|
||||
_ => panic!(),
|
||||
}
|
||||
@ -755,7 +786,7 @@ mod tests {
|
||||
#[test]
|
||||
fn khr_xlib_surface_ext_missing() {
|
||||
let instance = instance!();
|
||||
match unsafe { Surface::from_xlib(instance, ptr::null::<u8>(), 0) } {
|
||||
match unsafe { Surface::from_xlib(instance, ptr::null::<u8>(), 0, ()) } {
|
||||
Err(SurfaceCreationError::MissingExtension { .. }) => (),
|
||||
_ => panic!(),
|
||||
}
|
||||
@ -764,7 +795,9 @@ mod tests {
|
||||
#[test]
|
||||
fn khr_wayland_surface_ext_missing() {
|
||||
let instance = instance!();
|
||||
match unsafe { Surface::from_wayland(instance, ptr::null::<u8>(), ptr::null::<u8>()) } {
|
||||
match unsafe {
|
||||
Surface::from_wayland(instance, ptr::null::<u8>(), ptr::null::<u8>(), ())
|
||||
} {
|
||||
Err(SurfaceCreationError::MissingExtension { .. }) => (),
|
||||
_ => panic!(),
|
||||
}
|
||||
@ -773,7 +806,7 @@ mod tests {
|
||||
#[test]
|
||||
fn khr_mir_surface_ext_missing() {
|
||||
let instance = instance!();
|
||||
match unsafe { Surface::from_mir(instance, ptr::null::<u8>(), ptr::null::<u8>()) } {
|
||||
match unsafe { Surface::from_mir(instance, ptr::null::<u8>(), ptr::null::<u8>(), ()) } {
|
||||
Err(SurfaceCreationError::MissingExtension { .. }) => (),
|
||||
_ => panic!(),
|
||||
}
|
||||
@ -782,7 +815,7 @@ mod tests {
|
||||
#[test]
|
||||
fn khr_android_surface_ext_missing() {
|
||||
let instance = instance!();
|
||||
match unsafe { Surface::from_anativewindow(instance, ptr::null::<u8>()) } {
|
||||
match unsafe { Surface::from_anativewindow(instance, ptr::null::<u8>(), ()) } {
|
||||
Err(SurfaceCreationError::MissingExtension { .. }) => (),
|
||||
_ => panic!(),
|
||||
}
|
||||
|
@ -66,8 +66,8 @@ use vk;
|
||||
///
|
||||
/// If you try to draw on an image without acquiring it first, the execution will block. (TODO
|
||||
/// behavior may change).
|
||||
pub fn acquire_next_image(swapchain: Arc<Swapchain>, timeout: Option<Duration>)
|
||||
-> Result<(usize, SwapchainAcquireFuture), AcquireError> {
|
||||
pub fn acquire_next_image<W>(swapchain: Arc<Swapchain<W>>, timeout: Option<Duration>)
|
||||
-> Result<(usize, SwapchainAcquireFuture<W>), AcquireError> {
|
||||
let semaphore = Semaphore::from_pool(swapchain.device.clone())?;
|
||||
let fence = Fence::from_pool(swapchain.device.clone())?;
|
||||
|
||||
@ -101,8 +101,8 @@ pub fn acquire_next_image(swapchain: Arc<Swapchain>, timeout: Option<Duration>)
|
||||
///
|
||||
/// The actual behavior depends on the present mode that you passed when creating the
|
||||
/// swapchain.
|
||||
pub fn present<F>(swapchain: Arc<Swapchain>, before: F, queue: Arc<Queue>, index: usize)
|
||||
-> PresentFuture<F>
|
||||
pub fn present<F, W>(swapchain: Arc<Swapchain<W>>, before: F, queue: Arc<Queue>, index: usize)
|
||||
-> PresentFuture<F,W>
|
||||
where F: GpuFuture
|
||||
{
|
||||
assert!(index < swapchain.images.len());
|
||||
@ -131,9 +131,9 @@ pub fn present<F>(swapchain: Arc<Swapchain>, before: F, queue: Arc<Queue>, index
|
||||
/// This is just an optimizaion hint, as the vulkan driver is free to ignore the given present region.
|
||||
///
|
||||
/// If `VK_KHR_incremental_present` is not enabled on the device, the parameter will be ignored.
|
||||
pub fn present_incremental<F>(swapchain: Arc<Swapchain>, before: F, queue: Arc<Queue>,
|
||||
pub fn present_incremental<F, W>(swapchain: Arc<Swapchain<W>>, before: F, queue: Arc<Queue>,
|
||||
index: usize, present_region: PresentRegion)
|
||||
-> PresentFuture<F>
|
||||
-> PresentFuture<F, W>
|
||||
where F: GpuFuture
|
||||
{
|
||||
assert!(index < swapchain.images.len());
|
||||
@ -157,11 +157,11 @@ pub fn present_incremental<F>(swapchain: Arc<Swapchain>, before: F, queue: Arc<Q
|
||||
}
|
||||
|
||||
/// Contains the swapping system and the images that can be shown on a surface.
|
||||
pub struct Swapchain {
|
||||
pub struct Swapchain<W> {
|
||||
// The Vulkan device this swapchain was created with.
|
||||
device: Arc<Device>,
|
||||
// The surface, which we need to keep alive.
|
||||
surface: Arc<Surface>,
|
||||
surface: Arc<Surface<W>>,
|
||||
// The swapchain object.
|
||||
swapchain: vk::SwapchainKHR,
|
||||
|
||||
@ -196,7 +196,7 @@ struct ImageEntry {
|
||||
undefined_layout: AtomicBool,
|
||||
}
|
||||
|
||||
impl Swapchain {
|
||||
impl <W> Swapchain<W> {
|
||||
/// Builds a new swapchain. Allocates images who content can be made visible on a surface.
|
||||
///
|
||||
/// See also the `Surface::get_capabilities` function which returns the values that are
|
||||
@ -222,11 +222,11 @@ impl Swapchain {
|
||||
// TODO: isn't it unsafe to take the surface through an Arc when it comes to vulkano-win?
|
||||
#[inline]
|
||||
pub fn new<F, S>(
|
||||
device: Arc<Device>, surface: Arc<Surface>, num_images: u32, format: F,
|
||||
device: Arc<Device>, surface: Arc<Surface<W>>, num_images: u32, format: F,
|
||||
dimensions: [u32; 2], layers: u32, usage: ImageUsage, sharing: S,
|
||||
transform: SurfaceTransform, alpha: CompositeAlpha, mode: PresentMode, clipped: bool,
|
||||
old_swapchain: Option<&Arc<Swapchain>>)
|
||||
-> Result<(Arc<Swapchain>, Vec<Arc<SwapchainImage>>), SwapchainCreationError>
|
||||
old_swapchain: Option<&Arc<Swapchain<W>>>)
|
||||
-> Result<(Arc<Swapchain<W>>, Vec<Arc<SwapchainImage<W>>>), SwapchainCreationError>
|
||||
where F: FormatDesc,
|
||||
S: Into<SharingMode>
|
||||
{
|
||||
@ -249,7 +249,7 @@ impl Swapchain {
|
||||
/// Recreates the swapchain with new dimensions.
|
||||
pub fn recreate_with_dimension(
|
||||
&self, dimensions: [u32; 2])
|
||||
-> Result<(Arc<Swapchain>, Vec<Arc<SwapchainImage>>), SwapchainCreationError> {
|
||||
-> Result<(Arc<Swapchain<W>>, Vec<Arc<SwapchainImage<W>>>), SwapchainCreationError> {
|
||||
Swapchain::new_inner(self.device.clone(),
|
||||
self.surface.clone(),
|
||||
self.num_images,
|
||||
@ -266,11 +266,11 @@ impl Swapchain {
|
||||
Some(self))
|
||||
}
|
||||
|
||||
fn new_inner(device: Arc<Device>, surface: Arc<Surface>, num_images: u32, format: Format,
|
||||
fn new_inner(device: Arc<Device>, surface: Arc<Surface<W>>, num_images: u32, format: Format,
|
||||
color_space: ColorSpace, dimensions: [u32; 2], layers: u32, usage: ImageUsage,
|
||||
sharing: SharingMode, transform: SurfaceTransform, alpha: CompositeAlpha,
|
||||
mode: PresentMode, clipped: bool, old_swapchain: Option<&Swapchain>)
|
||||
-> Result<(Arc<Swapchain>, Vec<Arc<SwapchainImage>>), SwapchainCreationError> {
|
||||
mode: PresentMode, clipped: bool, old_swapchain: Option<&Swapchain<W>>)
|
||||
-> Result<(Arc<Swapchain<W>>, Vec<Arc<SwapchainImage<W>>>), SwapchainCreationError> {
|
||||
assert_eq!(device.instance().internal_object(),
|
||||
surface.instance().internal_object());
|
||||
|
||||
@ -557,7 +557,7 @@ impl Swapchain {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl VulkanObject for Swapchain {
|
||||
unsafe impl<W> VulkanObject for Swapchain<W> {
|
||||
type Object = vk::SwapchainKHR;
|
||||
|
||||
const TYPE: vk::DebugReportObjectTypeEXT = vk::DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT;
|
||||
@ -568,20 +568,20 @@ unsafe impl VulkanObject for Swapchain {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl DeviceOwned for Swapchain {
|
||||
unsafe impl<W> DeviceOwned for Swapchain<W> {
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Swapchain {
|
||||
impl<W> fmt::Debug for Swapchain<W> {
|
||||
#[inline]
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
write!(fmt, "<Vulkan swapchain {:?}>", self.swapchain)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Swapchain {
|
||||
impl<W> Drop for Swapchain<W> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
@ -748,8 +748,8 @@ impl From<CapabilitiesError> for SwapchainCreationError {
|
||||
|
||||
/// Represents the moment when the GPU will have access to a swapchain image.
|
||||
#[must_use]
|
||||
pub struct SwapchainAcquireFuture {
|
||||
swapchain: Arc<Swapchain>,
|
||||
pub struct SwapchainAcquireFuture<W> {
|
||||
swapchain: Arc<Swapchain<W>>,
|
||||
image_id: usize,
|
||||
// Semaphore that is signalled when the acquire is complete. Empty if the acquire has already
|
||||
// happened.
|
||||
@ -760,7 +760,7 @@ pub struct SwapchainAcquireFuture {
|
||||
finished: AtomicBool,
|
||||
}
|
||||
|
||||
impl SwapchainAcquireFuture {
|
||||
impl<W> SwapchainAcquireFuture<W> {
|
||||
/// Returns the index of the image in the list of images returned when creating the swapchain.
|
||||
#[inline]
|
||||
pub fn image_id(&self) -> usize {
|
||||
@ -769,12 +769,12 @@ impl SwapchainAcquireFuture {
|
||||
|
||||
/// Returns the corresponding swapchain.
|
||||
#[inline]
|
||||
pub fn swapchain(&self) -> &Arc<Swapchain> {
|
||||
pub fn swapchain(&self) -> &Arc<Swapchain<W>> {
|
||||
&self.swapchain
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl GpuFuture for SwapchainAcquireFuture {
|
||||
unsafe impl<W> GpuFuture for SwapchainAcquireFuture<W> {
|
||||
#[inline]
|
||||
fn cleanup_finished(&mut self) {
|
||||
}
|
||||
@ -845,14 +845,14 @@ unsafe impl GpuFuture for SwapchainAcquireFuture {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl DeviceOwned for SwapchainAcquireFuture {
|
||||
unsafe impl<W> DeviceOwned for SwapchainAcquireFuture<W> {
|
||||
#[inline]
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
&self.swapchain.device
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for SwapchainAcquireFuture {
|
||||
impl<W> Drop for SwapchainAcquireFuture<W> {
|
||||
fn drop(&mut self) {
|
||||
if !*self.finished.get_mut() {
|
||||
if let Some(ref fence) = self.fence {
|
||||
@ -950,12 +950,12 @@ impl From<Error> for AcquireError {
|
||||
|
||||
/// Represents a swapchain image being presented on the screen.
|
||||
#[must_use = "Dropping this object will immediately block the thread until the GPU has finished processing the submission"]
|
||||
pub struct PresentFuture<P>
|
||||
pub struct PresentFuture<P, W>
|
||||
where P: GpuFuture
|
||||
{
|
||||
previous: P,
|
||||
queue: Arc<Queue>,
|
||||
swapchain: Arc<Swapchain>,
|
||||
swapchain: Arc<Swapchain<W>>,
|
||||
image_id: usize,
|
||||
present_region: Option<PresentRegion>,
|
||||
// True if `flush()` has been called on the future, which means that the present command has
|
||||
@ -966,7 +966,7 @@ pub struct PresentFuture<P>
|
||||
finished: AtomicBool,
|
||||
}
|
||||
|
||||
impl<P> PresentFuture<P>
|
||||
impl<P, W> PresentFuture<P, W>
|
||||
where P: GpuFuture
|
||||
{
|
||||
/// Returns the index of the image in the list of images returned when creating the swapchain.
|
||||
@ -977,12 +977,12 @@ impl<P> PresentFuture<P>
|
||||
|
||||
/// Returns the corresponding swapchain.
|
||||
#[inline]
|
||||
pub fn swapchain(&self) -> &Arc<Swapchain> {
|
||||
pub fn swapchain(&self) -> &Arc<Swapchain<W>> {
|
||||
&self.swapchain
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<P> GpuFuture for PresentFuture<P>
|
||||
unsafe impl<P, W> GpuFuture for PresentFuture<P, W>
|
||||
where P: GpuFuture
|
||||
{
|
||||
#[inline]
|
||||
@ -1113,7 +1113,7 @@ unsafe impl<P> GpuFuture for PresentFuture<P>
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<P> DeviceOwned for PresentFuture<P>
|
||||
unsafe impl<P, W> DeviceOwned for PresentFuture<P, W>
|
||||
where P: GpuFuture
|
||||
{
|
||||
#[inline]
|
||||
@ -1122,7 +1122,7 @@ unsafe impl<P> DeviceOwned for PresentFuture<P>
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> Drop for PresentFuture<P>
|
||||
impl<P, W> Drop for PresentFuture<P, W>
|
||||
where P: GpuFuture
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
@ -1156,9 +1156,9 @@ pub struct AcquiredImage {
|
||||
/// - The semaphore and/or the fence must be kept alive until it is signaled.
|
||||
/// - The swapchain must not have been replaced by being passed as the old swapchain when creating
|
||||
/// a new one.
|
||||
pub unsafe fn acquire_next_image_raw(swapchain: &Swapchain, timeout: Option<Duration>,
|
||||
pub unsafe fn acquire_next_image_raw<W>(swapchain: &Swapchain<W>, timeout: Option<Duration>,
|
||||
semaphore: Option<&Semaphore>, fence: Option<&Fence>)
|
||||
-> Result<AcquiredImage, AcquireError> {
|
||||
-> Result<AcquiredImage, AcquireError> {
|
||||
let vk = swapchain.device.pointers();
|
||||
|
||||
let timeout_ns = if let Some(timeout) = timeout {
|
||||
|
@ -236,9 +236,9 @@ pub unsafe trait GpuFuture: DeviceOwned {
|
||||
///
|
||||
/// > **Note**: This is just a shortcut for the `Swapchain::present()` function.
|
||||
#[inline]
|
||||
fn then_swapchain_present(self, queue: Arc<Queue>, swapchain: Arc<Swapchain>,
|
||||
fn then_swapchain_present<W>(self, queue: Arc<Queue>, swapchain: Arc<Swapchain<W>>,
|
||||
image_index: usize)
|
||||
-> PresentFuture<Self>
|
||||
-> PresentFuture<Self,W>
|
||||
where Self: Sized
|
||||
{
|
||||
swapchain::present(swapchain, self, queue, image_index)
|
||||
@ -248,9 +248,9 @@ pub unsafe trait GpuFuture: DeviceOwned {
|
||||
///
|
||||
/// > **Note**: This is just a shortcut for the `Swapchain::present_incremental()` function.
|
||||
#[inline]
|
||||
fn then_swapchain_present_incremental(self, queue: Arc<Queue>, swapchain: Arc<Swapchain>,
|
||||
fn then_swapchain_present_incremental<W>(self, queue: Arc<Queue>, swapchain: Arc<Swapchain<W>>,
|
||||
image_index: usize, present_region: PresentRegion)
|
||||
-> PresentFuture<Self>
|
||||
-> PresentFuture<Self,W>
|
||||
where Self: Sized
|
||||
{
|
||||
swapchain::present_incremental(swapchain, self, queue, image_index, present_region)
|
||||
|
Loading…
Reference in New Issue
Block a user