==> tests/scenes.c <==1/* pathtrace-core's default_scene_is_valid and payload_digest_and_set (the set half), every
2 * validation rule on a mutated default scene with the codes the Rust returns, and job scenes with a
3 * golden digest from the Rust. */
4#include "pathtrace/job_scene.h"
5
6#include "pathtrace/scene.h"
7#include "pathtrace/view.h"
8
9#include <stdio.h>
10#include <string.h>
11
12static int failures;
13#define CHECK(c) \
14 do { \
15 if (!(c)) { \
16 fprintf(stderr, "%s:%d: CHECK(%s) failed\n", __FILE__, __LINE__, #c); \
17 failures++; \
18 } \
19 } while (0)
20
21#define N PT_DEFAULT_SCENE_WORDS
22
23int main(void) {
24 static uint32_t b[N];
25 CHECK(pt_validate(pt_default_scene, N) == 0);
26 CHECK(pt_tiles(pt_default_scene) == 300);
27 memcpy(b, pt_default_scene, sizeof b);
28 b[PT_H_WIDTH] = 600;
29 CHECK(pt_validate(b, N) == 4);
30
31 /* Codes, as the Rust returns them (gold pathtrace "validate"). */
32 CHECK(pt_validate(pt_default_scene, 20) == 1);
33 const struct {
34 size_t word;
35 uint32_t value, code;
36 } muts[15] = {{PT_H_MAGIC, 1, 2}, {PT_H_VERSION, 2, 2}, {PT_H_WORDS, 2000, 3}, {PT_H_WORDS, 551, 7},
37 {PT_H_WIDTH, 600, 4}, {PT_H_HEIGHT, 0, 4}, {PT_H_SPP, 0, 5}, {PT_H_PASSES, 5000, 5},
38 {PT_H_DEPTH, 17, 5}, {PT_H_NMAT, 0, 6}, {PT_H_NQUAD, 65, 6}, {PT_H_NTRI, 19, 7},
39 {PT_HEADER_WORDS, 9, 8}, {PT_H_LIGHT, 6, 10}, {PT_H_LIGHT, 0xffffffffu, 0}};
40 for (int i = 0; i < 15; i++) {
41 memcpy(b, pt_default_scene, sizeof b);
42 b[muts[i].word] = muts[i].value;
43 if (pt_validate(b, N) != muts[i].code) {
44 fprintf(stderr, "word %zu := %u: code %u, want %u\n", muts[i].word, muts[i].value, pt_validate(b, N),
45 muts[i].code);
46 failures++;
47 }
48 }
49 pt_layout l = pt_layout_of(pt_default_scene);
50 const size_t mat_words[3] = {l.quad + 15, l.sph + 5, l.tri + 12};
51 for (int i = 0; i < 3; i++) {
52 memcpy(b, pt_default_scene, sizeof b);
53 b[mat_words[i]] = 99;
54 CHECK(pt_validate(b, N) == 9);
55 }
56
57 /* OP_SET's args set exactly the settable words. */
58 memcpy(b, pt_default_scene, sizeof b);
59 CHECK(pt_set_param(b, N, pt_set_arg(PT_H_WIDTH, 1280)) && pt_set_param(b, N, pt_set_arg(PT_H_HEIGHT, 720)) &&
60 pt_set_param(b, N, pt_set_arg(PT_H_SPP, 32)));
61 CHECK(!pt_set_param(b, N, pt_set_arg(PT_H_WORDS, 7)) && !pt_set_param(b, N, pt_set_arg(PT_H_MAGIC, 1)));
62 CHECK(b[PT_H_WIDTH] == 1280 && b[PT_H_HEIGHT] == 720 && b[PT_H_SPP] == 32 && pt_tiles(b) == 1200);
63 CHECK(pt_validate(b, N) == 4);
64 CHECK(pt_validate_in(b, N, PT_FLEET_MAX_TILES) == 0);
65
66 /* Job scenes (gold pathtrace "job_scene"). */
67 const pt_setup_task setup[4] = {{PT_OP_SET, pt_set_arg(PT_H_WIDTH, 2048)},
68 {PT_OP_SET, pt_set_arg(PT_H_HEIGHT, 1536)},
69 {PT_OP_DEFAULT, 0},
70 {PT_OP_SET, pt_set_arg(PT_H_SPP, 3)}};
71 CHECK(pt_job_scene(setup, 4, b) == -1);
72 uint64_t h = 0xcbf29ce484222325ull;
73 for (size_t i = 0; i < N; i++) h = (h ^ b[i]) * 0x100000001b3ull;
74 CHECK(h == 0x3e59d8a64c44a945ull);
75 const pt_setup_task bad1[1] = {{PT_OP_SET, pt_set_arg(PT_H_WORDS, 1)}};
76 const pt_setup_task bad2[2] = {{PT_OP_DEFAULT, 0}, {9, 0}};
77 CHECK(pt_job_scene(bad1, 1, b) == 0);
78 CHECK(pt_job_scene(bad2, 2, b) == 1);
79 return failures != 0;
80}