Added ShaderLoader using shaderc (GCC only)

Signed-off-by: Robear Selwans <robear.selwans@outlook.com>
This commit is contained in:
2021-06-08 09:50:34 +02:00
parent c267a04de4
commit fe03cb933f
8 changed files with 214 additions and 5 deletions

View File

@@ -1,6 +1,6 @@
project('evol-mod-assetmanager', 'c', project('evol-mod-assetmanager', ['c', 'cpp'],
version : '0.1', version : '0.1',
default_options : ['warning_level=3', 'c_std=c11']) default_options : ['warning_level=3', 'c_std=c11', 'default_library=shared'])
src = subproject('evol').get_variable('evolmod_subdir') + '/meson.build' src = subproject('evol').get_variable('evolmod_subdir') + '/meson.build'
dst = meson.current_source_dir() + '/import/' dst = meson.current_source_dir() + '/import/'
@@ -15,6 +15,7 @@ mod_src = [
# Loaders # Loaders
'src/loaders/TextLoader/TextLoader.c', 'src/loaders/TextLoader/TextLoader.c',
'src/loaders/JSONLoader/JSONLoader.c', 'src/loaders/JSONLoader/JSONLoader.c',
'src/loaders/ShaderLoader/ShaderLoader.c',
] ]
mod_incdir = [ mod_incdir = [
@@ -24,6 +25,9 @@ mod_incdir = [
mod_deps = [ mod_deps = [
evmod_deps, evmod_deps,
dependency('shaderc'),
dependency('threads'),
dependency('assetsys'), dependency('assetsys'),
dependency('evmod_ecs'), dependency('evmod_ecs'),
] ]

View File

@@ -23,3 +23,10 @@ EV_NS_DEF_BEGIN(JSONLoader)
EV_NS_DEF_FN(JSONAsset, loadAsset, (AssetHandle, handle)) EV_NS_DEF_FN(JSONAsset, loadAsset, (AssetHandle, handle))
EV_NS_DEF_END(JSONLoader) EV_NS_DEF_END(JSONLoader)
EV_NS_DEF_BEGIN(ShaderLoader)
EV_NS_DEF_FN(ShaderAsset, loadAsset, (AssetHandle, handle), (ShaderAssetStage, stage), (CONST_STR, shader_name), (CONST_STR, entrypoint), (CompiledShaderType, type))
EV_NS_DEF_END(ShaderLoader)

View File

@@ -9,3 +9,26 @@ TYPE(TextAsset, struct {
TYPE(JSONAsset, struct { TYPE(JSONAsset, struct {
PTR json_data; PTR json_data;
}) })
TYPE(ShaderAssetStage, enum {
EV_SHADERASSETSTAGE_VERTEX,
EV_SHADERASSETSTAGE_FRAGMENT,
EV_SHADERASSETSTAGE_COMPUTE,
EV_SHADERASSETSTAGE_GEOMETRY,
EV_SHADERASSETSTAGE_DETECT,
EV_SHADERASSETSTAGE_COUNT
})
TYPE(CompiledShaderType, enum {
EV_SHADER_ASM,
EV_SHADER_BIN
})
TYPE(ShaderAsset, struct {
PTR binary;
U64 len;
GenericHandle internal_handle;
CompiledShaderType type;
})

View File

@@ -0,0 +1,105 @@
#define TYPE_MODULE evmod_assets
#include <evol/meta/type_import.h>
#include <evol/common/ev_log.h>
#include "../LoaderCommon.h"
#include "ShaderLoader.h"
#include <shaderc/shaderc.h>
struct {
shaderc_compiler_t compiler;
shaderc_compile_options_t compile_options;
} ShaderLoaderData = {NULL,NULL};
void
ev_shaderloader_init()
{
ShaderLoaderData.compiler = shaderc_compiler_initialize();
ShaderLoaderData.compile_options = shaderc_compile_options_initialize();
}
void
ev_shaderloader_deinit()
{
shaderc_compile_options_release(ShaderLoaderData.compile_options);
shaderc_compiler_release(ShaderLoaderData.compiler);
}
shaderc_shader_kind
shader_kind_from_ShaderAssetStage(
ShaderAssetStage asset)
{
switch(asset) {
case EV_SHADERASSETSTAGE_VERTEX:
return shaderc_glsl_vertex_shader;
case EV_SHADERASSETSTAGE_FRAGMENT:
return shaderc_glsl_fragment_shader;
case EV_SHADERASSETSTAGE_COMPUTE:
return shaderc_glsl_compute_shader;
case EV_SHADERASSETSTAGE_GEOMETRY:
return shaderc_glsl_geometry_shader;
case EV_SHADERASSETSTAGE_DETECT:
return shaderc_glsl_infer_from_source;
default:
ev_log_warn("Invalid ShaderAssetStage. Trying to infer stage from source.");
return shaderc_glsl_infer_from_source;
}
}
typedef shaderc_compilation_result_t (*ShaderCompilationFn)();
ShaderAsset
ev_shaderloader_loadasset(
AssetHandle handle,
ShaderAssetStage stage,
CONST_STR shader_name,
CONST_STR entrypoint,
CompiledShaderType type)
{
const Asset *asset = ev_asset_getfromhandle(handle);
ShaderCompilationFn compilation_fn =
(type == EV_SHADER_BIN)
?(ShaderCompilationFn)shaderc_compile_into_spv:
(type == EV_SHADER_ASM)
?(ShaderCompilationFn)shaderc_compile_into_spv_assembly
:NULL;
shaderc_compilation_result_t result = compilation_fn(
ShaderLoaderData.compiler,
asset->data, asset->size,
shader_kind_from_ShaderAssetStage(stage),
shader_name, entrypoint?entrypoint:"main",
ShaderLoaderData.compile_options);
if(shaderc_result_get_compilation_status(result) != shaderc_compilation_status_success) {
if(shaderc_result_get_num_errors(result) > 0) {
ev_log_error(shaderc_result_get_error_message(result));
}
}
if(shaderc_result_get_num_warnings(result) > 0) {
ev_log_warn(shaderc_result_get_error_message(result));
}
ShaderAsset inter = (ShaderAsset) {
.binary = (PTR)shaderc_result_get_bytes(result),
.len = shaderc_result_get_length(result),
.internal_handle = (GenericHandle)result
};
ev_asset_markas(handle, LoaderData.assetType, &inter);
return inter;
}
void
ev_shaderloader_shaderasset_destr(
ShaderAsset shader)
{
shaderc_result_release((shaderc_compilation_result_t)shader.internal_handle);
}
void
ev_shaderloader_setassettype(
GenericHandle type)
{
LoaderData.assetType = type;
}

View File

@@ -0,0 +1,23 @@
#pragma once
void
ev_shaderloader_init();
void
ev_shaderloader_deinit();
ShaderAsset
ev_shaderloader_loadasset(
AssetHandle handle,
ShaderAssetStage stage,
CONST_STR shader_name,
CONST_STR entrypoint,
CompiledShaderType type);
void
ev_shaderloader_shaderasset_destr(
ShaderAsset shader);
void
ev_shaderloader_setassettype(
GenericHandle type);

View File

@@ -9,6 +9,7 @@
#include "loaders/LoaderCommon.h" #include "loaders/LoaderCommon.h"
#include "loaders/TextLoader/TextLoader.h" #include "loaders/TextLoader/TextLoader.h"
#include "loaders/JSONLoader/JSONLoader.h" #include "loaders/JSONLoader/JSONLoader.h"
#include "loaders/ShaderLoader/ShaderLoader.h"
#define AssetSysCheck(...) do { \ #define AssetSysCheck(...) do { \
assetsys_error_t res = __VA_ARGS__; \ assetsys_error_t res = __VA_ARGS__; \
@@ -31,7 +32,7 @@ onRemoveAssetComponent(
ECSQuery query) ECSQuery query)
{ {
Asset *assets = ECS->getQueryColumn(query, sizeof(Asset), 1); Asset *assets = ECS->getQueryColumn(query, sizeof(Asset), 1);
for(int i = 0; i < ECS->getQueryMatchCount(query); i++) { for(U32 i = 0; i < ECS->getQueryMatchCount(query); i++) {
aligned_free(assets[i].data); aligned_free(assets[i].data);
} }
} }
@@ -41,7 +42,7 @@ onRemoveTextAsset(
ECSQuery query) ECSQuery query)
{ {
TextAsset *assets = ECS->getQueryColumn(query, sizeof(TextAsset), 1); TextAsset *assets = ECS->getQueryColumn(query, sizeof(TextAsset), 1);
for(int i = 0; i < ECS->getQueryMatchCount(query); i++) { for(U32 i = 0; i < ECS->getQueryMatchCount(query); i++) {
ev_textloader_textasset_destr(assets[i]); ev_textloader_textasset_destr(assets[i]);
} }
} }
@@ -51,13 +52,24 @@ onRemoveJSONAsset(
ECSQuery query) ECSQuery query)
{ {
JSONAsset *assets = ECS->getQueryColumn(query, sizeof(JSONAsset), 1); JSONAsset *assets = ECS->getQueryColumn(query, sizeof(JSONAsset), 1);
for(int i = 0; i < ECS->getQueryMatchCount(query); i++) { for(U32 i = 0; i < ECS->getQueryMatchCount(query); i++) {
ev_jsonloader_jsonasset_destr(assets[i]); ev_jsonloader_jsonasset_destr(assets[i]);
} }
} }
void
onRemoveShaderAsset(
ECSQuery query)
{
ShaderAsset *assets = ECS->getQueryColumn(query, sizeof(ShaderAsset), 1);
for(U32 i = 0; i < ECS->getQueryMatchCount(query); i++) {
ev_shaderloader_shaderasset_destr(assets[i]);
}
}
EV_CONSTRUCTOR EV_CONSTRUCTOR
{ {
ev_log_trace("evmod_asset constructor");
static_assert(sizeof(AssetEntityID) == sizeof(AssetHandle), "AssetEntityID not the same size of AssetHandle"); static_assert(sizeof(AssetEntityID) == sizeof(AssetHandle), "AssetEntityID not the same size of AssetHandle");
AssetManagerData.sys = assetsys_create( 0 ); AssetManagerData.sys = assetsys_create( 0 );
@@ -76,9 +88,14 @@ EV_CONSTRUCTOR
ev_jsonloader_setassettype(AssetECS->registerComponent("JSONAsset", sizeof(JSONAsset), EV_ALIGNOF(JSONAsset))); ev_jsonloader_setassettype(AssetECS->registerComponent("JSONAsset", sizeof(JSONAsset), EV_ALIGNOF(JSONAsset)));
AssetECS->setOnRemoveTrigger("JSONAssetOnRemove", "JSONAsset", onRemoveJSONAsset); AssetECS->setOnRemoveTrigger("JSONAssetOnRemove", "JSONAsset", onRemoveJSONAsset);
ev_shaderloader_setassettype(AssetECS->registerComponent("ShaderAsset", sizeof(ShaderAsset), EV_ALIGNOF(ShaderAsset)));
AssetECS->setOnRemoveTrigger("ShaderAssetOnRemove", "ShaderAsset", onRemoveShaderAsset);
} }
} }
ev_shaderloader_init();
return AssetManagerData.sys == NULL; return AssetManagerData.sys == NULL;
} }
@@ -92,6 +109,8 @@ EV_DESTRUCTOR
if(AssetManagerData.ecs_mod) { if(AssetManagerData.ecs_mod) {
evol_unloadmodule(AssetManagerData.ecs_mod); evol_unloadmodule(AssetManagerData.ecs_mod);
} }
ev_shaderloader_deinit();
return 0; return 0;
} }
@@ -165,6 +184,7 @@ ev_asset_markas(
EV_BINDINGS EV_BINDINGS
{ {
ev_log_debug("Binding functions in evmod_asset");
EV_NS_BIND_FN(AssetManager, mount, ev_assetmanager_mount); EV_NS_BIND_FN(AssetManager, mount, ev_assetmanager_mount);
EV_NS_BIND_FN(Asset, load, ev_asset_load); EV_NS_BIND_FN(Asset, load, ev_asset_load);
@@ -175,5 +195,7 @@ EV_BINDINGS
EV_NS_BIND_FN(JSONLoader, loadAsset, ev_jsonloader_loadasset); EV_NS_BIND_FN(JSONLoader, loadAsset, ev_jsonloader_loadasset);
EV_NS_BIND_FN(ShaderLoader, loadAsset, ev_shaderloader_loadasset);
return 0; return 0;
} }

View File

@@ -0,0 +1,13 @@
project('libshaderc', 'cpp')
fs = import('fs')
cxxc = meson.get_compiler('cpp')
shaderc_inc = include_directories('install/include')
shaderc_dep = declare_dependency(
dependencies: cxxc.find_library('shaderc_combined', dirs: meson.current_source_dir()/'install/lib'),
include_directories: shaderc_inc,
)
meson.override_dependency('shaderc', shaderc_dep)

12
subprojects/shaderc.wrap Normal file
View File

@@ -0,0 +1,12 @@
[wrap-file]
directory = libshaderc
source_url = https://storage.googleapis.com/shaderc/artifacts/prod/graphics_shader_compiler/shaderc/linux/continuous_clang_release/364/20210607-072233/install.tgz
source_filename = libshaderc-upstream.tgz
source_hash = f46dd35f6904af2b3330201ffb0f2f1ef5f8b8ede44491fad1a37b4a791772ef
lead_directory_missing = libshaderc
patch_directory = libshaderc
[provide]
dependency_names = shaderc