==> src/scene.c <==1/* The scene format's layout, validation and settable words (pathtrace-core lib.rs). */
2#include "pathtrace/scene.h"
3
4const size_t pt_settable[PT_SETTABLE_COUNT] = {PT_H_WIDTH, PT_H_HEIGHT, PT_H_SPP,
5 PT_H_PASSES, PT_H_DEPTH, PT_H_SEED};
6
7pt_layout pt_layout_of(const uint32_t *sc) {
8 pt_layout l;
9 uint32_t nmat = sc[PT_H_NMAT];
10 l.nquad = sc[PT_H_NQUAD];
11 l.nsph = sc[PT_H_NSPH];
12 l.ntri = sc[PT_H_NTRI];
13 l.mat = PT_HEADER_WORDS;
14 l.quad = l.mat + PT_MAT_WORDS * (size_t)nmat;
15 l.sph = l.quad + PT_QUAD_WORDS * (size_t)l.nquad;
16 l.tri = l.sph + PT_SPH_WORDS * (size_t)l.nsph;
17 l.light = sc[PT_H_LIGHT];
18 return l;
19}
20
21uint32_t pt_validate(const uint32_t *sc, size_t len) { return pt_validate_in(sc, len, PT_MAX_TILES); }
22
23uint32_t pt_validate_in(const uint32_t *sc, size_t len, uint32_t max_tiles) {
24 if (len < PT_HEADER_WORDS) return 1;
25 if (sc[PT_H_MAGIC] != PT_MAGIC_SCENE || sc[PT_H_VERSION] != PT_VERSION) return 2;
26 size_t words = sc[PT_H_WORDS];
27 if (words > len || words > PT_SCENE_MAX_WORDS) return 3;
28 uint32_t w = sc[PT_H_WIDTH], h = sc[PT_H_HEIGHT];
29 if (w == 0 || h == 0 || w % PT_TILE_W != 0 || h % PT_TILE_H != 0 ||
30 (uint64_t)(w / PT_TILE_W) * (h / PT_TILE_H) > max_tiles)
31 return 4;
32 if (sc[PT_H_SPP] < 1 || sc[PT_H_SPP] > 1024 || sc[PT_H_PASSES] < 1 || sc[PT_H_PASSES] > 4096 ||
33 sc[PT_H_DEPTH] < 1 || sc[PT_H_DEPTH] > 16)
34 return 5;
35 uint32_t nmat = sc[PT_H_NMAT], nquad = sc[PT_H_NQUAD], nsph = sc[PT_H_NSPH], ntri = sc[PT_H_NTRI];
36 if (nmat == 0 || nmat > 64 || nquad > 64 || nsph > 64 || ntri > 64) return 6;
37 pt_layout l = pt_layout_of(sc);
38 if (l.tri + PT_TRI_WORDS * (size_t)ntri != words) return 7;
39 for (size_t i = 0; i < nmat; i++)
40 if (sc[l.mat + PT_MAT_WORDS * i] > PT_EMIT) return 8;
41 for (size_t i = 0; i < nquad; i++)
42 if (sc[l.quad + PT_QUAD_WORDS * i + 15] >= nmat) return 9;
43 for (size_t i = 0; i < nsph; i++)
44 if (sc[l.sph + PT_SPH_WORDS * i + 5] >= nmat) return 9;
45 for (size_t i = 0; i < ntri; i++)
46 if (sc[l.tri + PT_TRI_WORDS * i + 12] >= nmat) return 9;
47 if (sc[PT_H_LIGHT] != PT_NO_LIGHT && sc[PT_H_LIGHT] >= nquad) return 10;
48 return 0;
49}
50
51bool pt_set_param(uint32_t *sc, size_t len, uint32_t arg) {
52 size_t word = arg >> 24;
53 uint32_t value = arg & 0x00ffffffu;
54 bool settable = false;
55 for (int i = 0; i < PT_SETTABLE_COUNT; i++) settable |= pt_settable[i] == word;
56 if (!settable || word >= len) return false;
57 sc[word] = value;
58 return true;
59}