Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 5 additions & 112 deletions wgpu-hal/src/vulkan/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use core::{ffi::CStr, marker::PhantomData};
use ash::{ext, google, khr, vk};
use parking_lot::Mutex;

use super::conv;
use crate::vulkan::semaphore_list::SemaphoreList;

use super::semaphore_list::SemaphoreListMode;

fn depth_stencil_required_flags() -> vk::FormatFeatureFlags {
vk::FormatFeatureFlags::SAMPLED_IMAGE | vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT
Expand Down Expand Up @@ -1956,8 +1958,6 @@ impl super::Adapter {
}
});

let swapchain_fn = khr::swapchain::Device::new(&self.instance.raw, &raw_device);

// Note that VK_EXT_debug_utils is an instance extension (enabled at the instance
// level) but contains a few functions that can be loaded directly on the Device for a
// dispatch-table-less pointer.
Expand Down Expand Up @@ -2237,11 +2237,10 @@ impl super::Adapter {

let queue = super::Queue {
raw: raw_queue,
swapchain_fn,
device: Arc::clone(&shared),
family_index,
relay_semaphores: Mutex::new(relay_semaphores),
signal_semaphores: Default::default(),
signal_semaphores: Mutex::new(SemaphoreList::new(SemaphoreListMode::Signal)),
};

let mem_allocator = {
Expand Down Expand Up @@ -2563,113 +2562,7 @@ impl crate::Adapter for super::Adapter {
&self,
surface: &super::Surface,
) -> Option<crate::SurfaceCapabilities> {
if !self.private_caps.can_present {
return None;
}
let queue_family_index = 0; //TODO
{
profiling::scope!("vkGetPhysicalDeviceSurfaceSupportKHR");
match unsafe {
surface.functor.get_physical_device_surface_support(
self.raw,
queue_family_index,
surface.raw,
)
} {
Ok(true) => (),
Ok(false) => return None,
Err(e) => {
log::error!("get_physical_device_surface_support: {e}");
return None;
}
}
}

let caps = {
profiling::scope!("vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
match unsafe {
surface
.functor
.get_physical_device_surface_capabilities(self.raw, surface.raw)
} {
Ok(caps) => caps,
Err(e) => {
log::error!("get_physical_device_surface_capabilities: {e}");
return None;
}
}
};

// If image count is 0, the support number of images is unlimited.
let max_image_count = if caps.max_image_count == 0 {
!0
} else {
caps.max_image_count
};

// `0xFFFFFFFF` indicates that the extent depends on the created swapchain.
let current_extent = if caps.current_extent.width != !0 && caps.current_extent.height != !0
{
Some(wgt::Extent3d {
width: caps.current_extent.width,
height: caps.current_extent.height,
depth_or_array_layers: 1,
})
} else {
None
};

let raw_present_modes = {
profiling::scope!("vkGetPhysicalDeviceSurfacePresentModesKHR");
match unsafe {
surface
.functor
.get_physical_device_surface_present_modes(self.raw, surface.raw)
} {
Ok(present_modes) => present_modes,
Err(e) => {
log::error!("get_physical_device_surface_present_modes: {e}");
// Per definition of `SurfaceCapabilities`, there must be at least one present mode.
return None;
}
}
};

let raw_surface_formats = {
profiling::scope!("vkGetPhysicalDeviceSurfaceFormatsKHR");
match unsafe {
surface
.functor
.get_physical_device_surface_formats(self.raw, surface.raw)
} {
Ok(formats) => formats,
Err(e) => {
log::error!("get_physical_device_surface_formats: {e}");
// Per definition of `SurfaceCapabilities`, there must be at least one present format.
return None;
}
}
};

let formats = raw_surface_formats
.into_iter()
.filter_map(conv::map_vk_surface_formats)
.collect();
Some(crate::SurfaceCapabilities {
formats,
// TODO: Right now we're always trunkating the swap chain
// (presumably - we're actually setting the min image count which isn't necessarily the swap chain size)
// Instead, we should use extensions when available to wait in present.
// See https://github.com/gfx-rs/wgpu/issues/2869
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`.
current_extent,
usage: conv::map_vk_image_usage(caps.supported_usage_flags),
present_modes: raw_present_modes
.into_iter()
.flat_map(conv::map_vk_present_mode)
.collect(),
composite_alpha_modes: conv::map_vk_composite_alpha(caps.supported_composite_alpha),
})
surface.inner.surface_capabilities(self)
}

unsafe fn get_presentation_timestamp(&self) -> wgt::PresentationTimestamp {
Expand Down
118 changes: 1 addition & 117 deletions wgpu-hal/src/vulkan/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use core::{
};

use arrayvec::ArrayVec;
use ash::{ext, khr, vk};
use ash::{ext, vk};
use hashbrown::hash_map::Entry;
use parking_lot::Mutex;

Expand Down Expand Up @@ -489,122 +489,6 @@ struct CompiledStage {
}

impl super::Device {
pub(super) unsafe fn create_swapchain(
&self,
surface: &super::Surface,
config: &crate::SurfaceConfiguration,
provided_old_swapchain: Option<super::Swapchain>,
) -> Result<super::Swapchain, crate::SurfaceError> {
profiling::scope!("Device::create_swapchain");
let functor = khr::swapchain::Device::new(&surface.instance.raw, &self.shared.raw);

let old_swapchain = match provided_old_swapchain {
Some(osc) => osc.raw,
None => vk::SwapchainKHR::null(),
};

let color_space = if config.format == wgt::TextureFormat::Rgba16Float {
// Enable wide color gamut mode
// Vulkan swapchain for Android only supports DISPLAY_P3_NONLINEAR_EXT and EXTENDED_SRGB_LINEAR_EXT
vk::ColorSpaceKHR::EXTENDED_SRGB_LINEAR_EXT
} else {
vk::ColorSpaceKHR::SRGB_NONLINEAR
};

let original_format = self.shared.private_caps.map_texture_format(config.format);
let mut raw_flags = vk::SwapchainCreateFlagsKHR::empty();
let mut raw_view_formats: Vec<vk::Format> = vec![];
if !config.view_formats.is_empty() {
raw_flags |= vk::SwapchainCreateFlagsKHR::MUTABLE_FORMAT;
raw_view_formats = config
.view_formats
.iter()
.map(|f| self.shared.private_caps.map_texture_format(*f))
.collect();
raw_view_formats.push(original_format);
}

let mut info = vk::SwapchainCreateInfoKHR::default()
.flags(raw_flags)
.surface(surface.raw)
.min_image_count(config.maximum_frame_latency + 1) // TODO: https://github.com/gfx-rs/wgpu/issues/2869
.image_format(original_format)
.image_color_space(color_space)
.image_extent(vk::Extent2D {
width: config.extent.width,
height: config.extent.height,
})
.image_array_layers(config.extent.depth_or_array_layers)
.image_usage(conv::map_texture_usage(config.usage))
.image_sharing_mode(vk::SharingMode::EXCLUSIVE)
.pre_transform(vk::SurfaceTransformFlagsKHR::IDENTITY)
.composite_alpha(conv::map_composite_alpha_mode(config.composite_alpha_mode))
.present_mode(conv::map_present_mode(config.present_mode))
.clipped(true)
.old_swapchain(old_swapchain);

let mut format_list_info = vk::ImageFormatListCreateInfo::default();
if !raw_view_formats.is_empty() {
format_list_info = format_list_info.view_formats(&raw_view_formats);
info = info.push_next(&mut format_list_info);
}

let result = {
profiling::scope!("vkCreateSwapchainKHR");
unsafe { functor.create_swapchain(&info, None) }
};

// doing this before bailing out with error
if old_swapchain != vk::SwapchainKHR::null() {
unsafe { functor.destroy_swapchain(old_swapchain, None) }
}

let raw = match result {
Ok(swapchain) => swapchain,
Err(error) => {
return Err(match error {
vk::Result::ERROR_SURFACE_LOST_KHR
| vk::Result::ERROR_INITIALIZATION_FAILED => crate::SurfaceError::Lost,
vk::Result::ERROR_NATIVE_WINDOW_IN_USE_KHR => {
crate::SurfaceError::Other("Native window is in use")
}
// We don't use VK_EXT_image_compression_control
// VK_ERROR_COMPRESSION_EXHAUSTED_EXT
other => super::map_host_device_oom_and_lost_err(other).into(),
});
}
};

let images =
unsafe { functor.get_swapchain_images(raw) }.map_err(super::map_host_device_oom_err)?;

// NOTE: It's important that we define the same number of acquire/present semaphores
// as we will need to index into them with the image index.
let acquire_semaphores = (0..=images.len())
.map(|i| {
super::SwapchainAcquireSemaphore::new(&self.shared, i)
.map(Mutex::new)
.map(Arc::new)
})
.collect::<Result<Vec<_>, _>>()?;

let present_semaphores = (0..=images.len())
.map(|i| Arc::new(Mutex::new(super::SwapchainPresentSemaphores::new(i))))
.collect::<Vec<_>>();

Ok(super::Swapchain {
raw,
functor,
device: Arc::clone(&self.shared),
images,
config: config.clone(),
acquire_semaphores,
next_acquire_index: 0,
present_semaphores,
next_present_time: None,
})
}

/// # Safety
///
/// - `vk_image` must be created respecting `desc`
Expand Down
Loading