Split GLSL compiler from shader module creation
This commit is contained in:
parent
65ade3e017
commit
7ba1f35142
3 changed files with 65 additions and 46 deletions
|
|
@ -218,31 +218,40 @@ public:
|
|||
std::string text; // the file contents - or include error message if name is empty
|
||||
};
|
||||
|
||||
class ShaderBuilder
|
||||
class GLSLCompiler
|
||||
{
|
||||
public:
|
||||
ShaderBuilder();
|
||||
|
||||
static void Init();
|
||||
static void Deinit();
|
||||
|
||||
ShaderBuilder& Type(ShaderType type);
|
||||
ShaderBuilder& AddSource(const std::string& name, const std::string& code);
|
||||
GLSLCompiler& Type(ShaderType type);
|
||||
GLSLCompiler& AddSource(const std::string& name, const std::string& code);
|
||||
|
||||
ShaderBuilder& OnIncludeSystem(std::function<ShaderIncludeResult(std::string headerName, std::string includerName, size_t inclusionDepth)> onIncludeSystem);
|
||||
ShaderBuilder& OnIncludeLocal(std::function<ShaderIncludeResult(std::string headerName, std::string includerName, size_t inclusionDepth)> onIncludeLocal);
|
||||
GLSLCompiler& OnIncludeSystem(std::function<ShaderIncludeResult(std::string headerName, std::string includerName, size_t inclusionDepth)> onIncludeSystem);
|
||||
GLSLCompiler& OnIncludeLocal(std::function<ShaderIncludeResult(std::string headerName, std::string includerName, size_t inclusionDepth)> onIncludeLocal);
|
||||
|
||||
ShaderBuilder& DebugName(const char* name) { debugName = name; return *this; }
|
||||
|
||||
std::unique_ptr<VulkanShader> Create(const char *shadername, VulkanDevice *device);
|
||||
std::vector<uint32_t> Compile(uint32_t apiVersion/* = VK_API_VERSION_1_0*/);
|
||||
std::vector<uint32_t> Compile(VulkanDevice* device);
|
||||
|
||||
private:
|
||||
std::vector<std::pair<std::string, std::string>> sources;
|
||||
std::function<ShaderIncludeResult(std::string headerName, std::string includerName, size_t inclusionDepth)> onIncludeSystem;
|
||||
std::function<ShaderIncludeResult(std::string headerName, std::string includerName, size_t inclusionDepth)> onIncludeLocal;
|
||||
int stage = 0;
|
||||
friend class GLSLCompilerIncluderImpl;
|
||||
};
|
||||
|
||||
class ShaderBuilder
|
||||
{
|
||||
public:
|
||||
ShaderBuilder& Code(std::vector<uint32_t> spirv) { code = std::move(spirv); return *this; }
|
||||
ShaderBuilder& DebugName(const char* name) { debugName = name; return *this; }
|
||||
|
||||
std::unique_ptr<VulkanShader> Create(const char *shadername, VulkanDevice *device);
|
||||
|
||||
private:
|
||||
std::vector<uint32_t> code;
|
||||
const char* debugName = nullptr;
|
||||
friend class ShaderBuilderIncluderImpl;
|
||||
};
|
||||
|
||||
class AccelerationStructureBuilder
|
||||
|
|
|
|||
|
|
@ -6,21 +6,17 @@
|
|||
#include "glslang/glslang/Public/ResourceLimits.h"
|
||||
#include "glslang/spirv/GlslangToSpv.h"
|
||||
|
||||
void ShaderBuilder::Init()
|
||||
void GLSLCompiler::Init()
|
||||
{
|
||||
ShInitialize();
|
||||
}
|
||||
|
||||
void ShaderBuilder::Deinit()
|
||||
void GLSLCompiler::Deinit()
|
||||
{
|
||||
ShFinalize();
|
||||
}
|
||||
|
||||
ShaderBuilder::ShaderBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
ShaderBuilder& ShaderBuilder::Type(ShaderType type)
|
||||
GLSLCompiler& GLSLCompiler::Type(ShaderType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -34,34 +30,34 @@ ShaderBuilder& ShaderBuilder::Type(ShaderType type)
|
|||
return *this;
|
||||
}
|
||||
|
||||
ShaderBuilder& ShaderBuilder::AddSource(const std::string& name, const std::string& code)
|
||||
GLSLCompiler& GLSLCompiler::AddSource(const std::string& name, const std::string& code)
|
||||
{
|
||||
sources.push_back({ name, code });
|
||||
return *this;
|
||||
}
|
||||
|
||||
ShaderBuilder& ShaderBuilder::OnIncludeSystem(std::function<ShaderIncludeResult(std::string headerName, std::string includerName, size_t inclusionDepth)> onIncludeSystem)
|
||||
GLSLCompiler& GLSLCompiler::OnIncludeSystem(std::function<ShaderIncludeResult(std::string headerName, std::string includerName, size_t inclusionDepth)> onIncludeSystem)
|
||||
{
|
||||
this->onIncludeSystem = std::move(onIncludeSystem);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ShaderBuilder& ShaderBuilder::OnIncludeLocal(std::function<ShaderIncludeResult(std::string headerName, std::string includerName, size_t inclusionDepth)> onIncludeLocal)
|
||||
GLSLCompiler& GLSLCompiler::OnIncludeLocal(std::function<ShaderIncludeResult(std::string headerName, std::string includerName, size_t inclusionDepth)> onIncludeLocal)
|
||||
{
|
||||
this->onIncludeLocal = std::move(onIncludeLocal);
|
||||
return *this;
|
||||
}
|
||||
|
||||
class ShaderBuilderIncluderImpl : public glslang::TShader::Includer
|
||||
class GLSLCompilerIncluderImpl : public glslang::TShader::Includer
|
||||
{
|
||||
public:
|
||||
ShaderBuilderIncluderImpl(ShaderBuilder* shaderBuilder) : shaderBuilder(shaderBuilder)
|
||||
GLSLCompilerIncluderImpl(GLSLCompiler* compiler) : compiler(compiler)
|
||||
{
|
||||
}
|
||||
|
||||
IncludeResult* includeSystem(const char* headerName, const char* includerName, size_t inclusionDepth) override
|
||||
{
|
||||
if (!shaderBuilder->onIncludeSystem)
|
||||
if (!compiler->onIncludeSystem)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -71,7 +67,7 @@ public:
|
|||
std::unique_ptr<ShaderIncludeResult> result;
|
||||
try
|
||||
{
|
||||
result = std::make_unique<ShaderIncludeResult>(shaderBuilder->onIncludeSystem(headerName, includerName, inclusionDepth));
|
||||
result = std::make_unique<ShaderIncludeResult>(compiler->onIncludeSystem(headerName, includerName, inclusionDepth));
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
|
@ -95,7 +91,7 @@ public:
|
|||
|
||||
IncludeResult* includeLocal(const char* headerName, const char* includerName, size_t inclusionDepth) override
|
||||
{
|
||||
if (!shaderBuilder->onIncludeLocal)
|
||||
if (!compiler->onIncludeLocal)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -105,7 +101,7 @@ public:
|
|||
std::unique_ptr<ShaderIncludeResult> result;
|
||||
try
|
||||
{
|
||||
result = std::make_unique<ShaderIncludeResult>(shaderBuilder->onIncludeLocal(headerName, includerName, inclusionDepth));
|
||||
result = std::make_unique<ShaderIncludeResult>(compiler->onIncludeLocal(headerName, includerName, inclusionDepth));
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
|
@ -137,10 +133,15 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
ShaderBuilder* shaderBuilder = nullptr;
|
||||
GLSLCompiler* compiler = nullptr;
|
||||
};
|
||||
|
||||
std::unique_ptr<VulkanShader> ShaderBuilder::Create(const char *shadername, VulkanDevice *device)
|
||||
std::vector<uint32_t> GLSLCompiler::Compile(VulkanDevice* device)
|
||||
{
|
||||
return Compile(device->Instance->ApiVersion);
|
||||
}
|
||||
|
||||
std::vector<uint32_t> GLSLCompiler::Compile(uint32_t apiVersion)
|
||||
{
|
||||
EShLanguage stage = (EShLanguage)this->stage;
|
||||
|
||||
|
|
@ -156,22 +157,23 @@ std::unique_ptr<VulkanShader> ShaderBuilder::Create(const char *shadername, Vulk
|
|||
glslang::TShader shader(stage);
|
||||
shader.setStringsWithLengthsAndNames(sourcesC.data(), lengthsC.data(), namesC.data(), (int)sources.size());
|
||||
shader.setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, 100);
|
||||
if (device->Instance->ApiVersion >= VK_API_VERSION_1_2)
|
||||
{
|
||||
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_2);
|
||||
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_4);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0);
|
||||
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0);
|
||||
}
|
||||
if (apiVersion >= VK_API_VERSION_1_2)
|
||||
{
|
||||
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_2);
|
||||
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_4);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0);
|
||||
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0);
|
||||
}
|
||||
|
||||
ShaderBuilderIncluderImpl includer(this);
|
||||
GLSLCompilerIncluderImpl includer(this);
|
||||
bool compileSuccess = shader.parse(GetDefaultResources(), 110, false, EShMsgVulkanRules, includer);
|
||||
if (!compileSuccess)
|
||||
{
|
||||
VulkanError((std::string("Shader compile failed: ") + shader.getInfoLog()).c_str());
|
||||
return {};
|
||||
}
|
||||
|
||||
glslang::TProgram program;
|
||||
|
|
@ -180,12 +182,14 @@ std::unique_ptr<VulkanShader> ShaderBuilder::Create(const char *shadername, Vulk
|
|||
if (!linkSuccess)
|
||||
{
|
||||
VulkanError((std::string("Shader link failed: ") + program.getInfoLog()).c_str());
|
||||
return {};
|
||||
}
|
||||
|
||||
glslang::TIntermediate *intermediate = program.getIntermediate(stage);
|
||||
glslang::TIntermediate* intermediate = program.getIntermediate(stage);
|
||||
if (!intermediate)
|
||||
{
|
||||
VulkanError("Internal shader compiler error");
|
||||
return {};
|
||||
}
|
||||
|
||||
glslang::SpvOptions spvOptions;
|
||||
|
|
@ -193,14 +197,20 @@ std::unique_ptr<VulkanShader> ShaderBuilder::Create(const char *shadername, Vulk
|
|||
spvOptions.disableOptimizer = false;
|
||||
spvOptions.optimizeSize = true;
|
||||
|
||||
std::vector<unsigned int> spirv;
|
||||
std::vector<uint32_t> spirv;
|
||||
spv::SpvBuildLogger logger;
|
||||
glslang::GlslangToSpv(*intermediate, spirv, &logger, &spvOptions);
|
||||
return spirv;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<VulkanShader> ShaderBuilder::Create(const char *shadername, VulkanDevice *device)
|
||||
{
|
||||
VkShaderModuleCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
createInfo.codeSize = spirv.size() * sizeof(unsigned int);
|
||||
createInfo.pCode = spirv.data();
|
||||
createInfo.codeSize = code.size() * sizeof(uint32_t);
|
||||
createInfo.pCode = code.data();
|
||||
|
||||
VkShaderModule shaderModule;
|
||||
VkResult result = vkCreateShaderModule(device->device, &createInfo, nullptr, &shaderModule);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ VulkanInstance::VulkanInstance(std::vector<uint32_t> apiVersionsToTry, std::set<
|
|||
{
|
||||
try
|
||||
{
|
||||
ShaderBuilder::Init();
|
||||
GLSLCompiler::Init();
|
||||
InitVolk();
|
||||
CreateInstance();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue