Add window surface, fix rendering of logical device on mac
This commit is contained in:
parent
9713441c2e
commit
2c5928dac4
@ -14,5 +14,5 @@ png = "0.17"
|
||||
pretty_env_logger = "0.4"
|
||||
thiserror = "1"
|
||||
tobj = { version = "3", features = ["log"] }
|
||||
vulkanalia = { version = "=0.16.0", features = ["libloading", "window"] }
|
||||
vulkanalia = { version = "=0.16.0", features = ["libloading", "window", "provisional"] }
|
||||
winit = "0.27"
|
||||
|
25
src/app.rs
25
src/app.rs
@ -8,6 +8,8 @@ use ::thiserror::Error;
|
||||
use ::vulkanalia::loader::{LibloadingLoader, LIBRARY};
|
||||
use ::vulkanalia::prelude::v1_0::*;
|
||||
use ::vulkanalia::vk::ExtDebugUtilsExtension;
|
||||
use ::vulkanalia::vk::KhrSurfaceExtension;
|
||||
use ::vulkanalia::window as vk_window;
|
||||
use ::winit::window::Window;
|
||||
|
||||
/// Our Vulkan app.
|
||||
@ -26,6 +28,7 @@ impl App {
|
||||
let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?;
|
||||
let mut data = AppData::default();
|
||||
let instance = create_instance(window, &entry, &mut data)?;
|
||||
data.surface = vk_window::create_surface(&instance, window)?;
|
||||
pick_physical_device(&instance, &mut data)?;
|
||||
let device = create_logical_device(&instance, &mut data)?;
|
||||
|
||||
@ -51,6 +54,7 @@ impl App {
|
||||
.destroy_debug_utils_messenger_ext(self.data.messenger, None);
|
||||
}
|
||||
|
||||
self.instance.destroy_surface_khr(self.data.surface, None);
|
||||
self.instance.destroy_instance(None);
|
||||
}
|
||||
}
|
||||
@ -58,9 +62,13 @@ impl App {
|
||||
/// The Vulkan handles and associated properties used by our Vulkan app.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct AppData {
|
||||
surface: vk::SurfaceKHR,
|
||||
// Debug
|
||||
messenger: vk::DebugUtilsMessengerEXT,
|
||||
// Physical Device / Logical Device
|
||||
physical_device: vk::PhysicalDevice,
|
||||
graphics_queue: vk::Queue,
|
||||
present_queue: vk::Queue,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@ -70,6 +78,7 @@ pub struct SuitabilityError(pub &'static str);
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub(crate) struct QueueFamilyIndicies {
|
||||
graphics: u32,
|
||||
present: u32,
|
||||
}
|
||||
|
||||
impl QueueFamilyIndicies {
|
||||
@ -85,8 +94,20 @@ impl QueueFamilyIndicies {
|
||||
.position(|p| p.queue_flags.contains(vk::QueueFlags::GRAPHICS))
|
||||
.map(|i| i as u32);
|
||||
|
||||
if let Some(graphics) = graphics {
|
||||
Ok(Self { graphics })
|
||||
let mut present = None;
|
||||
for (index, properties) in properties.iter().enumerate() {
|
||||
if instance.get_physical_device_surface_support_khr(
|
||||
physical_device,
|
||||
index as u32,
|
||||
data.surface,
|
||||
)? {
|
||||
present = Some(index as u32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if let (Some(graphics), Some(present)) = (graphics, present) {
|
||||
Ok(Self { graphics, present })
|
||||
} else {
|
||||
Err(anyhow!(SuitabilityError(
|
||||
"Missing required queue families."
|
||||
|
@ -37,6 +37,7 @@ pub(super) unsafe fn create_instance(
|
||||
entry: &Entry,
|
||||
data: &mut AppData,
|
||||
) -> Result<Instance> {
|
||||
// Application Info
|
||||
let application_info = vk::ApplicationInfo::builder()
|
||||
.application_name(b"Vulkan Tutorial\0")
|
||||
.application_version(vk::make_version(1, 0, 0))
|
||||
@ -44,6 +45,7 @@ pub(super) unsafe fn create_instance(
|
||||
.engine_version(vk::make_version(1, 0, 0))
|
||||
.api_version(vk::make_version(1, 0, 0));
|
||||
|
||||
// Layers
|
||||
let available_layers = entry
|
||||
.enumerate_instance_layer_properties()?
|
||||
.iter()
|
||||
@ -60,6 +62,7 @@ pub(super) unsafe fn create_instance(
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
// Extensions
|
||||
let mut extensions = vk_window::get_required_instance_extensions(window)
|
||||
.iter()
|
||||
.map(|e| e.as_ptr())
|
||||
@ -75,11 +78,17 @@ pub(super) unsafe fn create_instance(
|
||||
.any(|e| e.extension_name == vk::KHR_PORTABILITY_ENUMERATION_EXTENSION.name)
|
||||
{
|
||||
extensions.push(vk::KHR_PORTABILITY_ENUMERATION_EXTENSION.name.as_ptr());
|
||||
extensions.push(
|
||||
vk::KHR_GET_PHYSICAL_DEVICE_PROPERTIES2_EXTENSION
|
||||
.name
|
||||
.as_ptr(),
|
||||
);
|
||||
vk::InstanceCreateFlags::ENUMERATE_PORTABILITY_KHR
|
||||
} else {
|
||||
vk::InstanceCreateFlags::empty()
|
||||
};
|
||||
|
||||
// Create
|
||||
let mut info = vk::InstanceCreateInfo::builder()
|
||||
.application_info(&application_info)
|
||||
.enabled_layer_names(&layers)
|
||||
@ -97,6 +106,11 @@ pub(super) unsafe fn create_instance(
|
||||
|
||||
let instance = entry.create_instance(&info, None)?;
|
||||
|
||||
// Messenger
|
||||
if VALIDATION_ENABLED {
|
||||
data.messenger = instance.create_debug_utils_messenger_ext(&debug_info, None)?;
|
||||
}
|
||||
|
||||
Ok(instance)
|
||||
}
|
||||
|
||||
@ -133,30 +147,56 @@ pub(super) unsafe fn create_logical_device(
|
||||
instance: &Instance,
|
||||
data: &mut AppData,
|
||||
) -> Result<Device> {
|
||||
// Queue Create Infos
|
||||
let indices = QueueFamilyIndicies::get(instance, data, data.physical_device)?;
|
||||
|
||||
let queue_priorities = &[1.0];
|
||||
let queue_info = vk::DeviceQueueCreateInfo::builder()
|
||||
.queue_family_index(indices.graphics)
|
||||
.queue_priorities(queue_priorities);
|
||||
let mut unique_indices = HashSet::new();
|
||||
unique_indices.insert(indices.graphics);
|
||||
unique_indices.insert(indices.present);
|
||||
|
||||
let queue_priorities = &[1.0];
|
||||
let queue_infos = unique_indices
|
||||
.iter()
|
||||
.map(|i| {
|
||||
vk::DeviceQueueCreateInfo::builder()
|
||||
.queue_family_index(*i)
|
||||
.queue_priorities(queue_priorities)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Layers
|
||||
let layers = if VALIDATION_ENABLED {
|
||||
vec![VALIDATION_LAYER.as_ptr()]
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
// Extensions
|
||||
let extension_names = if instance
|
||||
.enumerate_device_extension_properties(data.physical_device, None)?
|
||||
.iter()
|
||||
.any(|e| e.extension_name == vk::KHR_PORTABILITY_SUBSET_EXTENSION.name)
|
||||
{
|
||||
vec![vk::KHR_PORTABILITY_SUBSET_EXTENSION.name.as_ptr()]
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
// Features
|
||||
let features = vk::PhysicalDeviceFeatures::builder();
|
||||
|
||||
let queue_infos = &[queue_info];
|
||||
// Create
|
||||
let info = vk::DeviceCreateInfo::builder()
|
||||
.queue_create_infos(queue_infos)
|
||||
.queue_create_infos(&queue_infos)
|
||||
.enabled_layer_names(&layers)
|
||||
.enabled_features(&features);
|
||||
.enabled_features(&features)
|
||||
.enabled_extension_names(&extension_names);
|
||||
|
||||
let device = instance.create_device(data.physical_device, &info, None)?;
|
||||
|
||||
// Queues
|
||||
data.graphics_queue = device.get_device_queue(indices.graphics, 0);
|
||||
data.present_queue = device.get_device_queue(indices.present, 0);
|
||||
|
||||
Ok(device)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user