Skip to content

Don't set redundant state in the WebGPURenderer #26184

@greggman

Description

@greggman

Description

I wrote a library to check for redundant state setting in WebGPU. For example, you might do

    pass.setVertexBuffer(0, buffer0);
    pass.setVertexBuffer(1, buffer1);
    pass.draw(...);
    pass.setVertexBuffer(0, buffer0);  // redundant. vertexBuffer 0 is already set to buffer0
    pass.setVertexBuffer(1, buffer1);  // redundant. vertexBuffer 1 is already set to buffer1
    pass.draw(...);

Checking three.js it sets redundant state. 2 examples: the materials example has 56 unneeded WebGPU calls per frame and the sprites example has 597 unneeded WebGPU calls per frame.

Solution

Tracking the state you've set already can be relatively easy. beginRenderPass starts with no state (or the default state). pass.executeBundles resets the vertexBuffer, indexBuffer, pipeline, and bindGroup state. Other state like viewport, scissor, blendConstant, and stencilReference last until pass.end

It probably doesn't matter for a small scene but it does add up to some measurable perf loss on both the JavaScript side and the WebGPU side for a large number of draw calls.

Alternatives

You can use the library to wrap the API. I don't recommend that as you can do it yourself at a higher level. The higher the level, the more code doesn't get executed. You can also reference the library to see what it's doing.

Additional context

No response

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions