feat(devkit): Devkit parallel compilation and slang support (AI GENERATED)#474
feat(devkit): Devkit parallel compilation and slang support (AI GENERATED)#474MohannedElfatih wants to merge 2 commits intoclshortfuse:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the devkit shader pipeline to support Slang-based disk shaders and SPIR-V inspection tools, and significantly reduces shader load time by parallelizing compilation across DXC/FXC/Slang.
Changes:
- Add Slang shader compilation support (including SPIR-V disassembly/decompilation helpers).
- Parallelize disk shader compilation in the watcher and add device-API–aware shader target resolution.
- Update CMake shader build to unify Slang/SPIR-V flags/paths and optionally emit validation/disassembly artifacts.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/shader_compiler_watcher.hpp | Adds Slang support, parallel compilation, and device-API–dependent target resolution. |
| src/utils/shader_compiler_slang.hpp | New Slang compiler runner plus SPIR-V disassembly/decompilation tooling via external executables. |
| src/utils/shader_compiler_directx.hpp | Makes DXC library loading thread-safe and introduces compile-time mutex toggles for parallelism. |
| src/addons/devkit/addon.cpp | Integrates Vulkan SPIR-V disassembly/decompilation and passes device API to the watcher. |
| CMakeLists.txt | Centralizes flags/paths for slangc + SPIR-V tools and adds optional spirv-val/spirv-dis outputs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| #include <algorithm> | ||
| #include <array> | ||
| #include <atomic> | ||
| #include <cctype> | ||
| #include <cstdint> | ||
| #include <cstring> | ||
| #include <cstdlib> | ||
| #include <exception> | ||
| #include <filesystem> | ||
| #include <mutex> | ||
| #include <sstream> | ||
| #include <shared_mutex> | ||
| #include <span> | ||
| #include <string> | ||
| #include <vector> |
| for (auto& [shader_hash, custom_shader] : custom_shaders_cache) { | ||
| if (!shader_hashes_processed.contains(shader_hash)) { | ||
| if (!custom_shader.removed) { | ||
| custom_shader.removed = true; | ||
| shader_hashes_updated.insert(shader_hash); | ||
| } |
| if (shader_hashes_processed.contains(shader_hash)) { | ||
| std::stringstream s; | ||
| s << "CompileCustomShaders(Ignoring duplicate shader: "; | ||
| s << PRINT_CRC32(shader_hash); | ||
| s << ", at " << item.entry_path; | ||
| s << ")"; | ||
| reshade::log::message(reshade::log::level::warning, s.str().c_str()); | ||
| continue; |
| if(SPIRV_DIS_BIN) | ||
| add_custom_command( | ||
| OUTPUT ${EMBED_FOLDER}/${SHADER_HASH}.spvasm | ||
| COMMAND "${SPIRV_DIS_BIN}" "${EMBED_FOLDER}/${SHADER_HASH}.spv" -o "${EMBED_FOLDER}/${SHADER_HASH}.spvasm" | ||
| DEPENDS ${FILE} | ||
| ) |
| add_custom_command( | ||
| OUTPUT ${EMBED_FOLDER}/${SHADER_NAME}.spvasm | ||
| COMMAND "${SPIRV_DIS_BIN}" "${EMBED_FOLDER}/${SHADER_NAME}.spv" -o "${EMBED_FOLDER}/${SHADER_NAME}.spvasm" | ||
| DEPENDS ${FILE} |
There was a problem hiding this comment.
Pull request overview
This PR extends the devkit shader toolchain by adding Slang shader support and SPIR-V disassembly/decompilation tooling, while also parallelizing shader compilation to reduce live-reload “Load Shaders” time.
Changes:
- Parallelize custom shader compilation in the watcher (DXC/FXC/Slang) and add device-API–aware target resolution.
- Add a Slang-based compiler wrapper that can compile
.slangshaders from disk and optionally disassemble/decompile SPIR-V via external tools. - Update CMake shader build steps to unify Slang flags and optionally run
spirv-val/ produce.spvasmviaspirv-dis.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/shader_compiler_watcher.hpp | Adds Slang integration and parallel compilation pipeline for disk shaders. |
| src/utils/shader_compiler_slang.hpp | Introduces Slang compiler invocation plus SPIR-V disassembly/decompilation helpers. |
| src/utils/shader_compiler_directx.hpp | Adjusts DXC loading and makes DXC/FXC locking behavior configurable for parallelism. |
| src/addons/devkit/addon.cpp | Hooks watcher device API, adds Vulkan disassembly/decompilation paths, and tweaks UI link selection behavior. |
| CMakeLists.txt | Unifies Slang flags/paths and adds optional spirv-val/spirv-dis steps and auxiliary outputs. |
Comments suppressed due to low confidence (1)
src/utils/shader_compiler_directx.hpp:134
LoadDXCompilernow usesstd::call_oncebut still accepts apathparameter. After the first call (even if it fails or uses a different path), subsequent calls cannot retry with another path and will keep returning the cached result. Either remove the path parameter or implement retry/path-aware caching so callers can load from a non-default location when needed.
inline HMODULE LoadDXCompiler(const std::wstring& path = L"dxcompiler.dll") {
std::call_once(dxc_compiler_library_once, [&]() {
dxc_compiler_library = LoadLibraryW(path.c_str());
});
return dxc_compiler_library;
}
// Narrow-string overloads for convenience
inline HMODULE LoadDXCompiler(const std::string& path) {
return LoadDXCompiler(std::wstring(path.begin(), path.end()));
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #include <algorithm> | ||
| #include <array> | ||
| #include <atomic> | ||
| #include <cctype> | ||
| #include <cstdint> | ||
| #include <cstring> | ||
| #include <cstdlib> | ||
| #include <exception> | ||
| #include <filesystem> | ||
| #include <mutex> | ||
| #include <sstream> | ||
| #include <shared_mutex> | ||
| #include <span> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| #include "./path.hpp" | ||
|
|
||
| namespace renodx::utils::shader::compiler::slang { | ||
|
|
||
| namespace internal { | ||
|
|
||
| static std::shared_mutex mutex_slangc_path; | ||
| static std::filesystem::path cached_slangc_path; | ||
| static std::atomic_uint32_t compile_counter = 0; | ||
| static std::optional<std::filesystem::path> cached_spirv_dis; | ||
| static std::optional<std::filesystem::path> cached_spirv_cross; |
There was a problem hiding this comment.
shader_compiler_slang.hpp uses std::optional for cached tool paths, but the header does not include <optional>. This makes the header non-self-contained and can break compilation depending on include order; add the missing standard header include here.
| previous_custom_shader.is_hlsl = custom_shader.is_hlsl; | ||
| previous_custom_shader.is_glsl = custom_shader.is_glsl; | ||
| previous_custom_shader.is_slang = custom_shader.is_slang; | ||
| previous_custom_shader.file_path = custom_shader.file_path; |
There was a problem hiding this comment.
When the compiled bytecode matches an existing cache entry, the code updates the source metadata but does not clear previous_custom_shader.removed. If a shader was previously marked removed and then re-added with identical output, it will stay marked as removed and may never become active again; ensure removed is reset to false when the shader is seen again.
| previous_custom_shader.file_path = custom_shader.file_path; | |
| previous_custom_shader.file_path = custom_shader.file_path; | |
| previous_custom_shader.removed = false; |
| if(SPIRV_DIS_BIN) | ||
| add_custom_command( | ||
| OUTPUT ${EMBED_FOLDER}/${SHADER_HASH}.spvasm | ||
| COMMAND "${SPIRV_DIS_BIN}" "${EMBED_FOLDER}/${SHADER_HASH}.spv" -o "${EMBED_FOLDER}/${SHADER_HASH}.spvasm" | ||
| DEPENDS ${FILE} | ||
| ) |
There was a problem hiding this comment.
This spirv-dis custom command depends on the original ${FILE} rather than the generated/copied ${EMBED_FOLDER}/${SHADER_HASH}.spv. That can allow CMake to schedule spirv-dis before the .spv exists, causing build failures. Make the .spvasm rule depend on the .spv output (and/or add it as a byproduct of the .spv rule).
| add_custom_command( | ||
| OUTPUT ${EMBED_FOLDER}/${SHADER_NAME}.spvasm | ||
| COMMAND "${SPIRV_DIS_BIN}" "${EMBED_FOLDER}/${SHADER_NAME}.spv" -o "${EMBED_FOLDER}/${SHADER_NAME}.spvasm" | ||
| DEPENDS ${FILE} |
There was a problem hiding this comment.
Same issue as above for the non-hash path: the spirv-dis .spvasm rule depends on ${FILE} instead of ${EMBED_FOLDER}/${SHADER_NAME}.spv, so the disassembly step may run before the .spv output is generated. Update the dependency to the .spv output to guarantee correct build ordering.
| DEPENDS ${FILE} | |
| DEPENDS ${EMBED_FOLDER}/${SHADER_NAME}.spv |
CMake:
Devkit:
Compiler: