Skip to content

Fix two out-of-bounds cache accesses causing device loss under dense caches (#4, #5) - #6

Open
halukoral wants to merge 2 commits into
NVIDIA-RTX:mainfrom
halukoral:fix/oob-invalid-index-and-resolve-probe
Open

Fix two out-of-bounds cache accesses causing device loss under dense caches (#4, #5)#6
halukoral wants to merge 2 commits into
NVIDIA-RTX:mainfrom
halukoral:fix/oob-invalid-index-and-resolve-probe

Conversation

@halukoral

Copy link
Copy Markdown

Fixes #4, fixes #5 — two independent out-of-bounds accesses, both surfacing as
VK_ERROR_DEVICE_LOST once the hash table becomes dense (large sceneScale,
geometry-dense views).

With both fixes our previously 100%-reproducing case (25k–100k instance dynamic
scene, sceneScale 100, capacity 2^22, Vulkan/GLSL path with
SHARC_ENABLE_RESPONSIVE_LIGHTING=1 + SHARC_ENABLE_SH_ENCODING=1) runs
indefinitely without device loss.

…fore the cache-index mask

When a hash-grid bucket is full, HashGridInsertEntry returns
HASH_GRID_INVALID_CACHE_INDEX and SharcUpdateHit stores that sentinel
into sharcState.cacheIndices verbatim. The propagation loops in
SharcUpdateHit and SharcUpdateMiss then run the stored index through an
unconditional '& SHARC_CACHE_INDEX_BIT_MASK' (compiled in whenever
SHARC_ENABLE_RESPONSIVE_LIGHTING is defined, regardless of the runtime
toggle), which rewrites 0xFFFFFFFF to SHARC_CACHE_INDEX_BIT_MASK. That
forged value passes SharcAddVoxelData's INVALID guard and the
interlocked adds land ~2 GiB past the accumulation buffer (with the
default 26-bit index layout and the 32-byte SH accumulation stride),
losing the device once the table gets dense enough for buckets to fill.

Verified against a driver-reported fault address: the faulting page was
exactly accumulationBase + SHARC_CACHE_INDEX_BIT_MASK * 32 rounded to
page granularity, bit-identical across independent device losses.

Skip the sentinel at the top of both loops, before the responsive
offset code: a post-mask compare would not be enough because
SharcGetResponsiveIndexOffset can shift the sentinel first when
responsive lighting is enabled at runtime.

Fixes NVIDIA-RTX#4
The sampleNumPrev == 0 recovery path probes forward blindly by
SHARC_LINEAR_PROBE_WINDOW_SIZE entries. An application is allowed to
allocate exactly 'capacity' entries per buffer (as the samples do), so
for entries in the last probe window this loop reads past the end of
both the hash-entry and resolved buffers. With buffer-device-address
access there is no robustness backstop, and once the high table slots
become occupied the read crosses the allocation's last page and the
device is lost. Before those slots fill up the loop breaks early on
empty keys (HASH_GRID_LIMIT_EMPTY_SLOTS), which is why the bug hides in
light scenes.

HashGridGetBaseSlot keeps normal bucket probes in range; this
entry-relative probe needs its own clamp.

Fixes NVIDIA-RTX#5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment