@@ -74,11 +74,6 @@ static tcpp::IInputStream* getInputStreamInclude(
74
74
if (!res_str.size ()) {
75
75
return nullptr ;
76
76
}
77
- else {
78
- // employ encloseWithinExtraInclGuards() in order to prevent infinite loop of (not necesarilly direct) self-inclusions while other # directives (incl guards among them) are disabled
79
- IShaderCompiler::disableAllDirectivesExceptIncludes (res_str);
80
- res_str = IShaderCompiler::encloseWithinExtraInclGuards (std::move (res_str), _maxInclCnt, name.string ().c_str ());
81
- }
82
77
83
78
return new tcpp::StringInputStream (std::move (res_str));
84
79
}
@@ -143,7 +138,7 @@ CHLSLCompiler::DxcCompilationResult CHLSLCompiler::dxcCompile(std::string& sourc
143
138
return result;
144
139
}
145
140
146
- std::string CHLSLCompiler::preprocessShader (std::string&& code, IShader::E_SHADER_STAGE stage, const SPreprocessorOptions& preprocessOptions) const
141
+ std::string CHLSLCompiler::preprocessShader (std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const
147
142
{
148
143
if (preprocessOptions.extraDefines .size ())
149
144
{
@@ -166,6 +161,52 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
166
161
}
167
162
);
168
163
164
+ auto pragmaShaderStageCallback = [&](IShader::E_SHADER_STAGE _stage) {
165
+ return [&](tcpp::Preprocessor& preprocessor, tcpp::Lexer& lexer, const std::string& text) {
166
+ stage = _stage;
167
+ return std::string (" " );
168
+ };
169
+ };
170
+
171
+ proc.AddCustomDirectiveHandler (std::string (" pragma shader_stage" ), [&](tcpp::Preprocessor& preprocessor, tcpp::Lexer& lexer, const std::string& text) {
172
+ if (!lexer.HasNextToken ()) return std::string (" #error Malformed shader_stage pragma" );
173
+ auto token = lexer.GetNextToken ();
174
+ if (token.mType != tcpp::E_TOKEN_TYPE::OPEN_BRACKET) return std::string (" #error Malformed shader_stage pragma" );
175
+
176
+ if (!lexer.HasNextToken ()) return std::string (" #error Malformed shader_stage pragma" );
177
+ token = lexer.GetNextToken ();
178
+ if (token.mType != tcpp::E_TOKEN_TYPE::IDENTIFIER) return std::string (" #error Malformed shader_stage pragma" );
179
+
180
+ auto & shaderStageIdentifier = token.mRawView ;
181
+ core::unordered_map<std::string, IShader::E_SHADER_STAGE> stageFromIdent = {
182
+ { " vertex" , IShader::ESS_VERTEX },
183
+ { " fragment" , IShader::ESS_FRAGMENT },
184
+ { " tesscontrol" , IShader::ESS_TESSELLATION_CONTROL },
185
+ { " tesseval" , IShader::ESS_TESSELLATION_EVALUATION },
186
+ { " geometry" , IShader::ESS_GEOMETRY },
187
+ { " compute" , IShader::ESS_COMPUTE }
188
+ };
189
+
190
+ auto found = stageFromIdent.find (shaderStageIdentifier);
191
+ if (found == stageFromIdent.end ())
192
+ {
193
+ return std::string (" #error Malformed shader_stage pragma, unknown stage" );
194
+ }
195
+ stage = found->second ;
196
+
197
+ if (!lexer.HasNextToken ()) return std::string (" #error Malformed shader_stage pragma" );
198
+ token = lexer.GetNextToken ();
199
+ if (token.mType != tcpp::E_TOKEN_TYPE::CLOSE_BRACKET) return std::string (" #error Malformed shader_stage pragma" );
200
+
201
+ while (lexer.HasNextToken ()) {
202
+ auto token = lexer.GetNextToken ();
203
+ if (token.mType == tcpp::E_TOKEN_TYPE::NEWLINE) break ;
204
+ if (token.mType != tcpp::E_TOKEN_TYPE::SPACE) return std::string (" #error Malformed shader_stage pragma" );
205
+ }
206
+
207
+ return std::string (" " );
208
+ });
209
+
169
210
return proc.Process ();
170
211
}
171
212
else
@@ -184,13 +225,14 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
184
225
return nullptr ;
185
226
}
186
227
187
- auto newCode = preprocessShader (code, hlslOptions.stage , hlslOptions.preprocessorOptions );
228
+ auto stage = hlslOptions.stage ;
229
+ auto newCode = preprocessShader (code, stage, hlslOptions.preprocessorOptions );
188
230
189
231
// Suffix is the shader model version
190
232
std::wstring targetProfile (L" XX_6_2" );
191
233
192
234
// Set profile two letter prefix based on stage
193
- switch (options. stage ) {
235
+ switch (stage) {
194
236
case asset::IShader::ESS_VERTEX:
195
237
targetProfile.replace (0 , 2 , L" vs" );
196
238
break ;
@@ -216,7 +258,7 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
216
258
targetProfile.replace (0 , 2 , L" ms" );
217
259
break ;
218
260
default :
219
- hlslOptions.preprocessorOptions .logger .log (" invalid shader stage %i" , system::ILogger::ELL_ERROR, options. stage );
261
+ hlslOptions.preprocessorOptions .logger .log (" invalid shader stage %i" , system::ILogger::ELL_ERROR, stage);
220
262
return nullptr ;
221
263
};
222
264
@@ -246,7 +288,7 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
246
288
247
289
compileResult.release ();
248
290
249
- return core::make_smart_refctd_ptr<asset::ICPUShader>(std::move (outSpirv), hlslOptions. stage , IShader::E_CONTENT_TYPE::ECT_SPIRV, hlslOptions.preprocessorOptions .sourceIdentifier .data ());
291
+ return core::make_smart_refctd_ptr<asset::ICPUShader>(std::move (outSpirv), stage, IShader::E_CONTENT_TYPE::ECT_SPIRV, hlslOptions.preprocessorOptions .sourceIdentifier .data ());
250
292
}
251
293
252
294
void CHLSLCompiler::insertIntoStart (std::string& code, std::ostringstream&& ins) const
0 commit comments