I have some code, probably from WGPU tutorial, that calls Device::create_render_pipeline. The argument there (RenderPipelineDescriptor<'_>
) appears to have a lifetime parameter.
Part of that descriptor is a VertexState<'a>
struct, which in turn has an slice of VertexBufferLayout<'a>
. My code that created the descriptor looked like:
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Render Pipeline"),
layout: Some(&render_pipeline_layout),
vertex: wgpu::VertexState {
module: &shader,
entry_point: Some("vs_main"),
buffers: &[ Vertex::desc(), InstanceData::desc() ],
...
Vertex
and InstanceData
are my own structs, that describe data sent to shader. The desc()
functions used to look like:
impl InstanceData {
pub fn desc() -> wgpu::VertexBufferLayout<'static> {
use std::mem;
wgpu::VertexBufferLayout {
array_stride: size_of::<InstanceData>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Instance,
attributes: &[
wgpu::VertexAttribute {
offset: 0,
shader_location: 2,
format: wgpu::VertexFormat::Float32x4,
},
...
I never really noticed it, because the code was copied from a tutorial, but I guess that function was creating an array of VertexAttribute
and returning a ref/slice to it as 'static
, and it got away with this because everything in the array was constant/static. So it wasn't really created afresh in each call to desc()
.
But now, I want to change desc()
to take a parameter, as shown below, so I can use it in different shaders where the first field @location
is different.
pub fn desc(start_location: u32) -> wgpu::VertexBufferLayout<'static> {
...
attributes: &[
wgpu::VertexAttribute {
offset: 0,
shader_location: start_location,
...
shader_location: start_location+1,
...
And the code above that calls desc(...)
would now pass a u32
:
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
...
buffers: &[ Vertex::desc(), InstanceData::desc(3) ],
Now it won't compile, as the array can no longer be 'static
. That makes sense.
But I'm not sure how I should refactor everything here. If I'm understanding things right, the RenderPipelineDescriptor
has a lifetime parameter because it has references inside it. So anything not 'static
I need to create and own in that function that calls create_render_pipeline
. Any pointers on how to do this? (Maybe I need to give more info about the surrounding code?)