check for and/or avoid redundant state setting in WebGPU
npm install webgpu-avoid-redundant-state-settingSetting state multiple times can be a source of lost performance.
There's overhead in calling from JavaScript into the WebGPU api.
There's also no guarantee the implementation optimizes this stuff
under the hood.
So, this is an attempt at
1. ## Trivially doing it for you
In this case just add
``js`
import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-avoid-redundant-state-setting.js';
or
`html`
To the top of your app and see if there is any perf difference.
note: there is overhead in checking for redundant state calls, especially for setBindGroup with dynamic offsets
as the library has to check each offset so there is some possibility perf will be worse
with this library. Measure for yourself or use (2) below to check your own code.
2. ## Making it easy to check if you're submitting redundant state
This way you can optimize your code.
In this case use
`js`
import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js';
or
`html`
Then check the JavaScript console.
Note: this assumes you're using requestAnimationFrame to render. If you are using something else to renderrequestVideoFrameCallback
like or setTimeout or other events,
look at the source
to see how to do this check for your specific situation.
If you see lots of redundant state setting, refactor your code to avoid it. You can look at the source code of this library
for some ideas. The easiest to avoid are redundant setVertexBuffer and setIndexBuffer calls. setBindGroup is harder
if it has to check dynamic offsets.
## Important!
You do NOT need to avoid setting all redundant state. Rather, this library is just meant to check
if you're setting 100s or 1000s of redundant state per pass.
There isn't very much state in WebGPU. The most (all?) state comes in GPURenderPassEncoder and GPUComputePassEncoder.setBindGroup
For example, you set bindGroups by calling and those are sticky until you end the pass encoder.
* compute and render pass state
* pipeline: set via setPipelinesetBindGroup
* bindGroups: set via
* render pass state
* vertexBuffers: set via setVertexBuffersetIndexBuffer
* indexBuffer: set via setViewport
* viewport: set via setScissor
* scissor: set via setBlendConstant
* blendConstant: set via setStencilReference
* stencilReference: set via
The one exception is in a render pass, executeBundles resets some of the state, both before and after.bindGroups
The states reset are the , vertexBuffers, indexBuffer, and pipeline.
During dev, serve the repo as in npx servez . then open a page to http://locahost:8080/test/`.
MIT