fix(rendering): retire mesh geometry slot on actor delete - #640
Merged
Conversation
… rewrite
Rendering:
- Register GbufferPass in render graph; was outputting black via dead BasePass
- Fix magenta background: shaderInt64 device feature not enabled, GbufferPass
Execute was returning before BeginRenderPass when no mesh in scene
- Split vertex_common.glsl / fragment_common.glsl into geometry_bindings.glsl,
texture_bindings.glsl, material.glsl, draw.glsl, draw_types.glsl, surface.glsl
to stop Int64/sampler extensions leaking into geometry-only shader stages
- Redesign RenderPass API: binding-number reflection, BindingsByName O(1) map,
arena-safe SetName/SetPipelineName, pipeline+shader name in error messages
- Fix ImGUIRenderer: remove stale SetSampler("LinearWrapSampler") call
Asset reload (second launch):
- IsAssetExtension: add .zemesh and .zematerial so VFSScanner processes them
- InferTypeFromExtension: map .zematerial -> MATERIAL (was falling through to MESH)
- ImguiLayer: set Scanner.SetAssetRegistry and post startup TriggerScan
- Add AssetManager::ReloadFromDisk — deserializes each unloaded MATERIAL/MESH
record from disk and calls IngestMaterial/IngestMesh
- Fix pre-existing buffer overflow in IngestMesh: sizeof(AssetNodeHierarchy)
used instead of sizeof(NodeHierarchy) for the Hierarchies memcpy, overflowing
308 KB past the allocated block and corrupting the NodeNames hash map
Containers:
- Rewrite UnorderedHashMap: power-of-2 capacity, linear probing with bitmask,
Array::init(cap,cap) + secure_memset(0), guard_load assertion at 75%
- Fix secure_memset arg order: (dst, value, count, dst_size) was swapped,
leaving all entry state bytes as garbage instead of EntryState::Empty
- Rewrite HashMap (ordered): same fixes; per-slot default construction since
prev/next must be size_type(-1), not 0
- 55 edge-case tests: power-of-2, tombstone reuse, collision cluster, large
batch, ordered insertion invariants, sort_keys idempotent
When a mesh actor was deleted from the outliner RemoveMeshInstance removed the draw-indirect entry but never freed the MeshSlot in the RRM, so the slot index was permanently consumed for the session. - RenderResourceManager::ReleaseMeshGeometry(uuid): frees the MeshSlot (sets Generation=0 so AllocMeshSlot can reuse it) and removes the entry from m_uuid_to_buffer. The VB/IB bytes are not reclaimed — the global geometry buffer is append-only — but the slot is available for reuse. - RenderScene::RemoveMeshInstance: checks if any remaining instance shares the same MeshUUID before releasing; only calls ReleaseMeshGeometry when the deleted instance was the last reference to that mesh. - HierarchyViewUIComponent: passes ctx->RenderResourceManager to RemoveMeshInstance so the slot is freed at delete time. - RenderScene.h: forward-declares RenderResourceManager to avoid pulling the full header into every TU that includes RenderScene.h.
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.
Closes #639
What
When a mesh actor was deleted from the outliner,
RemoveMeshInstanceremoved the draw-indirect entry but never freed theMeshSlotin the RRM. The slot index was permanently consumed for the session — repeated import-and-delete cycles would silently exhaustMAX_BUFFERS.Changes
RenderResourceManager::ReleaseMeshGeometry(uuid)— frees theMeshSlot(setsGeneration=0soAllocMeshSlotcan reuse it) and removes the entry fromm_uuid_to_buffer. The VB/IB bytes are not reclaimed (append-only buffer) but the slot is available for futureUploadMeshcalls.RenderScene::RemoveMeshInstance— checks if any remaining instance shares the sameMeshUUIDbefore releasing; only callsReleaseMeshGeometrywhen the deleted instance was the last reference to that mesh (handles multiple instances of the same asset).HierarchyViewUIComponent— passesctx->RenderResourceManagertoRemoveMeshInstanceat delete time.RenderScene.h— forward-declaresRenderResourceManagerto avoid pulling the full header into every TU that includesRenderScene.h.Known limitation
VB/IB bytes are not reclaimed — the global geometry buffer is append-only. Freed slots can be reused for new uploads but the original byte range in the buffer remains occupied. A future compaction pass would be needed to fully reclaim that space (tracked separately).
Test plan
[RRM] Released mesh geometry slotlog appears