voodoojs 0.4.6
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 +77 -0
- package/dist/chunk-234ZLC6W.js +401 -0
- package/dist/chunk-4HQEOXTK.js +10271 -0
- package/dist/chunk-5777LJVW.js +64 -0
- package/dist/chunk-5CKGDARU.js +1845 -0
- package/dist/chunk-A2UOVQBP.js +82 -0
- package/dist/chunk-E27NRARW.js +16 -0
- package/dist/chunk-JZIYRIY6.js +1196 -0
- package/dist/chunk-NNU6WOOU.js +641 -0
- package/dist/chunk-PQZEVFVZ.js +448 -0
- package/dist/chunk-RJUNPXQF.js +946 -0
- package/dist/chunk-U76IRJKH.js +72 -0
- package/dist/essential.cjs +13889 -0
- package/dist/essential.d.cts +24 -0
- package/dist/essential.d.ts +24 -0
- package/dist/essential.js +51 -0
- package/dist/gpu.cjs +2008 -0
- package/dist/gpu.d.cts +68 -0
- package/dist/gpu.d.ts +68 -0
- package/dist/gpu.js +273 -0
- package/dist/http.cjs +467 -0
- package/dist/http.d.cts +148 -0
- package/dist/http.d.ts +148 -0
- package/dist/http.js +7 -0
- package/dist/index-CaLD-0oh.d.cts +608 -0
- package/dist/index-CaLD-0oh.d.ts +608 -0
- package/dist/index-DTllqUtj.d.cts +261 -0
- package/dist/index-DTllqUtj.d.ts +261 -0
- package/dist/index.cjs +23063 -0
- package/dist/index.d.cts +1603 -0
- package/dist/index.d.ts +1603 -0
- package/dist/index.js +6924 -0
- package/dist/query-CKJ4oSpG.d.cts +1595 -0
- package/dist/query-DQFRmu3u.d.ts +1595 -0
- package/dist/reactivity.cjs +676 -0
- package/dist/reactivity.d.cts +188 -0
- package/dist/reactivity.d.ts +188 -0
- package/dist/reactivity.js +4 -0
- package/dist/socket.cjs +2685 -0
- package/dist/socket.d.cts +167 -0
- package/dist/socket.d.ts +167 -0
- package/dist/socket.js +238 -0
- package/dist/style-XEUAGGJK.js +5 -0
- package/dist/utils.cjs +397 -0
- package/dist/utils.d.cts +111 -0
- package/dist/utils.d.ts +111 -0
- package/dist/utils.js +4 -0
- package/dist/voodoo.core.js +8213 -0
- package/dist/voodoo.core.min.js +146 -0
- package/dist/voodoo.full.js +21193 -0
- package/dist/voodoo.full.min.js +1784 -0
- package/dist/voodoo.js +14185 -0
- package/dist/voodoo.min.js +420 -0
- package/package.json +127 -0
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module gpu/types
|
|
3
|
+
*
|
|
4
|
+
* Minimal WebGPU types, hand-written.
|
|
5
|
+
*
|
|
6
|
+
* The project doesn't accept new dependencies, so `@webgpu/types` is out and
|
|
7
|
+
* TypeScript's `lib.dom` still doesn't describe `navigator.gpu`. What's here
|
|
8
|
+
* is only the slice of the API the module actually calls: descriptors stay as
|
|
9
|
+
* `any` on purpose, because copying the entire schema would just create a second
|
|
10
|
+
* source of truth to keep in sync.
|
|
11
|
+
*
|
|
12
|
+
* The usage constants are also local. In production they exist as globals
|
|
13
|
+
* (`GPUBufferUsage` and company), but in jsdom they don't exist at all, and the module
|
|
14
|
+
* needs to be importable in an environment without GPU without blowing up on the first line.
|
|
15
|
+
*/
|
|
16
|
+
/** Texture format name, like `bgra8unorm`. */
|
|
17
|
+
type GPUTextureFormat = string;
|
|
18
|
+
interface GPUBuffer {
|
|
19
|
+
destroy(): void;
|
|
20
|
+
}
|
|
21
|
+
interface GPUTextureView {
|
|
22
|
+
readonly __textureView?: never;
|
|
23
|
+
}
|
|
24
|
+
interface GPUTexture {
|
|
25
|
+
createView(descriptor?: any): GPUTextureView;
|
|
26
|
+
destroy(): void;
|
|
27
|
+
readonly width: number;
|
|
28
|
+
readonly height: number;
|
|
29
|
+
}
|
|
30
|
+
interface GPUSampler {
|
|
31
|
+
readonly __sampler?: never;
|
|
32
|
+
}
|
|
33
|
+
/** A WGSL compiler message. `lineNum` starts at 1. */
|
|
34
|
+
interface GPUCompilationMessage {
|
|
35
|
+
readonly message: string;
|
|
36
|
+
readonly type: 'error' | 'warning' | 'info';
|
|
37
|
+
readonly lineNum: number;
|
|
38
|
+
readonly linePos: number;
|
|
39
|
+
}
|
|
40
|
+
interface GPUCompilationInfo {
|
|
41
|
+
readonly messages: readonly GPUCompilationMessage[];
|
|
42
|
+
}
|
|
43
|
+
interface GPUShaderModule {
|
|
44
|
+
getCompilationInfo?(): Promise<GPUCompilationInfo>;
|
|
45
|
+
}
|
|
46
|
+
interface GPUBindGroupLayout {
|
|
47
|
+
readonly __bindGroupLayout?: never;
|
|
48
|
+
}
|
|
49
|
+
interface GPUBindGroup {
|
|
50
|
+
readonly __bindGroup?: never;
|
|
51
|
+
}
|
|
52
|
+
interface GPUPipelineLayout {
|
|
53
|
+
readonly __pipelineLayout?: never;
|
|
54
|
+
}
|
|
55
|
+
interface GPURenderPipeline {
|
|
56
|
+
getBindGroupLayout(index: number): GPUBindGroupLayout;
|
|
57
|
+
}
|
|
58
|
+
interface GPUComputePipeline {
|
|
59
|
+
getBindGroupLayout(index: number): GPUBindGroupLayout;
|
|
60
|
+
}
|
|
61
|
+
interface GPURenderPassEncoder {
|
|
62
|
+
setPipeline(pipeline: GPURenderPipeline): void;
|
|
63
|
+
setBindGroup(index: number, group: GPUBindGroup | null): void;
|
|
64
|
+
draw(vertexCount: number, instanceCount?: number, firstVertex?: number, firstInstance?: number): void;
|
|
65
|
+
end(): void;
|
|
66
|
+
}
|
|
67
|
+
interface GPUComputePassEncoder {
|
|
68
|
+
setPipeline(pipeline: GPUComputePipeline): void;
|
|
69
|
+
setBindGroup(index: number, group: GPUBindGroup | null): void;
|
|
70
|
+
dispatchWorkgroups(x: number, y?: number, z?: number): void;
|
|
71
|
+
end(): void;
|
|
72
|
+
}
|
|
73
|
+
interface GPUCommandBuffer {
|
|
74
|
+
readonly __commandBuffer?: never;
|
|
75
|
+
}
|
|
76
|
+
interface GPUCommandEncoder {
|
|
77
|
+
beginRenderPass(descriptor: any): GPURenderPassEncoder;
|
|
78
|
+
beginComputePass(descriptor?: any): GPUComputePassEncoder;
|
|
79
|
+
finish(descriptor?: any): GPUCommandBuffer;
|
|
80
|
+
}
|
|
81
|
+
interface GPUQueue {
|
|
82
|
+
submit(buffers: GPUCommandBuffer[]): void;
|
|
83
|
+
writeBuffer(buffer: GPUBuffer, bufferOffset: number, data: ArrayBuffer | ArrayBufferView, dataOffset?: number, size?: number): void;
|
|
84
|
+
}
|
|
85
|
+
interface GPUDeviceLostInfo {
|
|
86
|
+
readonly reason: string;
|
|
87
|
+
readonly message: string;
|
|
88
|
+
}
|
|
89
|
+
interface GPUDevice {
|
|
90
|
+
readonly queue: GPUQueue;
|
|
91
|
+
readonly limits: Record<string, number>;
|
|
92
|
+
readonly lost?: Promise<GPUDeviceLostInfo>;
|
|
93
|
+
createBuffer(descriptor: any): GPUBuffer;
|
|
94
|
+
createTexture(descriptor: any): GPUTexture;
|
|
95
|
+
createSampler(descriptor?: any): GPUSampler;
|
|
96
|
+
createShaderModule(descriptor: any): GPUShaderModule;
|
|
97
|
+
createBindGroup(descriptor: any): GPUBindGroup;
|
|
98
|
+
createBindGroupLayout(descriptor: any): GPUBindGroupLayout;
|
|
99
|
+
createPipelineLayout(descriptor: any): GPUPipelineLayout;
|
|
100
|
+
createRenderPipeline(descriptor: any): GPURenderPipeline;
|
|
101
|
+
createComputePipeline(descriptor: any): GPUComputePipeline;
|
|
102
|
+
createCommandEncoder(descriptor?: any): GPUCommandEncoder;
|
|
103
|
+
pushErrorScope(filter: string): void;
|
|
104
|
+
popErrorScope(): Promise<{
|
|
105
|
+
message: string;
|
|
106
|
+
} | null>;
|
|
107
|
+
destroy(): void;
|
|
108
|
+
}
|
|
109
|
+
interface GPUAdapter {
|
|
110
|
+
readonly features: {
|
|
111
|
+
has(name: string): boolean;
|
|
112
|
+
};
|
|
113
|
+
readonly limits: Record<string, number>;
|
|
114
|
+
readonly info?: Record<string, unknown>;
|
|
115
|
+
requestDevice(descriptor?: any): Promise<GPUDevice>;
|
|
116
|
+
}
|
|
117
|
+
interface GPUCanvasContext {
|
|
118
|
+
configure(descriptor: any): void;
|
|
119
|
+
unconfigure(): void;
|
|
120
|
+
getCurrentTexture(): GPUTexture;
|
|
121
|
+
}
|
|
122
|
+
/** O objeto exposto em `navigator.gpu`. */
|
|
123
|
+
interface GPUNavigator {
|
|
124
|
+
requestAdapter(options?: any): Promise<GPUAdapter | null>;
|
|
125
|
+
getPreferredCanvasFormat?(): GPUTextureFormat;
|
|
126
|
+
}
|
|
127
|
+
/** Bits de `GPUBufferUsage`. */
|
|
128
|
+
declare const BUFFER_USAGE: {
|
|
129
|
+
readonly MAP_READ: 1;
|
|
130
|
+
readonly MAP_WRITE: 2;
|
|
131
|
+
readonly COPY_SRC: 4;
|
|
132
|
+
readonly COPY_DST: 8;
|
|
133
|
+
readonly UNIFORM: 64;
|
|
134
|
+
readonly STORAGE: 128;
|
|
135
|
+
};
|
|
136
|
+
/** Bits de `GPUTextureUsage`. */
|
|
137
|
+
declare const TEXTURE_USAGE: {
|
|
138
|
+
readonly COPY_SRC: 1;
|
|
139
|
+
readonly COPY_DST: 2;
|
|
140
|
+
readonly TEXTURE_BINDING: 4;
|
|
141
|
+
readonly STORAGE_BINDING: 8;
|
|
142
|
+
readonly RENDER_ATTACHMENT: 16;
|
|
143
|
+
};
|
|
144
|
+
/** Bits de `GPUShaderStage`. */
|
|
145
|
+
declare const SHADER_STAGE: {
|
|
146
|
+
readonly VERTEX: 1;
|
|
147
|
+
readonly FRAGMENT: 2;
|
|
148
|
+
readonly COMPUTE: 4;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @module gpu/wgsl
|
|
153
|
+
*
|
|
154
|
+
* Reading WGSL code to figure out what the shader needs on its own.
|
|
155
|
+
*
|
|
156
|
+
* The idea came from vgpu: whoever writes the shader already declared `@group`, `@binding`
|
|
157
|
+
* and the uniforms `struct` inside it. Repeating this in JavaScript is double work
|
|
158
|
+
* and one more chance for the two sides to get out of sync. So the module
|
|
159
|
+
* reads the source and builds the bind group layout, buffer size and offset
|
|
160
|
+
* of each field straight from the shader itself.
|
|
161
|
+
*
|
|
162
|
+
* Everything here is pure text functions: doesn't touch the DOM, doesn't need GPU and
|
|
163
|
+
* runs the same in jsdom. That's why this is the most tested part of the module.
|
|
164
|
+
*
|
|
165
|
+
* What reflection covers is described in `docs/gpu.md`. In summary: `struct`
|
|
166
|
+
* declared in the file itself, scalars, vectors, matrices and fixed-size arrays,
|
|
167
|
+
* plus textures, samplers and storage buffers. Left out: `@align`,
|
|
168
|
+
* `@size`, vertex `@location`, unsized arrays inside uniform (which
|
|
169
|
+
* WGSL also forbids) and user-defined `type`/alias.
|
|
170
|
+
*/
|
|
171
|
+
/** Family of a WGSL type. */
|
|
172
|
+
type WgslTypeKind = 'scalar' | 'vector' | 'matrix' | 'array' | 'struct' | 'unknown';
|
|
173
|
+
/** Description of a type, with size and alignment already resolved. */
|
|
174
|
+
interface WgslType {
|
|
175
|
+
/** Original text, like `vec3<f32>`. */
|
|
176
|
+
text: string;
|
|
177
|
+
kind: WgslTypeKind;
|
|
178
|
+
/** Base scalar. `f32` for types with no clear scalar. */
|
|
179
|
+
scalar: 'f32' | 'i32' | 'u32' | 'f16' | 'bool';
|
|
180
|
+
/** Bytes occupied. */
|
|
181
|
+
size: number;
|
|
182
|
+
/** Required alignment, in bytes. */
|
|
183
|
+
align: number;
|
|
184
|
+
/** How many scalars the value has in total. `vec3<f32>` has 3. */
|
|
185
|
+
components: number;
|
|
186
|
+
/** Matrix columns. */
|
|
187
|
+
columns?: number;
|
|
188
|
+
/** Matrix rows, i.e., the size of each column. */
|
|
189
|
+
rows?: number;
|
|
190
|
+
/** Distance between array elements, or between matrix columns. */
|
|
191
|
+
stride?: number;
|
|
192
|
+
/** Number of elements in a fixed-size array. */
|
|
193
|
+
count?: number;
|
|
194
|
+
/** Type of an array element. */
|
|
195
|
+
element?: WgslType;
|
|
196
|
+
/** Struct name, when `kind` is `struct`. */
|
|
197
|
+
struct?: string;
|
|
198
|
+
}
|
|
199
|
+
/** A struct field, with offset within the buffer. */
|
|
200
|
+
interface WgslField {
|
|
201
|
+
name: string;
|
|
202
|
+
type: WgslType;
|
|
203
|
+
/** Offset in bytes from the start of the struct. */
|
|
204
|
+
offset: number;
|
|
205
|
+
}
|
|
206
|
+
/** Struct declared in the shader. */
|
|
207
|
+
interface WgslStruct {
|
|
208
|
+
name: string;
|
|
209
|
+
fields: WgslField[];
|
|
210
|
+
/** Total size, already rounded to alignment. */
|
|
211
|
+
size: number;
|
|
212
|
+
align: number;
|
|
213
|
+
}
|
|
214
|
+
/** Role of a resource bound to the shader. */
|
|
215
|
+
type WgslBindingKind = 'uniform' | 'storage' | 'texture' | 'storage-texture' | 'sampler' | 'unknown';
|
|
216
|
+
/** A `@group(x) @binding(y) var ...` found in the source. */
|
|
217
|
+
interface WgslBinding {
|
|
218
|
+
group: number;
|
|
219
|
+
binding: number;
|
|
220
|
+
name: string;
|
|
221
|
+
kind: WgslBindingKind;
|
|
222
|
+
/** Type text, like `texture_2d<f32>`. */
|
|
223
|
+
typeText: string;
|
|
224
|
+
/** Access declared in `var<storage, read_write>`. */
|
|
225
|
+
access: 'read' | 'read-write' | 'write';
|
|
226
|
+
/** Struct of the uniforms, when the type points to a known struct. */
|
|
227
|
+
struct?: WgslStruct;
|
|
228
|
+
/** `true` for `sampler_comparison` and depth textures. */
|
|
229
|
+
comparison?: boolean;
|
|
230
|
+
/** Texture dimension, like `2d`, `cube`, or `3d`. */
|
|
231
|
+
viewDimension?: string;
|
|
232
|
+
/** Texture sample type: `float`, `unfilterable-float`, `depth`... */
|
|
233
|
+
sampleType?: string;
|
|
234
|
+
multisampled?: boolean;
|
|
235
|
+
}
|
|
236
|
+
/** An entry point declared with `@vertex`, `@fragment`, or `@compute`. */
|
|
237
|
+
interface WgslEntry {
|
|
238
|
+
stage: 'vertex' | 'fragment' | 'compute';
|
|
239
|
+
name: string;
|
|
240
|
+
/** Workgroup size, only for `@compute`. */
|
|
241
|
+
workgroupSize?: [number, number, number];
|
|
242
|
+
}
|
|
243
|
+
/** Complete result of reading a shader. */
|
|
244
|
+
interface WgslReflection {
|
|
245
|
+
structs: Record<string, WgslStruct>;
|
|
246
|
+
bindings: WgslBinding[];
|
|
247
|
+
entries: WgslEntry[];
|
|
248
|
+
/** Shortcut to the first uniform binding found. */
|
|
249
|
+
uniform?: WgslBinding;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Removes line and block comments. WGSL allows nested blocks, so
|
|
253
|
+
* counting is done with depth instead of a regex.
|
|
254
|
+
*
|
|
255
|
+
* Removed characters become spaces instead of disappearing, so the line number
|
|
256
|
+
* still matches the original file in error messages.
|
|
257
|
+
*/
|
|
258
|
+
declare function stripWgslComments(source: string): string;
|
|
259
|
+
/**
|
|
260
|
+
* Splits by top-level commas. Without this `array<vec4<f32>, 8>` would be
|
|
261
|
+
* cut in the middle of the generic.
|
|
262
|
+
*/
|
|
263
|
+
declare function splitTopLevel(text: string): string[];
|
|
264
|
+
/**
|
|
265
|
+
* Describes a WGSL type with size and alignment.
|
|
266
|
+
*
|
|
267
|
+
* The rules followed are for the `uniform` address space, which is the module's
|
|
268
|
+
* use case: struct aligned to 16 bytes and array stride also a multiple of 16.
|
|
269
|
+
* For `storage` WGSL is more relaxed; the difference is documented.
|
|
270
|
+
*/
|
|
271
|
+
declare function describeWgslType(text: string, structs?: Record<string, WgslStruct>): WgslType;
|
|
272
|
+
/**
|
|
273
|
+
* Reads `struct`s from the source and calculates the offset of each field.
|
|
274
|
+
*
|
|
275
|
+
* Structs are resolved in multiple passes because one can reference another
|
|
276
|
+
* that appears later in the file. Three passes cover any reasonable nesting
|
|
277
|
+
* without becoming a dependency graph.
|
|
278
|
+
*/
|
|
279
|
+
declare function reflectStructs(source: string): Record<string, WgslStruct>;
|
|
280
|
+
/** Reads the `@group @binding var ...` from the source. */
|
|
281
|
+
declare function reflectBindings(source: string, structs: Record<string, WgslStruct>): WgslBinding[];
|
|
282
|
+
/** Reads the `@vertex`, `@fragment`, and `@compute` from the source. */
|
|
283
|
+
declare function reflectEntries(source: string): WgslEntry[];
|
|
284
|
+
/**
|
|
285
|
+
* Reads a complete shader and returns everything the runtime needs to set it up.
|
|
286
|
+
*
|
|
287
|
+
* ```js
|
|
288
|
+
* const info = V.gpu.reflect(wgsl)
|
|
289
|
+
* info.uniform.struct.fields // [{ name: 'time', offset: 0, ... }]
|
|
290
|
+
* ```
|
|
291
|
+
*
|
|
292
|
+
* The function never throws: empty or invalid source returns an empty reflection, and
|
|
293
|
+
* the caller decides what to do. A broken shader is rejected by the driver,
|
|
294
|
+
* with a much better error message than ours.
|
|
295
|
+
*/
|
|
296
|
+
declare function reflectWgsl(source: string): WgslReflection;
|
|
297
|
+
/** Looks for the entry point name of a stage. */
|
|
298
|
+
declare function findEntry(reflection: WgslReflection, stage: WgslEntry['stage']): WgslEntry | undefined;
|
|
299
|
+
/**
|
|
300
|
+
* Builds a struct from a values object when there's no shader to consult. This is
|
|
301
|
+
* the path for `V.gpu.uniforms(gpu, { ... })`.
|
|
302
|
+
*
|
|
303
|
+
* The order of the object's keys becomes the order of the fields, so the object needs
|
|
304
|
+
* to mirror the shader's `struct`. When a shader exists, always prefer reflection:
|
|
305
|
+
* it doesn't depend on anyone remembering the correct order.
|
|
306
|
+
*/
|
|
307
|
+
declare function inferStruct(values: Record<string, unknown>, name?: string): WgslStruct;
|
|
308
|
+
/** Transforms a loose value into the list of scalars it represents. */
|
|
309
|
+
declare function flattenValue(value: unknown, components: number): number[];
|
|
310
|
+
/** Writes a field to the buffer, respecting the stride between matrix columns. */
|
|
311
|
+
declare function writeField(view: DataView, field: WgslField, value: unknown): boolean;
|
|
312
|
+
/**
|
|
313
|
+
* Writes an object of values into a buffer following the struct layout. Missing
|
|
314
|
+
* fields remain as they were, which allows updating only what changed without
|
|
315
|
+
* resending the rest.
|
|
316
|
+
*
|
|
317
|
+
* @returns the names of the fields that were actually written
|
|
318
|
+
*/
|
|
319
|
+
declare function writeStruct(buffer: ArrayBuffer, struct: WgslStruct, values: Record<string, unknown>): string[];
|
|
320
|
+
/** Creates the struct buffer already with initial values written. */
|
|
321
|
+
declare function packStruct(struct: WgslStruct, values?: Record<string, unknown>): ArrayBuffer;
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* @module gpu
|
|
325
|
+
*
|
|
326
|
+
* Voodoo's WebGPU layer, in the spirit of vgpu: loose functions that receive
|
|
327
|
+
* context as the first argument, with no hidden global state and no classes
|
|
328
|
+
* to instantiate.
|
|
329
|
+
*
|
|
330
|
+
* ```js
|
|
331
|
+
* const gpu = await V.gpu.init()
|
|
332
|
+
* const tela = V.gpu.surface(gpu, canvas, { dpr: [1, 2] })
|
|
333
|
+
* const ondas = V.gpu.effect(gpu, wgsl, { set: { speed: 1.4 } })
|
|
334
|
+
* const parar = V.gpu.frameLoop(gpu, (frame) => frame.pass(tela, ondas))
|
|
335
|
+
* ```
|
|
336
|
+
*
|
|
337
|
+
* The rule that governs everything: **never throw when WebGPU doesn't exist**.
|
|
338
|
+
* `supported()` returns `false`, `init()` returns `null` and everything else accepts
|
|
339
|
+
* `null` in place of context and becomes a no-op. A page using GPU
|
|
340
|
+
* for decoration can't break in a browser that doesn't have GPU yet.
|
|
341
|
+
*
|
|
342
|
+
* Shader bindings are not declared by hand: `gpu/wgsl` reads the source and builds
|
|
343
|
+
* the bind group layout, buffer size and offset of each uniform.
|
|
344
|
+
*/
|
|
345
|
+
|
|
346
|
+
/** Anything that occupies GPU memory and knows how to release itself. */
|
|
347
|
+
interface Disposable {
|
|
348
|
+
destroy(): void;
|
|
349
|
+
}
|
|
350
|
+
/** Context returned by `init()`. It's the first argument to everything. */
|
|
351
|
+
interface GpuContext {
|
|
352
|
+
adapter: GPUAdapter;
|
|
353
|
+
device: GPUDevice;
|
|
354
|
+
queue: GPUDevice['queue'];
|
|
355
|
+
/** Preferred canvas format on this device. */
|
|
356
|
+
format: GPUTextureFormat;
|
|
357
|
+
/** Open resources, so `destroy(gpu)` doesn't forget any. */
|
|
358
|
+
readonly resources: Set<Disposable>;
|
|
359
|
+
/** Becomes `true` after `destroy(gpu)`. All operations become no-ops. */
|
|
360
|
+
destroyed: boolean;
|
|
361
|
+
}
|
|
362
|
+
/** Options for `init()`. */
|
|
363
|
+
interface GpuInitOptions {
|
|
364
|
+
/** Adapter preference: `low-power` saves battery. */
|
|
365
|
+
powerPreference?: 'low-power' | 'high-performance';
|
|
366
|
+
/** Optional features requested from the device. Unavailable ones are ignored. */
|
|
367
|
+
features?: string[];
|
|
368
|
+
/** Desired minimum limits. */
|
|
369
|
+
limits?: Record<string, number>;
|
|
370
|
+
label?: string;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* `true` when the browser exposes WebGPU. Never throws, not in Node,
|
|
374
|
+
* not in jsdom, not in old browsers.
|
|
375
|
+
*/
|
|
376
|
+
declare function supported(): boolean;
|
|
377
|
+
/**
|
|
378
|
+
* Opens the adapter and device.
|
|
379
|
+
*
|
|
380
|
+
* ```js
|
|
381
|
+
* const gpu = await V.gpu.init()
|
|
382
|
+
* if (!gpu) mostrarVersaoSemGpu()
|
|
383
|
+
* ```
|
|
384
|
+
*
|
|
385
|
+
* @returns the context, or `null` when there's no WebGPU or the adapter refused
|
|
386
|
+
*/
|
|
387
|
+
declare function init(options?: GpuInitOptions): Promise<GpuContext | null>;
|
|
388
|
+
/**
|
|
389
|
+
* Single context for the page, created on first call.
|
|
390
|
+
*
|
|
391
|
+
* One device per tab is enough: it's what the `v-shader` directive uses, so
|
|
392
|
+
* ten canvases on the same page don't open ten devices.
|
|
393
|
+
*/
|
|
394
|
+
declare function shared(options?: GpuInitOptions): Promise<GpuContext | null>;
|
|
395
|
+
/** Forgets the shared context. Used by `destroy()` and by tests. */
|
|
396
|
+
declare function resetShared(): void;
|
|
397
|
+
/** Options for `surface()`. */
|
|
398
|
+
interface GpuSurfaceOptions {
|
|
399
|
+
/** Accepted range of `devicePixelRatio`, like `[1, 2]`. Default `[1, 2]`. */
|
|
400
|
+
dpr?: [number, number];
|
|
401
|
+
/** Canvas format. Default the device's preferred one. */
|
|
402
|
+
format?: GPUTextureFormat;
|
|
403
|
+
/** Makes the canvas transparent. Default `false`. */
|
|
404
|
+
alpha?: boolean;
|
|
405
|
+
}
|
|
406
|
+
/** Canvas configured to receive frames from the GPU. */
|
|
407
|
+
interface GpuSurface {
|
|
408
|
+
readonly canvas: HTMLCanvasElement | null;
|
|
409
|
+
readonly format: GPUTextureFormat;
|
|
410
|
+
readonly width: number;
|
|
411
|
+
readonly height: number;
|
|
412
|
+
/** View of the current frame. `null` when there's no GPU. */
|
|
413
|
+
view(): GPUTextureView | null;
|
|
414
|
+
/** Remeasures the canvas and reconfigures the context. */
|
|
415
|
+
resize(): void;
|
|
416
|
+
destroy(): void;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Prepares a `<canvas>` to receive frames.
|
|
420
|
+
*
|
|
421
|
+
* The buffer size follows the CSS size multiplied by
|
|
422
|
+
* `devicePixelRatio`, capped by the `dpr` range and the device's maximum texture size.
|
|
423
|
+
* A `ResizeObserver` keeps this up to date automatically.
|
|
424
|
+
*/
|
|
425
|
+
declare function surface(gpu: GpuContext | null, canvas: HTMLCanvasElement | null, options?: GpuSurfaceOptions): GpuSurface;
|
|
426
|
+
/** Options for `target()`. */
|
|
427
|
+
interface GpuTargetOptions {
|
|
428
|
+
width: number;
|
|
429
|
+
height: number;
|
|
430
|
+
format?: GPUTextureFormat;
|
|
431
|
+
label?: string;
|
|
432
|
+
}
|
|
433
|
+
/** Texture used as a render pass target, to chain effects. */
|
|
434
|
+
interface GpuTarget {
|
|
435
|
+
readonly texture: GPUTexture | null;
|
|
436
|
+
readonly width: number;
|
|
437
|
+
readonly height: number;
|
|
438
|
+
readonly format: GPUTextureFormat;
|
|
439
|
+
view(): GPUTextureView | null;
|
|
440
|
+
destroy(): void;
|
|
441
|
+
}
|
|
442
|
+
/** Creates a target texture for off-screen rendering. */
|
|
443
|
+
declare function target(gpu: GpuContext | null, options: GpuTargetOptions): GpuTarget;
|
|
444
|
+
/** Uniform buffer with known layout. */
|
|
445
|
+
interface GpuUniforms {
|
|
446
|
+
/** Layout in use, whether from reflection or initial values. */
|
|
447
|
+
readonly struct: WgslStruct;
|
|
448
|
+
readonly buffer: GPUBuffer | null;
|
|
449
|
+
/** Last applied values. */
|
|
450
|
+
readonly values: Record<string, unknown>;
|
|
451
|
+
/** Updates the given fields and sends the buffer. */
|
|
452
|
+
set(values: Record<string, unknown>): void;
|
|
453
|
+
destroy(): void;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Creates a uniform buffer from initial values.
|
|
457
|
+
*
|
|
458
|
+
* ```js
|
|
459
|
+
* const u = V.gpu.uniforms(gpu, { time: 0, tint: '#ff3d8b' })
|
|
460
|
+
* u.set({ time: 1.5 })
|
|
461
|
+
* ```
|
|
462
|
+
*
|
|
463
|
+
* Without a shader to consult, the layout comes from the object's key order. When
|
|
464
|
+
* there's a shader, `V.gpu.effect` prefers reflection, which doesn't depend on anyone
|
|
465
|
+
* remembering the right order.
|
|
466
|
+
*/
|
|
467
|
+
declare function uniforms(gpu: GpuContext | null, initial?: Record<string, unknown>): GpuUniforms;
|
|
468
|
+
/** Time in the frame loop, in seconds. */
|
|
469
|
+
interface GpuClock {
|
|
470
|
+
/** Seconds since the first frame. */
|
|
471
|
+
readonly time: number;
|
|
472
|
+
/** Seconds since the previous frame. */
|
|
473
|
+
readonly delta: number;
|
|
474
|
+
/** Current frame number, starting at zero. */
|
|
475
|
+
readonly frame: number;
|
|
476
|
+
/** Advances the clock. The frame loop calls it automatically. */
|
|
477
|
+
tick(now?: number): void;
|
|
478
|
+
reset(): void;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Creates a clock. The context comes in for symmetry with the rest of the API: the clock
|
|
482
|
+
* works the same with or without GPU, so the directive can write one path.
|
|
483
|
+
*/
|
|
484
|
+
declare function clock(_gpu?: GpuContext | null): GpuClock;
|
|
485
|
+
/** Options for `effect()`. */
|
|
486
|
+
interface GpuEffectOptions {
|
|
487
|
+
/** Initial uniform values. */
|
|
488
|
+
set?: Record<string, unknown>;
|
|
489
|
+
/** Name of `@fragment`. Default the first found in the source. */
|
|
490
|
+
entry?: string;
|
|
491
|
+
/** Destination format. Default the canvas's preferred format. */
|
|
492
|
+
format?: GPUTextureFormat;
|
|
493
|
+
/** Views bound to texture bindings, by variable name in WGSL. */
|
|
494
|
+
textures?: Record<string, GPUTextureView>;
|
|
495
|
+
label?: string;
|
|
496
|
+
}
|
|
497
|
+
/** A full-screen shader ready to draw. */
|
|
498
|
+
interface GpuEffect {
|
|
499
|
+
/** What reflection found in the source. Works even without GPU. */
|
|
500
|
+
readonly reflection: WgslReflection;
|
|
501
|
+
/** `false` when the pipeline didn't come up. Drawing becomes a no-op. */
|
|
502
|
+
readonly ok: boolean;
|
|
503
|
+
readonly uniforms: GpuUniforms;
|
|
504
|
+
/** Updates uniforms without recreating the pipeline. */
|
|
505
|
+
set(values: Record<string, unknown>): void;
|
|
506
|
+
/** Records the draw commands. Called by `frame.pass`. */
|
|
507
|
+
draw(pass: GPURenderPassEncoder): void;
|
|
508
|
+
destroy(): void;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Compiles a full-screen shader.
|
|
512
|
+
*
|
|
513
|
+
* When the source doesn't bring `@vertex`, Voodoo adds a triangle covering
|
|
514
|
+
* the screen and delivers `@location(0) uv` to the fragment. Writing just the `@fragment` is
|
|
515
|
+
* the common case, and what the `v-shader` directive expects.
|
|
516
|
+
*
|
|
517
|
+
* ```js
|
|
518
|
+
* const efeito = V.gpu.effect(gpu, wgsl, { set: { speed: 1.2 } })
|
|
519
|
+
* efeito.set({ speed: 2 }) // doesn't recompile anything
|
|
520
|
+
* ```
|
|
521
|
+
*/
|
|
522
|
+
declare function effect(gpu: GpuContext | null, wgsl: string, options?: GpuEffectOptions): GpuEffect;
|
|
523
|
+
/** Options for `compute()`. */
|
|
524
|
+
interface GpuComputeOptions {
|
|
525
|
+
set?: Record<string, unknown>;
|
|
526
|
+
entry?: string;
|
|
527
|
+
/** How many workgroups to dispatch. Default `[1, 1, 1]`. */
|
|
528
|
+
workgroups?: [number, number?, number?];
|
|
529
|
+
textures?: Record<string, GPUTextureView>;
|
|
530
|
+
label?: string;
|
|
531
|
+
}
|
|
532
|
+
/** A compute shader ready to dispatch. */
|
|
533
|
+
interface GpuCompute {
|
|
534
|
+
readonly reflection: WgslReflection;
|
|
535
|
+
readonly ok: boolean;
|
|
536
|
+
readonly uniforms: GpuUniforms;
|
|
537
|
+
set(values: Record<string, unknown>): void;
|
|
538
|
+
/** Records the dispatch. Called by `frame.compute`. */
|
|
539
|
+
dispatch(pass: GPUComputePassEncoder, workgroups?: [number, number?, number?]): void;
|
|
540
|
+
destroy(): void;
|
|
541
|
+
}
|
|
542
|
+
/** Compiles a compute shader. */
|
|
543
|
+
declare function compute(gpu: GpuContext | null, wgsl: string, options?: GpuComputeOptions): GpuCompute;
|
|
544
|
+
/** Target accepted by `frame.pass`. */
|
|
545
|
+
type GpuPassTarget = GpuSurface | GpuTarget | null;
|
|
546
|
+
/** Clear color, like `[r, g, b, a]` from 0 to 1. */
|
|
547
|
+
type GpuClearColor = [number, number, number, number];
|
|
548
|
+
/** The frame being built, delivered to the callback of `frame` and `frameLoop`. */
|
|
549
|
+
interface GpuFrame {
|
|
550
|
+
readonly encoder: GPUCommandEncoder | null;
|
|
551
|
+
/** Loop clock. Outside the loop, always marks frame zero. */
|
|
552
|
+
readonly clock: GpuClock;
|
|
553
|
+
/** Opens a render pass on the target and executes effects in order. */
|
|
554
|
+
pass(destino: GpuPassTarget, ...operacoes: Array<GpuEffect | null | undefined>): void;
|
|
555
|
+
/** Opens a compute pass and dispatches operations in order. */
|
|
556
|
+
compute(...operacoes: Array<GpuCompute | null | undefined>): void;
|
|
557
|
+
/** Color used when clearing the target. Default transparent. */
|
|
558
|
+
clear: GpuClearColor;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Records and submits a frame.
|
|
562
|
+
*
|
|
563
|
+
* ```js
|
|
564
|
+
* V.gpu.frame(gpu, (frame) => frame.pass(tela, ondas))
|
|
565
|
+
* ```
|
|
566
|
+
*/
|
|
567
|
+
declare function frame(gpu: GpuContext | null, build: (frame: GpuFrame) => void, relogio?: GpuClock): void;
|
|
568
|
+
/**
|
|
569
|
+
* Frame loop with `requestAnimationFrame`.
|
|
570
|
+
*
|
|
571
|
+
* ```js
|
|
572
|
+
* const parar = V.gpu.frameLoop(gpu, (frame) => {
|
|
573
|
+
* ondas.set({ time: frame.clock.time })
|
|
574
|
+
* frame.pass(tela, ondas)
|
|
575
|
+
* })
|
|
576
|
+
* ```
|
|
577
|
+
*
|
|
578
|
+
* @returns function that stops the loop. Without GPU, the loop never starts.
|
|
579
|
+
*/
|
|
580
|
+
declare function frameLoop(gpu: GpuContext | null, build: (frame: GpuFrame) => void): () => void;
|
|
581
|
+
/**
|
|
582
|
+
* Releases everything the context opened and shuts down the device.
|
|
583
|
+
*
|
|
584
|
+
* Calling twice does no harm, and calling with `null` doesn't either.
|
|
585
|
+
*/
|
|
586
|
+
declare function destroy(gpu: GpuContext | null): void;
|
|
587
|
+
/**
|
|
588
|
+
* Everything from the module grouped, to expose as `V.gpu` without clashing with names of
|
|
589
|
+
* other modules, like the `effect` from reactivity.
|
|
590
|
+
*/
|
|
591
|
+
declare const gpu: {
|
|
592
|
+
supported: typeof supported;
|
|
593
|
+
init: typeof init;
|
|
594
|
+
shared: typeof shared;
|
|
595
|
+
surface: typeof surface;
|
|
596
|
+
target: typeof target;
|
|
597
|
+
uniforms: typeof uniforms;
|
|
598
|
+
clock: typeof clock;
|
|
599
|
+
effect: typeof effect;
|
|
600
|
+
compute: typeof compute;
|
|
601
|
+
frame: typeof frame;
|
|
602
|
+
frameLoop: typeof frameLoop;
|
|
603
|
+
destroy: typeof destroy;
|
|
604
|
+
/** WGSL reading, useful on its own for inspecting a shader. */
|
|
605
|
+
reflect: typeof reflectWgsl;
|
|
606
|
+
};
|
|
607
|
+
|
|
608
|
+
export { effect as $, type GpuContext as A, BUFFER_USAGE as B, type GpuEffect as C, type GpuEffectOptions as D, type GpuFrame as E, type GpuInitOptions as F, type GPUAdapter as G, type GpuPassTarget as H, type GpuSurface as I, type GpuSurfaceOptions as J, type GpuTarget as K, type GpuTargetOptions as L, type GpuUniforms as M, type WgslBindingKind as N, type WgslEntry as O, type WgslField as P, type WgslReflection as Q, type WgslStruct as R, SHADER_STAGE as S, TEXTURE_USAGE as T, type WgslType as U, type WgslTypeKind as V, type WgslBinding as W, clock as X, compute as Y, describeWgslType as Z, destroy as _, type GPUBindGroup as a, findEntry as a0, flattenValue as a1, frame as a2, frameLoop as a3, gpu as a4, inferStruct as a5, init as a6, packStruct as a7, reflectBindings as a8, reflectEntries as a9, reflectStructs as aa, reflectWgsl as ab, resetShared as ac, shared as ad, splitTopLevel as ae, stripWgslComments as af, supported as ag, surface as ah, target as ai, uniforms as aj, writeField as ak, writeStruct as al, type GPUBindGroupLayout as b, type GPUBuffer as c, type GPUCanvasContext as d, type GPUCommandBuffer as e, type GPUCommandEncoder as f, type GPUCompilationInfo as g, type GPUCompilationMessage as h, type GPUComputePassEncoder as i, type GPUComputePipeline as j, type GPUDevice as k, type GPUDeviceLostInfo as l, type GPUNavigator as m, type GPUPipelineLayout as n, type GPUQueue as o, type GPURenderPassEncoder as p, type GPURenderPipeline as q, type GPUSampler as r, type GPUShaderModule as s, type GPUTexture as t, type GPUTextureFormat as u, type GPUTextureView as v, type GpuClearColor as w, type GpuClock as x, type GpuCompute as y, type GpuComputeOptions as z };
|