pmse_render/vulkan/
vulkan_init.rs1use std::error::Error;
3use std::sync::Arc;
4
5use log::debug;
6use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
7use vulkano::{
8 device::{
9 physical::PhysicalDevice, Device, DeviceCreateInfo, DeviceExtensions, Queue,
10 QueueCreateInfo, QueueFlags,
11 },
12 instance::{Instance, InstanceCreateInfo},
13 memory::allocator::StandardMemoryAllocator,
14 swapchain::Surface,
15 VulkanLibrary,
16};
17
18use super::PmseRenderHost;
19use crate::E;
20
21#[derive(Debug, Clone)]
23pub struct PmseRenderInit {
24 库: Arc<VulkanLibrary>,
25}
26
27impl PmseRenderInit {
28 pub fn vulkan() -> Result<Self, Box<dyn Error>> {
30 debug!("init vulkan .. .");
31
32 let 库 = VulkanLibrary::new()?;
33 Ok(Self { 库 })
34 }
35
36 pub fn init_w(
38 self,
39 w: Arc<impl HasRawDisplayHandle + HasRawWindowHandle + Send + Sync + 'static>,
40 ) -> Result<PmseRenderHost, Box<dyn Error>> {
41 let 实例扩展 = Surface::required_extensions(w.as_ref());
42 let 实例 = Instance::new(
44 self.库.clone(),
45 InstanceCreateInfo {
46 enabled_extensions: 实例扩展,
47 ..Default::default()
48 },
49 )?;
50
51 let 设备扩展 = DeviceExtensions {
53 khr_swapchain: true,
54 ..DeviceExtensions::empty()
55 };
56 let (物理设备, 队列序号) = 选择设备(&实例, 设备扩展.clone())?;
57 let (设备, 队列) = 创建设备队列(&物理设备, 队列序号, 设备扩展)?;
58
59 let ma = Arc::new(StandardMemoryAllocator::new_default(设备.clone()));
61 let 表面 = Surface::from_window(实例.clone(), w)?;
63
64 Ok(PmseRenderHost::new(物理设备, 设备, 队列, ma, 表面))
66 }
67}
68
69fn 选择设备(
73 实例: &Arc<Instance>,
74 扩展: DeviceExtensions,
75) -> Result<(Arc<PhysicalDevice>, u32), Box<dyn Error>> {
76 let 设备列表 = 实例
80 .enumerate_physical_devices()?
81 .filter(|p| p.supported_extensions().contains(&扩展));
82 let mut d1: Option<Arc<PhysicalDevice>> = None;
83 for i in 设备列表 {
84 debug!(" {}", i.properties().device_name);
86 if d1.is_none() {
87 d1.replace(i);
88 }
89 }
90 let 设备 = d1.ok_or(E("ERROR vulkan list device".into()))?;
91
92 for f in 设备.queue_family_properties() {
94 debug!("vulkan device queue {:?}", f.queue_count);
95 }
96 let queue_family_index = 设备
97 .queue_family_properties()
98 .iter()
99 .enumerate()
100 .position(|(_i, q)| q.queue_flags.contains(QueueFlags::GRAPHICS))
101 .ok_or(E("ERROR vulkan find queue".into()))? as u32;
102 debug!("vulkan queue index {}", queue_family_index);
103
104 Ok((设备, queue_family_index))
105}
106
107fn 创建设备队列(
109 设备: &Arc<PhysicalDevice>,
110 queue_family_index: u32,
111 enabled_extensions: DeviceExtensions,
112) -> Result<(Arc<Device>, Arc<Queue>), Box<dyn Error>> {
113 let (d, mut 队列) = Device::new(
114 设备.clone(),
115 DeviceCreateInfo {
116 queue_create_infos: vec![QueueCreateInfo {
117 queue_family_index,
118 ..Default::default()
119 }],
120 enabled_extensions,
121 ..Default::default()
122 },
123 )?;
124 let q = 队列.next().unwrap();
125 Ok((d, q))
126}