Skip to content

Commit 0afe712

Browse files
authored
Merge pull request #979 from Devsh-Graphics-Programming/depfiles
Depfiles
2 parents 29fdaa1 + dc13c45 commit 0afe712

File tree

10 files changed

+976
-461
lines changed

10 files changed

+976
-461
lines changed

cmake/common.cmake

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,7 @@ option(NSC_DEBUG_EDIF_SOURCE_BIT "Add \"-fspv-debug=source\" to NSC Debug CLI" O
11421142
option(NSC_DEBUG_EDIF_LINE_BIT "Add \"-fspv-debug=line\" to NSC Debug CLI" OFF)
11431143
option(NSC_DEBUG_EDIF_TOOL_BIT "Add \"-fspv-debug=tool\" to NSC Debug CLI" ON)
11441144
option(NSC_DEBUG_EDIF_NON_SEMANTIC_BIT "Add \"-fspv-debug=vulkan-with-source\" to NSC Debug CLI" OFF)
1145+
option(NSC_USE_DEPFILE "Generate depfiles for NSC custom commands" ON)
11451146

11461147
function(NBL_CREATE_NSC_COMPILE_RULES)
11471148
set(COMMENT "this code has been autogenerated with Nabla CMake NBL_CREATE_HLSL_COMPILE_RULES utility")
@@ -1180,6 +1181,7 @@ struct DeviceConfigCaps
11801181
-fspv-target-env=vulkan1.3
11811182
-Wshadow
11821183
-Wconversion
1184+
-Wno-local-type-template-args
11831185
$<$<CONFIG:Debug>:-O0>
11841186
$<$<CONFIG:Release>:-O3>
11851187
$<$<CONFIG:RelWithDebInfo>:-O3>
@@ -1207,6 +1209,7 @@ struct DeviceConfigCaps
12071209

12081210
if(NOT NBL_EMBED_BUILTIN_RESOURCES)
12091211
list(APPEND REQUIRED_OPTIONS
1212+
-no-nbl-builtins
12101213
-I "${NBL_ROOT_PATH}/include"
12111214
-I "${NBL_ROOT_PATH}/3rdparty/dxc/dxc/external/SPIRV-Headers/include"
12121215
-I "${NBL_ROOT_PATH}/3rdparty/boost/superproject/libs/preprocessor/include"
@@ -1215,9 +1218,20 @@ struct DeviceConfigCaps
12151218
endif()
12161219

12171220
set(REQUIRED_SINGLE_ARGS TARGET BINARY_DIR OUTPUT_VAR INPUTS INCLUDE NAMESPACE MOUNT_POINT_DEFINE)
1218-
cmake_parse_arguments(IMPL "" "${REQUIRED_SINGLE_ARGS};LINK_TO" "COMMON_OPTIONS;DEPENDS" ${ARGV})
1221+
set(OPTIONAL_SINGLE_ARGS GLOB_DIR)
1222+
cmake_parse_arguments(IMPL "DISCARD_DEFAULT_GLOB" "${REQUIRED_SINGLE_ARGS};${OPTIONAL_SINGLE_ARGS};LINK_TO" "COMMON_OPTIONS;DEPENDS" ${ARGV})
12191223
NBL_PARSE_REQUIRED(IMPL ${REQUIRED_SINGLE_ARGS})
12201224

1225+
set(IMPL_HLSL_GLOB "")
1226+
if(NOT IMPL_DISCARD_DEFAULT_GLOB)
1227+
set(GLOB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
1228+
if(IMPL_GLOB_DIR)
1229+
set(GLOB_ROOT "${IMPL_GLOB_DIR}")
1230+
endif()
1231+
get_filename_component(GLOB_ROOT "${GLOB_ROOT}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
1232+
file(GLOB_RECURSE IMPL_HLSL_GLOB CONFIGURE_DEPENDS "${GLOB_ROOT}/*.hlsl")
1233+
endif()
1234+
12211235
if(NOT TARGET ${IMPL_TARGET})
12221236
add_library(${IMPL_TARGET} INTERFACE)
12231237
endif()
@@ -1293,6 +1307,10 @@ namespace @IMPL_NAMESPACE@ {
12931307
list(APPEND MP_DEFINES ${IMPL_MOUNT_POINT_DEFINE}="${IMPL_BINARY_DIR}")
12941308
set_target_properties(${IMPL_TARGET} PROPERTIES NBL_MOUNT_POINT_DEFINES "${MP_DEFINES}")
12951309

1310+
set(RTE "NSC Rules")
1311+
set(IN "${RTE}/In")
1312+
set(OUT "${RTE}/Out")
1313+
12961314
string(JSON JSON_LENGTH LENGTH "${IMPL_INPUTS}")
12971315
math(EXPR LAST_INDEX "${JSON_LENGTH} - 1")
12981316

@@ -1479,30 +1497,73 @@ namespace @IMPL_NAMESPACE@ {
14791497
# generate keys and commands for compiling shaders
14801498
set(FINAL_KEY_REL_PATH "$<CONFIG>/${FINAL_KEY}")
14811499
set(TARGET_OUTPUT "${IMPL_BINARY_DIR}/${FINAL_KEY_REL_PATH}")
1500+
set(DEPFILE_PATH "${TARGET_OUTPUT}.d")
1501+
set(NBL_NSC_LOG_PATH "${TARGET_OUTPUT}.log")
1502+
1503+
set(NBL_NSC_DEPFILE_ARGS "")
1504+
if(NSC_USE_DEPFILE)
1505+
set(NBL_NSC_DEPFILE_ARGS -MD -MF "${DEPFILE_PATH}")
1506+
endif()
14821507

14831508
set(NBL_NSC_COMPILE_COMMAND
14841509
"$<TARGET_FILE:nsc>"
14851510
-Fc "${TARGET_OUTPUT}"
14861511
${COMPILE_OPTIONS} ${REQUIRED_OPTIONS} ${IMPL_COMMON_OPTIONS}
1512+
${NBL_NSC_DEPFILE_ARGS}
14871513
"${CONFIG_FILE}"
14881514
)
14891515

1490-
add_custom_command(OUTPUT "${TARGET_OUTPUT}"
1516+
get_filename_component(NBL_NSC_INPUT_NAME "${TARGET_INPUT}" NAME)
1517+
get_filename_component(NBL_NSC_CONFIG_NAME "${CONFIG_FILE}" NAME)
1518+
set(NBL_NSC_BYPRODUCTS "${NBL_NSC_LOG_PATH}")
1519+
if(NSC_USE_DEPFILE)
1520+
list(APPEND NBL_NSC_BYPRODUCTS "${DEPFILE_PATH}")
1521+
endif()
1522+
1523+
set(NBL_NSC_CUSTOM_COMMAND_ARGS
1524+
OUTPUT "${TARGET_OUTPUT}"
1525+
BYPRODUCTS ${NBL_NSC_BYPRODUCTS}
14911526
COMMAND ${NBL_NSC_COMPILE_COMMAND}
14921527
DEPENDS ${DEPENDS_ON}
1493-
COMMENT "Creating \"${TARGET_OUTPUT}\""
1528+
COMMENT "${NBL_NSC_CONFIG_NAME} (${NBL_NSC_INPUT_NAME})"
14941529
VERBATIM
14951530
COMMAND_EXPAND_LISTS
14961531
)
1497-
set_source_files_properties("${TARGET_OUTPUT}" PROPERTIES GENERATED TRUE)
1532+
if(NSC_USE_DEPFILE)
1533+
list(APPEND NBL_NSC_CUSTOM_COMMAND_ARGS DEPFILE "${DEPFILE_PATH}")
1534+
endif()
1535+
add_custom_command(${NBL_NSC_CUSTOM_COMMAND_ARGS})
1536+
set(NBL_NSC_OUT_FILES "${TARGET_OUTPUT}" "${NBL_NSC_LOG_PATH}")
1537+
if(NSC_USE_DEPFILE)
1538+
list(APPEND NBL_NSC_OUT_FILES "${DEPFILE_PATH}")
1539+
endif()
14981540

1499-
set(HEADER_ONLY_LIKE "${CONFIG_FILE}" "${TARGET_INPUT}" "${TARGET_OUTPUT}")
1541+
set_source_files_properties(${NBL_NSC_OUT_FILES} PROPERTIES GENERATED TRUE)
1542+
1543+
set(HEADER_ONLY_LIKE "${CONFIG_FILE}" "${TARGET_INPUT}" ${NBL_NSC_OUT_FILES})
15001544
target_sources(${IMPL_TARGET} PRIVATE ${HEADER_ONLY_LIKE})
15011545

15021546
set_source_files_properties(${HEADER_ONLY_LIKE} PROPERTIES
15031547
HEADER_FILE_ONLY ON
15041548
VS_TOOL_OVERRIDE None
15051549
)
1550+
if(CMAKE_CONFIGURATION_TYPES)
1551+
foreach(_CFG IN LISTS CMAKE_CONFIGURATION_TYPES)
1552+
set(TARGET_OUTPUT_IDE "${IMPL_BINARY_DIR}/${_CFG}/${FINAL_KEY}")
1553+
set(NBL_NSC_OUT_FILES_IDE "${TARGET_OUTPUT_IDE}" "${TARGET_OUTPUT_IDE}.log")
1554+
if(NSC_USE_DEPFILE)
1555+
list(APPEND NBL_NSC_OUT_FILES_IDE "${TARGET_OUTPUT_IDE}.d")
1556+
endif()
1557+
source_group("${OUT}/${_CFG}" FILES ${NBL_NSC_OUT_FILES_IDE})
1558+
endforeach()
1559+
else()
1560+
set(TARGET_OUTPUT_IDE "${IMPL_BINARY_DIR}/${FINAL_KEY}")
1561+
set(NBL_NSC_OUT_FILES_IDE "${TARGET_OUTPUT_IDE}" "${TARGET_OUTPUT_IDE}.log")
1562+
if(NSC_USE_DEPFILE)
1563+
list(APPEND NBL_NSC_OUT_FILES_IDE "${TARGET_OUTPUT_IDE}.d")
1564+
endif()
1565+
source_group("${OUT}" FILES ${NBL_NSC_OUT_FILES_IDE})
1566+
endif()
15061567

15071568
set_source_files_properties("${TARGET_OUTPUT}" PROPERTIES
15081569
NBL_SPIRV_REGISTERED_INPUT "${TARGET_INPUT}"
@@ -1544,12 +1605,15 @@ namespace @IMPL_NAMESPACE@ {
15441605
list(APPEND KEYS ${ACCESS_KEY})
15451606
endforeach()
15461607

1547-
set(RTE "NSC Rules")
1548-
set(IN "${RTE}/In")
1549-
set(OUT "${RTE}/Out")
1550-
15511608
source_group("${IN}" FILES ${CONFIGS} ${INPUTS})
1552-
source_group("${OUT}" FILES ${SPIRVs})
1609+
if(IMPL_HLSL_GLOB)
1610+
target_sources(${IMPL_TARGET} PRIVATE ${IMPL_HLSL_GLOB})
1611+
set_source_files_properties(${IMPL_HLSL_GLOB} PROPERTIES
1612+
HEADER_FILE_ONLY ON
1613+
VS_TOOL_OVERRIDE None
1614+
)
1615+
source_group("HLSL Files" FILES ${IMPL_HLSL_GLOB})
1616+
endif()
15531617

15541618
set(${IMPL_OUTPUT_VAR} ${KEYS} PARENT_SCOPE)
15551619
endfunction()

docs/nsc-prebuilds.md

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ Keys are strings that match the output layout:
6060
- `INPUT` (string, required): path to `.hlsl` (relative to `CMAKE_CURRENT_SOURCE_DIR` or absolute).
6161
- `KEY` (string, required): base key (prefer without `.spv`; it is always appended, so using `foo.spv` will result in `foo.spv.spv`).
6262
- `COMPILE_OPTIONS` (array of strings, optional): per-input extra options (e.g. `["-T","cs_6_8"]`).
63-
- `DEPENDS` (array of strings, optional): per-input dependencies (extra files that should trigger rebuild).
63+
- `DEPENDS` (array of strings, optional): extra per-input dependencies that are not discovered via `#include` (see below).
6464
- `CAPS` (array, optional): permutation caps (see below).
6565

6666
You can register many rules in a single call, and you can call the function multiple times to append rules to the same `TARGET`.
@@ -87,31 +87,21 @@ The helper also exposes CMake options that append NSC debug flags **only for Deb
8787

8888
## Source files and rebuild dependencies (important)
8989

90-
Make sure shader inputs and includes are:
90+
NSC supports depfiles and the CMake custom commands consume them, so **changes in any `#include`d HLSL file automatically trigger recompilation of the affected `.spv` outputs**. In most cases you no longer need to list includes manually.
9191

92-
1. Marked as header-only on your target (so the IDE shows them, but the build system doesn't try to compile them with default HLSL rules like `fxc`):
92+
Use `DEPENDS` only for **extra** inputs that are not discovered via `#include` (e.g. a generated header that is not included, a config file read by a custom include generator, or any non-HLSL file that should trigger a rebuild). You can register those extra dependencies if you need them, but in most projects `DEPENDS` should stay empty.
9393

94-
```cmake
95-
target_sources(${EXECUTABLE_NAME} PRIVATE ${DEPENDS})
96-
set_source_files_properties(${DEPENDS} PROPERTIES HEADER_FILE_ONLY ON)
97-
```
94+
By default `NBL_CREATE_NSC_COMPILE_RULES` also collects `*.hlsl` files for IDE visibility. It recursively scans the current source directory (or `GLOB_DIR` if provided), adds those files as header-only, and groups them under `HLSL Files`. If you do not want this behavior, pass `DISCARD_DEFAULT_GLOB`.
9895

99-
2. Listed as dependencies of the NSC custom commands (so editing any of them triggers a rebuild of the `.spv` outputs).
100-
101-
This is what the `DEPENDS` argument of `NBL_CREATE_NSC_COMPILE_RULES` (and/or per-input JSON `DEPENDS`) is for. Always include the main `INPUT` file itself and any files it includes; otherwise the build system might not re-run `nsc` when you change them.
96+
- `GLOB_DIR` (optional): root directory for the default `*.hlsl` scan.
97+
- `DISCARD_DEFAULT_GLOB` (flag): disables the default scan and IDE grouping.
10298

10399
## Minimal usage (no permutations)
104100

105101
Example pattern (as in `examples_tests/27_MPMCScheduler/CMakeLists.txt`):
106102

107103
```cmake
108104
set(OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/auto-gen")
109-
set(DEPENDS
110-
app_resources/common.hlsl
111-
app_resources/shader.comp.hlsl
112-
)
113-
target_sources(${EXECUTABLE_NAME} PRIVATE ${DEPENDS})
114-
set_source_files_properties(${DEPENDS} PROPERTIES HEADER_FILE_ONLY ON)
115105
116106
set(JSON [=[
117107
[
@@ -128,7 +118,6 @@ set(JSON [=[
128118
NBL_CREATE_NSC_COMPILE_RULES(
129119
TARGET ${EXECUTABLE_NAME}SPIRV
130120
LINK_TO ${EXECUTABLE_NAME}
131-
DEPENDS ${DEPENDS}
132121
BINARY_DIR ${OUTPUT_DIRECTORY}
133122
MOUNT_POINT_DEFINE NBL_THIS_EXAMPLE_BUILD_MOUNT_POINT
134123
COMMON_OPTIONS -I ${CMAKE_CURRENT_SOURCE_DIR}
@@ -298,6 +287,8 @@ If the error looks like a preprocessing issue, note that we use Boost.Wave as th
298287
<details>
299288
<summary>NSC rules + archive + runtime key usage</summary>
300289

290+
NSC emits depfiles and the custom commands consume them, so changes in `#include`d HLSL files automatically trigger recompilation of the affected outputs. In most cases you do not need to list includes manually. Use `DEPENDS` only for extra inputs that are not discovered via `#include`.
291+
301292
### CMake (`CMakeLists.txt`)
302293

303294
```cmake
@@ -306,20 +297,13 @@ include(common)
306297
nbl_create_executable_project("" "" "" "")
307298
308299
set(OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/auto-gen")
309-
set(DEPENDS
310-
app_resources/common.hlsl
311-
app_resources/shader.hlsl
312-
)
313-
target_sources(${EXECUTABLE_NAME} PRIVATE ${DEPENDS})
314-
set_source_files_properties(${DEPENDS} PROPERTIES HEADER_FILE_ONLY ON)
315300
316301
set(JSON [=[
317302
[
318303
{
319304
"INPUT": "app_resources/shader.hlsl",
320305
"KEY": "shader",
321306
"COMPILE_OPTIONS": ["-T", "lib_6_8"],
322-
"DEPENDS": [],
323307
"CAPS": [
324308
{
325309
"kind": "limits",
@@ -341,7 +325,6 @@ set(JSON [=[
341325
NBL_CREATE_NSC_COMPILE_RULES(
342326
TARGET ${EXECUTABLE_NAME}SPIRV
343327
LINK_TO ${EXECUTABLE_NAME}
344-
DEPENDS ${DEPENDS}
345328
BINARY_DIR ${OUTPUT_DIRECTORY}
346329
MOUNT_POINT_DEFINE NBL_THIS_EXAMPLE_BUILD_MOUNT_POINT
347330
COMMON_OPTIONS -I ${CMAKE_CURRENT_SOURCE_DIR}

include/nbl/asset/utils/IShaderCompiler.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
137137
const CIncludeFinder* includeFinder = nullptr;
138138
std::span<const SMacroDefinition> extraDefines = {};
139139
E_SPIRV_VERSION targetSpirvVersion = E_SPIRV_VERSION::ESV_1_6;
140+
bool depfile = false;
141+
system::path depfilePath = {};
140142
};
141143

142144
// https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/SPIR-V.rst#debugging
@@ -215,6 +217,10 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
215217
// Needed for json vector serialization. Making it private and declaring from_json(_, SEntry&) as friend didn't work
216218
inline SPreprocessingDependency() {}
217219

220+
inline const system::path& getRequestingSourceDir() const { return requestingSourceDir; }
221+
inline std::string_view getIdentifier() const { return identifier; }
222+
inline bool isStandardInclude() const { return standardInclude; }
223+
218224
private:
219225
friend void to_json(nlohmann::json& j, const SEntry::SPreprocessingDependency& dependency);
220226
friend void from_json(const nlohmann::json& j, SEntry::SPreprocessingDependency& dependency);
@@ -447,6 +453,17 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
447453
NBL_API2 EntrySet::const_iterator find_impl(const SEntry& mainFile, const CIncludeFinder* finder) const;
448454
};
449455

456+
struct DepfileWriteParams
457+
{
458+
system::ISystem* system = nullptr;
459+
std::string_view depfilePath = {};
460+
std::string_view outputPath = {};
461+
std::string_view sourceIdentifier = {};
462+
system::path workingDirectory = {};
463+
};
464+
465+
static bool writeDepfile(const DepfileWriteParams& params, const CCache::SEntry::dependency_container_t& dependencies, const CIncludeFinder* includeFinder = nullptr, system::logger_opt_ptr logger = nullptr);
466+
450467
core::smart_refctd_ptr<IShader> compileToSPIRV(const std::string_view code, const SCompilerOptions& options) const;
451468

452469
inline core::smart_refctd_ptr<IShader> compileToSPIRV(const char* code, const SCompilerOptions& options) const

include/nbl/system/IFileBase.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ class IFileBase : public core::IReferenceCounted
2525
ECF_READ_WRITE = 0b0011,
2626
ECF_MAPPABLE = 0b0100,
2727
//! Implies ECF_MAPPABLE
28-
ECF_COHERENT = 0b1100
28+
ECF_COHERENT = 0b1100,
29+
ECF_SHARE_READ_WRITE = 0b100000,
30+
ECF_SHARE_DELETE = 0b1000000
2931
};
3032

3133
//! Get size of file.

0 commit comments

Comments
 (0)