instance refactor
This commit is contained in:
parent
c1c69d5e54
commit
41e4a2ed9c
|
|
@ -238,7 +238,7 @@ impl DeviceBuilder {
|
||||||
match display_handle {
|
match display_handle {
|
||||||
RawDisplayHandle::Xlib(display) => {
|
RawDisplayHandle::Xlib(display) => {
|
||||||
let surface =
|
let surface =
|
||||||
ash::khr::xlib_surface::Instance::new(&instance.entry, &instance.instance);
|
ash::khr::xlib_surface::Instance::new(&instance.entry, &instance.raw);
|
||||||
surface.get_physical_device_xlib_presentation_support(
|
surface.get_physical_device_xlib_presentation_support(
|
||||||
pdev,
|
pdev,
|
||||||
queue_family,
|
queue_family,
|
||||||
|
|
@ -249,10 +249,8 @@ impl DeviceBuilder {
|
||||||
}
|
}
|
||||||
RawDisplayHandle::Xcb(_xcb_display_handle) => todo!("xcb"),
|
RawDisplayHandle::Xcb(_xcb_display_handle) => todo!("xcb"),
|
||||||
RawDisplayHandle::Wayland(wayland_display_handle) => {
|
RawDisplayHandle::Wayland(wayland_display_handle) => {
|
||||||
let surface = ash::khr::wayland_surface::Instance::new(
|
let surface =
|
||||||
&instance.entry,
|
ash::khr::wayland_surface::Instance::new(&instance.entry, &instance.raw);
|
||||||
&instance.instance,
|
|
||||||
);
|
|
||||||
surface.get_physical_device_wayland_presentation_support(
|
surface.get_physical_device_wayland_presentation_support(
|
||||||
pdev,
|
pdev,
|
||||||
queue_family,
|
queue_family,
|
||||||
|
|
@ -263,7 +261,7 @@ impl DeviceBuilder {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
RawDisplayHandle::Windows(_) => {
|
RawDisplayHandle::Windows(_) => {
|
||||||
ash::khr::win32_surface::Instance::new(&instance.entry, &instance.instance)
|
ash::khr::win32_surface::Instance::new(&instance.entry, &instance.raw)
|
||||||
.get_physical_device_win32_presentation_support(pdev, queue_family)
|
.get_physical_device_win32_presentation_support(pdev, queue_family)
|
||||||
}
|
}
|
||||||
_ => panic!("unsupported platform"),
|
_ => panic!("unsupported platform"),
|
||||||
|
|
@ -278,7 +276,7 @@ impl DeviceBuilder {
|
||||||
) -> DeviceQueueFamilies {
|
) -> DeviceQueueFamilies {
|
||||||
let queue_familiy_properties = unsafe {
|
let queue_familiy_properties = unsafe {
|
||||||
instance
|
instance
|
||||||
.instance
|
.raw
|
||||||
.get_physical_device_queue_family_properties(pdev)
|
.get_physical_device_queue_family_properties(pdev)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -461,7 +459,7 @@ impl DeviceBuilder {
|
||||||
requirements: &PhysicalDeviceFeatures,
|
requirements: &PhysicalDeviceFeatures,
|
||||||
extra_properties: Vec<Box<dyn ExtendsDeviceProperties2Debug>>,
|
extra_properties: Vec<Box<dyn ExtendsDeviceProperties2Debug>>,
|
||||||
) -> Result<PhysicalDevice> {
|
) -> Result<PhysicalDevice> {
|
||||||
let pdevs = unsafe { instance.instance.enumerate_physical_devices()? };
|
let pdevs = unsafe { instance.raw.enumerate_physical_devices()? };
|
||||||
|
|
||||||
let (pdev, properties) = pdevs
|
let (pdev, properties) = pdevs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -472,7 +470,7 @@ impl DeviceBuilder {
|
||||||
.map(|b| dyn_clone::clone_box(&**b))
|
.map(|b| dyn_clone::clone_box(&**b))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
);
|
);
|
||||||
props.query(&instance.instance, pdev);
|
props.query(&instance.raw, pdev);
|
||||||
|
|
||||||
(pdev, props)
|
(pdev, props)
|
||||||
})
|
})
|
||||||
|
|
@ -483,8 +481,7 @@ impl DeviceBuilder {
|
||||||
// TODO: figure out a way to fall back to some
|
// TODO: figure out a way to fall back to some
|
||||||
// device which doesn't support all of the extensions.
|
// device which doesn't support all of the extensions.
|
||||||
.filter(|(pdev, _)| {
|
.filter(|(pdev, _)| {
|
||||||
let query_features =
|
let query_features = PhysicalDeviceFeatures::query(&instance.raw, *pdev).unwrap();
|
||||||
PhysicalDeviceFeatures::query(&instance.instance, *pdev).unwrap();
|
|
||||||
|
|
||||||
requirements.compatible_with(&query_features)
|
requirements.compatible_with(&query_features)
|
||||||
})
|
})
|
||||||
|
|
@ -794,30 +791,32 @@ impl Device {
|
||||||
|
|
||||||
let instance = unsafe { entry.create_instance(&create_info, None)? };
|
let instance = unsafe { entry.create_instance(&create_info, None)? };
|
||||||
|
|
||||||
let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::default()
|
let debug_utils = {
|
||||||
.message_severity(
|
let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::default()
|
||||||
vk::DebugUtilsMessageSeverityFlagsEXT::ERROR
|
.message_severity(
|
||||||
| vk::DebugUtilsMessageSeverityFlagsEXT::WARNING
|
vk::DebugUtilsMessageSeverityFlagsEXT::ERROR
|
||||||
| vk::DebugUtilsMessageSeverityFlagsEXT::INFO,
|
| vk::DebugUtilsMessageSeverityFlagsEXT::WARNING
|
||||||
)
|
| vk::DebugUtilsMessageSeverityFlagsEXT::INFO,
|
||||||
.message_type(
|
)
|
||||||
vk::DebugUtilsMessageTypeFlagsEXT::GENERAL
|
.message_type(
|
||||||
| vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION
|
vk::DebugUtilsMessageTypeFlagsEXT::GENERAL
|
||||||
| vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE,
|
| vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION
|
||||||
)
|
| vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE,
|
||||||
.pfn_user_callback(Some(crate::debug::debug_callback));
|
)
|
||||||
|
.pfn_user_callback(Some(crate::debug::debug_callback));
|
||||||
|
|
||||||
let debug_utils_instance = ash::ext::debug_utils::Instance::new(&entry, &instance);
|
let instance = ext::debug_utils::Instance::new(&entry, &instance);
|
||||||
let debug_utils_messenger =
|
let messenger = unsafe { instance.create_debug_utils_messenger(&debug_info, None)? };
|
||||||
unsafe { debug_utils_instance.create_debug_utils_messenger(&debug_info, None)? };
|
|
||||||
|
|
||||||
let surface_instance = ash::khr::surface::Instance::new(&entry, &instance);
|
crate::DebugUtils {
|
||||||
|
instance,
|
||||||
|
messenger,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let instance = Arc::new(Instance {
|
let instance = Arc::new(Instance {
|
||||||
instance,
|
raw: instance,
|
||||||
debug_utils: debug_utils_instance,
|
_debug_utils: debug_utils,
|
||||||
debug_utils_messenger,
|
|
||||||
surface: surface_instance,
|
|
||||||
entry,
|
entry,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -885,7 +884,7 @@ impl Device {
|
||||||
tracing::debug!("creating device: {:#?}", device_info);
|
tracing::debug!("creating device: {:#?}", device_info);
|
||||||
let device = unsafe {
|
let device = unsafe {
|
||||||
let device = instance
|
let device = instance
|
||||||
.instance
|
.raw
|
||||||
.create_device(physical.pdev, &device_info, None)?;
|
.create_device(physical.pdev, &device_info, None)?;
|
||||||
|
|
||||||
tracing::debug!("allocating queues: {queue_infos:#?}");
|
tracing::debug!("allocating queues: {queue_infos:#?}");
|
||||||
|
|
@ -919,15 +918,15 @@ impl Device {
|
||||||
let transfer_queue = get_queue(physical.queue_families.transfer);
|
let transfer_queue = get_queue(physical.queue_families.transfer);
|
||||||
|
|
||||||
let alloc_info =
|
let alloc_info =
|
||||||
vk_mem::AllocatorCreateInfo::new(&instance.instance, &device, physical.pdev);
|
vk_mem::AllocatorCreateInfo::new(&instance.raw, &device, physical.pdev);
|
||||||
|
|
||||||
let alloc = vk_mem::Allocator::new(alloc_info)?;
|
let alloc = vk_mem::Allocator::new(alloc_info)?;
|
||||||
|
|
||||||
DeviceInner {
|
DeviceInner {
|
||||||
device: DeviceWrapper(device.clone()),
|
device: DeviceWrapper(device.clone()),
|
||||||
physical,
|
physical,
|
||||||
swapchain: khr::swapchain::Device::new(&instance.instance, &device),
|
swapchain: khr::swapchain::Device::new(&instance.raw, &device),
|
||||||
debug_utils: ash::ext::debug_utils::Device::new(&instance.instance, &device),
|
debug_utils: ash::ext::debug_utils::Device::new(&instance.raw, &device),
|
||||||
instance,
|
instance,
|
||||||
alloc,
|
alloc,
|
||||||
allocated_queues,
|
allocated_queues,
|
||||||
|
|
|
||||||
1
crates/renderer/src/instance.rs
Normal file
1
crates/renderer/src/instance.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
|
|
@ -13,7 +13,7 @@ use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
||||||
use parking_lot::{Mutex, MutexGuard};
|
use parking_lot::{Mutex, MutexGuard};
|
||||||
|
|
||||||
use ash::{
|
use ash::{
|
||||||
Entry,
|
Entry, ext,
|
||||||
prelude::VkResult,
|
prelude::VkResult,
|
||||||
vk::{self},
|
vk::{self},
|
||||||
};
|
};
|
||||||
|
|
@ -28,6 +28,7 @@ pub mod device;
|
||||||
#[path = "egui.rs"]
|
#[path = "egui.rs"]
|
||||||
mod egui_pass;
|
mod egui_pass;
|
||||||
mod images;
|
mod images;
|
||||||
|
pub mod instance;
|
||||||
mod memory;
|
mod memory;
|
||||||
mod pipeline;
|
mod pipeline;
|
||||||
pub mod render_graph;
|
pub mod render_graph;
|
||||||
|
|
@ -434,32 +435,29 @@ pub struct PhysicalDevice {
|
||||||
properties: PhysicalDeviceProperties,
|
properties: PhysicalDeviceProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Instance {
|
struct DebugUtils {
|
||||||
entry: Entry,
|
instance: ext::debug_utils::Instance,
|
||||||
instance: ash::Instance,
|
messenger: vk::DebugUtilsMessengerEXT,
|
||||||
debug_utils: ash::ext::debug_utils::Instance,
|
|
||||||
debug_utils_messenger: vk::DebugUtilsMessengerEXT,
|
|
||||||
surface: ash::khr::surface::Instance,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Instance {
|
impl Drop for DebugUtils {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.debug_utils
|
self.instance
|
||||||
.destroy_debug_utils_messenger(self.debug_utils_messenger, None);
|
.destroy_debug_utils_messenger(self.messenger, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<ash::Instance> for Instance {
|
pub struct DebugUtilsCreateInfo {
|
||||||
fn as_ref(&self) -> &ash::Instance {
|
pub severity: vk::DebugUtilsMessageSeverityFlagsEXT,
|
||||||
&self.instance
|
pub message_type: vk::DebugUtilsMessageTypeFlagsEXT,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl AsRef<ash::khr::surface::Instance> for Instance {
|
|
||||||
fn as_ref(&self) -> &ash::khr::surface::Instance {
|
pub struct Instance {
|
||||||
&self.surface
|
entry: Entry,
|
||||||
}
|
raw: ash::Instance,
|
||||||
|
_debug_utils: DebugUtils,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SamplerCache {
|
pub struct SamplerCache {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use derive_more::Debug;
|
use derive_more::Debug;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Surface {
|
pub struct Surface {
|
||||||
raw: vk::SurfaceKHR,
|
raw: vk::SurfaceKHR,
|
||||||
|
|
@ -41,8 +42,8 @@ impl Surface {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn headless(instance: &Arc<Instance>) -> Result<Self> {
|
pub fn headless(instance: &Arc<Instance>) -> Result<Self> {
|
||||||
let headless_instance =
|
let headless_instance =
|
||||||
ash::ext::headless_surface::Instance::new(&instance.entry, &instance.instance);
|
ash::ext::headless_surface::Instance::new(&instance.entry, &instance.raw);
|
||||||
let functor = khr::surface::Instance::new(&instance.entry, &instance.instance);
|
let functor = khr::surface::Instance::new(&instance.entry, &instance.raw);
|
||||||
|
|
||||||
// SAFETY: the headless surface does not have any platform-specific requirements, and does not depend on any external handles, so it is safe to create without additional guarantees.
|
// SAFETY: the headless surface does not have any platform-specific requirements, and does not depend on any external handles, so it is safe to create without additional guarantees.
|
||||||
// (note): ash marks this function as unsafe, likely because of
|
// (note): ash marks this function as unsafe, likely because of
|
||||||
|
|
@ -70,12 +71,12 @@ impl Surface {
|
||||||
display_handle: RawDisplayHandle,
|
display_handle: RawDisplayHandle,
|
||||||
window_handle: RawWindowHandle,
|
window_handle: RawWindowHandle,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let functor = khr::surface::Instance::new(&instance.entry, &instance.instance);
|
let functor = khr::surface::Instance::new(&instance.entry, &instance.raw);
|
||||||
// SAFETY: the caller guarantees the validity of the display and window handles, and that they remain valid for the lifetime of the surface.
|
// SAFETY: the caller guarantees the validity of the display and window handles, and that they remain valid for the lifetime of the surface.
|
||||||
let surface = unsafe {
|
let surface = unsafe {
|
||||||
ash_window::create_surface(
|
ash_window::create_surface(
|
||||||
&instance.entry,
|
&instance.entry,
|
||||||
&instance.instance,
|
&instance.raw,
|
||||||
display_handle,
|
display_handle,
|
||||||
window_handle,
|
window_handle,
|
||||||
None,
|
None,
|
||||||
|
|
@ -87,6 +88,60 @@ impl Surface {
|
||||||
functor,
|
functor,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_swapchain_params(
|
||||||
|
&self,
|
||||||
|
pdev: vk::PhysicalDevice,
|
||||||
|
requested_extent: Option<vk::Extent2D>,
|
||||||
|
) -> Result<SwapchainParams> {
|
||||||
|
let functor = &self.functor;
|
||||||
|
let raw = self.raw;
|
||||||
|
let caps = unsafe { functor.get_physical_device_surface_capabilities(pdev, raw)? };
|
||||||
|
let formats = unsafe { functor.get_physical_device_surface_formats(pdev, raw)? };
|
||||||
|
let present_modes =
|
||||||
|
unsafe { functor.get_physical_device_surface_present_modes(pdev, raw)? };
|
||||||
|
|
||||||
|
let present_mode = present_modes
|
||||||
|
.iter()
|
||||||
|
.find(|&mode| mode == &vk::PresentModeKHR::MAILBOX)
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or(vk::PresentModeKHR::FIFO);
|
||||||
|
|
||||||
|
let format = formats
|
||||||
|
.iter()
|
||||||
|
.max_by_key(|&&format| {
|
||||||
|
let is_rgba_unorm = format.format == vk::Format::R8G8B8A8_UNORM
|
||||||
|
|| format.format == vk::Format::B8G8R8A8_UNORM;
|
||||||
|
let is_srgb = format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR;
|
||||||
|
is_rgba_unorm as u8 * 10 + is_srgb as u8
|
||||||
|
})
|
||||||
|
.or(formats.first())
|
||||||
|
.cloned()
|
||||||
|
.expect("no surface format available!");
|
||||||
|
|
||||||
|
// 0 here means no limit
|
||||||
|
let max_image_count = core::num::NonZero::new(caps.max_image_count)
|
||||||
|
.map(|n| n.get())
|
||||||
|
.unwrap_or(u32::MAX);
|
||||||
|
|
||||||
|
// we want PREFERRED_IMAGES_IN_FLIGHT images acquired at the same time,
|
||||||
|
let image_count =
|
||||||
|
(caps.min_image_count + Swapchain::PREFERRED_IMAGES_IN_FLIGHT).min(max_image_count);
|
||||||
|
|
||||||
|
let extent = current_extent_or_clamped(
|
||||||
|
&caps,
|
||||||
|
requested_extent.unwrap_or(vk::Extent2D::default().width(1).height(1)),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(SwapchainParams {
|
||||||
|
present_mode,
|
||||||
|
format: format.format,
|
||||||
|
color_space: format.color_space,
|
||||||
|
image_count,
|
||||||
|
extent,
|
||||||
|
min_image_count: caps.min_image_count,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
define_device_owned_handle! {
|
define_device_owned_handle! {
|
||||||
|
|
@ -162,70 +217,6 @@ impl core::fmt::Debug for Swapchain {
|
||||||
impl Swapchain {
|
impl Swapchain {
|
||||||
const PREFERRED_IMAGES_IN_FLIGHT: u32 = 3;
|
const PREFERRED_IMAGES_IN_FLIGHT: u32 = 3;
|
||||||
|
|
||||||
fn get_swapchain_params_from_surface(
|
|
||||||
instance: &Arc<Instance>,
|
|
||||||
surface: vk::SurfaceKHR,
|
|
||||||
pdev: vk::PhysicalDevice,
|
|
||||||
requested_extent: Option<vk::Extent2D>,
|
|
||||||
) -> Result<SwapchainParams> {
|
|
||||||
let caps = unsafe {
|
|
||||||
instance
|
|
||||||
.surface
|
|
||||||
.get_physical_device_surface_capabilities(pdev, surface)?
|
|
||||||
};
|
|
||||||
let formats = unsafe {
|
|
||||||
instance
|
|
||||||
.surface
|
|
||||||
.get_physical_device_surface_formats(pdev, surface)?
|
|
||||||
};
|
|
||||||
let present_modes = unsafe {
|
|
||||||
instance
|
|
||||||
.surface
|
|
||||||
.get_physical_device_surface_present_modes(pdev, surface)?
|
|
||||||
};
|
|
||||||
|
|
||||||
let present_mode = present_modes
|
|
||||||
.iter()
|
|
||||||
.find(|&mode| mode == &vk::PresentModeKHR::MAILBOX)
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or(vk::PresentModeKHR::FIFO);
|
|
||||||
|
|
||||||
let format = formats
|
|
||||||
.iter()
|
|
||||||
.max_by_key(|&&format| {
|
|
||||||
let is_rgba_unorm = format.format == vk::Format::R8G8B8A8_UNORM
|
|
||||||
|| format.format == vk::Format::B8G8R8A8_UNORM;
|
|
||||||
let is_srgb = format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR;
|
|
||||||
is_rgba_unorm as u8 * 10 + is_srgb as u8
|
|
||||||
})
|
|
||||||
.or(formats.first())
|
|
||||||
.cloned()
|
|
||||||
.expect("no surface format available!");
|
|
||||||
|
|
||||||
// 0 here means no limit
|
|
||||||
let max_image_count = core::num::NonZero::new(caps.max_image_count)
|
|
||||||
.map(|n| n.get())
|
|
||||||
.unwrap_or(u32::MAX);
|
|
||||||
|
|
||||||
// we want PREFERRED_IMAGES_IN_FLIGHT images acquired at the same time,
|
|
||||||
let image_count =
|
|
||||||
(caps.min_image_count + Self::PREFERRED_IMAGES_IN_FLIGHT).min(max_image_count);
|
|
||||||
|
|
||||||
let extent = current_extent_or_clamped(
|
|
||||||
&caps,
|
|
||||||
requested_extent.unwrap_or(vk::Extent2D::default().width(1).height(1)),
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(SwapchainParams {
|
|
||||||
present_mode,
|
|
||||||
format: format.format,
|
|
||||||
color_space: format.color_space,
|
|
||||||
image_count,
|
|
||||||
extent,
|
|
||||||
min_image_count: caps.min_image_count,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: Device,
|
device: Device,
|
||||||
surface: Arc<Surface>,
|
surface: Arc<Surface>,
|
||||||
|
|
@ -249,7 +240,7 @@ impl Swapchain {
|
||||||
image_count,
|
image_count,
|
||||||
min_image_count,
|
min_image_count,
|
||||||
extent,
|
extent,
|
||||||
} = Self::get_swapchain_params_from_surface(device.instance(), surface.raw, pdev, extent)?;
|
} = surface.get_swapchain_params(pdev, extent)?;
|
||||||
|
|
||||||
let (swapchain, images) = {
|
let (swapchain, images) = {
|
||||||
let lock = old_swapchain.as_ref().map(|handle| handle.lock());
|
let lock = old_swapchain.as_ref().map(|handle| handle.lock());
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue