GPUShader: Improve builtins support in GPUShaderCreateInfo

- Scan all static shaders for builtins on startup.
- Add possibility to manually add builtins.
- `ShaderCreateInfo.builtins_` contain builtins from all stages.
This commit is contained in:
Clément Foucault 2022-02-01 13:45:54 +01:00
parent 7475f7b0de
commit 9bbfade772
5 changed files with 58 additions and 26 deletions

View File

@ -314,9 +314,8 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
}
if (!info.vertex_source_.is_empty()) {
uint32_t builtins = 0;
char *code = gpu_shader_dependency_get_resolved_source(info.vertex_source_.c_str());
std::string interface = shader->vertex_interface_declare(info);
char *code = gpu_shader_dependency_get_resolved_source(info.vertex_source_.c_str(), &builtins);
Vector<const char *> sources;
standard_defines(sources);
@ -341,10 +340,8 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
}
if (!info.fragment_source_.is_empty()) {
uint32_t builtins = 0;
char *code = gpu_shader_dependency_get_resolved_source(info.fragment_source_.c_str());
std::string interface = shader->fragment_interface_declare(info);
char *code = gpu_shader_dependency_get_resolved_source(info.fragment_source_.c_str(),
&builtins);
Vector<const char *> sources;
standard_defines(sources);
@ -369,11 +366,9 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
}
if (!info.geometry_source_.is_empty()) {
uint32_t builtins = 0;
std::string interface = shader->geometry_interface_declare(info);
char *code = gpu_shader_dependency_get_resolved_source(info.geometry_source_.c_str());
std::string layout = shader->geometry_layout_declare(info);
char *code = gpu_shader_dependency_get_resolved_source(info.geometry_source_.c_str(),
&builtins);
std::string interface = shader->geometry_interface_declare(info);
Vector<const char *> sources;
standard_defines(sources);
@ -396,9 +391,7 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
}
if (!info.compute_source_.is_empty()) {
uint32_t builtins = 0;
char *code = gpu_shader_dependency_get_resolved_source(info.compute_source_.c_str(),
&builtins);
char *code = gpu_shader_dependency_get_resolved_source(info.compute_source_.c_str());
std::string layout = shader->compute_layout_declare(info);
Vector<const char *> sources;

View File

@ -34,6 +34,7 @@
#include "gpu_shader_create_info.hh"
#include "gpu_shader_create_info_private.hh"
#include "gpu_shader_dependency_private.h"
#include "gpu_shader_private.hh"
#undef GPU_SHADER_INTERFACE_INFO
@ -209,6 +210,19 @@ void gpu_shader_create_info_init()
draw_modelmat = draw_modelmat_legacy;
}
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()));
}
}
/* TEST */
// gpu_shader_create_info_compile_all();
}

View File

@ -63,6 +63,7 @@ enum class Type {
};
enum class BuiltinBits {
NONE = 0,
/**
* Allow getting barycentric coordinates inside the fragment shader.
* \note Emulated on OpenGL.
@ -72,6 +73,10 @@ enum class BuiltinBits {
FRONT_FACING = (1 << 4),
GLOBAL_INVOCATION_ID = (1 << 5),
INSTANCE_ID = (1 << 6),
/**
* Allow setting the target layer when the output is a layered framebuffer.
* \note Emulated through geometry shader on older hardware.
*/
LAYER = (1 << 7),
LOCAL_INVOCATION_ID = (1 << 8),
LOCAL_INVOCATION_INDEX = (1 << 9),
@ -226,6 +231,8 @@ struct ShaderCreateInfo {
* Only for names used by gpu::ShaderInterface.
*/
size_t interface_names_size_ = 0;
/** Manually set builtins. */
BuiltinBits builtins_ = BuiltinBits::NONE;
struct VertIn {
int index;
@ -538,6 +545,12 @@ struct ShaderCreateInfo {
return *(Self *)this;
}
Self &builtins(BuiltinBits builtin)
{
builtins_ |= builtin;
return *(Self *)this;
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -59,7 +59,6 @@ struct GPUSource {
/* Scan for builtins. */
/* FIXME: This can trigger false positive caused by disabled #if blocks. */
/* TODO(fclem): Could be made faster by scanning once. */
/* TODO(fclem): BARYCENTRIC_COORD. */
if (source.find("gl_FragCoord", 0)) {
builtins |= shader::BuiltinBits::FRAG_COORD;
}
@ -72,9 +71,6 @@ struct GPUSource {
if (source.find("gl_InstanceID", 0)) {
builtins |= shader::BuiltinBits::INSTANCE_ID;
}
if (source.find("gl_Layer", 0)) {
builtins |= shader::BuiltinBits::LAYER;
}
if (source.find("gl_LocalInvocationID", 0)) {
builtins |= shader::BuiltinBits::LOCAL_INVOCATION_ID;
}
@ -336,13 +332,23 @@ struct GPUSource {
}
/* Returns the final string with all includes done. */
void build(std::string &str, shader::BuiltinBits &out_builtins)
std::string build() const
{
std::string str;
for (auto *dep : dependencies) {
out_builtins |= builtins;
str += dep->source;
}
str += source;
return str;
}
shader::BuiltinBits builtins_get() const
{
shader::BuiltinBits out_builtins = shader::BuiltinBits::NONE;
for (auto *dep : dependencies) {
out_builtins |= dep->builtins;
}
return out_builtins;
}
};
@ -377,14 +383,19 @@ void gpu_shader_dependency_exit()
delete g_sources;
}
char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name, uint32_t *builtins)
uint32_t gpu_shader_dependency_get_builtins(const char *shader_source_name)
{
if (shader_source_name[0] == '\0') {
return 0;
}
GPUSource *source = g_sources->lookup(shader_source_name);
return static_cast<uint32_t>(source->builtins_get());
}
char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name)
{
GPUSource *source = g_sources->lookup(shader_source_name);
std::string str;
shader::BuiltinBits out_builtins;
source->build(str, out_builtins);
*builtins |= (uint32_t)out_builtins;
return strdup(str.c_str());
return strdup(source->build().c_str());
}
char *gpu_shader_dependency_get_source(const char *shader_source_name)

View File

@ -35,10 +35,11 @@ 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,
uint32_t *builtins);
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