Skip to content

Commit 2d87fb6

Browse files
authored
Merge branch 'Devsh-Graphics-Programming:master' into master
2 parents 64cbb65 + ffbd843 commit 2d87fb6

File tree

11 files changed

+200
-34
lines changed

11 files changed

+200
-34
lines changed

CMakeLists.txt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,8 @@ add_subdirectory(${THIRD_PARTY_SOURCE_DIR})
352352

353353
add_subdirectory(src/nbl)
354354
add_subdirectory("${NBL_PYTHON_MODULE_ROOT_PATH}" tests) # Python Framework
355-
356-
if(NBL_BUILD_EXAMPLES)
357-
add_subdirectory(examples_tests)
358-
endif()
355+
add_subdirectory(examples_tests)
356+
add_subdirectory(tools)
359357

360358
if(NBL_BUILD_DOCS)
361359
add_subdirectory(docs)

include/nbl/asset/utils/CHLSLCompiler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ class NBL_API2 CHLSLCompiler final : public IShaderCompiler
4747
//}
4848

4949
std::string preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const override;
50-
50+
std::string preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, std::vector<std::string>& dxc_compile_flags_override, const SPreprocessorOptions& preprocessOptions) const;
51+
5152
void insertIntoStart(std::string& code, std::ostringstream&& ins) const override;
5253
protected:
5354

src/nbl/asset/utils/CHLSLCompiler.cpp

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ DxcCompilationResult dxcCompile(const CHLSLCompiler* compiler, nbl::asset::impl:
8383
if ((options.debugInfoFlags.value & sourceEmittingFlags) != CHLSLCompiler::E_DEBUG_INFO_FLAGS::EDIF_NONE)
8484
{
8585
std::ostringstream insertion;
86-
insertion << "//#pragma compile_flags ";
86+
insertion << "#pragma compile_flags ";
8787

8888
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> conv;
8989
for (uint32_t arg = 0; arg < argCount; arg ++)
@@ -149,7 +149,8 @@ DxcCompilationResult dxcCompile(const CHLSLCompiler* compiler, nbl::asset::impl:
149149

150150
#include "nbl/asset/utils/waveContext.h"
151151

152-
std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const
152+
153+
std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, std::vector<std::string>& dxc_compile_flags_override, const SPreprocessorOptions& preprocessOptions) const
153154
{
154155
nbl::wave::context context(code.begin(),code.end(),preprocessOptions.sourceIdentifier.data(),{preprocessOptions});
155156
context.add_macro_definition("__HLSL_VERSION");
@@ -192,12 +193,22 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
192193
}
193194
}
194195

196+
if (context.get_hooks().m_dxc_compile_flags_override.size() != 0)
197+
dxc_compile_flags_override = context.get_hooks().m_dxc_compile_flags_override;
198+
195199
if(context.get_hooks().m_pragmaStage != IShader::ESS_UNKNOWN)
196200
stage = context.get_hooks().m_pragmaStage;
197201

202+
203+
198204
return resolvedString;
199205
}
200206

207+
std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const
208+
{
209+
std::vector<std::string> extra_dxc_compile_flags = {};
210+
return preprocessShader(std::move(code), stage, extra_dxc_compile_flags, preprocessOptions);
211+
}
201212

202213
core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* code, const IShaderCompiler::SCompilerOptions& options) const
203214
{
@@ -208,9 +219,9 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
208219
hlslOptions.preprocessorOptions.logger.log("code is nullptr", system::ILogger::ELL_ERROR);
209220
return nullptr;
210221
}
211-
222+
std::vector<std::string> dxc_compile_flags = {};
212223
auto stage = hlslOptions.stage;
213-
auto newCode = preprocessShader(code, stage, hlslOptions.preprocessorOptions);
224+
auto newCode = preprocessShader(code, stage, dxc_compile_flags, hlslOptions.preprocessorOptions);
214225

215226
// Suffix is the shader model version
216227
// TODO: Figure out a way to get the shader model version automatically
@@ -256,7 +267,21 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
256267
return nullptr;
257268
};
258269

259-
std::vector<LPCWSTR> arguments = {
270+
std::wstring* arg_storage = NULL;
271+
std::vector<LPCWSTR> arguments;
272+
273+
if (dxc_compile_flags.size()) { // #pragma wave overrides compile flags
274+
size_t arg_size = dxc_compile_flags.size();
275+
arguments = {};
276+
arguments.reserve(arg_size);
277+
arg_storage = new std::wstring[arg_size]; // prevent deallocation before shader compilation
278+
for (size_t i = 0; i < dxc_compile_flags.size(); i++) {
279+
arg_storage[i] = std::wstring(dxc_compile_flags[i].begin(), dxc_compile_flags[i].end());
280+
arguments.push_back(arg_storage[i].c_str());
281+
}
282+
}
283+
else {
284+
arguments = {
260285
L"-spirv",
261286
L"-HV", L"202x",
262287
L"-T", targetProfile.c_str(),
@@ -267,40 +292,43 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
267292
L"-Wno-c++1z-extensions",
268293
L"-Wno-gnu-static-float-init",
269294
L"-fspv-target-env=vulkan1.3"
270-
};
295+
};
296+
// If a custom SPIR-V optimizer is specified, use that instead of DXC's spirv-opt.
297+
// This is how we can get more optimizer options.
298+
//
299+
// Optimization is also delegated to SPIRV-Tools. Right now there are no difference between
300+
// optimization levels greater than zero; they will all invoke the same optimization recipe.
301+
// https://github.com/Microsoft/DirectXShaderCompiler/blob/main/docs/SPIR-V.rst#optimization
302+
if (hlslOptions.spirvOptimizer)
303+
{
304+
arguments.push_back(L"-O0");
305+
}
271306

272-
// If a custom SPIR-V optimizer is specified, use that instead of DXC's spirv-opt.
273-
// This is how we can get more optimizer options.
274-
//
275-
// Optimization is also delegated to SPIRV-Tools. Right now there are no difference between
276-
// optimization levels greater than zero; they will all invoke the same optimization recipe.
277-
// https://github.com/Microsoft/DirectXShaderCompiler/blob/main/docs/SPIR-V.rst#optimization
278-
if (hlslOptions.spirvOptimizer)
279-
{
280-
arguments.push_back(L"-O0");
307+
// Debug only values
308+
if (hlslOptions.debugInfoFlags.hasFlags(E_DEBUG_INFO_FLAGS::EDIF_FILE_BIT))
309+
arguments.push_back(L"-fspv-debug=file");
310+
if (hlslOptions.debugInfoFlags.hasFlags(E_DEBUG_INFO_FLAGS::EDIF_SOURCE_BIT))
311+
arguments.push_back(L"-fspv-debug=source");
312+
if (hlslOptions.debugInfoFlags.hasFlags(E_DEBUG_INFO_FLAGS::EDIF_LINE_BIT))
313+
arguments.push_back(L"-fspv-debug=line");
314+
if (hlslOptions.debugInfoFlags.hasFlags(E_DEBUG_INFO_FLAGS::EDIF_TOOL_BIT))
315+
arguments.push_back(L"-fspv-debug=tool");
316+
if (hlslOptions.debugInfoFlags.hasFlags(E_DEBUG_INFO_FLAGS::EDIF_NON_SEMANTIC_BIT))
317+
arguments.push_back(L"-fspv-debug=vulkan-with-source");
281318
}
282319

283-
// Debug only values
284-
if (hlslOptions.debugInfoFlags.hasFlags(E_DEBUG_INFO_FLAGS::EDIF_FILE_BIT))
285-
arguments.push_back(L"-fspv-debug=file");
286-
if (hlslOptions.debugInfoFlags.hasFlags(E_DEBUG_INFO_FLAGS::EDIF_SOURCE_BIT))
287-
arguments.push_back(L"-fspv-debug=source");
288-
if (hlslOptions.debugInfoFlags.hasFlags(E_DEBUG_INFO_FLAGS::EDIF_LINE_BIT))
289-
arguments.push_back(L"-fspv-debug=line");
290-
if (hlslOptions.debugInfoFlags.hasFlags(E_DEBUG_INFO_FLAGS::EDIF_TOOL_BIT))
291-
arguments.push_back(L"-fspv-debug=tool");
292-
if (hlslOptions.debugInfoFlags.hasFlags(E_DEBUG_INFO_FLAGS::EDIF_NON_SEMANTIC_BIT))
293-
arguments.push_back(L"-fspv-debug=vulkan-with-source");
294-
295320
auto compileResult = dxcCompile(
296321
this,
297322
m_dxcCompilerTypes,
298323
newCode,
299-
&arguments[0],
324+
arguments.data(),
300325
arguments.size(),
301326
hlslOptions
302327
);
303328

329+
if (arg_storage)
330+
delete[] arg_storage;
331+
304332
if (!compileResult.objectBlob)
305333
{
306334
return nullptr;
@@ -322,4 +350,6 @@ void CHLSLCompiler::insertIntoStart(std::string& code, std::ostringstream&& ins)
322350
{
323351
code.insert(0u, ins.str());
324352
}
353+
354+
325355
#endif

src/nbl/asset/utils/waveContext.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ struct load_to_string final
4747
struct preprocessing_hooks final : public boost::wave::context_policies::default_preprocessing_hooks
4848
{
4949
preprocessing_hooks(const IShaderCompiler::SPreprocessorOptions& _preprocessOptions)
50-
: m_includeFinder(_preprocessOptions.includeFinder), m_logger(_preprocessOptions.logger), m_pragmaStage(IShader::ESS_UNKNOWN) {}
50+
: m_includeFinder(_preprocessOptions.includeFinder), m_logger(_preprocessOptions.logger), m_pragmaStage(IShader::ESS_UNKNOWN), m_dxc_compile_flags_override()
51+
{
52+
hash_token_occurences = 0;
53+
}
5154

5255
template <typename ContextT>
5356
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)
@@ -56,6 +59,7 @@ struct preprocessing_hooks final : public boost::wave::context_policies::default
5659
return false;
5760
}
5861

62+
5963
// interpretation of #pragma's of the form 'wave option[(value)]'
6064
template <typename ContextT, typename ContainerT>
6165
bool interpret_pragma(
@@ -64,6 +68,7 @@ struct preprocessing_hooks final : public boost::wave::context_policies::default
6468
typename ContextT::token_type const& act_token
6569
)
6670
{
71+
hash_token_occurences++;
6772
auto optionStr = option.get_value().c_str();
6873
if (strcmp(optionStr,"shader_stage")==0)
6974
{
@@ -97,6 +102,23 @@ struct preprocessing_hooks final : public boost::wave::context_policies::default
97102
m_pragmaStage = found->second;
98103
return true;
99104
}
105+
106+
if (strcmp(optionStr, "dxc_compile_flags") == 0 && hash_token_occurences == 1) {
107+
m_dxc_compile_flags_override.clear();
108+
for (auto valueIter = values.begin(); valueIter != values.end(); valueIter++) {
109+
std::string compiler_option_s = std::string(valueIter->get_value().c_str());
110+
// if this compiler flag is encapsulated in quotation marks, strip them
111+
//if (compiler_option_s[0] == '"' && compiler_option_s[compiler_option_s.length() - 1] == '"')
112+
// compiler_option_s = compiler_option_s.substr(1, compiler_option_s.length() - 2);
113+
114+
// if the compiler flag is a separator that is a comma or whitespace, do not add to list of flag overrides
115+
if (compiler_option_s == "," || compiler_option_s == " ")
116+
continue;
117+
m_dxc_compile_flags_override.push_back(compiler_option_s);
118+
}
119+
return true;
120+
}
121+
100122
return false;
101123
}
102124

@@ -114,6 +136,9 @@ struct preprocessing_hooks final : public boost::wave::context_policies::default
114136
const IShaderCompiler::CIncludeFinder* m_includeFinder;
115137
system::logger_opt_ptr m_logger;
116138
IShader::E_SHADER_STAGE m_pragmaStage;
139+
int hash_token_occurences;
140+
std::vector<std::string> m_dxc_compile_flags_override;
141+
117142
};
118143

119144
class context : private boost::noncopyable

tools/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(ndt)

tools/ndt/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
set(NBL_EXTRA_SOURCES
2+
# TODO: Cypi list extra sources if you need
3+
)
4+
5+
nbl_create_executable_project("${NBL_EXTRA_SOURCES}" "" "" "" "${NBL_EXECUTABLE_PROJECT_CREATION_PCH_TARGET}")

tools/ndt/__init__.py

Whitespace-only changes.

tools/ndt/config.json.template

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"enableParallelBuild": true,
3+
"threadsPerBuildProcess" : 2,
4+
"isExecuted": true,
5+
"scriptPath": "test/test.py",
6+
"cmake": {
7+
"configurations": [ "Release", "Debug", "RelWithDebInfo" ],
8+
"buildModes": [],
9+
"requiredOptions": []
10+
},
11+
"profiles": [
12+
{
13+
"backend": "vulkan",
14+
"platform": "windows",
15+
"buildModes": [],
16+
"runConfiguration": "Release",
17+
"gpuArchitectures": [],
18+
"inputs": [
19+
"test/config/release.json.template"
20+
]
21+
}
22+
],
23+
"inputs": []
24+
}

tools/ndt/main.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// TODO: Cypi
2+
3+
4+
// nsc input/simple_shader.hlsl -T ps_6_0 -E Main -Fo output/shader.ps
5+
6+
#include "nbl/system/IApplicationFramework.h"
7+
8+
#include <iostream>
9+
#include <cstdlib>
10+
11+
12+
13+
class ShaderCompiler final : public system::IApplicationFramework
14+
{
15+
using base_t = system::IApplicationFramework;
16+
17+
public:
18+
using base_t::base_t;
19+
20+
bool onAppInitialized(smart_refctd_ptr<ISystem>&& system) override
21+
{
22+
if (!base_t::onAppInitialized(std::move(system)))
23+
return false;
24+
25+
auto argc = argv.size();
26+
27+
core::vector<std::string> arguments(argv + 1, argv + argc);
28+
29+
for (auto i=0; i<argc; i++)
30+
{
31+
if (argv[i] == "-no-nbl-builtins")
32+
{
33+
no_nbl_builtins = true;
34+
break;
35+
}
36+
}
37+
38+
std::string command = "dxc.exe";
39+
for (std::string arg : arguments)
40+
{
41+
command.append(" ").append(arg);
42+
}
43+
44+
int execute = std::system(command.c_str());
45+
46+
std::cout << "-no-nbl-builtins - " << no_nbl_builtins;
47+
48+
49+
return true;
50+
}
51+
52+
53+
void workLoopBody() override {}
54+
55+
bool keepRunning() override { return false; }
56+
57+
58+
private:
59+
bool no_nbl_builtins{false};
60+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"dependencies": [],
3+
"data": [
4+
{
5+
"dependencies": [],
6+
"command": [
7+
"${NBL_EXECUTABLE_GEN_EXP_FILEPATH}"
8+
]
9+
}
10+
]
11+
}

0 commit comments

Comments
 (0)