( canvas: OffscreenCanvas, powerPreference: GPUPowerPreference = "high-performance", )
| 143 | } |
| 144 | |
| 145 | export async function initWebGPU( |
| 146 | canvas: OffscreenCanvas, |
| 147 | powerPreference: GPUPowerPreference = "high-performance", |
| 148 | ): Promise<WebGPURenderer> { |
| 149 | const adapter = await requestWebGPUAdapter(powerPreference); |
| 150 | if (!adapter) { |
| 151 | throw new Error("No WebGPU adapter available"); |
| 152 | } |
| 153 | |
| 154 | const device = await adapter.requestDevice(); |
| 155 | |
| 156 | device.lost.then((info) => { |
| 157 | if (info.reason !== "destroyed") { |
| 158 | self.postMessage({ |
| 159 | type: "error", |
| 160 | message: `WebGPU device lost: ${info.reason} - ${info.message}`, |
| 161 | }); |
| 162 | } |
| 163 | }); |
| 164 | |
| 165 | const context = canvas.getContext("webgpu"); |
| 166 | if (!context) { |
| 167 | throw new Error("Failed to get WebGPU context from OffscreenCanvas"); |
| 168 | } |
| 169 | |
| 170 | const format = navigator.gpu.getPreferredCanvasFormat(); |
| 171 | context.configure({ |
| 172 | device, |
| 173 | format, |
| 174 | alphaMode: "opaque", |
| 175 | }); |
| 176 | |
| 177 | const bindGroupLayout = device.createBindGroupLayout({ |
| 178 | entries: [ |
| 179 | { |
| 180 | binding: 0, |
| 181 | visibility: GPUShaderStage.FRAGMENT, |
| 182 | sampler: { type: "filtering" }, |
| 183 | }, |
| 184 | { |
| 185 | binding: 1, |
| 186 | visibility: GPUShaderStage.FRAGMENT, |
| 187 | texture: { sampleType: "float" }, |
| 188 | }, |
| 189 | ], |
| 190 | }); |
| 191 | |
| 192 | const nv12BindGroupLayout = device.createBindGroupLayout({ |
| 193 | entries: [ |
| 194 | { |
| 195 | binding: 0, |
| 196 | visibility: GPUShaderStage.FRAGMENT, |
| 197 | sampler: { type: "filtering" }, |
| 198 | }, |
| 199 | { |
| 200 | binding: 1, |
| 201 | visibility: GPUShaderStage.FRAGMENT, |
| 202 | texture: { sampleType: "float" }, |
no test coverage detected