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:
parent
7475f7b0de
commit
9bbfade772
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue