import { LoadOp, StoreOp } from '../enum.js' import { CommandRecorderError } from '../utils/errors.js' import { SwapChain } from './swap-chain.js' export class CommandRecorder { static _defaultClearValue = { r: 0, g: 0, b: 0, a: 1 } _device: GPUDevice _swapChain: SwapChain _encoder: GPUCommandEncoder _passEncoder?: GPURenderPassEncoder get label() { return this._encoder.label } constructor(device: GPUDevice, swapChain: SwapChain, label: string) { this._device = device this._swapChain = swapChain this._encoder = device.createCommandEncoder({ label }) } _defaultColorAttachment(): [GPURenderPassColorAttachment] { const view = this._swapChain.getCurrentTextureView() return [{ view, clearValue: CommandRecorder._defaultClearValue, loadOp: LoadOp.Clear, storeOp: StoreOp.Store }] } beginRenderPass(colorAttachments: GPURenderPassColorAttachment[], depthStencilAttachment: GPURenderPassDepthStencilAttachment): GPURenderPassEncoder { if (this._passEncoder) { throw CommandRecorderError.activeRenderPass() } const attachments = colorAttachments || this._defaultColorAttachment() const descriptor = { label: this.label || 'RenderPass', colorAttachments: attachments, depthStencilAttachment } this._passEncoder = this._encoder.beginRenderPass(descriptor) return this._passEncoder } endRenderPass() { if (!this._passEncoder) { return } this._passEncoder.end() this._passEncoder = undefined } finish() { if (this._passEncoder) { this.endRenderPass() } return this._encoder.finish() } }