Browse Source

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

jp9000 12 years ago
parent
commit
34357f00fb

+ 2 - 3
README

@@ -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
libobs-opengl/gl-shaderparser.c

@@ -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;
 }

+ 0 - 1
libobs-opengl/gl-shaderparser.h

@@ -29,7 +29,6 @@
 
 struct gl_shader_parser {
 	struct dstr          gl_string;
-	struct dstr          gl_main_func;
 	struct shader_parser parser;
 };
 

+ 0 - 2
libobs/graphics/effect-parser.c

@@ -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);

+ 3 - 4
libobs/graphics/shader-parser.c

@@ -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;

+ 4 - 4
libobs/graphics/shader-parser.h

@@ -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);
 }