pmse_render/vulkan/
vulkan_init.rs

1//! vulkan 初始化
2use 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/// 正在初始化的 vulkan 渲染器
22#[derive(Debug, Clone)]
23pub struct PmseRenderInit {
24    库: Arc<VulkanLibrary>,
25}
26
27impl PmseRenderInit {
28    /// 初始化 vulkan (加载 vulkan 库 .so)
29    pub fn vulkan() -> Result<Self, Box<dyn Error>> {
30        debug!("init vulkan .. .");
31
32        let 库 = VulkanLibrary::new()?;
33        Ok(Self { 库 })
34    }
35
36    /// 窗口初始化, 传入窗口
37    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        // 创建 vulkan 实例
43        let 实例 = Instance::new(
44            self.库.clone(),
45            InstanceCreateInfo {
46                enabled_extensions: 实例扩展,
47                ..Default::default()
48            },
49        )?;
50
51        // 创建设备队列
52        let 设备扩展 = DeviceExtensions {
53            khr_swapchain: true,
54            ..DeviceExtensions::empty()
55        };
56        let (物理设备, 队列序号) = 选择设备(&实例, 设备扩展.clone())?;
57        let (设备, 队列) = 创建设备队列(&物理设备, 队列序号, 设备扩展)?;
58
59        // 创建内存分配器
60        let ma = Arc::new(StandardMemoryAllocator::new_default(设备.clone()));
61        // 创建窗口表面
62        let 表面 = Surface::from_window(实例.clone(), w)?;
63
64        // 初始化 (这部分) 完成
65        Ok(PmseRenderHost::new(物理设备, 设备, 队列, ma, 表面))
66    }
67}
68
69// (函数)
70
71/// 选择 vulkan 设备
72fn 选择设备(
73    实例: &Arc<Instance>,
74    扩展: DeviceExtensions,
75) -> Result<(Arc<PhysicalDevice>, u32), Box<dyn Error>> {
76    // TODO 优化设备选择功能
77
78    // 列出 (枚举) vulkan 设备
79    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        // 输出设备列表, 选择第一个 vulkan 设备
85        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    // 列出 (查找) vulkan 队列
93    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
107/// 创建 vulkan 设备, 队列
108fn 创建设备队列(
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}