Skip to content

Commit ecb40ce

Browse files
committed
NSC removed duplicate code, added compile options to CHLSLCompiler::SOptions
1 parent eafb1eb commit ecb40ce

File tree

3 files changed

+128
-199
lines changed

3 files changed

+128
-199
lines changed

include/nbl/asset/utils/CHLSLCompiler.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class NBL_API2 CHLSLCompiler final : public IShaderCompiler
3333
struct SOptions : IShaderCompiler::SCompilerOptions
3434
{
3535
// TODO: Add extra dxc options
36+
std::span<const std::string> dxcOptions;
3637
IShader::E_CONTENT_TYPE getCodeContentType() const override { return IShader::E_CONTENT_TYPE::ECT_HLSL; };
3738
};
3839

@@ -55,22 +56,16 @@ class NBL_API2 CHLSLCompiler final : public IShaderCompiler
5556

5657
void insertIntoStart(std::string& code, std::ostringstream&& ins) const override;
5758

58-
struct SdxcCompileResult {
59-
uint8_t *begin;
60-
size_t size;
61-
};
62-
SdxcCompileResult dxcCompile(std::string& source, LPCWSTR* args, uint32_t argCount, const CHLSLCompiler::SOptions& options) const;
63-
protected:
6459

65-
60+
protected:
6661
// This can't be a unique_ptr due to it being an undefined type
6762
// when Nabla is used as a lib
6863
nbl::asset::impl::DXC* m_dxcCompilerTypes;
6964

7065
static CHLSLCompiler::SOptions option_cast(const IShaderCompiler::SCompilerOptions& options)
7166
{
7267
CHLSLCompiler::SOptions ret = {};
73-
if (options.getCodeContentType() == IShader::E_CONTENT_TYPE::ECT_GLSL)
68+
if (options.getCodeContentType() == IShader::E_CONTENT_TYPE::ECT_HLSL)
7469
ret = static_cast<const CHLSLCompiler::SOptions&>(options);
7570
else
7671
ret.setCommonData(options);

src/nbl/asset/utils/CHLSLCompiler.cpp

Lines changed: 103 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,83 @@ CHLSLCompiler::~CHLSLCompiler()
7070
delete m_dxcCompilerTypes;
7171
}
7272

73-
CHLSLCompiler::SdxcCompileResult CHLSLCompiler::dxcCompile(std::string& source, LPCWSTR* args, uint32_t argCount, const CHLSLCompiler::SOptions& options) const
73+
74+
static void try_upgrade_hlsl_version(std::vector<std::wstring>& arguments)
75+
{
76+
auto foundShaderStageArgument = std::find(arguments.begin(), arguments.end(), L"-HV");
77+
if (foundShaderStageArgument != arguments.end()) {
78+
auto foundShaderStageArgumentValueIdx = foundShaderStageArgument - arguments.begin() + 1;
79+
std::wstring version = arguments[foundShaderStageArgumentValueIdx];
80+
if (version.length() >= 4 && (version[2] < '2' || (version[2] == '2' && version[3] <= '0')))
81+
arguments[foundShaderStageArgumentValueIdx] = L"2021";
82+
}
83+
}
84+
85+
86+
static void try_upgrade_shader_stage(std::vector<std::wstring> &arguments) {
87+
auto foundShaderStageArgument = std::find(arguments.begin(), arguments.end(), L"-T");
88+
if (foundShaderStageArgument != arguments.end()) {
89+
auto foundShaderStageArgumentValueIdx = foundShaderStageArgument - arguments.begin() + 1;
90+
std::wstring targetProfile = arguments[foundShaderStageArgumentValueIdx];
91+
if (targetProfile.length() >= 6) {
92+
int argument_version = (targetProfile[3] - '0') * 10 + (targetProfile[5] - '0');
93+
if (argument_version < 67)
94+
{
95+
targetProfile.replace(3, 3, L"6_7");
96+
arguments[foundShaderStageArgumentValueIdx] = targetProfile;
97+
}
98+
}
99+
}
100+
}
101+
102+
103+
static void add_required_arguments_if_not_present(std::vector<std::wstring>& arguments, system::logger_opt_ptr &logger) {
104+
constexpr int required_arg_size = 8;
105+
std::wstring required_arguments[] = {
106+
L"-spirv",
107+
L"-Zpr",
108+
L"-enable-16bit-types",
109+
L"-fvk-use-scalar-layout",
110+
L"-Wno-c++11-extensions",
111+
L"-Wno-c++1z-extensions",
112+
L"-Wno-gnu-static-float-init",
113+
L"-fspv-target-env=vulkan1.3"
114+
};
115+
bool found_arg_flags[required_arg_size]{};
116+
int argc = arguments.size();
117+
for (int i = 0; i < argc; i++)
118+
{
119+
for (int j = 0; j < required_arg_size; j++)
120+
{
121+
if (arguments[i] == required_arguments[j]) {
122+
found_arg_flags[j] = true;
123+
break;
124+
}
125+
}
126+
}
127+
for (int j = 0; j < required_arg_size; j++)
128+
{
129+
if (!found_arg_flags[j]) {
130+
logger.log("Required compile flag not found %ls. This flag will be force enabled as it is required by Nabla.", system::ILogger::ELL_WARNING, required_arguments[j]);
131+
arguments.push_back(required_arguments[j]);
132+
}
133+
}
134+
}
135+
136+
137+
template <typename T>
138+
static void populate_arguments_with_type_conversion(std::vector<std::wstring> &arguments, T &iterable_collection, system::logger_opt_ptr &logger) {
139+
size_t arg_size = iterable_collection.size();
140+
arguments.reserve(arg_size);
141+
for (auto it = iterable_collection.begin(); it != iterable_collection.end(); it++) {
142+
auto temp = std::wstring(it->begin(), it->end()); // *it is string, therefore create wstring
143+
arguments.push_back(temp);
144+
}
145+
add_required_arguments_if_not_present(arguments, logger);
146+
}
147+
148+
149+
static DxcCompilationResult dxcCompile(const CHLSLCompiler* compiler, nbl::asset::impl::DXC* dxc, std::string& source, LPCWSTR* args, uint32_t argCount, const CHLSLCompiler::SOptions& options)
74150
{
75151
// Append Commandline options into source only if debugInfoFlags will emit source
76152
auto sourceEmittingFlags =
@@ -90,9 +166,8 @@ CHLSLCompiler::SdxcCompileResult CHLSLCompiler::dxcCompile(std::string& source,
90166
}
91167

92168
insertion << ")\n";
93-
insertIntoStart(source, std::move(insertion));
169+
compiler->insertIntoStart(source, std::move(insertion));
94170
}
95-
nbl::asset::impl::DXC* dxc = m_dxcCompilerTypes;
96171
ComPtr<IDxcBlobEncoding> src;
97172
auto res = dxc->m_dxcUtils->CreateBlob(reinterpret_cast<const void*>(source.data()), source.size(), CP_UTF8, &src);
98173
assert(SUCCEEDED(res));
@@ -131,7 +206,7 @@ CHLSLCompiler::SdxcCompileResult CHLSLCompiler::dxcCompile(std::string& source,
131206
else
132207
{
133208
options.preprocessorOptions.logger.log("DXC Compilation Failed:\n%s", system::ILogger::ELL_ERROR, errorMessagesString.c_str());
134-
return { nullptr, 0 };
209+
return result;
135210
}
136211

137212
ComPtr<IDxcBlob> resultingBlob;
@@ -140,7 +215,7 @@ CHLSLCompiler::SdxcCompileResult CHLSLCompiler::dxcCompile(std::string& source,
140215

141216
result.objectBlob = resultingBlob;
142217

143-
return { (uint8_t*)result.objectBlob->GetBufferPointer(), result.objectBlob->GetBufferSize() };
218+
return result;
144219
}
145220

146221

@@ -263,21 +338,15 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
263338
hlslOptions.preprocessorOptions.logger.log("invalid shader stage %i", system::ILogger::ELL_ERROR, stage);
264339
return nullptr;
265340
};
266-
267-
std::wstring* arg_storage = NULL;
268-
std::vector<LPCWSTR> arguments;
269-
270-
if (dxc_compile_flags.size()) { // #pragma wave overrides compile flags
271-
size_t arg_size = dxc_compile_flags.size();
272-
arguments = {};
273-
arguments.reserve(arg_size);
274-
arg_storage = new std::wstring[arg_size]; // prevent deallocation before shader compilation
275-
for (size_t i = 0; i < dxc_compile_flags.size(); i++) {
276-
arg_storage[i] = std::wstring(dxc_compile_flags[i].begin(), dxc_compile_flags[i].end());
277-
arguments.push_back(arg_storage[i].c_str());
278-
}
341+
342+
std::vector<std::wstring> arguments = {};
343+
if (dxc_compile_flags.size()) { // #pragma dxc_compile_flags takes priority
344+
populate_arguments_with_type_conversion(arguments, dxc_compile_flags, hlslOptions.preprocessorOptions.logger);
279345
}
280-
else {
346+
else if (hlslOptions.dxcOptions.size()) { // second in order of priority is command line arguments
347+
populate_arguments_with_type_conversion(arguments, hlslOptions.dxcOptions, hlslOptions.preprocessorOptions.logger);
348+
}
349+
else { //lastly default arguments
281350
arguments = {
282351
L"-spirv",
283352
L"-HV", L"202x",
@@ -314,29 +383,35 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
314383
arguments.push_back(L"-fspv-debug=vulkan-with-source");
315384
}
316385

386+
try_upgrade_shader_stage(arguments);
387+
try_upgrade_hlsl_version(arguments);
388+
389+
uint32_t argc = arguments.size();
390+
LPCWSTR* argsArray = new LPCWSTR[argc];
391+
for (size_t i = 0; i < argc; i++)
392+
argsArray[i] = arguments[i].c_str();
393+
317394
auto compileResult = dxcCompile(
395+
this,
396+
m_dxcCompilerTypes,
318397
newCode,
319-
arguments.data(),
320-
arguments.size(),
398+
argsArray,
399+
argc,
321400
hlslOptions
322401
);
323402

324-
if (arg_storage)
325-
delete[] arg_storage;
326-
327-
if (!compileResult.begin)
403+
if (!compileResult.objectBlob)
328404
{
329405
return nullptr;
330406
}
331407

332-
auto outSpirv = core::make_smart_refctd_ptr<ICPUBuffer>(compileResult.size);
333-
memcpy(outSpirv->getPointer(), compileResult.begin, compileResult.size);
408+
auto outSpirv = core::make_smart_refctd_ptr<ICPUBuffer>(compileResult.objectBlob->GetBufferSize());
409+
memcpy(outSpirv->getPointer(), compileResult.objectBlob->GetBufferPointer(), compileResult.objectBlob->GetBufferSize());
334410

335411
// Optimizer step
336412
if (hlslOptions.spirvOptimizer)
337413
outSpirv = hlslOptions.spirvOptimizer->optimize(outSpirv.get(), hlslOptions.preprocessorOptions.logger);
338414

339-
340415
return core::make_smart_refctd_ptr<asset::ICPUShader>(std::move(outSpirv), stage, IShader::E_CONTENT_TYPE::ECT_SPIRV, hlslOptions.preprocessorOptions.sourceIdentifier.data());
341416
}
342417

0 commit comments

Comments
 (0)