wesl-gpu 0.1.1 → 0.1.3

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/dist/index.js CHANGED
@@ -335,20 +335,28 @@ async function linkAndCreatePipeline(params) {
335
335
  * - a virtual module containing a std uniform buffer (for size, etc.)
336
336
  */
337
337
  async function linkFragmentShader(params) {
338
- const { device, fragmentSource, bundles = [], resolver } = params;
339
- const { conditions, constants, packageName } = params;
338
+ const { fragmentSource, conditions, constants, packageName, config } = params;
339
+ const { device, resolver, libs = [], rootModuleName = "main" } = params;
340
+ const { weslSrc, virtualLibs } = params;
340
341
  const fullSource = `${fragmentSource}\n\n${fullscreenTriangleVertex}`;
341
- let sourceParams;
342
- if (resolver) sourceParams = { resolver: new CompositeResolver([new RecordResolver({ main: fullSource }, { packageName }), resolver]) };
343
- else sourceParams = { weslSrc: { main: fullSource } };
342
+ const resolvers = [];
343
+ resolvers.push(new RecordResolver({ [rootModuleName]: fullSource }, { packageName }));
344
+ if (weslSrc) resolvers.push(new RecordResolver(weslSrc, { packageName }));
345
+ let finalResolver = resolvers.length === 1 ? resolvers[0] : new CompositeResolver(resolvers);
346
+ if (resolver) finalResolver = new CompositeResolver([finalResolver, resolver]);
347
+ const mergedVirtualLibs = {
348
+ ...createUniformsVirtualLib(),
349
+ ...virtualLibs
350
+ };
344
351
  return (await link({
345
- ...sourceParams,
346
- rootModuleName: "main",
352
+ resolver: finalResolver,
353
+ rootModuleName,
347
354
  packageName,
348
- libs: bundles,
349
- virtualLibs: createUniformsVirtualLib(),
355
+ libs,
356
+ virtualLibs: mergedVirtualLibs,
350
357
  conditions,
351
- constants
358
+ constants,
359
+ config
352
360
  })).createShaderModule(device);
353
361
  }
354
362
  /** Create fullscreen fragment render pipeline from a shader module. */
@@ -492,4 +500,41 @@ function createBindGroup(device, uniformBuffer, textures = [], samplers = []) {
492
500
  }
493
501
 
494
502
  //#endregion
495
- export { DeviceCache, checkerboardTexture, colorBarsTexture, createBindGroup, createSampler, createUniformsVirtualLib, edgePatternTexture, fullscreenTriangleVertex, fullscreenVertexCount, gradientTexture, linkAndCreatePipeline, linkFragmentShader, noiseTexture, radialGradientTexture, renderFrame, renderUniformBuffer, simpleRender, solidTexture, updateRenderUniforms, withErrorScopes };
503
+ //#region src/RunFragment.ts
504
+ /**
505
+ * Run a fragment shader and return pixel data.
506
+ *
507
+ * Combines linking, uniform setup, and rendering into a single call.
508
+ * Useful for shader testing or single-frame renders.
509
+ *
510
+ * @returns Pixel data as a flattened number array
511
+ */
512
+ async function runFragment(params) {
513
+ const { src, device } = params;
514
+ const { textureFormat = "rgba32float", size = [1, 1] } = params;
515
+ const { textures, samplers, uniforms = {} } = params;
516
+ return simpleRender({
517
+ device,
518
+ module: await linkFragmentShader({
519
+ device,
520
+ fragmentSource: src,
521
+ resolver: params.resolver,
522
+ weslSrc: params.weslSrc,
523
+ libs: params.libs,
524
+ virtualLibs: params.virtualLibs,
525
+ conditions: params.conditions,
526
+ constants: params.constants,
527
+ packageName: params.packageName,
528
+ rootModuleName: params.rootModuleName,
529
+ config: params.config
530
+ }),
531
+ outputFormat: textureFormat,
532
+ size,
533
+ textures,
534
+ samplers,
535
+ uniformBuffer: renderUniformBuffer(device, size, uniforms)
536
+ });
537
+ }
538
+
539
+ //#endregion
540
+ export { DeviceCache, checkerboardTexture, colorBarsTexture, createBindGroup, createSampler, createUniformsVirtualLib, edgePatternTexture, fullscreenTriangleVertex, fullscreenVertexCount, gradientTexture, linkAndCreatePipeline, linkFragmentShader, noiseTexture, radialGradientTexture, renderFrame, renderUniformBuffer, runFragment, simpleRender, solidTexture, updateRenderUniforms, withErrorScopes };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "wesl-gpu",
3
3
  "description": "Browser-compatible WebGPU utilities for shader testing and rendering",
4
- "version": "0.1.1",
4
+ "version": "0.1.3",
5
5
  "type": "module",
6
6
  "repository": "github:wgsl-tooling-wg/wesl-js",
7
7
  "exports": {
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "thimbleberry": "^0.2.10",
15
- "wesl": "0.6.47"
15
+ "wesl": "0.6.49"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@webgpu/types": "^0.1.65"
@@ -0,0 +1,42 @@
1
+ import type { LinkParams } from "wesl";
2
+ import type { RenderUniforms } from "./RenderUniforms.ts";
3
+
4
+ /** WESL linker options - aligned with wesl's LinkParams */
5
+ export type WeslOptions = Pick<
6
+ LinkParams,
7
+ | "resolver"
8
+ | "weslSrc"
9
+ | "rootModuleName"
10
+ | "conditions"
11
+ | "libs"
12
+ | "virtualLibs"
13
+ | "packageName"
14
+ | "constants"
15
+ | "config"
16
+ >;
17
+
18
+ /** GPU rendering params for fragment shaders */
19
+ export interface FragmentRenderParams {
20
+ device: GPUDevice;
21
+
22
+ /** Output texture format. Default: "rgba32float" */
23
+ textureFormat?: GPUTextureFormat;
24
+
25
+ /** Output texture size. Default: [1, 1] */
26
+ size?: [width: number, height: number];
27
+
28
+ /** Uniform values (time, mouse). Resolution auto-populated from size. */
29
+ uniforms?: RenderUniforms;
30
+
31
+ /** Input textures. Bindings: [1..n], samplers at [n+1..n+m]. */
32
+ textures?: GPUTexture[];
33
+
34
+ /** Samplers. Length 1 (reused) or match textures.length. */
35
+ samplers?: GPUSampler[];
36
+ }
37
+
38
+ /** Combined params for fragment shader execution */
39
+ export interface FragmentParams extends WeslOptions, FragmentRenderParams {
40
+ /** Fragment shader source (vertex shader auto-provided) */
41
+ src: string;
42
+ }
@@ -1,29 +1,14 @@
1
- import type { LinkParams, ModuleResolver, WeslBundle } from "wesl";
2
1
  import { CompositeResolver, link, RecordResolver } from "wesl";
2
+ import type { WeslOptions } from "./FragmentParams.ts";
3
3
  import { fullscreenTriangleVertex } from "./FullscreenVertex.ts";
4
4
  import { createUniformsVirtualLib } from "./RenderUniforms.ts";
5
5
 
6
- export interface LinkFragmentParams {
6
+ export type LinkFragmentParams = WeslOptions & {
7
7
  device: GPUDevice;
8
8
 
9
9
  /** Fragment shader source (vertex shader is auto-provided) */
10
10
  fragmentSource: string;
11
-
12
- /** WESL library bundles for dependencies */
13
- bundles?: WeslBundle[];
14
-
15
- /** Resolver for lazy file loading (e.g., useSourceShaders mode in tests) */
16
- resolver?: ModuleResolver;
17
-
18
- /** Conditional compilation flags */
19
- conditions?: Record<string, boolean>;
20
-
21
- /** Compile-time constants */
22
- constants?: Record<string, string | number>;
23
-
24
- /** Package name (allows imports to mention the current package by name instead of package::) */
25
- packageName?: string;
26
- }
11
+ };
27
12
 
28
13
  export interface LinkAndCreateParams extends LinkFragmentParams {
29
14
  format: GPUTextureFormat;
@@ -52,31 +37,36 @@ export async function linkAndCreatePipeline(
52
37
  export async function linkFragmentShader(
53
38
  params: LinkFragmentParams,
54
39
  ): Promise<GPUShaderModule> {
55
- const { device, fragmentSource, bundles = [], resolver } = params;
56
- const { conditions, constants, packageName } = params;
40
+ const { fragmentSource, conditions, constants, packageName, config } = params;
41
+ const { device, resolver, libs = [], rootModuleName = "main" } = params;
42
+ const { weslSrc, virtualLibs } = params;
57
43
 
58
44
  const fullSource = `${fragmentSource}\n\n${fullscreenTriangleVertex}`;
59
45
 
60
- // Use provided resolver or fall back to simple weslSrc
61
- let sourceParams: Pick<LinkParams, "resolver" | "weslSrc">;
62
- if (resolver) {
63
- const srcResolver = new RecordResolver(
64
- { main: fullSource },
65
- { packageName },
66
- );
67
- sourceParams = { resolver: new CompositeResolver([srcResolver, resolver]) };
68
- } else {
69
- sourceParams = { weslSrc: { main: fullSource } };
70
- }
46
+ // Build resolver chain: fragmentSource first, then weslSrc, then provided resolver
47
+ const resolvers: RecordResolver[] = [];
48
+ resolvers.push(
49
+ new RecordResolver({ [rootModuleName]: fullSource }, { packageName }),
50
+ );
51
+ if (weslSrc) resolvers.push(new RecordResolver(weslSrc, { packageName }));
52
+
53
+ let finalResolver =
54
+ resolvers.length === 1 ? resolvers[0] : new CompositeResolver(resolvers);
55
+ if (resolver)
56
+ finalResolver = new CompositeResolver([finalResolver, resolver]);
57
+
58
+ // Merge user virtualLibs with default uniforms lib
59
+ const mergedVirtualLibs = { ...createUniformsVirtualLib(), ...virtualLibs };
71
60
 
72
61
  const linked = await link({
73
- ...sourceParams,
74
- rootModuleName: "main",
62
+ resolver: finalResolver,
63
+ rootModuleName,
75
64
  packageName,
76
- libs: bundles,
77
- virtualLibs: createUniformsVirtualLib(),
65
+ libs,
66
+ virtualLibs: mergedVirtualLibs,
78
67
  conditions,
79
68
  constants,
69
+ config,
80
70
  });
81
71
 
82
72
  return linked.createShaderModule(device);
@@ -0,0 +1,43 @@
1
+ import type { FragmentParams } from "./FragmentParams.ts";
2
+ import { linkFragmentShader } from "./FragmentPipeline.ts";
3
+ import { renderUniformBuffer } from "./RenderUniforms.ts";
4
+ import { simpleRender } from "./SimpleRender.ts";
5
+
6
+ /**
7
+ * Run a fragment shader and return pixel data.
8
+ *
9
+ * Combines linking, uniform setup, and rendering into a single call.
10
+ * Useful for shader testing or single-frame renders.
11
+ *
12
+ * @returns Pixel data as a flattened number array
13
+ */
14
+ export async function runFragment(params: FragmentParams): Promise<number[]> {
15
+ const { src, device } = params;
16
+ const { textureFormat = "rgba32float", size = [1, 1] } = params;
17
+ const { textures, samplers, uniforms = {} } = params;
18
+
19
+ const module = await linkFragmentShader({
20
+ device,
21
+ fragmentSource: src,
22
+ resolver: params.resolver,
23
+ weslSrc: params.weslSrc,
24
+ libs: params.libs,
25
+ virtualLibs: params.virtualLibs,
26
+ conditions: params.conditions,
27
+ constants: params.constants,
28
+ packageName: params.packageName,
29
+ rootModuleName: params.rootModuleName,
30
+ config: params.config,
31
+ });
32
+
33
+ const uniformBuffer = renderUniformBuffer(device, size, uniforms);
34
+ return simpleRender({
35
+ device,
36
+ module,
37
+ outputFormat: textureFormat,
38
+ size,
39
+ textures,
40
+ samplers,
41
+ uniformBuffer,
42
+ });
43
+ }
package/src/index.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  export * from "./DeviceCache.ts";
2
2
  export * from "./ErrorScopes.ts";
3
3
  export * from "./ExampleTextures.ts";
4
+ export * from "./FragmentParams.ts";
4
5
  export * from "./FragmentPipeline.ts";
5
6
  export * from "./FragmentRender.ts";
6
7
  export * from "./FullscreenVertex.ts";
7
8
  export * from "./RenderUniforms.ts";
9
+ export * from "./RunFragment.ts";
8
10
  export * from "./SimpleRender.ts";