Skip to content

Commit 0225037

Browse files
committed
Apply changes to handling directives
1 parent b9432c1 commit 0225037

File tree

4 files changed

+92
-66
lines changed

4 files changed

+92
-66
lines changed

include/nbl/asset/utils/CGLSLCompiler.h

Lines changed: 12 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,6 @@ namespace nbl::asset
1414
class NBL_API2 CGLSLCompiler final : public IShaderCompiler
1515
{
1616
public:
17-
//string to be replaced with all "#" except those in "#include"
18-
static constexpr const char* PREPROC_DIRECTIVE_DISABLER = "_this_is_a_hash_";
19-
static constexpr const char* PREPROC_DIRECTIVE_ENABLER = PREPROC_DIRECTIVE_DISABLER;
20-
static constexpr const char* PREPROC_GL__DISABLER = "_this_is_a_GL__prefix_";
21-
static constexpr const char* PREPROC_GL__ENABLER = PREPROC_GL__DISABLER;
22-
static constexpr const char* PREPROC_LINE_CONTINUATION_DISABLER = "_this_is_a_line_continuation_\n";
23-
static constexpr const char* PREPROC_LINE_CONTINUATION_ENABLER = "_this_is_a_line_continuation_";
24-
2517

2618
IShader::E_CONTENT_TYPE getCodeContentType() const override { return IShader::E_CONTENT_TYPE::ECT_GLSL; };
2719

@@ -134,69 +126,28 @@ class NBL_API2 CGLSLCompiler final : public IShaderCompiler
134126
}
135127
}
136128

137-
static void disableAllDirectivesExceptIncludes(std::string& _code)
129+
std::string preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const override;
130+
131+
static constexpr const char* PREPROC_GL__DISABLER = "_this_is_a_GL__prefix_";
132+
static constexpr const char* PREPROC_GL__ENABLER = PREPROC_GL__DISABLER;
133+
static constexpr const char* PREPROC_LINE_CONTINUATION_DISABLER = "_this_is_a_line_continuation_\n";
134+
static constexpr const char* PREPROC_LINE_CONTINUATION_ENABLER = "_this_is_a_line_continuation_";
135+
136+
static void disableGlDirectives(std::string& _code)
138137
{
139-
// TODO: replace this with a proper-ish proprocessor and includer one day
140-
std::regex directive("#(?!(include|version|pragma shader_stage|line))");//all # not followed by "include" nor "version" nor "pragma shader_stage"
141-
//`#pragma shader_stage(...)` is needed for determining shader stage when `_stage` param of IShaderCompiler functions is set to ESS_UNKNOWN
142-
auto result = std::regex_replace(_code, directive, PREPROC_DIRECTIVE_DISABLER);
143138
std::regex glMacro("[ \t\r\n\v\f]GL_");
144-
result = std::regex_replace(result, glMacro, PREPROC_GL__DISABLER);
139+
auto result = std::regex_replace(_code, glMacro, PREPROC_GL__DISABLER);
145140
std::regex lineContinuation("\\\\[ \t\r\n\v\f]*\n");
146141
_code = std::regex_replace(result, lineContinuation, PREPROC_LINE_CONTINUATION_DISABLER);
147142
}
148-
static void reenableDirectives(std::string& _code)
143+
144+
static void reenableGlDirectives(std::string& _code)
149145
{
150146
std::regex lineContinuation(PREPROC_LINE_CONTINUATION_ENABLER);
151147
auto result = std::regex_replace(_code, lineContinuation, " \\");
152148
std::regex glMacro(PREPROC_GL__ENABLER);
153-
result = std::regex_replace(result, glMacro, " GL_");
154-
std::regex directive(PREPROC_DIRECTIVE_ENABLER);
155-
_code = std::regex_replace(result, directive, "#");
149+
_code = std::regex_replace(result, glMacro, " GL_");
156150
}
157-
static std::string encloseWithinExtraInclGuards(std::string&& _code, uint32_t _maxInclusions, const char* _identifier)
158-
{
159-
assert(_maxInclusions != 0u);
160-
161-
using namespace std::string_literals;
162-
std::string defBase_ = "_GENERATED_INCLUDE_GUARD_"s + _identifier + "_";
163-
std::replace_if(defBase_.begin(), defBase_.end(), [](char c) ->bool { return !::isalpha(c) && !::isdigit(c); }, '_');
164-
165-
auto genDefs = [&defBase_, _maxInclusions, _identifier] {
166-
auto defBase = [&defBase_](uint32_t n) { return defBase_ + std::to_string(n); };
167-
std::string defs = "#ifndef " + defBase(0) + "\n\t#define " + defBase(0) + "\n";
168-
for (uint32_t i = 1u; i <= _maxInclusions; ++i) {
169-
const std::string defname = defBase(i);
170-
defs += "#elif !defined(" + defname + ")\n\t#define " + defname + "\n";
171-
}
172-
defs += "#endif\n";
173-
return defs;
174-
};
175-
auto genUndefs = [&defBase_, _maxInclusions, _identifier] {
176-
auto defBase = [&defBase_](int32_t n) { return defBase_ + std::to_string(n); };
177-
std::string undefs = "#ifdef " + defBase(_maxInclusions) + "\n\t#undef " + defBase(_maxInclusions) + "\n";
178-
for (int32_t i = _maxInclusions - 1; i >= 0; --i) {
179-
const std::string defname = defBase(i);
180-
undefs += "#elif defined(" + defname + ")\n\t#undef " + defname + "\n";
181-
}
182-
undefs += "#endif\n";
183-
return undefs;
184-
};
185-
186-
return
187-
genDefs() +
188-
"\n"
189-
"#ifndef " + defBase_ + std::to_string(_maxInclusions) +
190-
"\n" +
191-
"#line 1 \"" + _identifier + "\"\n" +
192-
_code +
193-
"\n"
194-
"#endif"
195-
"\n\n" +
196-
genUndefs();
197-
}
198-
199-
std::string preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const override;
200151

201152
protected:
202153

include/nbl/asset/utils/IShaderCompiler.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,69 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
255255
}
256256
}
257257

258+
//string to be replaced with all "#" except those in "#include"
259+
static constexpr const char* PREPROC_DIRECTIVE_DISABLER = "_this_is_a_hash_";
260+
static constexpr const char* PREPROC_DIRECTIVE_ENABLER = PREPROC_DIRECTIVE_DISABLER;
261+
262+
// TODO make sure there are no GLSL specifics for these functions in the HLSL compiler
263+
//
264+
//all "#", except those in "#include"/"#version"/"#pragma shader_stage(...)", replaced with `PREPROC_DIRECTIVE_DISABLER`
265+
static void disableAllDirectivesExceptIncludes(std::string& _code)
266+
{
267+
// TODO: replace this with a proper-ish proprocessor and includer one day
268+
std::regex directive("#(?!(include|version|pragma shader_stage))");//all # not followed by "include" nor "version" nor "pragma shader_stage"
269+
//`#pragma shader_stage(...)` is needed for determining shader stage when `_stage` param of IShaderCompiler functions is set to ESS_UNKNOWN
270+
_code = std::regex_replace(_code, directive, PREPROC_DIRECTIVE_DISABLER);
271+
}
272+
273+
static void reenableDirectives(std::string& _code)
274+
{
275+
std::regex directive(PREPROC_DIRECTIVE_ENABLER);
276+
_code = std::regex_replace(_code, directive, "#");
277+
}
278+
279+
static std::string encloseWithinExtraInclGuards(std::string&& _code, uint32_t _maxInclusions, const char* _identifier)
280+
{
281+
assert(_maxInclusions != 0u);
282+
283+
using namespace std::string_literals;
284+
std::string defBase_ = "_GENERATED_INCLUDE_GUARD_"s + _identifier + "_";
285+
std::replace_if(defBase_.begin(), defBase_.end(), [](char c) ->bool { return !::isalpha(c) && !::isdigit(c); }, '_');
286+
287+
auto genDefs = [&defBase_, _maxInclusions, _identifier] {
288+
auto defBase = [&defBase_](uint32_t n) { return defBase_ + std::to_string(n); };
289+
std::string defs = "#ifndef " + defBase(0) + "\n\t#define " + defBase(0) + "\n";
290+
for (uint32_t i = 1u; i <= _maxInclusions; ++i) {
291+
const std::string defname = defBase(i);
292+
defs += "#elif !defined(" + defname + ")\n\t#define " + defname + "\n";
293+
}
294+
defs += "#endif\n";
295+
return defs;
296+
};
297+
auto genUndefs = [&defBase_, _maxInclusions, _identifier] {
298+
auto defBase = [&defBase_](int32_t n) { return defBase_ + std::to_string(n); };
299+
std::string undefs = "#ifdef " + defBase(_maxInclusions) + "\n\t#undef " + defBase(_maxInclusions) + "\n";
300+
for (int32_t i = _maxInclusions - 1; i >= 0; --i) {
301+
const std::string defname = defBase(i);
302+
undefs += "#elif defined(" + defname + ")\n\t#undef " + defname + "\n";
303+
}
304+
undefs += "#endif\n";
305+
return undefs;
306+
};
307+
308+
return
309+
genDefs() +
310+
"\n"
311+
"#ifndef " + defBase_ + std::to_string(_maxInclusions) +
312+
"\n" +
313+
"#line 1 \"" + _identifier + "\"\n" +
314+
_code +
315+
"\n"
316+
"#endif"
317+
"\n\n" +
318+
genUndefs();
319+
}
320+
258321
virtual IShader::E_CONTENT_TYPE getCodeContentType() const = 0;
259322

260323
CIncludeFinder* getDefaultIncludeFinder() { return m_defaultIncludeFinder.get(); }

src/nbl/asset/utils/CGLSLCompiler.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ namespace nbl::asset::impl
6666
}
6767
else {
6868
//employ encloseWithinExtraInclGuards() in order to prevent infinite loop of (not necesarilly direct) self-inclusions while other # directives (incl guards among them) are disabled
69-
CGLSLCompiler::disableAllDirectivesExceptIncludes(res_str);
70-
res_str = CGLSLCompiler::encloseWithinExtraInclGuards(std::move(res_str), m_maxInclCnt, name.string().c_str());
69+
IShaderCompiler::disableAllDirectivesExceptIncludes(res_str);
70+
CGLSLCompiler::disableGlDirectives(res_str);
71+
res_str = IShaderCompiler::encloseWithinExtraInclGuards(std::move(res_str), m_maxInclCnt, name.string().c_str());
7172

7273
res->content_length = res_str.size();
7374
res->content = new char[res_str.size() + 1u];
@@ -106,7 +107,8 @@ std::string CGLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
106107
}
107108
if (preprocessOptions.includeFinder != nullptr)
108109
{
109-
CGLSLCompiler::disableAllDirectivesExceptIncludes(code);//all "#", except those in "#include"/"#version"/"#pragma shader_stage(...)", replaced with `PREPROC_DIRECTIVE_DISABLER`
110+
IShaderCompiler::disableAllDirectivesExceptIncludes(code);
111+
CGLSLCompiler::disableGlDirectives(code);
110112
shaderc::Compiler comp;
111113
shaderc::CompileOptions options;
112114
options.SetTargetSpirv(shaderc_spirv_version_1_6);
@@ -121,7 +123,8 @@ std::string CGLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
121123
}
122124

123125
auto resolvedString = std::string(res.cbegin(), std::distance(res.cbegin(), res.cend()));
124-
CGLSLCompiler::reenableDirectives(resolvedString);
126+
IShaderCompiler::reenableDirectives(resolvedString);
127+
CGLSLCompiler::reenableGlDirectives(resolvedString);
125128
return resolvedString;
126129
}
127130
else

src/nbl/asset/utils/CHLSLCompiler.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ static tcpp::IInputStream* getInputStreamInclude(
7171
return nullptr;
7272
}
7373

74+
IShaderCompiler::disableAllDirectivesExceptIncludes(res_str);
75+
// TODO support this
76+
//res_str = IShaderCompiler::encloseWithinExtraInclGuards(std::move(res_str), _maxInclCnt, name.string().c_str());
77+
7478
return new tcpp::StringInputStream(std::move(res_str));
7579
}
7680

@@ -156,6 +160,8 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
156160
}
157161
if (preprocessOptions.includeFinder != nullptr)
158162
{
163+
IShaderCompiler::disableAllDirectivesExceptIncludes(code);
164+
159165
tcpp::StringInputStream codeIs = tcpp::StringInputStream(code);
160166
tcpp::Lexer lexer(codeIs);
161167
tcpp::Preprocessor proc(
@@ -217,7 +223,10 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
217223
return std::string("");
218224
});
219225

220-
return proc.Process();
226+
auto resolvedString = proc.Process();
227+
IShaderCompiler::reenableDirectives(resolvedString);
228+
229+
return resolvedString;
221230
}
222231
else
223232
{

0 commit comments

Comments
 (0)