@@ -95,109 +95,118 @@ CHLSLCompiler::~CHLSLCompiler()
95
95
static void try_upgrade_hlsl_version (std::vector<std::wstring>& arguments, system::logger_opt_ptr& logger)
96
96
{
97
97
auto stageArgumentPos = std::find (arguments.begin (), arguments.end (), L" -HV" );
98
- if (stageArgumentPos != arguments.end ()) {
99
- auto index = stageArgumentPos - arguments.begin () + 1 ; // -HV XXXXX, get index of second
100
- std::wstring version = arguments[index];
101
- if (!isalpha (version.back ()) && version.length () >= 4 && std::stoi (version) < 2021 )
102
- arguments[index] = L" 2021" ;
98
+ if (stageArgumentPos != arguments.end () && stageArgumentPos + 1 != arguments.end ())
99
+ {
100
+ std::wstring version = *(++stageArgumentPos);
101
+ if (!isalpha (version.back ()))
102
+ {
103
+ try
104
+ {
105
+ if (version.length () != 4 )
106
+ throw std::invalid_argument (" -HV argument is of incorrect length, expeciting 4. Fallign back to 2021" );
107
+ if (std::stoi (version) < 2021 )
108
+ throw std::invalid_argument (" -HV argument is too low" );
109
+ }
110
+ catch (const std::exception& ex)
111
+ {
112
+ version = L" 2021" ;
113
+ }
114
+ }
115
+ *stageArgumentPos = version;
103
116
}
104
- else {
117
+ else
118
+ {
105
119
logger.log (" Compile flag error: Required compile flag not found -HV. Force enabling -HV 202x, as it is required by Nabla." , system::ILogger::ELL_WARNING);
106
120
arguments.push_back (L" -HV" );
107
121
arguments.push_back (L" 202x" );
108
122
}
109
123
}
110
124
111
-
112
125
static void try_upgrade_shader_stage (std::vector<std::wstring>& arguments, asset::IShader::E_SHADER_STAGE shaderStageOverrideFromPragma, system::logger_opt_ptr& logger) {
113
-
114
- constexpr int MajorReqVersion = 6 ,
115
- MinorReqVersion = 7 ;
126
+
127
+ constexpr int MajorReqVersion = 6 , MinorReqVersion = 7 ;
116
128
auto overrideStageStr = ShaderStageToString (shaderStageOverrideFromPragma);
117
- auto foundShaderStageArgument = std::find (arguments.begin (), arguments.end (), L" -T" );
118
- if (foundShaderStageArgument != arguments.end () && foundShaderStageArgument + 1 != arguments.end ()) {
119
- auto foundShaderStageArgumentValueIdx = foundShaderStageArgument - arguments.begin () + 1 ;
120
- std::wstring s = arguments[foundShaderStageArgumentValueIdx];
129
+ if (shaderStageOverrideFromPragma != IShader::ESS_UNKNOWN && !overrideStageStr)
130
+ {
131
+ logger.log (" Invalid shader stage with int value '%i'.\n This value does not have a known string representation." ,
132
+ system::ILogger::ELL_ERROR, shaderStageOverrideFromPragma);
133
+ return ;
134
+ }
135
+ bool setDefaultValue = true ;
136
+ auto foundShaderStageArgument = std::find (arguments.begin (), arguments.end (), L" -T" );
137
+ if (foundShaderStageArgument != arguments.end () && foundShaderStageArgument +1 != arguments.end ()) {
138
+ auto foundShaderStageArgumentValueIdx = foundShaderStageArgument - arguments.begin () + 1 ;
139
+ std::wstring stageStr;
140
+ std::wstring s = arguments[foundShaderStageArgumentValueIdx];
121
141
if (s.length () >= 6 ) {
122
- std::wstring stageStr, majorVersionString, minorVersionString;
123
142
std::vector<std::wstring::iterator> underscorePositions = {};
124
143
auto it = std::find (s.begin (), s.end (), ' _' );
125
144
while (it != s.end ()) {
126
145
underscorePositions.push_back (it);
127
146
it = std::find (it + 1 , s.end (), ' _' );
128
147
}
129
148
130
- // Bad input check
131
- if (underscorePositions.size () < 2 )
132
- {
133
- logger.log (" Incorrect -T argument value.\n Expecting string with at least 2 '_' delimiters: between shader stage, version major and version minor." ,
134
- system::ILogger::ELL_ERROR);
135
- return ;
136
- }
137
-
138
- // Stage
139
- stageStr = std::wstring (s.begin (), underscorePositions[0 ]);
140
- if (shaderStageOverrideFromPragma != IShader::ESS_UNKNOWN) // replace first 2 characters if shaderStageOverrideFromPragma != Unknown
141
- {
142
- if (!overrideStageStr) {
143
- logger.log (" Invalid shader stage with int value '%i'.\n This value does not have a known string representation." ,
144
- system::ILogger::ELL_ERROR, shaderStageOverrideFromPragma);
149
+ if (underscorePositions.size () == 2 )
150
+ {
151
+ stageStr = shaderStageOverrideFromPragma != IShader::ESS_UNKNOWN ? std::wstring (overrideStageStr) : std::wstring (s.begin (), underscorePositions[0 ]);
152
+ // Version
153
+ std::wstring majorVersionString, minorVersionString;
154
+ int size = underscorePositions.size ();
155
+ auto secondLastUnderscore = underscorePositions[size - 2 ];
156
+ auto lastUnderscore = underscorePositions[size - 1 ];
157
+ majorVersionString = std::wstring (secondLastUnderscore + 1 , lastUnderscore);
158
+ minorVersionString = std::wstring (lastUnderscore + 1 , s.end ());
159
+ try
160
+ {
161
+ int major = std::stoi (majorVersionString);
162
+ int minor = std::stoi (minorVersionString);
163
+ if (major < MajorReqVersion || (major == MajorReqVersion && minor < MinorReqVersion))
164
+ {
165
+ // Overwrite the version
166
+ logger.log (" Upgrading shader stage version number to %i %i" , system::ILogger::ELL_DEBUG, MajorReqVersion, MinorReqVersion);
167
+ arguments[foundShaderStageArgumentValueIdx] = stageStr + L" _" + std::to_wstring (MajorReqVersion) + L" _" + std::to_wstring (MinorReqVersion);
168
+ }
169
+ else
170
+ {
171
+ // keep the version as it was
172
+ arguments[foundShaderStageArgumentValueIdx] = stageStr + L" _" + majorVersionString + L" _" + minorVersionString;
173
+ }
145
174
return ;
146
175
}
147
- stageStr = std::wstring (overrideStageStr);
148
- }
149
-
150
- // Version
151
- int size = underscorePositions.size ();
152
- auto secondLastUnderscore = underscorePositions[size - 2 ];
153
- auto lastUnderscore = underscorePositions[size - 1 ];
154
- majorVersionString = std::wstring (secondLastUnderscore + 1 , lastUnderscore);
155
- minorVersionString = std::wstring (lastUnderscore + 1 , s.end ());
156
- try
157
- {
158
- int major = std::stoi (majorVersionString);
159
- int minor = std::stoi (minorVersionString);
160
- if (major < MajorReqVersion || (major == MajorReqVersion && minor < MinorReqVersion))
176
+ catch (const std::invalid_argument& e)
161
177
{
162
- // Overwrite the version
163
- logger.log (" Upgrading shader stage version number to %i %i" , system::ILogger::ELL_DEBUG, MajorReqVersion, MinorReqVersion);
164
- arguments[foundShaderStageArgumentValueIdx] = stageStr + L" _" + std::to_wstring (MajorReqVersion) + L" _" + std::to_wstring (MinorReqVersion);
178
+ logger.log (" Parsing shader version failed, invalid argument exception: %s" , system::ILogger::ELL_ERROR, e.what ());
165
179
}
166
- else
180
+ catch ( const std::out_of_range& e)
167
181
{
168
- // keep the version as it was
169
- arguments[foundShaderStageArgumentValueIdx] = stageStr + L" _" + majorVersionString + L" _" + minorVersionString;
182
+ logger.log (" Parsing shader version failed, out of range exception: %s" , system::ILogger::ELL_ERROR, e.what ());
170
183
}
171
- return ;
172
- }
173
- catch (const std::invalid_argument& e) {
174
- logger.log (" Parsing shader version failed, invalid argument exception: %s" , system::ILogger::ELL_ERROR, e.what ());
175
-
176
184
}
177
- catch (const std::out_of_range& e) {
178
- logger.log (" Parsing shader version failed, out of range exception: %s" , system::ILogger::ELL_ERROR, e.what ());
185
+ else
186
+ {
187
+ logger.log (" Incorrect -T argument value.\n Expecting string with exactly 2 '_' delimiters: between shader stage, version major and version minor." ,
188
+ system::ILogger::ELL_ERROR);
179
189
}
180
-
181
- // In case of an exception
182
- arguments[foundShaderStageArgumentValueIdx] = stageStr + L" _" + std::to_wstring (MajorReqVersion) + L" _" + std::to_wstring (MinorReqVersion);
183
- return ;
184
190
}
185
- else {
191
+ else
192
+ {
186
193
logger.log (" invalid shader stage '%s' argument, expecting a string of length >= 6 " , system::ILogger::ELL_ERROR, s);
187
- }
188
- }
189
- else if (overrideStageStr) { // in case of no -T
194
+ }
195
+ // In case of an exception or str < 6
196
+ arguments[foundShaderStageArgumentValueIdx] = stageStr + L" _" + std::to_wstring (MajorReqVersion) + L" _" + std::to_wstring (MinorReqVersion);
197
+ setDefaultValue = false ;
198
+ }
199
+ if (setDefaultValue)
200
+ {
201
+ // in case of no -T
190
202
// push back default values for -T argument
191
203
// can be safely pushed to the back of argument list as output files should be evicted from args before passing to this func
192
204
// leaving only compiler flags
193
205
arguments.push_back (L" -T" );
194
206
arguments.push_back (std::wstring (overrideStageStr) + L" _" + std::to_wstring (MajorReqVersion) + L" _" + std::to_wstring (MinorReqVersion));
195
207
}
196
-
197
-
198
208
}
199
209
200
-
201
210
static void add_required_arguments_if_not_present (std::vector<std::wstring>& arguments, system::logger_opt_ptr &logger) {
202
211
auto set = std::unordered_set<std::wstring>();
203
212
for (int i = 0 ; i < arguments.size (); i++)
@@ -384,19 +393,7 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
384
393
populate_arguments_with_type_conversion (arguments, hlslOptions.dxcOptions , logger);
385
394
}
386
395
else { // lastly default arguments
387
-
388
- // Set profile two letter prefix based on stage
389
- auto stageStr = ShaderStageToString (stage);
390
- if (!stageStr) {
391
- logger.log (" invalid shader stage %i" , system::ILogger::ELL_ERROR, stage);
392
- return nullptr ;
393
- }
394
- targetProfile.replace (0 , 2 , stageStr);
395
-
396
- arguments = {
397
- L" -HV" , L" 202x" ,
398
- L" -T" , targetProfile.c_str (),
399
- };
396
+ arguments = {};
400
397
for (size_t i = 0 ; i < RequiredArgumentCount; i++)
401
398
arguments.push_back (RequiredArguments[i]);
402
399
// If a custom SPIR-V optimizer is specified, use that instead of DXC's spirv-opt.
@@ -406,21 +403,30 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
406
403
// optimization levels greater than zero; they will all invoke the same optimization recipe.
407
404
// https://github.com/Microsoft/DirectXShaderCompiler/blob/main/docs/SPIR-V.rst#optimization
408
405
if (hlslOptions.spirvOptimizer )
409
- {
410
406
arguments.push_back (L" -O0" );
411
- }
412
-
407
+ }
408
+ if (dxc_compile_flags.empty ())
409
+ {
410
+ auto set = std::unordered_set<std::wstring>();
411
+ for (int i = 0 ; i < arguments.size (); i++)
412
+ set.insert (arguments[i]);
413
+ auto add_if_missing = [&arguments, &set, logger](std::wstring flag) {
414
+ if (set.find (flag) == set.end ()) {
415
+ logger.log (" Adding debug flag %ls" , nbl::system::ILogger::ELL_DEBUG, flag.c_str ());
416
+ arguments.push_back (flag);
417
+ }
418
+ };
413
419
// Debug only values
414
420
if (hlslOptions.debugInfoFlags .hasFlags (E_DEBUG_INFO_FLAGS::EDIF_FILE_BIT))
415
- arguments. push_back (L" -fspv-debug=file" );
421
+ add_if_missing (L" -fspv-debug=file" );
416
422
if (hlslOptions.debugInfoFlags .hasFlags (E_DEBUG_INFO_FLAGS::EDIF_SOURCE_BIT))
417
- arguments. push_back (L" -fspv-debug=source" );
423
+ add_if_missing (L" -fspv-debug=source" );
418
424
if (hlslOptions.debugInfoFlags .hasFlags (E_DEBUG_INFO_FLAGS::EDIF_LINE_BIT))
419
- arguments. push_back (L" -fspv-debug=line" );
425
+ add_if_missing (L" -fspv-debug=line" );
420
426
if (hlslOptions.debugInfoFlags .hasFlags (E_DEBUG_INFO_FLAGS::EDIF_TOOL_BIT))
421
- arguments. push_back (L" -fspv-debug=tool" );
427
+ add_if_missing (L" -fspv-debug=tool" );
422
428
if (hlslOptions.debugInfoFlags .hasFlags (E_DEBUG_INFO_FLAGS::EDIF_NON_SEMANTIC_BIT))
423
- arguments. push_back (L" -fspv-debug=vulkan-with-source" );
429
+ add_if_missing (L" -fspv-debug=vulkan-with-source" );
424
430
}
425
431
426
432
try_upgrade_shader_stage (arguments, stage, logger);
0 commit comments