fix: add negative cache for failed spell visual model loads

Spell visual M2 models that fail to load (missing file, empty model,
or GPU upload failure) were re-attempted on every subsequent spell cast,
causing repeated file I/O during combat. Now caches failed model IDs in
spellVisualFailedModels_ so they are skipped on subsequent attempts.
This commit is contained in:
Kelsi 2026-03-20 05:56:33 -07:00
parent 90edb3bc07
commit bda5bb0a2b
2 changed files with 8 additions and 0 deletions

View file

@ -7,6 +7,7 @@
#include <future>
#include <cstddef>
#include <unordered_map>
#include <unordered_set>
#include <glm/glm.hpp>
#include <vulkan/vulkan.h>
#include <vk_mem_alloc.h>
@ -343,6 +344,7 @@ private:
std::unordered_map<uint32_t, std::string> spellVisualCastPath_; // visualId → cast M2 path
std::unordered_map<uint32_t, std::string> spellVisualImpactPath_; // visualId → impact M2 path
std::unordered_map<std::string, uint32_t> spellVisualModelIds_; // M2 path → M2Renderer modelId
std::unordered_set<uint32_t> spellVisualFailedModels_; // modelIds that failed to load (negative cache)
uint32_t nextSpellVisualModelId_ = 999000; // Reserved range 999000-999799
bool spellVisualDbcLoaded_ = false;
void loadSpellVisualDbc();

View file

@ -2860,16 +2860,21 @@ void Renderer::playSpellVisual(uint32_t visualId, const glm::vec3& worldPosition
spellVisualModelIds_[modelPath] = modelId;
}
// Skip models that have previously failed to load (avoid repeated I/O)
if (spellVisualFailedModels_.count(modelId)) return;
// Load the M2 model if not already loaded
if (!m2Renderer->hasModel(modelId)) {
auto m2Data = cachedAssetManager->readFile(modelPath);
if (m2Data.empty()) {
LOG_DEBUG("SpellVisual: could not read model: ", modelPath);
spellVisualFailedModels_.insert(modelId);
return;
}
pipeline::M2Model model = pipeline::M2Loader::load(m2Data);
if (model.vertices.empty() && model.particleEmitters.empty()) {
LOG_DEBUG("SpellVisual: empty model: ", modelPath);
spellVisualFailedModels_.insert(modelId);
return;
}
// Load skin file for WotLK-format M2s
@ -2880,6 +2885,7 @@ void Renderer::playSpellVisual(uint32_t visualId, const glm::vec3& worldPosition
}
if (!m2Renderer->loadModel(model, modelId)) {
LOG_WARNING("SpellVisual: failed to load model to GPU: ", modelPath);
spellVisualFailedModels_.insert(modelId);
return;
}
LOG_DEBUG("SpellVisual: loaded model id=", modelId, " path=", modelPath);