| 97 | }; |
| 98 | |
| 99 | export class WebGPUBackend extends KernelBackend { |
| 100 | bufferManager: BufferManager; |
| 101 | adapterInfo: AdapterInfo; |
| 102 | device: GPUDevice; |
| 103 | queue: GPUQueue; |
| 104 | tensorMap: DataStorage<TensorData>; |
| 105 | textureManager: TextureManager; |
| 106 | thresholdToIncreaseWorkgroups: number; |
| 107 | |
| 108 | private activeTimers: TimerNode[]; |
| 109 | private commandEncoder: GPUCommandEncoder; |
| 110 | private computePassEncoder: GPUComputePassEncoder; |
| 111 | private commandQueueOwnedIds = new WeakSet<DataId>(); |
| 112 | private dispatchCountInPass = 0; |
| 113 | private disposed = false; |
| 114 | private downloadWaitMs = 0; |
| 115 | private dummyCanvas: HTMLCanvasElement; |
| 116 | private dummyContext: GPUCanvasContext; |
| 117 | private tensorDataPendingDisposal: DataId[] = []; |
| 118 | private static nextDataId = 0; |
| 119 | private pipelineCache: |
| 120 | {[key: string]: GPUComputePipeline|Promise<GPUComputePipeline>}; |
| 121 | private programTimersStack: TimerNode[]; |
| 122 | private queryResolveBuffer: GPUBuffer = null; |
| 123 | private querySet: GPUQuerySet = null; |
| 124 | private querySetCount = 2; |
| 125 | private stagingPendingDisposal: GPUBuffer[] = []; |
| 126 | private supportTimestampQuery: boolean; |
| 127 | private uniformPendingDisposal: GPUBuffer[] = []; |
| 128 | private uploadWaitMs = 0; |
| 129 | private hasReadSyncWarned = false; |
| 130 | private hasTimestampQueryWarned = false; |
| 131 | |
| 132 | private nextDataId(): number { |
| 133 | return WebGPUBackend.nextDataId++; |
| 134 | } |
| 135 | |
| 136 | constructor(device: GPUDevice, adapterInfo?: GPUAdapterInfo) { |
| 137 | super(); |
| 138 | if (!webgpu_util.isWebGPUSupported()) { |
| 139 | throw new Error('WebGPU is not supported on this device'); |
| 140 | } |
| 141 | this.pipelineCache = {}; |
| 142 | this.device = device; |
| 143 | this.queue = device.queue; |
| 144 | this.commandEncoder = null; |
| 145 | this.computePassEncoder = null; |
| 146 | this.adapterInfo = new AdapterInfo(adapterInfo); |
| 147 | this.supportTimestampQuery = this.device.features.has('timestamp-query'); |
| 148 | this.thresholdToIncreaseWorkgroups = |
| 149 | this.adapterInfo.intelGPUGeneration >= 12 ? 16 : 8; |
| 150 | |
| 151 | this.bufferManager = new BufferManager(this.device); |
| 152 | this.textureManager = new TextureManager(this.device); |
| 153 | this.tensorMap = new DataStorage(this, engine()); |
| 154 | |
| 155 | // Profiling tools like PIX needs this dummy canvas to |
| 156 | // trigger capturing a frame. |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…