Fix terrain loss after map transition and GPU crash on WMO-only maps

Three fixes:
1. Water captureSceneHistory gated on hasSurfaces() — the image layout
   transitions (PRESENT_SRC→TRANSFER_SRC→PRESENT_SRC) were running every
   frame even on WMO-only maps with no water, causing VK_ERROR_DEVICE_LOST.

2. Tile cache invalidation: softReset() now clears tileCache_ since cache
   keys are (x,y) without map name — prevents stale cross-map cache hits.

3. Copy terrain/mesh into TerrainTile instead of std::move — the moved-from
   PendingTile was cached with empty data, so subsequent map loads returned
   tiles with 0 valid chunks from cache.

Also adds diagnostic skip env vars (WOWEE_SKIP_TERRAIN, WOWEE_SKIP_SKY,
WOWEE_SKIP_PREPASSES) and a 0-chunk warning in loadTerrain.
This commit is contained in:
Kelsi 2026-03-02 09:52:09 -08:00
parent 5519c73f5c
commit 335b1b1c3a
3 changed files with 34 additions and 12 deletions

View file

@ -912,8 +912,8 @@ bool TerrainManager::advanceFinalization(FinalizingTile& ft) {
// Commit tile to loadedTiles
auto tile = std::make_unique<TerrainTile>();
tile->coord = coord;
tile->terrain = std::move(pending->terrain);
tile->mesh = std::move(pending->mesh);
tile->terrain = pending->terrain; // copy (not move) — pending is cached for reuse
tile->mesh = pending->mesh; // copy (not move) — pending is cached for reuse
tile->loaded = true;
tile->m2InstanceIds = std::move(ft.m2InstanceIds);
tile->wmoInstanceIds = std::move(ft.wmoInstanceIds);
@ -1357,7 +1357,16 @@ void TerrainManager::softReset() {
finalizingTiles_.clear();
placedDoodadIds.clear();
LOG_INFO("Soft-resetting terrain (clearing tiles + water, workers stay alive)");
// Clear tile cache — keys are (x,y) without map name, so stale entries from
// a different map with overlapping coordinates would produce wrong geometry.
{
std::lock_guard<std::mutex> lock(tileCacheMutex_);
tileCache_.clear();
tileCacheLru_.clear();
tileCacheBytes_ = 0;
}
LOG_INFO("Soft-resetting terrain (clearing tiles + water + cache, workers stay alive)");
loadedTiles.clear();
failedTiles.clear();