@@ -21,6 +21,8 @@ using namespace nbl;
2121using namespace nbl ::asset;
2222using Microsoft::WRL::ComPtr;
2323
24+ static constexpr const wchar_t * SHADER_MODEL_PROFILE = L" XX_6_2" ;
25+
2426namespace nbl ::asset::hlsl::impl
2527{
2628 struct DXC {
@@ -57,7 +59,10 @@ static tcpp::IInputStream* getInputStreamInclude(
5759 uint32_t _maxInclCnt,
5860 const char * _requesting_source,
5961 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
6166)
6267{
6368 std::string res_str;
@@ -87,8 +92,25 @@ static tcpp::IInputStream* getInputStreamInclude(
8792 return new tcpp::StringInputStream (" #error File not found" );
8893 }
8994
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+
90102 IShaderCompiler::disableAllDirectivesExceptIncludes (res_str);
91103 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 ());
92114
93115 return new tcpp::StringInputStream (std::move (res_str));
94116}
@@ -169,13 +191,24 @@ DxcCompilationResult dxcCompile(const CHLSLCompiler* compiler, nbl::asset::hlsl:
169191
170192std::string CHLSLCompiler::preprocessShader (std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const
171193{
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 );
172201 if (preprocessOptions.extraDefines .size ())
173202 {
174203 insertExtraDefines (code, preprocessOptions.extraDefines );
204+ defineLeadingLinesMain += preprocessOptions.extraDefines .size ();
175205 }
176206
177207 IShaderCompiler::disableAllDirectivesExceptIncludes (code);
178208
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+
179212 tcpp::StringInputStream codeIs = tcpp::StringInputStream (code);
180213 tcpp::Lexer lexer (codeIs);
181214 tcpp::Preprocessor proc (
@@ -188,13 +221,17 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
188221 {
189222 return getInputStreamInclude (
190223 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
192226 );
193227 }
194228 else
195229 {
196230 return static_cast <tcpp::IInputStream*>(new tcpp::StringInputStream (std::string (" #error No include handler" )));
197231 }
232+ },
233+ [&]() {
234+ lineOffsetStack.pop_back ();
198235 }
199236 );
200237
@@ -239,6 +276,8 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
239276
240277 auto resolvedString = proc.Process ();
241278 IShaderCompiler::reenableDirectives (resolvedString);
279+
280+ printf (" Resolved string:\n\n %s\n " , resolvedString.c_str ());
242281 return resolvedString;
243282}
244283
@@ -265,7 +304,7 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
265304 // Another option is trying to fetch it from the commandline tool, either from parsing the help message
266305 // or from brute forcing every -T option until one isn't accepted
267306 //
268- std::wstring targetProfile (L" XX_6_2 " );
307+ std::wstring targetProfile (SHADER_MODEL_PROFILE );
269308
270309 // Set profile two letter prefix based on stage
271310 switch (stage) {
0 commit comments