Setting 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
-
In this case just add
import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-avoid-redundant-state-setting.js';
or
<script type="module" src="https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-avoid-redundant-state-setting.js"></script>
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. -
This way you can optimize your code.
In this case use
import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js';
or
<script type="module" src="https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js"></script>
Then check the JavaScript console.
Note: this assumes you're using
requestAnimationFrame
to render. If you are using something else to render likerequestVideoFrameCallback
orsetTimeout
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
andsetIndexBuffer
calls.setBindGroup
is harder if it has to check dynamic offsets.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
.
For example, you set bindGroups by calling setBindGroup
and those are sticky until you end
the pass encoder.
-
compute and render pass state
- pipeline: set via
setPipeline
- bindGroups: set via
setBindGroup
- pipeline: set via
-
render pass state
- vertexBuffers: set via
setVertexBuffer
- indexBuffer: set via
setIndexBuffer
- viewport: set via
setViewport
- scissor: set via
setScissor
- blendConstant: set via
setBlendConstant
- stencilReference: set via
setStencilReference
- vertexBuffers: set via
The one exception is in a render pass, executeBundles
resets some of the state, both before and after.
The states reset are the bindGroups
, vertexBuffers
, indexBuffer
, and pipeline
.
During dev, serve the repo as in npx servez .
then open a page to http://locahost:8080/test/
.
MIT