typegpu
Version:
A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.
171 lines (170 loc) • 8.13 kB
TypeScript
import type { Namespace } from './core/resolve/namespace.ts';
import type { Configurable, ExperimentalTgpuRoot } from './core/root/rootTypes.ts';
import { type Eventual, type SlotValuePair, type TgpuLazy, type TgpuSlot } from './core/slot/slotTypes.ts';
import { UnknownData } from './data/dataTypes.ts';
import { type ResolvedSnippet, type Snippet } from './data/snippet.ts';
import { type BaseData } from './data/wgslTypes.ts';
import { $internal } from './shared/symbols.ts';
import { type TgpuBindGroup, type TgpuBindGroupLayout, type TgpuLayoutEntry } from './tgpuBindGroupLayout.ts';
import type { LogResources, SupportedLogOp } from './tgsl/consoleLog/types.ts';
import type { ShaderGenerator } from './tgsl/shaderGenerator.ts';
import type { BlockScopeLayer, ExecMode, ExecState, ResolveFunctionOptions, FunctionArgumentAccess, FunctionScopeLayer, ItemLayer, ItemStateStack, ResolutionCtx, StackLayer, ShaderStage, Wgsl } from './types.ts';
import type { WgslEnableExtension } from './wgslExtensions.ts';
export type ResolutionCtxImplOptions = {
readonly enableExtensions?: WgslEnableExtension[] | undefined;
readonly shaderGenerator?: ShaderGenerator | undefined;
readonly config?: ((cfg: Configurable) => Configurable) | undefined;
readonly root?: ExperimentalTgpuRoot | undefined;
readonly namespace: Namespace;
readonly minify: boolean;
};
declare class ItemStateStackImpl implements ItemStateStack {
private _stack;
private _itemDepth;
get itemDepth(): number;
get topItem(): ItemLayer;
get topFunctionScope(): FunctionScopeLayer | undefined;
get topBlockScope(): BlockScopeLayer | undefined;
get blockDepth(): number;
pushItem(): void;
pushSlotBindings(pairs: SlotValuePair[]): void;
pushFunctionScope(functionType: 'normal' | ShaderStage, argAccess: Record<string, FunctionArgumentAccess>, returnType: BaseData | undefined, externalMap: Record<string, unknown>): FunctionScopeLayer;
pushBlockScope(): void;
pop<T extends StackLayer['type']>(type: T): Extract<StackLayer, {
type: T;
}>;
pop(): StackLayer | undefined;
readSlot<T>(slot: TgpuSlot<T>): T | undefined;
getSnippetById(id: string): Snippet | undefined;
/**
* Returns whether the given identifier is taken in any block scope up to the nearest function scope.
*/
isIdentifierTakenLocally(id: string): boolean;
/**
* Returns whether the given identifier is taken in any block scope on the stack.
*
* This is useful when resolving a global identifier for the first time within a nested function.
*/
isIdentifierTakenInCallStack(id: string): boolean;
defineBlockVariable(id: string, snippet: Snippet): void;
setBlockExternals(externals: Record<string, Snippet>): void;
clearBlockExternals(): void;
}
export declare class IndentController {
identLevel: number;
get pre(): string;
indent(): string;
dedent(): string;
withResetLevel<T>(callback: () => T): T;
}
interface FixedBindingConfig {
layoutEntry: TgpuLayoutEntry;
resource: object;
}
export declare class ResolutionCtxImpl implements ResolutionCtx {
#private;
private readonly _indentController;
private readonly _itemStateStack;
private readonly _declarations;
private _varyingLocations;
readonly gen: ShaderGenerator;
get varyingLocations(): Record<string, number> | undefined;
readonly [$internal]: {
itemStateStack: ItemStateStackImpl;
};
/**
* A map from registered bind group layouts to random strings put in
* place of their group index. The whole tree has to be traversed to
* collect every use of a typed bind group layout, since they can be
* explicitly imposed group indices, and they cannot collide.
*/
readonly bindGroupLayoutsToPlaceholderMap: Map<TgpuBindGroupLayout<Record<string, TgpuLayoutEntry | null>>, string>;
private _nextFreeLayoutPlaceholderIdx;
readonly fixedBindings: FixedBindingConfig[];
readonly enableExtensions: WgslEnableExtension[] | undefined;
expectedType: BaseData | undefined;
constructor(opts: ResolutionCtxImplOptions);
isIdentifierBanned(name: string): boolean;
isIdentifierTaken(name: string, scope: 'global' | 'block'): boolean;
makeUniqueIdentifier(primer: string | undefined, scope: 'global' | 'block'): string;
reserveIdentifier(name: string, scope: 'global' | 'block'): void;
get pre(): string;
get topFunctionScope(): FunctionScopeLayer | undefined;
get topFunctionReturnType(): BaseData | undefined;
get shelllessRepo(): import("./tgsl/shellless.ts").ShelllessRepository;
get blockDepth(): number;
indent(): string;
dedent(): string;
getDedented(code: string): string;
withResetIndentLevel<T>(callback: () => T): T;
getById(id: string): Snippet | null;
defineVariable(id: string, snippet: Snippet): void;
reportReturnType(dataType: BaseData): void;
pushBlockScope(): void;
popBlockScope(): void;
setBlockExternals(externals: Record<string, Snippet>): void;
clearBlockExternals(): void;
generateLog(op: SupportedLogOp, args: Snippet[]): Snippet;
get logResources(): LogResources | undefined;
resolveFunction(options: ResolveFunctionOptions): {
code: string;
returnType: BaseData;
};
addDeclaration(declaration: string, name?: string): void;
get declarations(): readonly ResolvedDeclaration[];
allocateLayoutEntry(layout: TgpuBindGroupLayout): string;
allocateFixedEntry(layoutEntry: TgpuLayoutEntry, resource: object): {
group: string;
binding: number;
};
readSlot<T>(slot: TgpuSlot<T>): T;
withSlots<T>(pairs: SlotValuePair[], callback: () => T): T;
withVaryingLocations<T>(locations: Record<string, number>, callback: () => T): T;
withRenamed<T>(item: object, name: string | undefined, callback: () => T): T;
unwrap<T>(eventual: Eventual<T>): T;
_getOrCompute<T>(lazy: TgpuLazy<T>): T;
/**
* @param item The item whose resolution should be either retrieved from the cache (if there is a cache hit), or resolved.
*/
_getOrInstantiate(item: object): ResolvedSnippet;
resolve(item: unknown, schema?: BaseData | UnknownData): ResolvedSnippet;
resolveSnippet(snippet: Snippet): ResolvedSnippet;
pushMode(mode: ExecState): void;
popMode(expected?: ExecMode): void;
get mode(): ExecState;
}
/**
* A single module-scope declaration emitted during resolution.
*
* @property name - The resolved identifier the declaration declares (a fn, struct, var, const or
* alias name), or `undefined` for declarations that don't declare a single identifier (e.g.
* `tgpu['~unstable'].declare`).
* @property code - The WGSL code of the declaration.
*/
export interface ResolvedDeclaration {
name: string | undefined;
code: string;
}
/**
* The results of a WGSL resolution.
*
* @param code - The resolved code.
* @param declarations - The module-scope declarations emitted by TypeGPU
* during this resolution, in emission order. When resolving an array without a
* template, `code` equals `declarations.map((d) => d.code).join('\n\n')` (unless extensions are enabled or minification is enabled).
* When resolving a template, the template itself is not included in `declarations`.
* With a shared namespace, only declarations emitted by *this* resolution are
* included (memoized ones are not re-emitted).
* @param usedBindGroupLayouts - List of used `tgpu.bindGroupLayout`s.
* @param catchall - Automatically constructed bind group for buffer usages and buffer bindings, preceded by its index.
* @param logResources - Buffers and information about used console.logs needed to decode the raw data.
*/
export interface ResolutionResult {
code: string;
declarations: ResolvedDeclaration[];
usedBindGroupLayouts: TgpuBindGroupLayout[];
catchall: [number, TgpuBindGroup] | undefined;
logResources: LogResources | undefined;
}
export declare function resolve(item: Wgsl, options: ResolutionCtxImplOptions): ResolutionResult;
export {};