Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/nbl/asset/utils/CWaveStringResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,20 @@ namespace nbl::wave
// now define them as "NBL_GLSL_LIMIT_MAX_IMAGE_DIMENSION_1D=32768"
// to match boost wave syntax
// https://www.boost.org/doc/libs/1_82_0/libs/wave/doc/class_reference_context.html#:~:text=Maintain%20defined%20macros-,add_macro_definition,-bool%20add_macro_definition

for (const auto& define : preprocessOptions.extraDefines)
context.add_macro_definition(define.identifier.data() + core::string("=") + define.definition.data());
{
const std::string macroDefinition = define.identifier.data() + core::string("=") + define.definition.data();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we suppose define.definition being a null span ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

define.definition can be an empty string but not a null span

const bool isMacroAdded = context.add_macro_definition(macroDefinition);
assert(isMacroAdded);
Copy link
Member

@AnastaZIuk AnastaZIuk Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a duplicate should not be asserted, in this case silent fail is better

you actually better just move .add_macro_definition into try block to let wave throw an exception which we handle nicely than assert (then we come back to silent fail + opportunity to catch stuff)

}

// preprocess
core::string resolvedString;
try
{
auto stream = std::stringstream();
for (auto i= context.begin(); i!= context.end(); i++)
for (auto i = context.begin(); i != context.end(); i++)
stream << i->get_value();
resolvedString = stream.str();
}
Expand Down
43 changes: 43 additions & 0 deletions tools/nsc/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,49 @@ class ShaderCompiler final : public IApplicationFramework
opt.debugInfoFlags = bitflag<IShaderCompiler::E_DEBUG_INFO_FLAGS>(IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_TOOL_BIT);
opt.dxcOptions = std::span<std::string>(m_arguments);

// need this struct becuase fields of IShaderCompiler::SMacroDefinition are string views
struct SMacroDefinitionBuffer
{
std::string identifier;
std::string definition;
};

core::vector<SMacroDefinitionBuffer> macroDefinitionBuffers;
core::vector<IShaderCompiler::SMacroDefinition> macroDefinitions;
{
for (const auto& argument : m_arguments)
{
if (argument.rfind("-D", 0) != 0)
continue;

std::string argumentTmp = argument.substr(2);

std::string identifier;
std::string definition;

const size_t equalPos = argumentTmp.find('=');
if (equalPos == std::string::npos)
{
identifier = argumentTmp;
definition = "";
Comment on lines +523 to +527
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it changes semantic of -D compared to how DXC/Clang/GCC and friends handle it

lack of = means empty definition now, try adding -DNAME and then

  1. #if NAME
  2. #if NAME == 1
  3. #if defined(NAME) && NAME
  4. #if NAME >= 2
  5. int x = NAME;

on -DNAME we should be defining 1 (-DNAME == -DNAME=1) in this case otherwise those above will fail

}
else
{
identifier = argumentTmp.substr(0, equalPos);
definition = argumentTmp.substr(equalPos + 1);
}

macroDefinitionBuffers.emplace_back(identifier, definition);
}

macroDefinitions.reserve(macroDefinitionBuffers.size());

for (const auto& macroDefinitionBuffer : macroDefinitionBuffers)
macroDefinitions.emplace_back(macroDefinitionBuffer.identifier, macroDefinitionBuffer.definition);
}

opt.preprocessorOptions.extraDefines = macroDefinitions;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok but you forgot about preprocessOnly mode


r.compiled = hlslcompiler->compileToSPIRV((const char*)shader->getContent()->getPointer(), opt);
r.ok = bool(r.compiled);
if (r.ok)
Expand Down
Loading