diff options
| author | Sssnowyyy <78863999+Sssnowyyy@users.noreply.github.com> | 2026-11-02 11:29:14 -0500 |
|---|---|---|
| committer | Sssnowyyy <78863999+Sssnowyyy@users.noreply.github.com> | 2026-11-02 14:53:47 -0500 |
| commit | 8b0666b74868da8221d9e3ef3995f3a862ee24b6 (patch) | |
| tree | 5537f23ab1306475a2df29bda7637058a11d8501 | |
| parent | bda49e810b5955bff8474e7b8f2b09eab51e9be2 (diff) | |
shader: restore the handle build depth when a build throws
BuildHandleProgram incremented g_handle_depth and decremented it at the end, so
a NotImplementedException from BuildHandleNode left the thread-local depth above
zero. That thread never cleared g_handle_slots again, and stale IR::Inst* keys
from an earlier program could match instructions of a later one (a freed
instruction's address can be reused). Do the decrement and the outermost clear in
SCOPE_EXIT.
Follow-up to e23b0f2fab.
Assisted-by: Claude Sonnet 5.5 (implementation and commit message)
| -rw-r--r-- | src/shader_recompiler/ir_opt/texture_pass.cpp | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index db8f1ac716..b33700cabd 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp @@ -16,6 +16,7 @@ #include <limits> #include <boost/container/small_vector.hpp> +#include "common/scope_exit.h" #include "common/settings.h" #include "shader_recompiler/environment.h" #include "shader_recompiler/frontend/ir/basic_block.h" @@ -455,6 +456,12 @@ bool BuildHandleProgram(const IR::Value& value, std::vector<u32>& code, int& bud if (outermost) { g_handle_slots.clear(); } + SCOPE_EXIT { + --g_handle_depth; + if (outermost) { + g_handle_slots.clear(); + } + }; const IR::Inst* const inst{value.InstRecursive()}; bool result; if (const auto it = g_handle_slots.find(inst); it != g_handle_slots.end()) { @@ -484,10 +491,6 @@ bool BuildHandleProgram(const IR::Value& value, std::vector<u32>& code, int& bud code.push_back(slot); } } - --g_handle_depth; - if (outermost) { - g_handle_slots.clear(); - } return result; } |
