From 4d4f9ddb4f21ec7e83482e1ed5553d776876f5ff Mon Sep 17 00:00:00 2001 From: Iwo Plaza Date: Tue, 20 Oct 2026 20:14:08 +0200 Subject: [PATCH] impr: Skip uniform alignment analysis when its warning is off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every `$usage('uniform')` walked the schema and computed memory layouts to decide whether to warn about non-portable uniform alignment (`uniform-schema-misaligned`). That warning is off by default in production builds, so the work was wasted there. - Adds `isEnabled(type)` to the internal logger, so callers can skip computing what a warning needs when it won't be shown. - `warnIfNotUniformAligned` returns early when its warning is disabled. In development and tests nothing changes. Node 22 with `NODE_ENV=production`, creating `root.createBuffer(Scene).$usage('uniform')` for a scene struct (camera matrices plus an array of 16 light structs). Medians of 9 fresh processes: | | main | this PR | |---|---|---| | First buffer | 1.90 ms | 0.45 ms | | Each of the next 200 | 69.2 µs | 3.8 µs | --- .../typegpu/src/core/pipeline/webgpuLimitations.ts | 13 +++++++++++-- packages/typegpu/src/tgpuLogger.ts | 6 ++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/typegpu/src/core/pipeline/webgpuLimitations.ts b/packages/typegpu/src/core/pipeline/webgpuLimitations.ts index df789a97b0..64eb46e672 100644 --- a/packages/typegpu/src/core/pipeline/webgpuLimitations.ts +++ b/packages/typegpu/src/core/pipeline/webgpuLimitations.ts @@ -47,8 +47,17 @@ function requiredAlignOf(schema: BaseData) { * See https://www.w3.org/TR/WGSL/#address-space-layout-constraints */ export function warnIfNotUniformAligned(schema: BaseData) { + if (!logger.isEnabled('uniform-schema-misaligned')) { + // Silenced by default in production, and computing memory layouts isn't free + return; + } + + checkUniformAlignment(schema); +} + +function checkUniformAlignment(schema: BaseData) { if (isWgslArray(schema)) { - warnIfNotUniformAligned(schema.elementType); + checkUniformAlignment(schema.elementType); const stride = roundUp(sizeOf(schema.elementType), alignmentOf(schema.elementType)); if (stride % 16 !== 0) { @@ -62,7 +71,7 @@ To address this, put the element schema in a struct and wrap the prop in 'd.alig } } if (isWgslStruct(schema)) { - Object.values(schema.propTypes).forEach(warnIfNotUniformAligned); + Object.values(schema.propTypes).forEach(checkUniformAlignment); Object.entries(schema.propTypes).forEach(([key, value]) => { const offset = memoryLayoutOf(schema, (schema) => schema[key]).offset; diff --git a/packages/typegpu/src/tgpuLogger.ts b/packages/typegpu/src/tgpuLogger.ts index e1f1125903..eaac927a6f 100644 --- a/packages/typegpu/src/tgpuLogger.ts +++ b/packages/typegpu/src/tgpuLogger.ts @@ -18,6 +18,8 @@ type WarningType = (typeof warningTypes)[number]; // internal API interface Logger { + /** Lets callers skip computing what a warning needs when it wouldn't be shown anyway. */ + isEnabled(type: WarningType): boolean; warn(type: WarningType, ...args: unknown[]): void; warnOnce(type: WarningType, key: object, tag: string, ...args: unknown[]): void; } @@ -67,6 +69,10 @@ export class TgpuLogger implements Logger, Warn { this.#enabledWarnings = new Set(this.#initialEnabledWarnings); } + isEnabled(type: WarningType): boolean { + return this.#enabledWarnings.has(type); + } + warn(type: WarningType, ...args: unknown[]) { if (this.#enabledWarnings.has(type)) { console.warn(`⚠️ [${type}] `, ...args);