Memory Management

C++

struct LinearBVHNode {
    Bounds3f bounds;
    union {
        int primitivesOffset;   // leaf
        int secondChildOffset;  // interior
    };
    uint16_t nPrimitives;  // 0 -> interior node
    uint8_t axis;          // interior node: xyz
    uint8_t pad[1];        // ensure 32 byte total size
};
...
BVHAccel::BVHAccel(std::vector<std::shared_ptr<Primitive>> p,
                   int maxPrimsInNode, SplitMethod splitMethod)
    : maxPrimsInNode(std::min(255, maxPrimsInNode)),
      splitMethod(splitMethod),
      primitives(std::move(p)) {
...
    MemoryArena arena(1024 * 1024);
...
    nodes = AllocAligned<LinearBVHNode>(totalNodes);
    int offset = 0;
    flattenBVHTree(root, &offset);
    CHECK_EQ(totalNodes, offset);
}
(gdb) file ~/builds/pbrt/debug/pbrt
(gdb) set args --nthreads 1 ganesha.pbrt
(gdb) b bvh.cpp:222
# get start address of the MemoryArena
(gdb) p /x arena->currentBlock
0x5555a4ebe000
# 32 bytes for each LinearBVHNode entry
(gdb) x/64wf 0x5555a4ebe000
# entry 1
0x5555a4ebe000: 290.87381       -41.5167999     -6.64449692     291.004791
0x5555a4ebe010: -41.4891701     -6.51357698     0       0
# entry 2
0x5555a4ebe020: 0       0       0       6.05380134e-39
0x5555a4ebe030: 1.40129846e-45  0       0       0
# entry 3
0x5555a4ebe040: 290.87381       -41.523941      -6.64449692     291.004791
0x5555a4ebe050: -41.4990196     -6.51357698     0       0
# entry 4
0x5555a4ebe060: 0       0       0       6.05380275e-39
0x5555a4ebe070: 1.40129846e-45  0       0       0
# entry 5
0x5555a4ebe080: 290.87381       -41.5853195     -6.90634203     291.266602
0x5555a4ebe090: -41.4515114     -6.64449692     -1.0229871e-16  3.0611365e-41
# entry 6
0x5555a4ebe0a0: -1.02295746e-16 3.0611365e-41   0       0
0x5555a4ebe0b0: 0       0       0       0
# entry 7
0x5555a4ebe0c0: 291.135712      -41.5853195     -6.90634203     291.266602
0x5555a4ebe0d0: -41.5323792     -6.64449692     -1.0229744e-16  3.0611365e-41
# entry 8
0x5555a4ebe0e0: -1.02296169e-16 3.0611365e-41   2.80259693e-45  0
0x5555a4ebe0f0: 0       0       0       0
# entry 5 and 7 are interesting (last 2 float values are != 0.0)
# but what do they really contain?
(gdb) x/2wd 0x5555a4ebe098
0x5555a4ebe098: -1528044928     21845
(gdb) x/4hd 0x5555a4ebe098
0x5555a4ebe098: -7552   -23317  21845   0
# that means entry 5 has 21845 Primitives

From the log:

BVH created with 7296745 nodes for 4323664 primitives (222.68 MB), arena allocated 446.00 MB

Rust

(gdb) b bvh.rs:166
(gdb) next
(gdb) p nodes
  Point3<f32> {x: -672, y: -42.3607292, z: -1000}, 
  Point3<f32> {x: 1328, y: 238.63269, z: 1000}, 
  offset: 3448876, n_primitives: 0, axis: 2, 
  Point3<f32> {x: 220, y: -42.3607292, z: -343.628326}, 
  Point3<f32> {x: 400, y: 238.63269, z: 0.0952380002}, 
  offset: 3, n_primitives: 0, axis: 2,
  Point3<f32> {x: 220, y: 61.3673019, z: -343.628326}
  Point3<f32> {x: 400, y: 238.63269, z: -312.371674}, 
  offset: 4323662, n_primitives: 2, axis: 0,
  Point3<f32> {x: 287.422211, y: -42.3607292, z: -14.1522799}, 
  Point3<f32> {x: 364.254913, y: 62.4432106, z: 0.0952380002}, 
  offset: 1748659, n_primitives: 0, axis: 1,
  Point3<f32> {x: 287.422211, y: -42.3607292, z: -13.6162205}, 
  Point3<f32> {x: 364.254913, y: 10.1114397, z: 0.0952380002}, 
  offset: 914162, n_primitives: 0, axis: 0},
  Point3<f32> {x: 287.422211, y: -42.3607292, z: -13.6162205}, 
  Point3<f32> {x: 325.960785, y: 10.1009398, z: 0.0324900001}, 
  offset: 417645, n_primitives: 0, axis: 1,
  Point3<f32> {x: 288.542114, y: -42.3607292, z: -12.8308096}, 
  Point3<f32> {x: 325.835693, y: -16.1148605, z: 0.0324900001}, 
  offset: 231158, n_primitives: 0, axis: 0,