Skip to content

Commit 546ed90

Browse files
committed
Merge branch 'master' into rt_pipeline_debug_render_fixes
2 parents 9574030 + c6e5d16 commit 546ed90

23 files changed

Lines changed: 790 additions & 242 deletions

.github/workflows/build-nabla.yml

Lines changed: 225 additions & 63 deletions
Large diffs are not rendered by default.

.github/workflows/run-nsc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ jobs:
123123
& "nginx/nginx-1.24.0/nginx.exe" -t -p "nginx/nginx-1.24.0" -c "conf/nginx.conf"
124124

125125
- name: Download NSC Godbolt artifact
126-
uses: actions/download-artifact@v4
126+
uses: actions/download-artifact@v8
127127
with:
128128
run-id: ${{ inputs.run_id }}
129129
pattern: run-windows-*-msvc-${{ inputs.build_config }}-nsc-godbolt-image

3rdparty/boost/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ endforeach()
120120
# include will lead to ABI mismatch hence we update the target and let inherit options
121121
target_compile_definitions(boost_wave
122122
PUBLIC BOOST_WAVE_ENABLE_COMMANDLINE_MACROS=1
123-
PUBLIC BOOST_WAVE_SUPPORT_PRAGMA_ONCE=0
123+
PUBLIC BOOST_WAVE_SUPPORT_PRAGMA_ONCE=1
124124
PUBLIC BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES=1
125125
PUBLIC BOOST_WAVE_SERIALIZATION=0
126126
PUBLIC BOOST_WAVE_SUPPORT_INCLUDE_NEXT=0
@@ -131,4 +131,4 @@ target_compile_definitions(boost_wave
131131

132132
set(NBL_BOOST_TARGETS
133133
${NBL_BOOST_TARGETS}
134-
PARENT_SCOPE)
134+
PARENT_SCOPE)

cmake/common.cmake

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@ function(nbl_install_exe_spec _TARGETS _RELATIVE_DESTINATION)
361361
endif()
362362

363363
install(TARGETS ${_TARGETS} ${_EXPORT_ARGS} RUNTIME DESTINATION ${_DEST_GE_} COMPONENT ${_COMPONENT})
364+
365+
foreach(_TRGT IN LISTS _TARGETS)
366+
install(PROGRAMS $<TARGET_PDB_FILE:${_TRGT}> DESTINATION debug/exe/${_RELATIVE_DESTINATION} CONFIGURATIONS Debug COMPONENT ${_COMPONENT})
367+
endforeach()
364368

365369
foreach(_TRGT IN LISTS _TARGETS)
366370
get_property(_DEFINED_PROPERTY_
@@ -1395,6 +1399,24 @@ namespace @IMPL_NAMESPACE@ {
13951399
list(APPEND DEPENDS_ON ${IMPL_DEPENDS})
13961400
endif()
13971401

1402+
function(ERROR_WHILE_PARSING_ITEM)
1403+
string(JSON ITEM GET "${IMPL_INPUTS}" ${INDEX})
1404+
message(FATAL_ERROR
1405+
"While parsing ${IMPL_TARGET}'s NSC compile rule\n${ITEM}\n"
1406+
${ARGV}
1407+
)
1408+
endfunction()
1409+
1410+
set(RULE_MODE compile)
1411+
string(JSON MODE_TYPE ERROR_VARIABLE MODE_ERROR TYPE "${IMPL_INPUTS}" ${INDEX} MODE)
1412+
if(NOT MODE_ERROR)
1413+
if(NOT MODE_TYPE STREQUAL "STRING")
1414+
ERROR_WHILE_PARSING_ITEM("MODE must be a string when present")
1415+
endif()
1416+
string(JSON RULE_MODE GET "${IMPL_INPUTS}" ${INDEX} MODE)
1417+
string(TOLOWER "${RULE_MODE}" RULE_MODE)
1418+
endif()
1419+
13981420
set(HAS_CAPS FALSE)
13991421
set(CAPS_LENGTH 0)
14001422
string(JSON CAPS_TYPE ERROR_VARIABLE ERROR_VAR TYPE "${IMPL_INPUTS}" ${INDEX} CAPS)
@@ -1405,13 +1427,12 @@ namespace @IMPL_NAMESPACE@ {
14051427
endif()
14061428
endif()
14071429

1408-
function(ERROR_WHILE_PARSING_ITEM)
1409-
string(JSON ITEM GET "${IMPL_INPUTS}" ${INDEX})
1410-
message(FATAL_ERROR
1411-
"While parsing ${IMPL_TARGET}'s NSC compile rule\n${ITEM}\n"
1412-
${ARGV}
1413-
)
1414-
endfunction()
1430+
if(NOT RULE_MODE MATCHES "^(compile|preprocess)$")
1431+
ERROR_WHILE_PARSING_ITEM(
1432+
"Invalid MODE \"${RULE_MODE}\"\n"
1433+
"Allowed modes are: compile, preprocess"
1434+
)
1435+
endif()
14151436

14161437
set(CAP_NAMES "")
14171438
set(CAP_TYPES "")
@@ -1498,6 +1519,15 @@ namespace @IMPL_NAMESPACE@ {
14981519

14991520
set_property(TARGET ${IMPL_TARGET} APPEND PROPERTY NBL_CANONICAL_IDENTIFIERS "${NEW_CANONICAL_IDENTIFIER}")
15001521

1522+
set(OUTPUT_EXT ".spv")
1523+
set(OUTPUT_PREFIX "$<CONFIG>/")
1524+
set(OUTPUT_GROUP_BY_CONFIG TRUE)
1525+
set(MODE_ARGS "")
1526+
if(RULE_MODE STREQUAL "preprocess")
1527+
set(OUTPUT_EXT ".preprocessed.hlsl")
1528+
list(APPEND MODE_ARGS -P)
1529+
endif()
1530+
15011531
set(HEADER_ITEM_VIEW [=[
15021532
namespace @IMPL_NAMESPACE@ {
15031533
template<>
@@ -1506,8 +1536,8 @@ namespace @IMPL_NAMESPACE@ {
15061536
{
15071537
nbl::core::string retval = "@BASE_KEY@";
15081538
@RETVAL_EVAL@
1509-
retval += ".spv";
1510-
return "$<CONFIG>/" + retval;
1539+
retval += "@OUTPUT_EXT@";
1540+
return "@OUTPUT_PREFIX@" + retval;
15111541
}
15121542
}
15131543
@@ -1532,27 +1562,29 @@ namespace @IMPL_NAMESPACE@ {
15321562
function(GENERATE_KEYS PREFIX CAP_INDEX CAPS_EVAL_PART)
15331563
if(NUM_CAPS EQUAL 0 OR CAP_INDEX EQUAL ${NUM_CAPS})
15341564
# generate .config file
1535-
set(FINAL_KEY "${BASE_KEY}${PREFIX}.spv") # always add ext even if its already there to make sure asset loader always is able to load as IShader
1565+
set(FINAL_KEY "${BASE_KEY}${PREFIX}${OUTPUT_EXT}")
15361566
set(CONFIG_FILE_TARGET_OUTPUT "${IMPL_BINARY_DIR}/${FINAL_KEY}")
15371567
set(CONFIG_FILE "${CONFIG_FILE_TARGET_OUTPUT}.config")
15381568
set(CAPS_EVAL "${CAPS_EVAL_PART}")
15391569
string(CONFIGURE "${DEVICE_CONFIG_VIEW}" CONFIG_CONTENT @ONLY)
15401570
file(WRITE "${CONFIG_FILE}" "${CONFIG_CONTENT}")
15411571

15421572
# generate keys and commands for compiling shaders
1543-
set(FINAL_KEY_REL_PATH "$<CONFIG>/${FINAL_KEY}")
1573+
set(FINAL_KEY_REL_PATH "${OUTPUT_PREFIX}${FINAL_KEY}")
15441574
set(TARGET_OUTPUT "${IMPL_BINARY_DIR}/${FINAL_KEY_REL_PATH}")
15451575
set(DEPFILE_PATH "${TARGET_OUTPUT}.d")
15461576
set(NBL_NSC_LOG_PATH "${TARGET_OUTPUT}.log")
15471577

15481578
set(NBL_NSC_DEPFILE_ARGS "")
1549-
if(NSC_USE_DEPFILE)
1579+
set(NBL_NSC_RULE_USE_DEPFILE ${NSC_USE_DEPFILE})
1580+
if(NBL_NSC_RULE_USE_DEPFILE)
15501581
set(NBL_NSC_DEPFILE_ARGS -MD -MF "${DEPFILE_PATH}")
15511582
endif()
15521583

15531584
set(NBL_NSC_COMPILE_COMMAND
15541585
"$<TARGET_FILE:Nabla::nsc>"
15551586
${NBL_NSC_EXTRA_ARGS}
1587+
${MODE_ARGS}
15561588
-Fc "${TARGET_OUTPUT}"
15571589
${COMPILE_OPTIONS} ${REQUIRED_OPTIONS} ${IMPL_COMMON_OPTIONS}
15581590
${NBL_NSC_DEPFILE_ARGS}
@@ -1562,7 +1594,7 @@ namespace @IMPL_NAMESPACE@ {
15621594
get_filename_component(NBL_NSC_INPUT_NAME "${TARGET_INPUT}" NAME)
15631595
get_filename_component(NBL_NSC_CONFIG_NAME "${CONFIG_FILE}" NAME)
15641596
set(NBL_NSC_BYPRODUCTS "${NBL_NSC_LOG_PATH}")
1565-
if(NSC_USE_DEPFILE)
1597+
if(NBL_NSC_RULE_USE_DEPFILE)
15661598
list(APPEND NBL_NSC_BYPRODUCTS "${DEPFILE_PATH}")
15671599
endif()
15681600

@@ -1582,12 +1614,12 @@ namespace @IMPL_NAMESPACE@ {
15821614
VERBATIM
15831615
COMMAND_EXPAND_LISTS
15841616
)
1585-
if(NSC_USE_DEPFILE)
1617+
if(NBL_NSC_RULE_USE_DEPFILE)
15861618
list(APPEND NBL_NSC_CUSTOM_COMMAND_ARGS DEPFILE "${DEPFILE_PATH}")
15871619
endif()
15881620
add_custom_command(${NBL_NSC_CUSTOM_COMMAND_ARGS})
15891621
set(NBL_NSC_OUT_FILES "${TARGET_OUTPUT}" "${NBL_NSC_LOG_PATH}")
1590-
if(NSC_USE_DEPFILE)
1622+
if(NBL_NSC_RULE_USE_DEPFILE)
15911623
list(APPEND NBL_NSC_OUT_FILES "${DEPFILE_PATH}")
15921624
endif()
15931625

@@ -1600,19 +1632,19 @@ namespace @IMPL_NAMESPACE@ {
16001632
HEADER_FILE_ONLY ON
16011633
VS_TOOL_OVERRIDE None
16021634
)
1603-
if(CMAKE_CONFIGURATION_TYPES)
1635+
if(CMAKE_CONFIGURATION_TYPES AND OUTPUT_GROUP_BY_CONFIG)
16041636
foreach(_CFG IN LISTS CMAKE_CONFIGURATION_TYPES)
16051637
set(TARGET_OUTPUT_IDE "${IMPL_BINARY_DIR}/${_CFG}/${FINAL_KEY}")
16061638
set(NBL_NSC_OUT_FILES_IDE "${TARGET_OUTPUT_IDE}" "${TARGET_OUTPUT_IDE}.log")
1607-
if(NSC_USE_DEPFILE)
1639+
if(NBL_NSC_RULE_USE_DEPFILE)
16081640
list(APPEND NBL_NSC_OUT_FILES_IDE "${TARGET_OUTPUT_IDE}.d")
16091641
endif()
16101642
source_group("${OUT}/${_CFG}" FILES ${NBL_NSC_OUT_FILES_IDE})
16111643
endforeach()
16121644
else()
16131645
set(TARGET_OUTPUT_IDE "${IMPL_BINARY_DIR}/${FINAL_KEY}")
16141646
set(NBL_NSC_OUT_FILES_IDE "${TARGET_OUTPUT_IDE}" "${TARGET_OUTPUT_IDE}.log")
1615-
if(NSC_USE_DEPFILE)
1647+
if(NBL_NSC_RULE_USE_DEPFILE)
16161648
list(APPEND NBL_NSC_OUT_FILES_IDE "${TARGET_OUTPUT_IDE}.d")
16171649
endif()
16181650
source_group("${OUT}" FILES ${NBL_NSC_OUT_FILES_IDE})

include/nbl/asset/utils/CHLSLCompiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,4 @@ class NBL_API2 CHLSLCompiler final : public IShaderCompiler
155155

156156
#endif
157157

158-
#endif
158+
#endif

include/nbl/system/ISystem.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ class NBL_API2 ISystem : public core::IReferenceCounted
143143

144144
void unmountBuiltins();
145145
bool areBuiltinsMounted() const;
146+
size_t getMountedBuiltinArchiveCount() const;
147+
inline size_t getMountedArchiveCount() const { return m_cachedArchiveFiles.getSize(); }
146148

147149
//
148150
struct SystemInfo
@@ -205,8 +207,16 @@ class NBL_API2 ISystem : public core::IReferenceCounted
205207
//! The key is file extension
206208
core::CMultiObjectCache<std::string,core::smart_refctd_ptr<IArchiveLoader>,std::vector> perFileExt;
207209
} m_loaders;
210+
struct SBuiltinMount
211+
{
212+
core::smart_refctd_ptr<IFileArchive> archive;
213+
system::path pathAlias;
214+
};
215+
void mountBuiltin(core::smart_refctd_ptr<IFileArchive>&& archive, const system::path& pathAlias = "");
216+
bool isBuiltinMounted(const SBuiltinMount& mount) const;
208217
//
209218
core::CMultiObjectCache<system::path,core::smart_refctd_ptr<IFileArchive>> m_cachedArchiveFiles;
219+
core::vector<SBuiltinMount> m_builtinMounts;
210220

211221
private:
212222
struct SRequestParams_NOOP

src/nbl/asset/utils/CHLSLCompiler.cpp

Lines changed: 101 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
#include <combaseapi.h>
2121
#include <sstream>
2222
#include <dxc/dxcapi.h>
23-
#include <boost/algorithm/string/predicate.hpp>
24-
#include <boost/algorithm/string/trim.hpp>
2523

2624
using namespace nbl;
2725
using namespace nbl::asset;
@@ -363,7 +361,98 @@ namespace nbl::wave
363361
extern nbl::core::string preprocess(std::string& code, const IShaderCompiler::SPreprocessorOptions& preprocessOptions, bool withCaching, std::function<void(nbl::wave::context&)> post);
364362
}
365363

366-
std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions, std::vector<std::string>& dxc_compile_flags_override, std::vector<CCache::SEntry::SPreprocessingDependency>* dependencies) const
364+
static bool isHorizontalWhitespace(const char c)
365+
{
366+
return c == ' ' || c == '\t' || c == '\r' || c == '\v' || c == '\f';
367+
}
368+
369+
static bool consumeIdentifier(std::string_view line, size_t& pos, const std::string_view identifier)
370+
{
371+
if (line.substr(pos, identifier.size()) != identifier)
372+
return false;
373+
374+
const size_t end = pos + identifier.size();
375+
if (end < line.size())
376+
{
377+
const char next = line[end];
378+
if ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z') || (next >= '0' && next <= '9') || next == '_')
379+
return false;
380+
}
381+
382+
pos = end;
383+
return true;
384+
}
385+
386+
static void normalizeLegacyShaderStagePragmas(std::string& code)
387+
{
388+
std::string normalized;
389+
normalized.reserve(code.size());
390+
391+
size_t lineStart = 0u;
392+
while (lineStart < code.size())
393+
{
394+
const size_t lineEnd = code.find('\n', lineStart);
395+
const bool hasNewline = lineEnd != std::string::npos;
396+
const size_t lineSize = hasNewline ? (lineEnd - lineStart) : (code.size() - lineStart);
397+
const std::string_view line(code.data() + lineStart, lineSize);
398+
399+
size_t pos = 0u;
400+
while (pos < line.size() && isHorizontalWhitespace(line[pos]))
401+
++pos;
402+
403+
bool normalizedLegacyPragma = false;
404+
if (pos < line.size() && line[pos] == '#')
405+
{
406+
++pos;
407+
while (pos < line.size() && isHorizontalWhitespace(line[pos]))
408+
++pos;
409+
410+
if (consumeIdentifier(line, pos, "pragma"))
411+
{
412+
while (pos < line.size() && isHorizontalWhitespace(line[pos]))
413+
++pos;
414+
415+
const size_t pragmaArgumentPos = pos;
416+
if (consumeIdentifier(line, pos, "shader_stage"))
417+
normalizedLegacyPragma = true;
418+
else
419+
pos = pragmaArgumentPos;
420+
}
421+
}
422+
423+
if (normalizedLegacyPragma)
424+
{
425+
normalized.append(line.substr(0u, pos - std::string_view("shader_stage").size()));
426+
normalized += "wave ";
427+
normalized.append(line.substr(pos - std::string_view("shader_stage").size()));
428+
}
429+
else
430+
{
431+
normalized.append(line);
432+
}
433+
434+
if (hasNewline)
435+
normalized.push_back('\n');
436+
437+
lineStart = hasNewline ? (lineEnd + 1u) : code.size();
438+
}
439+
440+
code = std::move(normalized);
441+
}
442+
443+
static void ensureTrailingNewline(std::string& code)
444+
{
445+
if (!code.empty() && code.back() != '\n' && code.back() != '\r')
446+
code.push_back('\n');
447+
}
448+
449+
static std::string preprocessShaderImpl(
450+
std::string&& code,
451+
IShader::E_SHADER_STAGE& stage,
452+
const CHLSLCompiler::SPreprocessorOptions& preprocessOptions,
453+
std::vector<std::string>& dxc_compile_flags_override,
454+
std::vector<IShaderCompiler::CCache::SEntry::SPreprocessingDependency>* dependencies,
455+
system::ISystem* system)
367456
{
368457
const bool depfileEnabled = preprocessOptions.depfile;
369458
if (depfileEnabled)
@@ -375,23 +464,13 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
375464
}
376465
}
377466

378-
std::vector<CCache::SEntry::SPreprocessingDependency> localDependencies;
467+
std::vector<IShaderCompiler::CCache::SEntry::SPreprocessingDependency> localDependencies;
379468
auto* dependenciesOut = dependencies;
380469
if (depfileEnabled && !dependenciesOut)
381470
dependenciesOut = &localDependencies;
382471

383-
// HACK: we do a pre-pre-process here to add \n after every #pragma to neutralize boost::wave's actions
384-
// See https://github.com/Devsh-Graphics-Programming/Nabla/issues/746
385-
size_t line_index = 0;
386-
for (size_t i = 0; i < code.size(); i++) {
387-
if (code[i] == '\n') {
388-
auto line = code.substr(line_index, i - line_index);
389-
boost::trim(line);
390-
if (boost::starts_with(line, "#pragma"))
391-
code.insert(i++, 1, '\n');
392-
line_index = i;
393-
}
394-
}
472+
normalizeLegacyShaderStagePragmas(code);
473+
ensureTrailingNewline(code);
395474

396475
// preprocess
397476
core::string resolvedString = nbl::wave::preprocess(code, preprocessOptions, bool(dependenciesOut),
@@ -409,19 +488,6 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
409488
}
410489
);
411490

412-
// for debugging cause MSVC doesn't like to show more than 21k LoC in TextVisualizer
413-
if constexpr (false)
414-
{
415-
system::ISystem::future_t<core::smart_refctd_ptr<system::IFile>> future;
416-
m_system->createFile(future,system::path(preprocessOptions.sourceIdentifier).parent_path()/"preprocessed.hlsl",system::IFileBase::ECF_WRITE);
417-
if (auto file=future.acquire(); file&&bool(*file))
418-
{
419-
system::IFile::success_t succ;
420-
(*file)->write(succ,resolvedString.data(),0,resolvedString.size()+1);
421-
succ.getBytesProcessed(true);
422-
}
423-
}
424-
425491
if (resolvedString.empty())
426492
return resolvedString;
427493

@@ -433,14 +499,19 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
433499
params.sourceIdentifier = preprocessOptions.sourceIdentifier;
434500
if (!params.sourceIdentifier.empty())
435501
params.workingDirectory = std::filesystem::path(std::string(params.sourceIdentifier)).parent_path();
436-
params.system = m_system.get();
502+
params.system = system;
437503
if (!IShaderCompiler::writeDepfile(params, *dependenciesOut, preprocessOptions.includeFinder, preprocessOptions.logger))
438504
return {};
439505
}
440506

441507
return resolvedString;
442508
}
443509

510+
std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions, std::vector<std::string>& dxc_compile_flags_override, std::vector<CCache::SEntry::SPreprocessingDependency>* dependencies) const
511+
{
512+
return preprocessShaderImpl(std::move(code), stage, preprocessOptions, dxc_compile_flags_override, dependencies, m_system.get());
513+
}
514+
444515
std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions, std::vector<CCache::SEntry::SPreprocessingDependency>* dependencies) const
445516
{
446517
std::vector<std::string> extra_dxc_compile_flags = {};

0 commit comments

Comments
 (0)