@photivra/engine 2.20.0 → 2.22.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.
- package/CHANGELOG.md +295 -1
- package/CITATION.cff +1 -1
- package/README.md +7 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +18 -0
- package/dist/capture/c2pa-embed.d.ts +116 -0
- package/dist/capture/c2pa-embed.js +493 -0
- package/dist/capture/c2pa-embed.js.map +1 -0
- package/dist/capture/dng-import.d.ts +73 -8
- package/dist/capture/dng-import.js +315 -80
- package/dist/capture/dng-import.js.map +1 -1
- package/dist/capture/dng-lens-correction-opcodes.d.ts +2 -2
- package/dist/capture/dng-lens-correction-opcodes.js +2 -2
- package/dist/capture/dng-lens-correction-opcodes.js.map +1 -1
- package/dist/capture/dng-opcodes.d.ts +96 -0
- package/dist/capture/dng-opcodes.js +391 -0
- package/dist/capture/dng-opcodes.js.map +1 -0
- package/dist/capture/dng-profile-maps.d.ts +99 -0
- package/dist/capture/dng-profile-maps.js +381 -0
- package/dist/capture/dng-profile-maps.js.map +1 -0
- package/dist/capture/dng-stage-image.d.ts +23 -0
- package/dist/capture/dng-stage-image.js +65 -0
- package/dist/capture/dng-stage-image.js.map +1 -0
- package/dist/capture/exposure-build-up-stage.d.ts +16 -0
- package/dist/capture/exposure-build-up-stage.js +4 -0
- package/dist/capture/exposure-build-up-stage.js.map +1 -0
- package/dist/capture/jpeg-xl-tiles.d.ts +22 -0
- package/dist/capture/jpeg-xl-tiles.js +151 -0
- package/dist/capture/jpeg-xl-tiles.js.map +1 -0
- package/dist/capture/lossy-jpeg.d.ts +17 -0
- package/dist/capture/lossy-jpeg.js +369 -0
- package/dist/capture/lossy-jpeg.js.map +1 -0
- package/dist/capture/native-environment-lean.d.ts +2 -1
- package/dist/capture/native-environment-lean.js +41 -73
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-tabulated.js +4 -3
- package/dist/capture/native-environment-tabulated.js.map +1 -1
- package/dist/capture/native-raw-development.d.ts +2 -1
- package/dist/capture/native-raw-development.js.map +1 -1
- package/dist/capture/native-raw.d.ts +3 -2
- package/dist/capture/native-raw.js +5 -4
- package/dist/capture/native-raw.js.map +1 -1
- package/dist/capture/sensor-raw-producer.d.ts +4 -1
- package/dist/capture/sensor-raw-producer.js +12 -3
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/color/neighbor-highlight-reconstruction.d.ts +66 -0
- package/dist/color/neighbor-highlight-reconstruction.js +234 -0
- package/dist/color/neighbor-highlight-reconstruction.js.map +1 -0
- package/dist/color/sensor-color-development.d.ts +5 -0
- package/dist/color/sensor-color-development.js +7 -1
- package/dist/color/sensor-color-development.js.map +1 -1
- package/dist/color/spectral-spikiness.d.ts +11 -0
- package/dist/color/spectral-spikiness.js +23 -0
- package/dist/color/spectral-spikiness.js.map +1 -0
- package/dist/core/execution-error.d.ts +21 -0
- package/dist/core/execution-error.js +12 -0
- package/dist/core/execution-error.js.map +1 -0
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/equipment/generic-lens-catalogue.d.ts +3 -2
- package/dist/equipment/generic-lens-catalogue.js +18 -5
- package/dist/equipment/generic-lens-catalogue.js.map +1 -1
- package/dist/equipment/generic-tier-assets.d.ts +32 -0
- package/dist/equipment/generic-tier-assets.js +16 -11
- package/dist/equipment/generic-tier-assets.js.map +1 -1
- package/dist/equipment/sensor-profile-body.d.ts +78 -0
- package/dist/equipment/sensor-profile-body.js +77 -0
- package/dist/equipment/sensor-profile-body.js.map +1 -0
- package/dist/equipment/sensor-profiles.d.ts +8 -0
- package/dist/equipment/sensor-profiles.js +82 -0
- package/dist/equipment/sensor-profiles.js.map +1 -0
- package/dist/facade/catalogue-lens-signal.d.ts +28 -3
- package/dist/facade/catalogue-lens-signal.js +83 -78
- package/dist/facade/catalogue-lens-signal.js.map +1 -1
- package/dist/facade/chart-radiance-batch.js +2 -1
- package/dist/facade/chart-radiance-batch.js.map +1 -1
- package/dist/facade/defocus-image-space-provider.d.ts +7 -0
- package/dist/facade/defocus-image-space-provider.js +64 -76
- package/dist/facade/defocus-image-space-provider.js.map +1 -1
- package/dist/facade/diffraction-provider.d.ts +1 -1
- package/dist/facade/diffraction-provider.js +4 -4
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view-gpu-session.js +39 -5
- package/dist/facade/display-view-gpu-session.js.map +1 -1
- package/dist/facade/display-view-gpu.d.ts +19 -6
- package/dist/facade/display-view-gpu.js.map +1 -1
- package/dist/facade/display-view-lens-signal.js +25 -23
- package/dist/facade/display-view-lens-signal.js.map +1 -1
- package/dist/facade/display-view-normal.d.ts +15 -0
- package/dist/facade/display-view-normal.js +44 -0
- package/dist/facade/display-view-normal.js.map +1 -0
- package/dist/facade/display-view-rendering.d.ts +97 -0
- package/dist/facade/display-view-rendering.js +598 -0
- package/dist/facade/display-view-rendering.js.map +1 -0
- package/dist/facade/display-view.d.ts +37 -65
- package/dist/facade/display-view.js +152 -499
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/expected-signal-setup.d.ts +3 -1
- package/dist/facade/expected-signal-setup.js +3 -3
- package/dist/facade/expected-signal-setup.js.map +1 -1
- package/dist/facade/expected-signal.d.ts +47 -14
- package/dist/facade/expected-signal.js +117 -112
- package/dist/facade/expected-signal.js.map +1 -1
- package/dist/facade/exposure-build-up.d.ts +70 -0
- package/dist/facade/exposure-build-up.js +164 -0
- package/dist/facade/exposure-build-up.js.map +1 -0
- package/dist/facade/fast-methods.d.ts +1 -1
- package/dist/facade/fast-methods.js +46 -9
- package/dist/facade/fast-methods.js.map +1 -1
- package/dist/facade/generic-lens-capture.d.ts +3 -3
- package/dist/facade/generic-lens-capture.js +3 -3
- package/dist/facade/generic-lens-capture.js.map +1 -1
- package/dist/facade/image-plane-enable.d.ts +7 -0
- package/dist/facade/image-plane-enable.js +17 -0
- package/dist/facade/image-plane-enable.js.map +1 -0
- package/dist/facade/image-plane-lattice-data.d.ts +6 -0
- package/dist/facade/image-plane-lattice-data.js +10 -0
- package/dist/facade/image-plane-lattice-data.js.map +1 -0
- package/dist/facade/image-plane-support.d.ts +33 -0
- package/dist/facade/image-plane-support.js +11 -0
- package/dist/facade/image-plane-support.js.map +1 -0
- package/dist/facade/image-plane.d.ts +36 -0
- package/dist/facade/image-plane.js +384 -0
- package/dist/facade/image-plane.js.map +1 -0
- package/dist/facade/mixed-illumination.d.ts +108 -0
- package/dist/facade/mixed-illumination.js +174 -0
- package/dist/facade/mixed-illumination.js.map +1 -0
- package/dist/facade/on-demand-kits.d.ts +14 -0
- package/dist/facade/on-demand-kits.js +36 -0
- package/dist/facade/on-demand-kits.js.map +1 -0
- package/dist/facade/opt-in-kit.d.ts +9 -0
- package/dist/facade/opt-in-kit.js +11 -0
- package/dist/facade/opt-in-kit.js.map +1 -0
- package/dist/facade/quality-kit.d.ts +21 -0
- package/dist/facade/quality-kit.js +23 -0
- package/dist/facade/quality-kit.js.map +1 -0
- package/dist/facade/quality-paths.d.ts +22 -0
- package/dist/facade/quality-paths.js +44 -0
- package/dist/facade/quality-paths.js.map +1 -0
- package/dist/facade/representative-light-sources.d.ts +72 -0
- package/dist/facade/representative-light-sources.js +124 -0
- package/dist/facade/representative-light-sources.js.map +1 -0
- package/dist/facade/scene-radiance.d.ts +145 -4
- package/dist/facade/scene-radiance.js +50 -13
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +68 -20
- package/dist/facade/simulate-capture.js +399 -146
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +10 -12
- package/dist/facade/simulate-display-view.js +70 -53
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/chart-composite-gpu.d.ts +13 -1
- package/dist/gpu/chart-composite-gpu.js +48 -9
- package/dist/gpu/chart-composite-gpu.js.map +1 -1
- package/dist/gpu/chart-radiance-gpu.js +4 -30
- package/dist/gpu/chart-radiance-gpu.js.map +1 -1
- package/dist/gpu/display-view-composite-material-module.d.ts +10 -4
- package/dist/gpu/display-view-composite-material-module.js +39 -13
- package/dist/gpu/display-view-composite-material-module.js.map +1 -1
- package/dist/gpu/display-view-gpu-renderer.d.ts +43 -0
- package/dist/gpu/display-view-gpu-renderer.js +134 -0
- package/dist/gpu/display-view-gpu-renderer.js.map +1 -0
- package/dist/gpu/display-view-image-material-module.d.ts +87 -0
- package/dist/gpu/display-view-image-material-module.js +361 -0
- package/dist/gpu/display-view-image-material-module.js.map +1 -0
- package/dist/gpu/display-view-image-quality.d.ts +87 -0
- package/dist/gpu/display-view-image-quality.js +625 -0
- package/dist/gpu/display-view-image-quality.js.map +1 -0
- package/dist/gpu/display-view-quality-gpu.d.ts +80 -65
- package/dist/gpu/display-view-quality-gpu.js +187 -445
- package/dist/gpu/display-view-quality-gpu.js.map +1 -1
- package/dist/gpu/display-view-speed-gpu.d.ts +67 -19
- package/dist/gpu/display-view-speed-gpu.js +181 -105
- package/dist/gpu/display-view-speed-gpu.js.map +1 -1
- package/dist/gpu/image-kernel-accelerator.js +3 -0
- package/dist/gpu/image-kernel-accelerator.js.map +1 -1
- package/dist/gpu/image-kernel-execution.d.ts +2 -13
- package/dist/gpu/image-kernel-execution.js +2 -10
- package/dist/gpu/image-kernel-execution.js.map +1 -1
- package/dist/gpu/wgsl-display-view-coupled-stub.d.ts +8 -0
- package/dist/gpu/wgsl-display-view-coupled-stub.js +21 -0
- package/dist/gpu/wgsl-display-view-coupled-stub.js.map +1 -0
- package/dist/gpu/wgsl-display-view-coupled.d.ts +88 -0
- package/dist/gpu/wgsl-display-view-coupled.js +353 -0
- package/dist/gpu/wgsl-display-view-coupled.js.map +1 -0
- package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +33 -24
- package/dist/gpu/wgsl-display-view-quality-kernel.js +166 -146
- package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
- package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +19 -44
- package/dist/gpu/wgsl-display-view-speed-kernel.js +116 -18
- package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
- package/dist/gpu/wgsl-exact-sum.d.ts +20 -0
- package/dist/gpu/wgsl-exact-sum.js +42 -0
- package/dist/gpu/wgsl-exact-sum.js.map +1 -0
- package/dist/index.d.ts +22 -6
- package/dist/index.js +16 -2
- package/dist/index.js.map +1 -1
- package/dist/motion/subject-motion.d.ts +66 -0
- package/dist/motion/subject-motion.js +52 -0
- package/dist/motion/subject-motion.js.map +1 -0
- package/dist/optics/generic-lens-lateral-color.d.ts +83 -0
- package/dist/optics/generic-lens-lateral-color.js +77 -0
- package/dist/optics/generic-lens-lateral-color.js.map +1 -0
- package/dist/optics/generic-lens-psf.js +54 -46
- package/dist/optics/generic-lens-psf.js.map +1 -1
- package/dist/optics/lens-psf-profile.d.ts +7 -0
- package/dist/optics/lens-psf-profile.js +2 -1
- package/dist/optics/lens-psf-profile.js.map +1 -1
- package/dist/output/camera-channel-response.d.ts +50 -0
- package/dist/output/camera-channel-response.js +69 -0
- package/dist/output/camera-channel-response.js.map +1 -0
- package/dist/output/developed-lens-corrections.d.ts +19 -5
- package/dist/output/developed-lens-corrections.js +28 -9
- package/dist/output/developed-lens-corrections.js.map +1 -1
- package/dist/output/generic-lens-corrections.d.ts +41 -5
- package/dist/output/generic-lens-corrections.js +52 -8
- package/dist/output/generic-lens-corrections.js.map +1 -1
- package/dist/output/native-capture-sdr.js +5 -2
- package/dist/output/native-capture-sdr.js.map +1 -1
- package/dist/output/print-plan.d.ts +41 -5
- package/dist/output/print-plan.js +59 -14
- package/dist/output/print-plan.js.map +1 -1
- package/dist/output/sdr-rendering.d.ts +18 -1
- package/dist/output/sdr-rendering.js +39 -2
- package/dist/output/sdr-rendering.js.map +1 -1
- package/dist/sensor/binomial-sample.d.ts +3 -0
- package/dist/sensor/binomial-sample.js +86 -0
- package/dist/sensor/binomial-sample.js.map +1 -0
- package/dist/sensor/native-sensor-report.d.ts +10 -0
- package/dist/sensor/native-sensor-report.js +16 -0
- package/dist/sensor/native-sensor-report.js.map +1 -0
- package/dist/sensor/sensor-characteristics.d.ts +91 -13
- package/dist/sensor/sensor-characteristics.js +30 -15
- package/dist/sensor/sensor-characteristics.js.map +1 -1
- package/docs/AGENT_GUIDE.md +1 -0
- package/docs/API_REFERENCE.md +214 -4
- package/docs/QUICK_START.md +162 -8
- package/docs/USAGE.md +195 -22
- package/docs/api/capture-c2pa-embed.md +177 -0
- package/docs/api/capture-dng-import.md +86 -10
- package/docs/api/capture-dng-opcodes.md +93 -0
- package/docs/api/capture-dng-profile-maps.md +141 -0
- package/docs/api/capture-dng-stage-image.md +43 -0
- package/docs/api/capture-jpeg-xl-tiles.md +33 -0
- package/docs/api/capture-lossy-jpeg.md +41 -0
- package/docs/api/capture-native-raw-development.md +2 -1
- package/docs/api/core-execution-error.md +43 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/equipment-generic-lens-catalogue.md +10 -5
- package/docs/api/equipment-sensor-profile-body.md +64 -0
- package/docs/api/equipment-sensor-profiles.md +86 -0
- package/docs/api/exports.json +460 -5
- package/docs/api/facade-display-view-gpu.md +5 -2
- package/docs/api/facade-display-view.md +11 -15
- package/docs/api/facade-exposure-build-up.md +105 -0
- package/docs/api/facade-fast-methods.md +47 -10
- package/docs/api/facade-image-plane-enable.md +16 -0
- package/docs/api/facade-mixed-illumination.md +67 -0
- package/docs/api/facade-quality-paths.md +24 -0
- package/docs/api/facade-representative-light-sources.md +131 -0
- package/docs/api/facade-scene-radiance.md +54 -3
- package/docs/api/facade-simulate-capture.md +48 -11
- package/docs/api/facade-simulate-display-view.md +10 -12
- package/docs/api/gpu-image-kernel-execution.md +0 -36
- package/docs/api/motion-subject-motion.md +23 -0
- package/docs/api/optics-generic-lens-lateral-color.md +79 -0
- package/docs/api/output-camera-channel-response.md +55 -0
- package/docs/api/output-developed-lens-corrections.md +10 -1
- package/docs/api/output-generic-lens-corrections.md +40 -4
- package/docs/api/output-print-plan.md +35 -1
- package/docs/api/output-sdr-rendering.md +6 -1
- package/docs/api/sensor-sensor-characteristics.md +54 -2
- package/llms.txt +3 -0
- package/package.json +6 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display-view-image-quality.js","sourceRoot":"","sources":["../../src/gpu/display-view-image-quality.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * The image-plane print in the GPU display view's Quality passes (#581): diffraction kernels, the defocus disc, the anti-aliasing\n * filter's spots and AHD for a photo, loaded with the image-plane GPU module (only after `prepareImagePlaneScenes()`). Passes 1\n * and 2 are the print's own; pass 3 (the display pixels) and the host finishing are the Quality renderer's, unchanged.\n *\n * **What the reference computes** (expected-signal.ts, the radiance path): with site kernels, per site of channel c,\n * Σ_g Σ_d Σ_n C_n,c(d)·L_n(p_g + d), where L_n(p) is the print's spectral radiance at spectral node n at lattice point p (the\n * provider's `radianceAt` on the lattice formula) and C_n,c(d) the reference's combined kernel per node (`perNode` of its\n * tables: Σ_members w·A_c(λ_n)·K_n(t)); without kernels, per query offset w·Σ_n A_c(λ_n)·L_n(p_o), the same value as the direct\n * path's `signalAt`.\n *\n * **Pass 1 (lattice radiance).** One invocation per lattice point of each group: the exact point (p + c)·g in double-float32\n * (p + c is exact in float32, checked by the Quality host; the scale's hi + lo from float64), the print-local point, the print's\n * edge in the composite kernel's bound arithmetic, the pixel coordinates, the bilinear weights as the Speed module forms them,\n * and for every node n\n *\n * L_n = W_n·Σ_j b_j·(ρ_black + (ρ_white − ρ_black)·Σ_corners w_jk·s_k(λ_n)),\n *\n * the reference's arithmetic regrouped. Each pixel's lattice cell and fractions come from the host (float64, as the reference\n * decodes the pixel), per band for the rows its lattice windows reach: 16 bytes per pixel (the cell, and per channel the smaller\n * of f and 1 − f rounded once, with a bit for which), so every corner weight carries at most 2E relative per channel. All terms\n * are non-negative: L_n carries `IMAGE_PLANE_LATTICE_U`·E relative (s 1, three channel weights 6, the nested trilinear form 6,\n * the paper 3, the bilinear weights 4, their products and sums 4, the moved-weight budget 1, W_n 2: 27, declared 32), or the\n * point is flagged: on the print's edge, near a nearest-pixel edge, or where a bilinear weight moved by the point's error could\n * change the value by more than E of it (the Speed module's rule, per node).\n *\n * **Mixed light (#597).** Under `illumination` W_n is replaced by the irradiance / π at the point, E_n(p) = Σ_i w_i(p)·T_i,n +\n * Σ_j c_j,n·h_j/d_j³ (src/facade/mixed-illumination.ts), from the light table (`imagePlaneLightTable`: the parts and the spectra at\n * the nodes, no channel value). The blend's position t is formed in double-float32 with te, its error beyond its own low part; each\n * weight comes from its own distance to the segment's ends (rounded once: E relative, plus te times the segment's slope); a regions\n * edge, or a hard edge of equal stops, within the point's bound flags it; a choice of the neighbouring segment moves the weights by\n * at most te times the steepest slope; each point source's h/d³ is a bounded value (B arithmetic). The node value's computed bound\n * (the tables' rounding, the weights, the products and the sums) must stay within (IMAGE_PLANE_LIGHT_U − 1)·E of it, else the point\n * is flagged, so a lit point carries (IMAGE_PLANE_LATTICE_U + IMAGE_PLANE_LIGHT_U)·E relative.\n *\n * **Flagged points.** With site kernels the reference evaluates the lattice formula itself, so the host replaces a flagged\n * point's values with the reference's own `radianceAt` there and clears its flag (as #492 resolves uncertain chart materials).\n * Without kernels the reference reads the environment's own query points, so a site that reads a flagged point (with a nonzero\n * weight) is flagged and its display pixels are recomputed on the host.\n *\n * **Pass 2 (sites).** The blocked sum (#492's order) of Σ_n L_n·C_n,c(t) over each group's dense tap rectangle (without kernels the\n * members' span, zero where no member sits): a term carries L's bound, the table's rounding and the product, the node sum's N − 1,\n * and the row, group and total additions, so the electrons carry (IMAGE_PLANE_LATTICE_U + N + cw + ch + G + 4)·E relative.\n * Then the Quality site tail (readout moments, white clip, running bounds), unchanged.\n */\n\nimport { ImageKernelExecutionError, WEBGPU_F32_UNIT_ROUNDOFF } from \"./image-kernel-execution.js\";\nimport { BUFFER_USAGE, linearDispatch, runComputePass, type GpuResourceScope, type WebGpuRuntime } from \"./webgpu-runtime.js\";\nimport { dwSplit } from \"./chart-composite-gpu.js\";\nimport type { ChartCompositeProductPath } from \"./wgsl-chart-composite-kernel.js\";\nimport { displayViewModuleCommonWgsl } from \"./display-view-composite-material-module.js\";\nimport { DISPLAY_VIEW_QUALITY_COMMON_WGSL, DISPLAY_VIEW_QUALITY_GROUP_WORDS, DISPLAY_VIEW_QUALITY_SITE_TAIL_WGSL, DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE } from \"./wgsl-display-view-quality-kernel.js\";\nimport { latticeCoordinate, type DisplayViewQualityImagePasses, type SignalGather } from \"./display-view-quality-gpu.js\";\nimport { queryGeometry } from \"./display-view-speed-gpu.js\";\nimport { displayViewSignalTables, type DisplayViewExpectedSignalInput } from \"../facade/expected-signal.js\";\nimport type { DisplayViewGpuSetup } from \"../facade/display-view.js\";\nimport { calculateIlluminantIrradianceScale, type ImagePlaneSignalScene } from \"../facade/scene-radiance.js\";\n\nconst E = 2 * WEBGPU_F32_UNIT_ROUNDOFF;\n/** Relative roundings of a lattice point's radiance (see the module comment). */\nexport const IMAGE_PLANE_LATTICE_U = 32;\n/**\n * #597: relative roundings of the mixed light at a lattice point (a point whose computed bound exceeds IMAGE_PLANE_LIGHT_U − 1 is\n * flagged; see the module comment), added to IMAGE_PLANE_LATTICE_U for a lit print.\n */\nexport const IMAGE_PLANE_LIGHT_U = 40;\n/** #597: layout of the light table (float32 / u32 words; see `imagePlaneLightTable`). */\nexport const IMAGE_PLANE_LIGHT = /* @__PURE__ */ Object.freeze({ kind: 0, sources: 1, points: 2, regions: 3, outside: 4, regionsAt: 6, pointsAt: 7, tablesAt: 8, slack: 9,\n surround: 10, maximumInverse: 11, halfHi: 12, halfLo: 13, aU: 16, aV: 18, dU: 20, dV: 22, inverse: 24, stops: 26, regionWords: 9, pointWords: 6, maximumPoints: 8 });\n/** Lattice nodes of the print (5 × 5 × 5). */\nconst NODES = 125;\n/** Words per pixel record. */\nconst RECORD_WORDS = 4;\n/** Layout of the photo uniform (u32 / float32 words, 96 bytes). */\nexport const IMAGE_PLANE_QUALITY_PARAMS = /* @__PURE__ */ Object.freeze({ width: 0, height: 1, nearest: 2, nodes: 3, row0: 4, zero: 5, lit: 6, suHi: 8, suLo: 9, svHi: 10, svLo: 11,\n kHi: 12, kLo: 13, halfWHi: 14, halfWLo: 15, halfHHi: 16, halfHLo: 17, aspectHi: 18, aspectLo: 19, slackX: 20, slackY: 21, black: 22, span: 23, words: 24 });\nconst FLOAT32_SAFE_MAGNITUDE = 2 ** 120, FLOAT32_MINIMUM_NORMAL = 2 ** -126;\n\nconst L = IMAGE_PLANE_LIGHT;\n/**\n * #597: the mixed light at a lattice point (see the module comment): `light_prepare` once per point (the blend's source and weights\n * with their error bound, and each point source's h/d³ as a bounded value), then `light_at(n)` per node, flagging the point when the\n * computed bound exceeds (IMAGE_PLANE_LIGHT_U − 1)·E of the value.\n */\nconst LIGHT_WGSL = /* wgsl */ `\nvar<private> blend_i: u32;\nvar<private> blend_w0: f32;\nvar<private> blend_w1: f32;\nvar<private> blend_e0: f32;\nvar<private> blend_e1: f32;\nvar<private> blend_amb: f32;\nvar<private> fall_v: array<f32, ${L.maximumPoints}>;\nvar<private> fall_e: array<f32, ${L.maximumPoints}>;\nfn lw(i: u32) -> u32 { return bitcast<u32>(light[i]); }\nfn ld(i: u32) -> D { return D(light[i], light[i + 1u]); }\n// a > b for double-float32 values.\nfn d_gt(a: D, b: D) -> bool { let d = d_sub(a, b); return d.h > 0.0 || (d.h == 0.0 && d.l > 0.0); }\n// sqrt of a bounded value: |√x − √x̃| ≤ e / (2√(v − e)), and WGSL's sqrt within 5E (inherited from 1 / inverseSqrt).\nfn bsqrt(a: B) -> B {\n let v = sqrt(max(a.v, 0.0));\n let low = a.v - SAFETY * a.e;\n if (!(low > 0.0)) { material_uncertain = true; return B(v, 3.0e38); }\n return B(v, a.e / (2.0 * sqrt(low)) + 5.0 * E * v);\n}\nfn light_prepare(u: D, v: D) {\n let kind = lw(${L.kind}u);\n let S = lw(${L.sources}u);\n blend_i = 0u; blend_w0 = 1.0; blend_w1 = 0.0; blend_e0 = 0.0; blend_e1 = 0.0; blend_amb = 0.0;\n // A point's error beyond its double-float32 arithmetic: the recovery and the reference's own rounding (the host's slack).\n let ce = 4.0 * DW * (abs(u.h) + abs(v.h) + 1.0) + light[${L.slack}u];\n if (kind == 3u) {\n var source = lw(${L.outside}u);\n let bu = bd(u);\n let bv = bd(v);\n for (var r = 0u; r < lw(${L.regions}u); r = r + 1u) {\n let b = lw(${L.regionsAt}u) + r * ${L.regionWords}u;\n if (ge(bu, bd(ld(b + 1u))) && le(bu, bd(ld(b + 3u))) && ge(bv, bd(ld(b + 5u))) && le(bv, bd(ld(b + 7u)))) { source = lw(b); break; }\n }\n blend_i = source;\n } else if (kind != 0u) {\n // t in double-float32 and te, its error bound beyond its own low part (the arithmetic and the point's error).\n var t: D;\n var te: f32;\n let a_u = d_sub(u, ld(${L.aU}u));\n let a_v = d_sub(v, ld(${L.aV}u));\n let inv = ld(${L.inverse}u);\n let ce_t = ce + 4.0 * DW * (abs(light[${L.aU}u]) + abs(light[${L.aV}u]));\n if (kind == 1u) {\n let x = d_mul(a_u, ld(${L.dU}u));\n let y = d_mul(a_v, ld(${L.dV}u));\n let scale = (abs(x.h) + abs(y.h)) * abs(inv.h);\n t = d_mul(d_add(x, y), inv);\n te = 8.0 * DW * (scale + 1.0) + ce_t * (abs(light[${L.dU}u]) + abs(light[${L.dV}u])) * abs(inv.h);\n if (t.h < 0.0) { t = D(0.0, 0.0); }\n if (d_gt(t, D(1.0, 0.0))) { t = D(1.0, 0.0); }\n } else {\n // The distance in double-float32: the float32 root and one Newton step.\n let dd = d_add(d_mul(a_u, a_u), d_mul(a_v, a_v));\n let r0 = sqrt(max(dd.h, 0.0));\n var r = D(r0, 0.0);\n if (r0 > 0.0) { let res = d_sub(dd, d_mul(D(r0, 0.0), D(r0, 0.0))); r = quick_two_sum(r0, ob(ob(res.h + res.l) / ob(2.0 * r0))); }\n t = d_mul(r, inv);\n te = 8.0 * DW * (abs(t.h) + 1.0) + 2.0 * ce_t * abs(inv.h);\n if (d_gt(t, D(1.0, 0.0))) { t = D(1.0, 0.0); }\n }\n // The segment [s_i, s_i+1) that holds t (the reference's order); a hard edge (equal stops) within the bound of t flags the point.\n var i = 0u;\n loop { if (i + 1u >= S) { break; } if (d_gt(ld(${L.stops}u + (i + 1u) * 4u), t)) { break; } i = i + 1u; }\n for (var k = 0u; k + 1u < S; k = k + 1u) {\n if (light[${L.stops}u + k * 4u + 2u] == 0.0 && abs(d_sub(t, ld(${L.stops}u + k * 4u)).h) <= SAFETY * te + DW * (abs(t.h) + 1.0)) { material_uncertain = true; }\n }\n let si = ld(${L.stops}u + i * 4u);\n // A neighbouring segment's choice moves the weights by at most t's bound times the steepest segment's slope.\n blend_amb = te * light[${L.maximumInverse}u];\n if (i + 1u < S && d_gt(t, si)) {\n // Each weight from its own distance to the segment's ends (double-float32, rounded once), so a small weight keeps a small relative error.\n let inv_i = ld(${L.stops}u + i * 4u + 2u);\n let fd = d_mul(d_sub(t, si), inv_i);\n let gd = d_mul(d_sub(ld(${L.stops}u + (i + 1u) * 4u), t), inv_i);\n blend_w1 = clamp(ob(fd.h + fd.l), 0.0, 1.0);\n blend_w0 = clamp(ob(gd.h + gd.l), 0.0, 1.0);\n let shared_e = (te + 4.0 * DW * (abs(t.h) + abs(si.h) + 1.0)) * abs(inv_i.h);\n blend_e1 = E * blend_w1 + shared_e;\n blend_e0 = E * blend_w0 + shared_e;\n }\n blend_i = i;\n }\n // Point sources: h/d³ at the point in metres (print-local × the print's half width), as bounded values.\n let half = ld(${L.halfHi}u);\n let x = d_mul(u, half);\n let y = d_mul(v, half);\n let cm = ce * abs(half.h) + 4.0 * DW * (abs(x.h) + abs(y.h));\n for (var j = 0u; j < lw(${L.points}u); j = j + 1u) {\n let b = lw(${L.pointsAt}u) + j * ${L.pointWords}u;\n var dx = bds(d_sub(x, ld(b)), abs(x.h) + abs(light[b]));\n dx.e = dx.e + cm;\n var dy = bds(d_sub(y, ld(b + 2u)), abs(y.h) + abs(light[b + 2u]));\n dy.e = dy.e + cm;\n let h = bd(ld(b + 4u));\n let d2 = badd(badd(bmul(dx, dx), bmul(dy, dy)), bmul(h, h));\n let fall = bdiv(h, bmul(d2, bsqrt(d2)));\n fall_v[j] = fall.v;\n fall_e[j] = fall.e;\n }\n}\n// The irradiance / π at node n of the prepared point: the blend's sources and the point sources from their spectra at the nodes.\nfn light_at(n: u32) -> f32 {\n let N = photo.nodes;\n let S = lw(${L.sources}u);\n let P = lw(${L.points}u);\n let tab = lw(${L.tablesAt}u);\n var value = 0.0;\n var err = 0.0;\n if (S > 0u) {\n let ti = light[tab + blend_i * N + n];\n var top = ti;\n for (var s = 0u; s < S; s = s + 1u) { top = max(top, light[tab + s * N + n]); }\n var tj = 0.0;\n if (blend_w1 == 0.0) { value = ti; } else { tj = light[tab + (blend_i + 1u) * N + n]; value = blend_w0 * ti + blend_w1 * tj; }\n err = 3.0 * E * value + blend_e0 * ti + blend_e1 * tj + blend_amb * top;\n }\n for (var j = 0u; j < P; j = j + 1u) {\n let c = light[tab + (S + j) * N + n];\n let term = c * fall_v[j];\n value = value + term;\n err = err + c * fall_e[j] + 2.0 * E * term;\n }\n err = err + f32(P + 1u) * E * value;\n if (!(err <= ${IMAGE_PLANE_LIGHT_U - 1}.0 * E * value)) { material_uncertain = true; }\n return value;\n}\n`;\n\n/**\n * #597: the light table of a lit print at the spectral nodes (the layout `IMAGE_PLANE_LIGHT`): the blend (kind, sources, its geometry\n * and stops with each segment's inverse width, 0 at a hard edge), the regions, the point sources (x, y, h in metres), then per node\n * T_i,n = k_i·S_i(λ_n)/π for each blend source and c_j·S_j(λ_n)/π for each point source: spectra only, no channel value. `slack` is the\n * reference's own rounding of a query point in print-local units.\n */\nexport function imagePlaneLightTable(light: NonNullable<ImagePlaneSignalScene[\"image\"][\"light\"]>, wavelengths: readonly number[], surroundReflectance: number, slack: number):\n { table: Float32Array<ArrayBuffer>; largestIrradiance: number } {\n const resolved = light.layout;\n if (!resolved) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The print's mixed light carries no parts for the GPU; use cpu-reference.\");\n // The blend's sources come first, then the point sources (their report carries the position and the intensity, c = I·k(1 lux)).\n const blend = resolved.blend as { kind: string; from?: { u: number; v: number }; to?: { u: number; v: number }; center?: { u: number; v: number }; radius?: number;\n regions?: readonly { source: number; uMin: number; uMax: number; vMin: number; vMax: number }[]; outsideSource?: number; stops?: readonly number[] } | null;\n const sources = resolved.sources.filter((s) => s.report.position === undefined), points = resolved.sources.filter((s) => s.report.position !== undefined).map((s) => {\n const position = s.report.position as { xM: number; yM: number; heightM: number };\n return { ...position, scale: calculateIlluminantIrradianceScale(s.illuminant.shape, 1) * (s.report.intensityCandela as number), shape: s.illuminant.shape };\n });\n const S = sources.length, P = points.length, N = wavelengths.length, regions = blend?.regions ?? [];\n if (P > L.maximumPoints) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"More point sources than the GPU pass holds.\");\n const regionsAt = L.stops + 4 * S, pointsAt = regionsAt + L.regionWords * regions.length, tablesAt = pointsAt + L.pointWords * P;\n const table = new Float32Array(tablesAt + (S + P) * N), words = new Uint32Array(table.buffer);\n const pair = (at: number, x: number): void => { [table[at], table[at + 1]] = dwSplit(x); };\n words[L.kind] = blend === null ? 0 : blend.kind === \"linear-gradient\" ? 1 : blend.kind === \"radial\" ? 2 : 3;\n words[L.sources] = S; words[L.points] = P; words[L.regions] = regions.length; words[L.outside] = blend?.outsideSource ?? 0;\n words[L.regionsAt] = regionsAt; words[L.pointsAt] = pointsAt; words[L.tablesAt] = tablesAt;\n table[L.slack] = slack; table[L.surround] = surroundReflectance;\n pair(L.halfHi, light.halfWidthM);\n if (blend?.kind === \"linear-gradient\") {\n const from = blend.from!, du = blend.to!.u - from.u, dv = blend.to!.v - from.v;\n pair(L.aU, from.u); pair(L.aV, from.v); pair(L.dU, du); pair(L.dV, dv); pair(L.inverse, 1 / (du * du + dv * dv));\n } else if (blend?.kind === \"radial\") { pair(L.aU, blend.center!.u); pair(L.aV, blend.center!.v); pair(L.inverse, 1 / blend.radius!); }\n let maximumInverse = 0;\n const stops = blend?.stops ?? [];\n stops.forEach((stop, i) => {\n const next = stops[i + 1], inverse = next !== undefined && next > stop ? 1 / (next - stop) : 0;\n pair(L.stops + 4 * i, stop); pair(L.stops + 4 * i + 2, inverse);\n maximumInverse = Math.max(maximumInverse, inverse);\n });\n table[L.maximumInverse] = maximumInverse;\n regions.forEach((r, i) => {\n const at = regionsAt + L.regionWords * i;\n words[at] = r.source; pair(at + 1, r.uMin); pair(at + 3, r.uMax); pair(at + 5, r.vMin); pair(at + 7, r.vMax);\n });\n points.forEach((p, j) => { const at = pointsAt + L.pointWords * j; pair(at, p.xM); pair(at + 2, p.yM); pair(at + 4, p.heightM); });\n // The largest irradiance / π anywhere (the blend's largest source and every point at normal incidence, 1/h²), for the tiny-value bound.\n let largestIrradiance = 0;\n wavelengths.forEach((nm, n) => {\n let top = 0, atNormal = 0;\n sources.forEach((source, i) => { const value = source.irradianceScale * source.illuminant.shape.evaluate(nm) / Math.PI; table[tablesAt + i * N + n] = value; top = Math.max(top, value); });\n points.forEach((p, j) => { const value = p.scale * p.shape.evaluate(nm) / Math.PI; table[tablesAt + (S + j) * N + n] = value; atNormal += value / (p.heightM * p.heightM); });\n largestIrradiance = Math.max(largestIrradiance, top + atNormal);\n });\n for (let i = tablesAt; i < table.length; i++) if (!(table[i]! >= 0 && table[i]! <= FLOAT32_SAFE_MAGNITUDE)) throw new ImageKernelExecutionError(\"unsupported-float32-domain\", \"A light's spectrum is outside the float32 domain.\");\n return { table, largestIrradiance };\n}\n\n/** The display-view helpers of the composite kernel's common part, with the barrier word read from the photo uniform. */\nconst photoCommon = (path: ChartCompositeProductPath): string => displayViewModuleCommonWgsl(path).replace(/\\blattice\\.zero\\b/gu, \"photo.zero\");\n\n/** Pass 1's WGSL (see the module comment). */\nexport function imagePlaneQualityLatticeWgsl(path: ChartCompositeProductPath): string {\n return `${DISPLAY_VIEW_QUALITY_COMMON_WGSL}\n@group(0) @binding(1) var<storage, read> groups: array<u32>;\n@group(0) @binding(2) var<storage, read_write> lattice_values: array<f32>;\n@group(0) @binding(3) var<storage, read_write> lattice_flags: array<u32>;\nstruct PhotoParams {\n width: u32, height: u32, nearest: u32, nodes: u32, row0: u32, zero: u32, lit: u32, pad1: u32,\n su_hi: f32, su_lo: f32, sv_hi: f32, sv_lo: f32, k_hi: f32, k_lo: f32, hw_hi: f32, hw_lo: f32,\n hh_hi: f32, hh_lo: f32, aspect_hi: f32, aspect_lo: f32, slack_x: f32, slack_y: f32, black: f32, span: f32,\n};\n@group(1) @binding(0) var<storage, read> records: array<u32>;\n@group(1) @binding(1) var<uniform> photo: PhotoParams;\n@group(1) @binding(2) var<storage, read> node_table: array<f32>;\n@group(1) @binding(3) var<storage, read> light: array<f32>;\n${photoCommon(path)}\n${LIGHT_WGSL}\nfn pixel_slack(x: D, slack: f32) -> f32 { return 4.0 * (DW * (abs(x.h) + 1.0)) + 4.0 * slack; }\nstruct Axis { i0: u32, i1: u32, w0: f32, w1: f32 }\nfn bilinear_axis(s: D, n: u32) -> Axis {\n var f0 = floor(s.h);\n if (f0 == s.h && s.l < 0.0) { f0 = f0 - 1.0; }\n let frac = d_sub(s, D(f0, 0.0));\n let comp = d_sub(D(ob(f0 + 1.0), 0.0), s);\n var w0 = 0.0; var w1 = 0.0;\n if (frac.h <= 0.5) { w1 = ob(frac.h + frac.l); w0 = ob(1.0 - w1); } else { w0 = ob(comp.h + comp.l); w1 = ob(1.0 - w0); }\n let last = i32(n) - 1;\n return Axis(u32(clamp(i32(f0), 0, last)), u32(clamp(i32(f0) + 1, 0, last)), w0, w1);\n}\n// A channel's two corner weights from its record: the stored smaller one and 1 minus it.\nfn channel_weights(word: u32, bit: u32, small: f32) -> vec2<f32> {\n if (((word >> bit) & 1u) == 0u) { return vec2<f32>(ob(1.0 - small), small); }\n return vec2<f32>(small, ob(1.0 - small));\n}\nstruct Pixel { base: u32, r: vec2<f32>, g: vec2<f32>, b: vec2<f32> }\nfn pixel_at(i: u32, j: u32) -> Pixel {\n let o = ((j - photo.row0) * photo.width + i) * ${RECORD_WORDS}u;\n let w = records[o];\n return Pixel((w & 3u) * 25u + ((w >> 2u) & 3u) * 5u + ((w >> 4u) & 3u), channel_weights(w, 6u, bitcast<f32>(records[o + 1u])),\n channel_weights(w, 7u, bitcast<f32>(records[o + 2u])), channel_weights(w, 8u, bitcast<f32>(records[o + 3u])));\n}\nfn node(k: u32, n: u32) -> f32 { return node_table[k * photo.nodes + n]; }\n// The white radiance at node n, or (#597) under mixed light the irradiance / π at the point.\nfn white_at(white: u32, n: u32) -> f32 { if (photo.lit != 0u) { return light_at(n); } return node_table[white + n]; }\n// One pixel's reflectance at node n: the reference's nested trilinear form, then the paper.\nfn pixel_value(px: Pixel, n: u32) -> f32 {\n let b = px.base;\n let lat = px.r.x * (px.g.x * (px.b.x * node(b, n) + px.b.y * node(b + 1u, n)) + px.g.y * (px.b.x * node(b + 5u, n) + px.b.y * node(b + 6u, n))) +\n px.r.y * (px.g.x * (px.b.x * node(b + 25u, n) + px.b.y * node(b + 26u, n)) + px.g.y * (px.b.x * node(b + 30u, n) + px.b.y * node(b + 31u, n)));\n return photo.black + photo.span * lat;\n}\n@compute @workgroup_size(${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE})\nfn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) wg: vec3<u32>) {\n let i = gid.x + gid.y * wg.x * ${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE}u;\n if (i >= params.lattice_total) { return; }\n var g = 0u;\n for (var k = 1u; k < params.groups; k = k + 1u) { if (i >= groups[k * GROUP + 4u]) { g = k; } }\n let base = g * GROUP;\n let lw = groups[base + 2u];\n let local = i - groups[base + 4u];\n let q = bitcast<i32>(groups[base + 1u]) + i32(local / lw);\n let p = bitcast<i32>(groups[base]) + i32(local % lw);\n material_uncertain = false;\n let N = photo.nodes;\n let out = i * N;\n let white = ${NODES}u * N;\n let k = D(photo.k_hi, photo.k_lo);\n let u = d_mul(d_mul(D(f32(p) + bitcast<f32>(groups[base + 6u]), 0.0), D(photo.su_hi, photo.su_lo)), k);\n let v = d_mul(d_mul(D(f32(q) + bitcast<f32>(groups[base + 7u]), 0.0), D(photo.sv_hi, photo.sv_lo)), k);\n let aspect = D(photo.aspect_hi, photo.aspect_lo);\n // #597: under mixed light the irradiance at the point (its blend and point sources) replaces the white radiance per node.\n if (photo.lit != 0u) { light_prepare(u, v); }\n if (!(le(babs(bd(u)), bx(1.0)) && le(babs(bd(v)), bd(aspect)))) {\n for (var n = 0u; n < N; n = n + 1u) {\n if (photo.lit != 0u) { lattice_values[out + n] = light[${L.surround}u] * light_at(n); } else { lattice_values[out + n] = node_table[white + N + n]; }\n }\n lattice_flags[i] = select(0u, 1u, material_uncertain);\n return;\n }\n let x = d_mul(d_add(u, D(1.0, 0.0)), D(photo.hw_hi, photo.hw_lo));\n let y = d_mul(d_sub(aspect, v), D(photo.hh_hi, photo.hh_lo));\n if (photo.nearest != 0u) {\n let last_x = f32(photo.width - 1u);\n let last_y = f32(photo.height - 1u);\n let px = pixel_at(u32(clamp(bfloor(bd(x), 1.0, last_x), 0.0, last_x)), u32(clamp(bfloor(bd(y), 1.0, last_y), 0.0, last_y)));\n for (var n = 0u; n < N; n = n + 1u) { lattice_values[out + n] = white_at(white, n) * pixel_value(px, n); }\n } else {\n let ax = bilinear_axis(d_sub(x, D(0.5, 0.0)), photo.width);\n let ay = bilinear_axis(d_sub(y, D(0.5, 0.0)), photo.height);\n let p00 = pixel_at(ax.i0, ay.i0);\n let p10 = pixel_at(ax.i1, ay.i0);\n let p01 = pixel_at(ax.i0, ay.i1);\n let p11 = pixel_at(ax.i1, ay.i1);\n let slack = (pixel_slack(x, photo.slack_x) + pixel_slack(y, photo.slack_y)) * 2.0;\n for (var n = 0u; n < N; n = n + 1u) {\n let s00 = pixel_value(p00, n);\n let s10 = pixel_value(p10, n);\n let s01 = pixel_value(p01, n);\n let s11 = pixel_value(p11, n);\n let value = ay.w0 * (ax.w0 * s00 + ax.w1 * s10) + ay.w1 * (ax.w0 * s01 + ax.w1 * s11);\n if (!(slack * max(max(s00, s10), max(s01, s11)) <= E * value)) { material_uncertain = true; }\n lattice_values[out + n] = white_at(white, n) * value;\n }\n }\n lattice_flags[i] = select(0u, 1u, material_uncertain);\n}\n`;\n}\n\n/** Pass 2's WGSL (see the module comment): the blocked sum over the nodes, then the Quality site tail. */\nexport const IMAGE_PLANE_QUALITY_SITES_WGSL = /* wgsl */ `${DISPLAY_VIEW_QUALITY_COMMON_WGSL}\n@group(0) @binding(1) var<storage, read> groups: array<u32>;\n@group(0) @binding(3) var<storage, read> table: array<f32>;\n@group(0) @binding(4) var<storage, read> lattice: array<f32>;\n@group(0) @binding(5) var<storage, read_write> sites: array<f32>;\n@group(0) @binding(6) var<storage, read> lattice_flags: array<u32>;\n${DISPLAY_VIEW_QUALITY_SITE_TAIL_WGSL}\n@compute @workgroup_size(${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE})\nfn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) wg: vec3<u32>) {\n let local = gid.x + gid.y * wg.x * ${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE}u;\n if (local >= params.count) { return; }\n let i = params.site_first + local;\n let ii = i % params.site_w;\n let jj = i / params.site_w;\n let c = channel_of(params.site_x0 + i32(ii), params.site_y0 + i32(jj));\n let T = params.taps;\n let N = bitcast<u32>(params.pad_h);\n var sum = 0.0;\n var flagged = false;\n for (var k = 0u; k < params.groups; k = k + 1u) {\n let g = k * GROUP;\n let lw = groups[g + 2u];\n let cw = lw - params.site_w + 1u;\n let ch = groups[g + 3u] - params.site_h + 1u;\n let lattice0 = groups[g + 4u] + jj * lw + ii;\n let tap0 = groups[g + 5u];\n var group_sum = 0.0;\n for (var dy = 0u; dy < ch; dy = dy + 1u) {\n let row = lattice0 + dy * lw;\n let row_tap = tap0 + dy * cw;\n var row_sum = 0.0;\n for (var dx = 0u; dx < cw; dx = dx + 1u) {\n let point = row + dx;\n let t = row_tap + dx;\n var cell = 0.0;\n var weight = 0.0;\n for (var n = 0u; n < N; n = n + 1u) {\n let w = table[(n * 3u + c) * T + t];\n weight = weight + w;\n cell = cell + lattice[point * N + n] * w;\n }\n if (lattice_flags[point] != 0u && weight > 0.0) { flagged = true; }\n row_sum = row_sum + cell;\n }\n group_sum = group_sum + row_sum;\n }\n sum = sum + group_sum;\n }\n let e = sum + dark_of(c);\n write_site(i, c, e, params.site_gamma * e + params.site_tiny, select(0u, 1u, flagged));\n}\n`;\n\n/**\n * The print's gather: per group its dense tap rectangle (with site kernels the reference's combined window; without them the\n * members' span), the lattice extent beyond the site window and the point constants, and the table C_n,c(t) at (n·3 + c)·T + t,\n * the reference's float64 values rounded once.\n */\nexport function imagePlaneQualityGather(signalInput: DisplayViewExpectedSignalInput, largestLitRadiance?: number): SignalGather {\n const tables = displayViewSignalTables(signalInput), W = signalInput.nativeWidth, H = signalInput.nativeHeight, R = signalInput.kernels ? signalInput.kernels.radius : 0;\n const N = signalInput.wavelengthsNm.length, A = signalInput.electronsPerRadiance, groups: SignalGather[\"groups\"] = [];\n const rects = tables.groups.map((group) => {\n const cw = signalInput.kernels ? group.cw : group.maxIx - group.minIx + 1, ch = signalInput.kernels ? group.ch : group.maxIy - group.minIy + 1;\n return { group, cw, ch, dpMin: group.minIx - R, dqMin: group.minIy - R };\n });\n let T = 0;\n for (const r of rects) {\n groups.push({ dpMin: r.dpMin, dqMin: r.dqMin, dpSpan: r.cw - 1, dqSpan: r.ch - 1, cu: 0.5 + r.group.fx - W / 2, cv: 0.5 + r.group.fy - H / 2, firstTap: T, cw: r.cw, ch: r.ch });\n T += r.cw * r.ch;\n }\n const table = new Float32Array(N * 3 * T), tiny = new Float64Array(T);\n let largestRadiance = 0;\n rects.forEach((r, g) => {\n const first = groups[g]!.firstTap;\n for (let n = 0; n < N; n++) for (let c = 0; c < 3; c++) {\n const values = new Float64Array(r.cw * r.ch);\n if (signalInput.kernels) values.set(r.group.perNode[n]![c]!);\n else for (const member of r.group.members) { const at = (member.iy - r.group.minIy) * r.cw + member.ix - r.group.minIx; values[at] = values[at]! + member.weight * A[c]![n]!; }\n for (let t = 0; t < values.length; t++) {\n const value = values[t]!;\n if (!(value >= 0 && value <= FLOAT32_SAFE_MAGNITUDE)) throw new ImageKernelExecutionError(\"unsupported-float32-domain\", \"A combined kernel value is outside the float32 domain.\");\n table[(n * 3 + c) * T + first + t] = value;\n if (value > 0 && value < FLOAT32_MINIMUM_NORMAL) tiny[first + t] = Math.max(tiny[first + t]!, value);\n }\n }\n });\n const image = (signalInput.scene as { image?: ImagePlaneSignalScene[\"image\"] }).image!;\n if (largestLitRadiance !== undefined) largestRadiance = largestLitRadiance;\n else for (const w of image.whiteRadiance) largestRadiance = Math.max(largestRadiance, w);\n let tinyMass = 0;\n for (let t = 0; t < T; t++) tinyMass += tiny[t]! * largestRadiance * N;\n return { groups, taps: new Uint32Array(0), tapCount: T, nodes: N, table, spread: new Float32Array(3 * Math.max(1, T)), materials: 0, tinyMass };\n}\n\n/** The print's Quality passes for a setup (see `DisplayViewQualityImagePasses`), with the double-word product path the device's probe chose. */\nexport function imagePlaneQualityPasses(runtime: WebGpuRuntime, gpu: DisplayViewGpuSetup, path: ChartCompositeProductPath): DisplayViewQualityImagePasses {\n const signalInput = gpu.signalInput, image = (signalInput.scene as { image?: ImagePlaneSignalScene[\"image\"] }).image;\n if (!image || !gpu.placement) throw new ImageKernelExecutionError(\"unsupported-on-backend\", \"The setup carries no image-plane print and placement; use cpu-reference.\");\n // #597: under mixed light, the light's table (its parts and spectra at the nodes), which replaces the white radiance in pass 1.\n const k0 = gpu.placement.chartUnitsPerFrameUnit, lit = image.light ? imagePlaneLightTable(image.light, signalInput.wavelengthsNm, image.surroundReflectance, 1e-14 * k0) : undefined;\n const scene = image.scene, N = signalInput.wavelengthsNm.length, gather = imagePlaneQualityGather(signalInput, lit?.largestIrradiance);\n let cw = 0, ch = 0;\n for (const g of gather.groups) { cw = Math.max(cw, g.cw); ch = Math.max(ch, g.ch); }\n // The lattice scale: the lattice formula's g with site kernels, else the environment's query lattice (checked within 2⁻⁴⁰ by queryGeometry).\n const g = 2 / signalInput.outputWidth, geometry = signalInput.kernels ? { scaleU: g, scaleV: -g } : queryGeometry(signalInput);\n const halfW = scene.width / 2, halfH = scene.height / (2 * scene.aspect), k = gpu.placement.chartUnitsPerFrameUnit;\n // The node table: s_k(λ_n) per node, then W_n, then the surround's radiance per node.\n const nodeTable = new Float32Array((NODES + 2) * N);\n signalInput.wavelengthsNm.forEach((nm, n) => {\n const reflectances = scene.nodeReflectances(nm);\n for (let node = 0; node < NODES; node++) nodeTable[node * N + n] = reflectances[node]!;\n nodeTable[NODES * N + n] = image.whiteRadiance[n]!;\n nodeTable[(NODES + 1) * N + n] = image.surroundReflectance * image.whiteRadiance[n]!;\n });\n const P = IMAGE_PLANE_QUALITY_PARAMS, params = new ArrayBuffer(4 * P.words), words = new Uint32Array(params), floats = new Float32Array(params);\n words[P.width] = scene.width; words[P.height] = scene.height; words[P.nearest] = scene.interpolation === \"nearest\" ? 1 : 0; words[P.nodes] = N; words[P.zero] = 0; words[P.lit] = lit ? 1 : 0;\n const lightTable = lit ? lit.table : new Float32Array(1);\n [floats[P.suHi], floats[P.suLo]] = dwSplit(geometry.scaleU); [floats[P.svHi], floats[P.svLo]] = dwSplit(geometry.scaleV); [floats[P.kHi], floats[P.kLo]] = dwSplit(k);\n [floats[P.halfWHi], floats[P.halfWLo]] = dwSplit(halfW); [floats[P.halfHHi], floats[P.halfHLo]] = dwSplit(halfH); [floats[P.aspectHi], floats[P.aspectLo]] = dwSplit(scene.aspect);\n floats[P.slackX] = 1e-14 * k * halfW; floats[P.slackY] = 1e-14 * k * halfH; floats[P.black] = scene.paperBlackReflectance; floats[P.span] = scene.paperWhiteReflectance - scene.paperBlackReflectance;\n const label = path === \"dekker\" ? \"image-plane\" : \"image-plane-fma\";\n const fractions = new Float64Array(3);\n const passes: DisplayViewQualityImagePasses = {\n gather, siteGamma: (IMAGE_PLANE_LATTICE_U + (lit ? IMAGE_PLANE_LIGHT_U : 0) + N + cw + ch + gather.groups.length + 4) * E, pointFloats: N,\n lattice: [\"photivra-display-view-quality-photo-lattice:\" + label, imagePlaneQualityLatticeWgsl(path)],\n sites: [\"photivra-display-view-quality-photo-sites\", IMAGE_PLANE_QUALITY_SITES_WGSL],\n async runLattice(band, pipeline, latticeParams, groupBuffer, groupWords, latticeTotal, signal): Promise<{ values: GPUBuffer; flags: GPUBuffer; resolved: number }> {\n let values = band.buffer(\"photivra-display-view-photo-lattice\", latticeTotal * 4 * N, BUFFER_USAGE.STORAGE | BUFFER_USAGE.COPY_SRC);\n let flags = band.buffer(\"photivra-display-view-photo-lattice-flags\", latticeTotal * 4, BUFFER_USAGE.STORAGE | BUFFER_USAGE.COPY_SRC);\n const group0 = runtime.device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [{ binding: 0, resource: { buffer: latticeParams } },\n { binding: 1, resource: { buffer: groupBuffer } }, { binding: 2, resource: { buffer: values } }, { binding: 3, resource: { buffer: flags } }] });\n const [valueData, flagData] = await runComputePass(runtime, band, pipeline, [group0, bandGroup(band, pipeline.getBindGroupLayout(1), groupWords)],\n linearDispatch(latticeTotal, DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE, runtime.maximumWorkgroupsPerDimension),\n [{ buffer: values, bytes: latticeTotal * 4 * N }, { buffer: flags, bytes: latticeTotal * 4 }], signal);\n const valueArray = new Float32Array(valueData!, 0, latticeTotal * N), flagArray = new Uint32Array(flagData!, 0, latticeTotal), resolved = resolve(valueArray, flagArray, groupWords);\n if (resolved > 0) { values = band.upload(\"photivra-display-view-photo-lattice-resolved\", valueArray, BUFFER_USAGE.STORAGE); flags = band.upload(\"photivra-display-view-photo-flags-resolved\", flagArray, BUFFER_USAGE.STORAGE); }\n return { values, flags, resolved };\n }\n };\n function bandGroup(scope: GpuResourceScope, layout: GPUBindGroupLayout, groupWords: Uint32Array): GPUBindGroup {\n // The pixel rows the band's lattice windows reach (the print-local v of each window's first and last rows, two rows of margin).\n const ints = new Int32Array(groupWords.buffer, groupWords.byteOffset, groupWords.length), groupFloats = new Float32Array(groupWords.buffer, groupWords.byteOffset, groupWords.length);\n let low = Infinity, high = -Infinity;\n for (let gi = 0; gi < gather.groups.length; gi++) {\n const base = gi * DISPLAY_VIEW_QUALITY_GROUP_WORDS, cv = groupFloats[base + 7]!;\n for (const q of [ints[base + 1]!, ints[base + 1]! + groupWords[base + 3]! - 1]) {\n const Y = (scene.aspect - (q + cv) * geometry.scaleV * k) * halfH;\n low = Math.min(low, Y); high = Math.max(high, Y);\n }\n }\n const row0 = Math.max(0, Math.min(scene.height - 1, Math.floor(low) - 2)), row1 = Math.max(row0, Math.min(scene.height - 1, Math.floor(high) + 2));\n const records = new Uint32Array((row1 - row0 + 1) * scene.width * RECORD_WORDS), recordFloats = new Float32Array(records.buffer);\n for (let j = row0, o = 0; j <= row1; j++) for (let i = 0; i < scene.width; i++, o += RECORD_WORDS) {\n const cell = scene.pixelLattice(j * scene.width + i, fractions);\n let word = Math.floor(cell / 25) | ((Math.floor(cell / 5) % 5) << 2) | ((cell % 5) << 4);\n for (let c = 0; c < 3; c++) {\n const f = fractions[c]!, high1 = f > 0.5;\n if (high1) word |= 1 << (6 + c);\n recordFloats[o + 1 + c] = high1 ? 1 - f : f;\n }\n records[o] = word;\n }\n const bandParams = params.slice(0);\n new Uint32Array(bandParams)[P.row0] = row0;\n if (records.byteLength > runtime.maximumStorageBindingBytes) throw new ImageKernelExecutionError(\"insufficient-limits\", \"A band's pixel records exceed the device's storage binding limit.\");\n return runtime.device.createBindGroup({ layout, entries: [\n { binding: 0, resource: { buffer: scope.upload(\"photivra-display-view-photo-records\", records, BUFFER_USAGE.STORAGE) } },\n { binding: 1, resource: { buffer: scope.upload(\"photivra-display-view-photo-params\", new Uint8Array(bandParams), BUFFER_USAGE.UNIFORM) } },\n { binding: 2, resource: { buffer: scope.upload(\"photivra-display-view-photo-nodes\", nodeTable, BUFFER_USAGE.STORAGE) } },\n { binding: 3, resource: { buffer: scope.upload(\"photivra-display-view-photo-light\", lightTable, BUFFER_USAGE.STORAGE) } }] });\n }\n function resolve(values: Float32Array, flags: Uint32Array, groupWords: Uint32Array): number {\n if (!signalInput.kernels) return 0;\n // The reference's lattice point (createDisplayViewExpectedSignal's latticeU / latticeV) and its radiance per node.\n const ints = new Int32Array(groupWords.buffer, groupWords.byteOffset, groupWords.length), groupsOf = displayViewSignalTables(signalInput).groups;\n const W = signalInput.nativeWidth, H = signalInput.nativeHeight, scale = 2 / signalInput.outputWidth;\n let resolved = 0;\n groupsOf.forEach((group, gi) => {\n const base = gi * DISPLAY_VIEW_QUALITY_GROUP_WORDS, lx0 = ints[base]!, ly0 = ints[base + 1]!, lw = groupWords[base + 2]!, lh = groupWords[base + 3]!, first = groupWords[base + 4]!;\n for (let local = 0; local < lw * lh; local++) {\n if (flags[first + local] === 0) continue;\n const p = lx0 + (local % lw), q = ly0 + Math.floor(local / lw);\n const u = latticeCoordinate(p, group.fx, W, scale), v = -latticeCoordinate(q, group.fy, H, scale);\n for (let n = 0; n < N; n++) values[(first + local) * N + n] = signalInput.scene.kind === \"radiance\" ? signalInput.scene.radianceAt(u, v, signalInput.wavelengthsNm[n]!) : 0;\n flags[first + local] = 0;\n resolved++;\n }\n });\n return resolved;\n }\n return passes;\n}\n"]}
|
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
* Host side of the display view's Quality path on the GPU (#479): the support check, the float64 tables (the lattice groups
|
|
3
3
|
* and their combined diffraction kernels per material and channel, as the reference forms them; the bilinear and AHD
|
|
4
4
|
* candidate kernels; the footprint geometry), the three passes per band of display rows (lattice materials, site moments,
|
|
5
|
-
* display pixels; `wgsl-display-view-quality-kernel.ts`), the
|
|
6
|
-
* reference's own `computeDisplayViewCorrectionStates`, #447, uploaded as a sorted table and grown from the grid keys the
|
|
7
|
-
* kernel records), and the reference's own float64 finishing per display pixel (`finishDisplayViewPixel` of the Speed host:
|
|
5
|
+
* display pixels; `wgsl-display-view-quality-kernel.ts`), and the reference's own float64 finishing per display pixel (`finishDisplayViewPixel` of the Speed host:
|
|
8
6
|
* the quantization term, the seeded noise draw, the Cholesky factor, the clipped centre, the sRGB encode and the rounding),
|
|
9
7
|
* so the noise draw is bit-identical to the CPU's.
|
|
10
8
|
*
|
|
@@ -16,22 +14,24 @@
|
|
|
16
14
|
*
|
|
17
15
|
* The float64 reference is `renderDisplayView` (facade/display-view.ts) on the exact-area-mean path with
|
|
18
16
|
* `createDisplayViewExpectedSignal` (facade/expected-signal.ts), chart materials, with or without diffraction kernels,
|
|
19
|
-
* the bilinear or the AHD candidates
|
|
17
|
+
* the bilinear or the AHD candidates. Internal: not exported from the package.
|
|
20
18
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
* #594: this module and its WGSL load on demand (`prepareDisplayViewQualityGpu` in `display-view-gpu-renderer.ts`, a dynamic
|
|
20
|
+
* import), at the first render that takes the Quality passes; the renderer and the Speed path never import it statically.
|
|
21
|
+
*
|
|
22
|
+
* Flagged display pixels (an uncertain lattice material among the sites read, AHD's choice on the noise-free mosaic able to move
|
|
23
23
|
* the pixel by more than DISPLAY_VIEW_QUALITY_CHOICE_SIGMA of its noise (#457), a non-finite output) are recomputed with the
|
|
24
24
|
* reference, so they are exact. Every stage's wall-clock time is reported (`stageMilliseconds`); on a software adapter it
|
|
25
25
|
* is not GPU performance.
|
|
26
26
|
*/
|
|
27
|
-
import { type
|
|
27
|
+
import { type DisplayViewRenderResult, type DisplayViewSetup } from "../facade/display-view.js";
|
|
28
28
|
import { type DisplayViewExpectedSignalInput } from "../facade/expected-signal.js";
|
|
29
29
|
import type { DisplayViewGpuSetup } from "../facade/display-view.js";
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
30
|
+
import type { DisplayViewMaterialModules } from "./display-view-composite-material-module.js";
|
|
31
|
+
import type { DisplayViewGpuConformanceCase } from "../facade/display-view-gpu.js";
|
|
32
32
|
import { type DisplayViewGpuMaterialModule } from "./display-view-speed-gpu.js";
|
|
33
33
|
import { type ImageKernelExecution, type ImageKernelRelativeErrorBound } from "./image-kernel-execution.js";
|
|
34
|
-
import { type WebGpuRuntime } from "./webgpu-runtime.js";
|
|
34
|
+
import { GpuResourceScope, type WebGpuRuntime } from "./webgpu-runtime.js";
|
|
35
35
|
type PipelineSource = (label: string, code: string) => Promise<GPUComputePipeline>;
|
|
36
36
|
type YieldControl = ((signal: AbortSignal) => Promise<void>) | undefined;
|
|
37
37
|
/**
|
|
@@ -56,8 +56,6 @@ export interface DisplayViewQualityGpuInput {
|
|
|
56
56
|
material: DisplayViewGpuMaterialModule;
|
|
57
57
|
/** Recompute flagged display pixels with the reference. Default true. */
|
|
58
58
|
recomputeFlagged?: boolean;
|
|
59
|
-
/** The states this renderer holds for the setup's correction key (grown by the render); a fresh store when absent. */
|
|
60
|
-
states?: CorrectionStateStore;
|
|
61
59
|
/**
|
|
62
60
|
* #492: sum each site's taps in blocks (rows, groups; `DISPLAY_VIEW_QUALITY_SITES_BLOCKED_WGSL`), whose bound grows with the
|
|
63
61
|
* kernel's width rather than its tap count. Default: when the setup's expected signal carries the defocus disc
|
|
@@ -66,6 +64,25 @@ export interface DisplayViewQualityGpuInput {
|
|
|
66
64
|
blockedSum?: boolean;
|
|
67
65
|
/** Largest taps (sites × taps per site) per site-pass dispatch; default `DISPLAY_VIEW_QUALITY_SITE_TAPS_PER_DISPATCH`. */
|
|
68
66
|
maximumSiteTapsPerDispatch?: number;
|
|
67
|
+
/** #581: an image-plane print's own passes 1 and 2 (`material` is then unused). */
|
|
68
|
+
image?: DisplayViewQualityImagePasses;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* #581: an image-plane print's passes 1 and 2 (src/gpu/display-view-image-quality.ts): pass 1 writes `pointFloats` radiance values
|
|
72
|
+
* per lattice point and a flag word; pass 2 is the blocked sum over them (the flags at binding 6).
|
|
73
|
+
*/
|
|
74
|
+
export interface DisplayViewQualityImagePasses {
|
|
75
|
+
gather: SignalGather;
|
|
76
|
+
siteGamma: number;
|
|
77
|
+
pointFloats: number;
|
|
78
|
+
lattice: [label: string, wgsl: string];
|
|
79
|
+
sites: [label: string, wgsl: string];
|
|
80
|
+
/** Runs pass 1 over a band's lattice windows, and with site kernels resolves its flagged points with the reference (their count). */
|
|
81
|
+
runLattice(band: GpuResourceScope, pipeline: GPUComputePipeline, params: GPUBuffer, groups: GPUBuffer, groupWords: Uint32Array, latticeTotal: number, signal: AbortSignal): Promise<{
|
|
82
|
+
values: GPUBuffer;
|
|
83
|
+
flags: GPUBuffer;
|
|
84
|
+
resolved: number;
|
|
85
|
+
}>;
|
|
69
86
|
}
|
|
70
87
|
/** Wall-clock milliseconds per stage of one render (upload, dispatch and readback of each pass; host work apart). */
|
|
71
88
|
export interface DisplayViewQualityStageTimings {
|
|
@@ -73,16 +90,12 @@ export interface DisplayViewQualityStageTimings {
|
|
|
73
90
|
lattice: number;
|
|
74
91
|
/** Pass 2: the site electrons through the combined kernels, the readout moments and the white clip. */
|
|
75
92
|
sites: number;
|
|
76
|
-
/** Pass 3: the display pixels (demosaic candidates, development, covariance
|
|
93
|
+
/** Pass 3: the display pixels (demosaic candidates, development, covariance), every dispatch of it. */
|
|
77
94
|
pixels: number;
|
|
78
|
-
/** The low-signal correction states computed on the host (the reference's own draws) and the table uploads. */
|
|
79
|
-
states: number;
|
|
80
95
|
/** The host finishing (quantization term, noise draw, Cholesky, encode) of every display pixel. */
|
|
81
96
|
finishing: number;
|
|
82
97
|
/** The reference's recomputation of flagged display pixels. */
|
|
83
98
|
recompute: number;
|
|
84
|
-
/** Pass 3 dispatches that were repeated because a correction state was missing. */
|
|
85
|
-
pixelRedispatches: number;
|
|
86
99
|
/** Pass 2 dispatches (one per band, or more where a band's sites × taps exceed the tap budget per dispatch, #492). */
|
|
87
100
|
siteDispatches: number;
|
|
88
101
|
}
|
|
@@ -103,9 +116,6 @@ export interface DisplayViewQualityGpuResult extends DisplayViewRenderResult {
|
|
|
103
116
|
pixelFlags: Uint32Array;
|
|
104
117
|
/** #533: display pixels (not flagged) with a real pixel whose saturation the kernel left undecided; their count is the host reference's. */
|
|
105
118
|
highlightRecomputedPixelIndices: Uint32Array;
|
|
106
|
-
/** Correction states the render computed on the host (new to the store), and the states the table held at the end. */
|
|
107
|
-
statesComputed: number;
|
|
108
|
-
statesHeld: number;
|
|
109
119
|
/** Taps per native site of the expected-signal gather (over every lattice group). */
|
|
110
120
|
tapsPerSite: number;
|
|
111
121
|
/** #492: whether the site pass summed in blocks (the defocus disc), and the relative bound of a site's electrons it used. */
|
|
@@ -118,36 +128,60 @@ export interface DisplayViewQualityGpuResult extends DisplayViewRenderResult {
|
|
|
118
128
|
latticePointsResolved: number;
|
|
119
129
|
stageMilliseconds: DisplayViewQualityStageTimings;
|
|
120
130
|
}
|
|
121
|
-
/**
|
|
122
|
-
* The low-signal correction states a renderer holds for one correction key, as the GPU table reads them: grid keys ascending
|
|
123
|
-
* with three float32 values each (the host keeps the float64 values; the table is their single rounding).
|
|
124
|
-
*/
|
|
125
|
-
export declare class CorrectionStateStore {
|
|
126
|
-
#private;
|
|
127
|
-
get size(): number;
|
|
128
|
-
has(key: number): boolean;
|
|
129
|
-
add(gridKeys: Int32Array, values: Float64Array): void;
|
|
130
|
-
/** The sorted table (rebuilt when states were added since the last call). */
|
|
131
|
-
table(): {
|
|
132
|
-
keys: Int32Array<ArrayBuffer>;
|
|
133
|
-
values: Float32Array<ArrayBuffer>;
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
/** The footprint shape of a view: real pixels per display pixel along each axis, and whether the exact area mean applies. */
|
|
137
|
-
export declare function footprintShape(setup: DisplayViewSetup): {
|
|
138
|
-
sx: number;
|
|
139
|
-
sy: number;
|
|
140
|
-
exact: boolean;
|
|
141
|
-
maximumColumns: number;
|
|
142
|
-
maximumRows: number;
|
|
143
|
-
};
|
|
144
131
|
/**
|
|
145
132
|
* Why the Quality kernels do not cover a request, or null when they do: chart materials, the exact area mean (footprints of
|
|
146
133
|
* at most 25 real pixels and 6 per axis), the identity or positive Reinhard tone curve, demosaic candidates within 3 sites
|
|
147
|
-
* (1 or 2 per phase), at most 64 lattice groups, lattice constants exact in float32,
|
|
134
|
+
* (1 or 2 per phase), at most 64 lattice groups, lattice constants exact in float32, and a raster at least
|
|
148
135
|
* 2·reach + 2 sites on each axis (so a reflected border site lies in the band's window).
|
|
149
136
|
*/
|
|
150
137
|
export declare function displayViewQualityGpuUnsupportedReason(setup: DisplayViewSetup, signalInput: DisplayViewExpectedSignalInput): string | null;
|
|
138
|
+
/** The lattice groups, taps and the spectral table of the expected signal (see the module comment). */
|
|
139
|
+
export interface SignalGather {
|
|
140
|
+
/**
|
|
141
|
+
* Per group: dpMin, dqMin, dpSpan, dqSpan (lattice extent beyond the site window), cu, cv; its first tap, and (with site
|
|
142
|
+
* kernels) its dense tap rectangle cw × ch (dp = dpMin + dx, dq = dqMin + dy at tap first + dy·cw + dx).
|
|
143
|
+
*/
|
|
144
|
+
groups: {
|
|
145
|
+
dpMin: number;
|
|
146
|
+
dqMin: number;
|
|
147
|
+
dpSpan: number;
|
|
148
|
+
dqSpan: number;
|
|
149
|
+
cu: number;
|
|
150
|
+
cv: number;
|
|
151
|
+
firstTap: number;
|
|
152
|
+
cw: number;
|
|
153
|
+
ch: number;
|
|
154
|
+
}[];
|
|
155
|
+
/** Per tap: group, dp − dpMin, dq − dqMin. */
|
|
156
|
+
taps: Uint32Array<ArrayBuffer>;
|
|
157
|
+
tapCount: number;
|
|
158
|
+
/** Spectral nodes N. */
|
|
159
|
+
nodes: number;
|
|
160
|
+
/**
|
|
161
|
+
* 2.21.0 (signals integrated from the material spectrum per site): per channel c, tap t and node n the channel's response and
|
|
162
|
+
* kernel C_c(t, n) at (c·T + t)·N + n (`nodeKernels`; without site kernels the member's weight times A_c(λ_n)), then per material
|
|
163
|
+
* m its spectral radiance L_m(λ_n) at 3·T·N + m·N + n, each float64 rounded once. No per-material channel value is formed: the
|
|
164
|
+
* site pass integrates Σ_t Σ_n C_c(t, n)·L_{m_t}(λ_n).
|
|
165
|
+
*/
|
|
166
|
+
table: Float32Array<ArrayBuffer>;
|
|
167
|
+
/**
|
|
168
|
+
* Per channel c and tap t (at c·T + t): a bound on the difference between any two materials' signals at that tap,
|
|
169
|
+
* Σ_n C_c(t, n)·(max_m L_m(λ_n) − min_m L_m(λ_n)), from the spectra's envelope (no per-material value), rounded up.
|
|
170
|
+
*/
|
|
171
|
+
spread: Float32Array<ArrayBuffer>;
|
|
172
|
+
materials: number;
|
|
173
|
+
/**
|
|
174
|
+
* An absolute bound on what a device that flushes results below the float32 normal range (WGSL allows it) can drop from a site:
|
|
175
|
+
* per tap the largest product C·max L below that range over the channels, plus one smallest normal per partial addition and
|
|
176
|
+
* per compensation step ((T + 2)·N of them), float64.
|
|
177
|
+
*/
|
|
178
|
+
tinyMass: number;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* One axis of the reference's lattice point (createDisplayViewExpectedSignal's latticeU / latticeV, written as it writes them):
|
|
182
|
+
* (i + 0.5 − size/2)·g with no shift, (i + 0.5 + f − size/2)·g otherwise; v is its negative.
|
|
183
|
+
*/
|
|
184
|
+
export declare const latticeCoordinate: (i: number, f: number, size: number, g: number) => number;
|
|
151
185
|
/** Renders one region of a Quality display view on the GPU (see the module comment). */
|
|
152
186
|
export declare function renderDisplayViewQualityOnGpu(runtime: WebGpuRuntime, bandBytes: number, input: DisplayViewQualityGpuInput, abort: AbortController, yieldControl: YieldControl, pipelines: PipelineSource): Promise<DisplayViewQualityGpuResult>;
|
|
153
187
|
/**
|
|
@@ -163,29 +197,10 @@ export declare function renderDisplayViewQualityOnGpu(runtime: WebGpuRuntime, ba
|
|
|
163
197
|
export declare function qualityMaterialSetup(gpu: DisplayViewGpuSetup): DisplayViewGpuSetup;
|
|
164
198
|
/** The material module of a Quality render's scene (see `qualityMaterialSetup`). */
|
|
165
199
|
export declare function qualityMaterialModule(modules: DisplayViewMaterialModules, gpu: DisplayViewGpuSetup, signal: AbortSignal): Promise<DisplayViewGpuMaterialModule>;
|
|
166
|
-
/** The pixel-aperture samples per axis and anti-aliasing spots of a request. */
|
|
167
|
-
export declare function offsetCount(request: DisplayViewGpuRequest): number;
|
|
168
|
-
/**
|
|
169
|
-
* Why the Quality renderer does not support a prepared request (`DisplayViewGpuRenderer.supports`), or true: engine charts and
|
|
170
|
-
* declared `material-layers` scenes (the material modules of `createDisplayViewMaterialModules`, #491), the identity or Reinhard
|
|
171
|
-
* tone curve and at most 64 query offsets (lattice groups). `lens.defocus` out of focus is supported (#492 step 2c: the site pass
|
|
172
|
-
* gathers the disc, or each node's diffraction kernel convolved with it, up to the reference's own caps of radius 64 and 96);
|
|
173
|
-
* whether a view's footprints take the exact area mean, whether the device passes the composite probe, and whether the kernel
|
|
174
|
-
* table fits the device's storage binding limit, is known only per render.
|
|
175
|
-
*/
|
|
176
|
-
export declare function displayViewQualityGpuSupports(request: DisplayViewGpuRequest): true | string;
|
|
177
200
|
/** #479's self-check (see `runQualityConformance`). */
|
|
178
201
|
export declare const DISPLAY_VIEW_QUALITY_CONFORMANCE_CASE: DisplayViewGpuConformanceCase;
|
|
179
202
|
/** #492's self-check of the defocus disc's blocked site sum (see `runQualityConformance`). */
|
|
180
203
|
export declare const DISPLAY_VIEW_QUALITY_DEFOCUS_CONFORMANCE_CASE: DisplayViewGpuConformanceCase;
|
|
181
|
-
/**
|
|
182
|
-
export declare
|
|
183
|
-
export declare function createDisplayViewGpuRenderer(runtime: WebGpuRuntime, options?: {
|
|
184
|
-
maximumBandBytes?: number;
|
|
185
|
-
yieldControl?: YieldControl;
|
|
186
|
-
}): DisplayViewGpuRenderer;
|
|
187
|
-
/** The factory `prepareDisplayView` creates the renderer with (one per device): the Speed and Quality kernels behind one renderer. */
|
|
188
|
-
export declare const displayViewGpuRendererFactory: DisplayViewGpuRendererFactory;
|
|
189
|
-
/** Registers the combined renderer as the display view's GPU renderer and returns the factory registered before. */
|
|
190
|
-
export declare function registerDisplayViewGpuRenderer(): DisplayViewGpuRendererFactory | null;
|
|
204
|
+
/** #594: the Quality kernels' self-check cases, run before the first render that takes the Quality passes (`onDemandConformanceCases`). */
|
|
205
|
+
export declare const DISPLAY_VIEW_QUALITY_CONFORMANCE_CASES: readonly DisplayViewGpuConformanceCase[];
|
|
191
206
|
export {};
|