S15.3: the camera-space tap is uniforms, not structure — and FR-MRG-2 moves below the profile
The fused chain, as operation.rs's tests fix it, is warp → as-shot white balance → operations → base curve → camera matrix → store. LinearWorking stores after the matrix, so the existing linear tap carries the body's base curve, and a composite stitched from it and developed as an unprofiled body would render that curve twice. FR-MRG-2 therefore stitches camera-linear RGB — after the warp, before white balance, curve and matrix — and the composite carries the first source's body, matrices and as-shot neutral so its own develop applies the profile once. The composer already makes this a uniform question: white balance, matrix and the curve flag are reserved uniforms, so the tap is a compose entry with no operations and a render entry that fills them neutral. panorama.md §5.1 states the shape and asks for f32 buffers.
This commit is contained in:
+37
-2
@@ -50,7 +50,7 @@ reused:
|
||||
|
||||
| Exists | Where | Reused for |
|
||||
|---|---|---|
|
||||
| Render a source to scene-linear on the GPU | `dr-gpu` demosaic → camera profile → working space | FR-MRG-2's input, once a tap after lens correction and before tone exists (S15.3) |
|
||||
| Render a source through the fused pass, with a linear f16 output mode | `dr-gpu` demosaic → `AdjustPass`, `OutputMode::LinearWorking` | FR-MRG-2's camera-space input, as a compose entry with no operations and the profile uniforms neutral (S15.3) |
|
||||
| Tiled rendering with a priority scheduler | ARCH §5.3 | Pulling source tiles on demand into an output chunk (§5 below) |
|
||||
| A non-CFA source entering the pipeline | `Demosaicer::from_rgba8` | The composite's decode path, if the container is a TIFF (S15.1) |
|
||||
| DNG matrices read through rawler | `dr-decode::profile` | The composite's decode path, if the container is a DNG |
|
||||
@@ -70,7 +70,7 @@ FR-MRG-10 states the rule; this is the table it was written from.
|
||||
|
||||
| Stage | Cost shape | Runs on | Why |
|
||||
|---|---|---|---|
|
||||
| Source to scene-linear | per pixel, full res | GPU, the existing pipeline | It *is* the pipeline |
|
||||
| Source to camera-linear | per pixel, full res | GPU, the existing pipeline | It *is* the pipeline, stopped early |
|
||||
| Keypoint detection | once per frame, at 1024 px | CPU, tract (NEON on the tablet) | Bounded by frame count, not output size. Same runtime faces and masks use. Hand-written WGSL convolutions for a model that runs five times would be work with no visible gain. |
|
||||
| Descriptor matching | K² × D per pair | CPU, SIMD | 2048² × 64 × 10 pairs ≈ 3 GFLOP — tens of milliseconds |
|
||||
| Rotation solve, bundle adjustment | 3N + 1 parameters, Levenberg–Marquardt | CPU | Microseconds. Not parallel work. |
|
||||
@@ -125,6 +125,41 @@ neutral graph at zoom 1 and gets the same caching every other consumer does.
|
||||
A tile pulled for one chunk is usually needed by the neighbouring chunk, and
|
||||
stays hot for it.
|
||||
|
||||
### 5.1 The tap — S15.3, answered by reading the composer
|
||||
|
||||
The fused shader's order, fixed by `operation.rs`'s own tests: warp → as-shot
|
||||
white balance → operations → base curve → camera matrix → store. The store is
|
||||
either the display encode or, in `OutputMode::LinearWorking`, an unclipped
|
||||
`rgba16float` of linear sRGB. That mode exists for the detail stage and is
|
||||
selected from the operations, never by a caller flag, so that a shader and
|
||||
the texture bound to it cannot disagree.
|
||||
|
||||
The merge wants the values *before* the curve and matrix (FR-MRG-2), and the
|
||||
composer already makes that a matter of uniforms rather than structure: the
|
||||
white balance, the matrix and the curve's active flag are all in the reserved
|
||||
uniform block, and a fused pass with no operations, `as_shot_wb = 1`,
|
||||
`cam_to_srgb = I` and `base_curve_last.z = 0` stores exactly camera-linear
|
||||
RGB after the warp. So the tap is:
|
||||
|
||||
- `EditGraph::compose_camera_linear()` — the `LinearWorking` tail with an
|
||||
empty operation list and identity framing, paired by name with
|
||||
- `AdjustPass::render_camera_linear()` — binds the f16 target, fills the
|
||||
reserved uniforms neutral instead of from the source, returns the texture,
|
||||
- and a float readback beside the existing 8-bit one.
|
||||
|
||||
Nothing in the chain moves. **Precision:** the tap and every chunk buffer
|
||||
after it should be `rgba32float`, not f16. A 14-bit sensor has 16 384 steps
|
||||
to white; f16 has 2 048 in the top octave, and a composite that is going to
|
||||
be re-developed deserves the sensor's precision. The cost is 2× on buffers
|
||||
FR-MRG-11 already bounds.
|
||||
|
||||
**What the DNG carries as a consequence:** the first source's `Make`,
|
||||
`Model` and `UniqueCameraModel` — so `base_curve::for_body` finds the 6D's
|
||||
curve — its `ColorMatrix1`/`2` with illuminants, and its `AsShotNeutral`. The
|
||||
composite then develops through the same profile as its sources, applied
|
||||
once. The spike's 64 × 48 file (§8) already carries the matrix and neutral;
|
||||
the body name is a string.
|
||||
|
||||
## 6. The keypoint model
|
||||
|
||||
FR-MRG-8: works without weights, better with them. The licence read comes
|
||||
|
||||
Reference in New Issue
Block a user