Remove type parameter from Surface (#2036)

This commit is contained in:
Rua 2022-10-20 09:26:34 +02:00 committed by GitHub
parent 725c12c542
commit cdab36a322
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 543 additions and 532 deletions

View File

@ -46,8 +46,8 @@ use vulkano::{
}, },
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -145,6 +145,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -152,7 +153,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -257,7 +258,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -392,7 +394,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -20,8 +20,8 @@ use vulkano::{
instance::{Instance, InstanceCreateInfo}, instance::{Instance, InstanceCreateInfo},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -114,6 +114,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -121,7 +122,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -176,7 +177,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -298,7 +300,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {
images images

View File

@ -39,8 +39,8 @@ use vulkano::{
image::{view::ImageView, ImageUsage}, image::{view::ImageView, ImageUsage},
instance::{Instance, InstanceCreateInfo}, instance::{Instance, InstanceCreateInfo},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -49,7 +49,7 @@ use vulkano_win::VkSurfaceBuild;
use winit::{ use winit::{
event::{Event, WindowEvent}, event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop}, event_loop::{ControlFlow, EventLoop},
window::WindowBuilder, window::{Window, WindowBuilder},
}; };
mod frame; mod frame;
@ -135,6 +135,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let (swapchain, images) = Swapchain::new( let (swapchain, images) = Swapchain::new(
device.clone(), device.clone(),
@ -142,7 +143,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -194,7 +195,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }

View File

@ -47,8 +47,8 @@ mod linux {
render_pass::{Framebuffer, RenderPass, Subpass}, render_pass::{Framebuffer, RenderPass, Subpass},
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo}, sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
swapchain::{ swapchain::{
AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{ sync::{
now, ExternalSemaphoreHandleType, ExternalSemaphoreHandleTypes, FlushError, GpuFuture, now, ExternalSemaphoreHandleType, ExternalSemaphoreHandleTypes, FlushError, GpuFuture,
@ -291,9 +291,10 @@ mod linux {
previous_frame_end.as_mut().unwrap().cleanup_finished(); previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain { if recreate_swapchain {
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let (new_swapchain, new_images) = let (new_swapchain, new_images) =
match swapchain.recreate(SwapchainCreateInfo { match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
..swapchain.create_info() ..swapchain.create_info()
}) { }) {
Ok(r) => r, Ok(r) => r,
@ -407,8 +408,8 @@ mod linux {
) -> ( ) -> (
Arc<vulkano::device::Device>, Arc<vulkano::device::Device>,
Arc<vulkano::instance::Instance>, Arc<vulkano::instance::Instance>,
Arc<Swapchain<winit::window::Window>>, Arc<Swapchain>,
Arc<vulkano::swapchain::Surface<winit::window::Window>>, Arc<vulkano::swapchain::Surface>,
vulkano::pipeline::graphics::viewport::Viewport, vulkano::pipeline::graphics::viewport::Viewport,
Arc<Queue>, Arc<Queue>,
Arc<RenderPass>, Arc<RenderPass>,
@ -536,6 +537,7 @@ mod linux {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -543,7 +545,7 @@ mod linux {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -673,7 +675,7 @@ mod linux {
} }
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -42,8 +42,8 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo}, sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -136,6 +136,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -143,7 +144,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -378,7 +379,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -479,7 +481,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -40,8 +40,8 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo}, sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -134,6 +134,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -141,7 +142,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -305,7 +306,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -406,7 +408,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -49,8 +49,8 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo}, sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -140,6 +140,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -147,7 +148,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -318,7 +319,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -419,7 +421,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -52,8 +52,8 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
single_pass_renderpass, single_pass_renderpass,
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -154,6 +154,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -161,7 +162,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -335,7 +336,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -477,7 +479,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -37,8 +37,8 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
single_pass_renderpass, single_pass_renderpass,
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -151,6 +151,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -158,7 +159,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -332,7 +333,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -438,7 +440,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -40,8 +40,8 @@ use vulkano::{
}, },
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainAbstract, acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainCreateInfo, SwapchainCreationError, SwapchainPresentInfo, SwapchainCreationError, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -55,8 +55,8 @@ use winit::{
// A struct to contain resources related to a window // A struct to contain resources related to a window
struct WindowSurface { struct WindowSurface {
surface: Arc<Surface<Window>>, surface: Arc<Surface>,
swapchain: Arc<Swapchain<Window>>, swapchain: Arc<Swapchain>,
framebuffers: Vec<Arc<Framebuffer>>, framebuffers: Vec<Arc<Framebuffer>>,
recreate_swapchain: bool, recreate_swapchain: bool,
previous_frame_end: Option<Box<dyn GpuFuture>>, previous_frame_end: Option<Box<dyn GpuFuture>>,
@ -84,7 +84,8 @@ fn main() {
.build_vk_surface(&event_loop, instance.clone()) .build_vk_surface(&event_loop, instance.clone())
.unwrap(); .unwrap();
// Use the window's id as a means to access it from the hashmap // Use the window's id as a means to access it from the hashmap
let window_id = surface.window().id(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let window_id = window.id();
// Find the device and a queue. // Find the device and a queue.
// TODO: it is assumed the device, queue, and surface surface_capabilities are the same for all windows // TODO: it is assumed the device, queue, and surface surface_capabilities are the same for all windows
@ -155,6 +156,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -162,7 +164,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_caps.min_image_count, min_image_count: surface_caps.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -318,7 +320,8 @@ fn main() {
let surface = WindowBuilder::new() let surface = WindowBuilder::new()
.build_vk_surface(event_loop, instance.clone()) .build_vk_surface(event_loop, instance.clone())
.unwrap(); .unwrap();
let window_id = surface.window().id(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let window_id = window.id();
let (swapchain, images) = { let (swapchain, images) = {
let composite_alpha = surface_caps let composite_alpha = surface_caps
.supported_composite_alpha .supported_composite_alpha
@ -339,7 +342,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_caps.min_image_count, min_image_count: surface_caps.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -367,9 +370,15 @@ fn main() {
); );
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
window_surfaces window_surfaces.values().for_each(|s| {
.values() let window = s
.for_each(|s| s.surface.window().request_redraw()); .surface
.object()
.unwrap()
.downcast_ref::<Window>()
.unwrap();
window.request_redraw()
});
} }
Event::RedrawRequested(window_id) => { Event::RedrawRequested(window_id) => {
let WindowSurface { let WindowSurface {
@ -380,7 +389,8 @@ fn main() {
ref mut previous_frame_end, ref mut previous_frame_end,
} = window_surfaces.get_mut(&window_id).unwrap(); } = window_surfaces.get_mut(&window_id).unwrap();
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -475,7 +485,7 @@ fn main() {
} }
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -39,8 +39,8 @@ use vulkano::{
query::{QueryControlFlags, QueryPool, QueryPoolCreateInfo, QueryResultFlags, QueryType}, query::{QueryControlFlags, QueryPool, QueryPoolCreateInfo, QueryResultFlags, QueryType},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -130,6 +130,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -137,7 +138,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -343,7 +344,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -537,7 +539,7 @@ fn main() {
} }
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -38,8 +38,8 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo}, sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -130,6 +130,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -137,7 +138,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -297,7 +298,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -398,7 +400,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -45,8 +45,8 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
shader::ShaderModule, shader::ShaderModule,
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -145,6 +145,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -152,7 +153,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -273,7 +274,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -368,7 +370,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -45,8 +45,8 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo}, sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -146,6 +146,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -153,7 +154,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -435,7 +436,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -536,7 +538,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -39,9 +39,7 @@ use vulkano::{
GraphicsPipeline, PipelineBindPoint, GraphicsPipeline, PipelineBindPoint,
}, },
render_pass::{Framebuffer, FramebufferCreateInfo, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, Subpass},
swapchain::{ swapchain::{PresentMode, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo},
PresentMode, Swapchain, SwapchainAbstract, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{FenceSignalFuture, GpuFuture}, sync::{FenceSignalFuture, GpuFuture},
VulkanLibrary, VulkanLibrary,
}; };
@ -49,7 +47,7 @@ use vulkano_win::VkSurfaceBuild;
use winit::{ use winit::{
event::{Event, WindowEvent}, event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop}, event_loop::{ControlFlow, EventLoop},
window::WindowBuilder, window::{Window, WindowBuilder},
}; };
const WINDOW_WIDTH: u32 = 800; const WINDOW_WIDTH: u32 = 800;
@ -453,7 +451,8 @@ fn main() {
*control_flow = ControlFlow::Exit; *control_flow = ControlFlow::Exit;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }

View File

@ -37,8 +37,8 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
shader::ShaderModule, shader::ShaderModule,
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -132,6 +132,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -139,7 +140,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -244,7 +245,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -400,7 +402,7 @@ fn window_size_dependent_setup(
device: Arc<Device>, device: Arc<Device>,
vs: &ShaderModule, vs: &ShaderModule,
fs: &ShaderModule, fs: &ShaderModule,
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
) -> (Arc<GraphicsPipeline>, Vec<Arc<Framebuffer>>) { ) -> (Arc<GraphicsPipeline>, Vec<Arc<Framebuffer>>) {
let dimensions = images[0].dimensions().width_height(); let dimensions = images[0].dimensions().width_height();

View File

@ -45,8 +45,8 @@ use vulkano::{
}, },
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -238,6 +238,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -245,7 +246,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -380,7 +381,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -475,7 +477,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -40,8 +40,8 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
sampler::{Sampler, SamplerCreateInfo}, sampler::{Sampler, SamplerCreateInfo},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -136,6 +136,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new( Swapchain::new(
device.clone(), device.clone(),
@ -143,7 +144,7 @@ fn main() {
SwapchainCreateInfo { SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
image_format, image_format,
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
..ImageUsage::empty() ..ImageUsage::empty()
@ -306,7 +307,8 @@ fn main() {
recreate_swapchain = true; recreate_swapchain = true;
} }
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -407,7 +409,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -47,8 +47,8 @@ use vulkano::{
}, },
render_pass::{LoadOp, StoreOp}, render_pass::{LoadOp, StoreOp},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
Version, VulkanLibrary, Version, VulkanLibrary,
@ -234,6 +234,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
// Please take a look at the docs for the meaning of the parameters we didn't mention. // Please take a look at the docs for the meaning of the parameters we didn't mention.
Swapchain::new( Swapchain::new(
@ -257,7 +258,7 @@ fn main() {
// //
// Both of these cases need the swapchain to use the window dimensions, so we just // Both of these cases need the swapchain to use the window dimensions, so we just
// use that. // use that.
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
@ -460,10 +461,11 @@ fn main() {
// In this example that includes the swapchain, the framebuffers and the dynamic state viewport. // In this example that includes the swapchain, the framebuffers and the dynamic state viewport.
if recreate_swapchain { if recreate_swapchain {
// Get the new dimensions of the window. // Get the new dimensions of the window.
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let (new_swapchain, new_images) = let (new_swapchain, new_images) =
match swapchain.recreate(SwapchainCreateInfo { match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
..swapchain.create_info() ..swapchain.create_info()
}) { }) {
Ok(r) => r, Ok(r) => r,
@ -605,9 +607,9 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<ImageView<SwapchainImage<Window>>>> { ) -> Vec<Arc<ImageView<SwapchainImage>>> {
let dimensions = images[0].dimensions().width_height(); let dimensions = images[0].dimensions().width_height();
viewport.dimensions = [dimensions[0] as f32, dimensions[1] as f32]; viewport.dimensions = [dimensions[0] as f32, dimensions[1] as f32];

View File

@ -40,8 +40,8 @@ use vulkano::{
}, },
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass}, render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{ swapchain::{
acquire_next_image, AcquireError, Swapchain, SwapchainAbstract, SwapchainCreateInfo, acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
SwapchainCreationError, SwapchainPresentInfo, SwapchainPresentInfo,
}, },
sync::{self, FlushError, GpuFuture}, sync::{self, FlushError, GpuFuture},
VulkanLibrary, VulkanLibrary,
@ -214,6 +214,7 @@ fn main() {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
// Please take a look at the docs for the meaning of the parameters we didn't mention. // Please take a look at the docs for the meaning of the parameters we didn't mention.
Swapchain::new( Swapchain::new(
@ -237,7 +238,7 @@ fn main() {
// //
// Both of these cases need the swapchain to use the window dimensions, so we just // Both of these cases need the swapchain to use the window dimensions, so we just
// use that. // use that.
image_extent: surface.window().inner_size().into(), image_extent: window.inner_size().into(),
image_usage: ImageUsage { image_usage: ImageUsage {
color_attachment: true, color_attachment: true,
@ -459,7 +460,8 @@ fn main() {
Event::RedrawEventsCleared => { Event::RedrawEventsCleared => {
// Do not draw frame when screen dimensions are zero. // Do not draw frame when screen dimensions are zero.
// On Windows, this can occur from minimizing the application. // On Windows, this can occur from minimizing the application.
let dimensions = surface.window().inner_size(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let dimensions = window.inner_size();
if dimensions.width == 0 || dimensions.height == 0 { if dimensions.width == 0 || dimensions.height == 0 {
return; return;
} }
@ -615,7 +617,7 @@ fn main() {
/// This method is called once during initialization, then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage>],
render_pass: Arc<RenderPass>, render_pass: Arc<RenderPass>,
viewport: &mut Viewport, viewport: &mut Viewport,
) -> Vec<Arc<Framebuffer>> { ) -> Vec<Arc<Framebuffer>> {

View File

@ -26,7 +26,7 @@ use vulkano_win::create_surface_from_winit;
use winit::window::Window; use winit::window::Window;
/// Swapchain Image View. Your final render target typically. /// Swapchain Image View. Your final render target typically.
pub type SwapchainImageView = Arc<ImageView<SwapchainImage<Window>>>; pub type SwapchainImageView = Arc<ImageView<SwapchainImage>>;
/// Multipurpose image view /// Multipurpose image view
pub type DeviceImageView = Arc<ImageView<StorageImage>>; pub type DeviceImageView = Arc<ImageView<StorageImage>>;
@ -41,10 +41,10 @@ pub const DEFAULT_IMAGE_FORMAT: Format = Format::R8G8B8A8_UNORM;
/// ///
/// The intended usage of this struct is through [`crate::window::VulkanoWindows`]. /// The intended usage of this struct is through [`crate::window::VulkanoWindows`].
pub struct VulkanoWindowRenderer { pub struct VulkanoWindowRenderer {
surface: Arc<Surface<Window>>, surface: Arc<Surface>,
graphics_queue: Arc<Queue>, graphics_queue: Arc<Queue>,
compute_queue: Arc<Queue>, compute_queue: Arc<Queue>,
swapchain: Arc<Swapchain<Window>>, swapchain: Arc<Swapchain>,
final_views: Vec<SwapchainImageView>, final_views: Vec<SwapchainImageView>,
/// Additional image views that you can add which are resized with the window. /// Additional image views that you can add which are resized with the window.
/// Use associated functions to get access to these. /// Use associated functions to get access to these.
@ -67,7 +67,8 @@ impl VulkanoWindowRenderer {
) -> VulkanoWindowRenderer { ) -> VulkanoWindowRenderer {
// Create rendering surface from window // Create rendering surface from window
let surface = let surface =
create_surface_from_winit(window, vulkano_context.instance().clone()).unwrap(); create_surface_from_winit(Arc::new(window), vulkano_context.instance().clone())
.unwrap();
// Create swap chain & frame(s) to which we'll render // Create swap chain & frame(s) to which we'll render
let (swap_chain, final_views) = Self::create_swapchain( let (swap_chain, final_views) = Self::create_swapchain(
@ -97,10 +98,10 @@ impl VulkanoWindowRenderer {
/// can be modified with the `swapchain_create_info_modify` function passed as an input. /// can be modified with the `swapchain_create_info_modify` function passed as an input.
fn create_swapchain( fn create_swapchain(
device: Arc<Device>, device: Arc<Device>,
surface: Arc<Surface<Window>>, surface: Arc<Surface>,
window_descriptor: &WindowDescriptor, window_descriptor: &WindowDescriptor,
swapchain_create_info_modify: fn(&mut SwapchainCreateInfo), swapchain_create_info_modify: fn(&mut SwapchainCreateInfo),
) -> (Arc<Swapchain<Window>>, Vec<SwapchainImageView>) { ) -> (Arc<Swapchain>, Vec<SwapchainImageView>) {
let surface_capabilities = device let surface_capabilities = device
.physical_device() .physical_device()
.surface_capabilities(&surface, Default::default()) .surface_capabilities(&surface, Default::default())
@ -112,7 +113,8 @@ impl VulkanoWindowRenderer {
.unwrap()[0] .unwrap()[0]
.0, .0,
); );
let image_extent = surface.window().inner_size().into(); let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
let image_extent = window.inner_size().into();
let (swapchain, images) = Swapchain::new(device, surface, { let (swapchain, images) = Swapchain::new(device, surface, {
let mut create_info = SwapchainCreateInfo { let mut create_info = SwapchainCreateInfo {
min_image_count: surface_capabilities.min_image_count, min_image_count: surface_capabilities.min_image_count,
@ -179,14 +181,14 @@ impl VulkanoWindowRenderer {
/// Render target surface. /// Render target surface.
#[inline] #[inline]
pub fn surface(&self) -> Arc<Surface<Window>> { pub fn surface(&self) -> Arc<Surface> {
self.surface.clone() self.surface.clone()
} }
/// Winit window (you can manipulate window through this). /// Winit window (you can manipulate window through this).
#[inline] #[inline]
pub fn window(&self) -> &Window { pub fn window(&self) -> &Window {
self.surface.window() self.surface.object().unwrap().downcast_ref().unwrap()
} }
/// Size of the physical window. /// Size of the physical window.

View File

@ -5,7 +5,7 @@ use crate::get_metal_layer_macos;
use raw_window_handle::{ use raw_window_handle::{
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle, HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
}; };
use std::sync::Arc; use std::{any::Any, sync::Arc};
use vulkano::{ use vulkano::{
instance::Instance, instance::Instance,
swapchain::{Surface, SurfaceCreationError}, swapchain::{Surface, SurfaceCreationError},
@ -13,24 +13,21 @@ use vulkano::{
/// Creates a vulkan surface from a generic window /// Creates a vulkan surface from a generic window
/// which implements HasRawWindowHandle and thus can reveal the os-dependent handle. /// which implements HasRawWindowHandle and thus can reveal the os-dependent handle.
pub fn create_surface_from_handle<W>( pub fn create_surface_from_handle(
window: W, window: Arc<impl Any + Send + Sync + HasRawWindowHandle + HasRawDisplayHandle>,
instance: Arc<Instance>, instance: Arc<Instance>,
) -> Result<Arc<Surface<W>>, SurfaceCreationError> ) -> Result<Arc<Surface>, SurfaceCreationError> {
where
W: HasRawWindowHandle + HasRawDisplayHandle,
{
unsafe { unsafe {
match window.raw_window_handle() { match window.raw_window_handle() {
RawWindowHandle::AndroidNdk(h) => { RawWindowHandle::AndroidNdk(h) => {
Surface::from_android(instance, h.a_native_window, window) Surface::from_android(instance, h.a_native_window, Some(window))
} }
RawWindowHandle::UiKit(_h) => { RawWindowHandle::UiKit(_h) => {
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
{ {
// Ensure the layer is CAMetalLayer // Ensure the layer is CAMetalLayer
let layer = get_metal_layer_ios(_h.ui_view); let layer = get_metal_layer_ios(_h.ui_view);
Surface::from_ios(instance, layer, window) Surface::from_ios(instance, layer, Some(window))
} }
#[cfg(not(target_os = "ios"))] #[cfg(not(target_os = "ios"))]
{ {
@ -42,7 +39,7 @@ where
{ {
// Ensure the layer is CAMetalLayer // Ensure the layer is CAMetalLayer
let layer = get_metal_layer_macos(_h.ns_view); let layer = get_metal_layer_macos(_h.ns_view);
Surface::from_mac_os(instance, layer as *const (), window) Surface::from_mac_os(instance, layer as *const (), Some(window))
} }
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
{ {
@ -54,22 +51,24 @@ where
RawDisplayHandle::Wayland(d) => d, RawDisplayHandle::Wayland(d) => d,
_ => panic!("Invalid RawDisplayHandle"), _ => panic!("Invalid RawDisplayHandle"),
}; };
Surface::from_wayland(instance, d.display, h.surface, window) Surface::from_wayland(instance, d.display, h.surface, Some(window))
}
RawWindowHandle::Win32(h) => {
Surface::from_win32(instance, h.hinstance, h.hwnd, Some(window))
} }
RawWindowHandle::Win32(h) => Surface::from_win32(instance, h.hinstance, h.hwnd, window),
RawWindowHandle::Xcb(h) => { RawWindowHandle::Xcb(h) => {
let d = match window.raw_display_handle() { let d = match window.raw_display_handle() {
RawDisplayHandle::Xcb(d) => d, RawDisplayHandle::Xcb(d) => d,
_ => panic!("Invalid RawDisplayHandle"), _ => panic!("Invalid RawDisplayHandle"),
}; };
Surface::from_xcb(instance, d.connection, h.window, window) Surface::from_xcb(instance, d.connection, h.window, Some(window))
} }
RawWindowHandle::Xlib(h) => { RawWindowHandle::Xlib(h) => {
let d = match window.raw_display_handle() { let d = match window.raw_display_handle() {
RawDisplayHandle::Xlib(d) => d, RawDisplayHandle::Xlib(d) => d,
_ => panic!("Invalid RawDisplayHandle"), _ => panic!("Invalid RawDisplayHandle"),
}; };
Surface::from_xlib(instance, d.display, h.window, window) Surface::from_xlib(instance, d.display, h.window, Some(window))
} }
RawWindowHandle::Web(_) => unimplemented!(), RawWindowHandle::Web(_) => unimplemented!(),
_ => unimplemented!(), _ => unimplemented!(),

View File

@ -1,8 +1,6 @@
use std::{ use std::{
borrow::Borrow,
error::Error, error::Error,
fmt::{Display, Error as FmtError, Formatter}, fmt::{Display, Error as FmtError, Formatter},
rc::Rc,
sync::Arc, sync::Arc,
}; };
use vulkano::{ use vulkano::{
@ -36,13 +34,10 @@ pub fn required_extensions(library: &VulkanLibrary) -> InstanceExtensions {
/// Create a surface from a Winit window or a reference to it. The surface takes `W` to prevent it /// Create a surface from a Winit window or a reference to it. The surface takes `W` to prevent it
/// from being dropped before the surface. /// from being dropped before the surface.
pub fn create_surface_from_winit<W>( pub fn create_surface_from_winit(
window: W, window: Arc<Window>,
instance: Arc<Instance>, instance: Arc<Instance>,
) -> Result<Arc<Surface<W>>, SurfaceCreationError> ) -> Result<Arc<Surface>, SurfaceCreationError> {
where
W: SafeBorrow<Window>,
{
unsafe { winit_to_surface(instance, window) } unsafe { winit_to_surface(instance, window) }
} }
@ -51,7 +46,7 @@ pub trait VkSurfaceBuild<E> {
self, self,
event_loop: &EventLoopWindowTarget<E>, event_loop: &EventLoopWindowTarget<E>,
instance: Arc<Instance>, instance: Arc<Instance>,
) -> Result<Arc<Surface<Window>>, CreationError>; ) -> Result<Arc<Surface>, CreationError>;
} }
impl<E> VkSurfaceBuild<E> for WindowBuilder { impl<E> VkSurfaceBuild<E> for WindowBuilder {
@ -59,8 +54,8 @@ impl<E> VkSurfaceBuild<E> for WindowBuilder {
self, self,
event_loop: &EventLoopWindowTarget<E>, event_loop: &EventLoopWindowTarget<E>,
instance: Arc<Instance>, instance: Arc<Instance>,
) -> Result<Arc<Surface<Window>>, CreationError> { ) -> Result<Arc<Surface>, CreationError> {
let window = self.build(event_loop)?; let window = Arc::new(self.build(event_loop)?);
Ok(create_surface_from_winit(window, instance)?) Ok(create_surface_from_winit(window, instance)?)
} }
@ -110,14 +105,14 @@ impl From<WindowCreationError> for CreationError {
} }
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
unsafe fn winit_to_surface<W: SafeBorrow<Window>>( unsafe fn winit_to_surface(
instance: Arc<Instance>, instance: Arc<Instance>,
win: W, window: Arc<Window>,
) -> Result<Arc<Surface<W>>, SurfaceCreationError> { ) -> Result<Arc<Surface>, SurfaceCreationError> {
use raw_window_handle::HasRawWindowHandle; use raw_window_handle::HasRawWindowHandle;
use raw_window_handle::RawWindowHandle::AndroidNdk; use raw_window_handle::RawWindowHandle::AndroidNdk;
if let AndroidNdk(handle) = win.borrow().raw_window_handle() { if let AndroidNdk(handle) = window.raw_window_handle() {
Surface::from_android(instance, handle.a_native_window, win) Surface::from_android(instance, handle.a_native_window, Some(window))
} else { } else {
unreachable!("This should be unreachable if the target is android"); unreachable!("This should be unreachable if the target is android");
} }
@ -129,33 +124,32 @@ unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
not(target_os = "macos"), not(target_os = "macos"),
not(target_os = "ios") not(target_os = "ios")
))] ))]
unsafe fn winit_to_surface<W: SafeBorrow<Window>>( unsafe fn winit_to_surface(
instance: Arc<Instance>, instance: Arc<Instance>,
win: W, window: Arc<Window>,
) -> Result<Arc<Surface<W>>, SurfaceCreationError> { ) -> Result<Arc<Surface>, SurfaceCreationError> {
use winit::platform::unix::WindowExtUnix; use winit::platform::unix::WindowExtUnix;
match ( match (window.wayland_display(), window.wayland_surface()) {
win.borrow().wayland_display(), (Some(display), Some(surface)) => {
win.borrow().wayland_surface(), Surface::from_wayland(instance, display, surface, Some(window))
) { }
(Some(display), Some(surface)) => Surface::from_wayland(instance, display, surface, win),
_ => { _ => {
// No wayland display found, check if we can use xlib. // No wayland display found, check if we can use xlib.
// If not, we use xcb. // If not, we use xcb.
if instance.enabled_extensions().khr_xlib_surface { if instance.enabled_extensions().khr_xlib_surface {
Surface::from_xlib( Surface::from_xlib(
instance, instance,
win.borrow().xlib_display().unwrap(), window.xlib_display().unwrap(),
win.borrow().xlib_window().unwrap() as _, window.xlib_window().unwrap() as _,
win, Some(window),
) )
} else { } else {
Surface::from_xcb( Surface::from_xcb(
instance, instance,
win.borrow().xcb_connection().unwrap(), window.xcb_connection().unwrap(),
win.borrow().xlib_window().unwrap() as _, window.xlib_window().unwrap() as _,
win, Some(window),
) )
} }
} }
@ -196,13 +190,13 @@ pub(crate) unsafe fn get_metal_layer_macos(view: *mut std::ffi::c_void) -> *mut
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
unsafe fn winit_to_surface<W: SafeBorrow<Window>>( unsafe fn winit_to_surface(
instance: Arc<Instance>, instance: Arc<Instance>,
win: W, window: Arc<Window>,
) -> Result<Arc<Surface<W>>, SurfaceCreationError> { ) -> Result<Arc<Surface>, SurfaceCreationError> {
use winit::platform::macos::WindowExtMacOS; use winit::platform::macos::WindowExtMacOS;
let layer = get_metal_layer_macos(win.borrow().ns_view()); let layer = get_metal_layer_macos(window.ns_view());
Surface::from_mac_os(instance, layer as *const (), win) Surface::from_mac_os(instance, layer as *const (), Some(window))
} }
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -227,27 +221,27 @@ pub(crate) unsafe fn get_metal_layer_ios(view: *mut std::ffi::c_void) -> IOSMeta
} }
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
unsafe fn winit_to_surface<W: SafeBorrow<Window>>( unsafe fn winit_to_surface(
instance: Arc<Instance>, instance: Arc<Instance>,
win: W, window: Arc<Window>,
) -> Result<Arc<Surface<W>>, SurfaceCreationError> { ) -> Result<Arc<Surface>, SurfaceCreationError> {
use winit::platform::ios::WindowExtIOS; use winit::platform::ios::WindowExtIOS;
let layer = get_metal_layer_ios(win.borrow().ui_view()); let layer = get_metal_layer_ios(window.ui_view());
Surface::from_ios(instance, layer, win) Surface::from_ios(instance, layer, Some(window))
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
unsafe fn winit_to_surface<W: SafeBorrow<Window>>( unsafe fn winit_to_surface(
instance: Arc<Instance>, instance: Arc<Instance>,
win: W, window: Arc<Window>,
) -> Result<Arc<Surface<W>>, SurfaceCreationError> { ) -> Result<Arc<Surface>, SurfaceCreationError> {
use winit::platform::windows::WindowExtWindows; use winit::platform::windows::WindowExtWindows;
Surface::from_win32( Surface::from_win32(
instance, instance,
win.borrow().hinstance() as *const (), window.hinstance() as *const (),
win.borrow().hwnd() as *const (), window.hwnd() as *const (),
win, Some(window),
) )
} }
@ -262,14 +256,3 @@ use winit::{monitor::MonitorHandle, platform::windows::MonitorHandleExtWindows};
pub fn create_win32_monitor_from_winit(monitor_handle: &MonitorHandle) -> Win32Monitor { pub fn create_win32_monitor_from_winit(monitor_handle: &MonitorHandle) -> Win32Monitor {
unsafe { Win32Monitor::new(monitor_handle.hmonitor() as *const ()) } unsafe { Win32Monitor::new(monitor_handle.hmonitor() as *const ()) }
} }
/// An alternative to `Borrow<T>` with the requirement that all calls to
/// `borrow` return the same object.
pub unsafe trait SafeBorrow<T>: Borrow<T> {}
unsafe impl<T> SafeBorrow<T> for T {}
unsafe impl<'a, T> SafeBorrow<T> for &'a T {}
unsafe impl<'a, T> SafeBorrow<T> for &'a mut T {}
unsafe impl<T> SafeBorrow<T> for Rc<T> {}
unsafe impl<T> SafeBorrow<T> for Arc<T> {}
unsafe impl<T> SafeBorrow<T> for Box<T> {}

View File

@ -1478,9 +1478,9 @@ impl PhysicalDevice {
/// # Panics /// # Panics
/// ///
/// - Panics if the physical device and the surface don't belong to the same instance. /// - Panics if the physical device and the surface don't belong to the same instance.
pub fn surface_capabilities<W>( pub fn surface_capabilities(
&self, &self,
surface: &Surface<W>, surface: &Surface,
surface_info: SurfaceInfo, surface_info: SurfaceInfo,
) -> Result<SurfaceCapabilities, PhysicalDeviceError> { ) -> Result<SurfaceCapabilities, PhysicalDeviceError> {
self.validate_surface_capabilities(surface, &surface_info)?; self.validate_surface_capabilities(surface, &surface_info)?;
@ -1488,9 +1488,9 @@ impl PhysicalDevice {
unsafe { Ok(self.surface_capabilities_unchecked(surface, surface_info)?) } unsafe { Ok(self.surface_capabilities_unchecked(surface, surface_info)?) }
} }
fn validate_surface_capabilities<W>( fn validate_surface_capabilities(
&self, &self,
surface: &Surface<W>, surface: &Surface,
surface_info: &SurfaceInfo, surface_info: &SurfaceInfo,
) -> Result<(), PhysicalDeviceError> { ) -> Result<(), PhysicalDeviceError> {
if !(self if !(self
@ -1543,9 +1543,9 @@ impl PhysicalDevice {
} }
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn surface_capabilities_unchecked<W>( pub unsafe fn surface_capabilities_unchecked(
&self, &self,
surface: &Surface<W>, surface: &Surface,
surface_info: SurfaceInfo, surface_info: SurfaceInfo,
) -> Result<SurfaceCapabilities, VulkanError> { ) -> Result<SurfaceCapabilities, VulkanError> {
/* Input */ /* Input */
@ -1701,9 +1701,9 @@ impl PhysicalDevice {
/// # Panics /// # Panics
/// ///
/// - Panics if the physical device and the surface don't belong to the same instance. /// - Panics if the physical device and the surface don't belong to the same instance.
pub fn surface_formats<W>( pub fn surface_formats(
&self, &self,
surface: &Surface<W>, surface: &Surface,
surface_info: SurfaceInfo, surface_info: SurfaceInfo,
) -> Result<Vec<(Format, ColorSpace)>, PhysicalDeviceError> { ) -> Result<Vec<(Format, ColorSpace)>, PhysicalDeviceError> {
self.validate_surface_formats(surface, &surface_info)?; self.validate_surface_formats(surface, &surface_info)?;
@ -1711,9 +1711,9 @@ impl PhysicalDevice {
unsafe { Ok(self.surface_formats_unchecked(surface, surface_info)?) } unsafe { Ok(self.surface_formats_unchecked(surface, surface_info)?) }
} }
fn validate_surface_formats<W>( fn validate_surface_formats(
&self, &self,
surface: &Surface<W>, surface: &Surface,
surface_info: &SurfaceInfo, surface_info: &SurfaceInfo,
) -> Result<(), PhysicalDeviceError> { ) -> Result<(), PhysicalDeviceError> {
if !(self if !(self
@ -1780,9 +1780,9 @@ impl PhysicalDevice {
} }
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn surface_formats_unchecked<W>( pub unsafe fn surface_formats_unchecked(
&self, &self,
surface: &Surface<W>, surface: &Surface,
surface_info: SurfaceInfo, surface_info: SurfaceInfo,
) -> Result<Vec<(Format, ColorSpace)>, VulkanError> { ) -> Result<Vec<(Format, ColorSpace)>, VulkanError> {
surface.surface_formats.get_or_try_insert( surface.surface_formats.get_or_try_insert(
@ -1928,19 +1928,16 @@ impl PhysicalDevice {
/// # Panics /// # Panics
/// ///
/// - Panics if the physical device and the surface don't belong to the same instance. /// - Panics if the physical device and the surface don't belong to the same instance.
pub fn surface_present_modes<W>( pub fn surface_present_modes(
&self, &self,
surface: &Surface<W>, surface: &Surface,
) -> Result<impl Iterator<Item = PresentMode>, PhysicalDeviceError> { ) -> Result<impl Iterator<Item = PresentMode>, PhysicalDeviceError> {
self.validate_surface_present_modes(surface)?; self.validate_surface_present_modes(surface)?;
unsafe { Ok(self.surface_present_modes_unchecked(surface)?) } unsafe { Ok(self.surface_present_modes_unchecked(surface)?) }
} }
fn validate_surface_present_modes<W>( fn validate_surface_present_modes(&self, surface: &Surface) -> Result<(), PhysicalDeviceError> {
&self,
surface: &Surface<W>,
) -> Result<(), PhysicalDeviceError> {
if !self.instance.enabled_extensions().khr_surface { if !self.instance.enabled_extensions().khr_surface {
return Err(PhysicalDeviceError::RequirementNotMet { return Err(PhysicalDeviceError::RequirementNotMet {
required_for: "`surface_present_modes`", required_for: "`surface_present_modes`",
@ -1966,9 +1963,9 @@ impl PhysicalDevice {
} }
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn surface_present_modes_unchecked<W>( pub unsafe fn surface_present_modes_unchecked(
&self, &self,
surface: &Surface<W>, surface: &Surface,
) -> Result<impl Iterator<Item = PresentMode>, VulkanError> { ) -> Result<impl Iterator<Item = PresentMode>, VulkanError> {
surface surface
.surface_present_modes .surface_present_modes
@ -2020,20 +2017,20 @@ impl PhysicalDevice {
/// The results of this function are cached, so that future calls with the same arguments /// The results of this function are cached, so that future calls with the same arguments
/// do not need to make a call to the Vulkan API again. /// do not need to make a call to the Vulkan API again.
#[inline] #[inline]
pub fn surface_support<W>( pub fn surface_support(
&self, &self,
queue_family_index: u32, queue_family_index: u32,
surface: &Surface<W>, surface: &Surface,
) -> Result<bool, PhysicalDeviceError> { ) -> Result<bool, PhysicalDeviceError> {
self.validate_surface_support(queue_family_index, surface)?; self.validate_surface_support(queue_family_index, surface)?;
unsafe { Ok(self.surface_support_unchecked(queue_family_index, surface)?) } unsafe { Ok(self.surface_support_unchecked(queue_family_index, surface)?) }
} }
fn validate_surface_support<W>( fn validate_surface_support(
&self, &self,
queue_family_index: u32, queue_family_index: u32,
_surface: &Surface<W>, _surface: &Surface,
) -> Result<(), PhysicalDeviceError> { ) -> Result<(), PhysicalDeviceError> {
if !self.instance.enabled_extensions().khr_surface { if !self.instance.enabled_extensions().khr_surface {
return Err(PhysicalDeviceError::RequirementNotMet { return Err(PhysicalDeviceError::RequirementNotMet {
@ -2057,10 +2054,10 @@ impl PhysicalDevice {
} }
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn surface_support_unchecked<W>( pub unsafe fn surface_support_unchecked(
&self, &self,
queue_family_index: u32, queue_family_index: u32,
surface: &Surface<W>, surface: &Surface,
) -> Result<bool, VulkanError> { ) -> Result<bool, VulkanError> {
surface surface
.surface_support .surface_support

View File

@ -10,7 +10,7 @@
use super::{traits::ImageContent, ImageAccess, ImageDescriptorLayouts, ImageInner, ImageLayout}; use super::{traits::ImageContent, ImageAccess, ImageDescriptorLayouts, ImageInner, ImageLayout};
use crate::{ use crate::{
device::{Device, DeviceOwned}, device::{Device, DeviceOwned},
swapchain::{Swapchain, SwapchainAbstract}, swapchain::Swapchain,
OomError, OomError,
}; };
use std::{ use std::{
@ -32,22 +32,19 @@ use std::{
/// the screen. Once an image has been presented, it can no longer be used unless it is acquired /// the screen. Once an image has been presented, it can no longer be used unless it is acquired
/// again. /// again.
#[derive(Debug)] #[derive(Debug)]
pub struct SwapchainImage<W> { pub struct SwapchainImage {
swapchain: Arc<Swapchain<W>>, swapchain: Arc<Swapchain>,
image_index: u32, image_index: u32,
} }
impl<W> SwapchainImage<W> impl SwapchainImage {
where
W: Send + Sync,
{
/// Builds a `SwapchainImage` from raw components. /// Builds a `SwapchainImage` from raw components.
/// ///
/// This is an internal method that you shouldn't call. /// This is an internal method that you shouldn't call.
pub unsafe fn from_raw( pub unsafe fn from_raw(
swapchain: Arc<Swapchain<W>>, swapchain: Arc<Swapchain>,
image_index: u32, image_index: u32,
) -> Result<Arc<SwapchainImage<W>>, OomError> { ) -> Result<Arc<SwapchainImage>, OomError> {
Ok(Arc::new(SwapchainImage { Ok(Arc::new(SwapchainImage {
swapchain, swapchain,
image_index, image_index,
@ -55,7 +52,7 @@ where
} }
/// Returns the swapchain this image belongs to. /// Returns the swapchain this image belongs to.
pub fn swapchain(&self) -> &Arc<Swapchain<W>> { pub fn swapchain(&self) -> &Arc<Swapchain> {
&self.swapchain &self.swapchain
} }
@ -72,16 +69,13 @@ where
} }
} }
unsafe impl<W> DeviceOwned for SwapchainImage<W> { unsafe impl DeviceOwned for SwapchainImage {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Arc<Device> {
self.swapchain.device() self.swapchain.device()
} }
} }
unsafe impl<W> ImageAccess for SwapchainImage<W> unsafe impl ImageAccess for SwapchainImage {
where
W: Send + Sync,
{
fn inner(&self) -> ImageInner<'_> { fn inner(&self) -> ImageInner<'_> {
self.my_image() self.my_image()
} }
@ -112,30 +106,21 @@ where
} }
} }
unsafe impl<P, W> ImageContent<P> for SwapchainImage<W> unsafe impl<P> ImageContent<P> for SwapchainImage {
where
W: Send + Sync,
{
fn matches_format(&self) -> bool { fn matches_format(&self) -> bool {
true // FIXME: true // FIXME:
} }
} }
impl<W> PartialEq for SwapchainImage<W> impl PartialEq for SwapchainImage {
where
W: Send + Sync,
{
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.inner() == other.inner() self.inner() == other.inner()
} }
} }
impl<W> Eq for SwapchainImage<W> where W: Send + Sync {} impl Eq for SwapchainImage {}
impl<W> Hash for SwapchainImage<W> impl Hash for SwapchainImage {
where
W: Send + Sync,
{
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state); self.inner().hash(state);
} }

View File

@ -83,15 +83,18 @@
//! //!
//! # use std::sync::Arc; //! # use std::sync::Arc;
//! # struct Window(*const u32); //! # struct Window(*const u32);
//! # impl Window { //! # impl Window { fn hwnd(&self) -> *const u32 { self.0 } }
//! # fn hwnd(&self) -> *const u32 { self.0 } //! # unsafe impl Send for Window {}
//! # } //! # unsafe impl Sync for Window {}
//! #
//! # fn build_window() -> Arc<Window> { Arc::new(Window(ptr::null())) } //! # fn build_window() -> Arc<Window> { Arc::new(Window(ptr::null())) }
//! let window = build_window(); // Third-party function, not provided by vulkano //! let window = build_window(); // Third-party function, not provided by vulkano
//! let _surface = unsafe { //! let _surface = unsafe {
//! let hinstance: *const () = ptr::null(); // Windows-specific object //! let hinstance: *const () = ptr::null(); // Windows-specific object
//! Surface::from_win32(instance.clone(), hinstance, window.hwnd(), Arc::clone(&window)).unwrap() //! Surface::from_win32(
//! instance.clone(),
//! hinstance, window.hwnd(),
//! Some(window),
//! ).unwrap()
//! }; //! };
//! ``` //! ```
//! //!
@ -146,7 +149,7 @@
//! # use vulkano::device::Device; //! # use vulkano::device::Device;
//! # use vulkano::swapchain::Surface; //! # use vulkano::swapchain::Surface;
//! # use std::cmp::{max, min}; //! # use std::cmp::{max, min};
//! # fn choose_caps(device: Arc<Device>, surface: Arc<Surface<()>>) -> Result<(), Box<dyn Error>> { //! # fn choose_caps(device: Arc<Device>, surface: Arc<Surface>) -> Result<(), Box<dyn Error>> {
//! let surface_capabilities = device //! let surface_capabilities = device
//! .physical_device() //! .physical_device()
//! .surface_capabilities(&surface, Default::default())?; //! .surface_capabilities(&surface, Default::default())?;
@ -181,7 +184,7 @@
//! # use vulkano::format::Format; //! # use vulkano::format::Format;
//! # use vulkano::swapchain::{Surface, Swapchain, SurfaceTransform, PresentMode, CompositeAlpha, ColorSpace, FullScreenExclusive, SwapchainCreateInfo}; //! # use vulkano::swapchain::{Surface, Swapchain, SurfaceTransform, PresentMode, CompositeAlpha, ColorSpace, FullScreenExclusive, SwapchainCreateInfo};
//! # fn create_swapchain( //! # fn create_swapchain(
//! # device: Arc<Device>, surface: Arc<Surface<()>>, //! # device: Arc<Device>, surface: Arc<Surface>,
//! # min_image_count: u32, image_format: Format, image_extent: [u32; 2], //! # min_image_count: u32, image_format: Format, image_extent: [u32; 2],
//! # pre_transform: SurfaceTransform, composite_alpha: CompositeAlpha, //! # pre_transform: SurfaceTransform, composite_alpha: CompositeAlpha,
//! # present_mode: PresentMode, full_screen_exclusive: FullScreenExclusive //! # present_mode: PresentMode, full_screen_exclusive: FullScreenExclusive
@ -246,7 +249,7 @@
//! use vulkano::swapchain::{self, SwapchainPresentInfo}; //! use vulkano::swapchain::{self, SwapchainPresentInfo};
//! use vulkano::sync::GpuFuture; //! use vulkano::sync::GpuFuture;
//! # let queue: ::std::sync::Arc<::vulkano::device::Queue> = return; //! # let queue: ::std::sync::Arc<::vulkano::device::Queue> = return;
//! # let mut swapchain: ::std::sync::Arc<swapchain::Swapchain<()>> = return; //! # let mut swapchain: ::std::sync::Arc<swapchain::Swapchain> = return;
//! // let mut (swapchain, images) = Swapchain::new(...); //! // let mut (swapchain, images) = Swapchain::new(...);
//! loop { //! loop {
//! # let mut command_buffer: ::vulkano::command_buffer::PrimaryAutoCommandBuffer = return; //! # let mut command_buffer: ::vulkano::command_buffer::PrimaryAutoCommandBuffer = return;
@ -284,8 +287,8 @@
//! use vulkano::sync::GpuFuture; //! use vulkano::sync::GpuFuture;
//! //!
//! // let (swapchain, images) = Swapchain::new(...); //! // let (swapchain, images) = Swapchain::new(...);
//! # let mut swapchain: ::std::sync::Arc<::vulkano::swapchain::Swapchain<()>> = return; //! # let mut swapchain: ::std::sync::Arc<::vulkano::swapchain::Swapchain> = return;
//! # let mut images: Vec<::std::sync::Arc<::vulkano::image::SwapchainImage<()>>> = return; //! # let mut images: Vec<::std::sync::Arc<::vulkano::image::SwapchainImage>> = return;
//! # let queue: ::std::sync::Arc<::vulkano::device::Queue> = return; //! # let queue: ::std::sync::Arc<::vulkano::device::Queue> = return;
//! let mut recreate_swapchain = false; //! let mut recreate_swapchain = false;
//! //!
@ -333,8 +336,8 @@ pub use self::{
swapchain::{ swapchain::{
acquire_next_image, acquire_next_image_raw, present, wait_for_present, AcquireError, acquire_next_image, acquire_next_image_raw, present, wait_for_present, AcquireError,
AcquiredImage, FullScreenExclusive, FullScreenExclusiveError, PresentFuture, AcquiredImage, FullScreenExclusive, FullScreenExclusiveError, PresentFuture,
PresentWaitError, Swapchain, SwapchainAbstract, SwapchainAcquireFuture, PresentWaitError, Swapchain, SwapchainAcquireFuture, SwapchainCreateInfo,
SwapchainCreateInfo, SwapchainCreationError, Win32Monitor, SwapchainCreationError, Win32Monitor,
}, },
}; };
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -383,7 +386,7 @@ pub struct SwapchainPresentInfo {
/// The swapchain to present to. /// The swapchain to present to.
/// ///
/// There is no default value. /// There is no default value.
pub swapchain: Arc<dyn SwapchainAbstract>, pub swapchain: Arc<Swapchain>,
/// The index of the swapchain image to present to. /// The index of the swapchain image to present to.
/// ///
@ -423,7 +426,7 @@ pub struct SwapchainPresentInfo {
impl SwapchainPresentInfo { impl SwapchainPresentInfo {
/// Returns a `SwapchainPresentInfo` with the specified `swapchain` and `image_index`. /// Returns a `SwapchainPresentInfo` with the specified `swapchain` and `image_index`.
#[inline] #[inline]
pub fn swapchain_image_index(swapchain: Arc<dyn SwapchainAbstract>, image_index: u32) -> Self { pub fn swapchain_image_index(swapchain: Arc<Swapchain>, image_index: u32) -> Self {
Self { Self {
swapchain, swapchain,
image_index, image_index,
@ -438,7 +441,7 @@ impl SwapchainPresentInfo {
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct RectangleLayer { pub struct RectangleLayer {
/// Coordinates in pixels of the top-left hand corner of the rectangle. /// Coordinates in pixels of the top-left hand corner of the rectangle.
pub offset: [i32; 2], pub offset: [u32; 2],
/// Dimensions in pixels of the rectangle. /// Dimensions in pixels of the rectangle.
pub extent: [u32; 2], pub extent: [u32; 2],
@ -450,13 +453,9 @@ pub struct RectangleLayer {
impl RectangleLayer { impl RectangleLayer {
/// Returns true if this rectangle layer is compatible with swapchain. /// Returns true if this rectangle layer is compatible with swapchain.
#[inline] #[inline]
pub fn is_compatible_with(&self, swapchain: &dyn SwapchainAbstract) -> bool { pub fn is_compatible_with(&self, swapchain: &Swapchain) -> bool {
// FIXME negative offset is not disallowed by spec, but semantically should not be possible self.offset[0] + self.extent[0] <= swapchain.image_extent()[0]
debug_assert!(self.offset[0] >= 0); && self.offset[1] + self.extent[1] <= swapchain.image_extent()[1]
debug_assert!(self.offset[1] >= 0);
self.offset[0] as u32 + self.extent[0] <= swapchain.image_extent()[0]
&& self.offset[1] as u32 + self.extent[1] <= swapchain.image_extent()[1]
&& self.layer < swapchain.image_array_layers() && self.layer < swapchain.image_array_layers()
} }
} }
@ -466,8 +465,8 @@ impl From<&RectangleLayer> for ash::vk::RectLayerKHR {
fn from(val: &RectangleLayer) -> Self { fn from(val: &RectangleLayer) -> Self {
ash::vk::RectLayerKHR { ash::vk::RectLayerKHR {
offset: ash::vk::Offset2D { offset: ash::vk::Offset2D {
x: val.offset[0], x: val.offset[0] as i32,
y: val.offset[1], y: val.offset[1] as i32,
}, },
extent: ash::vk::Extent2D { extent: ash::vk::Extent2D {
width: val.extent[0], width: val.extent[0],

View File

@ -25,6 +25,7 @@ use crate::{
use objc::{class, msg_send, runtime::Object, sel, sel_impl}; use objc::{class, msg_send, runtime::Object, sel, sel_impl};
use std::{ use std::{
any::Any,
error::Error, error::Error,
fmt::{Debug, Display, Error as FmtError, Formatter}, fmt::{Debug, Display, Error as FmtError, Formatter},
hash::{Hash, Hasher}, hash::{Hash, Hasher},
@ -36,11 +37,11 @@ use std::{
/// Represents a surface on the screen. /// Represents a surface on the screen.
/// ///
/// Creating a `Surface` is platform-specific. /// Creating a `Surface` is platform-specific.
pub struct Surface<W> { pub struct Surface {
handle: ash::vk::SurfaceKHR, handle: ash::vk::SurfaceKHR,
instance: Arc<Instance>, instance: Arc<Instance>,
api: SurfaceApi, api: SurfaceApi,
window: W, object: Option<Arc<dyn Any + Send + Sync>>,
// If true, a swapchain has been associated to this surface, and that any new swapchain // If true, a swapchain has been associated to this surface, and that any new swapchain
// creation should be forbidden. // creation should be forbidden.
has_swapchain: AtomicBool, has_swapchain: AtomicBool,
@ -56,7 +57,7 @@ pub struct Surface<W> {
pub(crate) surface_support: OnceCache<(ash::vk::PhysicalDevice, u32), bool>, pub(crate) surface_support: OnceCache<(ash::vk::PhysicalDevice, u32), bool>,
} }
impl<W> Surface<W> { impl Surface {
/// Creates a `Surface` from a raw handle. /// Creates a `Surface` from a raw handle.
/// ///
/// # Safety /// # Safety
@ -64,18 +65,18 @@ impl<W> Surface<W> {
/// - `handle` must be a valid Vulkan object handle created from `instance`. /// - `handle` must be a valid Vulkan object handle created from `instance`.
/// - `handle` must have been created from `api`. /// - `handle` must have been created from `api`.
/// - The window object that `handle` was created from must outlive the created `Surface`. /// - The window object that `handle` was created from must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_handle( pub unsafe fn from_handle(
instance: Arc<Instance>, instance: Arc<Instance>,
handle: ash::vk::SurfaceKHR, handle: ash::vk::SurfaceKHR,
api: SurfaceApi, api: SurfaceApi,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Self { ) -> Self {
Surface { Surface {
handle, handle,
instance, instance,
api, api,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -91,10 +92,13 @@ impl<W> Surface<W> {
/// ///
/// Presenting to a headless surface does nothing, so this is mostly useless in itself. However, /// Presenting to a headless surface does nothing, so this is mostly useless in itself. However,
/// it may be useful for testing, and it is available for future extensions to layer on top of. /// it may be useful for testing, and it is available for future extensions to layer on top of.
pub fn headless(instance: Arc<Instance>, win: W) -> Result<Arc<Self>, SurfaceCreationError> { pub fn headless(
instance: Arc<Instance>,
object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_headless(&instance)?; Self::validate_headless(&instance)?;
unsafe { Ok(Self::headless_unchecked(instance, win)?) } unsafe { Ok(Self::headless_unchecked(instance, object)?) }
} }
fn validate_headless(instance: &Instance) -> Result<(), SurfaceCreationError> { fn validate_headless(instance: &Instance) -> Result<(), SurfaceCreationError> {
@ -114,7 +118,7 @@ impl<W> Surface<W> {
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn headless_unchecked( pub unsafe fn headless_unchecked(
instance: Arc<Instance>, instance: Arc<Instance>,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::HeadlessSurfaceCreateInfoEXT { let create_info = ash::vk::HeadlessSurfaceCreateInfoEXT {
flags: ash::vk::HeadlessSurfaceCreateFlagsEXT::empty(), flags: ash::vk::HeadlessSurfaceCreateFlagsEXT::empty(),
@ -139,7 +143,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::Headless, api: SurfaceApi::Headless,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -160,7 +164,7 @@ impl<W> Surface<W> {
pub fn from_display_plane( pub fn from_display_plane(
display_mode: &DisplayMode, display_mode: &DisplayMode,
plane: &DisplayPlane, plane: &DisplayPlane,
) -> Result<Arc<Surface<()>>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_display_plane(display_mode, plane)?; Self::validate_from_display_plane(display_mode, plane)?;
unsafe { Ok(Self::from_display_plane_unchecked(display_mode, plane)?) } unsafe { Ok(Self::from_display_plane_unchecked(display_mode, plane)?) }
@ -199,7 +203,7 @@ impl<W> Surface<W> {
pub unsafe fn from_display_plane_unchecked( pub unsafe fn from_display_plane_unchecked(
display_mode: &DisplayMode, display_mode: &DisplayMode,
plane: &DisplayPlane, plane: &DisplayPlane,
) -> Result<Arc<Surface<()>>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let instance = display_mode.display().physical_device().instance(); let instance = display_mode.display().physical_device().instance();
let create_info = ash::vk::DisplaySurfaceCreateInfoKHR { let create_info = ash::vk::DisplaySurfaceCreateInfoKHR {
@ -236,7 +240,7 @@ impl<W> Surface<W> {
handle, handle,
instance: instance.clone(), instance: instance.clone(),
api: SurfaceApi::DisplayPlane, api: SurfaceApi::DisplayPlane,
window: (), object: None,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -254,20 +258,24 @@ impl<W> Surface<W> {
/// ///
/// - `window` must be a valid Android `ANativeWindow` handle. /// - `window` must be a valid Android `ANativeWindow` handle.
/// - The object referred to by `window` must outlive the created `Surface`. /// - The object referred to by `window` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_android<T>( pub unsafe fn from_android<W>(
instance: Arc<Instance>, instance: Arc<Instance>,
window: *const T, window: *const W,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_android(&instance, window)?; Self::validate_from_android(&instance, window)?;
Ok(Self::from_android_unchecked(instance, window, win)?) Ok(Self::from_android_unchecked(
instance,
window,
object,
)?)
} }
fn validate_from_android<T>( fn validate_from_android<W>(
instance: &Instance, instance: &Instance,
_window: *const T, _window: *const W,
) -> Result<(), SurfaceCreationError> { ) -> Result<(), SurfaceCreationError> {
if !instance.enabled_extensions().khr_android_surface { if !instance.enabled_extensions().khr_android_surface {
return Err(SurfaceCreationError::RequirementNotMet { return Err(SurfaceCreationError::RequirementNotMet {
@ -286,10 +294,10 @@ impl<W> Surface<W> {
} }
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn from_android_unchecked<T>( pub unsafe fn from_android_unchecked<W>(
instance: Arc<Instance>, instance: Arc<Instance>,
window: *const T, window: *const W,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::AndroidSurfaceCreateInfoKHR { let create_info = ash::vk::AndroidSurfaceCreateInfoKHR {
flags: ash::vk::AndroidSurfaceCreateFlagsKHR::empty(), flags: ash::vk::AndroidSurfaceCreateFlagsKHR::empty(),
@ -315,7 +323,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::Android, api: SurfaceApi::Android,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -334,16 +342,21 @@ impl<W> Surface<W> {
/// - `dfb` must be a valid DirectFB `IDirectFB` handle. /// - `dfb` must be a valid DirectFB `IDirectFB` handle.
/// - `surface` must be a valid DirectFB `IDirectFBSurface` handle. /// - `surface` must be a valid DirectFB `IDirectFBSurface` handle.
/// - The object referred to by `dfb` and `surface` must outlive the created `Surface`. /// - The object referred to by `dfb` and `surface` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_directfb<D, S>( pub unsafe fn from_directfb<D, S>(
instance: Arc<Instance>, instance: Arc<Instance>,
dfb: *const D, dfb: *const D,
surface: *const S, surface: *const S,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_directfb(&instance, dfb, surface)?; Self::validate_from_directfb(&instance, dfb, surface)?;
Ok(Self::from_directfb_unchecked(instance, dfb, surface, win)?) Ok(Self::from_directfb_unchecked(
instance,
dfb,
surface,
object,
)?)
} }
fn validate_from_directfb<D, S>( fn validate_from_directfb<D, S>(
@ -375,7 +388,7 @@ impl<W> Surface<W> {
instance: Arc<Instance>, instance: Arc<Instance>,
dfb: *const D, dfb: *const D,
surface: *const S, surface: *const S,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::DirectFBSurfaceCreateInfoEXT { let create_info = ash::vk::DirectFBSurfaceCreateInfoEXT {
flags: ash::vk::DirectFBSurfaceCreateFlagsEXT::empty(), flags: ash::vk::DirectFBSurfaceCreateFlagsEXT::empty(),
@ -402,7 +415,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::DirectFB, api: SurfaceApi::DirectFB,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -420,18 +433,18 @@ impl<W> Surface<W> {
/// ///
/// - `image_pipe_handle` must be a valid Fuchsia `zx_handle_t` handle. /// - `image_pipe_handle` must be a valid Fuchsia `zx_handle_t` handle.
/// - The object referred to by `image_pipe_handle` must outlive the created `Surface`. /// - The object referred to by `image_pipe_handle` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_fuchsia_image_pipe( pub unsafe fn from_fuchsia_image_pipe(
instance: Arc<Instance>, instance: Arc<Instance>,
image_pipe_handle: ash::vk::zx_handle_t, image_pipe_handle: ash::vk::zx_handle_t,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_fuchsia_image_pipe(&instance, image_pipe_handle)?; Self::validate_from_fuchsia_image_pipe(&instance, image_pipe_handle)?;
Ok(Self::from_fuchsia_image_pipe_unchecked( Ok(Self::from_fuchsia_image_pipe_unchecked(
instance, instance,
image_pipe_handle, image_pipe_handle,
win, object,
)?) )?)
} }
@ -459,7 +472,7 @@ impl<W> Surface<W> {
pub unsafe fn from_fuchsia_image_pipe_unchecked( pub unsafe fn from_fuchsia_image_pipe_unchecked(
instance: Arc<Instance>, instance: Arc<Instance>,
image_pipe_handle: ash::vk::zx_handle_t, image_pipe_handle: ash::vk::zx_handle_t,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::ImagePipeSurfaceCreateInfoFUCHSIA { let create_info = ash::vk::ImagePipeSurfaceCreateInfoFUCHSIA {
flags: ash::vk::ImagePipeSurfaceCreateFlagsFUCHSIA::empty(), flags: ash::vk::ImagePipeSurfaceCreateFlagsFUCHSIA::empty(),
@ -486,7 +499,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::FuchsiaImagePipe, api: SurfaceApi::FuchsiaImagePipe,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -504,18 +517,18 @@ impl<W> Surface<W> {
/// ///
/// - `stream_descriptor` must be a valid Google Games Platform `GgpStreamDescriptor` handle. /// - `stream_descriptor` must be a valid Google Games Platform `GgpStreamDescriptor` handle.
/// - The object referred to by `stream_descriptor` must outlive the created `Surface`. /// - The object referred to by `stream_descriptor` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_ggp_stream_descriptor( pub unsafe fn from_ggp_stream_descriptor(
instance: Arc<Instance>, instance: Arc<Instance>,
stream_descriptor: ash::vk::GgpStreamDescriptor, stream_descriptor: ash::vk::GgpStreamDescriptor,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_ggp_stream_descriptor(&instance, stream_descriptor)?; Self::validate_from_ggp_stream_descriptor(&instance, stream_descriptor)?;
Ok(Self::from_ggp_stream_descriptor_unchecked( Ok(Self::from_ggp_stream_descriptor_unchecked(
instance, instance,
stream_descriptor, stream_descriptor,
win, object,
)?) )?)
} }
@ -543,7 +556,7 @@ impl<W> Surface<W> {
pub unsafe fn from_ggp_stream_descriptor_unchecked( pub unsafe fn from_ggp_stream_descriptor_unchecked(
instance: Arc<Instance>, instance: Arc<Instance>,
stream_descriptor: ash::vk::GgpStreamDescriptor, stream_descriptor: ash::vk::GgpStreamDescriptor,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::StreamDescriptorSurfaceCreateInfoGGP { let create_info = ash::vk::StreamDescriptorSurfaceCreateInfoGGP {
flags: ash::vk::StreamDescriptorSurfaceCreateFlagsGGP::empty(), flags: ash::vk::StreamDescriptorSurfaceCreateFlagsGGP::empty(),
@ -570,7 +583,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::GgpStreamDescriptor, api: SurfaceApi::GgpStreamDescriptor,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -588,17 +601,21 @@ impl<W> Surface<W> {
/// ///
/// - `metal_layer` must be a valid `IOSMetalLayer` handle. /// - `metal_layer` must be a valid `IOSMetalLayer` handle.
/// - The object referred to by `metal_layer` must outlive the created `Surface`. /// - The object referred to by `metal_layer` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
/// - The `UIView` must be backed by a `CALayer` instance of type `CAMetalLayer`. /// - The `UIView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
pub unsafe fn from_ios( pub unsafe fn from_ios(
instance: Arc<Instance>, instance: Arc<Instance>,
metal_layer: IOSMetalLayer, metal_layer: IOSMetalLayer,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_ios(&instance, &metal_layer)?; Self::validate_from_ios(&instance, &metal_layer)?;
Ok(Self::from_ios_unchecked(instance, metal_layer, win)?) Ok(Self::from_ios_unchecked(
instance,
metal_layer,
object,
)?)
} }
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -630,7 +647,7 @@ impl<W> Surface<W> {
pub unsafe fn from_ios_unchecked( pub unsafe fn from_ios_unchecked(
instance: Arc<Instance>, instance: Arc<Instance>,
metal_layer: IOSMetalLayer, metal_layer: IOSMetalLayer,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::IOSSurfaceCreateInfoMVK { let create_info = ash::vk::IOSSurfaceCreateInfoMVK {
flags: ash::vk::IOSSurfaceCreateFlagsMVK::empty(), flags: ash::vk::IOSSurfaceCreateFlagsMVK::empty(),
@ -656,7 +673,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::Ios, api: SurfaceApi::Ios,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
metal_layer, metal_layer,
@ -673,23 +690,23 @@ impl<W> Surface<W> {
/// ///
/// - `view` must be a valid `CAMetalLayer` or `NSView` handle. /// - `view` must be a valid `CAMetalLayer` or `NSView` handle.
/// - The object referred to by `view` must outlive the created `Surface`. /// - The object referred to by `view` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
/// - The `NSView` must be backed by a `CALayer` instance of type `CAMetalLayer`. /// - The `NSView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub unsafe fn from_mac_os<T>( pub unsafe fn from_mac_os<V>(
instance: Arc<Instance>, instance: Arc<Instance>,
view: *const T, view: *const V,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_mac_os(&instance, view)?; Self::validate_from_mac_os(&instance, view)?;
Ok(Self::from_mac_os_unchecked(instance, view, win)?) Ok(Self::from_mac_os_unchecked(instance, view, object)?)
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
fn validate_from_mac_os<T>( fn validate_from_mac_os<V>(
instance: &Instance, instance: &Instance,
_view: *const T, _view: *const V,
) -> Result<(), SurfaceCreationError> { ) -> Result<(), SurfaceCreationError> {
if !instance.enabled_extensions().mvk_macos_surface { if !instance.enabled_extensions().mvk_macos_surface {
return Err(SurfaceCreationError::RequirementNotMet { return Err(SurfaceCreationError::RequirementNotMet {
@ -712,10 +729,10 @@ impl<W> Surface<W> {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn from_mac_os_unchecked<T>( pub unsafe fn from_mac_os_unchecked<V>(
instance: Arc<Instance>, instance: Arc<Instance>,
view: *const T, view: *const V,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::MacOSSurfaceCreateInfoMVK { let create_info = ash::vk::MacOSSurfaceCreateInfoMVK {
flags: ash::vk::MacOSSurfaceCreateFlagsMVK::empty(), flags: ash::vk::MacOSSurfaceCreateFlagsMVK::empty(),
@ -741,7 +758,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::MacOs, api: SurfaceApi::MacOs,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -759,20 +776,20 @@ impl<W> Surface<W> {
/// ///
/// - `layer` must be a valid Metal `CAMetalLayer` handle. /// - `layer` must be a valid Metal `CAMetalLayer` handle.
/// - The object referred to by `layer` must outlive the created `Surface`. /// - The object referred to by `layer` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_metal<T>( pub unsafe fn from_metal<L>(
instance: Arc<Instance>, instance: Arc<Instance>,
layer: *const T, layer: *const L,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_metal(&instance, layer)?; Self::validate_from_metal(&instance, layer)?;
Ok(Self::from_metal_unchecked(instance, layer, win)?) Ok(Self::from_metal_unchecked(instance, layer, object)?)
} }
fn validate_from_metal<T>( fn validate_from_metal<L>(
instance: &Instance, instance: &Instance,
_layer: *const T, _layer: *const L,
) -> Result<(), SurfaceCreationError> { ) -> Result<(), SurfaceCreationError> {
if !instance.enabled_extensions().ext_metal_surface { if !instance.enabled_extensions().ext_metal_surface {
return Err(SurfaceCreationError::RequirementNotMet { return Err(SurfaceCreationError::RequirementNotMet {
@ -788,10 +805,10 @@ impl<W> Surface<W> {
} }
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn from_metal_unchecked<T>( pub unsafe fn from_metal_unchecked<L>(
instance: Arc<Instance>, instance: Arc<Instance>,
layer: *const T, layer: *const L,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::MetalSurfaceCreateInfoEXT { let create_info = ash::vk::MetalSurfaceCreateInfoEXT {
flags: ash::vk::MetalSurfaceCreateFlagsEXT::empty(), flags: ash::vk::MetalSurfaceCreateFlagsEXT::empty(),
@ -817,7 +834,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::Metal, api: SurfaceApi::Metal,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -836,24 +853,27 @@ impl<W> Surface<W> {
/// - `context` must be a valid QNX Screen `_screen_context` handle. /// - `context` must be a valid QNX Screen `_screen_context` handle.
/// - `window` must be a valid QNX Screen `_screen_window` handle. /// - `window` must be a valid QNX Screen `_screen_window` handle.
/// - The object referred to by `window` must outlive the created `Surface`. /// - The object referred to by `window` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_qnx_screen<T, U>( pub unsafe fn from_qnx_screen<C, W>(
instance: Arc<Instance>, instance: Arc<Instance>,
context: *const T, context: *const C,
window: *const U, window: *const W,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_qnx_screen(&instance, context, window)?; Self::validate_from_qnx_screen(&instance, context, window)?;
Ok(Self::from_qnx_screen_unchecked( Ok(Self::from_qnx_screen_unchecked(
instance, context, window, win, instance,
context,
window,
object,
)?) )?)
} }
fn validate_from_qnx_screen<T, U>( fn validate_from_qnx_screen<C, W>(
instance: &Instance, instance: &Instance,
_context: *const T, _context: *const C,
_window: *const U, _window: *const W,
) -> Result<(), SurfaceCreationError> { ) -> Result<(), SurfaceCreationError> {
if !instance.enabled_extensions().qnx_screen_surface { if !instance.enabled_extensions().qnx_screen_surface {
return Err(SurfaceCreationError::RequirementNotMet { return Err(SurfaceCreationError::RequirementNotMet {
@ -875,11 +895,11 @@ impl<W> Surface<W> {
} }
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn from_qnx_screen_unchecked<T, U>( pub unsafe fn from_qnx_screen_unchecked<C, W>(
instance: Arc<Instance>, instance: Arc<Instance>,
context: *const T, context: *const C,
window: *const U, window: *const W,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::ScreenSurfaceCreateInfoQNX { let create_info = ash::vk::ScreenSurfaceCreateInfoQNX {
flags: ash::vk::ScreenSurfaceCreateFlagsQNX::empty(), flags: ash::vk::ScreenSurfaceCreateFlagsQNX::empty(),
@ -906,7 +926,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::Qnx, api: SurfaceApi::Qnx,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -924,20 +944,20 @@ impl<W> Surface<W> {
/// ///
/// - `window` must be a valid `nn::vi::NativeWindowHandle` handle. /// - `window` must be a valid `nn::vi::NativeWindowHandle` handle.
/// - The object referred to by `window` must outlive the created `Surface`. /// - The object referred to by `window` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_vi<T>( pub unsafe fn from_vi<W>(
instance: Arc<Instance>, instance: Arc<Instance>,
window: *const T, window: *const W,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_vi(&instance, window)?; Self::validate_from_vi(&instance, window)?;
Ok(Self::from_vi_unchecked(instance, window, win)?) Ok(Self::from_vi_unchecked(instance, window, object)?)
} }
fn validate_from_vi<T>( fn validate_from_vi<W>(
instance: &Instance, instance: &Instance,
_window: *const T, _window: *const W,
) -> Result<(), SurfaceCreationError> { ) -> Result<(), SurfaceCreationError> {
if !instance.enabled_extensions().nn_vi_surface { if !instance.enabled_extensions().nn_vi_surface {
return Err(SurfaceCreationError::RequirementNotMet { return Err(SurfaceCreationError::RequirementNotMet {
@ -956,10 +976,10 @@ impl<W> Surface<W> {
} }
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn from_vi_unchecked<T>( pub unsafe fn from_vi_unchecked<W>(
instance: Arc<Instance>, instance: Arc<Instance>,
window: *const T, window: *const W,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::ViSurfaceCreateInfoNN { let create_info = ash::vk::ViSurfaceCreateInfoNN {
flags: ash::vk::ViSurfaceCreateFlagsNN::empty(), flags: ash::vk::ViSurfaceCreateFlagsNN::empty(),
@ -985,7 +1005,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::Vi, api: SurfaceApi::Vi,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -1006,17 +1026,20 @@ impl<W> Surface<W> {
/// - `display` must be a valid Wayland `wl_display` handle. /// - `display` must be a valid Wayland `wl_display` handle.
/// - `surface` must be a valid Wayland `wl_surface` handle. /// - `surface` must be a valid Wayland `wl_surface` handle.
/// - The objects referred to by `display` and `surface` must outlive the created `Surface`. /// - The objects referred to by `display` and `surface` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_wayland<D, S>( pub unsafe fn from_wayland<D, S>(
instance: Arc<Instance>, instance: Arc<Instance>,
display: *const D, display: *const D,
surface: *const S, surface: *const S,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_wayland(&instance, display, surface)?; Self::validate_from_wayland(&instance, display, surface)?;
Ok(Self::from_wayland_unchecked( Ok(Self::from_wayland_unchecked(
instance, display, surface, win, instance,
display,
surface,
object,
)?) )?)
} }
@ -1049,7 +1072,7 @@ impl<W> Surface<W> {
instance: Arc<Instance>, instance: Arc<Instance>,
display: *const D, display: *const D,
surface: *const S, surface: *const S,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::WaylandSurfaceCreateInfoKHR { let create_info = ash::vk::WaylandSurfaceCreateInfoKHR {
flags: ash::vk::WaylandSurfaceCreateFlagsKHR::empty(), flags: ash::vk::WaylandSurfaceCreateFlagsKHR::empty(),
@ -1076,7 +1099,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::Wayland, api: SurfaceApi::Wayland,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -1097,22 +1120,27 @@ impl<W> Surface<W> {
/// - `hinstance` must be a valid Win32 `HINSTANCE` handle. /// - `hinstance` must be a valid Win32 `HINSTANCE` handle.
/// - `hwnd` must be a valid Win32 `HWND` handle. /// - `hwnd` must be a valid Win32 `HWND` handle.
/// - The objects referred to by `hwnd` and `hinstance` must outlive the created `Surface`. /// - The objects referred to by `hwnd` and `hinstance` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_win32<T, U>( pub unsafe fn from_win32<I, W>(
instance: Arc<Instance>, instance: Arc<Instance>,
hinstance: *const T, hinstance: *const I,
hwnd: *const U, hwnd: *const W,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_win32(&instance, hinstance, hwnd)?; Self::validate_from_win32(&instance, hinstance, hwnd)?;
Ok(Self::from_win32_unchecked(instance, hinstance, hwnd, win)?) Ok(Self::from_win32_unchecked(
instance,
hinstance,
hwnd,
object,
)?)
} }
fn validate_from_win32<T, U>( fn validate_from_win32<I, W>(
instance: &Instance, instance: &Instance,
_hinstance: *const T, _hinstance: *const I,
_hwnd: *const U, _hwnd: *const W,
) -> Result<(), SurfaceCreationError> { ) -> Result<(), SurfaceCreationError> {
if !instance.enabled_extensions().khr_win32_surface { if !instance.enabled_extensions().khr_win32_surface {
return Err(SurfaceCreationError::RequirementNotMet { return Err(SurfaceCreationError::RequirementNotMet {
@ -1134,11 +1162,11 @@ impl<W> Surface<W> {
} }
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn from_win32_unchecked<T, U>( pub unsafe fn from_win32_unchecked<I, W>(
instance: Arc<Instance>, instance: Arc<Instance>,
hinstance: *const T, hinstance: *const I,
hwnd: *const U, hwnd: *const W,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::Win32SurfaceCreateInfoKHR { let create_info = ash::vk::Win32SurfaceCreateInfoKHR {
flags: ash::vk::Win32SurfaceCreateFlagsKHR::empty(), flags: ash::vk::Win32SurfaceCreateFlagsKHR::empty(),
@ -1165,7 +1193,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::Win32, api: SurfaceApi::Win32,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -1186,16 +1214,21 @@ impl<W> Surface<W> {
/// - `connection` must be a valid X11 `xcb_connection_t` handle. /// - `connection` must be a valid X11 `xcb_connection_t` handle.
/// - `window` must be a valid X11 `xcb_window_t` handle. /// - `window` must be a valid X11 `xcb_window_t` handle.
/// - The objects referred to by `connection` and `window` must outlive the created `Surface`. /// - The objects referred to by `connection` and `window` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_xcb<C>( pub unsafe fn from_xcb<C>(
instance: Arc<Instance>, instance: Arc<Instance>,
connection: *const C, connection: *const C,
window: ash::vk::xcb_window_t, window: ash::vk::xcb_window_t,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_xcb(&instance, connection, window)?; Self::validate_from_xcb(&instance, connection, window)?;
Ok(Self::from_xcb_unchecked(instance, connection, window, win)?) Ok(Self::from_xcb_unchecked(
instance,
connection,
window,
object,
)?)
} }
fn validate_from_xcb<C>( fn validate_from_xcb<C>(
@ -1227,7 +1260,7 @@ impl<W> Surface<W> {
instance: Arc<Instance>, instance: Arc<Instance>,
connection: *const C, connection: *const C,
window: ash::vk::xcb_window_t, window: ash::vk::xcb_window_t,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::XcbSurfaceCreateInfoKHR { let create_info = ash::vk::XcbSurfaceCreateInfoKHR {
flags: ash::vk::XcbSurfaceCreateFlagsKHR::empty(), flags: ash::vk::XcbSurfaceCreateFlagsKHR::empty(),
@ -1254,7 +1287,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::Xcb, api: SurfaceApi::Xcb,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -1275,16 +1308,21 @@ impl<W> Surface<W> {
/// - `display` must be a valid Xlib `Display` handle. /// - `display` must be a valid Xlib `Display` handle.
/// - `window` must be a valid Xlib `Window` handle. /// - `window` must be a valid Xlib `Window` handle.
/// - The objects referred to by `display` and `window` must outlive the created `Surface`. /// - The objects referred to by `display` and `window` must outlive the created `Surface`.
/// The `win` parameter can be used to ensure this. /// The `object` parameter can be used to ensure this.
pub unsafe fn from_xlib<D>( pub unsafe fn from_xlib<D>(
instance: Arc<Instance>, instance: Arc<Instance>,
display: *const D, display: *const D,
window: ash::vk::Window, window: ash::vk::Window,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, SurfaceCreationError> { ) -> Result<Arc<Self>, SurfaceCreationError> {
Self::validate_from_xlib(&instance, display, window)?; Self::validate_from_xlib(&instance, display, window)?;
Ok(Self::from_xlib_unchecked(instance, display, window, win)?) Ok(Self::from_xlib_unchecked(
instance,
display,
window,
object,
)?)
} }
fn validate_from_xlib<D>( fn validate_from_xlib<D>(
@ -1316,7 +1354,7 @@ impl<W> Surface<W> {
instance: Arc<Instance>, instance: Arc<Instance>,
display: *const D, display: *const D,
window: ash::vk::Window, window: ash::vk::Window,
win: W, object: Option<Arc<dyn Any + Send + Sync>>,
) -> Result<Arc<Self>, VulkanError> { ) -> Result<Arc<Self>, VulkanError> {
let create_info = ash::vk::XlibSurfaceCreateInfoKHR { let create_info = ash::vk::XlibSurfaceCreateInfoKHR {
flags: ash::vk::XlibSurfaceCreateFlagsKHR::empty(), flags: ash::vk::XlibSurfaceCreateFlagsKHR::empty(),
@ -1343,7 +1381,7 @@ impl<W> Surface<W> {
handle, handle,
instance, instance,
api: SurfaceApi::Xlib, api: SurfaceApi::Xlib,
window: win, object,
has_swapchain: AtomicBool::new(false), has_swapchain: AtomicBool::new(false),
#[cfg(target_os = "ios")] #[cfg(target_os = "ios")]
@ -1356,18 +1394,22 @@ impl<W> Surface<W> {
} }
/// Returns the instance this surface was created with. /// Returns the instance this surface was created with.
#[inline]
pub fn instance(&self) -> &Arc<Instance> { pub fn instance(&self) -> &Arc<Instance> {
&self.instance &self.instance
} }
/// Returns the windowing API that was used to construct the surface. /// Returns the windowing API that was used to construct the surface.
#[inline]
pub fn api(&self) -> SurfaceApi { pub fn api(&self) -> SurfaceApi {
self.api self.api
} }
/// Returns a reference to the `W` type parameter that was passed when creating the surface. /// Returns a reference to the `object` parameter that was passed when creating the
pub fn window(&self) -> &W { /// surface.
&self.window #[inline]
pub fn object(&self) -> Option<&Arc<dyn Any + Send + Sync>> {
self.object.as_ref()
} }
/// Resizes the sublayer bounds on iOS. /// Resizes the sublayer bounds on iOS.
@ -1388,7 +1430,7 @@ impl<W> Surface<W> {
} }
} }
impl<W> Drop for Surface<W> { impl Drop for Surface {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
let fns = self.instance.fns(); let fns = self.instance.fns();
@ -1401,7 +1443,7 @@ impl<W> Drop for Surface<W> {
} }
} }
unsafe impl<W> VulkanObject for Surface<W> { unsafe impl VulkanObject for Surface {
type Object = ash::vk::SurfaceKHR; type Object = ash::vk::SurfaceKHR;
fn internal_object(&self) -> ash::vk::SurfaceKHR { fn internal_object(&self) -> ash::vk::SurfaceKHR {
@ -1409,13 +1451,13 @@ unsafe impl<W> VulkanObject for Surface<W> {
} }
} }
impl<W> Debug for Surface<W> { impl Debug for Surface {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
let Self { let Self {
handle, handle,
instance, instance,
api, api,
window: _, object: _,
has_swapchain, has_swapchain,
.. ..
} = self; } = self;
@ -1430,22 +1472,22 @@ impl<W> Debug for Surface<W> {
} }
} }
impl<W> PartialEq for Surface<W> { impl PartialEq for Surface {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.handle == other.handle && self.instance() == other.instance() self.handle == other.handle && self.instance() == other.instance()
} }
} }
impl<W> Eq for Surface<W> {} impl Eq for Surface {}
impl<W> Hash for Surface<W> { impl Hash for Surface {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state); self.handle.hash(state);
self.instance().hash(state); self.instance().hash(state);
} }
} }
unsafe impl<W> SurfaceSwapchainLock for Surface<W> { unsafe impl SurfaceSwapchainLock for Surface {
fn flag(&self) -> &AtomicBool { fn flag(&self) -> &AtomicBool {
&self.has_swapchain &self.has_swapchain
} }
@ -2032,7 +2074,7 @@ mod tests {
#[test] #[test]
fn khr_win32_surface_ext_missing() { fn khr_win32_surface_ext_missing() {
let instance = instance!(); let instance = instance!();
match unsafe { Surface::from_win32(instance, ptr::null::<u8>(), ptr::null::<u8>(), ()) } { match unsafe { Surface::from_win32(instance, ptr::null::<u8>(), ptr::null::<u8>(), None) } {
Err(SurfaceCreationError::RequirementNotMet { Err(SurfaceCreationError::RequirementNotMet {
requires_one_of: requires_one_of:
RequiresOneOf { RequiresOneOf {
@ -2048,7 +2090,7 @@ mod tests {
#[test] #[test]
fn khr_xcb_surface_ext_missing() { fn khr_xcb_surface_ext_missing() {
let instance = instance!(); let instance = instance!();
match unsafe { Surface::from_xcb(instance, ptr::null::<u8>(), 0, ()) } { match unsafe { Surface::from_xcb(instance, ptr::null::<u8>(), 0, None) } {
Err(SurfaceCreationError::RequirementNotMet { Err(SurfaceCreationError::RequirementNotMet {
requires_one_of: requires_one_of:
RequiresOneOf { RequiresOneOf {
@ -2064,7 +2106,7 @@ mod tests {
#[test] #[test]
fn khr_xlib_surface_ext_missing() { fn khr_xlib_surface_ext_missing() {
let instance = instance!(); let instance = instance!();
match unsafe { Surface::from_xlib(instance, ptr::null::<u8>(), 0, ()) } { match unsafe { Surface::from_xlib(instance, ptr::null::<u8>(), 0, None) } {
Err(SurfaceCreationError::RequirementNotMet { Err(SurfaceCreationError::RequirementNotMet {
requires_one_of: requires_one_of:
RequiresOneOf { RequiresOneOf {
@ -2080,7 +2122,8 @@ mod tests {
#[test] #[test]
fn khr_wayland_surface_ext_missing() { fn khr_wayland_surface_ext_missing() {
let instance = instance!(); 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>(), None) }
{
Err(SurfaceCreationError::RequirementNotMet { Err(SurfaceCreationError::RequirementNotMet {
requires_one_of: requires_one_of:
RequiresOneOf { RequiresOneOf {
@ -2096,7 +2139,7 @@ mod tests {
#[test] #[test]
fn khr_android_surface_ext_missing() { fn khr_android_surface_ext_missing() {
let instance = instance!(); let instance = instance!();
match unsafe { Surface::from_android(instance, ptr::null::<u8>(), ()) } { match unsafe { Surface::from_android(instance, ptr::null::<u8>(), None) } {
Err(SurfaceCreationError::RequirementNotMet { Err(SurfaceCreationError::RequirementNotMet {
requires_one_of: requires_one_of:
RequiresOneOf { RequiresOneOf {

View File

@ -45,10 +45,10 @@ use std::{
}; };
/// Contains the swapping system and the images that can be shown on a surface. /// Contains the swapping system and the images that can be shown on a surface.
pub struct Swapchain<W> { pub struct Swapchain {
handle: ash::vk::SwapchainKHR, handle: ash::vk::SwapchainKHR,
device: Arc<Device>, device: Arc<Device>,
surface: Arc<Surface<W>>, surface: Arc<Surface>,
min_image_count: u32, min_image_count: u32,
image_format: Format, image_format: Format,
@ -88,10 +88,7 @@ struct ImageEntry {
undefined_layout: AtomicBool, undefined_layout: AtomicBool,
} }
impl<W> Swapchain<W> impl Swapchain {
where
W: Send + Sync,
{
/// Creates a new `Swapchain`. /// Creates a new `Swapchain`.
/// ///
/// This function returns the swapchain plus a list of the images that belong to the /// This function returns the swapchain plus a list of the images that belong to the
@ -106,9 +103,9 @@ where
// TODO: isn't it unsafe to take the surface through an Arc when it comes to vulkano-win? // TODO: isn't it unsafe to take the surface through an Arc when it comes to vulkano-win?
pub fn new( pub fn new(
device: Arc<Device>, device: Arc<Device>,
surface: Arc<Surface<W>>, surface: Arc<Surface>,
mut create_info: SwapchainCreateInfo, mut create_info: SwapchainCreateInfo,
) -> Result<(Arc<Swapchain<W>>, Vec<Arc<SwapchainImage<W>>>), SwapchainCreationError> { ) -> Result<(Arc<Swapchain>, Vec<Arc<SwapchainImage>>), SwapchainCreationError> {
Self::validate(&device, &surface, &mut create_info)?; Self::validate(&device, &surface, &mut create_info)?;
// Checking that the surface doesn't already have a swapchain. // Checking that the surface doesn't already have a swapchain.
@ -181,7 +178,7 @@ where
pub fn recreate( pub fn recreate(
self: &Arc<Self>, self: &Arc<Self>,
mut create_info: SwapchainCreateInfo, mut create_info: SwapchainCreateInfo,
) -> Result<(Arc<Swapchain<W>>, Vec<Arc<SwapchainImage<W>>>), SwapchainCreationError> { ) -> Result<(Arc<Swapchain>, Vec<Arc<SwapchainImage>>), SwapchainCreationError> {
Self::validate(&self.device, &self.surface, &mut create_info)?; Self::validate(&self.device, &self.surface, &mut create_info)?;
{ {
@ -267,7 +264,7 @@ where
fn validate( fn validate(
device: &Device, device: &Device,
surface: &Surface<W>, surface: &Surface,
create_info: &mut SwapchainCreateInfo, create_info: &mut SwapchainCreateInfo,
) -> Result<(), SwapchainCreationError> { ) -> Result<(), SwapchainCreationError> {
let &mut SwapchainCreateInfo { let &mut SwapchainCreateInfo {
@ -554,9 +551,9 @@ where
unsafe fn create( unsafe fn create(
device: &Device, device: &Device,
surface: &Surface<W>, surface: &Surface,
create_info: &SwapchainCreateInfo, create_info: &SwapchainCreateInfo,
old_swapchain: Option<&Swapchain<W>>, old_swapchain: Option<&Swapchain>,
) -> Result<(ash::vk::SwapchainKHR, Vec<ash::vk::Image>), SwapchainCreationError> { ) -> Result<(ash::vk::SwapchainKHR, Vec<ash::vk::Image>), SwapchainCreationError> {
let &SwapchainCreateInfo { let &SwapchainCreateInfo {
min_image_count, min_image_count,
@ -746,10 +743,63 @@ where
} }
/// Returns the saved Surface, from the Swapchain creation. /// Returns the saved Surface, from the Swapchain creation.
pub fn surface(&self) -> &Arc<Surface<W>> { pub fn surface(&self) -> &Arc<Surface> {
&self.surface &self.surface
} }
/// Returns one of the images that belongs to this swapchain.
#[inline]
pub fn raw_image(&self, image_index: u32) -> Option<ImageInner<'_>> {
self.images.get(image_index as usize).map(|i| ImageInner {
image: &i.image,
first_layer: 0,
num_layers: self.image_array_layers,
first_mipmap_level: 0,
num_mipmap_levels: 1,
})
}
/// Returns the number of images of the swapchain.
#[inline]
pub fn image_count(&self) -> u32 {
self.images.len() as u32
}
/// Returns the format of the images of the swapchain.
#[inline]
pub fn image_format(&self) -> Format {
self.image_format
}
/// Returns the color space of the images of the swapchain.
#[inline]
pub fn image_color_space(&self) -> ColorSpace {
self.image_color_space
}
/// Returns the extent of the images of the swapchain.
#[inline]
pub fn image_extent(&self) -> [u32; 2] {
self.image_extent
}
/// Returns the number of array layers of the images of the swapchain.
#[inline]
pub fn image_array_layers(&self) -> u32 {
self.image_array_layers
}
#[inline]
pub(crate) unsafe fn full_screen_exclusive_held(&self) -> &AtomicBool {
&self.full_screen_exclusive_held
}
#[inline]
pub(crate) unsafe fn try_claim_present_id(&self, present_id: NonZeroU64) -> bool {
let present_id = u64::from(present_id);
self.prev_present_id.fetch_max(present_id, Ordering::SeqCst) < present_id
}
/// Returns the pre-transform that was passed when creating the swapchain. /// Returns the pre-transform that was passed when creating the swapchain.
pub fn pre_transform(&self) -> SurfaceTransform { pub fn pre_transform(&self) -> SurfaceTransform {
self.pre_transform self.pre_transform
@ -867,7 +917,7 @@ where
} }
} }
impl<W> Drop for Swapchain<W> { impl Drop for Swapchain {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
let fns = self.device.fns(); let fns = self.device.fns();
@ -881,7 +931,7 @@ impl<W> Drop for Swapchain<W> {
} }
} }
unsafe impl<W> VulkanObject for Swapchain<W> { unsafe impl VulkanObject for Swapchain {
type Object = ash::vk::SwapchainKHR; type Object = ash::vk::SwapchainKHR;
fn internal_object(&self) -> ash::vk::SwapchainKHR { fn internal_object(&self) -> ash::vk::SwapchainKHR {
@ -889,28 +939,28 @@ unsafe impl<W> VulkanObject for Swapchain<W> {
} }
} }
unsafe impl<W> DeviceOwned for Swapchain<W> { unsafe impl DeviceOwned for Swapchain {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Arc<Device> {
&self.device &self.device
} }
} }
impl<W> PartialEq for Swapchain<W> { impl PartialEq for Swapchain {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.handle == other.handle && self.device() == other.device() self.handle == other.handle && self.device() == other.device()
} }
} }
impl<W> Eq for Swapchain<W> {} impl Eq for Swapchain {}
impl<W> Hash for Swapchain<W> { impl Hash for Swapchain {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state); self.handle.hash(state);
self.device().hash(state); self.device().hash(state);
} }
} }
impl<W> Debug for Swapchain<W> { impl Debug for Swapchain {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
let Self { let Self {
handle, handle,
@ -960,95 +1010,6 @@ impl<W> Debug for Swapchain<W> {
} }
} }
/// Trait for types that represent the GPU can access an image view.
pub unsafe trait SwapchainAbstract:
VulkanObject<Object = ash::vk::SwapchainKHR> + DeviceOwned + Debug + Send + Sync
{
/// Returns one of the images that belongs to this swapchain.
fn raw_image(&self, index: u32) -> Option<ImageInner<'_>>;
/// Returns the number of images of the swapchain.
fn image_count(&self) -> u32;
/// Returns the format of the images of the swapchain.
fn image_format(&self) -> Format;
/// Returns the color space of the images of the swapchain.
fn image_color_space(&self) -> ColorSpace;
/// Returns the extent of the images of the swapchain.
fn image_extent(&self) -> [u32; 2];
/// Returns the number of array layers of the images of the swapchain.
fn image_array_layers(&self) -> u32;
#[doc(hidden)]
unsafe fn try_claim_present_id(&self, present_id: NonZeroU64) -> bool;
#[doc(hidden)]
unsafe fn full_screen_exclusive_held(&self) -> &AtomicBool;
}
unsafe impl<W> SwapchainAbstract for Swapchain<W>
where
W: Send + Sync,
{
fn raw_image(&self, image_index: u32) -> Option<ImageInner<'_>> {
self.images.get(image_index as usize).map(|i| ImageInner {
image: &i.image,
first_layer: 0,
num_layers: self.image_array_layers,
first_mipmap_level: 0,
num_mipmap_levels: 1,
})
}
fn image_count(&self) -> u32 {
self.images.len() as u32
}
fn image_format(&self) -> Format {
self.image_format
}
fn image_color_space(&self) -> ColorSpace {
self.image_color_space
}
fn image_extent(&self) -> [u32; 2] {
self.image_extent
}
fn image_array_layers(&self) -> u32 {
self.image_array_layers
}
unsafe fn full_screen_exclusive_held(&self) -> &AtomicBool {
&self.full_screen_exclusive_held
}
unsafe fn try_claim_present_id(&self, present_id: NonZeroU64) -> bool {
let present_id = u64::from(present_id);
self.prev_present_id.fetch_max(present_id, Ordering::SeqCst) < present_id
}
}
impl PartialEq for dyn SwapchainAbstract {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.internal_object() == other.internal_object() && self.device() == other.device()
}
}
impl Eq for dyn SwapchainAbstract {}
impl Hash for dyn SwapchainAbstract {
fn hash<H: Hasher>(&self, state: &mut H) {
self.internal_object().hash(state);
self.device().hash(state);
}
}
/// Parameters to create a new `Swapchain`. /// Parameters to create a new `Swapchain`.
/// ///
/// Many of the values here must be supported by the physical device. /// Many of the values here must be supported by the physical device.
@ -1538,10 +1499,10 @@ impl From<OomError> for FullScreenExclusiveError {
/// The second field in the tuple in the Ok result is a bool represent if the acquisition was /// The second field in the tuple in the Ok result is a bool represent if the acquisition was
/// suboptimal. In this case the acquired image is still usable, but the swapchain should be /// suboptimal. In this case the acquired image is still usable, but the swapchain should be
/// recreated as the Surface's properties no longer match the swapchain. /// recreated as the Surface's properties no longer match the swapchain.
pub fn acquire_next_image<W>( pub fn acquire_next_image(
swapchain: Arc<Swapchain<W>>, swapchain: Arc<Swapchain>,
timeout: Option<Duration>, timeout: Option<Duration>,
) -> Result<(u32, bool, SwapchainAcquireFuture<W>), AcquireError> { ) -> Result<(u32, bool, SwapchainAcquireFuture), AcquireError> {
let semaphore = Arc::new(Semaphore::from_pool(swapchain.device.clone())?); let semaphore = Arc::new(Semaphore::from_pool(swapchain.device.clone())?);
let fence = Fence::from_pool(swapchain.device.clone())?; let fence = Fence::from_pool(swapchain.device.clone())?;
@ -1617,8 +1578,8 @@ where
/// Returns a bool to represent if the presentation was suboptimal. In this case the swapchain is /// Returns a bool to represent if the presentation was suboptimal. In this case the swapchain is
/// still usable, but the swapchain should be recreated as the Surface's properties no longer match /// still usable, but the swapchain should be recreated as the Surface's properties no longer match
/// the swapchain. /// the swapchain.
pub fn wait_for_present<W>( pub fn wait_for_present(
swapchain: Arc<Swapchain<W>>, swapchain: Arc<Swapchain>,
present_id: u64, present_id: u64,
timeout: Option<Duration>, timeout: Option<Duration>,
) -> Result<bool, PresentWaitError> { ) -> Result<bool, PresentWaitError> {
@ -1675,8 +1636,8 @@ pub fn wait_for_present<W>(
/// Represents the moment when the GPU will have access to a swapchain image. /// Represents the moment when the GPU will have access to a swapchain image.
#[must_use] #[must_use]
pub struct SwapchainAcquireFuture<W> { pub struct SwapchainAcquireFuture {
swapchain: Arc<Swapchain<W>>, swapchain: Arc<Swapchain>,
image_index: u32, image_index: u32,
// Semaphore that is signalled when the acquire is complete. Empty if the acquire has already // Semaphore that is signalled when the acquire is complete. Empty if the acquire has already
// happened. // happened.
@ -1687,22 +1648,19 @@ pub struct SwapchainAcquireFuture<W> {
finished: AtomicBool, finished: AtomicBool,
} }
impl<W> SwapchainAcquireFuture<W> { impl SwapchainAcquireFuture {
/// Returns the index of the image in the list of images returned when creating the swapchain. /// Returns the index of the image in the list of images returned when creating the swapchain.
pub fn image_index(&self) -> u32 { pub fn image_index(&self) -> u32 {
self.image_index self.image_index
} }
/// Returns the corresponding swapchain. /// Returns the corresponding swapchain.
pub fn swapchain(&self) -> &Arc<Swapchain<W>> { pub fn swapchain(&self) -> &Arc<Swapchain> {
&self.swapchain &self.swapchain
} }
} }
unsafe impl<W> GpuFuture for SwapchainAcquireFuture<W> unsafe impl GpuFuture for SwapchainAcquireFuture {
where
W: Send + Sync,
{
fn cleanup_finished(&mut self) {} fn cleanup_finished(&mut self) {}
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> { unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
@ -1795,7 +1753,7 @@ where
} }
} }
impl<W> Drop for SwapchainAcquireFuture<W> { impl Drop for SwapchainAcquireFuture {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(ref fence) = self.fence { if let Some(ref fence) = self.fence {
fence.wait(None).unwrap(); // TODO: handle error? fence.wait(None).unwrap(); // TODO: handle error?
@ -1807,7 +1765,7 @@ impl<W> Drop for SwapchainAcquireFuture<W> {
} }
} }
unsafe impl<W> DeviceOwned for SwapchainAcquireFuture<W> { unsafe impl DeviceOwned for SwapchainAcquireFuture {
fn device(&self) -> &Arc<Device> { fn device(&self) -> &Arc<Device> {
&self.swapchain.device &self.swapchain.device
} }
@ -2028,7 +1986,7 @@ where
} }
/// Returns the corresponding swapchain. /// Returns the corresponding swapchain.
pub fn swapchain(&self) -> &Arc<dyn SwapchainAbstract> { pub fn swapchain(&self) -> &Arc<Swapchain> {
&self.swapchain_info.swapchain &self.swapchain_info.swapchain
} }
} }
@ -2274,8 +2232,8 @@ pub struct AcquiredImage {
/// - The semaphore and/or the fence must be kept alive until it is signaled. /// - 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 /// - The swapchain must not have been replaced by being passed as the old swapchain when creating
/// a new one. /// a new one.
pub unsafe fn acquire_next_image_raw<W>( pub unsafe fn acquire_next_image_raw(
swapchain: &Swapchain<W>, swapchain: &Swapchain,
timeout: Option<Duration>, timeout: Option<Duration>,
semaphore: Option<&Semaphore>, semaphore: Option<&Semaphore>,
fence: Option<&Fence>, fence: Option<&Fence>,