Skip to content

perf(webgpu): no native round trip per setVertexBuffer/setIndexBuffer; per-call benchmark - #218

Merged
triniwiz merged 1 commit into
masterfrom
perf/webgpu-binding-call-cost
Nov 14, 2026
Merged

triniwiz merged 1 commit into
masterfrom
perf/webgpu-binding-call-cost

Conversation

@triniwiz

Copy link
Copy Markdown
Member

The hot render-pass methods already go through V8 fast calls, so this pass went after what sits around them.

  • GPUBuffer caches size and usage once at creation. The wrappers read buffer.size on every setVertexBuffer(slot, buffer) and setIndexBuffer(buffer, format) call (how three.js calls them) to default the size, which crossed into native each time. They now pass "rest of the buffer" through, and the Rust entry points hand wgpu None instead of the whole buffer size, which was also wrong whenever an offset was given.
  • The pass encoder entry points cloned the pass label and fetched the error sink on every draw and state call without using them.
  • tools/demo/canvas/webgpu/perf.ts: a per-call WebGPU benchmark next to the 2D and WebGL ones. --es demo canvas-perf --es suite webgpu on Android, --demo=canvas-perf --suite=webgpu on the simulator; one PERF| line per op.

iOS simulator (same C++ V8 bindings as Android), ns per call:

call before after
setVertexBuffer(slot, buffer) 449 397
setIndexBuffer(buffer, format) 444 395
buffer.size 51 31
setPipeline / setBindGroup / draw / drawIndexed / writeBuffer unchanged unchanged

A three.js WebGPURenderer scene at about 4k draws per frame on the Linux build: median render() 40.4 to 38.3 ms, rendering unchanged.

@coderabbitai

coderabbitai Bot commented Nov 14, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 00ac5a2a-3973-45aa-a098-2e968b5b5403

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

…; per-call benchmark

- GPUBuffer caches size and usage once at creation. The wrappers read
  buffer.size on every setVertexBuffer(slot, buffer) and
  setIndexBuffer(buffer, format) call to default the size, which crossed
  into native each time. They now pass "rest of the buffer" through, and
  the Rust entry points hand wgpu None instead of the whole buffer size,
  which was also wrong whenever an offset was given.
- The pass encoder entry points cloned the pass label and fetched the
  error sink on every draw and state call without using them.
- tools/demo/canvas/webgpu/perf.ts: a per-call WebGPU benchmark next to
  the 2D and WebGL ones (canvas-perf page, suite "webgpu").

iOS simulator, ns per call, before -> after: setVertexBuffer(slot, buffer)
449 -> 397, setIndexBuffer(buffer, format) 444 -> 395, buffer.size 51 -> 31;
the other calls unchanged. A three.js scene at about 4k draws on Linux:
median render 40.4 -> 38.3 ms.
@triniwiz
triniwiz force-pushed the perf/webgpu-binding-call-cost branch from 577dc5b to 6554280 Compare November 14, 2026 05:33
@triniwiz
triniwiz merged commit fc7ed1a into master Nov 14, 2026
6 of 25 checks passed
@triniwiz
triniwiz deleted the perf/webgpu-binding-call-cost branch November 14, 2026 05:37
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.

1 participant