wgpu/src/core/command-recorder.ts
2025-04-21 23:36:59 -05:00

71 lines
1.6 KiB
TypeScript

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()
}
}