更新到 v22.0 后 wgpu RenderPass 的生命周期问题

问题描述 投票:0回答:1

我有一段代码在

wgpu
v0.19 版本中运行。现在我尝试将
wgpu
更新到 v22 并收到与生命周期相关的编译错误,但我无法找出原因。

这是代码片段:

    pub fn render(&mut self, wgpu_frame: &mut WgpuFrame, run_ui: impl FnMut(&Context)) {
        // some unrelated stuff

        {
            let mut render_pass =
                wgpu_frame
                    .encoder
                    .begin_render_pass(&wgpu::RenderPassDescriptor {
                        color_attachments: &[Some(wgpu::RenderPassColorAttachment {
                            view: wgpu_frame.texture_view,
                            resolve_target: None,
                            ops: wgpu::Operations {
                                load: wgpu::LoadOp::Load,
                                store: wgpu::StoreOp::Store,
                            },
                        })],
                        depth_stencil_attachment: None,
                        label: Some("egui render pass"),
                        timestamp_writes: None,
                        occlusion_query_set: None,
                    });

            self.renderer
                .render(&mut render_pass, &paint_jobs, &screen_descriptor);
        }

        // a little more unrelated stuff
    }

尝试编译此代码时遇到的错误是:

   --> galileo/examples/with_egui/src/state/egui_state.rs:93:17
    |
59  |       pub fn render(&mut self, wgpu_frame: &mut WgpuFrame, run_ui: impl FnMut(&Context)) {
    |                                ----------  - let's call the lifetime of this reference `'1`
    |                                |
    |                                `wgpu_frame` is a reference that is only valid in the method body
...
93  | /                 wgpu_frame
94  | |                     .encoder
95  | |                     .begin_render_pass(&wgpu::RenderPassDescriptor {
96  | |                         color_attachments: &[Some(wgpu::RenderPassColorAttachment {
...   |
107 | |                         occlusion_query_set: None,
108 | |                     });
    | |                      ^
    | |                      |
    | |______________________`wgpu_frame` escapes the method body here
    |                        argument requires that `'1` must outlive `'static`

方法

render
定义为:

    pub fn render<'a>(
        &self,
        render_pass: &'a mut wgpu::RenderPass<'a>,
        paint_jobs: &[epaint::ClippedPrimitive],
        screen_descriptor: &ScreenDescriptor,
    ) {}

如果我删除上面的

'a
生命周期,我会收到类似的
RenderPass
生命周期错误...

我不明白的是为什么编译器坚持认为

wgpu_frame
必须比
'static
更长寿?这个要求从何而来?我怎样才能减轻这个要求?

以防万一,

begin_render_pass
方法具有以下签名:

    pub fn begin_render_pass<'encoder>(
        &'encoder mut self,
        desc: &RenderPassDescriptor<'_>,
    ) -> RenderPass<'encoder> {}

这也不需要任何东西来延长

'static
...

我知道我可以通过调用

render_pass.forget_lifetime()
让编译器保持沉默,但我宁愿了解编译器想要从我这里得到什么,而不是让它关闭。

rust wgpu-rs
1个回答
0
投票

问题就在这里:

       render_pass: &'a mut wgpu::RenderPass<'a>,

&mut 内部和外部使用

same
生命周期参数本质上总是不正确的,因为您施加了同时约束:

  • 渲染通道被借用只要
    'a
  • 渲染通道包含为
    'a
    借用的东西,因此当
    'a
    结束时
  • 无效

这最终意味着“这是借来的,以维持其自身的存在”,而且它永远不能被丢弃。相反,您应该让生命周期不同,这最容易通过不命名来实现:

       render_pass: &mut wgpu::RenderPass<'_>,
© www.soinside.com 2019 - 2024. All rights reserved.