From 09c0fa5daf51c2284ae282b0eca84d479e0996da Mon Sep 17 00:00:00 2001 From: Jake Wang <2645794+jakezwang@users.noreply.github.com> Date: Mon, 12 Oct 2026 05:15:24 -0400 Subject: [PATCH] fix(shader): release bundled optimizer traversal maps --- core/shader/recompiler/CMakeLists.txt | 1 + core/shader/recompiler/PatchSpirvTools.cmake | 52 ++++++++++++++++++++ docs/dev/TechnicalDebt.md | 1 + 3 files changed, 54 insertions(+) create mode 100644 core/shader/recompiler/PatchSpirvTools.cmake diff --git a/core/shader/recompiler/CMakeLists.txt b/core/shader/recompiler/CMakeLists.txt index 6d3d68e2d..d4ff8cefa 100644 --- a/core/shader/recompiler/CMakeLists.txt +++ b/core/shader/recompiler/CMakeLists.txt @@ -12,6 +12,7 @@ function(add_shader_recompiler target runtimeTarget) set(SPIRV_WERROR OFF) set(BUILD_SHARED_LIBS OFF) add_subdirectory("${PROJECT_SOURCE_DIR}/3rdparty/SPIRV-Tools" "${CMAKE_BINARY_DIR}/3rdparty/SPIRV-Tools" EXCLUDE_FROM_ALL) + include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/PatchSpirvTools.cmake") endif() if(NOT TARGET glslang) diff --git a/core/shader/recompiler/PatchSpirvTools.cmake b/core/shader/recompiler/PatchSpirvTools.cmake new file mode 100644 index 000000000..2a6e17df0 --- /dev/null +++ b/core/shader/recompiler/PatchSpirvTools.cmake @@ -0,0 +1,52 @@ +get_target_property(spirvToolsSourceDir SPIRV-Tools-opt SOURCE_DIR) +set(spirvToolsRedundancySource "${spirvToolsSourceDir}/redundancy_elimination.cpp") +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${spirvToolsRedundancySource}") +file(READ "${spirvToolsRedundancySource}" spirvToolsRedundancy) + +set(spirvToolsOldTraversal [=[ + for (DominatorTreeNode* child : todo[next_node].node->children_) { + todo.push_back({child, todo[next_node].value_to_id_map}); + } +]=]) +set(spirvToolsNewTraversal [=[ + const auto& children = todo[next_node].node->children_; + for (size_t child_index = 0; child_index < children.size(); ++child_index) { + if (child_index + 1 == children.size()) { + todo.push_back({children[child_index], + std::move(todo[next_node].value_to_id_map)}); + } else { + todo.push_back({children[child_index], todo[next_node].value_to_id_map}); + } + } + todo[next_node].value_to_id_map.clear(); +]=]) +string(FIND "${spirvToolsRedundancy}" "${spirvToolsOldTraversal}" spirvToolsTraversalPosition) +if(spirvToolsTraversalPosition EQUAL -1) + message(FATAL_ERROR "SPIRV-Tools redundancy traversal has changed; review the local memory fix") +endif() +string(REPLACE "${spirvToolsOldTraversal}" "${spirvToolsNewTraversal}" spirvToolsRedundancy "${spirvToolsRedundancy}") +string(REPLACE "#include \"source/opt/redundancy_elimination.h\"\n" + "#include \"source/opt/redundancy_elimination.h\"\n\n#include \n" + spirvToolsRedundancy "${spirvToolsRedundancy}") + +set(spirvToolsPatchedDir "${CMAKE_BINARY_DIR}/3rdparty/SPIRV-Tools/patched") +set(spirvToolsPatchedSource "${spirvToolsPatchedDir}/redundancy_elimination.cpp") +file(MAKE_DIRECTORY "${spirvToolsPatchedDir}") +file(CONFIGURE OUTPUT "${spirvToolsPatchedSource}" CONTENT "${spirvToolsRedundancy}" @ONLY) + +get_target_property(spirvToolsSources SPIRV-Tools-opt SOURCES) +set(spirvToolsPatchedSources) +set(spirvToolsReplacements 0) +foreach(source IN LISTS spirvToolsSources) + get_filename_component(sourcePath "${source}" ABSOLUTE BASE_DIR "${spirvToolsSourceDir}") + if(sourcePath STREQUAL spirvToolsRedundancySource) + list(APPEND spirvToolsPatchedSources "${spirvToolsPatchedSource}") + math(EXPR spirvToolsReplacements "${spirvToolsReplacements} + 1") + else() + list(APPEND spirvToolsPatchedSources "${source}") + endif() +endforeach() +if(NOT spirvToolsReplacements EQUAL 1) + message(FATAL_ERROR "SPIRV-Tools optimizer sources have changed; review the local memory fix") +endif() +set_property(TARGET SPIRV-Tools-opt PROPERTY SOURCES "${spirvToolsPatchedSources}") diff --git a/docs/dev/TechnicalDebt.md b/docs/dev/TechnicalDebt.md index 446bdd0bc..3ea051993 100644 --- a/docs/dev/TechnicalDebt.md +++ b/docs/dev/TechnicalDebt.md @@ -2,6 +2,7 @@ ### Build +- The bundled [SPIRV-Tools build](../../core/shader/recompiler/PatchSpirvTools.cmake) replaces the redundancy-elimination source with a build-directory copy that releases processed traversal maps. Remove this patch when the pinned revision includes [SPIRV-Tools #6962](https://github.com/KhronosGroup/SPIRV-Tools/pull/6962). System-dependency builds need the fix in their installed SPIRV-Tools package. - Building on Windows requires a specific version of mingw - MinGW-w64 GCC 15.2.0 (`winlibs-gcc15`, `x86_64-ucrt-posix-seh`) - Even compiled prx libraries on Windows require nearby (static linking of these dependencies causes conflicts): - libgcc_s_seh-1.dll