mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-10-20 13:04:54 -04:00
finish up GLSL conversion stuff and make some minor tweaks to shader parser
This commit is contained in:
1 parent
f9d1a4b9ed
commit
34357f00fb
6 files changed
+305
-38
No files matched your search
@@ -14,9 +14,8 @@ What's the goal of rewriting OBS?
|
||||
necessary for user interface. It also means allowing the use of OpenGL as
|
||||
well as Direct3D.
|
||||
|
||||
- Separate the application from the core, allowing custom user interfaces and
|
||||
custom appliction of the core if desired, and easier extending of the user
|
||||
interface.
|
||||
- Separate the application from the core, allowing custom custom appliction of
|
||||
the core if desired, and easier extending of the user interface.
|
||||
|
||||
- Simplify complex systems to not only make it easier to use, but easier to
|
||||
maintain.
|
||||
|
||||
+296
-24
@@ -18,7 +18,10 @@
|
||||
#include "gl-subsystem.h"
|
||||
#include "gl-shaderparser.h"
|
||||
|
||||
static void gl_write_type_n(struct gl_shader_parser *glsp,
|
||||
static void gl_write_function_contents(struct gl_shader_parser *glsp,
|
||||
struct cf_token **p_token, const char *end);
|
||||
|
||||
static bool gl_write_type_n(struct gl_shader_parser *glsp,
|
||||
const char *type, size_t len)
|
||||
{
|
||||
if (astrcmp_n(type, "float2", len) == 0)
|
||||
@@ -40,19 +43,22 @@ static void gl_write_type_n(struct gl_shader_parser *glsp,
|
||||
else if (astrcmp_n(type, "texture_cube", len) == 0)
|
||||
dstr_cat(&glsp->gl_string, "samplerCube");
|
||||
else
|
||||
dstr_ncat(&glsp->gl_string, type, len);
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void gl_write_type(struct gl_shader_parser *glsp,
|
||||
const char *type)
|
||||
{
|
||||
gl_write_type_n(glsp, type, strlen(type));
|
||||
if (!gl_write_type_n(glsp, type, strlen(type)))
|
||||
dstr_cat(&glsp->gl_string, type);
|
||||
}
|
||||
|
||||
static inline void gl_write_type_token(struct gl_shader_parser *glsp,
|
||||
static inline bool gl_write_type_token(struct gl_shader_parser *glsp,
|
||||
struct cf_token *token)
|
||||
{
|
||||
gl_write_type_n(glsp, token->str.array, token->str.len);
|
||||
return gl_write_type_n(glsp, token->str.array, token->str.len);
|
||||
}
|
||||
|
||||
static void gl_write_var(struct gl_shader_parser *glsp, struct shader_var *var)
|
||||
@@ -65,7 +71,6 @@ static void gl_write_var(struct gl_shader_parser *glsp, struct shader_var *var)
|
||||
gl_write_type(glsp, var->type);
|
||||
dstr_cat(&glsp->gl_string, " ");
|
||||
dstr_cat(&glsp->gl_string, var->name);
|
||||
dstr_cat(&glsp->gl_string, ";\n");
|
||||
}
|
||||
|
||||
static inline void gl_write_params(struct gl_shader_parser *glsp)
|
||||
@@ -74,6 +79,7 @@ static inline void gl_write_params(struct gl_shader_parser *glsp)
|
||||
for (i = 0; i < glsp->parser.params.num; i++) {
|
||||
struct shader_var *var = glsp->parser.params.array+i;
|
||||
gl_write_var(glsp, var);
|
||||
dstr_cat(&glsp->gl_string, ";\n");
|
||||
}
|
||||
|
||||
dstr_cat(&glsp->gl_string, "\n");
|
||||
@@ -85,7 +91,7 @@ static void gl_write_storage_var(struct gl_shader_parser *glsp,
|
||||
|
||||
/* unwraps a structure that's used for input/output */
|
||||
static void gl_unwrap_storage_struct(struct gl_shader_parser *glsp,
|
||||
struct shader_struct *st, const char *storage,
|
||||
struct shader_struct *st, const char *name, const char *storage,
|
||||
const char *prefix)
|
||||
{
|
||||
struct dstr prefix_str;
|
||||
@@ -94,7 +100,7 @@ static void gl_unwrap_storage_struct(struct gl_shader_parser *glsp,
|
||||
dstr_init(&prefix_str);
|
||||
if (prefix)
|
||||
dstr_copy(&prefix_str, prefix);
|
||||
dstr_cat(&prefix_str, st->name);
|
||||
dstr_cat(&prefix_str, name);
|
||||
dstr_cat(&prefix_str, "_");
|
||||
|
||||
for (i = 0; i < st->vars.num; i++) {
|
||||
@@ -112,7 +118,7 @@ static void gl_write_storage_var(struct gl_shader_parser *glsp,
|
||||
var->type);
|
||||
|
||||
if (st) {
|
||||
gl_unwrap_storage_struct(glsp, st, storage, prefix);
|
||||
gl_unwrap_storage_struct(glsp, st, var->name, storage, prefix);
|
||||
} else {
|
||||
if (storage) {
|
||||
dstr_cat(&glsp->gl_string, storage);
|
||||
@@ -132,25 +138,23 @@ static inline void gl_write_inputs(struct gl_shader_parser *glsp,
|
||||
struct shader_func *main)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < main->params.num; i++) {
|
||||
struct shader_var *var = main->params.array+i;
|
||||
gl_write_storage_var(glsp, var, "in", "in_");
|
||||
}
|
||||
for (i = 0; i < main->params.num; i++)
|
||||
gl_write_storage_var(glsp, main->params.array+i, "in",
|
||||
"inputval_");
|
||||
dstr_cat(&glsp->gl_string, "\n");
|
||||
}
|
||||
|
||||
static void gl_write_outputs(struct gl_shader_parser *glsp,
|
||||
struct shader_func *main)
|
||||
{
|
||||
struct shader_var var;
|
||||
struct shader_var var = {0};
|
||||
var.type = main->return_type;
|
||||
var.name = "outputval";
|
||||
if (main->mapping)
|
||||
var.mapping = main->mapping;
|
||||
|
||||
shader_var_init(&var);
|
||||
var.type = bstrdup(main->return_type);
|
||||
var.name = bstrdup("return_val");
|
||||
if (main->return_mapping)
|
||||
var.mapping = bstrdup(main->return_mapping);
|
||||
|
||||
gl_write_storage_var(glsp, &var, "out", "out_");
|
||||
shader_var_free(&var);
|
||||
gl_write_storage_var(glsp, &var, "out", NULL);
|
||||
dstr_cat(&glsp->gl_string, "\n");
|
||||
}
|
||||
|
||||
static void gl_write_struct(struct gl_shader_parser *glsp,
|
||||
@@ -166,6 +170,7 @@ static void gl_write_struct(struct gl_shader_parser *glsp,
|
||||
|
||||
dstr_cat(&glsp->gl_string, "\t");
|
||||
gl_write_var(glsp, var);
|
||||
dstr_cat(&glsp->gl_string, ";\n");
|
||||
}
|
||||
|
||||
dstr_cat(&glsp->gl_string, "};\n\n");
|
||||
@@ -203,8 +208,272 @@ static inline void gl_write_structs(struct gl_shader_parser *glsp)
|
||||
* All else can be left as-is
|
||||
*/
|
||||
|
||||
static void gl_write_functions(struct gl_shader_parser *glsp)
|
||||
static inline bool gl_write_texture_call(struct gl_shader_parser *glsp,
|
||||
struct shader_var *var, const char *call)
|
||||
{
|
||||
struct cf_parser *cfp = &glsp->parser.cfp;
|
||||
if (!go_to_token(cfp, ",", NULL))
|
||||
return false;
|
||||
|
||||
dstr_cat(&glsp->gl_string, call);
|
||||
dstr_cat(&glsp->gl_string, "(");
|
||||
dstr_cat(&glsp->gl_string, var->name);
|
||||
dstr_cat(&glsp->gl_string, ", ");
|
||||
return true;
|
||||
}
|
||||
|
||||
/* processes texture.Sample(sampler, texcoord) */
|
||||
static bool gl_write_texture_code(struct gl_shader_parser *glsp,
|
||||
struct cf_token **p_token, struct shader_var *var)
|
||||
{
|
||||
struct cf_parser *cfp = &glsp->parser.cfp;
|
||||
bool written = false;
|
||||
cfp->cur_token = *p_token;
|
||||
|
||||
if (!next_token(cfp)) return false;
|
||||
if (!token_is(cfp, ".")) return false;
|
||||
if (!next_token(cfp)) return false;
|
||||
|
||||
if (token_is(cfp, "Sample"))
|
||||
written = gl_write_texture_call(glsp, var, "texture");
|
||||
else if (token_is(cfp, "SampleBias"))
|
||||
written = gl_write_texture_call(glsp, var, "texture");
|
||||
else if (token_is(cfp, "SampleGrad"))
|
||||
written = gl_write_texture_call(glsp, var, "textureGrad");
|
||||
else if (token_is(cfp, "SampleLevel"))
|
||||
written = gl_write_texture_call(glsp, var, "textureLod");
|
||||
|
||||
if (!written)
|
||||
return false;
|
||||
|
||||
if (!next_token(cfp)) return false;
|
||||
|
||||
gl_write_function_contents(glsp, &cfp->cur_token, ")");
|
||||
dstr_cat(&glsp->gl_string, ")");
|
||||
|
||||
*p_token = cfp->cur_token;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline struct shader_var *sp_getparam(struct gl_shader_parser *glsp,
|
||||
struct cf_token *token)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < glsp->parser.params.num; i++) {
|
||||
struct shader_var *param = glsp->parser.params.array+i;
|
||||
if (strref_cmp(&token->str, param->name) == 0)
|
||||
return param;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool gl_write_intrinsic(struct gl_shader_parser *glsp,
|
||||
struct cf_token **p_token)
|
||||
{
|
||||
struct cf_token *token = *p_token;
|
||||
bool written = true;
|
||||
|
||||
if (strref_cmp(&token->str, "atan2") == 0) {
|
||||
dstr_cat(&glsp->gl_string, "atan2");
|
||||
} else if (strref_cmp(&token->str, "ddx") == 0) {
|
||||
dstr_cat(&glsp->gl_string, "dFdx");
|
||||
} else if (strref_cmp(&token->str, "ddy") == 0) {
|
||||
dstr_cat(&glsp->gl_string, "dFdy");
|
||||
} else if (strref_cmp(&token->str, "frac") == 0) {
|
||||
dstr_cat(&glsp->gl_string, "fract");
|
||||
} else if (strref_cmp(&token->str, "lerp") == 0) {
|
||||
dstr_cat(&glsp->gl_string, "mix");
|
||||
} else if (strref_cmp(&token->str, "rsqrt") == 0) {
|
||||
dstr_cat(&glsp->gl_string, "inversesqrt");
|
||||
} else {
|
||||
struct shader_var *var = sp_getparam(glsp, token);
|
||||
if (var && astrcmp_n(var->type, "texture", 7) == 0)
|
||||
written = gl_write_texture_code(glsp, &token, var);
|
||||
else
|
||||
written = false;
|
||||
}
|
||||
|
||||
if (written)
|
||||
*p_token = token;
|
||||
return written;
|
||||
}
|
||||
|
||||
static void gl_write_function_contents(struct gl_shader_parser *glsp,
|
||||
struct cf_token **p_token, const char *end)
|
||||
{
|
||||
struct cf_token *token = *p_token;
|
||||
|
||||
dstr_cat_strref(&glsp->gl_string, &token->str);
|
||||
|
||||
while (token->type != CFTOKEN_NONE) {
|
||||
token++;
|
||||
|
||||
if (end && strref_cmp(&token->str, end) == 0)
|
||||
break;
|
||||
|
||||
if (token->type == CFTOKEN_NAME) {
|
||||
if (!gl_write_type_token(glsp, token) &&
|
||||
!gl_write_intrinsic(glsp, &token))
|
||||
dstr_cat_strref(&glsp->gl_string, &token->str);
|
||||
|
||||
} else if (token->type == CFTOKEN_OTHER) {
|
||||
if (*token->str.array == '{')
|
||||
gl_write_function_contents(glsp, &token, "}");
|
||||
else if (*token->str.array == '(')
|
||||
gl_write_function_contents(glsp, &token, ")");
|
||||
|
||||
dstr_cat_strref(&glsp->gl_string, &token->str);
|
||||
|
||||
} else {
|
||||
dstr_cat_strref(&glsp->gl_string, &token->str);
|
||||
}
|
||||
}
|
||||
|
||||
*p_token = token;
|
||||
}
|
||||
|
||||
static void gl_write_function(struct gl_shader_parser *glsp,
|
||||
struct shader_func *func)
|
||||
{
|
||||
size_t i;
|
||||
struct cf_token *token;
|
||||
|
||||
gl_write_type(glsp, func->return_type);
|
||||
dstr_cat(&glsp->gl_string, " ");
|
||||
|
||||
if (strcmp(func->name, "main") == 0)
|
||||
dstr_cat(&glsp->gl_string, "__main__");
|
||||
else
|
||||
dstr_cat(&glsp->gl_string, func->name);
|
||||
|
||||
dstr_cat(&glsp->gl_string, "(");
|
||||
|
||||
for (i = 0; i < func->params.num; i++) {
|
||||
struct shader_var *param = func->params.array+i;
|
||||
|
||||
if (i > 0)
|
||||
dstr_cat(&glsp->gl_string, ", ");
|
||||
gl_write_var(glsp, param);
|
||||
}
|
||||
|
||||
dstr_cat(&glsp->gl_string, ")\n");
|
||||
|
||||
token = func->start;
|
||||
gl_write_function_contents(glsp, &token, "}");
|
||||
dstr_cat(&glsp->gl_string, "}\n\n");
|
||||
}
|
||||
|
||||
static inline void gl_write_functions(struct gl_shader_parser *glsp)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < glsp->parser.funcs.num; i++) {
|
||||
struct shader_func *func = glsp->parser.funcs.array+i;
|
||||
gl_write_function(glsp, func);
|
||||
}
|
||||
}
|
||||
|
||||
static void gl_write_main_storage_var(struct gl_shader_parser *glsp,
|
||||
struct shader_var *var, const char *dst, const char *src,
|
||||
bool input)
|
||||
{
|
||||
struct shader_struct *st;
|
||||
struct dstr dst_copy = {0};
|
||||
char ch_left = input ? '.' : '_';
|
||||
char ch_right = input ? '_' : '.';
|
||||
|
||||
if (dst) {
|
||||
dstr_copy(&dst_copy, dst);
|
||||
dstr_cat_ch(&dst_copy, ch_left);
|
||||
} else {
|
||||
dstr_copy(&dst_copy, "\t");
|
||||
}
|
||||
|
||||
dstr_cat(&dst_copy, var->name);
|
||||
|
||||
st = shader_parser_getstruct(&glsp->parser, var->type);
|
||||
if (st) {
|
||||
struct dstr src_copy = {0};
|
||||
size_t i;
|
||||
|
||||
if (src)
|
||||
dstr_copy(&src_copy, src);
|
||||
dstr_cat(&src_copy, var->name);
|
||||
dstr_cat_ch(&src_copy, ch_right);
|
||||
|
||||
for (i = 0; i < st->vars.num; i++) {
|
||||
struct shader_var *var = st->vars.array+i;
|
||||
gl_write_main_storage_var(glsp, var, dst_copy.array,
|
||||
src_copy.array, input);
|
||||
}
|
||||
|
||||
dstr_free(&src_copy);
|
||||
} else {
|
||||
if (!dstr_isempty(&dst_copy))
|
||||
dstr_cat_dstr(&glsp->gl_string, &dst_copy);
|
||||
dstr_cat(&glsp->gl_string, " = ");
|
||||
if (src)
|
||||
dstr_cat(&glsp->gl_string, src);
|
||||
dstr_cat(&glsp->gl_string, var->name);
|
||||
dstr_cat(&glsp->gl_string, ";\n");
|
||||
}
|
||||
|
||||
dstr_free(&dst_copy);
|
||||
}
|
||||
|
||||
static void gl_write_main_storage_output(struct gl_shader_parser *glsp,
|
||||
bool input, const char *type)
|
||||
{
|
||||
struct shader_var var = {0};
|
||||
|
||||
if (input) {
|
||||
var.name = "inputval";
|
||||
var.type = (char*)type;
|
||||
gl_write_main_storage_var(glsp, &var, NULL, NULL, true);
|
||||
} else {
|
||||
var.name = "outputval";
|
||||
var.type = (char*)type;
|
||||
gl_write_main_storage_var(glsp, &var, NULL, NULL, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void gl_write_main(struct gl_shader_parser *glsp,
|
||||
struct shader_func *main)
|
||||
{
|
||||
size_t i;
|
||||
dstr_cat(&glsp->gl_string, "void main(void)\n{\n");
|
||||
for (i = 0; i < main->params.num; i++) {
|
||||
dstr_cat(&glsp->gl_string, "\t");
|
||||
dstr_cat(&glsp->gl_string, main->params.array[i].type);
|
||||
dstr_cat(&glsp->gl_string, " ");
|
||||
dstr_cat(&glsp->gl_string, main->params.array[i].name);
|
||||
dstr_cat(&glsp->gl_string, "\n");
|
||||
}
|
||||
|
||||
if (!main->mapping) {
|
||||
dstr_cat(&glsp->gl_string, "\t");
|
||||
dstr_cat(&glsp->gl_string, main->return_type);
|
||||
dstr_cat(&glsp->gl_string, " outputval;\n\n");
|
||||
}
|
||||
|
||||
/* gl_write_main_storage(glsp, true, main->params.array[0].type); */
|
||||
gl_write_main_storage_var(glsp, main->params.array, NULL,
|
||||
"inputval_", true);
|
||||
|
||||
dstr_cat(&glsp->gl_string, "\n\toutputval = __main__(");
|
||||
for (i = 0; i < main->params.num; i++) {
|
||||
if (i)
|
||||
dstr_cat(&glsp->gl_string, ", ");
|
||||
dstr_cat(&glsp->gl_string, main->params.array[i].name);
|
||||
}
|
||||
dstr_cat(&glsp->gl_string, ");\n");
|
||||
|
||||
if (!main->mapping) {
|
||||
dstr_cat(&glsp->gl_string, "\n");
|
||||
gl_write_main_storage_output(glsp, false, main->return_type);
|
||||
}
|
||||
|
||||
dstr_cat(&glsp->gl_string, "}\n");
|
||||
}
|
||||
|
||||
static bool gl_shader_buildstring(struct gl_shader_parser *glsp)
|
||||
@@ -221,7 +490,7 @@ static bool gl_shader_buildstring(struct gl_shader_parser *glsp)
|
||||
gl_write_outputs(glsp, main);
|
||||
gl_write_structs(glsp);
|
||||
gl_write_functions(glsp);
|
||||
// gl_write_main(glsp);
|
||||
gl_write_main(glsp, main);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -236,5 +505,8 @@ bool gl_shader_parse(struct gl_shader_parser *glsp,
|
||||
bfree(str);
|
||||
}
|
||||
|
||||
if (success)
|
||||
success = gl_shader_buildstring(glsp);
|
||||
|
||||
return success;
|
||||
}
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
struct gl_shader_parser {
|
||||
struct dstr gl_string;
|
||||
struct dstr gl_main_func;
|
||||
struct shader_parser parser;
|
||||
};
|
||||
|
||||
|
||||
@@ -971,8 +971,6 @@ static inline void ep_write_param(struct dstr *shader, struct ep_param *param,
|
||||
struct dstr new;
|
||||
dstr_init_copy(&new, param->name);
|
||||
darray_push_back(sizeof(struct dstr), used_params, &new);
|
||||
|
||||
dstr_cat(shader, "uniform ");
|
||||
}
|
||||
|
||||
dstr_cat(shader, param->type);
|
||||
|
||||
@@ -304,8 +304,7 @@ error:
|
||||
static inline int sp_check_for_keyword(struct shader_parser *sp,
|
||||
const char *keyword, bool *val)
|
||||
{
|
||||
bool new_val;
|
||||
new_val = token_is(&sp->cfp, keyword);
|
||||
bool new_val = token_is(&sp->cfp, keyword);
|
||||
if (new_val) {
|
||||
if (!next_valid_token(&sp->cfp))
|
||||
return PARSE_EOF;
|
||||
@@ -325,7 +324,7 @@ static inline int sp_parse_func_param(struct shader_parser *sp,
|
||||
struct shader_func *func, struct shader_var *var)
|
||||
{
|
||||
int errcode;
|
||||
bool is_uniform;
|
||||
bool is_uniform = false;
|
||||
|
||||
if (!next_valid_token(&sp->cfp))
|
||||
return PARSE_EOF;
|
||||
@@ -418,7 +417,7 @@ static void sp_parse_function(struct shader_parser *sp, char *type, char *name)
|
||||
if (errorcode != PARSE_SUCCESS)
|
||||
goto error;
|
||||
|
||||
func.return_mapping = mapping;
|
||||
func.mapping = mapping;
|
||||
|
||||
if (!next_valid_token(&sp->cfp))
|
||||
goto error;
|
||||
|
||||
@@ -141,10 +141,10 @@ static inline void shader_struct_free(struct shader_struct *ss)
|
||||
struct shader_func {
|
||||
char *name;
|
||||
char *return_type;
|
||||
char *return_mapping;
|
||||
char *mapping;
|
||||
DARRAY(struct shader_var) params;
|
||||
|
||||
const struct cf_token *start, *end;
|
||||
struct cf_token *start, *end;
|
||||
};
|
||||
|
||||
static inline void shader_func_init(struct shader_func *sf,
|
||||
@@ -153,7 +153,7 @@ static inline void shader_func_init(struct shader_func *sf,
|
||||
da_init(sf->params);
|
||||
|
||||
sf->return_type = return_type;
|
||||
sf->return_mapping = NULL;
|
||||
sf->mapping = NULL;
|
||||
sf->name = name;
|
||||
sf->start = NULL;
|
||||
sf->end = NULL;
|
||||
@@ -168,7 +168,7 @@ static inline void shader_func_free(struct shader_func *sf)
|
||||
|
||||
bfree(sf->name);
|
||||
bfree(sf->return_type);
|
||||
bfree(sf->return_mapping);
|
||||
bfree(sf->mapping);
|
||||
da_free(sf->params);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user