Skip to content

Commit

Permalink
update memory layout article
Browse files Browse the repository at this point in the history
I have a feeling this article is maybe too terse
but I added a couple of example showing overlapping
views and a comment amount `map`.

Maybe I should re-write this article?

I think originally I was going to have a separate typedarray
article but I feel like the 2 topics kind of go hand-in-hand,
or at least as written.
  • Loading branch information
greggman committed Nov 6, 2023
1 parent ade367c commit b43e24b
Showing 1 changed file with 56 additions and 0 deletions.
56 changes: 56 additions & 0 deletions webgpu/lessons/webgpu-memory-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ ourStructValuesAsF32[kAccelerationOffset] = 3.4;
ourStructValuesAsU32[kFrameCountOffset] = 56; // an integer value
```

## `TypedArrays`

Note, like many things in programming there are multiple ways we could
do this. `TypeArray`s have a constructor that takes various forms. For example

Expand All @@ -99,6 +101,16 @@ do this. `TypeArray`s have a constructor that takes various forms. For example
srcArray.forEach((v, i) => dstArray[i] = v);
```

What does "copied by value" mean? Take this example

```js
const f32s = new Float32Array([0.8, 0.9, 1.0, 1.1, 1.2]);
const u32s = new Uint32Array(f32s);
console.log(u32s); // produces 0, 0, 1, 1, 1
```

The reason is you can't put values like 0.8 and 1.2 into a `Uint32Array`

* `new Float32Array(someArrayBuffer)`

This is the case we used before. A new `Float32Array` view is made on an
Expand Down Expand Up @@ -165,6 +177,50 @@ accelerationView[0] = 3.4;
frameCountView[0] = 56;
```

## Multiple views of the same `ArrayBuffer`

Having a view of **the same arrayBuffer** means exactly that. For example

```js
const v1 = new Float32Array(5);
const v2 = v1.subarray(3, 5); // view the last 2 floats of v1
v2[0] = 123;
v2[1] = 456;
console.log(v1); // shows 0, 0, 0, 123, 456
```

Similarly if we have different typed views

```js
const f32 = new Float32Array([1, 1000, -1000])
const u32 = new Uint32Array(f32.buffer);

console.log(Array.from(u32).map(v => v.toString(16).padStart(8, '0')));
// shows '3f800000', '447a0000', 'c47a0000'
```

The values above are the 32bit hex representations of the floating point values for 1, 1000, -1000

## `map` issues

Be aware, the `map` function of a `TypedArray` makes a new typed array of the same type!

```js
const f32a = new Float32Array(1, 2, 3);
const f32b = f32a.map(v => v * 2); // Ok
const f32c = f32a.map(v => `${v} doubled = ${v *2}`); // BAD!
// you can't put a string in a Float32Array
```

If you need to map a typedarray into some other type you'll either need to loop over the array yourself
or else convert it to a JavaScript array which you can do with `Array.from`. Taking the example above

```js
const f32d = Array.from(f32a).map(v => `${v} doubled = ${v *2}`); // Ok
```

## vec and mat types

[WGSL](webgpu-wgsl.html) has types made from the 4 base types.
They are:

Expand Down

0 comments on commit b43e24b

Please sign in to comment.