Skip to content

Commit 01334a4

Browse files
committed
Use inference of shader stage from #pragma
1 parent fecf44f commit 01334a4

File tree

7 files changed

+78
-34
lines changed

7 files changed

+78
-34
lines changed

include/nbl/asset/utils/CHLSLCompiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class NBL_API2 CHLSLCompiler final : public IShaderCompiler
4242
// return "";
4343
//}
4444

45-
std::string preprocessShader(std::string&& code, IShader::E_SHADER_STAGE stage, const SPreprocessorOptions& preprocessOptions) const override;
45+
std::string preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const override;
4646

4747
protected:
4848

include/nbl/asset/utils/IShaderCompiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
178178
179179
@returns Shader containing logically same High Level code as input but with #include directives resolved.
180180
*/
181-
virtual std::string preprocessShader(std::string&& code, IShader::E_SHADER_STAGE stage, const SPreprocessorOptions& preprocessOptions) const;
181+
virtual std::string preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const;
182182

183183
std::string preprocessShader(system::IFile* sourcefile, IShader::E_SHADER_STAGE stage, const SPreprocessorOptions& preprocessOptions) const;
184184

src/nbl/asset/interchange/CHLSLLoader.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,22 @@ SAssetBundle CHLSLLoader::loadAsset(system::IFile* _file, const IAssetLoader::SA
2828
const auto filename = _file->getFileName();
2929
std::filesystem::path extension = filename.extension();
3030

31-
//core::unordered_map<std::string,IShader::E_SHADER_STAGE> typeFromExt = {
32-
// {".vert",IShader::ESS_VERTEX},
33-
// {".tesc",IShader::ESS_TESSELLATION_CONTROL},
34-
// {".tese",IShader::ESS_TESSELLATION_EVALUATION},
35-
// {".geom",IShader::ESS_GEOMETRY},
36-
// {".frag",IShader::ESS_FRAGMENT},
37-
// {".comp",IShader::ESS_COMPUTE}
38-
// };
39-
//auto found = typeFromExt.find(extension.string());
40-
//if (found == typeFromExt.end())
41-
//{
42-
// _NBL_ALIGNED_FREE(source);
43-
// return {};
44-
//}
45-
46-
auto shader = core::make_smart_refctd_ptr<ICPUShader>(reinterpret_cast<char*>(source), IShader::ESS_COMPUTE, IShader::E_CONTENT_TYPE::ECT_HLSL, filename.string());
31+
core::unordered_map<std::string,IShader::E_SHADER_STAGE> typeFromExt = {
32+
{".vert.hlsl",IShader::ESS_VERTEX},
33+
{".tesc.hlsl",IShader::ESS_TESSELLATION_CONTROL},
34+
{".tese.hlsl",IShader::ESS_TESSELLATION_EVALUATION},
35+
{".geom.hlsl",IShader::ESS_GEOMETRY},
36+
{".frag.hlsl",IShader::ESS_FRAGMENT},
37+
{".comp.hlsl",IShader::ESS_COMPUTE}
38+
};
39+
auto found = typeFromExt.find(extension.string());
40+
auto shaderStage = IShader::ESS_UNKNOWN;
41+
if (found != typeFromExt.end())
42+
{
43+
shaderStage = found->second;
44+
}
45+
46+
auto shader = core::make_smart_refctd_ptr<ICPUShader>(reinterpret_cast<char*>(source), shaderStage, IShader::E_CONTENT_TYPE::ECT_HLSL, filename.string());
4747
_NBL_ALIGNED_FREE(source);
4848

4949
return SAssetBundle(nullptr,{ core::make_smart_refctd_ptr<ICPUSpecializedShader>(std::move(shader),ISpecializedShader::SInfo({},nullptr,"main")) });

src/nbl/asset/utils/CCompilerSet.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,17 @@ core::smart_refctd_ptr<ICPUShader> CCompilerSet::preprocessShader(const ICPUShad
4444
case IShader::E_CONTENT_TYPE::ECT_HLSL:
4545
{
4646
const char* code = reinterpret_cast<const char*>(shader->getContent()->getPointer());
47-
auto resolvedCode = m_HLSLCompiler->preprocessShader(code, shader->getStage(), preprocessOptions);
48-
return core::make_smart_refctd_ptr<ICPUShader>(resolvedCode.c_str(), shader->getStage(), IShader::E_CONTENT_TYPE::ECT_HLSL, std::string(shader->getFilepathHint()));
47+
auto stage = shader->getStage();
48+
auto resolvedCode = m_HLSLCompiler->preprocessShader(code, stage, preprocessOptions);
49+
return core::make_smart_refctd_ptr<ICPUShader>(resolvedCode.c_str(), stage, IShader::E_CONTENT_TYPE::ECT_HLSL, std::string(shader->getFilepathHint()));
4950
}
5051
break;
5152
case IShader::E_CONTENT_TYPE::ECT_GLSL:
5253
{
5354
const char* code = reinterpret_cast<const char*>(shader->getContent()->getPointer());
54-
auto resolvedCode = m_GLSLCompiler->preprocessShader(code, shader->getStage(), preprocessOptions);
55-
return core::make_smart_refctd_ptr<ICPUShader>(resolvedCode.c_str(), shader->getStage(), IShader::E_CONTENT_TYPE::ECT_GLSL, std::string(shader->getFilepathHint()));
55+
auto stage = shader->getStage();
56+
auto resolvedCode = m_GLSLCompiler->preprocessShader(code, stage, preprocessOptions);
57+
return core::make_smart_refctd_ptr<ICPUShader>(resolvedCode.c_str(), stage, IShader::E_CONTENT_TYPE::ECT_GLSL, std::string(shader->getFilepathHint()));
5658
}
5759
break;
5860
default:

src/nbl/asset/utils/CHLSLCompiler.cpp

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,6 @@ static tcpp::IInputStream* getInputStreamInclude(
7474
if (!res_str.size()) {
7575
return nullptr;
7676
}
77-
else {
78-
//employ encloseWithinExtraInclGuards() in order to prevent infinite loop of (not necesarilly direct) self-inclusions while other # directives (incl guards among them) are disabled
79-
IShaderCompiler::disableAllDirectivesExceptIncludes(res_str);
80-
res_str = IShaderCompiler::encloseWithinExtraInclGuards(std::move(res_str), _maxInclCnt, name.string().c_str());
81-
}
8277

8378
return new tcpp::StringInputStream(std::move(res_str));
8479
}
@@ -143,7 +138,7 @@ CHLSLCompiler::DxcCompilationResult CHLSLCompiler::dxcCompile(std::string& sourc
143138
return result;
144139
}
145140

146-
std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADER_STAGE stage, const SPreprocessorOptions& preprocessOptions) const
141+
std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADER_STAGE& stage, const SPreprocessorOptions& preprocessOptions) const
147142
{
148143
if (preprocessOptions.extraDefines.size())
149144
{
@@ -166,6 +161,52 @@ std::string CHLSLCompiler::preprocessShader(std::string&& code, IShader::E_SHADE
166161
}
167162
);
168163

164+
auto pragmaShaderStageCallback = [&](IShader::E_SHADER_STAGE _stage) {
165+
return [&](tcpp::Preprocessor& preprocessor, tcpp::Lexer& lexer, const std::string& text) {
166+
stage = _stage;
167+
return std::string("");
168+
};
169+
};
170+
171+
proc.AddCustomDirectiveHandler(std::string("pragma shader_stage"), [&](tcpp::Preprocessor& preprocessor, tcpp::Lexer& lexer, const std::string& text) {
172+
if (!lexer.HasNextToken()) return std::string("#error Malformed shader_stage pragma");
173+
auto token = lexer.GetNextToken();
174+
if (token.mType != tcpp::E_TOKEN_TYPE::OPEN_BRACKET) return std::string("#error Malformed shader_stage pragma");
175+
176+
if (!lexer.HasNextToken()) return std::string("#error Malformed shader_stage pragma");
177+
token = lexer.GetNextToken();
178+
if (token.mType != tcpp::E_TOKEN_TYPE::IDENTIFIER) return std::string("#error Malformed shader_stage pragma");
179+
180+
auto& shaderStageIdentifier = token.mRawView;
181+
core::unordered_map<std::string, IShader::E_SHADER_STAGE> stageFromIdent = {
182+
{ "vertex", IShader::ESS_VERTEX },
183+
{ "fragment", IShader::ESS_FRAGMENT },
184+
{ "tesscontrol", IShader::ESS_TESSELLATION_CONTROL },
185+
{ "tesseval", IShader::ESS_TESSELLATION_EVALUATION },
186+
{ "geometry", IShader::ESS_GEOMETRY },
187+
{ "compute", IShader::ESS_COMPUTE }
188+
};
189+
190+
auto found = stageFromIdent.find(shaderStageIdentifier);
191+
if (found == stageFromIdent.end())
192+
{
193+
return std::string("#error Malformed shader_stage pragma, unknown stage");
194+
}
195+
stage = found->second;
196+
197+
if (!lexer.HasNextToken()) return std::string("#error Malformed shader_stage pragma");
198+
token = lexer.GetNextToken();
199+
if (token.mType != tcpp::E_TOKEN_TYPE::CLOSE_BRACKET) return std::string("#error Malformed shader_stage pragma");
200+
201+
while (lexer.HasNextToken()) {
202+
auto token = lexer.GetNextToken();
203+
if (token.mType == tcpp::E_TOKEN_TYPE::NEWLINE) break;
204+
if (token.mType != tcpp::E_TOKEN_TYPE::SPACE) return std::string("#error Malformed shader_stage pragma");
205+
}
206+
207+
return std::string("");
208+
});
209+
169210
return proc.Process();
170211
}
171212
else
@@ -184,13 +225,14 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
184225
return nullptr;
185226
}
186227

187-
auto newCode = preprocessShader(code, hlslOptions.stage, hlslOptions.preprocessorOptions);
228+
auto stage = hlslOptions.stage;
229+
auto newCode = preprocessShader(code, stage, hlslOptions.preprocessorOptions);
188230

189231
// Suffix is the shader model version
190232
std::wstring targetProfile(L"XX_6_2");
191233

192234
// Set profile two letter prefix based on stage
193-
switch (options.stage) {
235+
switch (stage) {
194236
case asset::IShader::ESS_VERTEX:
195237
targetProfile.replace(0, 2, L"vs");
196238
break;
@@ -216,7 +258,7 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
216258
targetProfile.replace(0, 2, L"ms");
217259
break;
218260
default:
219-
hlslOptions.preprocessorOptions.logger.log("invalid shader stage %i", system::ILogger::ELL_ERROR, options.stage);
261+
hlslOptions.preprocessorOptions.logger.log("invalid shader stage %i", system::ILogger::ELL_ERROR, stage);
220262
return nullptr;
221263
};
222264

@@ -246,7 +288,7 @@ core::smart_refctd_ptr<ICPUShader> CHLSLCompiler::compileToSPIRV(const char* cod
246288

247289
compileResult.release();
248290

249-
return core::make_smart_refctd_ptr<asset::ICPUShader>(std::move(outSpirv), hlslOptions.stage, IShader::E_CONTENT_TYPE::ECT_SPIRV, hlslOptions.preprocessorOptions.sourceIdentifier.data());
291+
return core::make_smart_refctd_ptr<asset::ICPUShader>(std::move(outSpirv), stage, IShader::E_CONTENT_TYPE::ECT_SPIRV, hlslOptions.preprocessorOptions.sourceIdentifier.data());
250292
}
251293

252294
void CHLSLCompiler::insertIntoStart(std::string& code, std::ostringstream&& ins) const

src/nbl/asset/utils/IShaderCompiler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ namespace nbl::asset::impl
101101

102102
std::string IShaderCompiler::preprocessShader(
103103
std::string&& code,
104-
IShader::E_SHADER_STAGE stage,
104+
IShader::E_SHADER_STAGE& stage,
105105
const SPreprocessorOptions& preprocessOptions) const
106106
{
107107
if (preprocessOptions.extraDefines.size())

src/nbl/video/CVulkanLogicalDevice.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ class CVulkanLogicalDevice final : public ILogicalDevice
570570
if (m_devf.vk.vkCreateShaderModule(m_vkdev, &vk_createInfo, nullptr, &vk_shaderModule) == VK_SUCCESS)
571571
{
572572
return core::make_smart_refctd_ptr<video::CVulkanShader>(
573-
core::smart_refctd_ptr<CVulkanLogicalDevice>(this), cpushader->getStage(), std::string(cpushader->getFilepathHint()), vk_shaderModule);
573+
core::smart_refctd_ptr<CVulkanLogicalDevice>(this), spirvShader->getStage(), std::string(cpushader->getFilepathHint()), vk_shaderModule);
574574
}
575575
else
576576
{

0 commit comments

Comments
 (0)