diff --git a/webgpu/lessons/webgpu-optimization.md b/webgpu/lessons/webgpu-optimization.md
index 4c554731..fb868b0a 100644
--- a/webgpu/lessons/webgpu-optimization.md
+++ b/webgpu/lessons/webgpu-optimization.md
@@ -466,12 +466,10 @@ We need a simple UI so we can adjust how many things we're drawing.
```js
const settings = {
numObjects: 1000,
- render: true,
};
const gui = new GUI();
gui.add(settings, 'numObjects', { min: 0, max: maxObjects, step: 1});
- gui.add(settings, 'render');
```
Now we can write our render loop.
@@ -643,6 +641,7 @@ A few more things left to do. Let's add in resizing
then = time;
+ const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
++
+ // Don't set the canvas size if it's already that size as it may be slow.
+ if (canvas.width !== width || canvas.height !== height) {
+ canvas.width = width;
@@ -844,7 +843,7 @@ async function main() {
requestAnimationFrame(render);
```
-And finally we need to show the timing
+And we need to show the timing
```js
async function main() {
@@ -879,6 +878,46 @@ async function main() {
requestAnimationFrame(render);
```
+One more thing, just to help with better comparisons. An issue we have now
+is, every visible cube has every pixel rendered or at least checked if it
+needs to be rendered. Since we're not optimizing the rendering of pixels
+but rather optimizing the usage of WebGPU itself, it can be useful to be
+able to draw to a 1x1 pixel canvas. This effectively removes nearly all
+of the time spend rasterizing triangles and instead leaves only the part
+of our code that is doing math and communicating with WebGPU.
+
+So let's add an option to do that
+
+```js
+ const settings = {
+ numObjects: 1000,
++ render: true,
+ };
+
+ const gui = new GUI();
+ gui.add(settings, 'numObjects', { min: 0, max: maxObjects, step: 1});
++ gui.add(settings, 'render');
+
+ let depthTexture;
+ let then = 0;
+ let frameCount = 0;
+
+ function render(time) {
+ time *= 0.001; // convert to seconds
+ const deltaTime = time - then;
+ then = time;
+ ++frameCount;
+
+ const startTimeMs = performance.now();
+
+- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
++ const {width, height} = settings.render
++ ? canvasToSizeMap.get(canvas) ?? canvas
++ : { width: 1, height: 1 };
+```
+
+Now, if we uncheck 'render', we'll remove almost all of the um, ahh ..., rendering.
+
And with that, we have our first "un-optimized" example. It's following the
steps listed near the top of the article, and it works.
@@ -2009,6 +2048,10 @@ which is almost 60% more than we started with.
{{{example url="../webgpu-optimization-step6-use-mapped-buffers.html"}}}
+With rendering unchecked, the difference is even better. For me I get
+9000 at 75fps with the original non-optimized example and 18000 at 75fps
+in this last version. That's a 2x speed up!
+
Other things that *might* help
* **Double buffer the large uniform buffer**
diff --git a/webgpu/lessons/webgpu-timing.md b/webgpu/lessons/webgpu-timing.md
index 83c9d96b..f1392160 100644
--- a/webgpu/lessons/webgpu-timing.md
+++ b/webgpu/lessons/webgpu-timing.md
@@ -2,11 +2,6 @@ Title: WebGPU Timing Performance
Description: Timing operations in WebGPU
TOC: Timing Performance
-
-
Let's go over various things you might want
to time for performance. We'll time 3 things:
@@ -825,6 +820,8 @@ async function main() {
...
```
+{{{example url="../webgpu-timing-with-timing-helper.html"}}}
+
A few points about the `TimingHelper` class:
* You still have to manually request the `'timestamp-query'` feature when you
diff --git a/webgpu/webgl-optimization-none-uniform-buffers.html b/webgpu/webgl-optimization-none-uniform-buffers.html
index 48b40b67..ab103c0d 100644
--- a/webgpu/webgl-optimization-none-uniform-buffers.html
+++ b/webgpu/webgl-optimization-none-uniform-buffers.html
@@ -358,7 +358,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgl-optimization-none.html b/webgpu/webgl-optimization-none.html
index 28ff4b10..04c05c89 100644
--- a/webgpu/webgl-optimization-none.html
+++ b/webgpu/webgl-optimization-none.html
@@ -355,7 +355,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-all.html b/webgpu/webgpu-optimization-all.html
index ea29f48e..88471889 100644
--- a/webgpu/webgpu-optimization-all.html
+++ b/webgpu/webgpu-optimization-all.html
@@ -460,7 +460,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-none.html b/webgpu/webgpu-optimization-none.html
index 2989ac35..77b26c65 100644
--- a/webgpu/webgpu-optimization-none.html
+++ b/webgpu/webgpu-optimization-none.html
@@ -432,7 +432,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step3-global-vs-per-object-uniforms.html b/webgpu/webgpu-optimization-step3-global-vs-per-object-uniforms.html
index 2c7d919e..320824df 100644
--- a/webgpu/webgpu-optimization-step3-global-vs-per-object-uniforms.html
+++ b/webgpu/webgpu-optimization-step3-global-vs-per-object-uniforms.html
@@ -456,7 +456,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step4-material-uniforms.html b/webgpu/webgpu-optimization-step4-material-uniforms.html
index 27c1b894..b7031037 100644
--- a/webgpu/webgpu-optimization-step4-material-uniforms.html
+++ b/webgpu/webgpu-optimization-step4-material-uniforms.html
@@ -465,7 +465,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step5-double-buffer-frequently-updated-uniform-buffers-pre-submit.html b/webgpu/webgpu-optimization-step5-double-buffer-frequently-updated-uniform-buffers-pre-submit.html
index 5e299854..cb167cc4 100644
--- a/webgpu/webgpu-optimization-step5-double-buffer-frequently-updated-uniform-buffers-pre-submit.html
+++ b/webgpu/webgpu-optimization-step5-double-buffer-frequently-updated-uniform-buffers-pre-submit.html
@@ -477,7 +477,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step5-double-buffer-frequently-updated-uniform-buffers.html b/webgpu/webgpu-optimization-step5-double-buffer-frequently-updated-uniform-buffers.html
index 5e299854..cb167cc4 100644
--- a/webgpu/webgpu-optimization-step5-double-buffer-frequently-updated-uniform-buffers.html
+++ b/webgpu/webgpu-optimization-step5-double-buffer-frequently-updated-uniform-buffers.html
@@ -477,7 +477,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step5-use-buffer-offsets.html b/webgpu/webgpu-optimization-step5-use-buffer-offsets.html
index 3efac7ac..bd16b55f 100644
--- a/webgpu/webgpu-optimization-step5-use-buffer-offsets.html
+++ b/webgpu/webgpu-optimization-step5-use-buffer-offsets.html
@@ -468,7 +468,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step6-use-mapped-buffers-2-command-buffers.html b/webgpu/webgpu-optimization-step6-use-mapped-buffers-2-command-buffers.html
index be325171..2c8809de 100644
--- a/webgpu/webgpu-optimization-step6-use-mapped-buffers-2-command-buffers.html
+++ b/webgpu/webgpu-optimization-step6-use-mapped-buffers-2-command-buffers.html
@@ -467,7 +467,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step6-use-mapped-buffers-dyanmic-offsets.html b/webgpu/webgpu-optimization-step6-use-mapped-buffers-dyanmic-offsets.html
index a81aa00b..1d7ca9a8 100644
--- a/webgpu/webgpu-optimization-step6-use-mapped-buffers-dyanmic-offsets.html
+++ b/webgpu/webgpu-optimization-step6-use-mapped-buffers-dyanmic-offsets.html
@@ -505,7 +505,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step6-use-mapped-buffers-math-w-offsets.html b/webgpu/webgpu-optimization-step6-use-mapped-buffers-math-w-offsets.html
index d1811819..ffe102cf 100644
--- a/webgpu/webgpu-optimization-step6-use-mapped-buffers-math-w-offsets.html
+++ b/webgpu/webgpu-optimization-step6-use-mapped-buffers-math-w-offsets.html
@@ -1027,7 +1027,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step6-use-mapped-buffers.html b/webgpu/webgpu-optimization-step6-use-mapped-buffers.html
index 9e3b8ee4..a70a8d6c 100644
--- a/webgpu/webgpu-optimization-step6-use-mapped-buffers.html
+++ b/webgpu/webgpu-optimization-step6-use-mapped-buffers.html
@@ -467,7 +467,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step7-double-buffer-2-submit.html b/webgpu/webgpu-optimization-step7-double-buffer-2-submit.html
index 8c64cedb..cc32e983 100644
--- a/webgpu/webgpu-optimization-step7-double-buffer-2-submit.html
+++ b/webgpu/webgpu-optimization-step7-double-buffer-2-submit.html
@@ -469,7 +469,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step7-double-buffer-typedarray-set.html b/webgpu/webgpu-optimization-step7-double-buffer-typedarray-set.html
index bbade6c2..89ce54ac 100644
--- a/webgpu/webgpu-optimization-step7-double-buffer-typedarray-set.html
+++ b/webgpu/webgpu-optimization-step7-double-buffer-typedarray-set.html
@@ -472,7 +472,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
diff --git a/webgpu/webgpu-optimization-step7-double-buffer.html b/webgpu/webgpu-optimization-step7-double-buffer.html
index 90cbee2e..45b3d7a1 100644
--- a/webgpu/webgpu-optimization-step7-double-buffer.html
+++ b/webgpu/webgpu-optimization-step7-double-buffer.html
@@ -469,7 +469,10 @@
const startTimeMs = performance.now();
- const {width, height} = canvasToSizeMap.get(canvas) ?? canvas;
+ const {width, height} = settings.render
+ ? canvasToSizeMap.get(canvas) ?? canvas
+ : { width: 1, height: 1 };
+
// Don't set the canvas size if it's already that size as it may be slow.
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;