Skip to content
Snippets Groups Projects
Commit 44ebe324 authored by Tobias Frisch's avatar Tobias Frisch
Browse files

Merge branch '147-vcc-shady-support' into 'develop'

Resolve "VCC/Shady support"

Closes #147

See merge request !116
parents adf52ba1 e800d8d3
No related branches found
No related tags found
1 merge request!116Resolve "VCC/Shady support"
Showing
with 527 additions and 3 deletions
......@@ -70,3 +70,12 @@
path = modules/asset_loader/lib/wuffs-mirror-release-c
url = https://github.com/google/wuffs-mirror-release-c.git
branch = main
[submodule "modules/shader_compiler/lib/shady"]
path = modules/shader_compiler/lib/shady
url = https://github.com/TheJackiMonster/shady.git
[submodule "modules/shader_compiler/lib/SPIRV-Headers"]
path = modules/shader_compiler/lib/SPIRV-Headers
url = https://github.com/KhronosGroup/SPIRV-Headers.git
[submodule "modules/shader_compiler/lib/murmur3"]
path = modules/shader_compiler/lib/murmur3
url = https://github.com/PeterScott/murmur3.git
......@@ -21,6 +21,15 @@ set(vkcv_shader_compiler_sources
${vkcv_shader_compiler_include}/vkcv/shader/HLSLCompiler.hpp
${vkcv_shader_compiler_source}/vkcv/shader/HLSLCompiler.cpp
${vkcv_shader_compiler_include}/vkcv/shader/ShadyCompiler.hpp
${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)
......@@ -33,9 +42,16 @@ set_target_properties(vkcv_shader_compiler PROPERTIES PUBLIC_HEADER "${vkcv_shad
set(vkcv_shader_compiler_lib lib)
set(vkcv_shader_compiler_lib_path ${PROJECT_SOURCE_DIR}/${vkcv_shader_compiler_lib})
# Load SPIRV-Headers
include(config/SPIRV-Headers.cmake)
# Check and load GLSLANG
include(config/GLSLANG.cmake)
# Check and load Shady (with murmur3)
include(config/Murmur3.cmake)
include(config/Shady.cmake)
# link the required libraries to the module
target_link_libraries(vkcv_shader_compiler ${vkcv_shader_compiler_libraries} vkcv)
......
use_git_submodule("${vkcv_shader_compiler_lib_path}/murmur3" murmur3_status)
if (${murmur3_status})
add_library(murmur3 STATIC ${vkcv_shader_compiler_lib}/murmur3/murmur3.c)
target_include_directories(murmur3 INTERFACE ${vkcv_shader_compiler_lib}/murmur3)
set_target_properties(murmur3 PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif ()
use_git_submodule("${vkcv_shader_compiler_lib_path}/SPIRV-Headers" spriv_headers_status)
if (${spriv_headers_status})
add_subdirectory(${vkcv_shader_compiler_lib}/SPIRV-Headers)
list(APPEND vkcv_shader_compiler_libraries SPIRV-Headers)
list(APPEND vkcv_shader_compiler_includes ${vkcv_shader_compiler_lib}/SPIRV-Headers/include)
endif ()
use_git_submodule("${vkcv_shader_compiler_lib_path}/shady" shady_status)
if (${shady_status})
set(EXTERNAL_SPIRV_HEADERS ON CACHE INTERNAL "")
set(EXTERNAL_MURMUR3 ON CACHE INTERNAL "")
add_subdirectory(${vkcv_shader_compiler_lib}/shady)
if (vkcv_build_attribute EQUAL "SHARED")
list(APPEND vkcv_shader_compiler_libraries shady runtime)
else ()
list(APPEND vkcv_shader_compiler_libraries common driver)
endif ()
list(APPEND vkcv_shader_compiler_includes ${vkcv_shader_compiler_lib}/shady/include)
endif ()
......@@ -19,8 +19,6 @@ namespace vkcv::shader {
public:
/**
* The constructor of a runtime Glslang shader compiler instance.
*
* @param[in] target Compile target (optional)
*/
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;
};
/** @} */
}
#pragma once
#include <filesystem>
#include <vkcv/ShaderStage.hpp>
#include "Compiler.hpp"
namespace vkcv::shader {
/**
* @addtogroup vkcv_shader
* @{
*/
/**
* An abstract class to handle Shady runtime shader compilation.
*/
class ShadyCompiler : public Compiler {
public:
/**
* The constructor of a runtime Shady shader compiler instance.
*/
ShadyCompiler();
/**
* 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;
/**
* The destructor of a runtime Shady shader compiler instance.
*/
~ShadyCompiler() = default;
/**
* 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;
/**
* 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,
const std::filesystem::path& shaderPath,
const ShaderCompiledFunction& compiled,
const std::filesystem::path& includePath = "",
bool update = false) override;
};
/** @} */
}
#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;
};
/** @} */
}
Subproject commit bdd1b2ab1f03e616047bbcf8971157dccd50c792
Subproject commit dae94be0c0f54a399d23ea6cbe54bca5a4e93ce4
Subproject commit 0a92cf7ff4081d21db0724a8e66ab868b878df7d
#include "vkcv/shader/LLVMCompiler.hpp"
#include <vkcv/File.hpp>
#include <vkcv/Logger.hpp>
extern "C" {
#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;
}
return shadyCompileModule(module, shaderStage, shaderSource, compiled, includePath);
}
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;
}
}
#include "vkcv/shader/ShadyCompiler.hpp"
#include <vkcv/File.hpp>
#include <vkcv/Logger.hpp>
namespace vkcv::shader {
ShadyCompiler::ShadyCompiler()
: Compiler() {}
void ShadyCompiler::compile(ShaderStage shaderStage,
const std::filesystem::path &shaderPath,
const ShaderCompiledFunction &compiled,
const std::filesystem::path &includePath,
bool update) {
std::string shaderCode;
bool result = readTextFromFile(shaderPath, shaderCode);
if (!result) {
vkcv_log(LogLevel::ERROR, "Loading shader failed: (%s)", shaderPath.string().c_str());
}
if (!includePath.empty()) {
result = compileSource(shaderStage, shaderCode, compiled, includePath);
} else {
result = compileSource(shaderStage, shaderCode, compiled, shaderPath.parent_path());
}
if (!result) {
vkcv_log(LogLevel::ERROR, "Shader compilation failed: (%s)", shaderPath.string().c_str());
}
if (update) {
// TODO: Shader hot compilation during runtime
}
}
}
#include "vkcv/shader/SlimCompiler.hpp"
#include <vkcv/File.hpp>
#include <vkcv/Logger.hpp>
extern "C" {
#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;
}
return shadyCompileModule(module, shaderStage, shaderSource, compiled, includePath);
}
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;
}
}
......@@ -2,6 +2,7 @@
#include <vkcv/Core.hpp>
#include <vkcv/Pass.hpp>
#include <GLFW/glfw3.h>
#include <vkcv/ShaderProgram.hpp>
#include <vkcv/camera/CameraManager.hpp>
#include <vkcv/shader/GLSLCompiler.hpp>
......@@ -38,7 +39,7 @@ int main(int argc, const char** argv) {
vkcv::shader::GLSLCompiler compiler;
compiler.compileProgram(triangleShaderProgram, {
{vkcv::ShaderStage::VERTEX, "shaders/shader.vert"},
{ vkcv::ShaderStage::VERTEX, "shaders/shader.vert" },
{ vkcv::ShaderStage::FRAGMENT, "shaders/shader.frag" }
}, nullptr);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment