@@ -21,6 +21,8 @@ using namespace nbl;
21
21
using namespace nbl ::asset;
22
22
using Microsoft::WRL::ComPtr;
23
23
24
+ static constexpr const wchar_t * SHADER_MODEL_PROFILE = L" XX_6_2" ;
25
+
24
26
namespace nbl ::asset::hlsl::impl
25
27
{
26
28
struct DXC {
@@ -57,7 +59,10 @@ static tcpp::IInputStream* getInputStreamInclude(
57
59
uint32_t _maxInclCnt,
58
60
const char * _requesting_source,
59
61
const char * _requested_source,
60
- bool _type // true for #include "string"; false for #include <string>
62
+ bool _type, // true for #include "string"; false for #include <string>
63
+ uint32_t lexerLineIndex,
64
+ uint32_t leadingLinesImports,
65
+ std::vector<std::pair<uint32_t , std::string>>& includeStack
61
66
)
62
67
{
63
68
std::string res_str;
@@ -87,8 +92,25 @@ static tcpp::IInputStream* getInputStreamInclude(
87
92
return new tcpp::StringInputStream (" #error File not found" );
88
93
}
89
94
95
+ // Figure out what line in the current file this #include was
96
+ // That would be the current lexer line, minus the line where the current file was included
97
+ uint32_t lineGoBackTo = lexerLineIndex - includeStack.back ().first -
98
+ // if this is 2 includes deep (include within include), subtract leading import lines
99
+ // from the previous include
100
+ (includeStack.size () > 1 ? leadingLinesImports : 0 );
101
+
90
102
IShaderCompiler::disableAllDirectivesExceptIncludes (res_str);
91
103
res_str = IShaderCompiler::encloseWithinExtraInclGuards (std::move (res_str), _maxInclCnt, name.string ().c_str ());
104
+ res_str = res_str + " \n " +
105
+ IShaderCompiler::PREPROC_DIRECTIVE_DISABLER + " line " + std::to_string (lineGoBackTo) + " \" " + includeStack.back ().second + " \"\n " ;
106
+
107
+ // HACK: tcpp is having issues parsing the string, so this is a hack/mitigation that could be removed once tcpp is fixed
108
+ std::string identifier = name.string ().c_str ();
109
+ std::replace (identifier.begin (), identifier.end (), ' \\ ' , ' /' );
110
+
111
+ includeStack.push_back (std::pair<uint32_t , std::string>(lineGoBackTo, identifier));
112
+
113
+ printf (" included res_str:\n %s\n " , res_str.c_str ());
92
114
93
115
return new tcpp::StringInputStream (std::move (res_str));
94
116
}
@@ -169,13 +191,24 @@ DxcCompilationResult dxcCompile(const CHLSLCompiler* compiler, nbl::asset::hlsl:
169
191
170
192
std::string CHLSLCompiler::preprocessShader (std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const
171
193
{
194
+ std::ostringstream insertion;
195
+ insertion << IShaderCompiler::PREPROC_DIRECTIVE_ENABLER;
196
+ insertion << " line 1\n " ;
197
+ insertIntoStart (code, std::move (insertion));
198
+
199
+ uint32_t defineLeadingLinesMain = 0 ;
200
+ uint32_t leadingLinesImports = IShaderCompiler::encloseWithinExtraInclGuardsLeadingLines (preprocessOptions.maxSelfInclusionCount + 1u );
172
201
if (preprocessOptions.extraDefines .size ())
173
202
{
174
203
insertExtraDefines (code, preprocessOptions.extraDefines );
204
+ defineLeadingLinesMain += preprocessOptions.extraDefines .size ();
175
205
}
176
206
177
207
IShaderCompiler::disableAllDirectivesExceptIncludes (code);
178
208
209
+ // Keep track of the line in the original file where each #include was on each level of the include stack
210
+ std::vector<std::pair<uint32_t , std::string>> lineOffsetStack = { std::pair<uint32_t , std::string>(defineLeadingLinesMain, preprocessOptions.sourceIdentifier ) };
211
+
179
212
tcpp::StringInputStream codeIs = tcpp::StringInputStream (code);
180
213
tcpp::Lexer lexer (codeIs);
181
214
tcpp::Preprocessor proc (
@@ -188,13 +221,17 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
188
221
{
189
222
return getInputStreamInclude (
190
223
preprocessOptions.includeFinder , m_system.get (), preprocessOptions.maxSelfInclusionCount + 1u ,
191
- preprocessOptions.sourceIdentifier .data (), path.c_str (), !isSystemPath
224
+ preprocessOptions.sourceIdentifier .data (), path.c_str (), !isSystemPath,
225
+ lexer.GetCurrLineIndex (), leadingLinesImports, lineOffsetStack
192
226
);
193
227
}
194
228
else
195
229
{
196
230
return static_cast <tcpp::IInputStream*>(new tcpp::StringInputStream (std::string (" #error No include handler" )));
197
231
}
232
+ },
233
+ [&]() {
234
+ lineOffsetStack.pop_back ();
198
235
}
199
236
);
200
237
@@ -239,6 +276,8 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
239
276
240
277
auto resolvedString = proc.Process ();
241
278
IShaderCompiler::reenableDirectives (resolvedString);
279
+
280
+ printf (" Resolved string:\n\n %s\n " , resolvedString.c_str ());
242
281
return resolvedString;
243
282
}
244
283
@@ -265,7 +304,7 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
265
304
// Another option is trying to fetch it from the commandline tool, either from parsing the help message
266
305
// or from brute forcing every -T option until one isn't accepted
267
306
//
268
- std::wstring targetProfile (L" XX_6_2 " );
307
+ std::wstring targetProfile (SHADER_MODEL_PROFILE );
269
308
270
309
// Set profile two letter prefix based on stage
271
310
switch (stage) {
0 commit comments