Skip to content

Handle WGPUVertexStepMode_Undefined#490

Merged
cwfitzgerald merged 2 commits intogfx-rs:trunkfrom
AlbinBernhardssonARM:WGPUVertexStepMode_Undefined
Mar 20, 2026
Merged

Handle WGPUVertexStepMode_Undefined#490
cwfitzgerald merged 2 commits intogfx-rs:trunkfrom
AlbinBernhardssonARM:WGPUVertexStepMode_Undefined

Conversation

@AlbinBernhardssonARM
Copy link
Copy Markdown
Contributor

@AlbinBernhardssonARM AlbinBernhardssonARM force-pushed the WGPUVertexStepMode_Undefined branch from f397b61 to 163a1da Compare June 10, 2025 11:59
Copy link
Copy Markdown
Member

@cwfitzgerald cwfitzgerald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think is quite right actually - the behavior of undefined depends on the other arguments of the struct: https://github.com/webgpu-native/webgpu-headers/blob/main/webgpu.h#L4282-L4297

@almarklein
Copy link
Copy Markdown
Collaborator

@cwfitzgerald good to take that into account!

However, it's not clear to me how these different cases of "no attributes" should be mapped to the API in wgpu-core. And it looks like null is not allowed in the JS API?

stepMode defaults to "vertex" when attributes is not empty.
@AlbinBernhardssonARM AlbinBernhardssonARM force-pushed the WGPUVertexStepMode_Undefined branch from 163a1da to b739e52 Compare July 2, 2025 15:39
@AlbinBernhardssonARM
Copy link
Copy Markdown
Contributor Author

@cwfitzgerald good to take that into account!

However, it's not clear to me how these different cases of "no attributes" should be mapped to the API in wgpu-core. And it looks like null is not allowed in the JS API?

null is allowed in GPUVertexState.buffers. However, Firefox doesn't appear to handle this quite correctly. null entries are supposed to be skipped during vertex processing and validating draw calls. But the following fails in Firefox (works in Chrome) due to no vertex buffer being bound in slot 1:

let pipeline = device.createRenderPipeline({
  vertex: {
    buffers: [
      {
        // Vertex buffer slot 0...
      },
      null
    ],
    ...
  }
  ...
});

...

renderPassEncoder.setPipeline(pipeline);
renderPassEncoder.setVertexBuffer(0, vertexBuffer);
renderPassEncoder.draw();

Can be worked around by binding some dummy vertex buffer to slot 1.

The reason is wgpu-core doesn't handle null entries in VertexState.buffers. Firefox handles it by simply putting default values on null entries. However a null entry is not quite the same as an entry with attributes = []. An entry with attributes = [] still has to have a bound vertex buffer, based on the outcome of gpuweb/gpuweb#4999 .

So I think the proper, long-term solution is to handle null entries in wgpu-core. Short term solution for wgpu-native is either

  1. Match Firefox behavior and map WGPUVertexStepMode_Undefined, empty attributes or WGPUVertexStepMode_VertexBufferNotUsed as default values { array_stride: 0, step_mode: Vertex, attributes: []}.
  2. Raise an error. Which we already do since we don't handle WGPUVertexStepMode_Undefined or WGPUVertexStepMode_VertexBufferNotUsed. But we could handle WGPUVertexStepMode_Undefined for the non-empty attributes case. And i.m.o. current error message is not too helpful as it implies the wrong vertex step mode was used, when in fact the user did nothing wrong.

I've updated my commit to do 2 with an error message telling developers how they can work around the lack of support, but I can change it to 1 if we prefer.

Note: WGPUVertexStepMode_VertexBufferNotUsed will be removed next time we update webgpu-headers.

@cwfitzgerald
Copy link
Copy Markdown
Member

Sorry this got lost in the sea of PRs - could you take a look at the current state of wgpu-core as I think some of this may have changed? I'm going to try to get a wgpu update up for wgpu-native at some point soon.

@AlbinBernhardssonARM
Copy link
Copy Markdown
Contributor Author

wgpu-core (trunk) looks the same to me. VertexState.buffers still takes [VertexBufferLayout] (not [Option<VertexBufferLayout>]) and VertexBufferLayout.step_mode is VertexStepMode which doesn't have an unused entry. So still no way to express an unused slot as far as I can tell. Constrast with eg. FragmentState.targets.

The example JS I gave still doesn't work in Firefox. (A dummy vertex buffer has to be bound to make it work.)

Copy link
Copy Markdown
Member

@cwfitzgerald cwfitzgerald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@cwfitzgerald cwfitzgerald enabled auto-merge (squash) March 20, 2026 15:34
@cwfitzgerald cwfitzgerald merged commit fea6ee2 into gfx-rs:trunk Mar 20, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants