/ proof-of-concept / plate-dynamics-lab
Sign in
proof-of-concept / plate-dynamics-lab
plate-dynamics-lab / packages / components / src / hooks / useWebGpu.ts
39 lines · 1.3 KBBlameHistoryRaw
1import { useEffect, useState } from "react";
2import { describeAdapter } from "@plate-dyn/core";
4export type WebGpuSupport =
5 | { status: "checking" }
6 | { status: "available"; adapter: string }
7 | { status: "unavailable"; reason: string };
9/**
10 * Whether this browser exposes WebGPU, and on what. Asked once on the main
11 * thread so the controls can say what a GPU run would use; the worker makes
12 * its own device request when a run asks for it.
13 */
14export function useWebGpuSupport(): WebGpuSupport {
15 const [support, setSupport] = useState<WebGpuSupport>({ status: "checking" });
16 useEffect(() => {
17 let alive = true;
18 const set = (s: WebGpuSupport) => {
19 if (alive) setSupport(s);
20 };
21 (async () => {
22 try {
23 const gpu = (navigator as { gpu?: GPU }).gpu;
24 if (!gpu)
25 return set({ status: "unavailable", reason: "this browser does not expose WebGPU" });
26 const adapter = await gpu.requestAdapter();
27 if (!adapter)
28 return set({ status: "unavailable", reason: "no WebGPU adapter was offered" });
29 set({ status: "available", adapter: describeAdapter(adapter) });
30 } catch (e) {
31 set({ status: "unavailable", reason: e instanceof Error ? e.message : String(e) });
32 }
33 })();
34 return () => {
35 alive = false;
36 };
37 }, []);
38 return support;
↑↓ move↵openescclose