@plasius/gpu-renderer 0.2.43 → 0.2.44

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.
package/CHANGELOG.md CHANGED
@@ -17,6 +17,26 @@ All notable changes to this project will be documented in this file.
17
17
  - **Changed**
18
18
  - (placeholder)
19
19
 
20
+ - **Fixed**
21
+ - Preserved hosted pull-request isolation, bounded validation runtime, and
22
+ disabled package-manager cache finalization on self-hosted main validation.
23
+ - (placeholder)
24
+
25
+ - **Security**
26
+ - (placeholder)
27
+
28
+ ## [0.2.44] - 2026-08-31
29
+
30
+ - **Added**
31
+ - Added an explicit consent-, flag-, and capability-gated helper that converts
32
+ coarse renderer health observations into the closed shared feedback
33
+ diagnostics packet for approved generator and GPU demo surfaces.
34
+
35
+ - **Changed**
36
+ - Updated `@plasius/gpu-shared` to the protected-CD-published 1.1.1 release
37
+ that exposes the focused feedback-diagnostics contract, and revalidated
38
+ the renderer against the registry artifact.
39
+
20
40
  - **Fixed**
21
41
  - (placeholder)
22
42
 
@@ -90,11 +110,21 @@ All notable changes to this project will be documented in this file.
90
110
 
91
111
  - **Changed**
92
112
  - Updated internal GPU dependencies to their surviving clean lines and refreshed the esbuild resolution.
113
+ - Bound diagnostics to the focused shared-package subpath and canonical
114
+ contract-version export, and enabled complete declaration checking with the
115
+ published WebXR type definitions.
93
116
 
94
117
  - **Fixed**
95
- - (placeholder)
118
+ - Removed a duplicate public mesh `extensions` declaration and replaced
119
+ unresolved ambient XR session references with the `@plasius/gpu-xr` state
120
+ contract.
96
121
 
97
122
  - **Security**
123
+ - Updated the development-tool dependency graph to the patched
124
+ `brace-expansion` release after the feedback release audit.
125
+ - Kept feedback diagnostics separate from general renderer snapshots and
126
+ excluded user-captured pixels, DOM, player data, URLs, filenames, exact
127
+ measurements, adapter identity and raw warnings from the output contract.
98
128
  - Added permanent fail-closed Zero-Three validation for manifests, source,
99
129
  locks, installed dependency graphs, declarations, bundles, npm tarballs,
100
130
  CycloneDX SBOMs, and active documentation, with digest-bound evidence
@@ -657,6 +687,9 @@ All notable changes to this project will be documented in this file.
657
687
  contract used by the wavefront display-quality renderer.
658
688
 
659
689
  - **Fixed**
690
+ - Clamped wavefront tile capacity against the depth-scaled path-vertex
691
+ storage binding so supported high-depth reference renders stay within
692
+ `maxStorageBufferBindingSize`.
660
693
  - Raised the bounded wavefront `maxDepth` ceiling to 32 so offline/reference
661
694
  renders can request 20-bounce paths without being clamped by renderer
662
695
  configuration.
@@ -684,6 +717,9 @@ All notable changes to this project will be documented in this file.
684
717
  corruption and stalled validation captures on higher-SPP frames.
685
718
 
686
719
  - **Changed**
720
+ - Raised the bounded wavefront `maxDepth` ceiling to 32 so offline/reference
721
+ renders can request 20-bounce paths without being clamped by renderer
722
+ configuration.
687
723
  - Changed internal wavefront frame batching and dispatch-diagnostics plumbing
688
724
  to live in a dedicated runtime helper module so scheduling concerns stay
689
725
  separated from shader and pipeline assembly.
@@ -1069,3 +1105,4 @@ All notable changes to this project will be documented in this file.
1069
1105
  [0.2.41]: https://github.com/Plasius-LTD/gpu-renderer/releases/tag/v0.2.41
1070
1106
  [0.2.42]: https://github.com/Plasius-LTD/gpu-renderer/releases/tag/v0.2.42
1071
1107
  [0.2.43]: https://github.com/Plasius-LTD/gpu-renderer/releases/tag/v0.2.43
1108
+ [0.2.44]: https://github.com/Plasius-LTD/gpu-renderer/releases/tag/v0.2.44
package/README.md CHANGED
@@ -8,19 +8,56 @@
8
8
  [![Security Policy](https://img.shields.io/badge/security%20policy-yes-orange.svg)](./SECURITY.md)
9
9
  [![Changelog](https://img.shields.io/badge/changelog-md-blue.svg)](./CHANGELOG.md)
10
10
 
11
- [![license](https://img.shields.io/github/license/Plasius-LTD/gpu-renderer)](./LICENSE)
12
-
13
11
  Framework-agnostic WebGPU renderer runtime for Plasius projects.
14
12
  This package is intended to replace Three.js-dependent render orchestration with
15
13
  an explicit WebGPU-first runtime that can be consumed from React, vanilla, or
16
14
  worker-driven app surfaces.
17
15
 
18
16
  The package targets Node.js 24, consumes the stable `@plasius/gpu-shared` 1.x
19
- runtime line (`^1.0.12`), and validates its development tooling against the
17
+ runtime line (`^1.1.1`), and validates its development tooling against the
20
18
  current ESLint 10 and TypeScript 7 baselines.
21
19
 
22
20
  Apache-2.0. ESM + CJS builds.
23
21
 
22
+ ## Privacy-Safe Feedback Diagnostics
23
+
24
+ Approved in-game viewers can explicitly convert a small set of current renderer
25
+ health observations into the closed
26
+ `@plasius/gpu-shared/feedback-diagnostics` packet:
27
+
28
+ ```js
29
+ import { createFeedbackGameDiagnosticSnapshot } from "@plasius/gpu-renderer";
30
+
31
+ const diagnostics = createFeedbackGameDiagnosticSnapshot({
32
+ featureEnabled,
33
+ capabilityGranted,
34
+ consentConfirmed: true,
35
+ surfaceId: "site.gpu-demo",
36
+ renderer: "webgpu",
37
+ backend: "worker",
38
+ viewportWidth: 1920,
39
+ viewportHeight: 1080,
40
+ frameRate: 59.9,
41
+ frameTimeMs: 16.7,
42
+ featureIds: ["renderer.frame-loop"],
43
+ counters: [{ code: "frame-drop", count: 2 }],
44
+ errorCodes: [],
45
+ });
46
+ ```
47
+
48
+ The helper returns `null` before reading renderer observations unless the
49
+ remotely evaluated `feedback.game-diagnostics.enabled` flag, the
50
+ `feedback.game-diagnostics.attach` capability, and explicit consent are all
51
+ present. It derives trusted provenance and returns only coarse buckets and
52
+ closed codes.
53
+
54
+ This API is deliberately separate from general renderer snapshots. It accepts
55
+ no canvas, user-captured pixels, DOM, player object, URL, filename,
56
+ adapter/device detail, coordinate or raw warning, performs no automatic
57
+ diagnostic capture or network/storage operation, and never registers
58
+ `/player-system`. Disabling the flag preserves ordinary structured-only bug
59
+ reporting.
60
+
24
61
  ## Install
25
62
 
26
63
  ```sh
package/dist/index.cjs CHANGED
@@ -24,8 +24,12 @@ __export(index_exports, {
24
24
  applyMediumTransmittance: () => applyMediumTransmittance,
25
25
  beerLambertTransmittance: () => beerLambertTransmittance,
26
26
  bindRendererToXrManager: () => bindRendererToXrManager,
27
+ bucketFeedbackGameFrameRate: () => bucketFeedbackGameFrameRate,
28
+ bucketFeedbackGameFrameTime: () => bucketFeedbackGameFrameTime,
29
+ bucketFeedbackGameViewport: () => bucketFeedbackGameViewport,
27
30
  createAnimatedSceneRenderer: () => createAnimatedSceneRenderer,
28
31
  createDefaultWavefrontSceneObjects: () => createDefaultWavefrontSceneObjects,
32
+ createFeedbackGameDiagnosticSnapshot: () => createFeedbackGameDiagnosticSnapshot,
29
33
  createGpuRenderer: () => createGpuRenderer,
30
34
  createMediumStack: () => createMediumStack,
31
35
  createProfessionalAnimatedSceneRenderer: () => createProfessionalAnimatedSceneRenderer,
@@ -2294,6 +2298,140 @@ async function createProfessionalAnimatedSceneRenderer(options = {}) {
2294
2298
  };
2295
2299
  }
2296
2300
 
2301
+ // src/feedback-diagnostics.js
2302
+ var import_feedback_diagnostics = require("@plasius/gpu-shared/feedback-diagnostics");
2303
+ var inputKeys = Object.freeze([
2304
+ "featureEnabled",
2305
+ "capabilityGranted",
2306
+ "consentConfirmed",
2307
+ "surfaceId",
2308
+ "renderer",
2309
+ "backend",
2310
+ "viewportWidth",
2311
+ "viewportHeight",
2312
+ "frameRate",
2313
+ "frameTimeMs",
2314
+ "featureIds",
2315
+ "counters",
2316
+ "errorCodes"
2317
+ ]);
2318
+ function bucketFeedbackGameViewport(width, height) {
2319
+ if (typeof width !== "number" || typeof height !== "number" || !Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
2320
+ return "unknown";
2321
+ }
2322
+ const shorterEdge = Math.min(width, height);
2323
+ const longerEdge = Math.max(width, height);
2324
+ const size = shorterEdge < 600 ? "small" : shorterEdge < 900 || longerEdge < 1440 ? "medium" : "large";
2325
+ const orientation = width > height ? "landscape" : "portrait";
2326
+ return `${size}-${orientation}`;
2327
+ }
2328
+ function bucketFeedbackGameFrameRate(frameRate) {
2329
+ if (typeof frameRate !== "number" || !Number.isFinite(frameRate) || frameRate < 0) {
2330
+ return "unknown";
2331
+ }
2332
+ if (frameRate < 15) {
2333
+ return "under-15";
2334
+ }
2335
+ if (frameRate < 30) {
2336
+ return "15-29";
2337
+ }
2338
+ if (frameRate < 60) {
2339
+ return "30-59";
2340
+ }
2341
+ return "60-plus";
2342
+ }
2343
+ function bucketFeedbackGameFrameTime(frameTimeMs) {
2344
+ if (typeof frameTimeMs !== "number" || !Number.isFinite(frameTimeMs) || frameTimeMs < 0) {
2345
+ return "unknown";
2346
+ }
2347
+ if (frameTimeMs < 17) {
2348
+ return "under-17ms";
2349
+ }
2350
+ if (frameTimeMs < 34) {
2351
+ return "17-33ms";
2352
+ }
2353
+ if (frameTimeMs < 67) {
2354
+ return "34-66ms";
2355
+ }
2356
+ return "over-66ms";
2357
+ }
2358
+ function createFeedbackGameDiagnosticSnapshot(input) {
2359
+ try {
2360
+ return createFeedbackGameDiagnosticSnapshotInternal(input);
2361
+ } catch {
2362
+ throw new TypeError("Invalid privacy-safe renderer diagnostics input.");
2363
+ }
2364
+ }
2365
+ function createFeedbackGameDiagnosticSnapshotInternal(input) {
2366
+ const snapshot = snapshotInputIfEnabled(input);
2367
+ if (snapshot === null) {
2368
+ return null;
2369
+ }
2370
+ const registration = typeof snapshot.surfaceId === "string" && Object.hasOwn(
2371
+ import_feedback_diagnostics.feedbackGameDiagnosticSurfaceRegistrations,
2372
+ snapshot.surfaceId
2373
+ ) ? import_feedback_diagnostics.feedbackGameDiagnosticSurfaceRegistrations[snapshot.surfaceId] : void 0;
2374
+ return (0, import_feedback_diagnostics.parseFeedbackGameDiagnostics)({
2375
+ type: "feedback-game-diagnostics",
2376
+ version: import_feedback_diagnostics.FEEDBACK_GAME_DIAGNOSTICS_CONTRACT_VERSION,
2377
+ surfaceId: snapshot.surfaceId,
2378
+ consentConfirmed: true,
2379
+ provenanceContractId: registration?.provenanceContractId,
2380
+ renderer: snapshot.renderer,
2381
+ backend: snapshot.backend,
2382
+ viewportBucket: bucketFeedbackGameViewport(
2383
+ snapshot.viewportWidth,
2384
+ snapshot.viewportHeight
2385
+ ),
2386
+ frameRateBucket: bucketFeedbackGameFrameRate(snapshot.frameRate),
2387
+ frameTimeBucket: bucketFeedbackGameFrameTime(snapshot.frameTimeMs),
2388
+ featureIds: snapshot.featureIds,
2389
+ counters: snapshot.counters,
2390
+ errorCodes: snapshot.errorCodes
2391
+ });
2392
+ }
2393
+ function snapshotInputIfEnabled(input) {
2394
+ assertValid(
2395
+ input !== null && typeof input === "object" && !Array.isArray(input) && (Object.getPrototypeOf(input) === Object.prototype || Object.getPrototypeOf(input) === null)
2396
+ );
2397
+ const gateKeys = [
2398
+ "featureEnabled",
2399
+ "capabilityGranted",
2400
+ "consentConfirmed"
2401
+ ];
2402
+ const snapshot = /* @__PURE__ */ Object.create(null);
2403
+ for (const key of gateKeys) {
2404
+ const descriptor = Object.getOwnPropertyDescriptor(input, key);
2405
+ assertValid(
2406
+ descriptor !== void 0 && descriptor.enumerable === true && Object.hasOwn(descriptor, "value") && typeof descriptor.value === "boolean"
2407
+ );
2408
+ snapshot[key] = descriptor.value;
2409
+ }
2410
+ const { featureEnabled, capabilityGranted, consentConfirmed } = snapshot;
2411
+ if (!featureEnabled || !capabilityGranted || !consentConfirmed) {
2412
+ return null;
2413
+ }
2414
+ const actualKeys = Reflect.ownKeys(input);
2415
+ assertValid(
2416
+ actualKeys.length === inputKeys.length && inputKeys.every((key) => actualKeys.includes(key)) && actualKeys.every(
2417
+ (key) => typeof key === "string" && inputKeys.includes(key)
2418
+ )
2419
+ );
2420
+ for (const key of inputKeys.filter((key2) => !gateKeys.includes(key2))) {
2421
+ const descriptor = Object.getOwnPropertyDescriptor(input, key);
2422
+ assertValid(
2423
+ descriptor !== void 0 && descriptor.enumerable === true && Object.hasOwn(descriptor, "value")
2424
+ );
2425
+ snapshot[key] = descriptor.value;
2426
+ }
2427
+ return Object.freeze(snapshot);
2428
+ }
2429
+ function assertValid(condition) {
2430
+ if (!condition) {
2431
+ throw new TypeError("Invalid privacy-safe renderer diagnostics input.");
2432
+ }
2433
+ }
2434
+
2297
2435
  // src/wavefront-frame-runtime.js
2298
2436
  function createGpuParallelismCounters() {
2299
2437
  return {
@@ -5139,7 +5277,13 @@ function clampTileSizeForDevice(config, device) {
5139
5277
  }
5140
5278
  const maxPixelsByRay = Math.floor(limit / RAY_RECORD_BYTES);
5141
5279
  const maxPixelsByHit = Math.floor(limit / HIT_RECORD_BYTES);
5142
- const maxPixels = Math.max(256, Math.min(maxPixelsByRay, maxPixelsByHit));
5280
+ const maxPixelsByPathVertex = Math.floor(
5281
+ limit / ((config.maxDepth + 1) * PATH_VERTEX_RECORD_BYTES)
5282
+ );
5283
+ const maxPixels = Math.max(
5284
+ 256,
5285
+ Math.min(maxPixelsByRay, maxPixelsByHit, maxPixelsByPathVertex)
5286
+ );
5143
5287
  if (config.tilePixelCapacity <= maxPixels) {
5144
5288
  return config.tileSize;
5145
5289
  }
@@ -11447,7 +11591,11 @@ async function createWavefrontPathTracingComputeRenderer(options = {}) {
11447
11591
  canvas,
11448
11592
  width: config.width,
11449
11593
  height: config.height,
11450
- tileSize: safeTileSize
11594
+ tileSize: safeTileSize,
11595
+ tilePixelCapacity: Math.min(
11596
+ config.tilePixelCapacity,
11597
+ safeTileSize * safeTileSize
11598
+ )
11451
11599
  });
11452
11600
  }
11453
11601
  config = Object.freeze({
@@ -13265,8 +13413,12 @@ function createRayTracingRenderPlan(options = {}) {
13265
13413
  applyMediumTransmittance,
13266
13414
  beerLambertTransmittance,
13267
13415
  bindRendererToXrManager,
13416
+ bucketFeedbackGameFrameRate,
13417
+ bucketFeedbackGameFrameTime,
13418
+ bucketFeedbackGameViewport,
13268
13419
  createAnimatedSceneRenderer,
13269
13420
  createDefaultWavefrontSceneObjects,
13421
+ createFeedbackGameDiagnosticSnapshot,
13270
13422
  createGpuRenderer,
13271
13423
  createMediumStack,
13272
13424
  createProfessionalAnimatedSceneRenderer,