==> include/pathtrace/t_tile.h <==1/* Template (included once per instantiation after t_math, t_intersect, t_sample and t_tonemap; see
2 * pathtrace/real.h): a tile's columns (one column a lane of a warp, or 32 columns in a loop on one
3 * CPU or wasm thread) and whole tiles. A column is PT_TILE_H pixels, top to bottom; a tile's pixels
4 * are PT_TILE_PIX, row-major. Digests are FNV-1a 64 (@ajax/pathtrace-digest). */
5#include "pathtrace/digest.h"
6#include "pathtrace/real.h"
7#include "pathtrace/scene.h"
8
9/* FNV-1a 64 over a column's r g b words, rows top to bottom. */
10PT_API uint64_t PT_FN(col_digest)(const pt_v c[PT_TILE_H]) {
11 uint64_t h = PT_FNV_OFFSET;
12 for (uint32_t r = 0; r < PT_TILE_H; r++) h = pt_fnv(pt_fnv(pt_fnv(h, pt_to_bits(c[r].x)), pt_to_bits(c[r].y)), pt_to_bits(c[r].z));
13 return h;
14}
15
16/* Pass p of column cx of tile t: each pixel's pass sum (a work item's payload) into part; its digest. */
17PT_API uint64_t PT_FN(column_pass)(const uint32_t *sc, const pt_layout *l, uint32_t t, uint32_t cx, uint32_t p,
18 pt_v part[PT_TILE_H]) {
19 uint32_t x0, y0;
20 pt_tile_origin(sc, t, &x0, &y0);
21 for (uint32_t row = 0; row < PT_TILE_H; row++) part[row] = PT_FN(pixel_pass)(sc, l, x0 + cx, y0 + row, p);
22 return PT_FN(col_digest)(part);
23}
24
25/* Tone maps a column of accumulators (n = passes x S samples) into rgb; (acc digest, rgb digest). */
26PT_API void PT_FN(retone)(const uint32_t *sc, uint32_t passes, uint32_t op, const pt_v acc[PT_TILE_H],
27 uint32_t rgb[PT_TILE_H], uint64_t *acc_digest, uint64_t *rgb_digest) {
28 uint32_t n = passes * sc[PT_H_SPP];
29 float exposure = PT_FN(ldr)(sc, PT_H_EXPOSURE);
30 uint64_t hr = PT_FNV_OFFSET;
31 for (uint32_t row = 0; row < PT_TILE_H; row++) {
32 rgb[row] = PT_FN(tonemap)(acc[row], n, exposure, op);
33 hr = pt_fnv(hr, rgb[row]);
34 }
35 *acc_digest = PT_FN(col_digest)(acc);
36 *rgb_digest = hr;
37}
38
39/* One pass folded into a column's accumulators (acc + part; the caller keeps pass order), then the
40 * tone map with n = passes S samples: (acc digest, rgb digest). */
41PT_API void PT_FN(fold_column)(const uint32_t *sc, uint32_t passes, uint32_t op, pt_v acc[PT_TILE_H],
42 const pt_v part[PT_TILE_H], uint32_t rgb[PT_TILE_H], uint64_t *acc_digest,
43 uint64_t *rgb_digest) {
44 for (uint32_t row = 0; row < PT_TILE_H; row++) acc[row] = PT_FN(vadd)(acc[row], part[row]);
45 PT_FN(retone)(sc, passes, op, acc, rgb, acc_digest, rgb_digest);
46}
47
48static inline void PT_FN(col_of)(const pt_v *px, uint32_t cx, pt_v c[PT_TILE_H]) {
49 for (uint32_t row = 0; row < PT_TILE_H; row++) c[row] = px[row * PT_TILE_W + cx];
50}
51static inline void PT_FN(put_col)(pt_v *px, uint32_t cx, const pt_v c[PT_TILE_H]) {
52 for (uint32_t row = 0; row < PT_TILE_H; row++) px[row * PT_TILE_W + cx] = c[row];
53}
54
55/* Pass p of tile t into part (PT_TILE_PIX pixels): the tile's pass-sum digest. */
56PT_API uint64_t PT_FN(tile_pass)(const uint32_t *sc, uint32_t t, uint32_t p, pt_v *part) {
57 pt_layout l = pt_layout_of(sc);
58 uint64_t d[32];
59 for (uint32_t cx = 0; cx < PT_TILE_W; cx++) {
60 pt_v c[PT_TILE_H];
61 d[cx] = PT_FN(column_pass)(sc, &l, t, cx, p, c);
62 PT_FN(put_col)(part, cx, c);
63 }
64 return pt_fold(d);
65}
66
67/* acc += part over the tile, tone mapped with n = passes S into rgb: the tile digests (acc, rgb). */
68PT_API void PT_FN(tile_fold)(const uint32_t *sc, uint32_t passes, uint32_t op, pt_v *acc, const pt_v *part,
69 uint32_t *rgb, uint64_t *acc_digest, uint64_t *rgb_digest) {
70 uint64_t ca[32], cr[32];
71 for (uint32_t cx = 0; cx < PT_TILE_W; cx++) {
72 pt_v a[PT_TILE_H], pc[PT_TILE_H];
73 uint32_t r[PT_TILE_H];
74 PT_FN(col_of)(acc, cx, a);
75 PT_FN(col_of)(part, cx, pc);
76 PT_FN(fold_column)(sc, passes, op, a, pc, r, &ca[cx], &cr[cx]);
77 PT_FN(put_col)(acc, cx, a);
78 for (uint32_t row = 0; row < PT_TILE_H; row++) rgb[row * PT_TILE_W + cx] = r[row];
79 }
80 *acc_digest = pt_fold(ca);
81 *rgb_digest = pt_fold(cr);
82}
83
84/* Re-tones a tile's accumulators into rgb: its rgb digest. */
85PT_API uint64_t PT_FN(tile_retone)(const uint32_t *sc, uint32_t passes, uint32_t op, const pt_v *acc, uint32_t *rgb) {
86 uint64_t cr[32];
87 for (uint32_t cx = 0; cx < PT_TILE_W; cx++) {
88 pt_v a[PT_TILE_H];
89 uint32_t r[PT_TILE_H];
90 uint64_t ignored;
91 PT_FN(col_of)(acc, cx, a);
92 PT_FN(retone)(sc, passes, op, a, r, &ignored, &cr[cx]);
93 for (uint32_t row = 0; row < PT_TILE_H; row++) rgb[row * PT_TILE_W + cx] = r[row];
94 }
95 return pt_fold(cr);
96}