mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-16 10:34:31 +00:00
wgpu: probed-size pool replaces per-chunk createBuffer
Drops the per-machine "guess the OOM ceiling" budget knob in favour of a single buffer pool whose capacity is *probed* at device-init time. The runtime answers the question: descend from min(maxBufferSize, 4 GB) through OOM error scopes, accept the largest size that allocates cleanly. On a desktop wgpu-native v29 box this lands at 2 GB; on browser-class platforms it'll land at 256 MB – 1 GB depending on the implementation. Same code path either way. Architecture: - WgpuBufferPool (new): single WGPUBuffer + free-list sub-allocator with adjacent-range coalescing and first-fit. 256 B alignment for storage-binding offsets. - Chunks now hold (pool_vertex_offset, pool_vertex_size) and (pool_index_offset, pool_index_size) instead of per-chunk WGPUBuffer handles. Load = pool.alloc + queueWriteBuffer. Unload = pool.free. - Bind groups bind pool_.buffer() at the chunk's specific (offset, size) for both the vertex and index storage bindings. - Eviction queries pool.largest_free_run_bytes() instead of a tracked budget; the two-phase LRU/distance evictor's policy is unchanged. What this fixes: - No more gpu-alloc-rs fragmentation OOM: one VkDeviceMemory block instead of N per-chunk blocks with rounding overhead. On the test dataset (~3 GB on disk, 562 k visible instances) the wgpu backend now runs through to render without OOM at any point. - No --streaming-vram-mb knob, no hardcoded budget constant, no per-machine calibration. The pool size adapts to whatever the runtime grants. Notes: - Error scope probing: wgpu-native v29 classifies "Not enough memory left" as WGPUErrorType_Validation, not OutOfMemory. We push both filters (nested) and treat either firing as probe failure. - The 4 GB probe cap is principled, not magic: above that, wgpu-native's advertised maxBufferSize is sometimes a sentinel (1 TB) that just forces wasteful halving steps. 4 GB is the largest buffer any realistic WebGPU implementation will grant a single allocation today. - Pool destroy()/release happens after model release in shutdown() so the underlying buffer outlives every bind group that references it. Follow-ups: spatial chunking (task #22) for finer eviction granularity; cull perf needs work at 100+ models / 1M+ instances (separate from streaming concerns). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -62,10 +62,6 @@ int main(int argc, char* argv[]) {
|
||||
"Enable streaming sidecar load. Reads metadata-only at load time; "
|
||||
"vertex chunks are deferred and loaded on demand as they become "
|
||||
"frustum-visible. Required for scenes that exceed GPU memory."});
|
||||
parser.addOption({"streaming-vram-mb",
|
||||
"Set the streaming residency budget in MB (default 1900). Tune "
|
||||
"down to test browser-class memory ceilings; tune up if your GPU "
|
||||
"+ driver are happy with larger allocations.", "mb"});
|
||||
parser.process(app);
|
||||
|
||||
auto* viewport = new WgpuViewportWindow;
|
||||
@@ -74,16 +70,6 @@ int main(int argc, char* argv[]) {
|
||||
if (parser.isSet("web-limits")) viewport->web_limits_ = true;
|
||||
if (parser.isSet("bvh")) viewport->bvh_enabled_ = true;
|
||||
if (parser.isSet("streaming")) viewport->streaming_enabled_ = true;
|
||||
if (parser.isSet("streaming-vram-mb")) {
|
||||
bool ok = false;
|
||||
const uint64_t mb = parser.value("streaming-vram-mb").toULongLong(&ok);
|
||||
if (ok && mb > 0) {
|
||||
viewport->streaming_vram_budget_bytes_ = mb * 1024ull * 1024ull;
|
||||
} else {
|
||||
qWarning() << "--streaming-vram-mb: failed to parse"
|
||||
<< parser.value("streaming-vram-mb");
|
||||
}
|
||||
}
|
||||
|
||||
QWidget* container = QWidget::createWindowContainer(viewport);
|
||||
container->setMinimumSize(320, 240);
|
||||
|
||||
Reference in New Issue
Block a user