瀏覽代碼

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

jp9000 12 年之前
父節點
當前提交
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
    necessary for user interface.  It also means allowing the use of OpenGL as
    well as Direct3D.
    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
  - Simplify complex systems to not only make it easier to use, but easier to
    maintain.
    maintain.

+ 296 - 24
libobs-opengl/gl-shaderparser.c

@@ -18,7 +18,10 @@
 #include "gl-subsystem.h"
 #include "gl-subsystem.h"
 #include "gl-shaderparser.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)
 		const char *type, size_t len)
 {
 {
 	if (astrcmp_n(type, "float2", len) == 0)
 	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)
 	else if (astrcmp_n(type, "texture_cube", len) == 0)
 		dstr_cat(&glsp->gl_string, "samplerCube");
 		dstr_cat(&glsp->gl_string, "samplerCube");
 	else
 	else
-		dstr_ncat(&glsp->gl_string, type, len);
+		return false;
+
+	return true;
 }
 }
 
 
 static inline void gl_write_type(struct gl_shader_parser *glsp,
 static inline void gl_write_type(struct gl_shader_parser *glsp,
 		const char *type)
 		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)
 		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)
 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);
 	gl_write_type(glsp, var->type);
 	dstr_cat(&glsp->gl_string, " ");
 	dstr_cat(&glsp->gl_string, " ");
 	dstr_cat(&glsp->gl_string, var->name);
 	dstr_cat(&glsp->gl_string, var->name);
-	dstr_cat(&glsp->gl_string, ";\n");
 }
 }
 
 
 static inline void gl_write_params(struct gl_shader_parser *glsp)
 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++) {
 	for (i = 0; i < glsp->parser.params.num; i++) {
 		struct shader_var *var = glsp->parser.params.array+i;
 		struct shader_var *var = glsp->parser.params.array+i;
 		gl_write_var(glsp, var);
 		gl_write_var(glsp, var);
+		dstr_cat(&glsp->gl_string, ";\n");
 	}
 	}
 
 
 	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 */
 /* unwraps a structure that's used for input/output */
 static void gl_unwrap_storage_struct(struct gl_shader_parser *glsp,
 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)
 		const char *prefix)
 {
 {
 	struct dstr prefix_str;
 	struct dstr prefix_str;
@@ -94,7 +100,7 @@ static void gl_unwrap_storage_struct(struct gl_shader_parser *glsp,
 	dstr_init(&prefix_str);
 	dstr_init(&prefix_str);
 	if (prefix)
 	if (prefix)
 		dstr_copy(&prefix_str, prefix);
 		dstr_copy(&prefix_str, prefix);
-	dstr_cat(&prefix_str, st->name);
+	dstr_cat(&prefix_str, name);
 	dstr_cat(&prefix_str, "_");
 	dstr_cat(&prefix_str, "_");
 
 
 	for (i = 0; i < st->vars.num; i++) {
 	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);
 			var->type);
 
 
 	if (st) {
 	if (st) {
-		gl_unwrap_storage_struct(glsp, st, storage, prefix);
+		gl_unwrap_storage_struct(glsp, st, var->name, storage, prefix);
 	} else {
 	} else {
 		if (storage) {
 		if (storage) {
 			dstr_cat(&glsp->gl_string, 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)
 		struct shader_func *main)
 {
 {
 	size_t i;
 	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,
 static void gl_write_outputs(struct gl_shader_parser *glsp,
 		struct shader_func *main)
 		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,
 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");
 		dstr_cat(&glsp->gl_string, "\t");
 		gl_write_var(glsp, var);
 		gl_write_var(glsp, var);
+		dstr_cat(&glsp->gl_string, ";\n");
 	}
 	}
 
 
 	dstr_cat(&glsp->gl_string, "};\n\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
  *   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)
 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_outputs(glsp, main);
 	gl_write_structs(glsp);
 	gl_write_structs(glsp);
 	gl_write_functions(glsp);
 	gl_write_functions(glsp);
-	// gl_write_main(glsp);
+	gl_write_main(glsp, main);
 
 
 	return true;
 	return true;
 }
 }
@@ -236,5 +505,8 @@ bool gl_shader_parse(struct gl_shader_parser *glsp,
 		bfree(str);
 		bfree(str);
 	}
 	}
 
 
+	if (success)
+		success = gl_shader_buildstring(glsp);
+
 	return success;
 	return success;
 }
 }

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

@@ -29,7 +29,6 @@
 
 
 struct gl_shader_parser {
 struct gl_shader_parser {
 	struct dstr          gl_string;
 	struct dstr          gl_string;
-	struct dstr          gl_main_func;
 	struct shader_parser parser;
 	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;
 		struct dstr new;
 		dstr_init_copy(&new, param->name);
 		dstr_init_copy(&new, param->name);
 		darray_push_back(sizeof(struct dstr), used_params, &new);
 		darray_push_back(sizeof(struct dstr), used_params, &new);
-
-		dstr_cat(shader, "uniform ");
 	}
 	}
 
 
 	dstr_cat(shader, param->type);
 	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,
 static inline int sp_check_for_keyword(struct shader_parser *sp,
 		const char *keyword, bool *val)
 		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 (new_val) {
 		if (!next_valid_token(&sp->cfp))
 		if (!next_valid_token(&sp->cfp))
 			return PARSE_EOF;
 			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)
 		struct shader_func *func, struct shader_var *var)
 {
 {
 	int errcode;
 	int errcode;
-	bool is_uniform;
+	bool is_uniform = false;
 
 
 	if (!next_valid_token(&sp->cfp))
 	if (!next_valid_token(&sp->cfp))
 		return PARSE_EOF;
 		return PARSE_EOF;
@@ -418,7 +417,7 @@ static void sp_parse_function(struct shader_parser *sp, char *type, char *name)
 		if (errorcode != PARSE_SUCCESS)
 		if (errorcode != PARSE_SUCCESS)
 			goto error;
 			goto error;
 
 
-		func.return_mapping = mapping;
+		func.mapping = mapping;
 
 
 		if (!next_valid_token(&sp->cfp))
 		if (!next_valid_token(&sp->cfp))
 			goto error;
 			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 {
 struct shader_func {
 	char *name;
 	char *name;
 	char *return_type;
 	char *return_type;
-	char *return_mapping;
+	char *mapping;
 	DARRAY(struct shader_var) params;
 	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,
 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);
 	da_init(sf->params);
 
 
 	sf->return_type    = return_type;
 	sf->return_type    = return_type;
-	sf->return_mapping = NULL;
+	sf->mapping = NULL;
 	sf->name           = name;
 	sf->name           = name;
 	sf->start          = NULL;
 	sf->start          = NULL;
 	sf->end            = NULL;
 	sf->end            = NULL;
@@ -168,7 +168,7 @@ static inline void shader_func_free(struct shader_func *sf)
 
 
 	bfree(sf->name);
 	bfree(sf->name);
 	bfree(sf->return_type);
 	bfree(sf->return_type);
-	bfree(sf->return_mapping);
+	bfree(sf->mapping);
 	da_free(sf->params);
 	da_free(sf->params);
 }
 }