Skip to content

Commit ffccf14

Browse files
committed
Added "CCompilerSet"
1 parent b85d61f commit ffccf14

File tree

10 files changed

+176
-65
lines changed

10 files changed

+176
-65
lines changed

include/nbl/asset/ICPUShader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class NBL_API ICPUShader : public IAsset, public IShader
132132
return m_code->isAnyDependencyDummy(_levelsBelow);
133133
}
134134

135-
core::smart_refctd_ptr<ICPUBuffer> m_code;
135+
core::smart_refctd_ptr<ICPUBuffer> m_code;
136136
E_CONTENT_TYPE m_contentType;
137137
};
138138

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (C) 2018-2022 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
5+
#ifndef _NBL_ASSET_C_COMPILER_SET_H_INCLUDED_
6+
#define _NBL_ASSET_C_COMPILER_SET_H_INCLUDED_
7+
8+
#include "nbl/core/declarations.h"
9+
#include "CGLSLCompiler.h"
10+
#include "CHLSLCompiler.h"
11+
12+
namespace nbl::asset
13+
{
14+
class NBL_API2 CCompilerSet : public core::IReferenceCounted
15+
{
16+
public:
17+
CCompilerSet(core::smart_refctd_ptr<system::ISystem>&& sys)
18+
: m_HLSLCompiler(core::make_smart_refctd_ptr<CHLSLCompiler>(core::smart_refctd_ptr(sys)))
19+
, m_GLSLCompiler(core::make_smart_refctd_ptr<CGLSLCompiler>(core::smart_refctd_ptr(sys)))
20+
{}
21+
22+
core::smart_refctd_ptr<ICPUBuffer> compileToSPIRV(core::smart_refctd_ptr<asset::ICPUShader> shader, const IShaderCompiler::SOptions& options);
23+
24+
inline core::smart_refctd_ptr<IShaderCompiler> getShaderCompiler(IShader::E_CONTENT_TYPE contentType) const
25+
{
26+
if (contentType == IShader::E_CONTENT_TYPE::ECT_HLSL)
27+
return m_HLSLCompiler;
28+
else if (contentType == IShader::E_CONTENT_TYPE::ECT_GLSL)
29+
return m_GLSLCompiler;
30+
else
31+
return nullptr;
32+
}
33+
34+
protected:
35+
core::smart_refctd_ptr<CHLSLCompiler> m_HLSLCompiler = nullptr;
36+
core::smart_refctd_ptr<CGLSLCompiler> m_GLSLCompiler = nullptr;
37+
};
38+
}
39+
40+
#endif

include/nbl/asset/utils/CGLSLCompiler.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace nbl::asset
1212
{
1313

14-
class NBL_API CGLSLCompiler final : public IShaderCompiler
14+
class NBL_API2 CGLSLCompiler final : public IShaderCompiler
1515
{
1616
public:
1717
IShader::E_CONTENT_TYPE getCodeContentType() const override { return IShader::E_CONTENT_TYPE::ECT_GLSL; };
@@ -20,6 +20,11 @@ class NBL_API CGLSLCompiler final : public IShaderCompiler
2020

2121
struct SOptions : IShaderCompiler::SOptions
2222
{
23+
void setCommonData(const IShaderCompiler::SOptions& opt)
24+
{
25+
static_cast<IShaderCompiler::SOptions&>(*this) = opt;
26+
}
27+
2328
virtual IShader::E_CONTENT_TYPE getCodeContentType() const override { return IShader::E_CONTENT_TYPE::ECT_GLSL; };
2429
};
2530

@@ -37,12 +42,8 @@ class NBL_API CGLSLCompiler final : public IShaderCompiler
3742
This function does NOT process #include directives! Use resolveIncludeDirectives() first.
3843
3944
@params code high level code
40-
@param options
41-
entryPoint Must be "main" since shaderc does not allow other entry points for GLSL. Kept with hope that shaderc will drop that requirement.
42-
compilationId String that will be printed along with possible errors as source identifier.
43-
genDebugInfo Requests compiler to generate debug info (most importantly objects' names).
44-
The engine, while running on OpenGL, won't be able to set push constants for shaders loaded as SPIR-V without debug info.
45-
outAssembly Optional parameter; if not nullptr, SPIR-V assembly is saved in there.
45+
@params options see IShaderCompiler::SOptions
46+
- entryPoint Must be "main" since shaderc does not allow other entry points for GLSL. Kept with hope that shaderc will drop that requirement.
4647
4748
@returns Shader containing SPIR-V bytecode.
4849
*/
@@ -52,7 +53,7 @@ class NBL_API CGLSLCompiler final : public IShaderCompiler
5253

5354
core::smart_refctd_ptr<ICPUShader> createSPIRVShader(system::IFile* sourceFile, const CGLSLCompiler::SOptions& options) const;
5455

55-
// TODO: REMOVE
56+
// TODO: REMOVE after GL Deprecation
5657
core::smart_refctd_ptr<ICPUBuffer> compileSPIRVFromGLSL(
5758
const char* _glslCode,
5859
IShader::E_SHADER_STAGE _stage,
@@ -63,7 +64,7 @@ class NBL_API CGLSLCompiler final : public IShaderCompiler
6364
system::logger_opt_ptr logger = nullptr,
6465
const E_SPIRV_VERSION targetSpirvVersion = E_SPIRV_VERSION::ESV_1_6) const;
6566

66-
// TODO: REMOVE
67+
// TODO: REMOVE after GL Deprecation
6768
core::smart_refctd_ptr<ICPUShader> createSPIRVFromGLSL(
6869
const char* _glslCode,
6970
IShader::E_SHADER_STAGE _stage,
@@ -75,7 +76,7 @@ class NBL_API CGLSLCompiler final : public IShaderCompiler
7576
system::logger_opt_ptr logger = nullptr,
7677
const E_SPIRV_VERSION targetSpirvVersion = E_SPIRV_VERSION::ESV_1_6) const;
7778

78-
// TODO: REMOVE
79+
// TODO: REMOVE after GL Deprecation
7980
core::smart_refctd_ptr<ICPUShader> createSPIRVFromGLSL(
8081
system::IFile* _sourcefile,
8182
IShader::E_SHADER_STAGE _stage,

include/nbl/asset/utils/CHLSLCompiler.h

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace nbl::asset
1212
{
1313

14-
class NBL_API CHLSLCompiler final : public IShaderCompiler
14+
class NBL_API2 CHLSLCompiler final : public IShaderCompiler
1515
{
1616
public:
1717
IShader::E_CONTENT_TYPE getCodeContentType() const override { return IShader::E_CONTENT_TYPE::ECT_HLSL; };
@@ -21,32 +21,15 @@ class NBL_API CHLSLCompiler final : public IShaderCompiler
2121
struct SOptions : IShaderCompiler::SOptions
2222
{
2323
// TODO: Add extra dxc options
24-
virtual IShader::E_CONTENT_TYPE getCodeContentType() const override { return IShader::E_CONTENT_TYPE::ECT_HLSL; };
25-
};
26-
27-
/**
28-
If options.stage is ESS_UNKNOWN, then compiler will try to deduce shader stage from #pragma annotation, i.e.:
29-
#pragma shader_stage(vertex), or
30-
#pragma shader_stage(tesscontrol), or
31-
#pragma shader_stage(tesseval), or
32-
#pragma shader_stage(geometry), or
33-
#pragma shader_stage(fragment), or
34-
#pragma shader_stage(compute)
35-
36-
Such annotation should be placed right after #version directive.
3724

38-
This function does NOT process #include directives! Use resolveIncludeDirectives() first.
25+
void setCommonData(const IShaderCompiler::SOptions& opt)
26+
{
27+
static_cast<IShaderCompiler::SOptions&>(*this) = opt;
28+
}
3929

40-
@params code high level code
41-
@param options
42-
entryPoint Must be "main" since shaderc does not allow other entry points for HLSL. Kept with hope that shaderc will drop that requirement.
43-
compilationId String that will be printed along with possible errors as source identifier.
44-
genDebugInfo Requests compiler to generate debug info (most importantly objects' names).
45-
The engine, while running on OpenGL, won't be able to set push constants for shaders loaded as SPIR-V without debug info.
46-
outAssembly Optional parameter; if not nullptr, SPIR-V assembly is saved in there.
30+
virtual IShader::E_CONTENT_TYPE getCodeContentType() const override { return IShader::E_CONTENT_TYPE::ECT_HLSL; };
31+
};
4732

48-
@returns Shader containing SPIR-V bytecode.
49-
*/
5033
core::smart_refctd_ptr<ICPUBuffer> compileToSPIRV(const char* code, const CHLSLCompiler::SOptions& options) const;
5134

5235
core::smart_refctd_ptr<ICPUShader> createSPIRVShader(const char* code, const CHLSLCompiler::SOptions& options) const;

include/nbl/asset/utils/IShaderCompiler.h

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
namespace nbl::asset
1818
{
1919

20-
class NBL_API IShaderCompiler : public core::IReferenceCounted
20+
class NBL_API2 IShaderCompiler : public core::IReferenceCounted
2121
{
2222
public:
2323

@@ -107,16 +107,30 @@ class NBL_API IShaderCompiler : public core::IReferenceCounted
107107

108108
IShaderCompiler(core::smart_refctd_ptr<system::ISystem>&& system);
109109

110+
/*
111+
@stage shaderStage
112+
@targetSpirvVersion spirv version
113+
@entryPoint entryPoint
114+
@sourceIdentifier String that will be printed along with possible errors as source identifier, and used as include's requestingSrc
115+
@outAssembly Optional parameter; if not nullptr, SPIR-V assembly is saved in there.
116+
@spirvOptimizer Optional parameter;
117+
@logger Optional parameter; used for logging errors/info
118+
@includeFinder Optional parameter; if not nullptr, it will resolve the includes in the code
119+
@maxSelfInclusionCount used only when includeFinder is not nullptr
120+
@genDebugInfo Requests compiler to generate debug info (most importantly objects' names).
121+
The engine, while running on OpenGL, won't be able to set push constants for shaders loaded as SPIR-V without debug info.
122+
*/
110123
struct SOptions
111124
{
112125
IShader::E_SHADER_STAGE stage = IShader::E_SHADER_STAGE::ESS_UNKNOWN;
113-
const E_SPIRV_VERSION targetSpirvVersion = E_SPIRV_VERSION::ESV_1_6;
126+
E_SPIRV_VERSION targetSpirvVersion = E_SPIRV_VERSION::ESV_1_6;
114127
const char* entryPoint = nullptr;
115128
const char* sourceIdentifier = nullptr;
116-
std::string* outAssembly = nullptr; // @optional,
117-
const ISPIRVOptimizer* spirvOptimizer = nullptr; // @optional,
118-
system::logger_opt_ptr logger = nullptr; // @optional, for logging purposes
119-
const CIncludeFinder* includeFinder = nullptr; // @optional, If not CGLSLCompiler will use it's default one.
129+
std::string* outAssembly = nullptr;
130+
const ISPIRVOptimizer* spirvOptimizer = nullptr;
131+
system::logger_opt_ptr logger = nullptr;
132+
const CIncludeFinder* includeFinder = nullptr;
133+
uint32_t maxSelfInclusionCount = 4u;
120134
bool genDebugInfo = true;
121135

122136
virtual IShader::E_CONTENT_TYPE getCodeContentType() const { return IShader::E_CONTENT_TYPE::ECT_UNKNOWN; };

include/nbl/video/ILogicalDevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "nbl/asset/asset.h"
55
#include "nbl/asset/utils/ISPIRVOptimizer.h"
6+
#include "nbl/asset/utils/CCompilerSet.h"
67

78
#include "nbl/video/IGPUFence.h"
89
/*

src/nbl/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ set(NBL_ASSET_SOURCES
234234
${NBL_ROOT_PATH}/src/nbl/asset/utils/IShaderCompiler.cpp
235235
${NBL_ROOT_PATH}/src/nbl/asset/utils/CGLSLCompiler.cpp
236236
${NBL_ROOT_PATH}/src/nbl/asset/utils/CHLSLCompiler.cpp
237+
${NBL_ROOT_PATH}/src/nbl/asset/utils/CCompilerSet.cpp
237238
${NBL_ROOT_PATH}/src/nbl/asset/utils/CShaderIntrospector.cpp
238239
${NBL_ROOT_PATH}/src/nbl/asset/interchange/CGLSLLoader.cpp
239240
${NBL_ROOT_PATH}/src/nbl/asset/interchange/CSPVLoader.cpp

src/nbl/asset/utils/CCompilerSet.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (C) 2018-2022 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
#include "nbl/asset/utils/CCompilerSet.h"
5+
6+
using namespace nbl;
7+
using namespace nbl::asset;
8+
9+
core::smart_refctd_ptr<ICPUBuffer> CCompilerSet::compileToSPIRV(core::smart_refctd_ptr<asset::ICPUShader> shader, const IShaderCompiler::SOptions& options)
10+
{
11+
core::smart_refctd_ptr<ICPUBuffer> outSpirvShader;
12+
if (shader)
13+
{
14+
switch (shader->getContentType())
15+
{
16+
case IShader::E_CONTENT_TYPE::ECT_HLSL:
17+
{
18+
const char* code = reinterpret_cast<const char*>(shader->getContent()->getPointer());
19+
if (options.getCodeContentType() == IShader::E_CONTENT_TYPE::ECT_HLSL)
20+
{
21+
m_HLSLCompiler->compileToSPIRV(code, static_cast<const CHLSLCompiler::SOptions&>(options));
22+
}
23+
else
24+
{
25+
CHLSLCompiler::SOptions hlslCompilerOptions = {};
26+
hlslCompilerOptions.setCommonData(options);
27+
m_HLSLCompiler->compileToSPIRV(code, hlslCompilerOptions);
28+
}
29+
}
30+
break;
31+
case IShader::E_CONTENT_TYPE::ECT_GLSL:
32+
{
33+
const char* code = reinterpret_cast<const char*>(shader->getContent()->getPointer());
34+
if (options.getCodeContentType() == IShader::E_CONTENT_TYPE::ECT_GLSL)
35+
{
36+
m_GLSLCompiler->compileToSPIRV(code, static_cast<const CGLSLCompiler::SOptions&>(options));
37+
}
38+
else
39+
{
40+
CGLSLCompiler::SOptions glslCompilerOptions = {};
41+
glslCompilerOptions.setCommonData(options);
42+
m_GLSLCompiler->compileToSPIRV(code, glslCompilerOptions);
43+
}
44+
}
45+
break;
46+
case IShader::E_CONTENT_TYPE::ECT_SPIRV:
47+
{
48+
outSpirvShader = core::smart_refctd_ptr<ICPUBuffer>(const_cast<ICPUBuffer*>(shader->getContent()));
49+
}
50+
break;
51+
}
52+
}
53+
return outSpirvShader;
54+
}

src/nbl/asset/utils/CGLSLCompiler.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ core::smart_refctd_ptr<ICPUBuffer> CGLSLCompiler::compileToSPIRV(const char* cod
2323
core::smart_refctd_ptr<ICPUBuffer> outSpirv = nullptr;
2424
if (code)
2525
{
26+
core::smart_refctd_ptr<asset::ICPUShader> cpuShader;
27+
if (options.includeFinder != nullptr)
28+
{
29+
cpuShader = resolveIncludeDirectives(code, options.stage, options.sourceIdentifier, options.maxSelfInclusionCount, options.logger);
30+
if (cpuShader)
31+
{
32+
code = reinterpret_cast<const char*>(cpuShader->getContent()->getPointer());
33+
}
34+
}
35+
2636
if (strcmp(options.entryPoint, "main") == 0)
2737
{
2838
shaderc::Compiler comp;

src/nbl/video/CVulkanLogicalDevice.h

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -514,34 +514,41 @@ class CVulkanLogicalDevice final : public ILogicalDevice
514514

515515
const asset::ICPUBuffer* source = cpushader->getContent();
516516

517-
core::smart_refctd_ptr<asset::ICPUBuffer> spirv;
518-
if (cpushader->getContentType() == asset::ICPUShader::E_CONTENT_TYPE::ECT_GLSL)
519-
{
520-
const char* begin = static_cast<const char*>(source->getPointer());
521-
const char* end = begin + source->getSize();
522-
523-
std::string glsl(begin, end);
524-
asset::IShader::insertDefines(glsl, m_physicalDevice->getExtraGLSLDefines());
525-
526-
auto logger = (m_physicalDevice->getDebugCallback()) ? m_physicalDevice->getDebugCallback()->getLogger() : nullptr;
517+
// TODO:
518+
core::smart_refctd_ptr<asset::CCompilerSet> compilerSet;
519+
520+
const char* begin = static_cast<const char*>(source->getPointer());
521+
const char* end = begin + source->getSize();
522+
std::string code(begin, end);
523+
524+
auto compiler = compilerSet->getShaderCompiler(cpushader->getContentType());
525+
asset::IShaderCompiler::SOptions commonCompileOptions = {};
526+
commonCompileOptions.logger = (m_physicalDevice->getDebugCallback()) ? m_physicalDevice->getDebugCallback()->getLogger() : nullptr;
527+
commonCompileOptions.includeFinder = compiler->getDefaultIncludeFinder(); // to resolve includes before compilation
528+
commonCompileOptions.stage = shaderStage;
529+
commonCompileOptions.sourceIdentifier = cpushader->getFilepathHint().c_str();
530+
commonCompileOptions.entryPoint = entryPoint;
531+
commonCompileOptions.genDebugInfo = true;
532+
commonCompileOptions.spirvOptimizer = nullptr; // TODO: create/get spirv optimizer in logical device?
533+
commonCompileOptions.targetSpirvVersion = m_physicalDevice->getLimits().spirvVersion;
534+
535+
if (cpushader->getContentType() != asset::ICPUShader::E_CONTENT_TYPE::ECT_SPIRV)
536+
asset::IShader::insertDefines(code, m_physicalDevice->getExtraGLSLDefines());
527537

528-
core::smart_refctd_ptr<asset::ICPUShader> glslShader_woIncludes =
529-
m_physicalDevice->getGLSLCompiler()->resolveIncludeDirectives(glsl.c_str(),
530-
shaderStage, cpushader->getFilepathHint().c_str(), 4u, logger);
538+
core::smart_refctd_ptr<asset::ICPUBuffer> spirv;
531539

532-
spirv = m_physicalDevice->getGLSLCompiler()->compileSPIRVFromGLSL(
533-
reinterpret_cast<const char*>(glslShader_woIncludes->getContent()->getPointer()),
534-
shaderStage,
535-
entryPoint,
536-
cpushader->getFilepathHint().c_str(),
537-
true,
538-
nullptr,
539-
logger,
540-
m_physicalDevice->getLimits().spirvVersion);
540+
if (cpushader->getContentType() == asset::ICPUShader::E_CONTENT_TYPE::ECT_HLSL)
541+
{
542+
// TODO: add specific HLSLCompiler::SOption params
543+
spirv = compilerSet->compileToSPIRV(cpushader, commonCompileOptions);
541544
}
542-
else
545+
else if (cpushader->getContentType() == asset::ICPUShader::E_CONTENT_TYPE::ECT_GLSL)
546+
{
547+
spirv = compilerSet->compileToSPIRV(cpushader, commonCompileOptions);
548+
}
549+
else if (cpushader->getContentType() == asset::ICPUShader::E_CONTENT_TYPE::ECT_SPIRV)
543550
{
544-
assert(false); // TODO[ShaderCompiler]: not supported right now
551+
spirv = core::smart_refctd_ptr<asset::ICPUBuffer>(const_cast<asset::ICPUBuffer*>(cpushader->getContent()));
545552
}
546553

547554
if (!spirv)

0 commit comments

Comments
 (0)