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
TypeScript
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 {};