UNPKG

webgpu-pipeline-kit

Version:

A type-safe declarative way of creating WebGPU pipelines

273 lines (256 loc) 15.3 kB
import { LogLevelDesc } from 'loglevel'; type Color = { r: number; g: number; b: number; a?: number; }; type NonEmptyArray<T> = [T, ...T[]]; type Decrement = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; type OneOrBoth<A, B> = (A & Partial<B>) | (B & Partial<A>); type Slice = { min: number; length: number; }; type CopySlice = Slice & { toIndex: number; }; type ValueSlices<T> = { values: T; copySlices: CopySlice[]; }; type Vec3 = readonly [number, number, number]; type WPKPrimitiveMap = { boolean: boolean; string: string; number: number; }; type WPKInstanceFormat = _WPKInstanceFormat<4>; type WPKInstanceOf<TFormat extends WPKInstanceFormat> = _WPKInstanceOf<TFormat, 4>; type _WPKInstanceFormat<Depth extends number> = Depth extends never ? never : keyof WPKPrimitiveMap | _WPKInstanceFormat<Decrement[Depth]>[] | { [key: string]: _WPKInstanceFormat<Decrement[Depth]>; }; type _WPKInstanceOf<TObj, TDepth extends number> = TObj extends keyof WPKPrimitiveMap ? WPKPrimitiveMap[TObj] : TObj extends readonly [any, ...any[]] ? { [K in keyof TObj]: _WPKInstanceOf<TObj[K], Decrement[TDepth]>; } : TObj extends object ? { [K in keyof TObj]: _WPKInstanceOf<TObj[K], Decrement[TDepth]>; } : never; type WPKCacheMutable<T, TKey> = { mutate: (id: TKey, element: T) => void; }; type WPKCacheResizeable<T> = { add: (element: T) => string; remove: (id: string) => void; indexOf: (id: string) => number; }; type WPKUniformCache<TUniformFormat extends WPKInstanceFormat, TMutable extends boolean> = { isMutable: TMutable; isDirty: () => boolean; get: () => WPKInstanceOf<TUniformFormat>; } & (TMutable extends true ? { mutate: (element: WPKInstanceOf<TUniformFormat>) => void; } : object); type WPKEntityCache<TEntityFormat extends WPKInstanceFormat, TMutable extends boolean, TResizeable extends boolean> = { isMutable: TMutable; isResizeable: TResizeable; count: () => number; isDirty: () => boolean; calculateChanges: () => ValueSlices<WPKInstanceOf<TEntityFormat>[]>; } & (TMutable extends true ? WPKCacheMutable<WPKInstanceOf<TEntityFormat>, TResizeable extends true ? string : number> : object) & (TResizeable extends true ? WPKCacheResizeable<WPKInstanceOf<TEntityFormat>> : object); type WPKTupleIndexes<T extends readonly unknown[]> = Extract<keyof T, `${number}`> extends `${infer N extends number}` ? N : never; type WPKIsExact<A, B> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? (<T>() => T extends B ? 1 : 2) extends (<T>() => T extends A ? 1 : 2) ? true : false : false; type WPKIsTuple<T> = T extends readonly unknown[] ? number extends T['length'] ? false : true : false; type _WPKMatchingPath<TType, TMatchingType, TPrefix extends string, TDepth extends number> = TDepth extends never ? never : TType extends readonly unknown[] ? WPKIsTuple<TType> extends true ? { [I in WPKTupleIndexes<TType>]: WPKIsExact<TType[I], TMatchingType> extends true ? `${TPrefix}${I}` : _WPKMatchingPath<TType[I], TMatchingType, `${TPrefix}${I}.`, Decrement[TDepth]>; }[WPKTupleIndexes<TType>] : never : TType extends object ? { [K in keyof TType & string]: WPKIsExact<TType[K], TMatchingType> extends true ? `${TPrefix}${K}` : _WPKMatchingPath<TType[K], TMatchingType, `${TPrefix}${K}.`, Decrement[TDepth]>; }[keyof TType & string] : never; type WPKMatchingPath<TType, TMatchingType> = _WPKMatchingPath<TType, TMatchingType, '', 4>; type WPKPrimitive8 = 'sint8' | 'snorm8' | 'uint8' | 'unorm8'; type WPKPrimitive16 = 'sint16' | 'snorm16' | 'uint16' | 'unorm16' | 'float16'; type WPKPrimitive32 = 'sint32' | 'uint32' | 'float32'; type WPKPrimitiveSignedInt = 'sint8' | 'sint16' | 'sint32'; type WPKPrimitive = WPKPrimitive8 | WPKPrimitive16 | WPKPrimitive32; type WPKMatchingPathScalar<TFormat extends WPKInstanceFormat> = WPKMatchingPath<WPKInstanceOf<TFormat>, number>; type WPKMatchingPathVec2<TFormat extends WPKInstanceFormat> = WPKMatchingPath<WPKInstanceOf<TFormat>, [number, number]>; type WPKMatchingPathVec3<TFormat extends WPKInstanceFormat> = WPKMatchingPath<WPKInstanceOf<TFormat>, [number, number, number]>; type WPKMatchingPathVec4<TFormat extends WPKInstanceFormat> = WPKMatchingPath<WPKInstanceOf<TFormat>, [number, number, number, number]>; type WPKDatumType<TDatumType = WPKPrimitive> = { datumType: TDatumType; }; type WPKLayoutTypes<TDimension, TDatumType = WPKPrimitive> = WPKDatumType<TDatumType> & { dimension: TDimension; }; type WPKLayoutScalar = WPKLayoutTypes<'scalar'>; type WPKLayoutVec2 = WPKLayoutTypes<'vec2'>; type WPKLayoutVec3 = WPKLayoutTypes<'vec3', WPKPrimitive32>; type WPKLayoutVec4 = WPKLayoutTypes<'vec4'>; type WPKLayout = WPKLayoutScalar | WPKLayoutVec2 | WPKLayoutVec3 | WPKLayoutVec4; type WPKPathScalar<TFormat extends WPKInstanceFormat> = WPKMatchingPathScalar<TFormat>; type WPKPathVec2<TFormat extends WPKInstanceFormat> = WPKMatchingPathVec2<TFormat> | [ WPKMatchingPathScalar<TFormat>, WPKMatchingPathScalar<TFormat> ]; type WPKPathVec3<TFormat extends WPKInstanceFormat> = WPKMatchingPathVec3<TFormat> | [ WPKMatchingPathScalar<TFormat>, WPKMatchingPathScalar<TFormat>, WPKMatchingPathScalar<TFormat> ]; type WPKPathVec4<TFormat extends WPKInstanceFormat> = WPKMatchingPathVec4<TFormat> | [ WPKMatchingPathScalar<TFormat>, WPKMatchingPathScalar<TFormat>, WPKMatchingPathScalar<TFormat>, WPKMatchingPathScalar<TFormat> ]; type WPKUserFormatScalar<TFormat extends WPKInstanceFormat> = WPKDatumType & { scalar: WPKPathScalar<TFormat>; }; type WPKUserFormatVec2<TFormat extends WPKInstanceFormat> = WPKDatumType & { vec2: WPKPathVec2<TFormat>; }; type WPKUserFormatVec3<TFormat extends WPKInstanceFormat> = WPKDatumType<WPKPrimitive32> & { vec3: WPKPathVec3<TFormat>; }; type WPKUserFormatVec4<TFormat extends WPKInstanceFormat> = WPKDatumType & { vec4: WPKPathVec4<TFormat>; }; type WPKUserFormatEntityIndex<TEntityFormat extends WPKInstanceFormat> = WPKDatumType<WPKPrimitiveSignedInt> & { entityIndexFromResizeableEntityCache: { key: WPKMatchingPath<WPKInstanceOf<TEntityFormat>, string>; target: WPKEntityCache<any, any, true>; }; }; type WPKUserFormat<TFormat extends WPKInstanceFormat, TIsEntity extends boolean> = WPKUserFormatScalar<TFormat> | WPKUserFormatVec2<TFormat> | WPKUserFormatVec3<TFormat> | WPKUserFormatVec4<TFormat> | (TIsEntity extends true ? WPKUserFormatEntityIndex<TFormat> : never); type WPKBufferType = 'uniform' | 'entity'; type WPKContentType = 'layout' | 'marshalled'; type WPKBufferTypes<TBufferType extends WPKBufferType, TContentType extends WPKContentType> = { bufferType: TBufferType; contentType: TContentType; }; type WPKFormatLayout = NonEmptyArray<WPKLayout>; type WPKFormatMarshall<TEntityFormat extends WPKInstanceFormat, TIsEntity extends boolean> = NonEmptyArray<WPKUserFormat<TEntityFormat, TIsEntity>>; type WPKBufferDetailLayout = { layout: WPKFormatLayout; }; type WPKBufferDetailMarshall<TEntityFormat extends WPKInstanceFormat, TIsEntity extends boolean> = { marshall: WPKFormatMarshall<TEntityFormat, TIsEntity>; }; type WPKBufferFormatUniform<TUniformFormat extends WPKInstanceFormat> = WPKBufferTypes<'uniform', 'marshalled'> & WPKBufferDetailMarshall<TUniformFormat, false>; type WPKBufferFormatEntityLayout = WPKBufferTypes<'entity', 'layout'> & WPKBufferDetailLayout; type WPKBufferFormatEntityMarshalled<TEntityFormat extends WPKInstanceFormat> = WPKBufferTypes<'entity', 'marshalled'> & WPKBufferDetailMarshall<TEntityFormat, true>; type WPKBufferFormatEntity<TEntityFormat extends WPKInstanceFormat> = WPKBufferFormatEntityLayout | WPKBufferFormatEntityMarshalled<TEntityFormat>; type WPKBufferFormat<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat> = WPKBufferFormatUniform<TUniformFormat> | WPKBufferFormatEntity<TEntityFormat>; type WPKBufferFormatMap<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat> = Record<string, WPKBufferFormat<TUniformFormat, TEntityFormat>>; type WPKBufferFormatKeyEntity<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormats extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = string & { [K in keyof TBufferFormats]: TBufferFormats[K] extends WPKBufferFormatEntity<TEntityFormat> ? K : never; }[keyof TBufferFormats]; type WPKBufferFormatKey<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormats extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = string & (keyof TBufferFormats); type WPKVertices = Vec3[]; type WPKIndices = Vec3[]; type WPKMesh = { vertices: WPKVertices; indices: WPKIndices; topology: GPUPrimitiveTopology; winding: GPUFrontFace; }; type WPKWorkGroupSize = { x: number; y?: number; z?: number; }; type WPKHasEntryPoint = { entryPoint: string; }; type WPKBufferLocationType = 'mesh' | 'user-defined'; type WPKBufferLocationStep = 'vertex' | 'instance'; type WPKBufferLocationBase<TType extends WPKBufferLocationType, TStep extends WPKBufferLocationStep> = { type: TType; location: number; step: TStep; }; type WPKForeignBufferRef<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormatMap extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = { formats: TBufferFormatMap; key: WPKBufferFormatKey<TUniformFormat, TEntityFormat, TBufferFormatMap>; }; type WPKBufferLocationMesh = WPKBufferLocationBase<'mesh', 'vertex'> & { format: 'float32x3'; }; type WPKBufferLocationUserDefined<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormatMap extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = WPKBufferLocationBase<'user-defined', 'instance'> & { buffer: WPKBufferFormatKeyEntity<TUniformFormat, TEntityFormat, TBufferFormatMap>; }; type WPKBufferLocation<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormatMap extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = WPKBufferLocationMesh | WPKBufferLocationUserDefined<TUniformFormat, TEntityFormat, TBufferFormatMap>; type WPKRenderPass<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormatMap extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = { vertex: WPKHasEntryPoint & { bufferLocations: Array<WPKBufferLocation<TUniformFormat, TEntityFormat, TBufferFormatMap>>; }; fragment: WPKHasEntryPoint; }; type WPKBufferBindingRef<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormatMap extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = WPKBufferFormatKey<TUniformFormat, TEntityFormat, TBufferFormatMap> | WPKForeignBufferRef<any, any, any>; type WPKBufferBinding<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormatMap extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = { group: number; binding: number; buffer: WPKBufferBindingRef<TUniformFormat, TEntityFormat, TBufferFormatMap>; }; type WPKComputePass = WPKHasEntryPoint & { workGroupSize: WPKWorkGroupSize; }; type WPKComputeShader<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormatMap extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = { compute: { shader: string; bufferBindings: Array<WPKBufferBinding<TUniformFormat, TEntityFormat, TBufferFormatMap>>; passes: Array<WPKComputePass>; }; }; type WPKRenderShader<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormatMap extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = { render: { shader: string; bufferBindings: Array<WPKBufferBinding<TUniformFormat, TEntityFormat, TBufferFormatMap>>; passes: Array<WPKRenderPass<TUniformFormat, TEntityFormat, TBufferFormatMap>>; mesh: WPKMesh; }; }; type WPKShader<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormatMap extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = OneOrBoth<WPKComputeShader<TUniformFormat, TEntityFormat, TBufferFormatMap>, WPKRenderShader<TUniformFormat, TEntityFormat, TBufferFormatMap>>; type WPKPipelineDefinition<TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormatMap extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>> = { name: string; shader: WPKShader<TUniformFormat, TEntityFormat, TBufferFormatMap>; bufferFormats: TBufferFormatMap; uniformCache: WPKUniformCache<TUniformFormat, any>; entityCache: WPKEntityCache<TEntityFormat, any, any>; }; type WPKPipelineOptions = { clear: Color; isAntiAliased: boolean; }; type WPKPipelineRunner = { invoke: (options: WPKPipelineOptions) => Promise<void>; }; declare const factories: { color: { BLACK: Color; RED: Color; GREEN: Color; BLUE: Color; WHITE: Color; of(r?: number, g?: number, b?: number, a?: number): Color; }; cache: { ofUniform: <TUniformFormat extends WPKInstanceFormat, TMutable extends boolean>(_uniformFormat: TUniformFormat, initialUniform: WPKInstanceOf<TUniformFormat>, mutable: TMutable) => WPKUniformCache<TUniformFormat, TMutable>; ofEntitiesFixedSize: <TEntityFormat extends WPKInstanceFormat, TMutable extends boolean>(_entityFormat: TEntityFormat, mutable: TMutable, ...elements: WPKInstanceOf<TEntityFormat>[]) => WPKEntityCache<TEntityFormat, TMutable, false>; ofEntitiesResizeable: <TEntityFormat extends WPKInstanceFormat, TMutable extends boolean>(_entityFormat: TEntityFormat, mutable: TMutable) => WPKEntityCache<TEntityFormat, TMutable, true>; }; mesh: { of: (type: GPUPrimitiveTopology, vertices: WPKVertices, indices: WPKIndices, winding: GPUFrontFace) => WPKMesh; triangle: (topProportion: number, axis?: Vec3) => WPKMesh; cube: () => WPKMesh; sphere(subdivisions: number): WPKMesh; }; pipelineRunner: { of: (canvas: HTMLCanvasElement, definitions_0: WPKPipelineDefinition<any, any, any>, ...definitions: WPKPipelineDefinition<any, any, any>[]) => Promise<WPKPipelineRunner>; }; shader: { ofForeignBufferRef: <TUniformFormat extends WPKInstanceFormat, TEntityFormat extends WPKInstanceFormat, TBufferFormatMap extends WPKBufferFormatMap<TUniformFormat, TEntityFormat>>(_foreignUniformFormat: TUniformFormat, _foreignEntityFormat: TEntityFormat, foreignBufferFormats: TBufferFormatMap, key: WPKBufferFormatKey<TUniformFormat, TEntityFormat, TBufferFormatMap>) => WPKForeignBufferRef<TUniformFormat, TEntityFormat, TBufferFormatMap>; }; }; type WPKLogNamespace = 'buffer' | 'cache' | 'data' | 'mesh' | 'pipeline'; declare const setLogLevel: (level: LogLevelDesc, namespace?: WPKLogNamespace) => void; export { type WPKBufferFormatMap, type WPKInstanceFormat, type WPKInstanceOf, type WPKLogNamespace, type WPKPipelineDefinition, type WPKPipelineOptions, type WPKShader, factories, setLogLevel };