Skip to content

Commit 620345f

Browse files
committed
updated chlslcompiler.cpp
1 parent c8d9952 commit 620345f

File tree

2 files changed

+97
-90
lines changed

2 files changed

+97
-90
lines changed

src/nbl/asset/utils/CHLSLCompiler.cpp

Lines changed: 95 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -95,109 +95,118 @@ CHLSLCompiler::~CHLSLCompiler()
9595
static void try_upgrade_hlsl_version(std::vector<std::wstring>& arguments, system::logger_opt_ptr& logger)
9696
{
9797
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;
103116
}
104-
else {
117+
else
118+
{
105119
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);
106120
arguments.push_back(L"-HV");
107121
arguments.push_back(L"202x");
108122
}
109123
}
110124

111-
112125
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;
116128
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'.\nThis 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];
121141
if (s.length() >= 6) {
122-
std::wstring stageStr, majorVersionString, minorVersionString;
123142
std::vector<std::wstring::iterator> underscorePositions = {};
124143
auto it = std::find(s.begin(), s.end(), '_');
125144
while (it != s.end()) {
126145
underscorePositions.push_back(it);
127146
it = std::find(it + 1, s.end(), '_');
128147
}
129148

130-
// Bad input check
131-
if (underscorePositions.size() < 2)
132-
{
133-
logger.log("Incorrect -T argument value.\nExpecting 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'.\nThis 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+
}
145174
return;
146175
}
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)
161177
{
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());
165179
}
166-
else
180+
catch (const std::out_of_range& e)
167181
{
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());
170183
}
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-
176184
}
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.\nExpecting string with exactly 2 '_' delimiters: between shader stage, version major and version minor.",
188+
system::ILogger::ELL_ERROR);
179189
}
180-
181-
// In case of an exception
182-
arguments[foundShaderStageArgumentValueIdx] = stageStr + L"_" + std::to_wstring(MajorReqVersion) + L"_" + std::to_wstring(MinorReqVersion);
183-
return;
184190
}
185-
else {
191+
else
192+
{
186193
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
190202
// push back default values for -T argument
191203
// can be safely pushed to the back of argument list as output files should be evicted from args before passing to this func
192204
// leaving only compiler flags
193205
arguments.push_back(L"-T");
194206
arguments.push_back(std::wstring(overrideStageStr) + L"_" + std::to_wstring(MajorReqVersion) + L"_" + std::to_wstring(MinorReqVersion));
195207
}
196-
197-
198208
}
199209

200-
201210
static void add_required_arguments_if_not_present(std::vector<std::wstring>& arguments, system::logger_opt_ptr &logger) {
202211
auto set = std::unordered_set<std::wstring>();
203212
for (int i = 0; i < arguments.size(); i++)
@@ -384,19 +393,7 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
384393
populate_arguments_with_type_conversion(arguments, hlslOptions.dxcOptions, logger);
385394
}
386395
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 = {};
400397
for (size_t i = 0; i < RequiredArgumentCount; i++)
401398
arguments.push_back(RequiredArguments[i]);
402399
// 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
406403
// optimization levels greater than zero; they will all invoke the same optimization recipe.
407404
// https://github.com/Microsoft/DirectXShaderCompiler/blob/main/docs/SPIR-V.rst#optimization
408405
if (hlslOptions.spirvOptimizer)
409-
{
410406
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+
};
413419
// Debug only values
414420
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");
416422
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");
418424
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");
420426
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");
422428
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");
424430
}
425431

426432
try_upgrade_shader_stage(arguments, stage, logger);

tools/nsc/main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class ShaderCompiler final : public system::IApplicationFramework
117117
{
118118
output_filepath = outputFlagVector[1];
119119
}
120-
m_arguments.erase(output_flag_pos, output_flag_pos+1);
120+
m_arguments.erase(output_flag_pos, output_flag_pos+2);
121121

122122
m_logger->log("Compiled shader code will be saved to " + output_filepath);
123123
}
@@ -135,6 +135,7 @@ class ShaderCompiler final : public system::IApplicationFramework
135135
m_arguments.push_back("-E");
136136
m_arguments.push_back("main");
137137
}
138+
138139
auto shader = open_shader_file(file_to_compile);
139140
if (shader->getContentType() != IShader::E_CONTENT_TYPE::ECT_HLSL)
140141
{

0 commit comments

Comments
 (0)