Skip to content

Commit ffab8f0

Browse files
committed
Factor out swapcahin to abstracted interface
1 parent f935660 commit ffab8f0

File tree

7 files changed

+1127
-851
lines changed

7 files changed

+1127
-851
lines changed

wgpu-hal/src/vulkan/adapter.rs

Lines changed: 5 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use core::{ffi::CStr, marker::PhantomData};
44
use ash::{ext, google, khr, vk};
55
use parking_lot::Mutex;
66

7-
use super::conv;
7+
use crate::vulkan::semaphore_list::SemaphoreList;
8+
9+
use super::semaphore_list::SemaphoreListMode;
810

911
fn depth_stencil_required_flags() -> vk::FormatFeatureFlags {
1012
vk::FormatFeatureFlags::SAMPLED_IMAGE | vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT
@@ -1956,8 +1958,6 @@ impl super::Adapter {
19561958
}
19571959
});
19581960

1959-
let swapchain_fn = khr::swapchain::Device::new(&self.instance.raw, &raw_device);
1960-
19611961
// Note that VK_EXT_debug_utils is an instance extension (enabled at the instance
19621962
// level) but contains a few functions that can be loaded directly on the Device for a
19631963
// dispatch-table-less pointer.
@@ -2237,11 +2237,10 @@ impl super::Adapter {
22372237

22382238
let queue = super::Queue {
22392239
raw: raw_queue,
2240-
swapchain_fn,
22412240
device: Arc::clone(&shared),
22422241
family_index,
22432242
relay_semaphores: Mutex::new(relay_semaphores),
2244-
signal_semaphores: Default::default(),
2243+
signal_semaphores: Mutex::new(SemaphoreList::new(SemaphoreListMode::Signal)),
22452244
};
22462245

22472246
let mem_allocator = {
@@ -2563,113 +2562,7 @@ impl crate::Adapter for super::Adapter {
25632562
&self,
25642563
surface: &super::Surface,
25652564
) -> Option<crate::SurfaceCapabilities> {
2566-
if !self.private_caps.can_present {
2567-
return None;
2568-
}
2569-
let queue_family_index = 0; //TODO
2570-
{
2571-
profiling::scope!("vkGetPhysicalDeviceSurfaceSupportKHR");
2572-
match unsafe {
2573-
surface.functor.get_physical_device_surface_support(
2574-
self.raw,
2575-
queue_family_index,
2576-
surface.raw,
2577-
)
2578-
} {
2579-
Ok(true) => (),
2580-
Ok(false) => return None,
2581-
Err(e) => {
2582-
log::error!("get_physical_device_surface_support: {e}");
2583-
return None;
2584-
}
2585-
}
2586-
}
2587-
2588-
let caps = {
2589-
profiling::scope!("vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
2590-
match unsafe {
2591-
surface
2592-
.functor
2593-
.get_physical_device_surface_capabilities(self.raw, surface.raw)
2594-
} {
2595-
Ok(caps) => caps,
2596-
Err(e) => {
2597-
log::error!("get_physical_device_surface_capabilities: {e}");
2598-
return None;
2599-
}
2600-
}
2601-
};
2602-
2603-
// If image count is 0, the support number of images is unlimited.
2604-
let max_image_count = if caps.max_image_count == 0 {
2605-
!0
2606-
} else {
2607-
caps.max_image_count
2608-
};
2609-
2610-
// `0xFFFFFFFF` indicates that the extent depends on the created swapchain.
2611-
let current_extent = if caps.current_extent.width != !0 && caps.current_extent.height != !0
2612-
{
2613-
Some(wgt::Extent3d {
2614-
width: caps.current_extent.width,
2615-
height: caps.current_extent.height,
2616-
depth_or_array_layers: 1,
2617-
})
2618-
} else {
2619-
None
2620-
};
2621-
2622-
let raw_present_modes = {
2623-
profiling::scope!("vkGetPhysicalDeviceSurfacePresentModesKHR");
2624-
match unsafe {
2625-
surface
2626-
.functor
2627-
.get_physical_device_surface_present_modes(self.raw, surface.raw)
2628-
} {
2629-
Ok(present_modes) => present_modes,
2630-
Err(e) => {
2631-
log::error!("get_physical_device_surface_present_modes: {e}");
2632-
// Per definition of `SurfaceCapabilities`, there must be at least one present mode.
2633-
return None;
2634-
}
2635-
}
2636-
};
2637-
2638-
let raw_surface_formats = {
2639-
profiling::scope!("vkGetPhysicalDeviceSurfaceFormatsKHR");
2640-
match unsafe {
2641-
surface
2642-
.functor
2643-
.get_physical_device_surface_formats(self.raw, surface.raw)
2644-
} {
2645-
Ok(formats) => formats,
2646-
Err(e) => {
2647-
log::error!("get_physical_device_surface_formats: {e}");
2648-
// Per definition of `SurfaceCapabilities`, there must be at least one present format.
2649-
return None;
2650-
}
2651-
}
2652-
};
2653-
2654-
let formats = raw_surface_formats
2655-
.into_iter()
2656-
.filter_map(conv::map_vk_surface_formats)
2657-
.collect();
2658-
Some(crate::SurfaceCapabilities {
2659-
formats,
2660-
// TODO: Right now we're always trunkating the swap chain
2661-
// (presumably - we're actually setting the min image count which isn't necessarily the swap chain size)
2662-
// Instead, we should use extensions when available to wait in present.
2663-
// See https://github.com/gfx-rs/wgpu/issues/2869
2664-
maximum_frame_latency: (caps.min_image_count - 1)..=(max_image_count - 1), // Note this can't underflow since both `min_image_count` is at least one and we already patched `max_image_count`.
2665-
current_extent,
2666-
usage: conv::map_vk_image_usage(caps.supported_usage_flags),
2667-
present_modes: raw_present_modes
2668-
.into_iter()
2669-
.flat_map(conv::map_vk_present_mode)
2670-
.collect(),
2671-
composite_alpha_modes: conv::map_vk_composite_alpha(caps.supported_composite_alpha),
2672-
})
2565+
surface.inner.surface_capabilities(self)
26732566
}
26742567

26752568
unsafe fn get_presentation_timestamp(&self) -> wgt::PresentationTimestamp {

wgpu-hal/src/vulkan/device.rs

Lines changed: 1 addition & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use core::{
88
};
99

1010
use arrayvec::ArrayVec;
11-
use ash::{ext, khr, vk};
11+
use ash::{ext, vk};
1212
use hashbrown::hash_map::Entry;
1313
use parking_lot::Mutex;
1414

@@ -489,122 +489,6 @@ struct CompiledStage {
489489
}
490490

491491
impl super::Device {
492-
pub(super) unsafe fn create_swapchain(
493-
&self,
494-
surface: &super::Surface,
495-
config: &crate::SurfaceConfiguration,
496-
provided_old_swapchain: Option<super::Swapchain>,
497-
) -> Result<super::Swapchain, crate::SurfaceError> {
498-
profiling::scope!("Device::create_swapchain");
499-
let functor = khr::swapchain::Device::new(&surface.instance.raw, &self.shared.raw);
500-
501-
let old_swapchain = match provided_old_swapchain {
502-
Some(osc) => osc.raw,
503-
None => vk::SwapchainKHR::null(),
504-
};
505-
506-
let color_space = if config.format == wgt::TextureFormat::Rgba16Float {
507-
// Enable wide color gamut mode
508-
// Vulkan swapchain for Android only supports DISPLAY_P3_NONLINEAR_EXT and EXTENDED_SRGB_LINEAR_EXT
509-
vk::ColorSpaceKHR::EXTENDED_SRGB_LINEAR_EXT
510-
} else {
511-
vk::ColorSpaceKHR::SRGB_NONLINEAR
512-
};
513-
514-
let original_format = self.shared.private_caps.map_texture_format(config.format);
515-
let mut raw_flags = vk::SwapchainCreateFlagsKHR::empty();
516-
let mut raw_view_formats: Vec<vk::Format> = vec![];
517-
if !config.view_formats.is_empty() {
518-
raw_flags |= vk::SwapchainCreateFlagsKHR::MUTABLE_FORMAT;
519-
raw_view_formats = config
520-
.view_formats
521-
.iter()
522-
.map(|f| self.shared.private_caps.map_texture_format(*f))
523-
.collect();
524-
raw_view_formats.push(original_format);
525-
}
526-
527-
let mut info = vk::SwapchainCreateInfoKHR::default()
528-
.flags(raw_flags)
529-
.surface(surface.raw)
530-
.min_image_count(config.maximum_frame_latency + 1) // TODO: https://github.com/gfx-rs/wgpu/issues/2869
531-
.image_format(original_format)
532-
.image_color_space(color_space)
533-
.image_extent(vk::Extent2D {
534-
width: config.extent.width,
535-
height: config.extent.height,
536-
})
537-
.image_array_layers(config.extent.depth_or_array_layers)
538-
.image_usage(conv::map_texture_usage(config.usage))
539-
.image_sharing_mode(vk::SharingMode::EXCLUSIVE)
540-
.pre_transform(vk::SurfaceTransformFlagsKHR::IDENTITY)
541-
.composite_alpha(conv::map_composite_alpha_mode(config.composite_alpha_mode))
542-
.present_mode(conv::map_present_mode(config.present_mode))
543-
.clipped(true)
544-
.old_swapchain(old_swapchain);
545-
546-
let mut format_list_info = vk::ImageFormatListCreateInfo::default();
547-
if !raw_view_formats.is_empty() {
548-
format_list_info = format_list_info.view_formats(&raw_view_formats);
549-
info = info.push_next(&mut format_list_info);
550-
}
551-
552-
let result = {
553-
profiling::scope!("vkCreateSwapchainKHR");
554-
unsafe { functor.create_swapchain(&info, None) }
555-
};
556-
557-
// doing this before bailing out with error
558-
if old_swapchain != vk::SwapchainKHR::null() {
559-
unsafe { functor.destroy_swapchain(old_swapchain, None) }
560-
}
561-
562-
let raw = match result {
563-
Ok(swapchain) => swapchain,
564-
Err(error) => {
565-
return Err(match error {
566-
vk::Result::ERROR_SURFACE_LOST_KHR
567-
| vk::Result::ERROR_INITIALIZATION_FAILED => crate::SurfaceError::Lost,
568-
vk::Result::ERROR_NATIVE_WINDOW_IN_USE_KHR => {
569-
crate::SurfaceError::Other("Native window is in use")
570-
}
571-
// We don't use VK_EXT_image_compression_control
572-
// VK_ERROR_COMPRESSION_EXHAUSTED_EXT
573-
other => super::map_host_device_oom_and_lost_err(other).into(),
574-
});
575-
}
576-
};
577-
578-
let images =
579-
unsafe { functor.get_swapchain_images(raw) }.map_err(super::map_host_device_oom_err)?;
580-
581-
// NOTE: It's important that we define the same number of acquire/present semaphores
582-
// as we will need to index into them with the image index.
583-
let acquire_semaphores = (0..=images.len())
584-
.map(|i| {
585-
super::SwapchainAcquireSemaphore::new(&self.shared, i)
586-
.map(Mutex::new)
587-
.map(Arc::new)
588-
})
589-
.collect::<Result<Vec<_>, _>>()?;
590-
591-
let present_semaphores = (0..=images.len())
592-
.map(|i| Arc::new(Mutex::new(super::SwapchainPresentSemaphores::new(i))))
593-
.collect::<Vec<_>>();
594-
595-
Ok(super::Swapchain {
596-
raw,
597-
functor,
598-
device: Arc::clone(&self.shared),
599-
images,
600-
config: config.clone(),
601-
acquire_semaphores,
602-
next_acquire_index: 0,
603-
present_semaphores,
604-
next_present_time: None,
605-
})
606-
}
607-
608492
/// # Safety
609493
///
610494
/// - `vk_image` must be created respecting `desc`

0 commit comments

Comments
 (0)