Skip to content

Commit ffbd843

Browse files
HazarduAnastaZIuk
authored andcommitted
Fixes to pragma wave dxc_compile_flags for hlsl preprocessor
1 parent f68ad87 commit ffbd843

File tree

2 files changed

+66
-43
lines changed

2 files changed

+66
-43
lines changed

src/nbl/asset/utils/CHLSLCompiler.cpp

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ DxcCompilationResult dxcCompile(const CHLSLCompiler* compiler, nbl::asset::impl:
8383
if ((options.debugInfoFlags.value & sourceEmittingFlags) != CHLSLCompiler::E_DEBUG_INFO_FLAGS::EDIF_NONE)
8484
{
8585
std::ostringstream insertion;
86-
insertion << "//#pragma compile_flags ";
86+
insertion << "#pragma compile_flags ";
8787

8888
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> conv;
8989
for (uint32_t arg = 0; arg < argCount; arg ++)
@@ -204,11 +204,11 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
204204
return resolvedString;
205205
}
206206

207-
//std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const
208-
//{
209-
// std::vector<LPCWSTR> extra_dxc_compile_flags = {};
210-
// return preprocessShader(code, stage, extra_dxc_compile_flags, preprocessOptions);
211-
//}
207+
std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const
208+
{
209+
std::vector<std::string> extra_dxc_compile_flags = {};
210+
return preprocessShader(std::move(code), stage, extra_dxc_compile_flags, preprocessOptions);
211+
}
212212

213213
core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* code, const IShaderCompiler::SCompilerOptions& options) const
214214
{
@@ -238,41 +238,47 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
238238
// Set profile two letter prefix based on stage
239239
switch (stage)
240240
{
241-
case asset::IShader::ESS_VERTEX:
242-
targetProfile.replace(0, 2, L"vs");
243-
break;
244-
case asset::IShader::ESS_TESSELLATION_CONTROL:
245-
targetProfile.replace(0, 2, L"ds");
246-
break;
247-
case asset::IShader::ESS_TESSELLATION_EVALUATION:
248-
targetProfile.replace(0, 2, L"hs");
249-
break;
250-
case asset::IShader::ESS_GEOMETRY:
251-
targetProfile.replace(0, 2, L"gs");
252-
break;
253-
case asset::IShader::ESS_FRAGMENT:
254-
targetProfile.replace(0, 2, L"ps");
255-
break;
256-
case asset::IShader::ESS_COMPUTE:
257-
targetProfile.replace(0, 2, L"cs");
258-
break;
259-
case asset::IShader::ESS_TASK:
260-
targetProfile.replace(0, 2, L"as");
261-
break;
262-
case asset::IShader::ESS_MESH:
263-
targetProfile.replace(0, 2, L"ms");
264-
break;
265-
default:
266-
hlslOptions.preprocessorOptions.logger.log("invalid shader stage %i", system::ILogger::ELL_ERROR, stage);
267-
return nullptr;
241+
case asset::IShader::ESS_VERTEX:
242+
targetProfile.replace(0, 2, L"vs");
243+
break;
244+
case asset::IShader::ESS_TESSELLATION_CONTROL:
245+
targetProfile.replace(0, 2, L"ds");
246+
break;
247+
case asset::IShader::ESS_TESSELLATION_EVALUATION:
248+
targetProfile.replace(0, 2, L"hs");
249+
break;
250+
case asset::IShader::ESS_GEOMETRY:
251+
targetProfile.replace(0, 2, L"gs");
252+
break;
253+
case asset::IShader::ESS_FRAGMENT:
254+
targetProfile.replace(0, 2, L"ps");
255+
break;
256+
case asset::IShader::ESS_COMPUTE:
257+
targetProfile.replace(0, 2, L"cs");
258+
break;
259+
case asset::IShader::ESS_TASK:
260+
targetProfile.replace(0, 2, L"as");
261+
break;
262+
case asset::IShader::ESS_MESH:
263+
targetProfile.replace(0, 2, L"ms");
264+
break;
265+
default:
266+
hlslOptions.preprocessorOptions.logger.log("invalid shader stage %i", system::ILogger::ELL_ERROR, stage);
267+
return nullptr;
268268
};
269269

270-
270+
std::wstring* arg_storage = NULL;
271271
std::vector<LPCWSTR> arguments;
272-
if (dxc_compile_flags.size()) {
272+
273+
if (dxc_compile_flags.size()) { // #pragma wave overrides compile flags
274+
size_t arg_size = dxc_compile_flags.size();
273275
arguments = {};
274-
for (size_t i = 0; i < dxc_compile_flags.size(); i++)
275-
arguments.push_back(LPCWSTR(dxc_compile_flags[i].c_str()));
276+
arguments.reserve(arg_size);
277+
arg_storage = new std::wstring[arg_size]; // prevent deallocation before shader compilation
278+
for (size_t i = 0; i < dxc_compile_flags.size(); i++) {
279+
arg_storage[i] = std::wstring(dxc_compile_flags[i].begin(), dxc_compile_flags[i].end());
280+
arguments.push_back(arg_storage[i].c_str());
281+
}
276282
}
277283
else {
278284
arguments = {
@@ -315,11 +321,14 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
315321
this,
316322
m_dxcCompilerTypes,
317323
newCode,
318-
&arguments[0],
324+
arguments.data(),
319325
arguments.size(),
320326
hlslOptions
321327
);
322328

329+
if (arg_storage)
330+
delete[] arg_storage;
331+
323332
if (!compileResult.objectBlob)
324333
{
325334
return nullptr;
@@ -341,4 +350,6 @@ void CHLSLCompiler::insertIntoStart(std::string& code, std::ostringstream&& ins)
341350
{
342351
code.insert(0u, ins.str());
343352
}
353+
354+
344355
#endif

src/nbl/asset/utils/waveContext.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ struct load_to_string final
4747
struct preprocessing_hooks final : public boost::wave::context_policies::default_preprocessing_hooks
4848
{
4949
preprocessing_hooks(const IShaderCompiler::SPreprocessorOptions& _preprocessOptions)
50-
: m_includeFinder(_preprocessOptions.includeFinder), m_logger(_preprocessOptions.logger), m_pragmaStage(IShader::ESS_UNKNOWN), m_dxc_compile_flags_override() {}
50+
: m_includeFinder(_preprocessOptions.includeFinder), m_logger(_preprocessOptions.logger), m_pragmaStage(IShader::ESS_UNKNOWN), m_dxc_compile_flags_override()
51+
{
52+
hash_token_occurences = 0;
53+
}
5154

5255
template <typename ContextT>
5356
bool locate_include_file(ContextT& ctx, std::string& file_path, bool is_system, char const* current_name, std::string& dir_path, std::string& native_name)
@@ -56,6 +59,7 @@ struct preprocessing_hooks final : public boost::wave::context_policies::default
5659
return false;
5760
}
5861

62+
5963
// interpretation of #pragma's of the form 'wave option[(value)]'
6064
template <typename ContextT, typename ContainerT>
6165
bool interpret_pragma(
@@ -64,6 +68,7 @@ struct preprocessing_hooks final : public boost::wave::context_policies::default
6468
typename ContextT::token_type const& act_token
6569
)
6670
{
71+
hash_token_occurences++;
6772
auto optionStr = option.get_value().c_str();
6873
if (strcmp(optionStr,"shader_stage")==0)
6974
{
@@ -98,15 +103,20 @@ struct preprocessing_hooks final : public boost::wave::context_policies::default
98103
return true;
99104
}
100105

101-
if (strcmp(optionStr, "dxc_compile_flags") == 0) {
106+
if (strcmp(optionStr, "dxc_compile_flags") == 0 && hash_token_occurences == 1) {
102107
m_dxc_compile_flags_override.clear();
103108
for (auto valueIter = values.begin(); valueIter != values.end(); valueIter++) {
104109
std::string compiler_option_s = std::string(valueIter->get_value().c_str());
105-
if (compiler_option_s[0] == '"' && compiler_option_s[compiler_option_s.length() - 1] == '"')
106-
compiler_option_s = compiler_option_s.substr(1, compiler_option_s.length() - 2);
110+
// if this compiler flag is encapsulated in quotation marks, strip them
111+
//if (compiler_option_s[0] == '"' && compiler_option_s[compiler_option_s.length() - 1] == '"')
112+
// compiler_option_s = compiler_option_s.substr(1, compiler_option_s.length() - 2);
113+
114+
// if the compiler flag is a separator that is a comma or whitespace, do not add to list of flag overrides
115+
if (compiler_option_s == "," || compiler_option_s == " ")
116+
continue;
107117
m_dxc_compile_flags_override.push_back(compiler_option_s);
108118
}
109-
119+
return true;
110120
}
111121

112122
return false;
@@ -126,7 +136,9 @@ struct preprocessing_hooks final : public boost::wave::context_policies::default
126136
const IShaderCompiler::CIncludeFinder* m_includeFinder;
127137
system::logger_opt_ptr m_logger;
128138
IShader::E_SHADER_STAGE m_pragmaStage;
139+
int hash_token_occurences;
129140
std::vector<std::string> m_dxc_compile_flags_override;
141+
130142
};
131143

132144
class context : private boost::noncopyable

0 commit comments

Comments
 (0)