UNPKG

typegpu

Version:

A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.

146 lines (145 loc) 9.1 kB
import { type TgpuBuffer, type UniformFlag } from './core/buffer/buffer.ts'; import { type TgpuComparisonSampler, type TgpuSampler } from './core/sampler/sampler.ts'; import { type PropsForSchema, type TgpuTexture, type TgpuTextureView } from './core/texture/texture.ts'; import { type SampledFlag } from './core/texture/usageExtension.ts'; import { type WgslExternalTexture, type WgslStorageTexture, type WgslTexture } from './data/texture.ts'; import type { TgpuRoot } from './core/root/rootTypes.ts'; import type { RestoreContext } from './serial/types.ts'; import type { BaseData } from './data/wgslTypes.ts'; import { type StorageFlag } from './extension.ts'; import type { TgpuNamable } from './shared/meta.ts'; import type { InferGPU, MemIdentity } from './shared/repr.ts'; import type { TgpuDeviceOwningSoul, TgpuSoul } from './shared/soul.ts'; import { $gpuValueOf, $internal, $soul } from './shared/symbols.ts'; import type { NullableToOptional, Prettify } from './shared/utilityTypes.ts'; import type { ResolvableObject, ShaderStage } from './types.ts'; import type { Unwrapper } from './unwrapper.ts'; import type { WgslComparisonSampler, WgslSampler } from './data/sampler.ts'; import { type TgpuBufferBinding, type TgpuMutable, type TgpuReadonly, type TgpuUniform } from './core/buffer/bufferBinding.ts'; export interface LayoutMembership { layout: TgpuBindGroupLayout; key: string; idx: number; } export type TgpuLayoutEntryBase = { /** * Limits this resource's visibility to specific shader stages. * * By default, each resource is visible to all shader stage types, but * depending on the underlying implementation, this may have performance implications. * * @default ['compute','fragment'] for mutable resources * @default ['compute','vertex','fragment'] for everything else */ visibility?: ShaderStage[]; }; export type TgpuLayoutUniform = TgpuLayoutEntryBase & { uniform: BaseData; }; export type TgpuLayoutStorage = TgpuLayoutEntryBase & { storage: BaseData | ((arrayLength: number) => BaseData); /** @default 'readonly' */ access?: 'mutable' | 'readonly'; }; export type TgpuLayoutSampler = TgpuLayoutEntryBase & { sampler: 'filtering' | 'non-filtering'; }; export type TgpuLayoutComparisonSampler = TgpuLayoutEntryBase & { sampler: 'comparison'; }; export type TgpuLayoutTexture<TSchema extends WgslTexture = WgslTexture> = TgpuLayoutEntryBase & { texture: TSchema; sampleType?: GPUTextureSampleType; }; export type TgpuLayoutStorageTexture<TSchema extends WgslStorageTexture = WgslStorageTexture> = TgpuLayoutEntryBase & { storageTexture: TSchema; }; export type TgpuLayoutExternalTexture = TgpuLayoutEntryBase & { externalTexture: WgslExternalTexture; }; export type TgpuLayoutEntry = TgpuLayoutUniform | TgpuLayoutStorage | TgpuLayoutSampler | TgpuLayoutComparisonSampler | TgpuLayoutTexture | TgpuLayoutStorageTexture | TgpuLayoutExternalTexture; type UnwrapRuntimeConstructorInner<T extends BaseData | ((_: number) => BaseData)> = T extends (_: number) => BaseData ? ReturnType<T> : T; export type UnwrapRuntimeConstructor<T extends BaseData | ((_: number) => BaseData)> = T extends unknown ? UnwrapRuntimeConstructorInner<T> : never; export interface TgpuBindGroupLayoutSoul extends TgpuSoul<'bind-group-layout'> { readonly entries: Record<string, TgpuLayoutEntry | null>; index?: number | undefined; } /** * A residue soul: entries may hold runtime-local resources (texture views), so * the soul holds the layout and the created bind group instead of the recipe. * It is completed by `[$internal].materialize()`. */ export interface TgpuBindGroupSoul<Entries extends Record<string, TgpuLayoutEntry | null> = Record<string, TgpuLayoutEntry | null>> extends TgpuDeviceOwningSoul<'bind-group', GPUBindGroup> { readonly layout: TgpuBindGroupLayout<Entries>; } export interface TgpuBindGroupLayout<Entries extends Record<string, TgpuLayoutEntry | null> = Record<string, TgpuLayoutEntry | null>> extends TgpuNamable { readonly [$internal]: ResolvableObject[]; readonly [$soul]: TgpuBindGroupLayoutSoul; readonly resourceType: 'bind-group-layout'; readonly entries: Entries; readonly [$gpuValueOf]: { [K in keyof Entries]: InferLayoutEntry<Entries[K]>; }; readonly $: { [K in keyof Entries]: InferLayoutEntry<Entries[K]>; }; /** * An explicit numeric index assigned to this bind group layout. If undefined, a unique * index is assigned automatically during resolution. This can be changed with the * `.$idx()` method. */ readonly index: number | undefined; /** * Associates this bind group layout with an explicit numeric index. When a call to this * method is omitted, a unique numeric index is assigned to it automatically. * * Used when generating WGSL code: `@group(${index}) @binding(...) ...;` */ $idx(index?: number): this; /** * Creates a raw WebGPU resource based on the typed descriptor. * NOTE: This creates a new resource every time, better to use `root.unwrap(...)` instead. * @param unwrapper Used to unwrap any resources that this resource depends on. */ unwrap(unwrapper: Unwrapper): GPUBindGroupLayout; } export type LayoutEntryToInput<T extends TgpuLayoutEntry | null> = TgpuLayoutEntry | null extends T ? TgpuBuffer<BaseData> | TgpuBufferBinding<BaseData> | GPUBuffer | TgpuSampler | GPUSampler | TgpuComparisonSampler | TgpuTexture | GPUTextureView | GPUExternalTexture : T extends TgpuLayoutUniform ? (TgpuBuffer<MemIdentity<UnwrapRuntimeConstructor<T['uniform']>>> & UniformFlag) | TgpuUniform<MemIdentity<UnwrapRuntimeConstructor<T['uniform']>>> | GPUBuffer : T extends TgpuLayoutStorage ? (TgpuBuffer<MemIdentity<UnwrapRuntimeConstructor<T['storage']>>> & StorageFlag) | (T extends { access: 'mutable'; } ? TgpuMutable<MemIdentity<UnwrapRuntimeConstructor<T['storage']>>> : TgpuReadonly<MemIdentity<UnwrapRuntimeConstructor<T['storage']>>>) | GPUBuffer : T extends TgpuLayoutSampler ? TgpuSampler | GPUSampler : T extends TgpuLayoutComparisonSampler ? TgpuComparisonSampler | GPUSampler : T extends TgpuLayoutTexture ? GPUTextureView | GPUTexture | (SampledFlag & TgpuTexture<Prettify<PropsForSchema<T['texture']>>>) | TgpuTextureView<WgslTexture> : T extends TgpuLayoutStorageTexture ? GPUTextureView | GPUTexture | (StorageFlag & TgpuTexture<Prettify<PropsForSchema<T['storageTexture']>>>) | TgpuTextureView<WgslStorageTexture> : T extends TgpuLayoutExternalTexture ? GPUExternalTexture : never; export type InferLayoutEntry<T extends TgpuLayoutEntry | null> = T extends TgpuLayoutUniform ? InferGPU<T['uniform']> : T extends TgpuLayoutStorage ? InferGPU<UnwrapRuntimeConstructor<T['storage']>> : T extends TgpuLayoutSampler ? InferGPU<WgslSampler> : T extends TgpuLayoutComparisonSampler ? InferGPU<WgslComparisonSampler> : T extends TgpuLayoutTexture<infer TSchema> ? InferGPU<TSchema> : T extends TgpuLayoutStorageTexture<infer TSchema> ? InferGPU<TSchema> : T extends TgpuLayoutExternalTexture ? InferGPU<T['externalTexture']> : never; export type ExtractBindGroupInputFromLayout<T extends Record<string, TgpuLayoutEntry | null>> = NullableToOptional<{ [K in keyof T]: LayoutEntryToInput<T[K]>; }>; export type TgpuBindGroup<Entries extends Record<string, TgpuLayoutEntry | null> = Record<string, TgpuLayoutEntry | null>> = { readonly [$internal]: { readonly materialize: () => GPUBindGroup; }; readonly [$soul]: TgpuBindGroupSoul<Entries>; readonly resourceType: 'bind-group'; readonly layout: TgpuBindGroupLayout<Entries>; unwrap(unwrapper: Unwrapper): GPUBindGroup; }; export declare function bindGroupLayout<Entries extends Record<string, TgpuLayoutEntry | null>>(entries: Entries): TgpuBindGroupLayout<Prettify<Entries>>; export declare function INTERNAL_restoreBindGroupLayout(soul: TgpuBindGroupLayoutSoul): TgpuBindGroupLayout; export declare function INTERNAL_restoreBindGroup(soul: TgpuBindGroupSoul, ctx: RestoreContext): TgpuBindGroup; export declare function isBindGroupLayout(value: unknown): value is TgpuBindGroupLayout; export declare function isBindGroup(value: unknown): value is TgpuBindGroup; /** * @category Errors */ export declare class MissingBindingError extends Error { constructor(groupLabel: string | undefined, key: string); } export declare class TgpuBindGroupImpl<Entries extends Record<string, TgpuLayoutEntry | null> = Record<string, TgpuLayoutEntry | null>> implements TgpuBindGroup<Entries> { #private; readonly [$internal]: { readonly materialize: () => GPUBindGroup; }; readonly [$soul]: TgpuBindGroupSoul<Entries>; readonly resourceType: "bind-group"; constructor(root: TgpuRoot | undefined, layout: TgpuBindGroupLayout<Entries>, entries: ExtractBindGroupInputFromLayout<Entries>, raw?: GPUBindGroup); get layout(): TgpuBindGroupLayout<Entries>; get entries(): ExtractBindGroupInputFromLayout<Entries>; unwrap(unwrapper: Unwrapper): GPUBindGroup; } export {};