Skip to content

Commit 63c6590

Browse files
committed
added loading shader code using asset manager, guessing stader stage by extension, alternative arg parsing using std::find
1 parent e751d08 commit 63c6590

File tree

2 files changed

+59
-68
lines changed

2 files changed

+59
-68
lines changed

src/nbl/asset/utils/CHLSLCompiler.cpp

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,10 @@ static void populate_arguments_with_type_conversion(std::vector<std::wstring> &a
166166

167167
static DxcCompilationResult dxcCompile(const CHLSLCompiler* compiler, nbl::asset::impl::DXC* dxc, std::string& source, LPCWSTR* args, uint32_t argCount, const CHLSLCompiler::SOptions& options)
168168
{
169-
// Append Commandline options into source only if debugInfoFlags will emit source
170-
auto sourceEmittingFlags =
171-
CHLSLCompiler::E_DEBUG_INFO_FLAGS::EDIF_SOURCE_BIT |
172-
CHLSLCompiler::E_DEBUG_INFO_FLAGS::EDIF_LINE_BIT |
173-
CHLSLCompiler::E_DEBUG_INFO_FLAGS::EDIF_NON_SEMANTIC_BIT;
174-
if ((options.debugInfoFlags.value & sourceEmittingFlags) != CHLSLCompiler::E_DEBUG_INFO_FLAGS::EDIF_NONE)
169+
// Emit compile flags as a #pragma directive
170+
// "#pragma wave dxc_compile_flags allows" intended use is to be able to recompile a shader with the same* flags as initial compilation
171+
// mainly meant to be used while debugging in RenderDoc.
172+
// * (except "-no-nbl-builtins")
175173
{
176174
std::ostringstream insertion;
177175
insertion << "#pragma wave dxc_compile_flags( ";
@@ -303,50 +301,32 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
303301
core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* code, const IShaderCompiler::SCompilerOptions& options) const
304302
{
305303
auto hlslOptions = option_cast(options);
306-
304+
auto logger = hlslOptions.preprocessorOptions.logger;
307305
if (!code)
308306
{
309-
hlslOptions.preprocessorOptions.logger.log("code is nullptr", system::ILogger::ELL_ERROR);
307+
logger.log("code is nullptr", system::ILogger::ELL_ERROR);
310308
return nullptr;
311309
}
312310
std::vector<std::string> dxc_compile_flags = {};
313-
IShader::E_SHADER_STAGE stageOverrideFromPragma = IShader::ESS_UNKNOWN;
314-
auto newCode = preprocessShader(code, stageOverrideFromPragma, hlslOptions.preprocessorOptions, dxc_compile_flags);
311+
IShader::E_SHADER_STAGE stage = options.stage;
312+
auto newCode = preprocessShader(code, stage, hlslOptions.preprocessorOptions, dxc_compile_flags);
315313

316314
// Suffix is the shader model version
317-
// TODO: Figure out a way to get the shader model version automatically
318-
//
319-
// We can't get it from the DXC library itself, as the different versions and the parsing
320-
// use a weird lexer based system that resolves to a hash, and all of that is in a scoped variable
321-
// (lib/DXIL/DxilShaderModel.cpp:83)
322-
//
323-
// Another option is trying to fetch it from the commandline tool, either from parsing the help message
324-
// or from brute forcing every -T option until one isn't accepted
325-
//
326315
std::wstring targetProfile(SHADER_MODEL_PROFILE);
327-
IShader::E_SHADER_STAGE stage = options.stage;
328-
if (stageOverrideFromPragma != IShader::ESS_UNKNOWN)
329-
{
330-
// Shader Stage was overriden using #pragma
331-
// #pragma wave shaderStage overrides all other definitions of shader stage, such as
332-
// -T argument (passed here as options.stage)
333-
// shader stage inferred from file extension in asset namespace
334-
stage = stageOverrideFromPragma;
335-
}
336316

337317
std::vector<std::wstring> arguments = {};
338318
if (dxc_compile_flags.size() || hlslOptions.dxcOptions.size()) { // #pragma dxc_compile_flags takes priority
339-
populate_arguments_with_type_conversion(arguments, dxc_compile_flags, hlslOptions.preprocessorOptions.logger);
319+
populate_arguments_with_type_conversion(arguments, dxc_compile_flags, logger);
340320
}
341321
else if (hlslOptions.dxcOptions.size()) { // second in order of priority is command line arguments
342-
populate_arguments_with_type_conversion(arguments, hlslOptions.dxcOptions, hlslOptions.preprocessorOptions.logger);
322+
populate_arguments_with_type_conversion(arguments, hlslOptions.dxcOptions, logger);
343323
}
344324
else { // lastly default arguments
345325

346326
// Set profile two letter prefix based on stage
347327
auto stageStr = ShaderStageToString(stage);
348328
if (!stageStr) {
349-
hlslOptions.preprocessorOptions.logger.log("invalid shader stage %i", system::ILogger::ELL_ERROR, stage);
329+
logger.log("invalid shader stage %i", system::ILogger::ELL_ERROR, stage);
350330
return nullptr;
351331
}
352332
targetProfile.replace(0, 2, stageStr);
@@ -381,8 +361,8 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
381361
arguments.push_back(L"-fspv-debug=vulkan-with-source");
382362
}
383363

384-
try_upgrade_shader_stage(arguments, stageOverrideFromPragma);
385-
try_upgrade_hlsl_version(arguments);
364+
try_upgrade_shader_stage(arguments, stage, logger);
365+
try_upgrade_hlsl_version(arguments, logger);
386366

387367
uint32_t argc = arguments.size();
388368
LPCWSTR* argsArray = new LPCWSTR[argc];
@@ -408,7 +388,7 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
408388

409389
// Optimizer step
410390
if (hlslOptions.spirvOptimizer)
411-
outSpirv = hlslOptions.spirvOptimizer->optimize(outSpirv.get(), hlslOptions.preprocessorOptions.logger);
391+
outSpirv = hlslOptions.spirvOptimizer->optimize(outSpirv.get(), logger);
412392

413393
return core::make_smart_refctd_ptr<asset::ICPUShader>(std::move(outSpirv), stage, IShader::E_CONTENT_TYPE::ECT_SPIRV, hlslOptions.preprocessorOptions.sourceIdentifier.data());
414394
}

tools/nsc/main.cpp

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -51,33 +51,26 @@ class ShaderCompiler final : public system::IApplicationFramework
5151
return false;
5252
}
5353
std::string output_filepath = "";
54-
for (auto i = 1; i < m_arguments.size(); i++)
55-
{
56-
if (m_arguments[i] == "-no-nbl-builtins")
57-
{
58-
// unmount builtins
59-
m_logger->log("Unmounting builtins.");
60-
m_system->unmountBuiltins();
61-
no_nbl_builtins = true;
62-
m_arguments.erase(m_arguments.begin() + i - 1);
63-
i--;
54+
55+
56+
auto builtin_flag_pos = std::find(m_arguments.begin(), m_arguments.end(), "-no-nbl-builtins");
57+
if (builtin_flag_pos != m_arguments.end()) {
58+
m_logger->log("Unmounting builtins.");
59+
m_system->unmountBuiltins();
60+
no_nbl_builtins = true;
61+
m_arguments.erase(builtin_flag_pos);
62+
}
63+
64+
auto output_flag_pos = std::find(m_arguments.begin(), m_arguments.end(), "-Fo");
65+
if (output_flag_pos != m_arguments.end()) {
66+
if (output_flag_pos + 1 != m_arguments.end()) {
67+
output_filepath = *output_flag_pos;
68+
m_logger->log("Compiled shader code will be saved to " + output_filepath);
69+
m_arguments.erase(output_flag_pos, output_flag_pos+1);
6470
}
65-
else if (m_arguments[i] == "-Fo")
66-
{
67-
// get filepath to save output to
68-
if (i + 1 < argc)
69-
{
70-
output_filepath = argv[i + 1];
71-
m_logger->log("Compiled shader code will be saved to " + output_filepath);
72-
m_arguments.erase(m_arguments.begin() + i, m_arguments.begin() + i + 1);
73-
i--;
74-
}
75-
else
76-
{
77-
m_logger->log("Incorrect arguments. Expecting filename after -Fo.", ILogger::ELL_ERROR);
78-
}
71+
else {
72+
m_logger->log("Incorrect arguments. Expecting filename after -Fo.", ILogger::ELL_ERROR);
7973
}
80-
8174
}
8275

8376
#ifndef NBL_EMBED_BUILTIN_RESOURCES
@@ -87,7 +80,9 @@ class ShaderCompiler final : public system::IApplicationFramework
8780
m_logger->log("nsc.exe was compiled with builtin resources disabled. Force enabling -no-nbl-builtins.", ILogger::ELL_WARNING);
8881
}
8982
#endif
90-
string shader_code = open_shader_file(file_to_compile);
83+
84+
//TODO unfuck this
85+
const ICPUShader* shader_code = open_shader_file(file_to_compile);
9186
auto compilation_result = compile_shader(shader_code, file_to_compile);
9287

9388
// writie compiled shader to file as bytes
@@ -110,38 +105,54 @@ class ShaderCompiler final : public system::IApplicationFramework
110105

111106
private:
112107

113-
core::smart_refctd_ptr<ICPUShader> compile_shader(std::string& shader_code, std::string_view sourceIdentifier) {
108+
core::smart_refctd_ptr<ICPUShader> compile_shader(const ICPUShader* shader_code, std::string_view sourceIdentifier) {
114109
constexpr uint32_t WorkgroupSize = 256;
115110
constexpr uint32_t WorkgroupCount = 2048;
116111
const string WorkgroupSizeAsStr = std::to_string(WorkgroupSize);
117112

118113
smart_refctd_ptr<CHLSLCompiler> hlslcompiler = make_smart_refctd_ptr<CHLSLCompiler>(smart_refctd_ptr(m_system));
119114

120115
CHLSLCompiler::SOptions options = {};
121-
options.stage = asset::IShader::E_SHADER_STAGE::ESS_UNKNOWN;
116+
options.stage = shader_code->getStage();
122117
//options.debugInfoFlags = IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_LINE_BIT;
123118
options.preprocessorOptions.sourceIdentifier = sourceIdentifier;
124119
options.preprocessorOptions.logger = m_logger.get();
125120
options.dxcOptions = std::span<std::string>(m_arguments);
126121
auto includeFinder = make_smart_refctd_ptr<IShaderCompiler::CIncludeFinder>(smart_refctd_ptr(m_system));
127122
options.preprocessorOptions.includeFinder = includeFinder.get();
128123

129-
return hlslcompiler->compileToSPIRV(shader_code.c_str(), options);
124+
return hlslcompiler->compileToSPIRV((const char*)shader_code->getContent()->getPointer(), options);
130125
}
131126

132127

133-
std::string open_shader_file(std::string& filepath) {
134-
std::ifstream stream(filepath);
135-
std::string str((std::istreambuf_iterator<char>(stream)),
136-
std::istreambuf_iterator<char>());
137-
return str;
128+
const ICPUShader* open_shader_file(std::string& filepath) {
129+
130+
m_assetMgr = make_smart_refctd_ptr<asset::IAssetManager>(smart_refctd_ptr(m_system));
131+
auto resourceArchive = make_smart_refctd_ptr<system::CMountDirectoryArchive>(localInputCWD, smart_refctd_ptr(m_logger), m_system.get());
132+
m_system->mount(std::move(resourceArchive));
133+
134+
IAssetLoader::SAssetLoadParams lp = {};
135+
lp.logger = m_logger.get();
136+
lp.workingDirectory = "";
137+
auto assetBundle = m_assetMgr->getAsset(filepath, lp);
138+
const auto assets = assetBundle.getContents();
139+
if (assets.empty()) {
140+
m_logger->log("Could not load shader %s", ILogger::ELL_ERROR, filepath);
141+
return false;
142+
}
143+
assert(assets.size() == 1);
144+
smart_refctd_ptr<ICPUSpecializedShader> source = IAsset::castDown<ICPUSpecializedShader>(assets[0]);
145+
146+
return source->getUnspecialized();
138147
}
139148

140149

141150
bool no_nbl_builtins{ false };
142151
smart_refctd_ptr<ISystem> m_system;
143152
smart_refctd_ptr<CStdoutLogger> m_logger;
144153
std::vector<std::string> m_arguments;
154+
core::smart_refctd_ptr<asset::IAssetManager> m_assetMgr;
155+
145156

146157
};
147158

0 commit comments

Comments
 (0)