UNPKG

wesl-debug

Version:

Utilities for testing WESL/WGSL shaders in Node.js environments.

206 lines (205 loc) 10.4 kB
import { LinkParams, VirtualLibraryFn } from "wesl"; import { WgslElementType, WgslElementType as WgslElementType$1 } from "thimbleberry"; import { ImageData, ImageData as ImageData$1 } from "vitest-image-snapshot"; //#region src/CompileShader.d.ts interface CompileShaderParams { /** The project directory, used for resolving dependencies. */ projectDir: string; /** The GPUDevice to use for shader compilation. */ device: GPUDevice; /** The WGSL/WESL shader source code. */ src: string; /** Optional conditions for shader compilation. */ conditions?: LinkParams["conditions"]; /** Optional constants for shader compilation. */ constants?: LinkParams["constants"]; /** Optional virtual libraries to include in the shader. */ virtualLibs?: LinkParams["virtualLibs"]; } /** * Compiles a single WESL shader source string into a GPUShaderModule for testing * with automatic package detection. * * Parses the shader source to find references to wesl packages, and * then searches installed npm packages to find the appropriate npm package * bundle to include in the link. */ declare function compileShader(params: CompileShaderParams): Promise<GPUShaderModule>; //#endregion //#region src/ErrorScopes.d.ts /** * Runs a function with WebGPU error scopes, automatically handling push/pop/check. * Throws if any validation, out-of-memory, or internal errors occur. */ declare function withErrorScopes<T>(device: GPUDevice, fn: () => T | Promise<T>): Promise<T>; //#endregion //#region src/ExampleTextures.d.ts interface SamplerOptions { addressMode?: "clamp-to-edge" | "repeat" | "mirror-repeat"; filterMode?: "nearest" | "linear"; } /** Create texture filled with solid color. Internally cached. */ declare function solidTexture(device: GPUDevice, color: [r: number, g: number, b: number, a: number], width: number, height: number): GPUTexture; /** Create gradient texture. Direction: 'horizontal' (default) or 'vertical'. */ declare function gradientTexture(device: GPUDevice, width: number, height: number, direction?: "horizontal" | "vertical"): GPUTexture; /** Create checkerboard pattern. cellSize: pixels per cell (default: width/4). */ declare function checkerboardTexture(device: GPUDevice, width: number, height: number, cellSize?: number): GPUTexture; /** Create sampler. Default: linear filtering with clamp-to-edge. Internally cached. */ declare function createSampler(device: GPUDevice, options?: SamplerOptions): GPUSampler; /** Create radial gradient texture (white center to black edge). */ declare function radialGradientTexture(device: GPUDevice, size: number): GPUTexture; /** Create edge pattern texture with sharp vertical, horizontal, and diagonal lines. */ declare function edgePatternTexture(device: GPUDevice, size: number): GPUTexture; /** Create color bars texture (RGB primaries and secondaries). */ declare function colorBarsTexture(device: GPUDevice, size: number): GPUTexture; /** Create seeded noise pattern (deterministic). */ declare function noiseTexture(device: GPUDevice, size: number, seed?: number): GPUTexture; //#endregion //#region src/ImageHelpers.d.ts /** Load PNG file and create GPU texture. */ declare function pngToTexture(device: GPUDevice, imagePath: string): Promise<GPUTexture>; //#endregion //#region src/RenderUniforms.d.ts /** User provided uniform values */ interface RenderUniforms { /** Elapsed time in seconds (default: 0.0) */ time?: number; /** Mouse position in [0,1] normalized coords (default: [0.0, 0.0]) */ mouse?: [number, number]; } /** * Creates a standard uniform buffer for running test fragment shaders. * * @param outputSize - Output texture dimensions (becomes uniforms.resolution) * @param uniforms - User-provided uniform values (time, mouse) * @returns GPUBuffer containing uniform data */ declare function renderUniformBuffer(device: GPUDevice, outputSize: [number, number], uniforms?: RenderUniforms): GPUBuffer; /** * return the WGSL struct for use in shaders as test::Uniforms. * * @returns virtual library object for passing to compileShader() */ declare function createUniformsVirtualLib(): Record<string, VirtualLibraryFn>; //#endregion //#region src/TestComputeShader.d.ts interface ComputeTestParams { /** WESL/WGSL source code for a compute shader to test*/ src: string; /** directory in your project. Used so that the test library * can find installed npm shader libraries. * That way your fragment shader can use import statements * from shader npm libraries. * (typically use import.meta.url) */ projectDir: string; /** gpu device for running the tests. * (typically use getGPUDevice() from wesl-debug) */ device: GPUDevice; /** format of result buffer * default: "u32" */ resultFormat?: WgslElementType$1; /** size of result buffer in bytes * default: 16 */ size?: number; /** flags for conditional compilation for testing shader specialization. * useful to test `@if` statements in the shader. */ conditions?: LinkParams["conditions"]; /** constants for shader compilation. * useful to inject host-provided values via the `constants::` namespace. */ constants?: LinkParams["constants"]; } /** * Transpiles and runs a simple compute shader on the GPU for testing. * * A storage buffer is available for the shader to write test results. * `test::results[0]` is the first element of the buffer in wesl. * After execution the storage buffer is copied back to the CPU and returned * for test validation. * * Shader libraries mentioned in the shader source are attached automatically * if they are in node_modules. * * @returns storage result array (typically four numbers if the buffer format is u32 or f32) */ declare function testComputeShader(params: ComputeTestParams): Promise<number[]>; /** * Transpiles and runs a simple compute shader on the GPU for testing. * * a storage buffer is available for the shader at `@group(0) @binding(0)`. * Compute shaders can write test results into the buffer. * After execution the storage buffer is copied back to the CPU and returned * for test validation. * * Shader libraries mentioned in the shader source are attached automatically * if they are in node_modules. * * @param module - The compiled GPUShaderModule containing the compute shader. * The shader is invoked once. * @param resultFormat - format for interpreting the result buffer data. (default u32) * @param size - size of result buffer in bytes (default 16) * @returns storage result array */ declare function runCompute(device: GPUDevice, module: GPUShaderModule, resultFormat?: WgslElementType$1, size?: number): Promise<number[]>; //#endregion //#region src/TestFragmentShader.d.ts declare const fullscreenTriangleVertex = "\n @vertex\n fn vs_main(@builtin(vertex_index) idx: u32) -> @builtin(position) vec4f {\n // Fullscreen triangle: covers viewport with 3 vertices, no vertex buffer needed\n var pos: vec2f;\n if (idx == 0u) {\n pos = vec2f(-1.0, -1.0); // Vertex 0: bottom-left (-1, -1)\n } else if (idx == 1u) {\n pos = vec2f(3.0, -1.0); // Vertex 1: bottom-right beyond viewport (3, -1)\n } else {\n pos = vec2f(-1.0, 3.0); // Vertex 2: top-left beyond viewport (-1, 3)\n }\n return vec4f(pos, 0.0, 1.0);\n }"; interface FragmentTestParams { /** WESL/WGSL source code for a fragment shader to test*/ src: string; /** directory in your project. Used so that the test library * can find installed npm shader libraries. * That way your fragment shader can use import statements * from shader npm libraries. * (typically use import.meta.url) */ projectDir: string; /** gpu device for running the tests. * (typically use getGPUDevice() from wesl-debug) */ device: GPUDevice; /** optionally select the texture format for the output texture * default: "rgba32float" */ textureFormat?: GPUTextureFormat; /** optionally specify the size of the output texture. * default: [1, 1] for simple color tests. * Use [2, 2] for derivative tests (forms a complete 2x2 quad for dpdx/dpdy) */ size?: [width: number, height: number]; /** flags for conditional compilation for testing shader specialization. * useful to test `@if` statements in the shader. */ conditions?: LinkParams["conditions"]; /** constants for shader compilation. * useful to inject host-provided values via the `constants::` namespace. */ constants?: LinkParams["constants"]; /** uniform values for the shader (time, mouse). * resolution is auto-populated from size parameter. * Creates test::Uniforms struct available in shader. */ uniforms?: RenderUniforms; /** input textures + samplers for the shader. * binds sequentially: [1]=texture, [2]=sampler, [3]=texture, [4]=sampler, ... * (binding 0 is reserved for uniforms) */ inputTextures?: Array<{ texture: GPUTexture; sampler: GPUSampler; }>; } /** Run a fragment shader and returns pixel (0,0) for validation. */ declare function testFragmentShader(params: FragmentTestParams): Promise<number[]>; /** Run a fragment shader and return the rendered image. */ declare function testFragmentShaderImage(params: FragmentTestParams): Promise<ImageData$1>; /** * Tests an animated shader at multiple time points. * Useful for validating that shaders change over time. * * @param params - Same as testFragmentShader, plus timePoints array * @returns Array of image arrays, one per time point */ declare function testAnimatedShader(params: FragmentTestParams & { timePoints: number[]; }): Promise<number[][]>; //#endregion //#region src/WebGPUTestSetup.d.ts /** get or create shared GPU device for testing */ declare function getGPUDevice(): Promise<GPUDevice>; /** destroy globally shared GPU test device */ declare function destroySharedDevice(): void; //#endregion export { CompileShaderParams, ComputeTestParams, FragmentTestParams, type ImageData, RenderUniforms, SamplerOptions, type WgslElementType, checkerboardTexture, colorBarsTexture, compileShader, createSampler, createUniformsVirtualLib, destroySharedDevice, edgePatternTexture, fullscreenTriangleVertex, getGPUDevice, gradientTexture, noiseTexture, pngToTexture, radialGradientTexture, renderUniformBuffer, runCompute, solidTexture, testAnimatedShader, testComputeShader, testFragmentShader, testFragmentShaderImage, withErrorScopes }; //# sourceMappingURL=index.d.ts.map