0

Background

I am doing the wgpu tutorial. In an early lesson, there is the following code:

    let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
        label: Some("Render Pass"),
        color_attachments: &[Some(wgpu::RenderPassColorAttachment {
            view: &view,
            resolve_target: None,
            ops: wgpu::Operations {
                load: wgpu::LoadOp::Clear(wgpu::Color {
                    r: 0.1,
                    g: 0.2,
                    b: 0.3,
                    a: 1.0,
                }),
                store: true,
            },
        })],
        depth_stencil_attachment: None,
    });

Since most of the RenderPassDescriptor struct is boilerplate, I would like to factor the creation of RenderPassDescriptor into another function. I tried to create the function like this:

pub fn make_render_pass_descriptor(view: &wgpu::TextureView, clear_color: wgpu::Color) -> wgpu::RenderPassDescriptor {
    wgpu::RenderPassDescriptor {
        label: Some("Render Pass"),
        color_attachments: &[
            Some(wgpu::RenderPassColorAttachment {
                view: view,
                resolve_target: None,
                ops: wgpu::Operations {
                    load: wgpu::LoadOp::Clear(clear_color),
                    store: true,
                },
            })
        ],
        depth_stencil_attachment: None,
    }
}

Which would let me replace the original code with the following:

    let descriptor      = make_render_pass_descriptor(view, clear_color);
    let mut render_pass = encoder.begin_render_pass(&descriptor);

The Problem

Unfortunately, since color_attachments is set to a temporary constant &[...], I get the following error:

error[E0515]: cannot return value referencing temporary value

Question

Ideally, I would like to tell the compiler to extend the lifetime of the temporary constant to the calling function's lifetime. Is this possible? If not, what is an idiomatic way to factor out the creation of the RenderPassDescriptor?

1
  • 1
    This is not possible (without a macro), and I think the idiomatic way is just to leave it as-is, perhaps put the entire call in a function. Commented Aug 16, 2022 at 16:31

1 Answer 1

1

wgpu “descriptors” are basically just complex named arguments for a function. Keep them together with their function calls, and you won't have these borrowing problems:

pub fn begin_render_pass<'p>(
    encoder: &'p mut wgpu::CommandEncoder,
    view: &wgpu::TextureView,
    clear_color: wgpu::Color,
) -> wgpu::RenderPass<'p> {
    encoder.begin_render_pass(wgpu::RenderPassDescriptor {
        label: Some("Render Pass"),
        color_attachments: &[
            Some(wgpu::RenderPassColorAttachment {
                view: view,
                resolve_target: None,
                ops: wgpu::Operations {
                    load: wgpu::LoadOp::Clear(clear_color),
                    store: true,
                },
            })
        ],
        depth_stencil_attachment: None,
    })
}
Sign up to request clarification or add additional context in comments.

2 Comments

I'd been assuming the descriptors might be used for other purposes too, but your explanation makes a lot of sense- thanks!
@statusfailed I actually have on my todo list to contribute an explanation of just this to the descriptors’ documentation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.