Complete TypeScript type definitions for the WebGPU standard enabling type-safe GPU programming.
—
Command recording, encoding, and execution including render passes and compute passes for GPU work submission.
Main interface for recording GPU commands into command buffers.
interface GPUCommandEncoder {
/** Optional debug label */
readonly label: string | undefined;
/**
* Begins a render pass
* @param descriptor - Render pass configuration
* @returns Render pass encoder
*/
beginRenderPass(descriptor: GPURenderPassDescriptor): GPURenderPassEncoder;
/**
* Begins a compute pass
* @param descriptor - Optional compute pass configuration
* @returns Compute pass encoder
*/
beginComputePass(descriptor?: GPUComputePassDescriptor): GPUComputePassEncoder;
/**
* Copies data between buffers
* @param source - Source buffer
* @param sourceOffset - Byte offset in source
* @param destination - Destination buffer
* @param destinationOffset - Byte offset in destination
* @param size - Number of bytes to copy
*/
copyBufferToBuffer(
source: GPUBuffer,
sourceOffset: GPUSize64,
destination: GPUBuffer,
destinationOffset: GPUSize64,
size: GPUSize64
): void;
/**
* Copies buffer data to a texture
* @param source - Source buffer and layout
* @param destination - Destination texture info
* @param copySize - Size of the region to copy
*/
copyBufferToTexture(
source: GPUTexelCopyBufferInfo,
destination: GPUTexelCopyTextureInfo,
copySize: GPUExtent3D
): void;
/**
* Copies texture data to a buffer
* @param source - Source texture info
* @param destination - Destination buffer and layout
* @param copySize - Size of the region to copy
*/
copyTextureToBuffer(
source: GPUTexelCopyTextureInfo,
destination: GPUTexelCopyBufferInfo,
copySize: GPUExtent3D
): void;
/**
* Copies data between textures
* @param source - Source texture info
* @param destination - Destination texture info
* @param copySize - Size of the region to copy
*/
copyTextureToTexture(
source: GPUTexelCopyTextureInfo,
destination: GPUTexelCopyTextureInfo,
copySize: GPUExtent3D
): void;
/**
* Clears a buffer with zeros
* @param buffer - Buffer to clear
* @param offset - Byte offset (optional)
* @param size - Number of bytes to clear (optional)
*/
clearBuffer(buffer: GPUBuffer, offset?: GPUSize64, size?: GPUSize64): void;
/**
* Writes a timestamp to a query set
* @param querySet - Query set for timestamps
* @param queryIndex - Query index to write to
*/
writeTimestamp(querySet: GPUQuerySet, queryIndex: GPUSize32): void;
/**
* Resolves query results to a buffer
* @param querySet - Query set to resolve
* @param firstQuery - First query index
* @param queryCount - Number of queries to resolve
* @param destination - Destination buffer
* @param destinationOffset - Byte offset in destination
*/
resolveQuerySet(
querySet: GPUQuerySet,
firstQuery: GPUSize32,
queryCount: GPUSize32,
destination: GPUBuffer,
destinationOffset: GPUSize64
): void;
/**
* Finishes command recording
* @param descriptor - Optional command buffer configuration
* @returns Completed command buffer
*/
finish(descriptor?: GPUCommandBufferDescriptor): GPUCommandBuffer;
// Debug commands
pushDebugGroup(groupLabel: string): void;
popDebugGroup(): void;
insertDebugMarker(markerLabel: string): void;
}
interface GPUCommandEncoderDescriptor extends GPUObjectDescriptorBase {}
interface GPUCommandBufferDescriptor extends GPUObjectDescriptorBase {}Immutable recorded commands ready for submission to the GPU queue.
interface GPUCommandBuffer {
/** Optional debug label */
readonly label: string | undefined;
}Records rendering commands within a render pass.
interface GPURenderPassEncoder extends GPURenderCommandsMixin {
/**
* Sets the viewport transformation
* @param x - X coordinate of viewport origin
* @param y - Y coordinate of viewport origin
* @param width - Viewport width
* @param height - Viewport height
* @param minDepth - Minimum depth value (0.0-1.0)
* @param maxDepth - Maximum depth value (0.0-1.0)
*/
setViewport(
x: number,
y: number,
width: number,
height: number,
minDepth: number,
maxDepth: number
): void;
/**
* Sets the scissor rectangle
* @param x - X coordinate of scissor origin
* @param y - Y coordinate of scissor origin
* @param width - Scissor width
* @param height - Scissor height
*/
setScissorRect(
x: GPUIntegerCoordinate,
y: GPUIntegerCoordinate,
width: GPUIntegerCoordinate,
height: GPUIntegerCoordinate
): void;
/**
* Begins an occlusion query
* @param queryIndex - Index in the query set
*/
beginOcclusionQuery(queryIndex: GPUSize32): void;
/** Ends the current occlusion query */
endOcclusionQuery(): void;
/** Ends the render pass */
end(): void;
// Inherited from GPURenderCommandsMixin
setPipeline(pipeline: GPURenderPipeline): void;
setIndexBuffer(buffer: GPUBuffer, format: GPUIndexFormat, offset?: GPUSize64, size?: GPUSize64): void;
setVertexBuffer(slot: GPUIndex32, buffer: GPUBuffer | null, offset?: GPUSize64, size?: GPUSize64): void;
draw(vertexCount: GPUSize32, instanceCount?: GPUSize32, firstVertex?: GPUSize32, firstInstance?: GPUSize32): void;
drawIndexed(indexCount: GPUSize32, instanceCount?: GPUSize32, firstIndex?: GPUSize32, baseVertex?: GPUSignedOffset32, firstInstance?: GPUSize32): void;
drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: GPUSize64): void;
drawIndexedIndirect(indirectBuffer: GPUBuffer, indirectOffset: GPUSize64): void;
// Inherited from GPUBindingCommandsMixin
setBindGroup(index: GPUIndex32, bindGroup: GPUBindGroup | null, dynamicOffsets?: Iterable<GPUBufferDynamicOffset>): void;
// Inherited from GPUDebugCommandsMixin
pushDebugGroup(groupLabel: string): void;
popDebugGroup(): void;
insertDebugMarker(markerLabel: string): void;
}Records compute commands within a compute pass.
interface GPUComputePassEncoder {
/** Optional debug label */
readonly label: string | undefined;
/**
* Sets the compute pipeline
* @param pipeline - Compute pipeline to use
*/
setPipeline(pipeline: GPUComputePipeline): void;
/**
* Dispatches compute workgroups
* @param workgroupCountX - Number of workgroups in X dimension
* @param workgroupCountY - Number of workgroups in Y dimension (default: 1)
* @param workgroupCountZ - Number of workgroups in Z dimension (default: 1)
*/
dispatchWorkgroups(
workgroupCountX: GPUSize32,
workgroupCountY?: GPUSize32,
workgroupCountZ?: GPUSize32
): void;
/**
* Dispatches workgroups with counts from buffer
* @param indirectBuffer - Buffer containing dispatch parameters
* @param indirectOffset - Byte offset in buffer
*/
dispatchWorkgroupsIndirect(
indirectBuffer: GPUBuffer,
indirectOffset: GPUSize64
): void;
/** Ends the compute pass */
end(): void;
// Inherited from GPUBindingCommandsMixin
setBindGroup(index: GPUIndex32, bindGroup: GPUBindGroup | null, dynamicOffsets?: Iterable<GPUBufferDynamicOffset>): void;
// Inherited from GPUDebugCommandsMixin
pushDebugGroup(groupLabel: string): void;
popDebugGroup(): void;
insertDebugMarker(markerLabel: string): void;
}Configuration for render passes including attachments and timing.
interface GPURenderPassDescriptor extends GPUObjectDescriptorBase {
/** Color attachments */
colorAttachments: Iterable<GPURenderPassColorAttachment | null>;
/** Depth/stencil attachment */
depthStencilAttachment?: GPURenderPassDepthStencilAttachment;
/** Occlusion query set */
occlusionQuerySet?: GPUQuerySet;
/** Timestamp query writes */
timestampWrites?: GPURenderPassTimestampWrites;
/** Maximum number of draw commands */
maxDrawCount?: GPUSize64;
}
interface GPURenderPassColorAttachment {
/** Color attachment texture view */
view: GPUTextureView;
/** Depth slice for 3D textures */
depthSlice?: GPUIntegerCoordinate;
/** Resolve target for multisampled textures */
resolveTarget?: GPUTextureView;
/** Clear value when loadOp is "clear" */
clearValue?: GPUColor;
/** Load operation */
loadOp: GPULoadOp;
/** Store operation */
storeOp: GPUStoreOp;
}
interface GPURenderPassDepthStencilAttachment {
/** Depth/stencil texture view */
view: GPUTextureView;
/** Depth clear value */
depthClearValue?: number;
/** Depth load operation */
depthLoadOp?: GPULoadOp;
/** Depth store operation */
depthStoreOp?: GPUStoreOp;
/** Whether depth is read-only */
depthReadOnly?: boolean;
/** Stencil clear value */
stencilClearValue?: GPUStencilValue;
/** Stencil load operation */
stencilLoadOp?: GPULoadOp;
/** Stencil store operation */
stencilStoreOp?: GPUStoreOp;
/** Whether stencil is read-only */
stencilReadOnly?: boolean;
}
interface GPURenderPassTimestampWrites {
/** Query set for timestamps */
querySet: GPUQuerySet;
/** Query index for beginning of pass */
beginningOfPassWriteIndex?: GPUSize32;
/** Query index for end of pass */
endOfPassWriteIndex?: GPUSize32;
}Configuration for compute passes.
interface GPUComputePassDescriptor extends GPUObjectDescriptorBase {
/** Timestamp query writes */
timestampWrites?: GPUComputePassTimestampWrites;
}
interface GPUComputePassTimestampWrites {
/** Query set for timestamps */
querySet: GPUQuerySet;
/** Query index for beginning of pass */
beginningOfPassWriteIndex?: GPUSize32;
/** Query index for end of pass */
endOfPassWriteIndex?: GPUSize32;
}Shared command functionality across different encoder types.
interface GPUBindingCommandsMixin {
/**
* Binds a bind group to a pipeline
* @param index - Bind group index
* @param bindGroup - Bind group to bind (null to unbind)
* @param dynamicOffsets - Dynamic buffer offsets
*/
setBindGroup(
index: GPUIndex32,
bindGroup: GPUBindGroup | null,
dynamicOffsets?: Iterable<GPUBufferDynamicOffset>
): void;
}
interface GPUDebugCommandsMixin {
/** Pushes a debug group for annotation */
pushDebugGroup(groupLabel: string): void;
/** Pops the current debug group */
popDebugGroup(): void;
/** Inserts a debug marker */
insertDebugMarker(markerLabel: string): void;
}
interface GPURenderCommandsMixin extends GPUBindingCommandsMixin, GPUDebugCommandsMixin {
/**
* Sets the render pipeline
* @param pipeline - Render pipeline to use
*/
setPipeline(pipeline: GPURenderPipeline): void;
/**
* Sets the index buffer
* @param buffer - Index buffer
* @param format - Index format (uint16 or uint32)
* @param offset - Byte offset in buffer
* @param size - Number of bytes to bind
*/
setIndexBuffer(
buffer: GPUBuffer,
format: GPUIndexFormat,
offset?: GPUSize64,
size?: GPUSize64
): void;
/**
* Sets a vertex buffer
* @param slot - Vertex buffer slot
* @param buffer - Vertex buffer (null to unbind)
* @param offset - Byte offset in buffer
* @param size - Number of bytes to bind
*/
setVertexBuffer(
slot: GPUIndex32,
buffer: GPUBuffer | null,
offset?: GPUSize64,
size?: GPUSize64
): void;
/**
* Draws primitives
* @param vertexCount - Number of vertices to draw
* @param instanceCount - Number of instances (default: 1)
* @param firstVertex - First vertex index (default: 0)
* @param firstInstance - First instance index (default: 0)
*/
draw(
vertexCount: GPUSize32,
instanceCount?: GPUSize32,
firstVertex?: GPUSize32,
firstInstance?: GPUSize32
): void;
/**
* Draws indexed primitives
* @param indexCount - Number of indices to draw
* @param instanceCount - Number of instances (default: 1)
* @param firstIndex - First index (default: 0)
* @param baseVertex - Value added to vertex index (default: 0)
* @param firstInstance - First instance index (default: 0)
*/
drawIndexed(
indexCount: GPUSize32,
instanceCount?: GPUSize32,
firstIndex?: GPUSize32,
baseVertex?: GPUSignedOffset32,
firstInstance?: GPUSize32
): void;
/**
* Draws with parameters from buffer
* @param indirectBuffer - Buffer containing draw parameters
* @param indirectOffset - Byte offset in buffer
*/
drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: GPUSize64): void;
/**
* Draws indexed with parameters from buffer
* @param indirectBuffer - Buffer containing draw parameters
* @param indirectOffset - Byte offset in buffer
*/
drawIndexedIndirect(indirectBuffer: GPUBuffer, indirectOffset: GPUSize64): void;
}Data structures for texture and buffer copy operations.
interface GPUTexelCopyBufferInfo {
/** Buffer to copy from/to */
buffer: GPUBuffer;
/** Byte offset in buffer */
offset?: GPUSize64;
/** Bytes per row of texel data */
bytesPerRow?: GPUSize32;
/** Rows per image */
rowsPerImage?: GPUSize32;
}
interface GPUTexelCopyTextureInfo {
/** Texture to copy from/to */
texture: GPUTexture;
/** Mip level to access */
mipLevel?: GPUIntegerCoordinate;
/** Origin for the copy */
origin?: GPUOrigin3D;
/** Texture aspect to access */
aspect?: GPUTextureAspect;
}
interface GPUCopyExternalImageSourceInfo {
/** External image source */
source: GPUCopyExternalImageSource;
/** Origin in the source */
origin?: GPUOrigin2D;
/** Whether to flip Y coordinate */
flipY?: boolean;
}
interface GPUCopyExternalImageDestInfo {
/** Destination texture */
texture: GPUTexture;
/** Mip level to write to */
mipLevel?: GPUIntegerCoordinate;
/** Origin in destination */
origin?: GPUOrigin3D;
/** Texture aspect to write to */
aspect?: GPUTextureAspect;
/** Color space conversion */
colorSpace?: GPUImageCopyColorSpace;
/** Premultiply alpha */
premultipliedAlpha?: boolean;
}
type GPUImageCopyColorSpace = "srgb" | "display-p3";// Create command encoder
const encoder = device.createCommandEncoder({ label: "Main Render Commands" });
// Begin render pass
const renderPass = encoder.beginRenderPass({
colorAttachments: [{
view: context.getCurrentTexture().createView(),
clearValue: { r: 0.2, g: 0.3, b: 0.8, a: 1.0 },
loadOp: "clear",
storeOp: "store"
}],
depthStencilAttachment: {
view: depthTexture.createView(),
depthClearValue: 1.0,
depthLoadOp: "clear",
depthStoreOp: "store"
},
label: "Main Render Pass"
});
// Set pipeline and resources
renderPass.setPipeline(renderPipeline);
renderPass.setBindGroup(0, uniformBindGroup);
renderPass.setBindGroup(1, materialBindGroup);
renderPass.setVertexBuffer(0, vertexBuffer);
renderPass.setIndexBuffer(indexBuffer, "uint16");
// Draw geometry
renderPass.drawIndexed(indexCount);
// End pass and submit
renderPass.end();
const commandBuffer = encoder.finish();
device.queue.submit([commandBuffer]);// Create compute command encoder
const computeEncoder = device.createCommandEncoder({ label: "Compute Commands" });
// Begin compute pass
const computePass = computeEncoder.beginComputePass({
label: "Data Processing Pass"
});
// Set compute pipeline and bind groups
computePass.setPipeline(computePipeline);
computePass.setBindGroup(0, computeBindGroup);
// Dispatch compute workgroups
const workgroupsX = Math.ceil(dataSize / 64); // 64 = workgroup size
computePass.dispatchWorkgroups(workgroupsX);
// End pass
computePass.end();
// Submit compute work
const computeCommandBuffer = computeEncoder.finish();
device.queue.submit([computeCommandBuffer]);const copyEncoder = device.createCommandEncoder({ label: "Copy Commands" });
// Copy buffer to buffer
copyEncoder.copyBufferToBuffer(
sourceBuffer, 0, // source and offset
destBuffer, 256, // destination and offset
1024 // size in bytes
);
// Copy buffer to texture
copyEncoder.copyBufferToTexture(
{
buffer: imageBuffer,
bytesPerRow: 1024 * 4, // 4 bytes per pixel
rowsPerImage: 768
},
{
texture: colorTexture,
mipLevel: 0
},
{ width: 1024, height: 768, depthOrArrayLayers: 1 }
);
// Copy texture to texture (mip generation)
for (let mip = 1; mip < mipLevels; mip++) {
const mipSize = Math.max(1, textureSize >> mip);
copyEncoder.copyTextureToTexture(
{
texture: sourceTexture,
mipLevel: mip - 1
},
{
texture: sourceTexture,
mipLevel: mip
},
{ width: mipSize, height: mipSize, depthOrArrayLayers: 1 }
);
}
device.queue.submit([copyEncoder.finish()]);const frameEncoder = device.createCommandEncoder({ label: "Frame Commands" });
// Shadow pass
const shadowPass = frameEncoder.beginRenderPass({
colorAttachments: [],
depthStencilAttachment: {
view: shadowMap.createView(),
depthClearValue: 1.0,
depthLoadOp: "clear",
depthStoreOp: "store"
},
label: "Shadow Pass"
});
shadowPass.setPipeline(shadowPipeline);
shadowPass.setBindGroup(0, lightBindGroup);
// ... render shadow casters
shadowPass.end();
// Main render pass
const mainPass = frameEncoder.beginRenderPass({
colorAttachments: [{
view: colorTarget.createView(),
clearValue: { r: 0.1, g: 0.1, b: 0.2, a: 1.0 },
loadOp: "clear",
storeOp: "store"
}],
depthStencilAttachment: {
view: depthBuffer.createView(),
depthClearValue: 1.0,
depthLoadOp: "clear",
depthStoreOp: "store"
},
label: "Main Pass"
});
mainPass.setPipeline(mainPipeline);
mainPass.setBindGroup(0, sceneBindGroup);
mainPass.setBindGroup(1, shadowBindGroup); // Shadow map from previous pass
// ... render scene
mainPass.end();
// Post-processing pass
const postPass = frameEncoder.beginRenderPass({
colorAttachments: [{
view: context.getCurrentTexture().createView(),
loadOp: "load",
storeOp: "store"
}],
label: "Post Process Pass"
});
postPass.setPipeline(postProcessPipeline);
postPass.setBindGroup(0, postProcessBindGroup);
postPass.draw(3); // Fullscreen triangle
postPass.end();
device.queue.submit([frameEncoder.finish()]);// Create timestamp queries
const timestampQuerySet = device.createQuerySet({
type: "timestamp",
count: 4
});
const queryBuffer = device.createBuffer({
size: 8 * 4, // 8 bytes per timestamp
usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
});
const readBuffer = device.createBuffer({
size: 8 * 4,
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
});
// Record with timing
const timedEncoder = device.createCommandEncoder();
timedEncoder.writeTimestamp(timestampQuerySet, 0); // Frame start
const renderPass = timedEncoder.beginRenderPass({
colorAttachments: [/* ... */],
timestampWrites: {
querySet: timestampQuerySet,
beginningOfPassWriteIndex: 1,
endOfPassWriteIndex: 2
}
});
// ... rendering commands ...
renderPass.end();
timedEncoder.writeTimestamp(timestampQuerySet, 3); // Frame end
// Resolve timestamps
timedEncoder.resolveQuerySet(timestampQuerySet, 0, 4, queryBuffer, 0);
timedEncoder.copyBufferToBuffer(queryBuffer, 0, readBuffer, 0, 8 * 4);
device.queue.submit([timedEncoder.finish()]);
// Read timing results
await readBuffer.mapAsync(GPUMapMode.READ);
const times = new BigUint64Array(readBuffer.getMappedRange());
const frameTime = Number(times[3] - times[0]) / 1000000; // Convert to milliseconds
console.log(`Frame time: ${frameTime.toFixed(2)}ms`);
readBuffer.unmap();const debugEncoder = device.createCommandEncoder({ label: "Debug Annotated Commands" });
debugEncoder.pushDebugGroup("Scene Rendering");
const renderPass = debugEncoder.beginRenderPass({
colorAttachments: [/* ... */],
label: "Scene Pass"
});
renderPass.pushDebugGroup("Opaque Objects");
renderPass.setPipeline(opaquePipeline);
// ... render opaque objects
renderPass.popDebugGroup();
renderPass.insertDebugMarker("Begin Transparent Objects");
renderPass.setPipeline(transparentPipeline);
// ... render transparent objects
renderPass.end();
debugEncoder.popDebugGroup();
debugEncoder.pushDebugGroup("Post Processing");
// ... post processing passes
debugEncoder.popDebugGroup();
device.queue.submit([debugEncoder.finish()]);Install with Tessl CLI
npx tessl i tessl/npm-webgpu--types