Add PhysicalDevice::presentation_support (#2562)

This commit is contained in:
marc0246 2024-09-11 17:02:27 +02:00 committed by GitHub
parent 79c30fd1a8
commit e8ddaef0e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
66 changed files with 512 additions and 344 deletions

2
Cargo.lock generated
View File

@ -2374,6 +2374,8 @@ dependencies = [
"thread_local",
"vk-parse",
"vulkano-macros",
"x11-dl",
"x11rb",
]
[[package]]

View File

@ -71,6 +71,8 @@ syn = "2.0"
thread_local = "1.1"
vk-parse = "0.12"
winit = { version = "0.29", default-features = false }
x11-dl = "2.0"
x11rb = "0.13"
# Only used in examples
glam = "0.25"

View File

@ -14,7 +14,7 @@ doc = false
[dependencies]
glam = { workspace = true }
rand = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
vulkano-taskgraph = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -110,9 +110,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -127,7 +124,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -232,6 +229,9 @@ fn main() -> Result<(), impl Error> {
let graphics_flight_id = resources.create_flight(MAX_FRAMES_IN_FLIGHT).unwrap();
let transfer_flight_id = resources.create_flight(1).unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let swapchain_format = device
.physical_device()
.surface_formats(&surface, Default::default())

View File

@ -12,5 +12,5 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }

View File

@ -12,6 +12,6 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -62,9 +62,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -79,7 +76,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -114,6 +111,9 @@ fn main() -> Result<(), impl Error> {
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -12,5 +12,5 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true }
vulkano = { workspace = true, default-features = true }
winit = { workspace = true, default-features = true }

View File

@ -42,9 +42,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -59,7 +56,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -93,6 +90,9 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -12,4 +12,4 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true }
vulkano = { workspace = true, default-features = true }

View File

@ -13,6 +13,6 @@ doc = false
[dependencies]
glam = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -65,9 +65,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -82,7 +79,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -116,6 +113,9 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, mut images) = {
let surface_capabilities = device
.physical_device()

View File

@ -12,5 +12,5 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }

View File

@ -13,5 +13,5 @@ doc = false
[dependencies]
png = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }

View File

@ -13,7 +13,7 @@ doc = false
[dependencies]
glium = "0.32.1"
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }
# Glium has still not been updated to the latest winit version

View File

@ -531,9 +531,6 @@ mod linux {
.unwrap()
};
let window = Arc::new(WindowBuilder::new().build(event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_external_semaphore: true,
khr_external_semaphore_fd: true,
@ -555,7 +552,7 @@ mod linux {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -597,6 +594,9 @@ mod linux {
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -13,6 +13,6 @@ doc = false
[dependencies]
png = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -67,9 +67,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -84,7 +81,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -118,6 +115,9 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -13,6 +13,6 @@ doc = false
[dependencies]
png = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -65,9 +65,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -82,7 +79,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -116,6 +113,9 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -13,6 +13,6 @@ doc = false
[dependencies]
png = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -71,9 +71,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -88,7 +85,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -122,6 +119,9 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -12,6 +12,6 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -78,9 +78,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
khr_storage_buffer_storage_class: true,
@ -96,7 +93,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -131,6 +128,9 @@ fn main() -> Result<(), impl Error> {
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -12,6 +12,6 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -77,9 +77,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -94,7 +91,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -129,6 +126,9 @@ fn main() -> Result<(), impl Error> {
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -14,7 +14,7 @@ doc = false
[dependencies]
glam = { workspace = true }
rand = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
vulkano-util = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -12,6 +12,6 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -97,9 +97,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
ext_mesh_shader: true,
@ -115,7 +112,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -154,6 +151,9 @@ fn main() -> Result<(), impl Error> {
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -13,5 +13,5 @@ doc = false
[dependencies]
png = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }

View File

@ -14,7 +14,7 @@ doc = false
[dependencies]
glam = { workspace = true }
rand = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
vulkano-util = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -12,6 +12,6 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -71,6 +71,54 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
};
let (physical_device, queue_family_index) = instance
.enumerate_physical_devices()
.unwrap()
.filter(|p| p.supported_extensions().contains(&device_extensions))
.filter_map(|p| {
p.queue_family_properties()
.iter()
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
.min_by_key(|(p, _)| match p.properties().device_type {
PhysicalDeviceType::DiscreteGpu => 0,
PhysicalDeviceType::IntegratedGpu => 1,
PhysicalDeviceType::VirtualGpu => 2,
PhysicalDeviceType::Cpu => 3,
PhysicalDeviceType::Other => 4,
_ => 5,
})
.unwrap();
println!(
"Using device: {} (type: {:?})",
physical_device.properties().device_name,
physical_device.properties().device_type,
);
let (device, mut queues) = Device::new(
physical_device,
DeviceCreateInfo {
enabled_extensions: device_extensions,
queue_create_infos: vec![QueueCreateInfo {
queue_family_index,
..Default::default()
}],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
@ -80,84 +128,27 @@ fn main() -> Result<(), impl Error> {
// Use the window's id as a means to access it from the hashmap.
let window_id = window.id();
// Find the device and a queue.
// TODO: it is assumed the device, queue, and surface surface_capabilities are the same for all
// windows.
let (device, queue, surface_caps) = {
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
};
let (physical_device, queue_family_index) = instance
.enumerate_physical_devices()
.unwrap()
.filter(|p| p.supported_extensions().contains(&device_extensions))
.filter_map(|p| {
p.queue_family_properties()
.iter()
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
})
.map(|i| (p, i as u32))
})
.min_by_key(|(p, _)| match p.properties().device_type {
PhysicalDeviceType::DiscreteGpu => 0,
PhysicalDeviceType::IntegratedGpu => 1,
PhysicalDeviceType::VirtualGpu => 2,
PhysicalDeviceType::Cpu => 3,
PhysicalDeviceType::Other => 4,
_ => 5,
})
.unwrap();
println!(
"Using device: {} (type: {:?})",
physical_device.properties().device_name,
physical_device.properties().device_type,
);
let (device, mut queues) = Device::new(
physical_device,
DeviceCreateInfo {
enabled_extensions: device_extensions,
queue_create_infos: vec![QueueCreateInfo {
queue_family_index,
..Default::default()
}],
..Default::default()
},
)
.unwrap();
// The swapchain and framebuffer images for this particular window.
let (swapchain, images) = {
let surface_capabilities = device
.physical_device()
.surface_capabilities(&surface, Default::default())
.unwrap();
(device, queues.next().unwrap(), surface_capabilities)
};
// The swapchain and framebuffer images for this particular window.
let (swapchain, images) = {
let image_format = device
.physical_device()
.surface_formats(&surface, Default::default())
.unwrap()[0]
.0;
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
Swapchain::new(
device.clone(),
surface.clone(),
SwapchainCreateInfo {
min_image_count: surface_caps.min_image_count.max(2),
min_image_count: surface_capabilities.min_image_count.max(2),
image_format,
image_extent: window.inner_size().into(),
image_usage: ImageUsage::COLOR_ATTACHMENT,
composite_alpha: surface_caps
composite_alpha: surface_capabilities
.supported_composite_alpha
.into_iter()
.next()
@ -353,10 +344,9 @@ fn main() -> Result<(), impl Error> {
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let window_id = window.id();
let (swapchain, images) = {
let composite_alpha = surface_caps
.supported_composite_alpha
.into_iter()
.next()
let surface_capabilities = device
.physical_device()
.surface_capabilities(&surface, Default::default())
.unwrap();
let image_format = device
.physical_device()
@ -368,11 +358,15 @@ fn main() -> Result<(), impl Error> {
device.clone(),
surface,
SwapchainCreateInfo {
min_image_count: surface_caps.min_image_count.max(2),
min_image_count: surface_capabilities.min_image_count.max(2),
image_format,
image_extent: window.inner_size().into(),
image_usage: ImageUsage::COLOR_ATTACHMENT,
composite_alpha,
composite_alpha: surface_capabilities
.supported_composite_alpha
.into_iter()
.next()
.unwrap(),
..Default::default()
},
)

View File

@ -13,5 +13,5 @@ doc = false
[dependencies]
png = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }

View File

@ -12,6 +12,6 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -60,9 +60,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -77,7 +74,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -111,6 +108,9 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -13,6 +13,6 @@ doc = false
[dependencies]
png = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -12,5 +12,5 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }

View File

@ -12,5 +12,5 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }

View File

@ -13,6 +13,6 @@ doc = false
[dependencies]
png = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -60,9 +60,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
khr_push_descriptor: true,
@ -78,7 +75,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -112,6 +109,9 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -13,6 +13,6 @@ doc = false
[dependencies]
png = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -66,9 +66,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -83,7 +80,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -124,6 +121,9 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -12,5 +12,5 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true }
vulkano = { workspace = true, default-features = true }
winit = { workspace = true, default-features = true }

View File

@ -68,9 +68,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -85,7 +82,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -119,6 +116,9 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -12,5 +12,5 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }

View File

@ -12,5 +12,5 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }

View File

@ -14,6 +14,6 @@ doc = false
[dependencies]
ron = { workspace = true }
serde = { workspace = true, features = ["derive"] }
vulkano = { workspace = true, features = ["serde", "macros"] }
vulkano = { workspace = true, default-features = true, features = ["serde"] }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -12,5 +12,5 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }

View File

@ -12,6 +12,6 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -71,17 +71,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(
WindowBuilder::new()
// For simplicity, we are going to assert that the window size is static.
.with_resizable(false)
.with_title("simple particles")
.with_inner_size(winit::dpi::PhysicalSize::new(WINDOW_WIDTH, WINDOW_HEIGHT))
.build(&event_loop)
.unwrap(),
);
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -96,7 +85,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -130,6 +119,17 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(
WindowBuilder::new()
// For simplicity, we are going to assert that the window size is static.
.with_resizable(false)
.with_title("simple particles")
.with_inner_size(winit::dpi::PhysicalSize::new(WINDOW_WIDTH, WINDOW_HEIGHT))
.build(&event_loop)
.unwrap(),
);
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -12,5 +12,5 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }

View File

@ -13,6 +13,6 @@ doc = false
[dependencies]
glam = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -73,9 +73,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -90,7 +87,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -125,6 +122,9 @@ fn main() -> Result<(), impl Error> {
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -12,6 +12,6 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -165,9 +165,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -188,7 +185,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -223,6 +220,9 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -13,6 +13,6 @@ doc = false
[dependencies]
png = { workspace = true }
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -67,9 +67,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
@ -84,7 +81,7 @@ fn main() -> Result<(), impl Error> {
.enumerate()
.position(|(i, q)| {
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
.map(|i| (p, i as u32))
})
@ -118,6 +115,9 @@ fn main() -> Result<(), impl Error> {
.unwrap();
let queue = queues.next().unwrap();
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
let (mut swapchain, images) = {
let surface_capabilities = device
.physical_device()

View File

@ -13,7 +13,7 @@ doc = false
[dependencies]
# The `vulkano` crate is the main crate that you must use to use Vulkan.
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
# Provides the `shader!` macro that is used to generate code for using shaders.
vulkano-shaders = { workspace = true }
# Contains the utility functions that make life easier.

View File

@ -12,6 +12,6 @@ bench = false
doc = false
[dependencies]
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
vulkano-shaders = { workspace = true }
winit = { workspace = true, default-features = true }

View File

@ -80,15 +80,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
// The objective of this example is to draw a triangle on a window. To do so, we first need to
// create the window. We use the `WindowBuilder` from the `winit` crate to do that here.
//
// Before we can render to a window, we must first create a `vulkano::swapchain::Surface`
// object from it, which represents the drawable surface of a window. For that we must wrap the
// `winit::window::Window` in an `Arc`.
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
// Choose device extensions that we're going to use. In order to present images to a surface,
// we need a `Swapchain`, which is provided by the `khr_swapchain` extension.
let mut device_extensions = DeviceExtensions {
@ -133,7 +124,7 @@ fn main() -> Result<(), impl Error> {
// a window surface, as we do in this example, we also need to check that
// queues in this queue family are capable of presenting images to the surface.
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
// The code here searches for the first queue family that is suitable. If none is
// found, `None` is returned to `filter_map`, which disqualifies this physical
@ -217,6 +208,15 @@ fn main() -> Result<(), impl Error> {
// iterator.
let queue = queues.next().unwrap();
// The objective of this example is to draw a triangle on a window. To do so, we first need to
// create the window. We use the `WindowBuilder` from the `winit` crate to do that here.
//
// Before we can render to a window, we must first create a `vulkano::swapchain::Surface`
// object from it, which represents the drawable surface of a window. For that we must wrap the
// `winit::window::Window` in an `Arc`.
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
// Before we can draw on the surface, we have to create what is called a swapchain. Creating a
// swapchain allocates the color buffers that will contain the image that will ultimately be
// visible on the screen. These images are returned alongside the swapchain.

View File

@ -13,7 +13,7 @@ doc = false
[dependencies]
# The `vulkano` crate is the main crate that you must use to use Vulkan.
vulkano = { workspace = true, features = ["macros"] }
vulkano = { workspace = true, default-features = true }
# Provides the `shader!` macro that is used to generate code for using shaders.
vulkano-shaders = { workspace = true }
# The Vulkan library doesn't provide any functionality to create and handle windows, as

View File

@ -75,15 +75,6 @@ fn main() -> Result<(), impl Error> {
)
.unwrap();
// The objective of this example is to draw a triangle on a window. To do so, we first need to
// create the window. We use the `WindowBuilder` from the `winit` crate to do that here.
//
// Before we can render to a window, we must first create a `vulkano::swapchain::Surface`
// object from it, which represents the drawable surface of a window. For that we must wrap the
// `winit::window::Window` in an `Arc`.
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
// Choose device extensions that we're going to use. In order to present images to a surface,
// we need a `Swapchain`, which is provided by the `khr_swapchain` extension.
let device_extensions = DeviceExtensions {
@ -123,7 +114,7 @@ fn main() -> Result<(), impl Error> {
// a window surface, as we do in this example, we also need to check that
// queues in this queue family are capable of presenting images to the surface.
q.queue_flags.intersects(QueueFlags::GRAPHICS)
&& p.surface_support(i as u32, &surface).unwrap_or(false)
&& p.presentation_support(i as u32, &event_loop).unwrap()
})
// The code here searches for the first queue family that is suitable. If none is
// found, `None` is returned to `filter_map`, which disqualifies this physical
@ -187,6 +178,15 @@ fn main() -> Result<(), impl Error> {
// iterator.
let queue = queues.next().unwrap();
// The objective of this example is to draw a triangle on a window. To do so, we first need to
// create the window. We use the `WindowBuilder` from the `winit` crate to do that here.
//
// Before we can render to a window, we must first create a `vulkano::swapchain::Surface`
// object from it, which represents the drawable surface of a window. For that we must wrap the
// `winit::window::Window` in an `Arc`.
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
let surface = Surface::from_window(instance.clone(), window.clone()).unwrap();
// Before we can draw on the surface, we have to create what is called a swapchain. Creating a
// swapchain allocates the color buffers that will contain the image that will ultimately be
// visible on the screen. These images are returned alongside the swapchain.

View File

@ -34,6 +34,10 @@ vulkano-macros = { workspace = true, optional = true }
objc = { workspace = true }
core-graphics-types = { workspace = true }
[target.'cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "hurd", target_os = "illumos", target_os = "linux", target_os = "netbsd", target_os = "openbsd", target_os = "solaris"))'.dependencies]
x11-dl = { workspace = true, optional = true }
x11rb = { workspace = true, features = ["allow-unsafe-code"], optional = true }
[build-dependencies]
ahash = { workspace = true }
heck = { workspace = true }
@ -50,9 +54,10 @@ vk-parse = { workspace = true }
libc = "0.2.153"
[features]
default = ["macros"]
macros = ["dep:vulkano-macros"]
default = ["macros", "x11"]
document_unchecked = []
macros = ["dep:vulkano-macros"]
x11 = ["dep:x11-dl", "dep:x11rb"]
[lints]
workspace = true

View File

@ -29,6 +29,7 @@ use crate::{
};
use bytemuck::cast_slice;
use parking_lot::RwLock;
use raw_window_handle::{HandleError, HasDisplayHandle, RawDisplayHandle};
use std::{
fmt::{Debug, Error as FmtError, Formatter},
mem::MaybeUninit,
@ -420,71 +421,6 @@ impl PhysicalDevice {
&self.queue_family_properties
}
/// Queries whether the physical device supports presenting to DirectFB surfaces from queues of
/// the given queue family.
///
/// # Safety
///
/// - `dfb` must be a valid DirectFB `IDirectFB` handle.
#[inline]
pub unsafe fn directfb_presentation_support(
&self,
queue_family_index: u32,
dfb: *mut ash::vk::IDirectFB,
) -> Result<bool, Box<ValidationError>> {
self.validate_directfb_presentation_support(queue_family_index, dfb)?;
Ok(self.directfb_presentation_support_unchecked(queue_family_index, dfb))
}
fn validate_directfb_presentation_support(
&self,
queue_family_index: u32,
_dfb: *mut ash::vk::IDirectFB,
) -> Result<(), Box<ValidationError>> {
if !self.instance.enabled_extensions().ext_directfb_surface {
return Err(Box::new(ValidationError {
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
"ext_directfb_surface",
)])]),
..Default::default()
}));
}
if queue_family_index >= self.queue_family_properties.len() as u32 {
return Err(Box::new(ValidationError {
context: "queue_family_index".into(),
problem: "is not less than the number of queue families in the physical device"
.into(),
vuids: &[
"VUID-vkGetPhysicalDeviceDirectFBPresentationSupportEXT-queueFamilyIndex-04119",
],
..Default::default()
}));
}
// VUID-vkGetPhysicalDeviceDirectFBPresentationSupportEXT-dfb-parameter
// Can't validate, therefore unsafe
Ok(())
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn directfb_presentation_support_unchecked(
&self,
queue_family_index: u32,
dfb: *mut ash::vk::IDirectFB,
) -> bool {
let fns = self.instance.fns();
(fns.ext_directfb_surface
.get_physical_device_direct_fb_presentation_support_ext)(
self.handle,
queue_family_index,
dfb,
) != 0
}
/// Returns the properties of displays attached to the physical device.
#[inline]
pub fn display_properties(
@ -1675,69 +1611,6 @@ impl PhysicalDevice {
})
}
/// Queries whether the physical device supports presenting to QNX Screen surfaces from queues
/// of the given queue family.
///
/// # Safety
///
/// - `window` must be a valid QNX Screen `_screen_window` handle.
pub unsafe fn qnx_screen_presentation_support(
&self,
queue_family_index: u32,
window: *mut ash::vk::_screen_window,
) -> Result<bool, Box<ValidationError>> {
self.validate_qnx_screen_presentation_support(queue_family_index, window)?;
Ok(self.qnx_screen_presentation_support_unchecked(queue_family_index, window))
}
fn validate_qnx_screen_presentation_support(
&self,
queue_family_index: u32,
_window: *mut ash::vk::_screen_window,
) -> Result<(), Box<ValidationError>> {
if !self.instance.enabled_extensions().qnx_screen_surface {
return Err(Box::new(ValidationError {
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
"qnx_screen_surface",
)])]),
..Default::default()
}));
}
if queue_family_index >= self.queue_family_properties.len() as u32 {
return Err(Box::new(ValidationError {
context: "queue_family_index".into(),
problem: "is not less than the number of queue families in the physical device"
.into(),
vuids: &[
"VUID-vkGetPhysicalDeviceScreenPresentationSupportQNX-queueFamilyIndex-04743",
],
..Default::default()
}));
}
// VUID-vkGetPhysicalDeviceScreenPresentationSupportQNX-window-parameter
// Can't validate, therefore unsafe
Ok(())
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn qnx_screen_presentation_support_unchecked(
&self,
queue_family_index: u32,
window: *mut ash::vk::_screen_window,
) -> bool {
let fns = self.instance.fns();
(fns.qnx_screen_surface
.get_physical_device_screen_presentation_support_qnx)(
self.handle,
queue_family_index,
window,
) != 0
}
/// Returns the properties of sparse images with a given image configuration.
///
/// The results of this function are cached, so that future calls with the same arguments
@ -2848,10 +2721,16 @@ impl PhysicalDevice {
)
}
/// Returns whether queues of the given queue family can draw on the given surface.
/// Returns whether queues of the given queue family support presentation to the given surface.
///
/// 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.
/// 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.
///
/// See also [`presentation_support`] for determining if a queue family supports presentation
/// to the surface of any window of a given event loop, for instance in cases where you have no
/// window and hence no surface at hand to test with or when you could have multiple windows.
///
/// [`presentation_support`]: Self::presentation_support
#[inline]
pub fn surface_support(
&self,
@ -3020,6 +2899,113 @@ impl PhysicalDevice {
}
}
/// Returns whether queues of the given queue family support presentation to surfaces of
/// windows of the given event loop.
///
/// On the X11 platform, this checks if the given queue family supports presentation to
/// surfaces of windows created with the root visual. This means that if you create your
/// window(s) with a different visual, the result of this function doesn't guarantee support
/// for that window's surface, and you should use [`xcb_presentation_support`] or
/// [`xlib_presentation_support`] directly to determine support for presentation to such
/// surfaces.
///
/// See also [`surface_support`] for determining if a queue family supports presentation to a
/// specific surface.
///
/// [`xcb_presentation_support`]: Self::xcb_presentation_support
/// [`xlib_presentation_support`]: Self::xlib_presentation_support
/// [`surface_support`]: Self::surface_support
pub fn presentation_support(
&self,
queue_family_index: u32,
event_loop: &impl HasDisplayHandle,
) -> Result<bool, Validated<HandleError>> {
let support = match event_loop
.display_handle()
.map_err(Validated::Error)?
.as_raw()
{
// https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap34.html#platformQuerySupport_android
RawDisplayHandle::Android(_) => true,
// https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap34.html#platformQuerySupport_macos
RawDisplayHandle::AppKit(_) => true,
RawDisplayHandle::Wayland(display) => {
let display = display.display.as_ptr();
unsafe { self.wayland_presentation_support(queue_family_index, display.cast()) }?
}
RawDisplayHandle::Windows(_display) => {
self.win32_presentation_support(queue_family_index)?
}
#[cfg(all(
any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd",
target_os = "solaris"
),
feature = "x11"
))]
RawDisplayHandle::Xcb(display) => {
let screen = display.screen;
let connection = display.connection.unwrap().as_ptr();
let visual_id = unsafe { get_xcb_root_visual_id(connection, screen) };
unsafe {
self.xcb_presentation_support(queue_family_index, connection.cast(), visual_id)
}?
}
#[cfg(all(
any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd",
target_os = "solaris"
),
feature = "x11"
))]
RawDisplayHandle::Xlib(display) => {
let screen = display.screen;
let display = display.display.unwrap().as_ptr();
let visual_id = unsafe { get_xlib_root_visual_id(display, screen) };
unsafe {
self.xlib_presentation_support(queue_family_index, display.cast(), visual_id)
}?
}
#[cfg(all(
any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd",
target_os = "solaris"
),
not(feature = "x11")
))]
RawDisplayHandle::Xcb(_) | RawDisplayHandle::Xlib(_) => panic!("unsupported platform"),
// https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap34.html#platformQuerySupport_ios
RawDisplayHandle::UiKit(_) => true,
_ => unimplemented!(
"the event loop was created with a windowing API that is not supported by \
Vulkan/Vulkano",
),
};
Ok(support)
}
/// Queries whether the physical device supports presenting to Wayland surfaces from queues of
/// the given queue family.
///
@ -3188,7 +3174,7 @@ impl PhysicalDevice {
&self,
queue_family_index: u32,
connection: *mut ash::vk::xcb_connection_t,
visual_id: ash::vk::VisualID,
visual_id: ash::vk::xcb_visualid_t,
) -> bool {
let fns = self.instance.fns();
(fns.khr_xcb_surface
@ -3266,6 +3252,134 @@ impl PhysicalDevice {
visual_id,
) != 0
}
/// Queries whether the physical device supports presenting to DirectFB surfaces from queues of
/// the given queue family.
///
/// # Safety
///
/// - `dfb` must be a valid DirectFB `IDirectFB` handle.
#[inline]
pub unsafe fn directfb_presentation_support(
&self,
queue_family_index: u32,
dfb: *mut ash::vk::IDirectFB,
) -> Result<bool, Box<ValidationError>> {
self.validate_directfb_presentation_support(queue_family_index, dfb)?;
Ok(self.directfb_presentation_support_unchecked(queue_family_index, dfb))
}
fn validate_directfb_presentation_support(
&self,
queue_family_index: u32,
_dfb: *mut ash::vk::IDirectFB,
) -> Result<(), Box<ValidationError>> {
if !self.instance.enabled_extensions().ext_directfb_surface {
return Err(Box::new(ValidationError {
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
"ext_directfb_surface",
)])]),
..Default::default()
}));
}
if queue_family_index >= self.queue_family_properties.len() as u32 {
return Err(Box::new(ValidationError {
context: "queue_family_index".into(),
problem: "is not less than the number of queue families in the physical device"
.into(),
vuids: &[
"VUID-vkGetPhysicalDeviceDirectFBPresentationSupportEXT-queueFamilyIndex-04119",
],
..Default::default()
}));
}
// VUID-vkGetPhysicalDeviceDirectFBPresentationSupportEXT-dfb-parameter
// Can't validate, therefore unsafe
Ok(())
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn directfb_presentation_support_unchecked(
&self,
queue_family_index: u32,
dfb: *mut ash::vk::IDirectFB,
) -> bool {
let fns = self.instance.fns();
(fns.ext_directfb_surface
.get_physical_device_direct_fb_presentation_support_ext)(
self.handle,
queue_family_index,
dfb,
) != 0
}
/// Queries whether the physical device supports presenting to QNX Screen surfaces from queues
/// of the given queue family.
///
/// # Safety
///
/// - `window` must be a valid QNX Screen `_screen_window` handle.
pub unsafe fn qnx_screen_presentation_support(
&self,
queue_family_index: u32,
window: *mut ash::vk::_screen_window,
) -> Result<bool, Box<ValidationError>> {
self.validate_qnx_screen_presentation_support(queue_family_index, window)?;
Ok(self.qnx_screen_presentation_support_unchecked(queue_family_index, window))
}
fn validate_qnx_screen_presentation_support(
&self,
queue_family_index: u32,
_window: *mut ash::vk::_screen_window,
) -> Result<(), Box<ValidationError>> {
if !self.instance.enabled_extensions().qnx_screen_surface {
return Err(Box::new(ValidationError {
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
"qnx_screen_surface",
)])]),
..Default::default()
}));
}
if queue_family_index >= self.queue_family_properties.len() as u32 {
return Err(Box::new(ValidationError {
context: "queue_family_index".into(),
problem: "is not less than the number of queue families in the physical device"
.into(),
vuids: &[
"VUID-vkGetPhysicalDeviceScreenPresentationSupportQNX-queueFamilyIndex-04743",
],
..Default::default()
}));
}
// VUID-vkGetPhysicalDeviceScreenPresentationSupportQNX-window-parameter
// Can't validate, therefore unsafe
Ok(())
}
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn qnx_screen_presentation_support_unchecked(
&self,
queue_family_index: u32,
window: *mut ash::vk::_screen_window,
) -> bool {
let fns = self.instance.fns();
(fns.qnx_screen_surface
.get_physical_device_screen_presentation_support_qnx)(
self.handle,
queue_family_index,
window,
) != 0
}
}
impl Debug for PhysicalDevice {
@ -3326,6 +3440,56 @@ unsafe impl InstanceOwned for PhysicalDevice {
impl_id_counter!(PhysicalDevice);
#[cfg(all(
any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd",
target_os = "solaris"
),
feature = "x11"
))]
unsafe fn get_xcb_root_visual_id(
connection: *mut std::ffi::c_void,
screen_id: std::ffi::c_int,
) -> u32 {
use x11rb::connection::Connection;
let connection =
unsafe { x11rb::xcb_ffi::XCBConnection::from_raw_xcb_connection(connection, false) }
.unwrap();
let screen = &connection.setup().roots[screen_id as usize];
screen.root_visual
}
#[cfg(all(
any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "netbsd",
target_os = "openbsd",
target_os = "solaris"
),
feature = "x11"
))]
unsafe fn get_xlib_root_visual_id(
display: *mut std::ffi::c_void,
screen_id: std::ffi::c_int,
) -> u32 {
let xlib_xcb = x11_dl::xlib_xcb::Xlib_xcb::open().unwrap();
let connection = unsafe { (xlib_xcb.XGetXCBConnection)(display.cast()) };
unsafe { get_xcb_root_visual_id(connection, screen_id) }
}
/// Properties of a group of physical devices that can be used to create a single logical device.
#[derive(Clone, Debug)]
#[non_exhaustive]

View File

@ -93,6 +93,7 @@
//! | Feature | Description |
//! |----------------------|----------------------------------------------------------------|
//! | `macros` | Include reexports from [`vulkano-macros`]. Enabled by default. |
//! | `x11` | Support for X11 platforms. Enabled by default. |
//! | `document_unchecked` | Include `_unchecked` functions in the generated documentation. |
//! | `serde` | Enables (de)serialization of certain types using [`serde`]. |
//!