webgpu-profiler 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,105 @@
1
+ import { resolveExtent, textureDescriptorBytes, } from "./instrument.js";
2
+ // ── Helpers ─────────────────────────────────────────────────────────────────
3
+ // Spec-defined WebGPU usage flag values, hardcoded so this module can be
4
+ // imported in Node / SSR environments where `GPUBufferUsage` /
5
+ // `GPUTextureUsage` global objects are not defined.
6
+ // https://www.w3.org/TR/webgpu/#typedefdef-gpubufferusageflags
7
+ const BUFFER_USAGE_NAMES = [
8
+ [0x0001, "MAP_READ"],
9
+ [0x0002, "MAP_WRITE"],
10
+ [0x0004, "COPY_SRC"],
11
+ [0x0008, "COPY_DST"],
12
+ [0x0010, "INDEX"],
13
+ [0x0020, "VERTEX"],
14
+ [0x0040, "UNIFORM"],
15
+ [0x0080, "STORAGE"],
16
+ [0x0100, "INDIRECT"],
17
+ [0x0200, "QUERY_RESOLVE"],
18
+ ];
19
+ const TEXTURE_USAGE_RENDER_ATTACHMENT = 0x10;
20
+ function decodeBufferUsage(flags) {
21
+ const names = [];
22
+ for (const [flag, name] of BUFFER_USAGE_NAMES) {
23
+ if (flags & flag)
24
+ names.push(name);
25
+ }
26
+ return names.join("|") || "0";
27
+ }
28
+ function isRenderAttachment(usage) {
29
+ return Boolean(usage & TEXTURE_USAGE_RENDER_ATTACHMENT);
30
+ }
31
+ // ── Public API ──────────────────────────────────────────────────────────────
32
+ export function profileMemory(instrumentation) {
33
+ const sampledTextures = [];
34
+ const renderTargets = [];
35
+ for (const { descriptor } of instrumentation.textures.values()) {
36
+ const dims = resolveExtent(descriptor.size);
37
+ const bytes = textureDescriptorBytes(descriptor);
38
+ const usage = descriptor.usage ?? 0;
39
+ const entry = {
40
+ name: descriptor.label || "(unnamed)",
41
+ width: dims.width,
42
+ height: dims.height,
43
+ depth: dims.depth,
44
+ format: descriptor.format,
45
+ mipLevels: descriptor.mipLevelCount ?? 1,
46
+ sampleCount: descriptor.sampleCount ?? 1,
47
+ isRenderTarget: isRenderAttachment(usage),
48
+ bytes,
49
+ };
50
+ if (entry.isRenderTarget)
51
+ renderTargets.push(entry);
52
+ else
53
+ sampledTextures.push(entry);
54
+ }
55
+ sampledTextures.sort((a, b) => b.bytes - a.bytes);
56
+ renderTargets.sort((a, b) => b.bytes - a.bytes);
57
+ const buffers = [];
58
+ for (const { descriptor } of instrumentation.buffers.values()) {
59
+ buffers.push({
60
+ name: descriptor.label || "(unnamed)",
61
+ bytes: descriptor.size,
62
+ usage: decodeBufferUsage(descriptor.usage),
63
+ });
64
+ }
65
+ buffers.sort((a, b) => b.bytes - a.bytes);
66
+ const totalSampled = sampledTextures.reduce((s, t) => s + t.bytes, 0);
67
+ const totalRT = renderTargets.reduce((s, t) => s + t.bytes, 0);
68
+ const totalBuf = buffers.reduce((s, b) => s + b.bytes, 0);
69
+ return {
70
+ sampledTextures,
71
+ renderTargets,
72
+ buffers,
73
+ totals: {
74
+ sampledTextures: totalSampled,
75
+ renderTargets: totalRT,
76
+ buffers: totalBuf,
77
+ all: totalSampled + totalRT + totalBuf,
78
+ },
79
+ };
80
+ }
81
+ /** Build a multi-line plain-text report. Feed to a copy button or bug report. */
82
+ export function reportToText(report) {
83
+ const mb = (b) => `${(b / 1024 / 1024).toFixed(2)} MB`;
84
+ const lines = [];
85
+ lines.push(`VRAM snapshot (live, from device.createBuffer/createTexture)`);
86
+ lines.push(``);
87
+ lines.push(`Sampled textures: ${mb(report.totals.sampledTextures)}`);
88
+ for (const t of report.sampledTextures) {
89
+ lines.push(` ${t.name.padEnd(32)} ${t.width}x${t.height}${t.depth > 1 ? `x${t.depth}` : ""} ${t.format} mips=${t.mipLevels} ${mb(t.bytes)}`);
90
+ }
91
+ lines.push(``);
92
+ lines.push(`Render targets: ${mb(report.totals.renderTargets)}`);
93
+ for (const t of report.renderTargets) {
94
+ lines.push(` ${t.name.padEnd(32)} ${t.width}x${t.height} ${t.format} ${mb(t.bytes)}`);
95
+ }
96
+ lines.push(``);
97
+ lines.push(`Buffers: ${mb(report.totals.buffers)}`);
98
+ for (const b of report.buffers) {
99
+ lines.push(` ${b.name.padEnd(32)} ${b.usage} ${mb(b.bytes)}`);
100
+ }
101
+ lines.push(``);
102
+ lines.push(`Total: ${mb(report.totals.all)}`);
103
+ return lines.join("\n");
104
+ }
105
+ //# sourceMappingURL=profiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiler.js","sourceRoot":"","sources":["../src/profiler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,sBAAsB,GAEvB,MAAM,iBAAiB,CAAC;AAiDzB,+EAA+E;AAE/E,yEAAyE;AACzE,+DAA+D;AAC/D,oDAAoD;AACpD,+DAA+D;AAC/D,MAAM,kBAAkB,GAAoC;IAC1D,CAAC,MAAM,EAAE,UAAU,CAAC;IACpB,CAAC,MAAM,EAAE,WAAW,CAAC;IACrB,CAAC,MAAM,EAAE,UAAU,CAAC;IACpB,CAAC,MAAM,EAAE,UAAU,CAAC;IACpB,CAAC,MAAM,EAAE,OAAO,CAAC;IACjB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAClB,CAAC,MAAM,EAAE,SAAS,CAAC;IACnB,CAAC,MAAM,EAAE,SAAS,CAAC;IACnB,CAAC,MAAM,EAAE,UAAU,CAAC;IACpB,CAAC,MAAM,EAAE,eAAe,CAAC;CAC1B,CAAC;AAEF,MAAM,+BAA+B,GAAG,IAAI,CAAC;AAE7C,SAAS,iBAAiB,CAAC,KAAa;IACtC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,kBAAkB,EAAE,CAAC;QAC9C,IAAI,KAAK,GAAG,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;AAChC,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa;IACvC,OAAO,OAAO,CAAC,KAAK,GAAG,+BAA+B,CAAC,CAAC;AAC1D,CAAC;AAGD,+EAA+E;AAE/E,MAAM,UAAU,aAAa,CAC3B,eAAsC;IAEtC,MAAM,eAAe,GAAmB,EAAE,CAAC;IAC3C,MAAM,aAAa,GAAmB,EAAE,CAAC;IAEzC,KAAK,MAAM,EAAE,UAAU,EAAE,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QAC/D,MAAM,IAAI,GAAG,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,IAAI,CAAC,CAAC;QACpC,MAAM,KAAK,GAAiB;YAC1B,IAAI,EAAE,UAAU,CAAC,KAAK,IAAI,WAAW;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,SAAS,EAAE,UAAU,CAAC,aAAa,IAAI,CAAC;YACxC,WAAW,EAAE,UAAU,CAAC,WAAW,IAAI,CAAC;YACxC,cAAc,EAAE,kBAAkB,CAAC,KAAK,CAAC;YACzC,KAAK;SACN,CAAC;QACF,IAAI,KAAK,CAAC,cAAc;YAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;;YAC/C,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IACD,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAClD,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAEhD,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,KAAK,MAAM,EAAE,UAAU,EAAE,IAAI,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,UAAU,CAAC,KAAK,IAAI,WAAW;YACrC,KAAK,EAAE,UAAU,CAAC,IAAI;YACtB,KAAK,EAAE,iBAAiB,CAAC,UAAU,CAAC,KAAK,CAAC;SAC3C,CAAC,CAAC;IACL,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAE1C,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAE1D,OAAO;QACL,eAAe;QACf,aAAa;QACb,OAAO;QACP,MAAM,EAAE;YACN,eAAe,EAAE,YAAY;YAC7B,aAAa,EAAE,OAAO;YACtB,OAAO,EAAE,QAAQ;YACjB,GAAG,EAAE,YAAY,GAAG,OAAO,GAAG,QAAQ;SACvC;KACF,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,MAAM,EAAE,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAC/D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;IAC3E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IACrE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CACpI,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACjE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACrC,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAC5E,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { type CSSProperties } from "react";
2
+ import { type DeviceInstrumentation } from "../instrument.js";
3
+ /**
4
+ * Viewport-pinned overlay that polls {@link profileMemory} on a timer and
5
+ * renders a copyable breakdown of all GPU memory the page has allocated
6
+ * through `device.createBuffer` / `device.createTexture`.
7
+ *
8
+ * Self-contained (no external CSS, no design-token dependency). Default
9
+ * styling is a dark transparent panel. Re-skin via `style` / `className`.
10
+ *
11
+ * Each section (Textures / Render targets / Buffers) is independently
12
+ * scrollable, so the HUD never overflows the viewport.
13
+ */
14
+ export interface MemoryHUDProps {
15
+ /**
16
+ * Optional. When omitted, the HUD reads the active instrumentation set
17
+ * by `instrumentDevice()` or `autoInstrument()` via subscription. Pass
18
+ * explicitly if you're managing multiple devices.
19
+ */
20
+ instrumentation?: DeviceInstrumentation | null;
21
+ refreshMs?: number;
22
+ corner?: "top-right" | "top-left" | "bottom-right" | "bottom-left";
23
+ className?: string;
24
+ style?: CSSProperties;
25
+ }
26
+ export declare function MemoryHUD({ instrumentation: explicit, refreshMs, corner, className, style, }?: MemoryHUDProps): import("react/jsx-runtime").JSX.Element | null;
27
+ //# sourceMappingURL=MemoryHUD.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemoryHUD.d.ts","sourceRoot":"","sources":["../../src/react/MemoryHUD.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,aAAa,EAEnB,MAAM,OAAO,CAAC;AAQf,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,eAAe,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,cAAc,GAAG,aAAa,CAAC;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAsED,wBAAgB,SAAS,CAAC,EACxB,eAAe,EAAE,QAAQ,EACzB,SAA8B,EAC9B,MAAoB,EACpB,SAAS,EACT,KAAK,GACN,GAAE,cAAmB,kDA6KrB"}
@@ -0,0 +1,232 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState, useSyncExternalStore, } from "react";
3
+ import { profileMemory, reportToText, } from "../profiler.js";
4
+ import { getActiveInstrumentation, subscribeActiveInstrumentation, } from "../instrument.js";
5
+ /**
6
+ * React hook that subscribes to the active instrumentation. Re-renders
7
+ * the calling component when `instrumentDevice` or `autoInstrument` sets
8
+ * (or clears) the global handle.
9
+ */
10
+ function useActiveInstrumentation() {
11
+ return useSyncExternalStore(subscribeActiveInstrumentation, getActiveInstrumentation, () => null);
12
+ }
13
+ const DEFAULT_REFRESH_MS = 1000;
14
+ const SECTION_MAX_HEIGHT = 240;
15
+ const MIN_WIDTH = 360;
16
+ const NAME_MAX_CHARS = 26;
17
+ const CORNERS = {
18
+ "top-right": { top: 8, right: 8 },
19
+ "top-left": { top: 8, left: 8 },
20
+ "bottom-right": { bottom: 8, right: 8 },
21
+ "bottom-left": { bottom: 8, left: 8 },
22
+ };
23
+ function mb(bytes) {
24
+ return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
25
+ }
26
+ /** Pre-truncate names that would otherwise blow the layout; the CSS
27
+ * ellipsis is a safety net for edges this helper misses. */
28
+ function shortName(name, maxLen = NAME_MAX_CHARS) {
29
+ if (name.length <= maxLen)
30
+ return name;
31
+ return name.slice(0, maxLen - 1) + "…";
32
+ }
33
+ // Default theme. Override via `style` prop or className.
34
+ const C = {
35
+ bg: "rgba(8, 12, 16, 0.92)",
36
+ border: "rgba(255, 255, 255, 0.1)",
37
+ hover: "rgba(255, 255, 255, 0.06)",
38
+ textPrimary: "rgba(255, 255, 255, 0.9)",
39
+ textSecondary: "rgba(255, 255, 255, 0.65)",
40
+ textMuted: "rgba(255, 255, 255, 0.4)",
41
+ };
42
+ const monoFont = 'ui-monospace, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace';
43
+ // One-time global style injection for focus-visible. The HUD otherwise
44
+ // uses inline styles only, so consumers can override via `style` / `className`
45
+ // without specificity wars. SSR-safe via the `document` guard.
46
+ const FOCUS_STYLE_ID = "webgpu-profiler-focus";
47
+ function ensureFocusStyle() {
48
+ if (typeof document === "undefined")
49
+ return;
50
+ if (document.getElementById(FOCUS_STYLE_ID))
51
+ return;
52
+ const el = document.createElement("style");
53
+ el.id = FOCUS_STYLE_ID;
54
+ el.textContent = `
55
+ [data-webgpu-profiler-btn]:focus-visible {
56
+ outline: 2px solid rgba(255, 255, 255, 0.5);
57
+ outline-offset: -2px;
58
+ border-radius: 4px;
59
+ }
60
+ `;
61
+ document.head.appendChild(el);
62
+ }
63
+ export function MemoryHUD({ instrumentation: explicit, refreshMs = DEFAULT_REFRESH_MS, corner = "top-right", className, style, } = {}) {
64
+ const active = useActiveInstrumentation();
65
+ const instrumentation = explicit !== undefined ? explicit : active;
66
+ const [report, setReport] = useState(null);
67
+ const [open, setOpen] = useState(true);
68
+ const [copied, setCopied] = useState(false);
69
+ const [headerHover, setHeaderHover] = useState(false);
70
+ const [copyHover, setCopyHover] = useState(false);
71
+ const timerRef = useRef(null);
72
+ useEffect(() => {
73
+ ensureFocusStyle();
74
+ }, []);
75
+ useEffect(() => {
76
+ if (!instrumentation)
77
+ return;
78
+ const tick = () => {
79
+ try {
80
+ setReport(profileMemory(instrumentation));
81
+ }
82
+ catch {
83
+ // Device may not yet be ready; ignore until next tick.
84
+ }
85
+ };
86
+ tick();
87
+ timerRef.current = window.setInterval(tick, refreshMs);
88
+ return () => {
89
+ if (timerRef.current !== null)
90
+ window.clearInterval(timerRef.current);
91
+ };
92
+ }, [instrumentation, refreshMs]);
93
+ if (!report)
94
+ return null;
95
+ const [copyFailed, setCopyFailed] = useState(false);
96
+ const handleCopy = async () => {
97
+ try {
98
+ await navigator.clipboard.writeText(reportToText(report));
99
+ setCopied(true);
100
+ window.setTimeout(() => setCopied(false), 1200);
101
+ }
102
+ catch (err) {
103
+ // Insecure context, sandboxed iframe, permission denied, etc.
104
+ // Surface the failure so the user knows to fall back to manual select.
105
+ console.warn("[webgpu-profiler] clipboard write failed:", err);
106
+ setCopyFailed(true);
107
+ window.setTimeout(() => setCopyFailed(false), 1500);
108
+ }
109
+ };
110
+ const containerStyle = {
111
+ position: "fixed",
112
+ zIndex: 9999,
113
+ pointerEvents: "auto",
114
+ minWidth: open ? MIN_WIDTH : undefined,
115
+ maxHeight: "calc(100vh - 16px)",
116
+ display: "flex",
117
+ flexDirection: "column",
118
+ background: C.bg,
119
+ border: `1px solid ${C.border}`,
120
+ borderRadius: 6,
121
+ fontFamily: monoFont,
122
+ fontSize: 11,
123
+ color: C.textSecondary,
124
+ backdropFilter: "blur(8px)",
125
+ WebkitBackdropFilter: "blur(8px)",
126
+ ...CORNERS[corner],
127
+ ...style,
128
+ };
129
+ return (_jsxs("div", { className: className, style: containerStyle, children: [_jsxs("button", { type: "button", "data-webgpu-profiler-btn": "", onClick: () => setOpen((v) => !v), onMouseEnter: () => setHeaderHover(true), onMouseLeave: () => setHeaderHover(false), style: {
130
+ all: "unset",
131
+ cursor: "pointer",
132
+ display: "flex",
133
+ alignItems: "center",
134
+ justifyContent: "space-between",
135
+ gap: 12,
136
+ padding: "6px 10px",
137
+ color: C.textPrimary,
138
+ borderBottom: open ? `1px solid ${C.border}` : undefined,
139
+ background: headerHover ? C.hover : "transparent",
140
+ flexShrink: 0,
141
+ transition: "background 100ms ease",
142
+ }, children: [_jsx("span", { children: "VRAM" }), _jsx("span", { style: { fontVariantNumeric: "tabular-nums" }, children: mb(report.totals.all) }), _jsx("span", { style: { color: C.textMuted }, children: open ? "▾" : "▸" })] }), open && (_jsxs("div", { style: {
143
+ padding: "8px 10px 0",
144
+ display: "flex",
145
+ flexDirection: "column",
146
+ gap: 6,
147
+ minHeight: 0,
148
+ flex: "1 1 auto",
149
+ }, children: [report.sampledTextures.length > 0 && (_jsx(Section, { label: "Sampled textures", total: report.totals.sampledTextures, children: report.sampledTextures.map((t, i) => (_jsx(TextureRow, { entry: t }, i))) })), report.renderTargets.length > 0 && (_jsx(Section, { label: "Render targets", total: report.totals.renderTargets, topBorder: true, children: report.renderTargets.map((t, i) => (_jsx(TextureRow, { entry: t }, i))) })), report.buffers.length > 0 && (_jsx(Section, { label: "Buffers", total: report.totals.buffers, topBorder: true, children: report.buffers.map((b, i) => (_jsx(BufferRow, { entry: b }, i))) }))] })), open && (_jsx("div", { style: {
150
+ display: "flex",
151
+ justifyContent: "flex-end",
152
+ borderTop: `1px solid ${C.border}`,
153
+ padding: "6px 10px",
154
+ flexShrink: 0,
155
+ }, children: _jsx("button", { type: "button", "data-webgpu-profiler-btn": "", onClick: handleCopy, onMouseEnter: () => setCopyHover(true), onMouseLeave: () => setCopyHover(false), title: "Copy report to clipboard", style: {
156
+ all: "unset",
157
+ cursor: "pointer",
158
+ fontSize: 10,
159
+ color: copyHover ? C.textPrimary : C.textMuted,
160
+ transition: "color 100ms ease",
161
+ }, children: copyFailed ? "copy failed" : copied ? "copied" : "copy report" }) }))] }));
162
+ }
163
+ // ── Rows ────────────────────────────────────────────────────────────────────
164
+ //
165
+ // Table rows with `width: 100%` and `table-layout: auto`. Names are
166
+ // pre-truncated to NAME_MAX_CHARS in JS so column widths stay reasonable;
167
+ // CSS overflow/ellipsis is the safety net.
168
+ function TextureRow({ entry }) {
169
+ return (_jsxs("tr", { style: { lineHeight: 1.4 }, children: [_jsx("td", { style: {
170
+ paddingRight: 8,
171
+ color: C.textPrimary,
172
+ overflow: "hidden",
173
+ textOverflow: "ellipsis",
174
+ whiteSpace: "nowrap",
175
+ }, title: entry.name, children: shortName(entry.name) }), _jsxs("td", { style: { paddingRight: 8, color: C.textMuted, whiteSpace: "nowrap" }, children: [entry.width, "x", entry.height, entry.depth > 1 ? `x${entry.depth}` : ""] }), _jsx("td", { style: { paddingRight: 8, color: C.textMuted, whiteSpace: "nowrap" }, children: entry.format }), _jsx("td", { style: {
176
+ textAlign: "right",
177
+ fontVariantNumeric: "tabular-nums",
178
+ color: C.textSecondary,
179
+ whiteSpace: "nowrap",
180
+ }, children: mb(entry.bytes) })] }));
181
+ }
182
+ function BufferRow({ entry }) {
183
+ return (_jsxs("tr", { style: { lineHeight: 1.4 }, children: [_jsx("td", { style: {
184
+ paddingRight: 8,
185
+ color: C.textPrimary,
186
+ overflow: "hidden",
187
+ textOverflow: "ellipsis",
188
+ whiteSpace: "nowrap",
189
+ }, title: entry.name, children: shortName(entry.name) }), _jsx("td", { style: {
190
+ paddingRight: 8,
191
+ color: C.textMuted,
192
+ fontSize: 10,
193
+ whiteSpace: "nowrap",
194
+ }, title: entry.usage, children: shortName(entry.usage, 18) }), _jsx("td", { style: {
195
+ textAlign: "right",
196
+ fontVariantNumeric: "tabular-nums",
197
+ color: C.textSecondary,
198
+ whiteSpace: "nowrap",
199
+ }, children: mb(entry.bytes) })] }));
200
+ }
201
+ function Section({ label, total, topBorder, children, }) {
202
+ return (_jsxs("div", { style: {
203
+ display: "flex",
204
+ flexDirection: "column",
205
+ minHeight: 0,
206
+ flex: "0 1 auto",
207
+ marginTop: topBorder ? 6 : 0,
208
+ paddingTop: topBorder ? 6 : 0,
209
+ borderTop: topBorder ? `1px solid ${C.border}` : undefined,
210
+ }, children: [_jsxs("div", { style: {
211
+ display: "flex",
212
+ justifyContent: "space-between",
213
+ color: C.textMuted,
214
+ marginBottom: 4,
215
+ flexShrink: 0,
216
+ }, children: [_jsx("span", { children: label }), _jsx("span", { style: { fontVariantNumeric: "tabular-nums" }, children: mb(total) })] }), _jsx("div", { style: {
217
+ overflowY: "auto",
218
+ overflowX: "hidden",
219
+ maxHeight: SECTION_MAX_HEIGHT,
220
+ minHeight: 0,
221
+ // `thin` shrinks the scrollbar; `stable` reserves space for it
222
+ // even when it's not visible, so the rightmost column never gets
223
+ // overlapped by an overlay scrollbar (macOS, mobile).
224
+ scrollbarWidth: "thin",
225
+ scrollbarGutter: "stable",
226
+ }, children: _jsx("table", { style: {
227
+ width: "100%",
228
+ tableLayout: "auto",
229
+ borderCollapse: "collapse",
230
+ }, children: _jsx("tbody", { children: children }) }) })] }));
231
+ }
232
+ //# sourceMappingURL=MemoryHUD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemoryHUD.js","sourceRoot":"","sources":["../../src/react/MemoryHUD.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { MemoryHUD, type MemoryHUDProps } from "./MemoryHUD.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { MemoryHUD } from "./MemoryHUD.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuB,MAAM,gBAAgB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "webgpu-profiler",
3
+ "version": "0.1.0",
4
+ "description": "Live GPU memory profiler for WebGPU. Patches GPUDevice once and gives you exact byte-level snapshots of every buffer and texture, plus an optional React HUD overlay.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ },
14
+ "./react": {
15
+ "types": "./dist/react/index.d.ts",
16
+ "import": "./dist/react/index.js"
17
+ },
18
+ "./package.json": "./package.json"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "src",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "clean": "rm -rf dist",
29
+ "pack:local": "yarn build && yarn pack -o package.tgz",
30
+ "release": "npm publish",
31
+ "prepublishOnly": "npm run clean && npm run build"
32
+ },
33
+ "keywords": [
34
+ "webgpu",
35
+ "gpu",
36
+ "memory",
37
+ "profiler",
38
+ "vram",
39
+ "performance",
40
+ "three.js",
41
+ "babylon.js",
42
+ "instrumentation"
43
+ ],
44
+ "author": "Redmond Riddell",
45
+ "license": "MIT",
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/soaringred/webgpu-profiler.git"
49
+ },
50
+ "homepage": "https://github.com/soaringred/webgpu-profiler#readme",
51
+ "bugs": {
52
+ "url": "https://github.com/soaringred/webgpu-profiler/issues"
53
+ },
54
+ "engines": {
55
+ "node": ">=18"
56
+ },
57
+ "peerDependencies": {
58
+ "react": ">=18"
59
+ },
60
+ "peerDependenciesMeta": {
61
+ "react": {
62
+ "optional": true
63
+ }
64
+ },
65
+ "devDependencies": {
66
+ "@types/react": "^19.0.0",
67
+ "@webgpu/types": "^0.1.40",
68
+ "react": "^19.0.0",
69
+ "typescript": "^5.3.0"
70
+ },
71
+ "sideEffects": false,
72
+ "packageManager": "yarn@4.12.0+sha512.f45ab632439a67f8bc759bf32ead036a1f413287b9042726b7cc4818b7b49e14e9423ba49b18f9e06ea4941c1ad062385b1d8760a8d5091a1a31e5f6219afca8"
73
+ }
package/src/index.ts ADDED
@@ -0,0 +1,20 @@
1
+ export {
2
+ instrumentDevice,
3
+ autoInstrument,
4
+ getActiveInstrumentation,
5
+ subscribeActiveInstrumentation,
6
+ textureDescriptorBytes,
7
+ resolveExtent,
8
+ type DeviceInstrumentation,
9
+ type TrackedBuffer,
10
+ type TrackedTexture,
11
+ type AutoInstrumentOptions,
12
+ } from "./instrument.js";
13
+
14
+ export {
15
+ profileMemory,
16
+ reportToText,
17
+ type MemoryReport,
18
+ type TextureEntry,
19
+ type BufferEntry,
20
+ } from "./profiler.js";