typegpu
Version:
A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.
87 lines (86 loc) • 3.06 kB
JavaScript
const version = "0.12.2";
import { DEV, TEST } from "./env.js";
import { $getNameForward, $soul, isMarkedInternal } from "./symbols.js";
import { normalizeMetadata } from "./normalizeMetadata.js";
const globalExt = globalThis;
if (globalExt.__TYPEGPU_VERSION__ !== undefined) {
console.warn(`Found duplicate TypeGPU version. First was ${globalExt.__TYPEGPU_VERSION__}, this one is ${version}. This may cause unexpected behavior.`);
}
globalExt.__TYPEGPU_VERSION__ = version;
globalExt.__TYPEGPU_AUTONAME__ = (exp, label) => isNamable(exp) && isMarkedInternal(exp) && !getName(exp) ? exp.$name(label) : exp;
// --- NAMING ---
const nameMap = new WeakMap();
export function isNamable(value) {
return !!value?.$name;
}
function isForwarded(value) {
return !!value?.[$getNameForward];
}
function soulOf(value) {
return value?.[$soul];
}
export function getName(definition) {
if (isForwarded(definition)) {
return getName(definition[$getNameForward]);
}
return (nameMap.get(definition) ??
// nameMap is runtime-local, soul labels travel with the resource between runtimes
soulOf(definition)?.label ??
globalExt.__TYPEGPU_META__?.get(definition)?.name);
}
export function setName(definition, name) {
if (isForwarded(definition)) {
setName(definition[$getNameForward], name);
return;
}
nameMap.set(definition, name);
const soul = soulOf(definition);
if (soul) {
soul.label = name;
}
}
// --- METADATA ---
const metadataMap = new WeakMap();
/**
* Retrieves normalized (non-raw) function metadata.
* If `globalExt.__TYPEGPU_META__` contains raw metadata for the function,
* it is normalized, and then deleted to avoid unnecessary re-normalization.
*/
export function getFunctionMetadata(definition) {
// it's fine, if it's not an object, the get will return undefined
const maybeRawMeta = globalExt.__TYPEGPU_META__?.get(definition);
if (maybeRawMeta) {
globalExt.__TYPEGPU_META__?.delete(definition);
const normalized = normalizeMetadata(maybeRawMeta);
metadataMap.set(definition, normalized);
if (maybeRawMeta.name && nameMap.get(definition) === undefined) {
nameMap.set(definition, maybeRawMeta.name);
}
}
return metadataMap.get(definition);
}
/**
* AST's are given to functions with a 'use gpu' directive, which this function checks for.
*/
export function hasTinyestMetadata(value) {
return typeof value === 'function' && !!getFunctionMetadata(value);
}
// --- PERF ---
/**
* Performance measurements are only enabled in dev & test environments for now
*/
export const PERF = ((DEV || TEST) && {
get enabled() {
return !!globalExt.__TYPEGPU_MEASURE_PERF__;
},
record(name, data) {
const records = (globalExt.__TYPEGPU_PERF_RECORDS__ ??= new Map());
let entries = records.get(name);
if (!entries) {
entries = [];
records.set(name, entries);
}
entries.push(data);
},
}) ||
undefined;