提交 34357f00 编写于 作者: J jp9000

finish up GLSL conversion stuff and make some minor tweaks to shader parser

上级 f9d1a4b9
......@@ -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.
......
......@@ -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;
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);
struct shader_var var = {0};
var.type = main->return_type;
var.name = "outputval";
if (main->mapping)
var.mapping = main->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);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册