@@ -153,6 +153,7 @@ class ShaderCompiler final : public system::IApplicationFramework
153153 });
154154 };
155155
156+ auto preprocessOnly = findOutputFlag (" -P" ) != m_arguments.end ();
156157 auto output_flag_pos_fc = findOutputFlag (" -Fc" );
157158 auto output_flag_pos_fo = findOutputFlag (" -Fo" );
158159 if (output_flag_pos_fc != m_arguments.end () && output_flag_pos_fo != m_arguments.end ()) {
@@ -195,7 +196,8 @@ class ShaderCompiler final : public system::IApplicationFramework
195196 return false ;
196197 }
197198
198- m_logger->log (" Compiled shader code will be saved to " + output_filepath, ILogger::ELL_INFO);
199+ std::string outputType = preprocessOnly ? " Preprocessed" : " Compiled" ;
200+ m_logger->log (outputType + " shader code will be saved to " + output_filepath, ILogger::ELL_INFO);
199201 }
200202
201203#ifndef NBL_EMBED_BUILTIN_RESOURCES
@@ -227,13 +229,27 @@ class ShaderCompiler final : public system::IApplicationFramework
227229 }
228230
229231 auto start = std::chrono::high_resolution_clock::now ();
230- auto compilation_result = compile_shader (shader.get (), shaderStage, file_to_compile);
232+ smart_refctd_ptr<IShader> compilation_result;
233+ std::string preprocessing_result;
234+ std::string_view result_view;
235+ if (preprocessOnly)
236+ {
237+ preprocessing_result = preprocess_shader (shader.get (), shaderStage, file_to_compile);
238+ result_view = preprocessing_result;
239+ }
240+ else
241+ {
242+ compilation_result = compile_shader (shader.get (), shaderStage, file_to_compile);
243+ result_view = { (const char *)compilation_result->getContent ()->getPointer (), compilation_result->getContent ()->getSize () };
244+ }
231245 auto end = std::chrono::high_resolution_clock::now ();
232246
233- // writie compiled shader to file as bytes
234- if (compilation_result)
247+ // write compiled/preprocessed shader to file as bytes
248+ std::string operationType = preprocessOnly ? " preprocessing" : " compilation" ;
249+ const bool success = preprocessOnly ? preprocessing_result != std::string{} : bool (compilation_result);
250+ if (success)
235251 {
236- m_logger->log (" Shader compilation successful." , ILogger::ELL_INFO);
252+ m_logger->log (" Shader " + operationType + " successful." , ILogger::ELL_INFO);
237253 const auto took = std::to_string (std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count ());
238254 m_logger->log (" Took %s ms." , ILogger::ELL_PERFORMANCE, took.c_str ());
239255 {
@@ -258,7 +274,7 @@ class ShaderCompiler final : public system::IApplicationFramework
258274 return false ;
259275 }
260276
261- output_file.write (( const char *)compilation_result-> getContent ()-> getPointer (), compilation_result-> getContent ()-> getSize ());
277+ output_file.write (result_view. data (), result_view. size ());
262278
263279 if (output_file.fail ())
264280 {
@@ -279,7 +295,7 @@ class ShaderCompiler final : public system::IApplicationFramework
279295 }
280296 else
281297 {
282- m_logger->log (" Shader compilation failed." , ILogger::ELL_ERROR);
298+ m_logger->log (" Shader " + operationType + " failed." , ILogger::ELL_ERROR);
283299 return false ;
284300 }
285301 }
@@ -291,6 +307,28 @@ class ShaderCompiler final : public system::IApplicationFramework
291307
292308private:
293309
310+ std::string preprocess_shader (const IShader* shader, hlsl::ShaderStage shaderStage, std::string_view sourceIdentifier) {
311+ smart_refctd_ptr<CHLSLCompiler> hlslcompiler = make_smart_refctd_ptr<CHLSLCompiler>(smart_refctd_ptr (m_system));
312+
313+ CHLSLCompiler::SPreprocessorOptions options = {};
314+ options.sourceIdentifier = sourceIdentifier;
315+ options.logger = m_logger.get ();
316+
317+ auto includeFinder = make_smart_refctd_ptr<IShaderCompiler::CIncludeFinder>(smart_refctd_ptr (m_system));
318+ auto includeLoader = includeFinder->getDefaultFileSystemLoader ();
319+
320+ // because before real compilation we do preprocess the input it doesn't really matter we proxy include search direcotries further with dxcOptions since at the end all includes are resolved to single file
321+ for (const auto & it : m_include_search_paths)
322+ includeFinder->addSearchPath (it, includeLoader);
323+
324+ options.includeFinder = includeFinder.get ();
325+
326+ const char * code_ptr = (const char *)shader->getContent ()->getPointer ();
327+ std::string_view code ({ code_ptr, strlen (code_ptr)});
328+
329+ return hlslcompiler->preprocessShader (std::string (code), shaderStage, options, nullptr );
330+ }
331+
294332 core::smart_refctd_ptr<IShader> compile_shader (const IShader* shader, hlsl::ShaderStage shaderStage, std::string_view sourceIdentifier) {
295333 smart_refctd_ptr<CHLSLCompiler> hlslcompiler = make_smart_refctd_ptr<CHLSLCompiler>(smart_refctd_ptr (m_system));
296334
0 commit comments