Skip to content
Snippets Groups Projects
Verified Commit 271347ad authored by Tobias Frisch's avatar Tobias Frisch
Browse files

Implement separate compiler classes for LLVM and slim front-ends

parent 66cc857c
No related branches found
No related tags found
1 merge request!116Resolve "VCC/Shady support"
...@@ -24,6 +24,12 @@ set(vkcv_shader_compiler_sources ...@@ -24,6 +24,12 @@ set(vkcv_shader_compiler_sources
${vkcv_shader_compiler_include}/vkcv/shader/ShadyCompiler.hpp ${vkcv_shader_compiler_include}/vkcv/shader/ShadyCompiler.hpp
${vkcv_shader_compiler_source}/vkcv/shader/ShadyCompiler.cpp ${vkcv_shader_compiler_source}/vkcv/shader/ShadyCompiler.cpp
${vkcv_shader_compiler_include}/vkcv/shader/SlimCompiler.hpp
${vkcv_shader_compiler_source}/vkcv/shader/SlimCompiler.cpp
${vkcv_shader_compiler_include}/vkcv/shader/LLVMCompiler.hpp
${vkcv_shader_compiler_source}/vkcv/shader/LLVMCompiler.cpp
) )
filter_headers(vkcv_shader_compiler_sources ${vkcv_shader_compiler_include} vkcv_shader_compiler_headers) filter_headers(vkcv_shader_compiler_sources ${vkcv_shader_compiler_include} vkcv_shader_compiler_headers)
......
...@@ -19,8 +19,6 @@ namespace vkcv::shader { ...@@ -19,8 +19,6 @@ namespace vkcv::shader {
public: public:
/** /**
* The constructor of a runtime Glslang shader compiler instance. * The constructor of a runtime Glslang shader compiler instance.
*
* @param[in] target Compile target (optional)
*/ */
GlslangCompiler(); GlslangCompiler();
......
#pragma once
#include <filesystem>
#include <vkcv/ShaderStage.hpp>
#include "ShadyCompiler.hpp"
namespace vkcv::shader {
/**
* @addtogroup vkcv_shader
* @{
*/
enum class LLVMCompileTarget {
UNKNOWN
};
/**
* A class to handle LLVM runtime shader compilation.
*/
class LLVMCompiler : public ShadyCompiler {
private:
LLVMCompileTarget m_target;
public:
/**
* The constructor of a runtime LLVM shader compiler instance.
*
* @param[in] target Compile target (optional)
*/
explicit LLVMCompiler(LLVMCompileTarget target = LLVMCompileTarget::UNKNOWN);
/**
* Compile a LLVM shader from source for a target stage with a custom shader
* include path and an event function called if the compilation completes.
*
* @param[in] shaderStage Shader pipeline stage
* @param[in] shaderSource Source of shader
* @param[in] compiled Shader compilation event
* @param[in] includePath Include path for shaders
* @return Result if the compilation succeeds
*/
bool compileSource(ShaderStage shaderStage,
const std::string& shaderSource,
const ShaderCompiledFunction& compiled,
const std::filesystem::path& includePath = "") override;
};
/** @} */
}
...@@ -7,20 +7,67 @@ ...@@ -7,20 +7,67 @@
namespace vkcv::shader { namespace vkcv::shader {
/**
* @addtogroup vkcv_shader
* @{
*/
/**
* An abstract class to handle Shady runtime shader compilation.
*/
class ShadyCompiler : public Compiler { class ShadyCompiler : public Compiler {
public: public:
/**
* The constructor of a runtime Shady shader compiler instance.
*/
ShadyCompiler(); ShadyCompiler();
ShadyCompiler(const ShadyCompiler& other); /**
* The copy-constructor of a runtime Shady shader compiler instance.
*
* @param[in] other Other instance of a Shady shader compiler instance
*/
ShadyCompiler(const ShadyCompiler& other) = default;
/**
* The move-constructor of a runtime Shady shader compiler instance.
*
* @param[out] other Other instance of a Shady shader compiler instance
*/
ShadyCompiler(ShadyCompiler&& other) = default; ShadyCompiler(ShadyCompiler&& other) = default;
~ShadyCompiler(); /**
* The destructor of a runtime Shady shader compiler instance.
*/
~ShadyCompiler() = default;
ShadyCompiler& operator=(const ShadyCompiler& other); /**
* The copy-operator of a runtime Shady shader compiler instance.
*
* @param[in] other Other instance of a Shady shader compiler instance
* @return Reference to this instance
*/
ShadyCompiler& operator=(const ShadyCompiler& other) = default;
/**
* The copy-operator of a runtime Shady shader compiler instance.
*
* @param[out] other Other instance of a Shady shader compiler instance
* @return Reference to this instance
*/
ShadyCompiler& operator=(ShadyCompiler&& other) = default; ShadyCompiler& operator=(ShadyCompiler&& other) = default;
/**
* Compile a shader from a specific file path for a target stage with
* a custom shader include path and an event function called if the
* compilation completes.
*
* @param[in] shaderStage Shader pipeline stage
* @param[in] shaderPath Filepath of shader
* @param[in] compiled Shader compilation event
* @param[in] includePath Include path for shaders
* @param[in] update Flag to update shaders during runtime
*/
void compile(ShaderStage shaderStage, void compile(ShaderStage shaderStage,
const std::filesystem::path& shaderPath, const std::filesystem::path& shaderPath,
const ShaderCompiledFunction& compiled, const ShaderCompiledFunction& compiled,
...@@ -29,4 +76,6 @@ namespace vkcv::shader { ...@@ -29,4 +76,6 @@ namespace vkcv::shader {
}; };
/** @} */
} }
#pragma once
#include <filesystem>
#include <vkcv/ShaderStage.hpp>
#include "ShadyCompiler.hpp"
namespace vkcv::shader {
/**
* @addtogroup vkcv_shader
* @{
*/
enum class SlimCompileTarget {
UNKNOWN
};
/**
* A class to handle Slim runtime shader compilation.
*/
class SlimCompiler : public ShadyCompiler {
private:
SlimCompileTarget m_target;
public:
/**
* The constructor of a runtime Slim shader compiler instance.
*
* @param[in] target Compile target (optional)
*/
explicit SlimCompiler(SlimCompileTarget target = SlimCompileTarget::UNKNOWN);
/**
* Compile a Slim shader from source for a target stage with a custom shader
* include path and an event function called if the compilation completes.
*
* @param[in] shaderStage Shader pipeline stage
* @param[in] shaderSource Source of shader
* @param[in] compiled Shader compilation event
* @param[in] includePath Include path for shaders
* @return Result if the compilation succeeds
*/
bool compileSource(ShaderStage shaderStage,
const std::string& shaderSource,
const ShaderCompiledFunction& compiled,
const std::filesystem::path& includePath = "") override;
};
/** @} */
}
#include "vkcv/shader/LLVMCompiler.hpp"
#include <vkcv/File.hpp>
#include <vkcv/Logger.hpp>
#include <shady/driver.h>
namespace vkcv::shader {
LLVMCompiler::LLVMCompiler(LLVMCompileTarget target)
: ShadyCompiler(), m_target(target) {}
static bool shadyCompileModule(Module* module,
ShaderStage shaderStage,
const std::string& shaderSource,
const ShaderCompiledFunction &compiled,
const std::filesystem::path &includePath) {
ShadyErrorCodes codes = driver_load_source_file(
SrcLLVM,
shaderSource.length(),
shaderSource.c_str(),
module
);
switch (codes) {
case NoError:
break;
case MissingInputArg:
case MissingOutputArg:
case InputFileDoesNotExist:
case InputFileIOError:
case MissingDumpCfgArg:
case MissingDumpIrArg:
case IncorrectLogLevel:
case InvalidTarget:
case ClangInvocationFailed:
default:
vkcv_log(LogLevel::ERROR, "Unknown error while loading shader");
return false;
}
const std::filesystem::path tmp_path = generateTemporaryFilePath();
DriverConfig config = default_driver_config();
config.target = TgtSPV;
config.output_filename = tmp_path.c_str();
codes = driver_compile(&config, module);
destroy_driver_config(&config);
switch (codes) {
case NoError:
break;
case MissingInputArg:
case MissingOutputArg:
case InputFileDoesNotExist:
case InputFileIOError:
case MissingDumpCfgArg:
case MissingDumpIrArg:
case IncorrectLogLevel:
case InvalidTarget:
case ClangInvocationFailed:
default:
vkcv_log(LogLevel::ERROR, "Unknown error while compiling shader");
return false;
}
if (compiled) {
compiled(shaderStage, tmp_path);
}
std::filesystem::remove(tmp_path);
return true;
}
static bool shadyCompileArena(IrArena* arena,
ShaderStage shaderStage,
const std::string& shaderSource,
const ShaderCompiledFunction &compiled,
const std::filesystem::path &includePath) {
Module* module = new_module(arena, "slim_module");
if (nullptr == module) {
vkcv_log(LogLevel::ERROR, "Module could not be created");
return false;
}
bool result = shadyCompileModule(module, shaderStage, shaderSource, compiled, includePath);
destroy_module(module);
return result;
}
bool LLVMCompiler::compileSource(ShaderStage shaderStage,
const std::string& shaderSource,
const ShaderCompiledFunction& compiled,
const std::filesystem::path& includePath) {
if (ShaderStage::COMPUTE != shaderStage) {
vkcv_log(LogLevel::ERROR, "Shader stage not supported");
return false;
}
ArenaConfig config = default_arena_config();
IrArena* arena = new_ir_arena(config);
if (nullptr == arena) {
vkcv_log(LogLevel::ERROR, "IR Arena could not be created");
return false;
}
bool result = shadyCompileArena(arena, shaderStage, shaderSource, compiled, includePath);
destroy_ir_arena(arena);
return result;
}
}
...@@ -8,127 +8,31 @@ ...@@ -8,127 +8,31 @@
namespace vkcv::shader { namespace vkcv::shader {
ShadyCompiler::ShadyCompiler() : Compiler() { ShadyCompiler::ShadyCompiler()
// TODO : Compiler() {}
}
ShadyCompiler::ShadyCompiler(const ShadyCompiler &other) : Compiler(other) {
// TODO
}
ShadyCompiler::~ShadyCompiler() {
// TODO
}
ShadyCompiler &ShadyCompiler::operator=(const ShadyCompiler &other) {
// TODO
return *this;
}
static bool shadyCompileModule(Module* module,
ShaderStage shaderStage,
const std::filesystem::path &shaderPath,
const ShaderCompiledFunction &compiled,
const std::filesystem::path &includePath) {
ShadyErrorCodes codes = driver_load_source_file_from_filename(
shaderPath.c_str(), module
);
switch (codes) {
case NoError:
break;
case MissingInputArg:
case MissingOutputArg:
case InputFileDoesNotExist:
case InputFileIOError:
case MissingDumpCfgArg:
case MissingDumpIrArg:
case IncorrectLogLevel:
case InvalidTarget:
case ClangInvocationFailed:
default:
vkcv_log(LogLevel::ERROR, "Unknown error while loading shader");
return false;
}
const std::filesystem::path tmp_path = generateTemporaryFilePath();
DriverConfig config = default_driver_config();
config.output_filename = tmp_path.c_str();
// TODO
codes = driver_compile(&config, module);
destroy_driver_config(&config);
switch (codes) {
case NoError:
break;
case MissingInputArg:
case MissingOutputArg:
case InputFileDoesNotExist:
case InputFileIOError:
case MissingDumpCfgArg:
case MissingDumpIrArg:
case IncorrectLogLevel:
case InvalidTarget:
case ClangInvocationFailed:
default:
vkcv_log(LogLevel::ERROR, "Unknown error while compiling shader");
return false;
}
if (compiled) {
compiled(shaderStage, tmp_path);
}
std::filesystem::remove(tmp_path);
return true;
}
static bool shadyCompileArena(IrArena* arena,
ShaderStage shaderStage,
const std::filesystem::path &shaderPath,
const ShaderCompiledFunction &compiled,
const std::filesystem::path &includePath) {
Module* module = new_module(arena, "main");
if (nullptr == module) {
vkcv_log(LogLevel::ERROR, "Module could not be created");
return false;
}
bool result = shadyCompileModule(module, shaderStage, shaderPath, compiled, includePath);
destroy_module(module);
return result;
}
void ShadyCompiler::compile(ShaderStage shaderStage, void ShadyCompiler::compile(ShaderStage shaderStage,
const std::filesystem::path &shaderPath, const std::filesystem::path &shaderPath,
const ShaderCompiledFunction &compiled, const ShaderCompiledFunction &compiled,
const std::filesystem::path &includePath, const std::filesystem::path &includePath,
bool update) { bool update) {
ArenaConfig config {}; std::string shaderCode;
bool result = readTextFromFile(shaderPath, shaderCode);
// TODO
if (!result) {
IrArena* arena = new_ir_arena(config); vkcv_log(LogLevel::ERROR, "Loading shader failed: (%s)", shaderPath.string().c_str());
if (nullptr == arena) {
vkcv_log(LogLevel::ERROR, "IR Arena could not be created");
return;
} }
bool result = shadyCompileArena(arena, shaderStage, shaderPath, compiled, includePath); if (!includePath.empty()) {
result = compileSource(shaderStage, shaderCode, compiled, includePath);
destroy_ir_arena(arena); } else {
result = compileSource(shaderStage, shaderCode, compiled, shaderPath.parent_path());
}
if (!result) { if (!result) {
vkcv_log(LogLevel::ERROR, "Shader compilation failed: (%s)", shaderPath.string().c_str()); vkcv_log(LogLevel::ERROR, "Shader compilation failed: (%s)", shaderPath.string().c_str());
} }
if (update) { if (update) {
// TODO: Shader hot compilation during runtime // TODO: Shader hot compilation during runtime
} }
......
#include "vkcv/shader/SlimCompiler.hpp"
#include <vkcv/File.hpp>
#include <vkcv/Logger.hpp>
#include <shady/driver.h>
namespace vkcv::shader {
SlimCompiler::SlimCompiler(SlimCompileTarget target)
: ShadyCompiler(), m_target(target) {}
static bool shadyCompileModule(Module* module,
ShaderStage shaderStage,
const std::string& shaderSource,
const ShaderCompiledFunction &compiled,
const std::filesystem::path &includePath) {
ShadyErrorCodes codes = driver_load_source_file(
SrcSlim,
shaderSource.length(),
shaderSource.c_str(),
module
);
switch (codes) {
case NoError:
break;
case MissingInputArg:
case MissingOutputArg:
case InputFileDoesNotExist:
case InputFileIOError:
case MissingDumpCfgArg:
case MissingDumpIrArg:
case IncorrectLogLevel:
case InvalidTarget:
case ClangInvocationFailed:
default:
vkcv_log(LogLevel::ERROR, "Unknown error while loading shader");
return false;
}
const std::filesystem::path tmp_path = generateTemporaryFilePath();
DriverConfig config = default_driver_config();
config.target = TgtSPV;
config.output_filename = tmp_path.c_str();
codes = driver_compile(&config, module);
destroy_driver_config(&config);
switch (codes) {
case NoError:
break;
case MissingInputArg:
case MissingOutputArg:
case InputFileDoesNotExist:
case InputFileIOError:
case MissingDumpCfgArg:
case MissingDumpIrArg:
case IncorrectLogLevel:
case InvalidTarget:
case ClangInvocationFailed:
default:
vkcv_log(LogLevel::ERROR, "Unknown error while compiling shader");
return false;
}
if (compiled) {
compiled(shaderStage, tmp_path);
}
std::filesystem::remove(tmp_path);
return true;
}
static bool shadyCompileArena(IrArena* arena,
ShaderStage shaderStage,
const std::string& shaderSource,
const ShaderCompiledFunction &compiled,
const std::filesystem::path &includePath) {
Module* module = new_module(arena, "slim_module");
if (nullptr == module) {
vkcv_log(LogLevel::ERROR, "Module could not be created");
return false;
}
bool result = shadyCompileModule(module, shaderStage, shaderSource, compiled, includePath);
destroy_module(module);
return result;
}
bool SlimCompiler::compileSource(ShaderStage shaderStage,
const std::string& shaderSource,
const ShaderCompiledFunction& compiled,
const std::filesystem::path& includePath) {
if (ShaderStage::COMPUTE != shaderStage) {
vkcv_log(LogLevel::ERROR, "Shader stage not supported");
return false;
}
ArenaConfig config = default_arena_config();
IrArena* arena = new_ir_arena(config);
if (nullptr == arena) {
vkcv_log(LogLevel::ERROR, "IR Arena could not be created");
return false;
}
bool result = shadyCompileArena(arena, shaderStage, shaderSource, compiled, includePath);
destroy_ir_arena(arena);
return result;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment