typegpu
Version:
A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.
122 lines (121 loc) • 7.84 kB
TypeScript
import type { Disarray } from '../../data/dataTypes.ts';
import type { PrimitiveOffsetInfo } from '../../data/offsetUtils.ts';
import type { BaseData, WgslArray } from '../../data/wgslTypes.ts';
import { $internal } from '../../shared/symbols.ts';
import type { TgpuBindGroup, TgpuBindGroupLayout, TgpuLayoutEntry } from '../../tgpuBindGroupLayout.ts';
import type { IndexFlag, IndirectFlag, TgpuBuffer, VertexFlag } from '../buffer/buffer.ts';
import { RenderDrawState } from '../pipeline/drawState.ts';
import type { TgpuRenderPipeline } from '../pipeline/renderPipeline.ts';
import { type TgpuQuerySet } from '../querySet/querySet.ts';
import type { ExperimentalTgpuRoot } from '../root/rootTypes.ts';
import type { TgpuCommandEncoder } from './commandEncoder.ts';
import type { TgpuVertexLayout } from '../vertexLayout/vertexLayout.ts';
import { type ColorAttachment, type DepthStencilAttachment, type TgpuPassTimestampWrites } from './attachments.ts';
/**
* The TypeGPU equivalent of {@link GPURenderPassDescriptor}. Attachment views accept
* TypeGPU textures, texture views and canvas contexts (next to raw {@link GPUTextureView}s),
* and query sets accept {@link TgpuQuerySet}.
*
* Load/store operations default to `loadOp: 'clear'`, `storeOp: 'store'`
* (and `depthClearValue: 1` for depth attachments). For depth/stencil attachments,
* defaults are derived from the view's format and aspect. A raw {@link GPUTextureView}
* with no explicit operations is assumed to be depth-only; provide explicit
* operations for raw stencil or depth-stencil views.
*/
export interface TgpuRenderPassDescriptor {
label?: string | undefined;
colorAttachments?: ColorAttachment | readonly (ColorAttachment | null)[] | undefined;
depthStencilAttachment?: DepthStencilAttachment | undefined;
occlusionQuerySet?: TgpuQuerySet<'occlusion'> | GPUQuerySet | undefined;
timestampWrites?: TgpuPassTimestampWrites | undefined;
maxDrawCount?: number | undefined;
}
export interface RenderPassInternals<TRaw extends GPURenderPassEncoder | GPURenderBundleEncoder = GPURenderPassEncoder | GPURenderBundleEncoder> {
readonly rawPass: TRaw;
readonly state: RenderDrawState;
/** Undefined for bundle encoders and for raw pass encoders the caller owns */
readonly owner: TgpuCommandEncoder | undefined;
appliedVersion: number | undefined;
}
/**
* The draw-recording surface shared by render passes and render bundle encoders,
* mirroring {@link GPURenderCommandsMixin}.
*
* Draw either by binding TypeGPU pipelines to it (`pipeline.with(pass).draw(...)`),
* or proxy-style via `pass.setPipeline(pipeline)` followed by `pass.draw(...)`.
* Pipeline resolution is lazy: shaders compile on the first draw.
*/
export interface TgpuRenderCommands {
readonly [$internal]: RenderPassInternals;
readonly resourceType: 'render-pass' | 'render-bundle-encoder';
/** Sets the current {@link TgpuRenderPipeline} for subsequent draw calls */
setPipeline(pipeline: TgpuRenderPipeline): void;
/** Associates a bind group with the layout it was created from */
setBindGroup(bindGroup: TgpuBindGroup): void;
/** Associates a bind group with the given layout */
setBindGroup<Entries extends Record<string, TgpuLayoutEntry | null>>(bindGroupLayout: TgpuBindGroupLayout<Entries>, bindGroup: TgpuBindGroup<Entries> | GPUBindGroup): void;
/** Binds a vertex buffer to the given vertex layout */
setVertexBuffer<TData extends WgslArray | Disarray>(vertexLayout: TgpuVertexLayout<TData>, buffer: (TgpuBuffer<TData> & VertexFlag) | GPUBuffer, offset?: number, size?: number): void;
/** Sets the current index buffer */
setIndexBuffer<TData extends WgslArray | Disarray>(buffer: (TgpuBuffer<TData> & IndexFlag) | GPUBuffer, indexFormat: GPUIndexFormat, offset?: number, size?: number): void;
draw(vertexCount: number, instanceCount?: number, firstVertex?: number, firstInstance?: number): void;
drawIndexed(indexCount: number, instanceCount?: number, firstIndex?: number, baseVertex?: number, firstInstance?: number): void;
/**
* Draws primitives using parameters read from a buffer.
* The buffer must contain 4 consecutive u32 values (vertexCount, instanceCount, firstVertex, firstInstance).
* To get the correct offset within complex data structures, use `d.memoryLayoutOf(...)`.
*
* @param indirectBuffer - Buffer marked with 'indirect' usage containing draw parameters or raw GPUBuffer
* @param indirectOffset - PrimitiveOffsetInfo pointing to the first draw parameter. If not provided, starts at offset 0. To obtain safe offsets, use `d.memoryLayoutOf(...)`.
*/
drawIndirect(indirectBuffer: (TgpuBuffer<BaseData> & IndirectFlag) | GPUBuffer, indirectOffset?: PrimitiveOffsetInfo | number): void;
/**
* Draws indexed primitives using parameters read from a buffer.
* The buffer must contain 5 consecutive 32-bit integer values (indexCount u32, instanceCount u32, firstIndex u32, baseVertex i32, firstInstance u32).
* To get the correct offset within complex data structures, use `d.memoryLayoutOf(...)`.
*
* @param indirectBuffer - Buffer marked with 'indirect' usage containing draw parameters or raw GPUBuffer
* @param indirectOffset - PrimitiveOffsetInfo pointing to the first draw parameter. If not provided, starts at offset 0. To obtain safe offsets, use `d.memoryLayoutOf(...)`.
*/
drawIndexedIndirect(indirectBuffer: (TgpuBuffer<BaseData> & IndirectFlag) | GPUBuffer, indirectOffset?: PrimitiveOffsetInfo | number): void;
}
/**
* Records draw commands into a render bundle, mirroring {@link GPURenderBundleEncoder}.
*
* Call `finish()` to obtain a {@link GPURenderBundle}, replayable in a render
* pass via {@link TgpuRenderPass.executeBundles}.
*/
export interface TgpuRenderBundleEncoder extends TgpuRenderCommands {
readonly [$internal]: RenderPassInternals<GPURenderBundleEncoder>;
readonly resourceType: 'render-bundle-encoder';
/** Completes the recording and returns the resulting {@link GPURenderBundle} */
finish(descriptor?: GPURenderBundleDescriptor): GPURenderBundle;
}
/**
* A render pass recording into a {@link TgpuCommandEncoder}. On top of the
* draw commands, it exposes the state that WebGPU scopes to a render pass.
*
* Call `end()` when done recording.
*/
export interface TgpuRenderPass extends TgpuRenderCommands {
readonly [$internal]: RenderPassInternals<GPURenderPassEncoder>;
readonly resourceType: 'render-pass';
setViewport(x: number, y: number, width: number, height: number, minDepth: number, maxDepth: number): void;
setScissorRect(x: number, y: number, width: number, height: number): void;
setBlendConstant(color: readonly [number, number, number, number] | GPUColor): void;
setStencilReference(reference: GPUStencilValue): void;
beginOcclusionQuery(queryIndex: GPUSize32): void;
endOcclusionQuery(): void;
/**
* Executes previously recorded {@link GPURenderBundle}s as part of this pass.
* As per the WebGPU spec, this resets the raw pass's pipeline, bind group
* and vertex/index buffer state. The state tracked by this typed pass is
* re-applied on the next draw.
*/
executeBundles(bundles: Iterable<GPURenderBundle>): void;
/** Completes the recording of this render pass */
end(): void;
}
export declare function INTERNAL_beginRenderPass(encoder: TgpuCommandEncoder, descriptor: TgpuRenderPassDescriptor): TgpuRenderPass;
export declare function INTERNAL_createRenderBundleEncoder(root: ExperimentalTgpuRoot, descriptor: GPURenderBundleEncoderDescriptor): TgpuRenderBundleEncoder;
export declare function INTERNAL_adoptRenderCommands(root: ExperimentalTgpuRoot, rawPass: GPURenderPassEncoder | GPURenderBundleEncoder): TgpuRenderCommands;