1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! 交换链 (swapchain) 创建/初始化
use std::error::Error;
use std::sync::Arc;

use vulkano::{
    device::{physical::PhysicalDevice, Device},
    image::{view::ImageView, Image, ImageUsage},
    render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass},
    swapchain::{Surface, Swapchain, SwapchainCreateInfo},
};

use crate::PmseRenderHost;

/// 交换链 (swapchain) 管理
#[derive(Debug)]
pub struct PmseRenderSc {
    /// (no Clone) 交换链
    交换链: Arc<Swapchain>,
    /// 图像
    图像: Vec<Arc<Image>>,
    /// 帧缓冲区
    帧缓冲: Vec<Arc<Framebuffer>>,
}

impl PmseRenderSc {
    pub fn new(h: &PmseRenderHost, size: [u32; 2]) -> Result<Self, Box<dyn Error>> {
        let (交换链, 图像) = 创建交换链(h.d(), h.p(), h.s(), size)?;
        // 稍后初始化 帧缓冲
        Ok(Self {
            交换链,
            图像,
            帧缓冲: vec![],
        })
    }

    /// 获取交换链
    pub fn sc(&self) -> &Arc<Swapchain> {
        &self.交换链
    }

    /// 创建帧缓冲区
    pub fn init_framebuffer(&mut self, rp: &Arc<RenderPass>) -> Result<(), Box<dyn Error>> {
        self.帧缓冲 = 创建帧缓冲区(&self.图像, rp)?;
        Ok(())
    }

    /// 获取帧缓冲
    pub fn framebuffer(&self) -> &Vec<Arc<Framebuffer>> {
        &self.帧缓冲
    }
}

/// 创建交换链
fn 创建交换链(
    设备: &Arc<Device>,
    物理设备: &Arc<PhysicalDevice>,
    表面: &Arc<Surface>,
    image_extent: [u32; 2],
) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), Box<dyn Error>> {
    let 能力 = 物理设备.surface_capabilities(表面, Default::default())?;
    let composite_alpha = 能力.supported_composite_alpha.into_iter().next().unwrap();
    let image_format = 物理设备.surface_formats(表面, Default::default())?[0].0;
    println!("  image format: {:?}", image_format);
    println!("  min_image_count {}", 能力.min_image_count);

    Ok(Swapchain::new(
        设备.clone(),
        表面.clone(),
        SwapchainCreateInfo {
            min_image_count: 能力.min_image_count + 1,
            image_format,
            image_extent,
            image_usage: ImageUsage::COLOR_ATTACHMENT,
            composite_alpha,
            ..Default::default()
        },
    )?)
}

/// 创建帧缓冲区
fn 创建帧缓冲区(
    图像: &Vec<Arc<Image>>,
    渲染过程: &Arc<RenderPass>,
) -> Result<Vec<Arc<Framebuffer>>, Box<dyn Error>> {
    let mut o: Vec<Arc<Framebuffer>> = Vec::new();
    for i in 图像 {
        let 视图 = ImageView::new_default(i.clone())?;
        o.push(Framebuffer::new(
            渲染过程.clone(),
            FramebufferCreateInfo {
                attachments: vec![视图],
                ..Default::default()
            },
        )?)
    }
    Ok(o)
}