Add a per-frame triangle budget for new geometry materialization#150
Open
BinqAdams wants to merge 1 commit into
Open
Add a per-frame triangle budget for new geometry materialization#150BinqAdams wants to merge 1 commit into
BinqAdams wants to merge 1 commit into
Conversation
New geometry materialization (vertex upload, interleave and BLAS build) runs synchronously in the draw submission path, so a burst of newly visible meshes, for example after camera rotation brings previously culled objects back into the frustum, lands in a single frame as one monolithic spike. Textures and opacity micromaps already have async streaming and per-frame build budgets respectively; geometry has no equivalent mechanism. When rtx.materializationBudgetTrianglesPerFrame is greater than zero, new geometry (DrawCallCache misses) is admitted while the frame's running triangle counter is under the budget; the final admission may overshoot by one mesh so a single mesh larger than the whole budget still loads. Over-budget draws are skipped without creating any state and retried on later frames: original draws through the game's own per-frame resubmission, replacement prims through a new ReplacementInstance::pendingMaterialization pending-work flag that keeps the instance off the preserve path until a pass defers nothing. Deferral trades the spike for one to three frames of pop-in at the frustum edge. Default 0 preserves existing behavior exactly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New geometry materialization (vertex upload, interleave and BLAS build) runs synchronously in the draw submission path. A burst of newly visible meshes, for example when camera rotation brings previously culled objects back into the frustum, therefore lands in a single frame as one monolithic spike. Textures and opacity micromaps already have async streaming and per-frame build budgets respectively; geometry has no equivalent mechanism.
When
rtx.materializationBudgetTrianglesPerFrameis greater than zero, new geometry (DrawCallCache misses) is admitted while the frame's running triangle counter is under the budget. The final admission may overshoot by one mesh, so a single mesh larger than the whole budget still loads. Over-budget draws are skipped without creating any state and retried on later frames: original draws through the game's own per-frame resubmission, replacement prims through a newReplacementInstance::pendingMaterializationpending-work flag that keeps the instance off the preserve path until a pass defers nothing. Deferral trades the spike for one to three frames of pop-in at the frustum edge, where it is effectively invisible.Default
0preserves existing behavior exactly.Testing
Test game: Painkiller Black Edition with a USD mod containing mesh replacements (the case that motivated the change; any content where many replaced or new meshes enter the view at once will do).
rtx.materializationBudgetTrianglesPerFrame = 500000inrtx.conf.Before the change: each turn produces frame spikes of roughly 35 ms (measured via Tracy: the dxvk-cs thread stalls in geometry upload and BLAS build for the re-entering meshes, largest single offender 1.68M triangles in the test content).
After the change: the spikes are gone; per-frame new-geometry work is bounded by the budget. Deferred meshes appear within one to three frames. Verified with an instance-lifecycle log that deferred draws are retried and materialize (largest deferral observed resolved in 2 frames), and specifically that replacement prims deferred while their
ReplacementInstanceis being set up still materialize instead of persisting as holes; level geometry, pickups and effects all present after sustained play, level changes and reloads.With the option at its default
0, behavior is unchanged.