1use std::error::Error;
3use std::sync::Arc;
4
5use log::{debug, error};
6use vulkano::{
7 command_buffer::PrimaryAutoCommandBuffer,
8 device::{physical::PhysicalDevice, Device, Queue},
9 image::{view::ImageView, Image, ImageUsage},
10 render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass},
11 swapchain::{self, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo},
12 sync::{self, GpuFuture},
13 Validated, VulkanError,
14};
15
16use super::PmseRenderHost;
17use crate::E;
18
19#[derive(Debug)]
21pub struct PmseRenderSc {
22 设备: Arc<Device>,
24 队列: Arc<Queue>,
26 交换链: Arc<Swapchain>,
28 图像: Vec<Arc<Image>>,
30 帧缓冲: Vec<Arc<Framebuffer>>,
32}
33
34impl PmseRenderSc {
35 pub fn new(h: &PmseRenderHost, size: [u32; 2]) -> Result<Self, Box<dyn Error>> {
36 let (交换链, 图像) = 创建交换链(h.d(), h.p(), h.s(), size)?;
37 Ok(Self {
39 设备: h.d().clone(),
40 队列: h.q().clone(),
41 交换链,
42 图像,
43 帧缓冲: vec![],
44 })
45 }
46
47 pub fn sc(&self) -> &Arc<Swapchain> {
49 &self.交换链
50 }
51
52 pub fn init_framebuffer(&mut self, rp: &Arc<RenderPass>) -> Result<(), Box<dyn Error>> {
54 self.帧缓冲 = 创建帧缓冲区(&self.图像, rp)?;
55 Ok(())
56 }
57
58 pub fn execute<T: CreateCommand>(&self, c: &T) -> Result<(), Box<dyn Error>> {
60 交换链执行(&self.设备, &self.队列, &self.交换链, &self.帧缓冲, c)
61 }
62}
63
64pub trait CreateCommand {
66 fn c(&self, fb: &Arc<Framebuffer>) -> Result<Arc<PrimaryAutoCommandBuffer>, Box<dyn Error>>;
68}
69
70fn 创建交换链(
72 设备: &Arc<Device>,
73 物理设备: &Arc<PhysicalDevice>,
74 表面: &Arc<Surface>,
75 image_extent: [u32; 2],
76) -> Result<(Arc<Swapchain>, Vec<Arc<Image>>), Box<dyn Error>> {
77 let 能力 = 物理设备.surface_capabilities(表面, Default::default())?;
78 let composite_alpha = 能力.supported_composite_alpha.into_iter().next().unwrap();
79 let image_format = 物理设备.surface_formats(表面, Default::default())?[0].0;
80 debug!(" image format: {:?}", image_format);
81 debug!(" min_image_count {}", 能力.min_image_count);
82
83 Ok(Swapchain::new(
84 设备.clone(),
85 表面.clone(),
86 SwapchainCreateInfo {
87 min_image_count: 能力.min_image_count + 1,
88 image_format,
89 image_extent,
90 image_usage: ImageUsage::COLOR_ATTACHMENT,
91 composite_alpha,
92 ..Default::default()
93 },
94 )?)
95}
96
97fn 创建帧缓冲区(
99 图像: &Vec<Arc<Image>>,
100 渲染过程: &Arc<RenderPass>,
101) -> Result<Vec<Arc<Framebuffer>>, Box<dyn Error>> {
102 let mut o: Vec<Arc<Framebuffer>> = Vec::new();
103 for i in 图像 {
104 let 视图 = ImageView::new_default(i.clone())?;
105 o.push(Framebuffer::new(
106 渲染过程.clone(),
107 FramebufferCreateInfo {
108 attachments: vec![视图],
109 ..Default::default()
110 },
111 )?)
112 }
113 Ok(o)
114}
115
116fn 交换链执行<T: CreateCommand>(
118 设备: &Arc<Device>,
119 队列: &Arc<Queue>,
120 交换链: &Arc<Swapchain>,
121 帧缓冲: &Vec<Arc<Framebuffer>>,
122 生成命令: &T,
123) -> Result<(), Box<dyn Error>> {
124 let (序号, _退化, 获取未来) =
126 match swapchain::acquire_next_image(交换链.clone(), None).map_err(Validated::unwrap) {
127 Ok(r) => r,
128 Err(VulkanError::OutOfDate) => {
129 error!("ERROR swapchain acquire OutOfDate");
131 return Err(Box::new(E("vulkan OutOfDate".into())));
132 }
133 Err(e) => {
134 error!("ERROR swapchain acquire {}", e);
136 return Err(Box::new(E("unknown error".into())));
137 }
138 };
139 let 命令 = 生成命令.c(&帧缓冲[序号 as usize])?;
141 let 执行 = sync::now(设备.clone())
143 .join(获取未来)
144 .then_execute(队列.clone(), 命令)?
145 .then_swapchain_present(
146 队列.clone(),
147 SwapchainPresentInfo::swapchain_image_index(交换链.clone(), 序号),
148 )
149 .then_signal_fence_and_flush();
150 match 执行.map_err(Validated::unwrap) {
152 Ok(f) => {
153 f.wait(None)?;
154 }
155 Err(e) => {
156 error!("ERROR flush {}", e);
158 }
159 }
160 Ok(())
161}