2
2
// This file is part of the "Nabla Engine".
3
3
// For conditions of distribution and use, see copyright notice in nabla.h
4
4
#include " nbl/asset/utils/CHLSLCompiler.h"
5
- #include " nbl/asset/utils/waveContext.h"
6
5
#include " nbl/asset/utils/shadercUtils.h"
7
6
// TODO: review
8
7
#ifdef NBL_EMBED_BUILTIN_RESOURCES
@@ -29,140 +28,14 @@ using Microsoft::WRL::ComPtr;
29
28
30
29
static constexpr const wchar_t * SHADER_MODEL_PROFILE = L" XX_6_7" ;
31
30
31
+
32
32
namespace nbl ::asset::impl
33
33
{
34
- struct DXC
35
- {
36
- ComPtr<IDxcUtils> m_dxcUtils;
37
- ComPtr<IDxcCompiler3> m_dxcCompiler;
38
- };
39
-
40
-
41
- // for including builtins
42
- struct load_file_or_builtin_to_string
43
- {
44
- template <typename IterContextT>
45
- class inner
46
- {
47
- public:
48
- template <typename PositionT>
49
- static void init_iterators (IterContextT& iter_ctx, PositionT const & act_pos, boost::wave::language_support language)
50
- {
51
- using iterator_type = typename IterContextT::iterator_type;
52
-
53
- std::string filepath (iter_ctx.filename .begin (), iter_ctx.filename .end ());
54
- auto inclFinder = iter_ctx.ctx .get_hooks ().m_includeFinder ;
55
- if (inclFinder)
56
- {
57
- std::optional<std::string> result;
58
- system::path requestingSourceDir (iter_ctx.ctx .get_current_directory ().string ());
59
- if (iter_ctx.type == IterContextT::base_type::file_type::system_header) // is it a sys include (#include <...>)?
60
- result = inclFinder->getIncludeStandard (requestingSourceDir, filepath);
61
- else // regular #include "..."
62
- result = inclFinder->getIncludeRelative (requestingSourceDir, filepath);
63
-
64
- if (!result)
65
- BOOST_WAVE_THROW_CTX (iter_ctx.ctx , boost::wave::preprocess_exception,
66
- bad_include_file, iter_ctx.filename .c_str (), act_pos);
67
- auto & res_str = *result;
68
- iter_ctx.instring = res_str;
69
- }
70
- iter_ctx.first = iterator_type (
71
- iter_ctx.instring .begin (), iter_ctx.instring .end (),
72
- PositionT (iter_ctx.filename ), language);
73
- iter_ctx.last = iterator_type ();
74
- }
75
-
76
- private:
77
- std::string instring;
78
- };
79
- };
80
-
81
-
82
- struct custom_preprocessing_hooks : public boost ::wave::context_policies::default_preprocessing_hooks
83
- {
84
-
85
- custom_preprocessing_hooks (const IShaderCompiler::SPreprocessorOptions& _preprocessOptions)
86
- : m_includeFinder(_preprocessOptions.includeFinder), m_logger(_preprocessOptions.logger), m_pragmaStage(IShader::ESS_UNKNOWN) {}
87
-
88
- const IShaderCompiler::CIncludeFinder* m_includeFinder;
89
- system::logger_opt_ptr m_logger;
90
- IShader::E_SHADER_STAGE m_pragmaStage;
91
-
92
-
93
- template <typename ContextT>
94
- bool locate_include_file (ContextT& ctx, std::string& file_path, bool is_system, char const * current_name, std::string& dir_path, std::string& native_name)
95
- {
96
- // on builtin return true
97
- dir_path = ctx.get_current_directory ().string ();
98
- std::optional<std::string> result;
99
- if (is_system) {
100
- result = m_includeFinder->getIncludeStandard (dir_path, file_path);
101
- dir_path = " " ;
102
- }
103
- else
104
- result = m_includeFinder->getIncludeRelative (dir_path, file_path);
105
- if (!result)
106
- {
107
- m_logger.log (" Pre-processor error: Bad include file.\n '%s' does not exist." , nbl::system::ILogger::ELL_ERROR, file_path.c_str ());
108
- return false ;
109
- }
110
- native_name = file_path;
111
- return true ;
112
- }
113
-
114
-
115
- // interpretation of #pragma's of the form 'wave option[(value)]'
116
- template <typename ContextT, typename ContainerT>
117
- bool
118
- interpret_pragma (ContextT const & ctx, ContainerT& pending,
119
- typename ContextT::token_type const & option, ContainerT const & values,
120
- typename ContextT::token_type const & act_token)
121
- {
122
- auto optionStr = option.get_value ().c_str ();
123
- if (strcmp (optionStr, " shader_stage" ) == 0 )
124
- {
125
- auto valueIter = values.begin ();
126
- if (valueIter == values.end ()) {
127
- m_logger.log (" Pre-processor error:\n Malformed shader_stage pragma. No shaderstage option given" , nbl::system::ILogger::ELL_ERROR);
128
- return false ;
129
- }
130
- auto shaderStageIdentifier = std::string (valueIter->get_value ().c_str ());
131
- core::unordered_map<std::string, IShader::E_SHADER_STAGE> stageFromIdent = {
132
- { " vertex" , IShader::ESS_VERTEX },
133
- { " fragment" , IShader::ESS_FRAGMENT },
134
- { " tesscontrol" , IShader::ESS_TESSELLATION_CONTROL },
135
- { " tesseval" , IShader::ESS_TESSELLATION_EVALUATION },
136
- { " geometry" , IShader::ESS_GEOMETRY },
137
- { " compute" , IShader::ESS_COMPUTE }
138
- };
139
- auto found = stageFromIdent.find (shaderStageIdentifier);
140
- if (found == stageFromIdent.end ())
141
- {
142
- m_logger.log (" Pre-processor error:\n Malformed shader_stage pragma. Unknown stage '%s'" , nbl::system::ILogger::ELL_ERROR, shaderStageIdentifier);
143
- return false ;
144
- }
145
- valueIter++;
146
- if (valueIter != values.end ()) {
147
- m_logger.log (" Pre-processor error:\n Malformed shader_stage pragma. Too many arguments" , nbl::system::ILogger::ELL_ERROR);
148
- return false ;
149
- }
150
- m_pragmaStage = found->second ;
151
- return true ;
152
- }
153
- return false ;
154
- }
155
-
156
-
157
- template <typename ContextT, typename ContainerT>
158
- bool found_error_directive (ContextT const & ctx, ContainerT const & message) {
159
- m_logger.log (" Pre-processor error:\n %s" , nbl::system::ILogger::ELL_ERROR, message);
160
- return true ;
161
- }
162
-
163
- };
164
-
165
-
34
+ struct DXC
35
+ {
36
+ ComPtr<IDxcUtils> m_dxcUtils;
37
+ ComPtr<IDxcCompiler3> m_dxcCompiler;
38
+ };
166
39
}
167
40
168
41
CHLSLCompiler::CHLSLCompiler (core::smart_refctd_ptr<system::ISystem>&& system)
@@ -182,15 +55,14 @@ CHLSLCompiler::CHLSLCompiler(core::smart_refctd_ptr<system::ISystem>&& system)
182
55
};
183
56
}
184
57
185
-
186
58
CHLSLCompiler::~CHLSLCompiler ()
187
59
{
188
60
delete m_dxcCompilerTypes;
189
61
}
190
62
191
- class DxcCompilationResult
63
+
64
+ struct DxcCompilationResult
192
65
{
193
- public:
194
66
ComPtr<IDxcBlobEncoding> errorMessages;
195
67
ComPtr<IDxcBlob> objectBlob;
196
68
ComPtr<IDxcResult> compileResult;
@@ -201,7 +73,6 @@ class DxcCompilationResult
201
73
}
202
74
};
203
75
204
-
205
76
DxcCompilationResult dxcCompile (const CHLSLCompiler* compiler, nbl::asset::impl::DXC* dxc, std::string& source, LPCWSTR* args, uint32_t argCount, const CHLSLCompiler::SOptions& options)
206
77
{
207
78
// Append Commandline options into source only if debugInfoFlags will emit source
@@ -276,13 +147,12 @@ DxcCompilationResult dxcCompile(const CHLSLCompiler* compiler, nbl::asset::impl:
276
147
}
277
148
278
149
279
- using lex_token_t = boost::wave::cpplexer::lex_token<>;
280
- using lex_iterator_t = boost::wave::cpplexer::lex_iterator<lex_token_t >;
150
+ #include " nbl/asset/utils/waveContext.h"
281
151
using wave_context_t = nbl::wave::context<std::string::iterator>;
282
152
283
153
std::string CHLSLCompiler::preprocessShader (std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const
284
154
{
285
- impl ::custom_preprocessing_hooks hooks (preprocessOptions);
155
+ wave ::custom_preprocessing_hooks hooks (preprocessOptions);
286
156
wave_context_t context (code.begin (), code.end (), preprocessOptions.sourceIdentifier .data (), hooks);
287
157
auto language = boost::wave::support_cpp20 | boost::wave::support_option_preserve_comments | boost::wave::support_option_emit_line_directives;
288
158
context.set_language (static_cast <boost::wave::language_support>(language));
@@ -297,9 +167,8 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
297
167
298
168
// preprocess
299
169
std::stringstream stream = std::stringstream ();
300
- for (auto i = context.begin (); i != context.end (); i++) {
170
+ for (auto i= context.begin (); i!= context.end (); i++)
301
171
stream << i->get_value ();
302
- }
303
172
core::string resolvedString = stream.str ();
304
173
305
174
// for debugging cause MSVC doesn't like to show more than 21k LoC in TextVisualizer
@@ -314,8 +183,10 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
314
183
succ.getBytesProcessed (true );
315
184
}
316
185
}
186
+
317
187
if (context.get_hooks ().m_pragmaStage != IShader::ESS_UNKNOWN)
318
188
stage = context.get_hooks ().m_pragmaStage ;
189
+
319
190
return resolvedString;
320
191
}
321
192
@@ -442,84 +313,4 @@ void CHLSLCompiler::insertIntoStart(std::string& code, std::ostringstream&& ins)
442
313
{
443
314
code.insert (0u , ins.str ());
444
315
}
445
-
446
-
447
-
448
-
449
- template <> inline bool boost::wave::impl::pp_iterator_functor<wave_context_t >::on_include_helper(char const * f, char const * s,
450
- bool is_system, bool include_next)
451
- {
452
- namespace fs = boost::filesystem;
453
-
454
- // try to locate the given file, searching through the include path lists
455
- std::string file_path (s);
456
- std::string dir_path;
457
- #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
458
- char const * current_name = include_next ? iter_ctx->real_filename .c_str () : 0 ;
459
- #else
460
- char const * current_name = 0 ; // never try to match current file name
461
- #endif
462
-
463
- // call the 'found_include_directive' hook function
464
- if (ctx.get_hooks ().found_include_directive (ctx.derived (), f, include_next))
465
- return true ; // client returned false: skip file to include
466
-
467
- file_path = util::impl::unescape_lit (file_path);
468
- std::string native_path_str;
469
-
470
- if (!ctx.get_hooks ().locate_include_file (ctx, file_path, is_system,
471
- current_name, dir_path, native_path_str))
472
- {
473
- BOOST_WAVE_THROW_CTX (ctx, preprocess_exception, bad_include_file,
474
- file_path.c_str (), act_pos);
475
- return false ;
476
- }
477
-
478
- // test, if this file is known through a #pragma once directive
479
- #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
480
- if (!ctx.has_pragma_once (native_path_str))
481
- #endif
482
- {
483
- // the new include file determines the actual current directory
484
- ctx.set_current_directory (native_path_str.c_str ());
485
-
486
- // preprocess the opened file
487
- boost::shared_ptr<base_iteration_context_type> new_iter_ctx (
488
- new iteration_context_type (ctx, native_path_str.c_str (), act_pos,
489
- boost::wave::enable_prefer_pp_numbers (ctx.get_language ()),
490
- is_system ? base_iteration_context_type::system_header :
491
- base_iteration_context_type::user_header));
492
-
493
- // call the include policy trace function
494
- ctx.get_hooks ().opened_include_file (ctx.derived (), dir_path, file_path,
495
- is_system);
496
-
497
- // store current file position
498
- iter_ctx->real_relative_filename = ctx.get_current_relative_filename ().c_str ();
499
- iter_ctx->filename = act_pos.get_file ();
500
- iter_ctx->line = act_pos.get_line ();
501
- iter_ctx->if_block_depth = ctx.get_if_block_depth ();
502
- iter_ctx->emitted_lines = (unsigned int )(-1 ); // force #line directive
503
-
504
- // push the old iteration context onto the stack and continue with the new
505
- ctx.push_iteration_context (act_pos, iter_ctx);
506
- iter_ctx = new_iter_ctx;
507
- seen_newline = true ; // fake a newline to trigger pp_directive
508
- must_emit_line_directive = true ;
509
-
510
- act_pos.set_file (iter_ctx->filename ); // initialize file position
511
- #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
512
- fs::path rfp (iter_ctx->real_filename .c_str ());
513
- std::string real_filename (rfp.string ());
514
- ctx.set_current_filename (real_filename.c_str ());
515
- #endif
516
-
517
- ctx.set_current_relative_filename (dir_path.c_str ());
518
- iter_ctx->real_relative_filename = dir_path.c_str ();
519
-
520
- act_pos.set_line (iter_ctx->line );
521
- act_pos.set_column (0 );
522
- }
523
- return true ;
524
- }
525
- #endif
316
+ #endif
0 commit comments