From 61adb4a803ddfbee78690f4f126b24db16b57410 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 13 Mar 2026 02:33:02 -0700 Subject: [PATCH] fix: free terrain descriptor sets when unloading mid-finalization tiles When unloadTile() was called for a tile still in finalizingTiles_ (mid-incremental-finalization), terrain chunks already uploaded to the GPU (terrainMeshDone=true) were not being cleaned up. The early-return path correctly removed water and M2/WMO instances but missed calling terrainRenderer->removeTile(), causing descriptor sets to leak. After ~20 minutes of play the VkDescriptorPool (MAX_MATERIAL_SETS=16384) filled up, causing all subsequent terrain material allocations to fail and the log to flood with "failed to allocate material descriptor set". Fix: check fit->terrainMeshDone before the early return and call terrainRenderer->removeTile() to free those descriptor sets. --- src/rendering/terrain_manager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rendering/terrain_manager.cpp b/src/rendering/terrain_manager.cpp index 579a909a..340b242d 100644 --- a/src/rendering/terrain_manager.cpp +++ b/src/rendering/terrain_manager.cpp @@ -1377,6 +1377,10 @@ void TerrainManager::unloadTile(int x, int y) { // Water may have already been loaded in TERRAIN phase, so clean it up. for (auto fit = finalizingTiles_.begin(); fit != finalizingTiles_.end(); ++fit) { if (fit->pending && fit->pending->coord == coord) { + // If terrain chunks were already uploaded, free their descriptor sets + if (fit->terrainMeshDone && terrainRenderer) { + terrainRenderer->removeTile(x, y); + } // If past TERRAIN phase, water was already loaded — remove it if (fit->phase != FinalizationPhase::TERRAIN && waterRenderer) { waterRenderer->removeTile(x, y);