GPUShader: Cleanup dependency system to not remove string allocation

Source files are now only referenced and listed for the driver to ingest.
Shader sources now includes generated data if any.
Also cleans up gpu_shader_dependency_get_builtins casts.
This commit is contained in:
2022-02-04 20:06:36 +01:00
parent ae50527c23
commit 671fb286ab
4 changed files with 89 additions and 81 deletions

View File

@@ -301,20 +301,22 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
std::string defines = shader->defines_declare(info);
std::string resources = shader->resources_declare(info);
char *shader_shared_utils = nullptr;
defines += "#define USE_GPU_SHADER_CREATE_INFO\n";
Vector<char *> typedefs;
for (auto filename : info.typedef_sources_) {
typedefs.append(gpu_shader_dependency_get_source(filename.c_str()));
Vector<const char *> typedefs;
if (!info.typedef_sources_.is_empty() || !info.typedef_source_generated.empty()) {
typedefs.append(gpu_shader_dependency_get_source("gpu_shader_shared_utils.h").c_str());
}
if (!typedefs.is_empty()) {
shader_shared_utils = gpu_shader_dependency_get_source("gpu_shader_shared_utils.h");
if (!info.typedef_source_generated.empty()) {
typedefs.append(info.typedef_source_generated.c_str());
}
for (auto filename : info.typedef_sources_) {
typedefs.append(gpu_shader_dependency_get_source(filename).c_str());
}
if (!info.vertex_source_.is_empty()) {
char *code = gpu_shader_dependency_get_resolved_source(info.vertex_source_.c_str());
auto code = gpu_shader_dependency_get_resolved_source(info.vertex_source_);
std::string interface = shader->vertex_interface_declare(info);
Vector<const char *> sources;
@@ -324,23 +326,18 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
sources.append("#define USE_GEOMETRY_SHADER\n");
}
sources.append(defines.c_str());
if (!typedefs.is_empty()) {
sources.append(shader_shared_utils);
}
for (auto *types : typedefs) {
sources.append(types);
}
sources.extend(typedefs);
sources.append(resources.c_str());
sources.append(interface.c_str());
sources.append(code);
sources.extend(code);
sources.extend(info.dependencies_generated);
sources.append(info.vertex_source_generated.c_str());
shader->vertex_shader_from_glsl(sources);
free(code);
}
if (!info.fragment_source_.is_empty()) {
char *code = gpu_shader_dependency_get_resolved_source(info.fragment_source_.c_str());
auto code = gpu_shader_dependency_get_resolved_source(info.fragment_source_);
std::string interface = shader->fragment_interface_declare(info);
Vector<const char *> sources;
@@ -350,23 +347,18 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
sources.append("#define USE_GEOMETRY_SHADER\n");
}
sources.append(defines.c_str());
if (!typedefs.is_empty()) {
sources.append(shader_shared_utils);
}
for (auto *types : typedefs) {
sources.append(types);
}
sources.extend(typedefs);
sources.append(resources.c_str());
sources.append(interface.c_str());
sources.append(code);
sources.extend(code);
sources.extend(info.dependencies_generated);
sources.append(info.fragment_source_generated.c_str());
shader->fragment_shader_from_glsl(sources);
free(code);
}
if (!info.geometry_source_.is_empty()) {
char *code = gpu_shader_dependency_get_resolved_source(info.geometry_source_.c_str());
auto code = gpu_shader_dependency_get_resolved_source(info.geometry_source_);
std::string layout = shader->geometry_layout_declare(info);
std::string interface = shader->geometry_interface_declare(info);
@@ -374,51 +366,29 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
standard_defines(sources);
sources.append("#define GPU_GEOMETRY_SHADER\n");
sources.append(defines.c_str());
if (!typedefs.is_empty()) {
sources.append(shader_shared_utils);
}
for (auto *types : typedefs) {
sources.append(types);
}
sources.extend(typedefs);
sources.append(resources.c_str());
sources.append(layout.c_str());
sources.append(interface.c_str());
sources.append(code);
sources.extend(code);
shader->geometry_shader_from_glsl(sources);
free(code);
}
if (!info.compute_source_.is_empty()) {
char *code = gpu_shader_dependency_get_resolved_source(info.compute_source_.c_str());
auto code = gpu_shader_dependency_get_resolved_source(info.compute_source_);
std::string layout = shader->compute_layout_declare(info);
Vector<const char *> sources;
standard_defines(sources);
sources.append("#define GPU_COMPUTE_SHADER\n");
sources.append(defines.c_str());
if (!typedefs.is_empty()) {
sources.append(shader_shared_utils);
}
for (auto *types : typedefs) {
sources.append(types);
}
sources.extend(typedefs);
sources.append(resources.c_str());
sources.append(layout.c_str());
sources.append(code);
sources.extend(code);
shader->compute_shader_from_glsl(sources);
free(code);
}
for (auto *types : typedefs) {
free(types);
}
if (shader_shared_utils) {
free(shader_shared_utils);
}
if (!shader->finalize(&info)) {

View File

@@ -242,14 +242,10 @@ void gpu_shader_create_info_init()
for (ShaderCreateInfo *info : g_create_infos->values()) {
if (info->do_static_compilation_) {
info->builtins_ |= static_cast<BuiltinBits>(
gpu_shader_dependency_get_builtins(info->vertex_source_.c_str()));
info->builtins_ |= static_cast<BuiltinBits>(
gpu_shader_dependency_get_builtins(info->fragment_source_.c_str()));
info->builtins_ |= static_cast<BuiltinBits>(
gpu_shader_dependency_get_builtins(info->geometry_source_.c_str()));
info->builtins_ |= static_cast<BuiltinBits>(
gpu_shader_dependency_get_builtins(info->compute_source_.c_str()));
info->builtins_ |= gpu_shader_dependency_get_builtins(info->vertex_source_);
info->builtins_ |= gpu_shader_dependency_get_builtins(info->fragment_source_);
info->builtins_ |= gpu_shader_dependency_get_builtins(info->geometry_source_);
info->builtins_ |= gpu_shader_dependency_get_builtins(info->compute_source_);
}
}

View File

@@ -332,14 +332,12 @@ struct GPUSource {
}
/* Returns the final string with all includes done. */
std::string build() const
void build(Vector<const char *> &result) const
{
std::string str;
for (auto *dep : dependencies) {
str += dep->source;
result.append(dep->source.c_str());
}
str += source;
return str;
result.append(source.c_str());
}
shader::BuiltinBits builtins_get() const
@@ -383,23 +381,47 @@ void gpu_shader_dependency_exit()
delete g_sources;
}
uint32_t gpu_shader_dependency_get_builtins(const char *shader_source_name)
namespace blender::gpu::shader {
BuiltinBits gpu_shader_dependency_get_builtins(const StringRefNull shader_source_name)
{
if (shader_source_name[0] == '\0') {
return 0;
if (shader_source_name.is_empty()) {
return shader::BuiltinBits::NONE;
}
if (g_sources->contains(shader_source_name) == false) {
std::cout << "Error: Could not find \"" << shader_source_name
<< "\" in the list of registered source.\n";
BLI_assert(0);
return shader::BuiltinBits::NONE;
}
GPUSource *source = g_sources->lookup(shader_source_name);
return static_cast<uint32_t>(source->builtins_get());
return source->builtins_get();
}
char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name)
Vector<const char *> gpu_shader_dependency_get_resolved_source(
const StringRefNull shader_source_name)
{
Vector<const char *> result;
GPUSource *source = g_sources->lookup(shader_source_name);
return strdup(source->build().c_str());
source->build(result);
return result;
}
char *gpu_shader_dependency_get_source(const char *shader_source_name)
StringRefNull gpu_shader_dependency_get_source(const StringRefNull shader_source_name)
{
GPUSource *src = g_sources->lookup(shader_source_name);
return strdup(src->source.c_str());
return src->source;
}
StringRefNull gpu_shader_dependency_get_filename_from_source_string(
const StringRefNull source_string)
{
for (auto &source : g_sources->values()) {
if (source->source.c_str() == source_string.c_str()) {
return source->filename;
}
}
return "";
}
} // namespace blender::gpu::shader

View File

@@ -34,12 +34,32 @@ void gpu_shader_dependency_init(void);
void gpu_shader_dependency_exit(void);
/* User must free the resulting string using free. */
char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name);
char *gpu_shader_dependency_get_source(const char *shader_source_name);
uint32_t gpu_shader_dependency_get_builtins(const char *shader_source_name);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
# include "BLI_string_ref.hh"
# include "BLI_vector.hh"
# include "gpu_shader_create_info.hh"
namespace blender::gpu::shader {
BuiltinBits gpu_shader_dependency_get_builtins(const StringRefNull source_name);
Vector<const char *> gpu_shader_dependency_get_resolved_source(const StringRefNull source_name);
StringRefNull gpu_shader_dependency_get_source(const StringRefNull source_name);
/**
* \brief Find the name of the file from which the given string was generated.
* \return Return filename or empty string.
* \note source_string needs to be identical to the one given by gpu_shader_dependency_get_source()
*/
StringRefNull gpu_shader_dependency_get_filename_from_source_string(
const StringRefNull source_string);
} // namespace blender::gpu::shader
#endif