Files
yawn/addons/handles/src/ComputePass.ts
T

99 lines
2.8 KiB
TypeScript

import type { Scene } from "./Scene";
export type GraphBuffer = {
id: string;
array: string;
usage?: string[];
sync?: "frame" | "loadout";
};
export type GraphTexture = {
id: string;
format?: string;
size?: [number | "canvas", number | "canvas", number?];
usage?: string[];
mipLevelCount?: number;
transient?: boolean;
};
export type GraphSampler = {
id: string;
magFilter?: "nearest" | "linear";
minFilter?: "nearest" | "linear";
mipmapFilter?: "nearest" | "linear";
addressModeU?: "clamp-to-edge" | "repeat" | "mirror-repeat";
addressModeV?: "clamp-to-edge" | "repeat" | "mirror-repeat";
anisotropyClamp?: number;
};
export type GraphBinding = {
group: number;
binding: number;
resource: string;
};
export type ComputePassOptions = {
id?: string;
code: string;
entry?: string;
dispatch?: [number, number?, number?];
after?: string[];
bindings?: GraphBinding[];
buffers?: GraphBuffer[];
textures?: GraphTexture[];
samplers?: GraphSampler[];
};
let nextComputePass = 1;
/** A graph-authored compute pass; attaching or updating it rebuilds the Scene loadout. */
export class ComputePass {
readonly id: string;
code: string;
entry: string;
dispatch: [number, number, number];
after: string[];
bindings: GraphBinding[];
buffers: GraphBuffer[];
textures: GraphTexture[];
samplers: GraphSampler[];
#scene?: Scene;
constructor(options: ComputePassOptions) {
if (!options?.code) throw new TypeError("ComputePass code is required");
this.id = options.id ?? `compute-${nextComputePass++}`;
this.code = options.code;
this.entry = options.entry ?? "main";
this.dispatch = [
options.dispatch?.[0] ?? 1,
options.dispatch?.[1] ?? 1,
options.dispatch?.[2] ?? 1,
];
this.after = [...(options.after ?? [])];
this.bindings = [...(options.bindings ?? [])];
this.buffers = [...(options.buffers ?? [])];
this.textures = [...(options.textures ?? [])];
this.samplers = [...(options.samplers ?? [])];
}
update(options: Partial<Omit<ComputePassOptions, "id">>) {
if (options.code !== undefined) this.code = options.code;
if (options.entry !== undefined) this.entry = options.entry;
if (options.dispatch !== undefined) this.dispatch = [
options.dispatch[0],
options.dispatch[1] ?? 1,
options.dispatch[2] ?? 1,
];
if (options.after !== undefined) this.after = [...options.after];
if (options.bindings !== undefined) this.bindings = [...options.bindings];
if (options.buffers !== undefined) this.buffers = [...options.buffers];
if (options.textures !== undefined) this.textures = [...options.textures];
if (options.samplers !== undefined) this.samplers = [...options.samplers];
return this.#scene?.updateRenderGraph() ?? Promise.resolve();
}
attach(scene?: Scene) {
this.#scene = scene;
}
}