Skip to content

Commit

Permalink
Create the swapchain
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasJowett committed Jun 15, 2023
1 parent 6e5e4fb commit 86ddd15
Showing 1 changed file with 115 additions and 37 deletions.
152 changes: 115 additions & 37 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,32 @@ extern crate vulkano_win;
extern crate winit;

mod halvar {
use std::sync::Arc;
use vulkano::{
device::{
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Queue,
QueueCreateInfo, QueueFlags,
},
image::{ImageUsage, SwapchainImage},
instance::{Instance, InstanceCreateInfo},
swapchain::{Surface, Swapchain, SwapchainCreateInfo},
VulkanLibrary,
};
use vulkano_win::VkSurfaceBuild;
use winit::{
dpi::LogicalSize,
event::{Event, WindowEvent},
event_loop::EventLoop,
window::{Window, WindowBuilder},
};
use std::sync::Arc;
use vulkano::{
instance::{Instance, InstanceCreateInfo},
swapchain::Surface,
VulkanLibrary,
device::{
physical::{PhysicalDevice, PhysicalDeviceType}, DeviceExtensions,
QueueFlags,
},
};

pub struct Application {
instance: Arc<Instance>,
surface: Arc<Surface>,
physical_device: Arc<PhysicalDevice>,
device: Arc<Device>,
queue: Arc<Queue>,
swapchain: Arc<Swapchain>,
images: Vec<Arc<SwapchainImage>>,
event_loop: EventLoop<()>,
}

Expand All @@ -38,12 +42,17 @@ mod halvar {
.build_vk_surface(&event_loop, instance.clone())
.unwrap();

let physical_device = Self::choose_physical_device(&instance, &surface);
let (device, queue) = Self::create_device(&instance, &surface);

let (swapchain, images) = Self::create_swapchain(&device, &surface);

Application {
instance,
surface,
physical_device,
device,
queue,
swapchain,
images,
event_loop,
}
}
Expand All @@ -65,37 +74,36 @@ mod halvar {
.unwrap()
}

pub fn choose_physical_device(instance: &Arc<Instance>, surface: &Arc<Surface>) -> Arc<PhysicalDevice> {
pub fn create_device(
instance: &Arc<Instance>,
surface: &Arc<Surface>,
) -> (Arc<Device>, Arc<Queue>) {
let device_extensions = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::empty()
};

let (physical_device, _queue_family_index) = instance
let (physical_device, queue_family_index) = instance
.enumerate_physical_devices()
.unwrap()
.filter(|p| {
p.supported_extensions().contains(&device_extensions)
})
.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))
.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,
}
.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,
})
.expect("No suitable physical device found");

Expand All @@ -106,16 +114,86 @@ mod halvar {
physical_device.properties().device_type,
);

physical_device
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: Arc<vulkano::device::Queue> = queues.next().unwrap();

(device, queue)
}

pub fn create_swapchain(
device: &Arc<Device>,
surface: &Arc<Surface>,
) -> (Arc<Swapchain>, Vec<Arc<SwapchainImage>>) {
let surface_capabilities = device
.physical_device()
.surface_capabilities(surface, Default::default())
.unwrap();

let image_format = Some(
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_capabilities.min_image_count,
image_format,
image_extent: window.inner_size().into(),
image_usage: ImageUsage::COLOR_ATTACHMENT,
composite_alpha: surface_capabilities
.supported_composite_alpha
.into_iter()
.next()
.unwrap(),
..Default::default()
},
)
.unwrap()
}

pub fn run(self) {
if Arc::strong_count(&self.instance) == 0 {
println!("Cannot run application without a vulkan instance");
return;
}
if Arc::strong_count(&self.physical_device) == 0 {
println!("Cannot run application without a physical rendering device");
if Arc::strong_count(&self.device) == 0 {
println!("Cannot run application without a vulkan device");
return;
}
if Arc::strong_count(&self.queue) == 0 {
println!("Cannot run application without a vulkan queue");
return;
}
if Arc::strong_count(&self.surface) == 0 {
println!("Cannot run application without a vulkan surface");
return;
}
if Arc::strong_count(&self.swapchain) == 0 {
println!("Cannot run application without a vulkan swapchain");
return;
}
if Vec::is_empty(&self.images) {
println!("Cannot run application without vulkan images");
return;
}
self.event_loop
Expand Down

0 comments on commit 86ddd15

Please sign in to comment.