@vgpu/render 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/perf/frame-time-measure.d.ts +22 -0
- package/dist/perf/frame-time-measure.d.ts.map +1 -0
- package/dist/perf/frame-time-measure.js +91 -0
- package/dist/perf/frame-time-measure.js.map +1 -0
- package/dist/perf/gpu-frame-time.d.ts +49 -0
- package/dist/perf/gpu-frame-time.d.ts.map +1 -0
- package/dist/perf/gpu-frame-time.js +50 -0
- package/dist/perf/gpu-frame-time.js.map +1 -0
- package/dist/perf/index.d.ts +5 -0
- package/dist/perf/index.d.ts.map +1 -0
- package/dist/perf/index.js +3 -0
- package/dist/perf/index.js.map +1 -0
- package/dist/perf/pixel-diff.d.ts +27 -0
- package/dist/perf/pixel-diff.d.ts.map +1 -0
- package/dist/perf/pixel-diff.js +40 -0
- package/dist/perf/pixel-diff.js.map +1 -0
- package/dist/pipeline-descriptor.d.ts +35 -0
- package/dist/pipeline-descriptor.d.ts.map +1 -0
- package/dist/pipeline-descriptor.js +44 -0
- package/dist/pipeline-descriptor.js.map +1 -0
- package/dist/pipeline.d.ts +22 -33
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +30 -46
- package/dist/pipeline.js.map +1 -1
- package/dist/render-pass.d.ts.map +1 -1
- package/dist/render-pass.js +4 -0
- package/dist/render-pass.js.map +1 -1
- package/dist/storage-buffer.d.ts +81 -0
- package/dist/storage-buffer.d.ts.map +1 -0
- package/dist/storage-buffer.js +91 -0
- package/dist/storage-buffer.js.map +1 -0
- package/dist/uniform.d.ts +55 -0
- package/dist/uniform.d.ts.map +1 -0
- package/dist/uniform.js +64 -0
- package/dist/uniform.js.map +1 -0
- package/package.json +8 -3
- package/src/createRenderPipeline.docs.md +34 -0
- package/src/perf/perf.docs.md +45 -0
- package/src/storage-buffer.docs.md +102 -0
- package/src/uniform.docs.md +70 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# StorageBuffer
|
|
2
|
+
|
|
3
|
+
`StorageBuffer` is one stable storage buffer for a single render (or compute)
|
|
4
|
+
pass, rewritten as needed and change-gated by the caller. It is the
|
|
5
|
+
storage-buffer counterpart to `Uniform`: it creates a `storage | copy_dst`
|
|
6
|
+
buffer, a bind group layout with a single storage binding at binding 0, and a
|
|
7
|
+
bind group wired to that buffer. `write()` uploads bytes with
|
|
8
|
+
`queue.writeBuffer` at a fixed offset — there is no dynamic offset and the bind
|
|
9
|
+
group never changes.
|
|
10
|
+
|
|
11
|
+
## When to use `StorageBuffer` vs `Uniform` vs `UniformPool`
|
|
12
|
+
|
|
13
|
+
Use `StorageBuffer` when the data is too large or too dynamic for a uniform:
|
|
14
|
+
arrays, runtime-sized data, particle/instance state, lookup tables. Storage
|
|
15
|
+
buffers can be much larger than uniforms — up to the adapter's
|
|
16
|
+
`maxStorageBufferBindingSize` (typically 128 MiB) versus a uniform's 64 KiB —
|
|
17
|
+
and the shader can write them with `access: "read-write"`.
|
|
18
|
+
|
|
19
|
+
Use `Uniform` for the common "globals/camera per pass" case: a small, fixed,
|
|
20
|
+
read-only buffer (`var<uniform>`).
|
|
21
|
+
|
|
22
|
+
Use `UniformPool` only when you have **many** small per-draw uniforms. It is a
|
|
23
|
+
dynamic-offset ring allocator: every slot binding is marked
|
|
24
|
+
`hasDynamicOffset: true` and the whole CPU mirror is re-uploaded each frame.
|
|
25
|
+
|
|
26
|
+
## `access`: read vs read-write
|
|
27
|
+
|
|
28
|
+
`access` controls the bind group layout entry type. Both modes default to
|
|
29
|
+
`FRAGMENT | COMPUTE` visibility:
|
|
30
|
+
|
|
31
|
+
- `"read"` (default) → WGSL `var<storage, read>`, layout type
|
|
32
|
+
`"read-only-storage"`.
|
|
33
|
+
- `"read-write"` → WGSL `var<storage, read_write>`, layout type `"storage"`.
|
|
34
|
+
|
|
35
|
+
> Neither default includes `VERTEX`. Read-write storage is forbidden in the
|
|
36
|
+
> vertex stage outright. Read-only storage is _allowed_ in the vertex stage, but
|
|
37
|
+
> `maxStorageBuffersInVertexStage` is **0** on many adapters (software/CI Vulkan,
|
|
38
|
+
> some mobile GPUs) — a `VERTEX`-visible default silently invalidates the layout
|
|
39
|
+
> there and the draw no-ops. For vertex-stage read-only storage, pass
|
|
40
|
+
> `visibility: VERTEX | …` explicitly **and** raise `maxStorageBuffersInVertexStage`
|
|
41
|
+
> via `requiredLimits` when requesting the device.
|
|
42
|
+
|
|
43
|
+
## Constructor
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
new StorageBuffer(device, {
|
|
47
|
+
size, // byte size of the storage buffer (required)
|
|
48
|
+
label, // optional debug label for buffer, layout, and bind group
|
|
49
|
+
access, // "read" (default) | "read-write"
|
|
50
|
+
visibility, // GPUShaderStageFlags; defaults by access (see above)
|
|
51
|
+
bindGroupLayout, // optional pipeline-owned layout to reuse instead of creating one
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
- `size`: byte size of the storage buffer. May be far larger than a uniform.
|
|
56
|
+
- `label`: optional debug label; suffixed `.bgl` / `.bg` for the layout and bind
|
|
57
|
+
group.
|
|
58
|
+
- `access`: `"read"` (default, read-only storage) or `"read-write"` (writable
|
|
59
|
+
storage). Selects the layout entry type and the default visibility.
|
|
60
|
+
- `visibility`: shader stages that access binding 0. Defaults to
|
|
61
|
+
`FRAGMENT | COMPUTE` for both access modes (no `VERTEX` — see the note above).
|
|
62
|
+
Ignored when `bindGroupLayout` is provided.
|
|
63
|
+
- `bindGroupLayout`: reuse a pipeline-owned bind group layout instead of creating
|
|
64
|
+
one. Its binding 0 must be a storage buffer compatible with `size` and
|
|
65
|
+
`access`.
|
|
66
|
+
|
|
67
|
+
## Members
|
|
68
|
+
|
|
69
|
+
- `storageBuffer.gpu`: the underlying storage `GPUBuffer`.
|
|
70
|
+
- `storageBuffer.buffer`: the VGPU `Buffer` wrapper around `gpu`.
|
|
71
|
+
- `storageBuffer.bindGroup`: the `GPUBindGroup` to bind for the pass.
|
|
72
|
+
- `storageBuffer.bindGroupLayout`: the `GPUBindGroupLayout` (created or reused).
|
|
73
|
+
- `storageBuffer.size`: the buffer byte size.
|
|
74
|
+
- `storageBuffer.access`: the resolved access mode (`"read"` or `"read-write"`).
|
|
75
|
+
- `storageBuffer.write(data, offset = 0)`: uploads `data` via
|
|
76
|
+
`device.queue.writeBuffer(gpu, offset, data)`. No dynamic offset; the bind
|
|
77
|
+
group is unchanged. Call only when the contents actually change.
|
|
78
|
+
- `storageBuffer.destroy()` / `storageBuffer.dispose()`: releases the backing
|
|
79
|
+
buffer once; idempotent.
|
|
80
|
+
|
|
81
|
+
## Example
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
// A read-only array the fragment shader samples:
|
|
85
|
+
// @group(0) @binding(0) var<storage, read> values: array<f32>;
|
|
86
|
+
const storage = new StorageBuffer(device, { size: 4 * count, label: "values" });
|
|
87
|
+
storage.write(new Float32Array(values));
|
|
88
|
+
|
|
89
|
+
const pipeline = createRenderPipelineFromDescriptor(device, {
|
|
90
|
+
layout: device.gpu.createPipelineLayout({ bindGroupLayouts: [storage.bindGroupLayout] }),
|
|
91
|
+
vertex: { module, entryPoint: "vs_main" },
|
|
92
|
+
fragment: { module, entryPoint: "fs_main", targets: [{ format }] },
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
pass.setPipeline(pipeline);
|
|
96
|
+
pass.setBindGroup(0, storage.bindGroup);
|
|
97
|
+
pass.draw(3);
|
|
98
|
+
|
|
99
|
+
// A compute-written scratch buffer:
|
|
100
|
+
// @group(0) @binding(0) var<storage, read_write> out: array<u32>;
|
|
101
|
+
const scratch = new StorageBuffer(device, { size: 4 * count, access: "read-write" });
|
|
102
|
+
```
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Uniform
|
|
2
|
+
|
|
3
|
+
`Uniform` is one stable uniform buffer for a single render pass, rewritten per
|
|
4
|
+
frame and change-gated by the caller. It creates a `uniform | copy_dst` buffer,
|
|
5
|
+
a bind group layout with a single uniform binding at binding 0, and a bind group
|
|
6
|
+
wired to that buffer. `write()` uploads bytes with `queue.writeBuffer` at a fixed
|
|
7
|
+
offset — there is no dynamic offset and the bind group never changes.
|
|
8
|
+
|
|
9
|
+
## When to use `Uniform` vs `UniformPool`
|
|
10
|
+
|
|
11
|
+
Use `Uniform` for the common "globals/camera per pass" case: a single buffer you
|
|
12
|
+
overwrite each frame, where you decide when the contents actually changed.
|
|
13
|
+
|
|
14
|
+
Use `UniformPool` only when you have **many** per-draw uniforms. It is a
|
|
15
|
+
dynamic-offset ring allocator: every slot binding is marked
|
|
16
|
+
`hasDynamicOffset: true` and the whole CPU mirror is re-uploaded each frame. For
|
|
17
|
+
one stable buffer that is the wrong shape — it forces a dynamic-offset layout and
|
|
18
|
+
defeats change-gating.
|
|
19
|
+
|
|
20
|
+
## Constructor
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
new Uniform(device, {
|
|
24
|
+
size, // byte size of the uniform buffer (required)
|
|
25
|
+
label, // optional debug label for buffer, layout, and bind group
|
|
26
|
+
visibility, // GPUShaderStageFlags; defaults to VERTEX | FRAGMENT
|
|
27
|
+
bindGroupLayout, // optional pipeline-owned layout to reuse instead of creating one
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- `size`: byte size of the uniform buffer.
|
|
32
|
+
- `label`: optional debug label; suffixed `.bgl` / `.bg` for the layout and bind
|
|
33
|
+
group.
|
|
34
|
+
- `visibility`: shader stages that read binding 0. Defaults to
|
|
35
|
+
`GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT`. Ignored when
|
|
36
|
+
`bindGroupLayout` is provided.
|
|
37
|
+
- `bindGroupLayout`: reuse a pipeline-owned bind group layout instead of creating
|
|
38
|
+
one. Its binding 0 must be a uniform buffer compatible with `size`.
|
|
39
|
+
|
|
40
|
+
## Members
|
|
41
|
+
|
|
42
|
+
- `uniform.gpu`: the underlying uniform `GPUBuffer`.
|
|
43
|
+
- `uniform.buffer`: the VGPU `Buffer` wrapper around `gpu`.
|
|
44
|
+
- `uniform.bindGroup`: the `GPUBindGroup` to bind for the pass.
|
|
45
|
+
- `uniform.bindGroupLayout`: the `GPUBindGroupLayout` (created or reused).
|
|
46
|
+
- `uniform.size`: the buffer byte size.
|
|
47
|
+
- `uniform.write(data, offset = 0)`: uploads `data` via
|
|
48
|
+
`device.queue.writeBuffer(gpu, offset, data)`. No dynamic offset; the bind group
|
|
49
|
+
is unchanged. Call only when the uniform contents actually change.
|
|
50
|
+
- `uniform.destroy()` / `uniform.dispose()`: releases the backing buffer once;
|
|
51
|
+
idempotent.
|
|
52
|
+
|
|
53
|
+
## Example
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
const uniform = new Uniform(device, { size: 64, label: "globals" });
|
|
57
|
+
|
|
58
|
+
// Per frame, only when inputs changed:
|
|
59
|
+
if (dirty) uniform.write(globalsBytes);
|
|
60
|
+
|
|
61
|
+
const pipeline = createRenderPipelineFromDescriptor(device, {
|
|
62
|
+
layout: device.gpu.createPipelineLayout({ bindGroupLayouts: [uniform.bindGroupLayout] }),
|
|
63
|
+
vertex: { module, entryPoint: "vs_main" },
|
|
64
|
+
fragment: { module, entryPoint: "fs_main", targets: [{ format }] },
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
pass.setPipeline(pipeline);
|
|
68
|
+
pass.setBindGroup(0, uniform.bindGroup);
|
|
69
|
+
pass.draw(3);
|
|
70
|
+
```
|