skip to content
==> 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}