@photivra/engine 2.19.0 → 2.21.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.
Files changed (242) hide show
  1. package/CHANGELOG.md +289 -1
  2. package/CITATION.cff +1 -1
  3. package/NODE_SUPPORT.md +7 -5
  4. package/README.md +7 -6
  5. package/SECURITY.md +1 -1
  6. package/THIRD_PARTY.md +21 -10
  7. package/dist/capture/dng-lens-correction-opcodes.d.ts +32 -0
  8. package/dist/capture/dng-lens-correction-opcodes.js +119 -0
  9. package/dist/capture/dng-lens-correction-opcodes.js.map +1 -0
  10. package/dist/capture/exposure-build-up-stage.d.ts +16 -0
  11. package/dist/capture/exposure-build-up-stage.js +4 -0
  12. package/dist/capture/exposure-build-up-stage.js.map +1 -0
  13. package/dist/capture/native-environment-lean.d.ts +2 -1
  14. package/dist/capture/native-environment-lean.js +42 -78
  15. package/dist/capture/native-environment-lean.js.map +1 -1
  16. package/dist/capture/native-environment-tabulated.js +4 -3
  17. package/dist/capture/native-environment-tabulated.js.map +1 -1
  18. package/dist/capture/native-raw-dng.d.ts +6 -0
  19. package/dist/capture/native-raw-dng.js +16 -2
  20. package/dist/capture/native-raw-dng.js.map +1 -1
  21. package/dist/capture/native-raw.d.ts +3 -2
  22. package/dist/capture/native-raw.js +5 -4
  23. package/dist/capture/native-raw.js.map +1 -1
  24. package/dist/capture/sensor-raw-producer.d.ts +4 -1
  25. package/dist/capture/sensor-raw-producer.js +15 -8
  26. package/dist/capture/sensor-raw-producer.js.map +1 -1
  27. package/dist/core/shared-helpers.d.ts +2 -0
  28. package/dist/core/shared-helpers.js +4 -0
  29. package/dist/core/shared-helpers.js.map +1 -1
  30. package/dist/core/version.d.ts +1 -1
  31. package/dist/core/version.js +1 -1
  32. package/dist/core/version.js.map +1 -1
  33. package/dist/equipment/generic-lens-catalogue.d.ts +11 -4
  34. package/dist/equipment/generic-lens-catalogue.js +49 -7
  35. package/dist/equipment/generic-lens-catalogue.js.map +1 -1
  36. package/dist/equipment/generic-tier-assets.d.ts +32 -0
  37. package/dist/equipment/generic-tier-assets.js +18 -14
  38. package/dist/equipment/generic-tier-assets.js.map +1 -1
  39. package/dist/equipment/generic-tier-presets.js +2 -3
  40. package/dist/equipment/generic-tier-presets.js.map +1 -1
  41. package/dist/equipment/sensor-profile-body.d.ts +78 -0
  42. package/dist/equipment/sensor-profile-body.js +77 -0
  43. package/dist/equipment/sensor-profile-body.js.map +1 -0
  44. package/dist/equipment/sensor-profiles.d.ts +8 -0
  45. package/dist/equipment/sensor-profiles.js +82 -0
  46. package/dist/equipment/sensor-profiles.js.map +1 -0
  47. package/dist/facade/catalogue-lens-signal.d.ts +2 -2
  48. package/dist/facade/catalogue-lens-signal.js +58 -71
  49. package/dist/facade/catalogue-lens-signal.js.map +1 -1
  50. package/dist/facade/chart-radiance-batch.js +2 -1
  51. package/dist/facade/chart-radiance-batch.js.map +1 -1
  52. package/dist/facade/defocus-image-space-provider.d.ts +7 -0
  53. package/dist/facade/defocus-image-space-provider.js +64 -76
  54. package/dist/facade/defocus-image-space-provider.js.map +1 -1
  55. package/dist/facade/display-view-gpu-session.js +2 -0
  56. package/dist/facade/display-view-gpu-session.js.map +1 -1
  57. package/dist/facade/display-view-gpu.d.ts +13 -5
  58. package/dist/facade/display-view-gpu.js +4 -4
  59. package/dist/facade/display-view-gpu.js.map +1 -1
  60. package/dist/facade/display-view-lens-signal.d.ts +1 -1
  61. package/dist/facade/display-view-lens-signal.js +30 -26
  62. package/dist/facade/display-view-lens-signal.js.map +1 -1
  63. package/dist/facade/display-view.d.ts +3 -1
  64. package/dist/facade/display-view.js +6 -24
  65. package/dist/facade/display-view.js.map +1 -1
  66. package/dist/facade/expected-signal-setup.d.ts +3 -1
  67. package/dist/facade/expected-signal-setup.js +1 -1
  68. package/dist/facade/expected-signal-setup.js.map +1 -1
  69. package/dist/facade/expected-signal.d.ts +47 -14
  70. package/dist/facade/expected-signal.js +117 -112
  71. package/dist/facade/expected-signal.js.map +1 -1
  72. package/dist/facade/exposure-build-up.d.ts +70 -0
  73. package/dist/facade/exposure-build-up.js +164 -0
  74. package/dist/facade/exposure-build-up.js.map +1 -0
  75. package/dist/facade/fast-methods.d.ts +50 -0
  76. package/dist/facade/fast-methods.js +58 -0
  77. package/dist/facade/fast-methods.js.map +1 -0
  78. package/dist/facade/fast-resolution.d.ts +12 -0
  79. package/dist/facade/fast-resolution.js +18 -0
  80. package/dist/facade/fast-resolution.js.map +1 -0
  81. package/dist/facade/generic-lens-capture.d.ts +5 -4
  82. package/dist/facade/generic-lens-capture.js +5 -4
  83. package/dist/facade/generic-lens-capture.js.map +1 -1
  84. package/dist/facade/image-plane-enable.d.ts +7 -0
  85. package/dist/facade/image-plane-enable.js +17 -0
  86. package/dist/facade/image-plane-enable.js.map +1 -0
  87. package/dist/facade/image-plane-lattice-data.d.ts +6 -0
  88. package/dist/facade/image-plane-lattice-data.js +10 -0
  89. package/dist/facade/image-plane-lattice-data.js.map +1 -0
  90. package/dist/facade/image-plane-support.d.ts +33 -0
  91. package/dist/facade/image-plane-support.js +11 -0
  92. package/dist/facade/image-plane-support.js.map +1 -0
  93. package/dist/facade/image-plane.d.ts +36 -0
  94. package/dist/facade/image-plane.js +353 -0
  95. package/dist/facade/image-plane.js.map +1 -0
  96. package/dist/facade/mixed-illumination.d.ts +108 -0
  97. package/dist/facade/mixed-illumination.js +174 -0
  98. package/dist/facade/mixed-illumination.js.map +1 -0
  99. package/dist/facade/representative-light-sources.d.ts +72 -0
  100. package/dist/facade/representative-light-sources.js +124 -0
  101. package/dist/facade/representative-light-sources.js.map +1 -0
  102. package/dist/facade/scene-radiance.d.ts +129 -4
  103. package/dist/facade/scene-radiance.js +48 -13
  104. package/dist/facade/scene-radiance.js.map +1 -1
  105. package/dist/facade/simulate-capture.d.ts +88 -19
  106. package/dist/facade/simulate-capture.js +374 -145
  107. package/dist/facade/simulate-capture.js.map +1 -1
  108. package/dist/facade/simulate-display-view.d.ts +3 -2
  109. package/dist/facade/simulate-display-view.js +36 -18
  110. package/dist/facade/simulate-display-view.js.map +1 -1
  111. package/dist/gpu/chart-composite-gpu.d.ts +13 -1
  112. package/dist/gpu/chart-composite-gpu.js +48 -9
  113. package/dist/gpu/chart-composite-gpu.js.map +1 -1
  114. package/dist/gpu/chart-radiance-gpu.js +4 -30
  115. package/dist/gpu/chart-radiance-gpu.js.map +1 -1
  116. package/dist/gpu/display-view-composite-material-module.d.ts +10 -4
  117. package/dist/gpu/display-view-composite-material-module.js +39 -13
  118. package/dist/gpu/display-view-composite-material-module.js.map +1 -1
  119. package/dist/gpu/display-view-image-material-module.d.ts +86 -0
  120. package/dist/gpu/display-view-image-material-module.js +339 -0
  121. package/dist/gpu/display-view-image-material-module.js.map +1 -0
  122. package/dist/gpu/display-view-image-quality.d.ts +45 -0
  123. package/dist/gpu/display-view-image-quality.js +380 -0
  124. package/dist/gpu/display-view-image-quality.js.map +1 -0
  125. package/dist/gpu/display-view-quality-gpu.d.ts +67 -1
  126. package/dist/gpu/display-view-quality-gpu.js +136 -205
  127. package/dist/gpu/display-view-quality-gpu.js.map +1 -1
  128. package/dist/gpu/display-view-speed-gpu.d.ts +51 -3
  129. package/dist/gpu/display-view-speed-gpu.js +131 -93
  130. package/dist/gpu/display-view-speed-gpu.js.map +1 -1
  131. package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +29 -15
  132. package/dist/gpu/wgsl-display-view-quality-kernel.js +58 -36
  133. package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
  134. package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +21 -6
  135. package/dist/gpu/wgsl-display-view-speed-kernel.js +46 -11
  136. package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
  137. package/dist/gpu/wgsl-exact-sum.d.ts +20 -0
  138. package/dist/gpu/wgsl-exact-sum.js +42 -0
  139. package/dist/gpu/wgsl-exact-sum.js.map +1 -0
  140. package/dist/index.d.ts +18 -3
  141. package/dist/index.js +12 -1
  142. package/dist/index.js.map +1 -1
  143. package/dist/motion/subject-motion.d.ts +66 -0
  144. package/dist/motion/subject-motion.js +52 -0
  145. package/dist/motion/subject-motion.js.map +1 -0
  146. package/dist/optics/aperture-diameter.d.ts +47 -0
  147. package/dist/optics/aperture-diameter.js +50 -0
  148. package/dist/optics/aperture-diameter.js.map +1 -0
  149. package/dist/optics/detail-limit.d.ts +182 -0
  150. package/dist/optics/detail-limit.js +336 -0
  151. package/dist/optics/detail-limit.js.map +1 -0
  152. package/dist/optics/generic-lens-lateral-color.d.ts +83 -0
  153. package/dist/optics/generic-lens-lateral-color.js +77 -0
  154. package/dist/optics/generic-lens-lateral-color.js.map +1 -0
  155. package/dist/optics/generic-lens-psf.d.ts +18 -2
  156. package/dist/optics/generic-lens-psf.js +79 -48
  157. package/dist/optics/generic-lens-psf.js.map +1 -1
  158. package/dist/optics/lens-psf-profile.d.ts +7 -0
  159. package/dist/optics/lens-psf-profile.js +2 -1
  160. package/dist/optics/lens-psf-profile.js.map +1 -1
  161. package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
  162. package/dist/optics/scene-to-sensor-irradiance.js +7 -0
  163. package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
  164. package/dist/output/crop-to-match-focal-length.d.ts +62 -0
  165. package/dist/output/crop-to-match-focal-length.js +63 -0
  166. package/dist/output/crop-to-match-focal-length.js.map +1 -0
  167. package/dist/output/developed-lens-corrections.d.ts +19 -5
  168. package/dist/output/developed-lens-corrections.js +30 -11
  169. package/dist/output/developed-lens-corrections.js.map +1 -1
  170. package/dist/output/generic-lens-corrections.d.ts +41 -3
  171. package/dist/output/generic-lens-corrections.js +57 -9
  172. package/dist/output/generic-lens-corrections.js.map +1 -1
  173. package/dist/output/lens-corrections.d.ts +12 -2
  174. package/dist/output/lens-corrections.js +22 -7
  175. package/dist/output/lens-corrections.js.map +1 -1
  176. package/dist/output/print-contrast-reference.js +1 -1
  177. package/dist/output/print-contrast-reference.js.map +1 -1
  178. package/dist/output/print-plan.d.ts +41 -5
  179. package/dist/output/print-plan.js +59 -14
  180. package/dist/output/print-plan.js.map +1 -1
  181. package/dist/output/print-size-blur-noise.d.ts +110 -0
  182. package/dist/output/print-size-blur-noise.js +138 -0
  183. package/dist/output/print-size-blur-noise.js.map +1 -0
  184. package/dist/sensor/binomial-sample.d.ts +3 -0
  185. package/dist/sensor/binomial-sample.js +86 -0
  186. package/dist/sensor/binomial-sample.js.map +1 -0
  187. package/dist/sensor/eqe-electron-rate.js +1 -7
  188. package/dist/sensor/eqe-electron-rate.js.map +1 -1
  189. package/dist/sensor/exposure-window.d.ts +2 -0
  190. package/dist/sensor/exposure-window.js +2 -2
  191. package/dist/sensor/exposure-window.js.map +1 -1
  192. package/dist/sensor/readout-timing.js +2 -23
  193. package/dist/sensor/readout-timing.js.map +1 -1
  194. package/dist/sensor/response-application-compatibility.js +1 -6
  195. package/dist/sensor/response-application-compatibility.js.map +1 -1
  196. package/dist/sensor/responsivity-photocurrent.js +1 -7
  197. package/dist/sensor/responsivity-photocurrent.js.map +1 -1
  198. package/dist/sensor/sensor-characteristics.d.ts +147 -0
  199. package/dist/sensor/sensor-characteristics.js +126 -0
  200. package/dist/sensor/sensor-characteristics.js.map +1 -0
  201. package/dist/sensor/spatial-sample-reduction.js +1 -5
  202. package/dist/sensor/spatial-sample-reduction.js.map +1 -1
  203. package/dist/sensor/spectral-quadrature.js +1 -6
  204. package/dist/sensor/spectral-quadrature.js.map +1 -1
  205. package/dist/sensor/temporal-photo-signal.d.ts +3 -0
  206. package/dist/sensor/temporal-photo-signal.js +5 -2
  207. package/dist/sensor/temporal-photo-signal.js.map +1 -1
  208. package/dist/stabilization/system.d.ts +9 -0
  209. package/dist/stabilization/system.js +5 -6
  210. package/dist/stabilization/system.js.map +1 -1
  211. package/docs/AGENT_GUIDE.md +5 -0
  212. package/docs/API_REFERENCE.md +173 -2
  213. package/docs/QUICK_START.md +213 -6
  214. package/docs/USAGE.md +157 -3
  215. package/docs/api/capture-native-raw-dng.md +6 -0
  216. package/docs/api/core-version.md +1 -1
  217. package/docs/api/equipment-generic-lens-catalogue.md +17 -7
  218. package/docs/api/equipment-sensor-profile-body.md +64 -0
  219. package/docs/api/equipment-sensor-profiles.md +86 -0
  220. package/docs/api/exports.json +357 -2
  221. package/docs/api/facade-display-view-gpu.md +5 -2
  222. package/docs/api/facade-exposure-build-up.md +105 -0
  223. package/docs/api/facade-fast-methods.md +99 -0
  224. package/docs/api/facade-image-plane-enable.md +16 -0
  225. package/docs/api/facade-mixed-illumination.md +67 -0
  226. package/docs/api/facade-representative-light-sources.md +131 -0
  227. package/docs/api/facade-scene-radiance.md +54 -3
  228. package/docs/api/facade-simulate-capture.md +60 -15
  229. package/docs/api/facade-simulate-display-view.md +3 -2
  230. package/docs/api/motion-subject-motion.md +23 -0
  231. package/docs/api/optics-aperture-diameter.md +51 -0
  232. package/docs/api/optics-detail-limit.md +203 -0
  233. package/docs/api/optics-generic-lens-lateral-color.md +79 -0
  234. package/docs/api/output-crop-to-match-focal-length.md +67 -0
  235. package/docs/api/output-developed-lens-corrections.md +10 -1
  236. package/docs/api/output-generic-lens-corrections.md +40 -2
  237. package/docs/api/output-lens-corrections.md +11 -1
  238. package/docs/api/output-print-plan.md +35 -1
  239. package/docs/api/output-print-size-blur-noise.md +115 -0
  240. package/docs/api/sensor-sensor-characteristics.md +105 -0
  241. package/llms.txt +6 -0
  242. package/package.json +1 -1
@@ -37,6 +37,7 @@ import { dwSplit, packChartScene, probeChartCompositeDevice } from "./chart-comp
37
37
  import { chartPresetMaterialModule } from "./display-view-chart-material-module.js";
38
38
  import { BUFFER_USAGE, GpuResourceScope } from "./webgpu-runtime.js";
39
39
  import { DISPLAY_VIEW_GPU_MAXIMUM_OFFSETS } from "./wgsl-display-view-speed-kernel.js";
40
+ import { imagePlaneSupport } from "../facade/image-plane-support.js";
40
41
  /** One WGSL rounding of + − × in either direction (E = 2⁻²³). */
41
42
  const E = 2 * WEBGPU_F32_UNIT_ROUNDOFF;
42
43
  /** The module's id in the pipeline cache (one shader per product path for every composite scene; the scene is data): the Dekker path's. */
@@ -55,24 +56,31 @@ export const DISPLAY_VIEW_LATTICE = /* @__PURE__ */ Object.freeze({ scaleUHi: 0,
55
56
  * defines `material_at(p: vec2<f32>)` (see the module comment). The constants E and SLACK come from the kernel's preamble. `path`
56
57
  * is the double-word product path the device's probe chose (default Dekker's).
57
58
  */
58
- export function chartCompositeMaterialWgsl(path = "dekker") {
59
+ /** The composite kernel's text renamed for a display-view module: its flag is `material_uncertain`, its barrier word `lattice.zero`. */
60
+ function renameForDisplayView(code) {
61
+ return code.replace(/^const SLACK: f32 = [^\n]*\n/mu, "").replace(/\bflagged\b/gu, "material_uncertain").replace(/\bmargin\(/gu, "bmargin(").replace(/\bparams\.zero\b/gu, "lattice.zero");
62
+ }
63
+ /**
64
+ * #581: the composite kernel's common part (double-float32 with its rounding barrier, the bound arithmetic, `bfloor`) renamed for a
65
+ * display-view module (shared by the composite and the image-plane modules); the kernel's preamble gives E and SLACK.
66
+ */
67
+ export function displayViewModuleCommonWgsl(path) {
59
68
  const source = chartCompositeWgsl(path);
60
- const commonStart = source.indexOf("const DW: f32"), commonEnd = source.indexOf("struct Params"), bodyStart = source.indexOf("const SEGMENT_BOX"), bodyEnd = source.indexOf("@compute");
61
- if (commonStart < 0 || commonEnd < commonStart || bodyStart < commonEnd || bodyEnd < bodyStart)
69
+ const commonStart = source.indexOf("const DW: f32"), commonEnd = source.indexOf("struct Params");
70
+ if (commonStart < 0 || commonEnd < commonStart)
62
71
  throw new ImageKernelExecutionError("gpu-validation", "The composite chart kernel's material functions were not found.");
63
- const rename = (code) => code.replace(/^const SLACK: f32 = [^\n]*\n/mu, "").replace(/\bflagged\b/gu, "material_uncertain").replace(/\bmargin\(/gu, "bmargin(").replace(/\bparams\.zero\b/gu, "lattice.zero");
64
- return `${rename(source.slice(commonStart, commonEnd))}
65
- @group(1) @binding(0) var<storage, read> af: array<f32>;
66
- @group(1) @binding(1) var<storage, read> ai: array<u32>;
67
- struct LatticeParams {
72
+ return renameForDisplayView(source.slice(commonStart, commonEnd));
73
+ }
74
+ /** The lattice uniform and the offsets table of a display-view module (@group(1) bindings 2 and 3; `DISPLAY_VIEW_LATTICE`). */
75
+ export const LATTICE_BINDINGS_WGSL = `struct LatticeParams {
68
76
  scale_u_hi: f32, scale_u_lo: f32, scale_v_hi: f32, scale_v_lo: f32,
69
77
  chart_k_hi: f32, chart_k_lo: f32, chart_aspect: f32, tolerance: f32,
70
78
  offsets: u32, placed: u32, surround: u32, zero: u32,
71
79
  };
72
80
  @group(1) @binding(2) var<uniform> lattice: LatticeParams;
73
- @group(1) @binding(3) var<storage, read> lattice_offsets: array<vec4<f32>>;
74
- ${rename(source.slice(bodyStart, bodyEnd))}
75
- // The exact lattice point of one axis from the kernel's p = fl(fl(x + c)·scale): the offset whose constant c puts p/scale
81
+ @group(1) @binding(3) var<storage, read> lattice_offsets: array<vec4<f32>>;`;
82
+ /** The exact lattice point recovery (see the module comment), shared by the composite and the image-plane modules. */
83
+ export const LATTICE_POINT_WGSL = `// The exact lattice point of one axis from the kernel's p = fl(fl(x + c)·scale): the offset whose constant c puts p/scale
76
84
  // nearest an integer x, then (x + c)·scale in double-float32 from the exact integer and the float64 constants (hi + lo).
77
85
  fn lattice_point(p: f32, scale: D, axis: u32) -> D {
78
86
  let rough = p / scale.h;
@@ -88,7 +96,17 @@ fn lattice_point(p: f32, scale: D, axis: u32) -> D {
88
96
  }
89
97
  if (!(best <= lattice.tolerance)) { material_uncertain = true; }
90
98
  return d_mul(d_add(D(site, 0.0), D(c_hi, c_lo)), scale);
91
- }
99
+ }`;
100
+ export function chartCompositeMaterialWgsl(path = "dekker") {
101
+ const source = chartCompositeWgsl(path), bodyStart = source.indexOf("const SEGMENT_BOX"), bodyEnd = source.indexOf("@compute");
102
+ if (bodyStart < 0 || bodyEnd < bodyStart)
103
+ throw new ImageKernelExecutionError("gpu-validation", "The composite chart kernel's material functions were not found.");
104
+ return `${displayViewModuleCommonWgsl(path)}
105
+ @group(1) @binding(0) var<storage, read> af: array<f32>;
106
+ @group(1) @binding(1) var<storage, read> ai: array<u32>;
107
+ ${LATTICE_BINDINGS_WGSL}
108
+ ${renameForDisplayView(source.slice(bodyStart, bodyEnd))}
109
+ ${LATTICE_POINT_WGSL}
92
110
  fn material_at(p: vec2<f32>) -> u32 {
93
111
  var u = lattice_point(p.x, D(lattice.scale_u_hi, lattice.scale_u_lo), 0u);
94
112
  var v = lattice_point(p.y, D(lattice.scale_v_hi, lattice.scale_v_lo), 1u);
@@ -190,6 +208,11 @@ function sceneOf(gpu) {
190
208
  }
191
209
  export function createDisplayViewMaterialModules(runtime, pipelines) {
192
210
  const presets = new WeakMap(), uploads = [];
211
+ // #581: image-plane prints (their double-float32 arithmetic is the composite kernel's, so the same probe gates them), through the
212
+ // module prepareImagePlaneScenes() loaded; created on the first photo.
213
+ let images;
214
+ // A photo reaches the GPU only after the request was resolved, so the module is enabled.
215
+ const imageModules = async () => images ??= (await imagePlaneSupport().loadGpuModule()).createDisplayViewImageModules(runtime, probe);
193
216
  let probed = null;
194
217
  const wgsl = new Map();
195
218
  const probe = (signal) => {
@@ -216,6 +239,8 @@ export function createDisplayViewMaterialModules(runtime, pipelines) {
216
239
  };
217
240
  return {
218
241
  async moduleFor(gpu, signal) {
242
+ if (gpu.signalInput.scene.image)
243
+ return await (await imageModules()).moduleFor(gpu, signal);
219
244
  const scene = sceneOf(gpu), placement = gpu.placement ?? null, signalInput = gpu.signalInput;
220
245
  const tableMaterials = signalInput.scene.kind === "materials" ? signalInput.scene.materials.length : -1;
221
246
  if (tableMaterials !== scene.materials.length + (placement ? 1 : 0))
@@ -240,9 +265,10 @@ export function createDisplayViewMaterialModules(runtime, pipelines) {
240
265
  { binding: 2, kind: "uniform", data: new Uint8Array(lattice.params) }, { binding: 3, kind: "storage", data: lattice.offsets }
241
266
  ] };
242
267
  },
268
+ async imagePasses(gpu, signal) { return await (await imageModules()).qualityPasses(gpu, signal); },
243
269
  get uploadedScenes() { return uploads.length; },
244
270
  release() { for (const entry of uploads.splice(0))
245
- entry.scope.release(); }
271
+ entry.scope.release(); images?.release(); }
246
272
  };
247
273
  }
248
274
  //# sourceMappingURL=display-view-composite-material-module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"display-view-composite-material-module.js","sourceRoot":"","sources":["../../src/gpu/display-view-composite-material-module.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * The composite-chart and mask-layer material module of the GPU display view (#491): the Speed kernel's `material_at`\n * (the seam of #478, `DisplayViewGpuMaterialModule`) built from the composite chart kernel's classification (#477,\n * `wgsl-chart-composite-kernel.ts`: `material()`, its bound arithmetic and double-float32), so that composite charts,\n * every 2.3 element as a plain chart, the sine-profile Siemens star and declared `material-layers` scenes render on the\n * GPU. The scene's packed records (`packChartScene`) are uploaded once per renderer and reused across a view's parts,\n * as the composite kernel reuses them per accelerator; the device probe of the composite kernel gates the module.\n *\n * **The query point.** The Speed kernel hands the module p = fl(fl(x + c)·scale) per axis: the site coordinate x plus the\n * offset constant c = 0.5 + o − W/2 (`DISPLAY_VIEW_AUX.offsets`), times the frame-units-per-site scale rounded once to\n * float32, so p carries up to 2E relative error (E = 2⁻²³) against the reference's float64 query point. The composite\n * kernel's chirp decisions (the zone plate's phase, the stars' sector cross products) need the point to about 2⁻⁴⁰; fed\n * p directly they would flag most of a 64-cycle sine star. The module therefore **recovers the exact lattice point**: it\n * knows the offsets c_o (uploaded as float32 hi + lo pairs) and the scale (hi + lo), divides p by the scale's high part\n * (within 6E·|s| of s = x + c_o), picks the offset whose c_o puts the quotient nearest an integer x, and re-forms the point\n * in double-float32 as (x + c_o)·scale from the exact integer and the float64 constants. The host admits a lattice only\n * when the recovery is unambiguous: the distinct fractional parts of the offsets (mod 1) lie more than four tolerances\n * apart, the tolerance being 8E·max|s| + 2⁻¹²; a point whose residual exceeds the tolerance on the device is flagged.\n * The recovered point differs from the exact (x + c_o)·g by at most about 2⁻⁴⁶ relative (two double-float32 operations\n * and the split constants' 2⁻⁴⁸), inside the composite kernel's own allowance for a point (DW = 2⁻⁴⁰ relative in `bd`).\n * The reference's own float64 query point differs from the exact lattice value by its float64 rounding only: measured at\n * most 5.6·10⁻¹⁶ absolute over every site and offset of the #491 fixtures, and checked by the host at the frame's four\n * corners within 2⁻⁴⁸·(|p| + 1); that is inside the composite kernel's 10⁻¹⁴ slack for the reference's rounding. So the\n * composite kernel's bounds and SAFETY factor (4) apply unchanged, and the module's point error is far inside the Speed\n * kernel's contract (≤ 2E + 10⁻¹⁴): no Speed bound term changes.\n *\n * **A fixed-size chart** (`chartSize`): the reference maps the frame point to chart-local units, cu = (u·m)/h with m the\n * metres per frame unit and h the chart's half width, and returns the surround material outside |cu| ≤ 1, |cv| ≤ aspect.\n * The module multiplies the recovered point by k = m/h (hi + lo) in double-float32 and tests the chart rectangle in bound\n * arithmetic (flagging points within their bound of its edge); the surround is the materials table's last entry.\n */\nimport { ImageKernelExecutionError, WEBGPU_F32_UNIT_ROUNDOFF } from \"./image-kernel-execution.js\";\nimport { chartCompositeWgsl, type ChartCompositeProductPath } from \"./wgsl-chart-composite-kernel.js\";\nimport { chartGpuPresetCode } from \"./chart-radiance-gpu.js\";\nimport { dwSplit, packChartScene, probeChartCompositeDevice, type PackedChartScene } from \"./chart-composite-gpu.js\";\nimport type { ChartCompositeProbeRecord } from \"./image-kernel-execution.js\";\nimport { chartPresetMaterialModule } from \"./display-view-chart-material-module.js\";\nimport type { ChartRadianceBatchPlan } from \"../facade/chart-radiance-batch.js\";\nimport type { ResolvedChartScene } from \"../facade/chart-scenes.js\";\nimport type { ResolvedChartMaterialLayers } from \"../facade/chart-material-layers.js\";\nimport type { DisplayViewExpectedSignalInput } from \"../facade/expected-signal.js\";\nimport type { DisplayViewGpuSetup } from \"../facade/display-view.js\";\nimport { BUFFER_USAGE, GpuResourceScope, type WebGpuRuntime } from \"./webgpu-runtime.js\";\nimport { DISPLAY_VIEW_GPU_MAXIMUM_OFFSETS } from \"./wgsl-display-view-speed-kernel.js\";\nimport type { DisplayViewGpuMaterialModule } from \"./display-view-speed-gpu.js\";\n\ntype PipelineSource = (label: string, code: string) => Promise<GPUComputePipeline>;\n\n/** One WGSL rounding of + − × in either direction (E = 2⁻²³). */\nconst E = 2 * WEBGPU_F32_UNIT_ROUNDOFF;\n/** The module's id in the pipeline cache (one shader per product path for every composite scene; the scene is data): the Dekker path's. */\nexport const CHART_COMPOSITE_MATERIAL_MODULE_ID = \"chart-composite\";\n/** The module's id per product path (the fma path's shader is a different pipeline). */\nexport function chartCompositeMaterialModuleId(path: ChartCompositeProductPath): string { return path === \"dekker\" ? CHART_COMPOSITE_MATERIAL_MODULE_ID : CHART_COMPOSITE_MATERIAL_MODULE_ID + \"-fma\"; }\n/** Scenes whose records stay uploaded per renderer (the composite kernel keeps the same number per accelerator). */\nconst KEPT_SCENES = 4;\n/** The corner check of the query-point model against the reference's own query points, relative to |p| + 1 (inside the composite kernel's 10⁻¹⁴ slack). */\nconst MODEL_TOLERANCE = 2 ** -48;\n\n/** Layout of the lattice uniform (float32 / u32 words, 48 bytes) and the offsets table (one vec4 per offset: cu hi, cu lo, cv hi, cv lo). */\nexport const DISPLAY_VIEW_LATTICE = /* @__PURE__ */ Object.freeze({ scaleUHi: 0, scaleULo: 1, scaleVHi: 2, scaleVLo: 3, chartKHi: 4, chartKLo: 5, chartAspect: 6, tolerance: 7, offsets: 8, placed: 9, surround: 10, zero: 11, words: 12 });\n\n/**\n * The composite kernel's classification (`material(p: vec4<f32>)` with its bound arithmetic, double-float32, cos polynomial,\n * elements and layers) renamed for the display-view kernel, its records bound at @group(1), and the lattice recovery that\n * defines `material_at(p: vec2<f32>)` (see the module comment). The constants E and SLACK come from the kernel's preamble. `path`\n * is the double-word product path the device's probe chose (default Dekker's).\n */\nexport function chartCompositeMaterialWgsl(path: ChartCompositeProductPath = \"dekker\"): string {\n const source = chartCompositeWgsl(path);\n const commonStart = source.indexOf(\"const DW: f32\"), commonEnd = source.indexOf(\"struct Params\"), bodyStart = source.indexOf(\"const SEGMENT_BOX\"), bodyEnd = source.indexOf(\"@compute\");\n if (commonStart < 0 || commonEnd < commonStart || bodyStart < commonEnd || bodyEnd < bodyStart) throw new ImageKernelExecutionError(\"gpu-validation\", \"The composite chart kernel's material functions were not found.\");\n const rename = (code: string): string => code.replace(/^const SLACK: f32 = [^\\n]*\\n/mu, \"\").replace(/\\bflagged\\b/gu, \"material_uncertain\").replace(/\\bmargin\\(/gu, \"bmargin(\").replace(/\\bparams\\.zero\\b/gu, \"lattice.zero\");\n return `${rename(source.slice(commonStart, commonEnd))}\n@group(1) @binding(0) var<storage, read> af: array<f32>;\n@group(1) @binding(1) var<storage, read> ai: array<u32>;\nstruct LatticeParams {\n scale_u_hi: f32, scale_u_lo: f32, scale_v_hi: f32, scale_v_lo: f32,\n chart_k_hi: f32, chart_k_lo: f32, chart_aspect: f32, tolerance: f32,\n offsets: u32, placed: u32, surround: u32, zero: u32,\n};\n@group(1) @binding(2) var<uniform> lattice: LatticeParams;\n@group(1) @binding(3) var<storage, read> lattice_offsets: array<vec4<f32>>;\n${rename(source.slice(bodyStart, bodyEnd))}\n// The exact lattice point of one axis from the kernel's p = fl(fl(x + c)·scale): the offset whose constant c puts p/scale\n// nearest an integer x, then (x + c)·scale in double-float32 from the exact integer and the float64 constants (hi + lo).\nfn lattice_point(p: f32, scale: D, axis: u32) -> D {\n let rough = p / scale.h;\n var best = 3.0e38; var site = 0.0; var c_hi = 0.0; var c_lo = 0.0;\n for (var o = 0u; o < lattice.offsets; o = o + 1u) {\n let row = lattice_offsets[o];\n let hi = select(row.z, row.x, axis == 0u);\n let lo = select(row.w, row.y, axis == 0u);\n let d = rough - hi;\n let n = round(d);\n let r = abs(d - n);\n if (r < best) { best = r; site = n; c_hi = hi; c_lo = lo; }\n }\n if (!(best <= lattice.tolerance)) { material_uncertain = true; }\n return d_mul(d_add(D(site, 0.0), D(c_hi, c_lo)), scale);\n}\nfn material_at(p: vec2<f32>) -> u32 {\n var u = lattice_point(p.x, D(lattice.scale_u_hi, lattice.scale_u_lo), 0u);\n var v = lattice_point(p.y, D(lattice.scale_v_hi, lattice.scale_v_lo), 1u);\n if (lattice.placed != 0u) {\n let k = D(lattice.chart_k_hi, lattice.chart_k_lo);\n u = d_mul(u, k); v = d_mul(v, k);\n if (!(le(babs(bd(u)), bx(1.0)) && le(babs(bd(v)), bc(lattice.chart_aspect)))) { return lattice.surround; }\n }\n return material(vec4<f32>(u.h, u.l, v.h, v.l));\n}\n`;\n}\n\n/** A fixed-size chart's placement for the module: chart-local frame units per frame unit (m/h) and the chart's aspect. */\nexport interface DisplayViewChartPlacement { chartUnitsPerFrameUnit: number; aspect: number }\n\n/** The lattice constants of a render (see the module comment): the uniform words and the offsets table. */\nexport interface DisplayViewLatticeConstants { params: ArrayBuffer; offsets: Float32Array<ArrayBuffer>; tolerance: number; scaleU: number; scaleV: number }\n\n/**\n * The query lattice of an expected-signal input as the module needs it, or an `unsupported-on-backend` error: the scale per\n * axis from the reference's own query points (two sites a frame apart), the model (x + c)·scale checked against the reference\n * at the frame's four corners for every offset within 2⁻⁴⁸·(|p| + 1), the offsets as hi + lo pairs, and the recovery tolerance\n * 8E·max|x + c| + 2⁻¹², which the distinct fractional parts of the offsets must clear four times over.\n */\nexport function displayViewLatticeConstants(signalInput: DisplayViewExpectedSignalInput, placement: DisplayViewChartPlacement | null, surroundMaterial: number): DisplayViewLatticeConstants {\n const W = signalInput.nativeWidth, H = signalInput.nativeHeight, offsets = signalInput.offsets, query = signalInput.queryPoint;\n if (!query) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The expected signal has no query points (the Quality path); use cpu-reference.\");\n if (offsets.length < 1 || offsets.length > DISPLAY_VIEW_GPU_MAXIMUM_OFFSETS) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The kernel holds 1 to \" + DISPLAY_VIEW_GPU_MAXIMUM_OFFSETS + \" query offsets.\");\n if (!(W >= 2 && H >= 2 && W <= 2 ** 20 && H <= 2 ** 20)) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The native frame is outside the lattice recovery's range (2 to 2^20 sites per axis).\");\n const point = new Float64Array(2), x1 = W - 1, y1 = H - 1;\n query(0, 0, 0, point); const u0 = point[0]!, v0 = point[1]!;\n query(x1, 0, 0, point); const u1 = point[0]!;\n query(0, y1, 0, point); const v1 = point[1]!;\n const scaleU = (u1 - u0) / x1, scaleV = (v1 - v0) / y1;\n if (!(Number.isFinite(scaleU) && Number.isFinite(scaleV) && scaleU !== 0 && scaleV !== 0)) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The request's query lattice has no scale; use cpu-reference.\");\n const cu = new Float64Array(offsets.length), cv = new Float64Array(offsets.length);\n let smax = 0;\n for (let o = 0; o < offsets.length; o++) {\n const offset = offsets[o]!;\n cu[o] = 0.5 + offset.x - W / 2; cv[o] = 0.5 + offset.y - H / 2;\n smax = Math.max(smax, Math.abs(cu[o]!), Math.abs(x1 + cu[o]!), Math.abs(cv[o]!), Math.abs(y1 + cv[o]!));\n for (const [x, y] of [[0, 0], [x1, 0], [0, y1], [x1, y1]] as const) {\n query(x, y, o, point);\n const mu = (x + cu[o]!) * scaleU, mv = (y + cv[o]!) * scaleV;\n if (!(Math.abs(mu - point[0]!) <= MODEL_TOLERANCE * (Math.abs(point[0]!) + 1) && Math.abs(mv - point[1]!) <= MODEL_TOLERANCE * (Math.abs(point[1]!) + 1)))\n throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The request's query points are not a rectilinear site lattice within 2^-48; use cpu-reference.\");\n }\n }\n const tolerance = Math.fround(8 * E * smax + 2 ** -12);\n if (!(tolerance < 1 / 8)) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The query lattice is too wide for the exact point recovery; use cpu-reference.\");\n // Distinct fractional parts of the offsets must be told apart on the device: more than four tolerances apart, or an exact integer apart (the same lattice).\n for (const axis of [cu, cv]) {\n for (let a = 0; a < axis.length; a++) for (let b = a + 1; b < axis.length; b++) {\n const delta = axis[a]! - axis[b]!, fractional = Math.abs(delta - Math.round(delta));\n if (fractional !== 0 && !(fractional > 4 * tolerance))\n throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"Two query offsets are too close (mod one site) for the exact point recovery; use cpu-reference.\");\n }\n }\n const params = new ArrayBuffer(4 * DISPLAY_VIEW_LATTICE.words), floats = new Float32Array(params), words = new Uint32Array(params);\n const [suH, suL] = dwSplit(scaleU), [svH, svL] = dwSplit(scaleV);\n floats[DISPLAY_VIEW_LATTICE.scaleUHi] = suH; floats[DISPLAY_VIEW_LATTICE.scaleULo] = suL; floats[DISPLAY_VIEW_LATTICE.scaleVHi] = svH; floats[DISPLAY_VIEW_LATTICE.scaleVLo] = svL;\n if (placement) {\n const [kH, kL] = dwSplit(placement.chartUnitsPerFrameUnit);\n if (!(Number.isFinite(kH) && kH > 0 && Number.isFinite(placement.aspect) && placement.aspect > 0)) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The chart placement is not finite.\");\n floats[DISPLAY_VIEW_LATTICE.chartKHi] = kH; floats[DISPLAY_VIEW_LATTICE.chartKLo] = kL; floats[DISPLAY_VIEW_LATTICE.chartAspect] = placement.aspect;\n }\n floats[DISPLAY_VIEW_LATTICE.tolerance] = tolerance;\n words[DISPLAY_VIEW_LATTICE.offsets] = offsets.length; words[DISPLAY_VIEW_LATTICE.placed] = placement ? 1 : 0; words[DISPLAY_VIEW_LATTICE.surround] = surroundMaterial;\n words[DISPLAY_VIEW_LATTICE.zero] = 0; // the rounding barrier's zero (`lattice.zero`)\n const table = new Float32Array(4 * offsets.length);\n for (let o = 0; o < offsets.length; o++) {\n const [uH, uL] = dwSplit(cu[o]!), [vH, vL] = dwSplit(cv[o]!);\n table[4 * o] = uH; table[4 * o + 1] = uL; table[4 * o + 2] = vH; table[4 * o + 3] = vL;\n }\n return { params, offsets: table, tolerance, scaleU, scaleV };\n}\n\n/** The resolved scene behind a GPU setup: the chart whose geometry is packed, the layers (or null) and the materials the kernel indexes. */\nfunction sceneOf(gpu: DisplayViewGpuSetup): { chart: ResolvedChartScene; layers: ResolvedChartMaterialLayers | null; materials: ResolvedChartScene[\"materials\"]; key: object } {\n if (gpu.layers) return { chart: gpu.layers.chart, layers: gpu.layers, materials: gpu.layers.materials, key: gpu.layers };\n if (gpu.chart) return { chart: gpu.chart, layers: null, materials: gpu.chart.materials, key: gpu.chart };\n throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The GPU material lookup covers chart presets, composite charts and declared material-layers scenes; a caller scene function runs on cpu-reference (describe it as material-layers).\");\n}\n\ninterface UploadedRecords { key: object; scope: GpuResourceScope; af: GPUBuffer; ai: GPUBuffer; packed: PackedChartScene }\n\n/**\n * The material modules of one display-view renderer (one device): the chart-preset module for the eight 2.0 presets filling\n * the frame, the composite module for everything else the chart kernels classify. The composite module's device probe runs\n * once per renderer (single flight; a refusal is retried on the next render), its scene records are uploaded once per scene\n * and the four most recent kept until `release()`.\n */\nexport interface DisplayViewMaterialModules {\n /** The module of a setup's scene, or an `unsupported-on-backend` error (a caller function scene, a failed probe, a materials mismatch). */\n moduleFor(gpu: DisplayViewGpuSetup, signal: AbortSignal): Promise<DisplayViewGpuMaterialModule>;\n /** Uploaded scenes (for tests). */\n readonly uploadedScenes: number;\n release(): void;\n}\n\nexport function createDisplayViewMaterialModules(runtime: WebGpuRuntime, pipelines: PipelineSource): DisplayViewMaterialModules {\n const presets = new WeakMap<ResolvedChartScene, DisplayViewGpuMaterialModule>(), uploads: UploadedRecords[] = [];\n let probed: Promise<ChartCompositeProbeRecord> | null = null;\n const wgsl = new Map<ChartCompositeProductPath, string>();\n const probe = (signal: AbortSignal): Promise<ChartCompositeProbeRecord> => {\n probed ??= probeChartCompositeDevice(runtime, pipelines, signal).catch((error: unknown) => { probed = null; throw error; });\n return probed;\n };\n const records = (scene: ReturnType<typeof sceneOf>): UploadedRecords => {\n const index = uploads.findIndex((e) => e.key === scene.key);\n if (index >= 0) { const [entry] = uploads.splice(index, 1); uploads.push(entry!); return entry!; }\n // packChartScene reads the plan's chart, layers and materials only.\n const packed = packChartScene({ chart: scene.chart, layers: scene.layers, materials: scene.materials } as unknown as ChartRadianceBatchPlan);\n if (Math.max(packed.af.byteLength, packed.ai.byteLength) > runtime.maximumStorageBindingBytes) throw new ImageKernelExecutionError(\"insufficient-limits\", \"Chart records exceed the device's storage binding limit.\");\n const scope = new GpuResourceScope(runtime);\n const entry: UploadedRecords = { key: scene.key, scope, af: scope.upload(\"photivra-display-view-chart-floats\", packed.af, BUFFER_USAGE.STORAGE), ai: scope.upload(\"photivra-display-view-chart-records\", packed.ai, BUFFER_USAGE.STORAGE), packed };\n uploads.push(entry);\n while (uploads.length > KEPT_SCENES) uploads.shift()!.scope.release();\n return entry;\n };\n return {\n async moduleFor(gpu, signal): Promise<DisplayViewGpuMaterialModule> {\n const scene = sceneOf(gpu), placement = gpu.placement ?? null, signalInput = gpu.signalInput;\n const tableMaterials = signalInput.scene.kind === \"materials\" ? signalInput.scene.materials.length : -1;\n if (tableMaterials !== scene.materials.length + (placement ? 1 : 0))\n throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The expected signal's materials do not match the scene's (\" + tableMaterials + \" against \" + scene.materials.length + (placement ? \" plus the surround\" : \"\") + \"); use cpu-reference.\");\n if (!scene.layers && !placement && chartGpuPresetCode({ chart: scene.chart } as unknown as ChartRadianceBatchPlan) !== undefined) {\n let module = presets.get(scene.chart);\n if (!module) { module = chartPresetMaterialModule(scene.chart); presets.set(scene.chart, module); }\n return module;\n }\n const record = await probe(signal), path = record.productPath ?? \"dekker\";\n const lattice = displayViewLatticeConstants(signalInput, placement, scene.materials.length), uploaded = records(scene);\n let code = wgsl.get(path);\n if (code === undefined) { code = chartCompositeMaterialWgsl(path); wgsl.set(path, code); }\n return { id: chartCompositeMaterialModuleId(path), wgsl: code, compositeProbe: record, bindings: [\n { binding: 0, kind: \"storage\", buffer: uploaded.af }, { binding: 1, kind: \"storage\", buffer: uploaded.ai },\n { binding: 2, kind: \"uniform\", data: new Uint8Array(lattice.params) }, { binding: 3, kind: \"storage\", data: lattice.offsets }] };\n },\n get uploadedScenes(): number { return uploads.length; },\n release(): void { for (const entry of uploads.splice(0)) entry.scope.release(); }\n };\n}\n"]}
1
+ {"version":3,"file":"display-view-composite-material-module.js","sourceRoot":"","sources":["../../src/gpu/display-view-composite-material-module.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * The composite-chart and mask-layer material module of the GPU display view (#491): the Speed kernel's `material_at`\n * (the seam of #478, `DisplayViewGpuMaterialModule`) built from the composite chart kernel's classification (#477,\n * `wgsl-chart-composite-kernel.ts`: `material()`, its bound arithmetic and double-float32), so that composite charts,\n * every 2.3 element as a plain chart, the sine-profile Siemens star and declared `material-layers` scenes render on the\n * GPU. The scene's packed records (`packChartScene`) are uploaded once per renderer and reused across a view's parts,\n * as the composite kernel reuses them per accelerator; the device probe of the composite kernel gates the module.\n *\n * **The query point.** The Speed kernel hands the module p = fl(fl(x + c)·scale) per axis: the site coordinate x plus the\n * offset constant c = 0.5 + o − W/2 (`DISPLAY_VIEW_AUX.offsets`), times the frame-units-per-site scale rounded once to\n * float32, so p carries up to 2E relative error (E = 2⁻²³) against the reference's float64 query point. The composite\n * kernel's chirp decisions (the zone plate's phase, the stars' sector cross products) need the point to about 2⁻⁴⁰; fed\n * p directly they would flag most of a 64-cycle sine star. The module therefore **recovers the exact lattice point**: it\n * knows the offsets c_o (uploaded as float32 hi + lo pairs) and the scale (hi + lo), divides p by the scale's high part\n * (within 6E·|s| of s = x + c_o), picks the offset whose c_o puts the quotient nearest an integer x, and re-forms the point\n * in double-float32 as (x + c_o)·scale from the exact integer and the float64 constants. The host admits a lattice only\n * when the recovery is unambiguous: the distinct fractional parts of the offsets (mod 1) lie more than four tolerances\n * apart, the tolerance being 8E·max|s| + 2⁻¹²; a point whose residual exceeds the tolerance on the device is flagged.\n * The recovered point differs from the exact (x + c_o)·g by at most about 2⁻⁴⁶ relative (two double-float32 operations\n * and the split constants' 2⁻⁴⁸), inside the composite kernel's own allowance for a point (DW = 2⁻⁴⁰ relative in `bd`).\n * The reference's own float64 query point differs from the exact lattice value by its float64 rounding only: measured at\n * most 5.6·10⁻¹⁶ absolute over every site and offset of the #491 fixtures, and checked by the host at the frame's four\n * corners within 2⁻⁴⁸·(|p| + 1); that is inside the composite kernel's 10⁻¹⁴ slack for the reference's rounding. So the\n * composite kernel's bounds and SAFETY factor (4) apply unchanged, and the module's point error is far inside the Speed\n * kernel's contract (≤ 2E + 10⁻¹⁴): no Speed bound term changes.\n *\n * **A fixed-size chart** (`chartSize`): the reference maps the frame point to chart-local units, cu = (u·m)/h with m the\n * metres per frame unit and h the chart's half width, and returns the surround material outside |cu| ≤ 1, |cv| ≤ aspect.\n * The module multiplies the recovered point by k = m/h (hi + lo) in double-float32 and tests the chart rectangle in bound\n * arithmetic (flagging points within their bound of its edge); the surround is the materials table's last entry.\n */\nimport { ImageKernelExecutionError, WEBGPU_F32_UNIT_ROUNDOFF } from \"./image-kernel-execution.js\";\nimport { chartCompositeWgsl, type ChartCompositeProductPath } from \"./wgsl-chart-composite-kernel.js\";\nimport { chartGpuPresetCode } from \"./chart-radiance-gpu.js\";\nimport { dwSplit, packChartScene, probeChartCompositeDevice, type PackedChartScene } from \"./chart-composite-gpu.js\";\nimport type { ChartCompositeProbeRecord } from \"./image-kernel-execution.js\";\nimport { chartPresetMaterialModule } from \"./display-view-chart-material-module.js\";\nimport type { ChartRadianceBatchPlan } from \"../facade/chart-radiance-batch.js\";\nimport type { ResolvedChartScene } from \"../facade/chart-scenes.js\";\nimport type { ResolvedChartMaterialLayers } from \"../facade/chart-material-layers.js\";\nimport type { DisplayViewExpectedSignalInput } from \"../facade/expected-signal.js\";\nimport type { DisplayViewGpuSetup } from \"../facade/display-view.js\";\nimport { BUFFER_USAGE, GpuResourceScope, type WebGpuRuntime } from \"./webgpu-runtime.js\";\nimport { DISPLAY_VIEW_GPU_MAXIMUM_OFFSETS } from \"./wgsl-display-view-speed-kernel.js\";\nimport type { DisplayViewGpuMaterialModule } from \"./display-view-speed-gpu.js\";\nimport { imagePlaneSupport } from \"../facade/image-plane-support.js\";\nimport type { DisplayViewImageModules } from \"./display-view-image-material-module.js\";\nimport type { DisplayViewQualityImagePasses } from \"./display-view-quality-gpu.js\";\n\ntype PipelineSource = (label: string, code: string) => Promise<GPUComputePipeline>;\n\n/** One WGSL rounding of + − × in either direction (E = 2⁻²³). */\nconst E = 2 * WEBGPU_F32_UNIT_ROUNDOFF;\n/** The module's id in the pipeline cache (one shader per product path for every composite scene; the scene is data): the Dekker path's. */\nexport const CHART_COMPOSITE_MATERIAL_MODULE_ID = \"chart-composite\";\n/** The module's id per product path (the fma path's shader is a different pipeline). */\nexport function chartCompositeMaterialModuleId(path: ChartCompositeProductPath): string { return path === \"dekker\" ? CHART_COMPOSITE_MATERIAL_MODULE_ID : CHART_COMPOSITE_MATERIAL_MODULE_ID + \"-fma\"; }\n/** Scenes whose records stay uploaded per renderer (the composite kernel keeps the same number per accelerator). */\nconst KEPT_SCENES = 4;\n/** The corner check of the query-point model against the reference's own query points, relative to |p| + 1 (inside the composite kernel's 10⁻¹⁴ slack). */\nconst MODEL_TOLERANCE = 2 ** -48;\n\n/** Layout of the lattice uniform (float32 / u32 words, 48 bytes) and the offsets table (one vec4 per offset: cu hi, cu lo, cv hi, cv lo). */\nexport const DISPLAY_VIEW_LATTICE = /* @__PURE__ */ Object.freeze({ scaleUHi: 0, scaleULo: 1, scaleVHi: 2, scaleVLo: 3, chartKHi: 4, chartKLo: 5, chartAspect: 6, tolerance: 7, offsets: 8, placed: 9, surround: 10, zero: 11, words: 12 });\n\n/**\n * The composite kernel's classification (`material(p: vec4<f32>)` with its bound arithmetic, double-float32, cos polynomial,\n * elements and layers) renamed for the display-view kernel, its records bound at @group(1), and the lattice recovery that\n * defines `material_at(p: vec2<f32>)` (see the module comment). The constants E and SLACK come from the kernel's preamble. `path`\n * is the double-word product path the device's probe chose (default Dekker's).\n */\n/** The composite kernel's text renamed for a display-view module: its flag is `material_uncertain`, its barrier word `lattice.zero`. */\nfunction renameForDisplayView(code: string): string {\n return code.replace(/^const SLACK: f32 = [^\\n]*\\n/mu, \"\").replace(/\\bflagged\\b/gu, \"material_uncertain\").replace(/\\bmargin\\(/gu, \"bmargin(\").replace(/\\bparams\\.zero\\b/gu, \"lattice.zero\");\n}\n/**\n * #581: the composite kernel's common part (double-float32 with its rounding barrier, the bound arithmetic, `bfloor`) renamed for a\n * display-view module (shared by the composite and the image-plane modules); the kernel's preamble gives E and SLACK.\n */\nexport function displayViewModuleCommonWgsl(path: ChartCompositeProductPath): string {\n const source = chartCompositeWgsl(path);\n const commonStart = source.indexOf(\"const DW: f32\"), commonEnd = source.indexOf(\"struct Params\");\n if (commonStart < 0 || commonEnd < commonStart) throw new ImageKernelExecutionError(\"gpu-validation\", \"The composite chart kernel's material functions were not found.\");\n return renameForDisplayView(source.slice(commonStart, commonEnd));\n}\n/** The lattice uniform and the offsets table of a display-view module (@group(1) bindings 2 and 3; `DISPLAY_VIEW_LATTICE`). */\nexport const LATTICE_BINDINGS_WGSL = `struct LatticeParams {\n scale_u_hi: f32, scale_u_lo: f32, scale_v_hi: f32, scale_v_lo: f32,\n chart_k_hi: f32, chart_k_lo: f32, chart_aspect: f32, tolerance: f32,\n offsets: u32, placed: u32, surround: u32, zero: u32,\n};\n@group(1) @binding(2) var<uniform> lattice: LatticeParams;\n@group(1) @binding(3) var<storage, read> lattice_offsets: array<vec4<f32>>;`;\n/** The exact lattice point recovery (see the module comment), shared by the composite and the image-plane modules. */\nexport const LATTICE_POINT_WGSL = `// The exact lattice point of one axis from the kernel's p = fl(fl(x + c)·scale): the offset whose constant c puts p/scale\n// nearest an integer x, then (x + c)·scale in double-float32 from the exact integer and the float64 constants (hi + lo).\nfn lattice_point(p: f32, scale: D, axis: u32) -> D {\n let rough = p / scale.h;\n var best = 3.0e38; var site = 0.0; var c_hi = 0.0; var c_lo = 0.0;\n for (var o = 0u; o < lattice.offsets; o = o + 1u) {\n let row = lattice_offsets[o];\n let hi = select(row.z, row.x, axis == 0u);\n let lo = select(row.w, row.y, axis == 0u);\n let d = rough - hi;\n let n = round(d);\n let r = abs(d - n);\n if (r < best) { best = r; site = n; c_hi = hi; c_lo = lo; }\n }\n if (!(best <= lattice.tolerance)) { material_uncertain = true; }\n return d_mul(d_add(D(site, 0.0), D(c_hi, c_lo)), scale);\n}`;\nexport function chartCompositeMaterialWgsl(path: ChartCompositeProductPath = \"dekker\"): string {\n const source = chartCompositeWgsl(path), bodyStart = source.indexOf(\"const SEGMENT_BOX\"), bodyEnd = source.indexOf(\"@compute\");\n if (bodyStart < 0 || bodyEnd < bodyStart) throw new ImageKernelExecutionError(\"gpu-validation\", \"The composite chart kernel's material functions were not found.\");\n return `${displayViewModuleCommonWgsl(path)}\n@group(1) @binding(0) var<storage, read> af: array<f32>;\n@group(1) @binding(1) var<storage, read> ai: array<u32>;\n${LATTICE_BINDINGS_WGSL}\n${renameForDisplayView(source.slice(bodyStart, bodyEnd))}\n${LATTICE_POINT_WGSL}\nfn material_at(p: vec2<f32>) -> u32 {\n var u = lattice_point(p.x, D(lattice.scale_u_hi, lattice.scale_u_lo), 0u);\n var v = lattice_point(p.y, D(lattice.scale_v_hi, lattice.scale_v_lo), 1u);\n if (lattice.placed != 0u) {\n let k = D(lattice.chart_k_hi, lattice.chart_k_lo);\n u = d_mul(u, k); v = d_mul(v, k);\n if (!(le(babs(bd(u)), bx(1.0)) && le(babs(bd(v)), bc(lattice.chart_aspect)))) { return lattice.surround; }\n }\n return material(vec4<f32>(u.h, u.l, v.h, v.l));\n}\n`;\n}\n\n/** A fixed-size chart's placement for the module: chart-local frame units per frame unit (m/h) and the chart's aspect. */\nexport interface DisplayViewChartPlacement { chartUnitsPerFrameUnit: number; aspect: number }\n\n/** The lattice constants of a render (see the module comment): the uniform words and the offsets table. */\nexport interface DisplayViewLatticeConstants { params: ArrayBuffer; offsets: Float32Array<ArrayBuffer>; tolerance: number; scaleU: number; scaleV: number }\n\n/**\n * The query lattice of an expected-signal input as the module needs it, or an `unsupported-on-backend` error: the scale per\n * axis from the reference's own query points (two sites a frame apart), the model (x + c)·scale checked against the reference\n * at the frame's four corners for every offset within 2⁻⁴⁸·(|p| + 1), the offsets as hi + lo pairs, and the recovery tolerance\n * 8E·max|x + c| + 2⁻¹², which the distinct fractional parts of the offsets must clear four times over.\n */\nexport function displayViewLatticeConstants(signalInput: DisplayViewExpectedSignalInput, placement: DisplayViewChartPlacement | null, surroundMaterial: number): DisplayViewLatticeConstants {\n const W = signalInput.nativeWidth, H = signalInput.nativeHeight, offsets = signalInput.offsets, query = signalInput.queryPoint;\n if (!query) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The expected signal has no query points (the Quality path); use cpu-reference.\");\n if (offsets.length < 1 || offsets.length > DISPLAY_VIEW_GPU_MAXIMUM_OFFSETS) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The kernel holds 1 to \" + DISPLAY_VIEW_GPU_MAXIMUM_OFFSETS + \" query offsets.\");\n if (!(W >= 2 && H >= 2 && W <= 2 ** 20 && H <= 2 ** 20)) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The native frame is outside the lattice recovery's range (2 to 2^20 sites per axis).\");\n const point = new Float64Array(2), x1 = W - 1, y1 = H - 1;\n query(0, 0, 0, point); const u0 = point[0]!, v0 = point[1]!;\n query(x1, 0, 0, point); const u1 = point[0]!;\n query(0, y1, 0, point); const v1 = point[1]!;\n const scaleU = (u1 - u0) / x1, scaleV = (v1 - v0) / y1;\n if (!(Number.isFinite(scaleU) && Number.isFinite(scaleV) && scaleU !== 0 && scaleV !== 0)) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The request's query lattice has no scale; use cpu-reference.\");\n const cu = new Float64Array(offsets.length), cv = new Float64Array(offsets.length);\n let smax = 0;\n for (let o = 0; o < offsets.length; o++) {\n const offset = offsets[o]!;\n cu[o] = 0.5 + offset.x - W / 2; cv[o] = 0.5 + offset.y - H / 2;\n smax = Math.max(smax, Math.abs(cu[o]!), Math.abs(x1 + cu[o]!), Math.abs(cv[o]!), Math.abs(y1 + cv[o]!));\n for (const [x, y] of [[0, 0], [x1, 0], [0, y1], [x1, y1]] as const) {\n query(x, y, o, point);\n const mu = (x + cu[o]!) * scaleU, mv = (y + cv[o]!) * scaleV;\n if (!(Math.abs(mu - point[0]!) <= MODEL_TOLERANCE * (Math.abs(point[0]!) + 1) && Math.abs(mv - point[1]!) <= MODEL_TOLERANCE * (Math.abs(point[1]!) + 1)))\n throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The request's query points are not a rectilinear site lattice within 2^-48; use cpu-reference.\");\n }\n }\n const tolerance = Math.fround(8 * E * smax + 2 ** -12);\n if (!(tolerance < 1 / 8)) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The query lattice is too wide for the exact point recovery; use cpu-reference.\");\n // Distinct fractional parts of the offsets must be told apart on the device: more than four tolerances apart, or an exact integer apart (the same lattice).\n for (const axis of [cu, cv]) {\n for (let a = 0; a < axis.length; a++) for (let b = a + 1; b < axis.length; b++) {\n const delta = axis[a]! - axis[b]!, fractional = Math.abs(delta - Math.round(delta));\n if (fractional !== 0 && !(fractional > 4 * tolerance))\n throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"Two query offsets are too close (mod one site) for the exact point recovery; use cpu-reference.\");\n }\n }\n const params = new ArrayBuffer(4 * DISPLAY_VIEW_LATTICE.words), floats = new Float32Array(params), words = new Uint32Array(params);\n const [suH, suL] = dwSplit(scaleU), [svH, svL] = dwSplit(scaleV);\n floats[DISPLAY_VIEW_LATTICE.scaleUHi] = suH; floats[DISPLAY_VIEW_LATTICE.scaleULo] = suL; floats[DISPLAY_VIEW_LATTICE.scaleVHi] = svH; floats[DISPLAY_VIEW_LATTICE.scaleVLo] = svL;\n if (placement) {\n const [kH, kL] = dwSplit(placement.chartUnitsPerFrameUnit);\n if (!(Number.isFinite(kH) && kH > 0 && Number.isFinite(placement.aspect) && placement.aspect > 0)) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The chart placement is not finite.\");\n floats[DISPLAY_VIEW_LATTICE.chartKHi] = kH; floats[DISPLAY_VIEW_LATTICE.chartKLo] = kL; floats[DISPLAY_VIEW_LATTICE.chartAspect] = placement.aspect;\n }\n floats[DISPLAY_VIEW_LATTICE.tolerance] = tolerance;\n words[DISPLAY_VIEW_LATTICE.offsets] = offsets.length; words[DISPLAY_VIEW_LATTICE.placed] = placement ? 1 : 0; words[DISPLAY_VIEW_LATTICE.surround] = surroundMaterial;\n words[DISPLAY_VIEW_LATTICE.zero] = 0; // the rounding barrier's zero (`lattice.zero`)\n const table = new Float32Array(4 * offsets.length);\n for (let o = 0; o < offsets.length; o++) {\n const [uH, uL] = dwSplit(cu[o]!), [vH, vL] = dwSplit(cv[o]!);\n table[4 * o] = uH; table[4 * o + 1] = uL; table[4 * o + 2] = vH; table[4 * o + 3] = vL;\n }\n return { params, offsets: table, tolerance, scaleU, scaleV };\n}\n\n/** The resolved scene behind a GPU setup: the chart whose geometry is packed, the layers (or null) and the materials the kernel indexes. */\nfunction sceneOf(gpu: DisplayViewGpuSetup): { chart: ResolvedChartScene; layers: ResolvedChartMaterialLayers | null; materials: ResolvedChartScene[\"materials\"]; key: object } {\n if (gpu.layers) return { chart: gpu.layers.chart, layers: gpu.layers, materials: gpu.layers.materials, key: gpu.layers };\n if (gpu.chart) return { chart: gpu.chart, layers: null, materials: gpu.chart.materials, key: gpu.chart };\n throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The GPU material lookup covers chart presets, composite charts and declared material-layers scenes; a caller scene function runs on cpu-reference (describe it as material-layers).\");\n}\n\ninterface UploadedRecords { key: object; scope: GpuResourceScope; af: GPUBuffer; ai: GPUBuffer; packed: PackedChartScene }\n\n/**\n * The material modules of one display-view renderer (one device): the chart-preset module for the eight 2.0 presets filling\n * the frame, the composite module for everything else the chart kernels classify. The composite module's device probe runs\n * once per renderer (single flight; a refusal is retried on the next render), its scene records are uploaded once per scene\n * and the four most recent kept until `release()`.\n */\nexport interface DisplayViewMaterialModules {\n /** The module of a setup's scene, or an `unsupported-on-backend` error (a caller function scene, a failed probe, a materials mismatch). */\n moduleFor(gpu: DisplayViewGpuSetup, signal: AbortSignal): Promise<DisplayViewGpuMaterialModule>;\n /** #581: an image-plane print's Quality passes (after `prepareImagePlaneScenes()`), or an `unsupported-on-backend` error. */\n imagePasses(gpu: DisplayViewGpuSetup, signal: AbortSignal): Promise<DisplayViewQualityImagePasses>;\n /** Uploaded scenes (for tests). */\n readonly uploadedScenes: number;\n release(): void;\n}\n\nexport function createDisplayViewMaterialModules(runtime: WebGpuRuntime, pipelines: PipelineSource): DisplayViewMaterialModules {\n const presets = new WeakMap<ResolvedChartScene, DisplayViewGpuMaterialModule>(), uploads: UploadedRecords[] = [];\n // #581: image-plane prints (their double-float32 arithmetic is the composite kernel's, so the same probe gates them), through the\n // module prepareImagePlaneScenes() loaded; created on the first photo.\n let images: DisplayViewImageModules | undefined;\n // A photo reaches the GPU only after the request was resolved, so the module is enabled.\n const imageModules = async (): Promise<DisplayViewImageModules> => images ??= (await imagePlaneSupport()!.loadGpuModule()).createDisplayViewImageModules(runtime, probe) as DisplayViewImageModules;\n let probed: Promise<ChartCompositeProbeRecord> | null = null;\n const wgsl = new Map<ChartCompositeProductPath, string>();\n const probe = (signal: AbortSignal): Promise<ChartCompositeProbeRecord> => {\n probed ??= probeChartCompositeDevice(runtime, pipelines, signal).catch((error: unknown) => { probed = null; throw error; });\n return probed;\n };\n const records = (scene: ReturnType<typeof sceneOf>): UploadedRecords => {\n const index = uploads.findIndex((e) => e.key === scene.key);\n if (index >= 0) { const [entry] = uploads.splice(index, 1); uploads.push(entry!); return entry!; }\n // packChartScene reads the plan's chart, layers and materials only.\n const packed = packChartScene({ chart: scene.chart, layers: scene.layers, materials: scene.materials } as unknown as ChartRadianceBatchPlan);\n if (Math.max(packed.af.byteLength, packed.ai.byteLength) > runtime.maximumStorageBindingBytes) throw new ImageKernelExecutionError(\"insufficient-limits\", \"Chart records exceed the device's storage binding limit.\");\n const scope = new GpuResourceScope(runtime);\n const entry: UploadedRecords = { key: scene.key, scope, af: scope.upload(\"photivra-display-view-chart-floats\", packed.af, BUFFER_USAGE.STORAGE), ai: scope.upload(\"photivra-display-view-chart-records\", packed.ai, BUFFER_USAGE.STORAGE), packed };\n uploads.push(entry);\n while (uploads.length > KEPT_SCENES) uploads.shift()!.scope.release();\n return entry;\n };\n return {\n async moduleFor(gpu, signal): Promise<DisplayViewGpuMaterialModule> {\n if ((gpu.signalInput.scene as { image?: unknown }).image) return await (await imageModules()).moduleFor(gpu, signal);\n const scene = sceneOf(gpu), placement = gpu.placement ?? null, signalInput = gpu.signalInput;\n const tableMaterials = signalInput.scene.kind === \"materials\" ? signalInput.scene.materials.length : -1;\n if (tableMaterials !== scene.materials.length + (placement ? 1 : 0))\n throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The expected signal's materials do not match the scene's (\" + tableMaterials + \" against \" + scene.materials.length + (placement ? \" plus the surround\" : \"\") + \"); use cpu-reference.\");\n if (!scene.layers && !placement && chartGpuPresetCode({ chart: scene.chart } as unknown as ChartRadianceBatchPlan) !== undefined) {\n let module = presets.get(scene.chart);\n if (!module) { module = chartPresetMaterialModule(scene.chart); presets.set(scene.chart, module); }\n return module;\n }\n const record = await probe(signal), path = record.productPath ?? \"dekker\";\n const lattice = displayViewLatticeConstants(signalInput, placement, scene.materials.length), uploaded = records(scene);\n let code = wgsl.get(path);\n if (code === undefined) { code = chartCompositeMaterialWgsl(path); wgsl.set(path, code); }\n return { id: chartCompositeMaterialModuleId(path), wgsl: code, compositeProbe: record, bindings: [\n { binding: 0, kind: \"storage\", buffer: uploaded.af }, { binding: 1, kind: \"storage\", buffer: uploaded.ai },\n { binding: 2, kind: \"uniform\", data: new Uint8Array(lattice.params) }, { binding: 3, kind: \"storage\", data: lattice.offsets }] };\n },\n async imagePasses(gpu, signal): Promise<DisplayViewQualityImagePasses> { return await (await imageModules()).qualityPasses(gpu, signal); },\n get uploadedScenes(): number { return uploads.length; },\n release(): void { for (const entry of uploads.splice(0)) entry.scope.release(); images?.release(); }\n };\n}\n"]}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The image-plane module of the GPU display view (#581): the Speed kernel's `scene_value` (the seam of #478 and #491,
3
+ * `DisplayViewGpuMaterialModule`) for an image-plane print, so that a photo renders on the device like a chart.
4
+ *
5
+ * **What the reference computes** at a query point (expected-signal.ts, the direct path's `signalAt`): the print-local point
6
+ * cu = u·m/h, cv = v·m/h (outside |cu| ≤ 1, |cv| ≤ aspect the surround: its reflectance times the neutral signal N_c); the
7
+ * pixel coordinates X = (cu + 1)·W/2, Y = (aspect − cv)·H/(2·aspect); then the bilinear weights of the four nearest pixel
8
+ * centers (clamped to the edge) times each pixel's channel signal S_j,c = Σ_n A_c(λ_n)·ρ_j(λ_n)·W_n, integrated from the pixel's
9
+ * reconstructed spectrum ρ_j (its cell's eight node spectra blended, then the paper; `ResolvedImagePlaneScene.pixelSignals`), or
10
+ * the nearest pixel's. No per-channel values of the lattice nodes are formed.
11
+ *
12
+ * **On the device.** The host computes every pixel's S_j,c in float64 and rounds it once to float32 (3 values per pixel). When
13
+ * they fit one storage binding they are uploaded once per scene and kept on the device while the renderer lives; otherwise each
14
+ * band of a render builds and uploads only its rows. Either way they are built and written 4 MiB of rows at a time, so the host
15
+ * never holds more than that of S (owner decision 2026-11-09; the bytes are those of the whole array). The module recovers the exact lattice point from the
16
+ * kernel's float32 point as the composite module does (`LATTICE_POINT_WGSL`, about 2⁻⁴⁶ relative), forms cu, cv, X and Y
17
+ * in double-float32 and decides the print's edge in the composite kernel's bound arithmetic (a point within its bound of the
18
+ * edge is flagged: the display pixel is recomputed on the host). Per axis it splits s = X − ½ into its integer part n and
19
+ * fraction f exactly (double-float32), rounds the smaller of f and 1 − f once to float32 and forms the other as 1 minus it, so
20
+ * each weight carries at most 2E relative error (E = 2⁻²³) besides the point's own error. The point's error moves weight
21
+ * between neighbors: with δ the bound of |X_gpu − X_ref| in pixels (4·(2⁻⁴⁰·(|X| + 1)) + 4·10⁻¹⁴·W/2·k: the recovery, the
22
+ * double-float32 steps and the reference's own float64 rounding of its query point, generously), the value moves by at most
23
+ * (δx + δy)·2·max S, and the point is flagged when that exceeds E times the value. So an unflagged value carries a relative
24
+ * error only: S's rounding 1, the weights 2 + 2, the two products and two sums 4, the flag's budget 1, that is 10 roundings
25
+ * beyond the table lookup's one (`extraSiteRoundings`), added to the Speed kernel's chains (docs/WEBGPU.md, "Display view (Speed)").
26
+ * `nearest` takes the pixel under the point, flagging a point within its bound of a pixel edge (`bfloor`). All S are
27
+ * non-negative (non-negative responses, illuminant and spectra), so the weighted sums need no cancellation term.
28
+ *
29
+ * The surround's three channel signals, integrated from its spectrum (its reflectance times the white radiance at each node) like
30
+ * a pixel's, are the kernel's binding 3 (`spectral_table`, which this module does not otherwise use).
31
+ */
32
+ import { type ChartCompositeProbeRecord } from "./image-kernel-execution.js";
33
+ import { type WebGpuRuntime } from "./webgpu-runtime.js";
34
+ import type { ChartCompositeProductPath } from "./wgsl-chart-composite-kernel.js";
35
+ import type { DisplayViewGpuMaterialModule } from "./display-view-speed-gpu.js";
36
+ import { type DisplayViewGpuSetup } from "../facade/display-view.js";
37
+ import type { ImagePlaneSignalScene } from "../facade/scene-radiance.js";
38
+ import { type DisplayViewQualityImagePasses } from "./display-view-quality-gpu.js";
39
+ /** The module's id per product path. */
40
+ export declare function imagePlaneMaterialModuleId(path: ChartCompositeProductPath): string;
41
+ /** Roundings of the module's value beyond the table lookup's one (see the module comment). */
42
+ export declare const IMAGE_PLANE_EXTRA_SITE_ROUNDINGS = 10;
43
+ /** Layout of the photo uniform (float32 / u32 words, 64 bytes). */
44
+ export declare const IMAGE_PLANE_PARAMS: Readonly<{
45
+ width: 0;
46
+ height: 1;
47
+ nearest: 2;
48
+ row0: 3;
49
+ halfWHi: 4;
50
+ halfWLo: 5;
51
+ halfHHi: 6;
52
+ halfHLo: 7;
53
+ aspectHi: 8;
54
+ aspectLo: 9;
55
+ slackX: 10;
56
+ slackY: 11;
57
+ words: 16;
58
+ }>;
59
+ /** The module's WGSL with one product path (see the module comment). */
60
+ export declare function imagePlaneMaterialWgsl(path?: ChartCompositeProductPath): string;
61
+ /** The image-plane print behind a GPU setup's expected signal (`ImagePlaneSignalScene.image`), or undefined. */
62
+ export declare function imagePlaneOf(gpu: DisplayViewGpuSetup): ImagePlaneSignalScene["image"] | undefined;
63
+ /** The image-plane modules of one display-view renderer: `moduleFor` builds the setup's module (its uploads kept), `release` frees them. */
64
+ export interface DisplayViewImageModules {
65
+ /** The setup's module; the first call on a runtime runs the module's self-check (`runImagePlaneConformance`) and refuses the device if it fails. */
66
+ moduleFor(gpu: DisplayViewGpuSetup, signal: AbortSignal): Promise<DisplayViewGpuMaterialModule>;
67
+ /** The setup's module without the self-check (the self-check itself uses it). */
68
+ build(gpu: DisplayViewGpuSetup, path: ChartCompositeProductPath): DisplayViewGpuMaterialModule;
69
+ /** #581: the print's Quality passes 1 and 2 (src/gpu/display-view-image-quality.ts), after the same self-check. */
70
+ qualityPasses(gpu: DisplayViewGpuSetup, signal: AbortSignal): Promise<DisplayViewQualityImagePasses>;
71
+ release(): void;
72
+ }
73
+ /**
74
+ * The image-plane modules of a renderer; `probe` is the composite module's device probe (single flight), whose double-word product
75
+ * path the module's double-float32 takes.
76
+ */
77
+ export declare function createDisplayViewImageModules(runtime: WebGpuRuntime, probe: (signal: AbortSignal) => Promise<ChartCompositeProbeRecord>): DisplayViewImageModules;
78
+ /**
79
+ * #581's run-time self-check of the module, run on a device's first photo: a 12 × 8 photo (a color ramp with hard edges, every
80
+ * lattice cell's corner colors among its pixels) printed at 0.8 of the frame's width on the 18 % surround of a 38 × 26 frame shown
81
+ * at 13 × 9, the GPU against `renderDisplayView` within the a-priori bounds, every flagged pixel recomputed: the Speed kernel with
82
+ * the 2 × 2 box, then the Quality passes with the four-spot filter's 16 offsets and synthetic radius-1 kernels at three nodes.
83
+ * A device that fails the double-float32 probe refuses photos (unsupported-on-backend, as composite charts), so the check passes
84
+ * there without keeping the device's charts off the GPU.
85
+ */
86
+ export declare function runImagePlaneConformance(handle: unknown, signal: AbortSignal | undefined): Promise<true | string>;