mirror of
https://github.com/libretro/RetroArch
synced 2025-03-20 10:20:51 +00:00
video_shader_parse.c - reduce stack usage
This commit is contained in:
parent
9aa16ddfcc
commit
ba77d862a3
@ -119,8 +119,6 @@ static enum gfx_wrap_type wrap_str_to_mode(const char *wrap_mode)
|
||||
static bool video_shader_parse_pass(config_file_t *conf,
|
||||
struct video_shader_pass *pass, unsigned i)
|
||||
{
|
||||
char tmp_str[PATH_MAX_LENGTH];
|
||||
char tmp_path[PATH_MAX_LENGTH];
|
||||
char shader_name[64];
|
||||
char filter_name_buf[64];
|
||||
char wrap_name_buf[64];
|
||||
@ -136,6 +134,9 @@ static bool video_shader_parse_pass(config_file_t *conf,
|
||||
char scale_type_x[64];
|
||||
char scale_type_y[64];
|
||||
char frame_count_mod[64];
|
||||
size_t path_size = PATH_MAX_LENGTH * sizeof(char);
|
||||
char *tmp_str = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
char *tmp_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
struct gfx_fbo_scale *scale = NULL;
|
||||
bool tmp_bool = false;
|
||||
float fattr = 0.0f;
|
||||
@ -150,14 +151,14 @@ static bool video_shader_parse_pass(config_file_t *conf,
|
||||
|
||||
/* Source */
|
||||
snprintf(shader_name, sizeof(shader_name), "shader%u", i);
|
||||
if (!config_get_path(conf, shader_name, tmp_str, sizeof(tmp_str)))
|
||||
if (!config_get_path(conf, shader_name, tmp_str, path_size))
|
||||
{
|
||||
RARCH_ERR("Couldn't parse shader source (%s).\n", shader_name);
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
|
||||
strlcpy(tmp_path, tmp_str, sizeof(tmp_path));
|
||||
path_resolve_realpath(tmp_path, sizeof(tmp_path));
|
||||
strlcpy(tmp_path, tmp_str, path_size);
|
||||
path_resolve_realpath(tmp_path, path_size);
|
||||
|
||||
if (!path_file_exists(tmp_path))
|
||||
strlcpy(pass->source.path, tmp_str, sizeof(pass->source.path));
|
||||
@ -246,7 +247,7 @@ static bool video_shader_parse_pass(config_file_t *conf,
|
||||
break;
|
||||
default:
|
||||
RARCH_ERR("Invalid attribute.\n");
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,7 +268,7 @@ static bool video_shader_parse_pass(config_file_t *conf,
|
||||
break;
|
||||
default:
|
||||
RARCH_ERR("Invalid attribute.\n");
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,7 +320,14 @@ static bool video_shader_parse_pass(config_file_t *conf,
|
||||
}
|
||||
}
|
||||
|
||||
free(tmp_str);
|
||||
free(tmp_path);
|
||||
return true;
|
||||
|
||||
error:
|
||||
free(tmp_str);
|
||||
free(tmp_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -334,15 +342,20 @@ static bool video_shader_parse_pass(config_file_t *conf,
|
||||
static bool video_shader_parse_textures(config_file_t *conf,
|
||||
struct video_shader *shader)
|
||||
{
|
||||
char textures[1024];
|
||||
size_t path_size = PATH_MAX_LENGTH * sizeof(char);
|
||||
const char *id = NULL;
|
||||
char *save = NULL;
|
||||
char tmp_path[PATH_MAX_LENGTH];
|
||||
char *textures = (char*)malloc(1024 * sizeof(char));
|
||||
char *tmp_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
textures[0] = '\0';
|
||||
|
||||
if (!config_get_array(conf, "textures", textures, sizeof(textures)))
|
||||
if (!config_get_array(conf, "textures", textures, 1024 * sizeof(char)))
|
||||
{
|
||||
free(textures);
|
||||
free(tmp_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (id = strtok_r(textures, ";", &save);
|
||||
id && shader->luts < GFX_MAX_TEXTURES;
|
||||
@ -361,11 +374,12 @@ static bool video_shader_parse_textures(config_file_t *conf,
|
||||
sizeof(shader->lut[shader->luts].path)))
|
||||
{
|
||||
RARCH_ERR("Cannot find path to texture \"%s\" ...\n", id);
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
|
||||
strlcpy(tmp_path, shader->lut[shader->luts].path, sizeof(tmp_path));
|
||||
path_resolve_realpath(tmp_path, sizeof(tmp_path));
|
||||
strlcpy(tmp_path, shader->lut[shader->luts].path,
|
||||
path_size);
|
||||
path_resolve_realpath(tmp_path, path_size);
|
||||
|
||||
if (path_file_exists(tmp_path))
|
||||
{
|
||||
@ -394,7 +408,14 @@ static bool video_shader_parse_textures(config_file_t *conf,
|
||||
shader->lut[shader->luts].mipmap = false;
|
||||
}
|
||||
|
||||
free(textures);
|
||||
free(tmp_path);
|
||||
return true;
|
||||
|
||||
error:
|
||||
free(textures);
|
||||
free(tmp_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -434,25 +455,34 @@ static struct video_shader_parameter *video_shader_parse_find_parameter(
|
||||
bool video_shader_resolve_current_parameters(config_file_t *conf,
|
||||
struct video_shader *shader)
|
||||
{
|
||||
char parameters[4096];
|
||||
size_t param_size = 4096 * sizeof(char);
|
||||
char *parameters = (char*)malloc(4096 * sizeof(char));
|
||||
const char *id = NULL;
|
||||
char *save = NULL;
|
||||
|
||||
if (!conf)
|
||||
{
|
||||
free(parameters);
|
||||
return false;
|
||||
}
|
||||
|
||||
parameters[0] = '\0';
|
||||
|
||||
/* Read in parameters which override the defaults. */
|
||||
if (!config_get_array(conf, "parameters",
|
||||
parameters, sizeof(parameters)))
|
||||
parameters, param_size))
|
||||
{
|
||||
free(parameters);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (id = strtok_r(parameters, ";", &save); id;
|
||||
id = strtok_r(NULL, ";", &save))
|
||||
{
|
||||
struct video_shader_parameter *parameter = (struct video_shader_parameter*)
|
||||
video_shader_parse_find_parameter(shader->parameters, shader->num_parameters, id);
|
||||
struct video_shader_parameter *parameter =
|
||||
(struct video_shader_parameter*)
|
||||
video_shader_parse_find_parameter(
|
||||
shader->parameters, shader->num_parameters, id);
|
||||
|
||||
if (!parameter)
|
||||
{
|
||||
@ -463,6 +493,8 @@ bool video_shader_resolve_current_parameters(config_file_t *conf,
|
||||
if (!config_get_float(conf, id, ¶meter->current))
|
||||
RARCH_WARN("[CGP/GLSLP]: Parameter %s is not set in preset.\n", id);
|
||||
}
|
||||
|
||||
free(parameters);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -487,28 +519,36 @@ bool video_shader_resolve_parameters(config_file_t *conf,
|
||||
|
||||
for (i = 0; i < shader->passes; i++)
|
||||
{
|
||||
char line[4096];
|
||||
RFILE *file = NULL;
|
||||
size_t line_size = 4096 * sizeof(char);
|
||||
char *line = (char*)malloc(4096 * sizeof(char));
|
||||
const char *path = shader->pass[i].source.path;
|
||||
|
||||
#ifdef HAVE_SLANG
|
||||
/* First try to use the more robust slang implementation to support #includes. */
|
||||
/* FIXME: The check for slang can be removed if it's sufficiently tested for
|
||||
* GLSL/Cg as well, it should be the same implementation. */
|
||||
if (!string_is_empty(path) && (string_is_equal_fast(path_get_extension(path), "slang", 5)) &&
|
||||
slang_preprocess_parse_parameters(shader->pass[i].source.path, shader))
|
||||
{
|
||||
free(line);
|
||||
continue;
|
||||
}
|
||||
/* If that doesn't work, fallback to the old path.
|
||||
* Ideally, we'd get rid of this path sooner or later. */
|
||||
#endif
|
||||
file = filestream_open(path, RFILE_MODE_READ_TEXT, -1);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
free(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
line[0] = '\0';
|
||||
|
||||
while (shader->num_parameters < ARRAY_SIZE(shader->parameters)
|
||||
&& filestream_gets(file, line, sizeof(line)))
|
||||
&& filestream_gets(file, line, line_size))
|
||||
{
|
||||
int ret = sscanf(line,
|
||||
"#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
|
||||
@ -533,6 +573,7 @@ bool video_shader_resolve_parameters(config_file_t *conf,
|
||||
param++;
|
||||
}
|
||||
|
||||
free(line);
|
||||
filestream_close(file);
|
||||
}
|
||||
|
||||
@ -554,15 +595,21 @@ bool video_shader_resolve_parameters(config_file_t *conf,
|
||||
static bool video_shader_parse_imports(config_file_t *conf,
|
||||
struct video_shader *shader)
|
||||
{
|
||||
char imports[1024];
|
||||
char tmp_str[PATH_MAX_LENGTH];
|
||||
size_t path_size = PATH_MAX_LENGTH * sizeof(char);
|
||||
char *imports = (char*)malloc(1024 * sizeof(char));
|
||||
char *tmp_str = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
const char *id = NULL;
|
||||
char *save = NULL;
|
||||
|
||||
imports[0] = tmp_str[0] = '\0';
|
||||
|
||||
if (!config_get_array(conf, "imports", imports, sizeof(imports)))
|
||||
if (!config_get_array(conf, "imports", imports,
|
||||
1024 * sizeof(char)))
|
||||
{
|
||||
free(imports);
|
||||
free(tmp_str);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (id = strtok_r(imports, ";", &save);
|
||||
id && shader->variables < GFX_MAX_VARIABLES;
|
||||
@ -595,7 +642,7 @@ static bool video_shader_parse_imports(config_file_t *conf,
|
||||
if (!config_get_array(conf, semantic_buf, semantic, sizeof(semantic)))
|
||||
{
|
||||
RARCH_ERR("No semantic for import variable.\n");
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
|
||||
semantic_hash = djb2_calculate(semantic);
|
||||
@ -622,7 +669,7 @@ static bool video_shader_parse_imports(config_file_t *conf,
|
||||
break;
|
||||
default:
|
||||
RARCH_ERR("Invalid semantic.\n");
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
@ -644,7 +691,7 @@ static bool video_shader_parse_imports(config_file_t *conf,
|
||||
|
||||
default:
|
||||
RARCH_ERR("Invalid input slot for import.\n");
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (config_get_hex(conf, wram_buf, &addr))
|
||||
@ -655,7 +702,7 @@ static bool video_shader_parse_imports(config_file_t *conf,
|
||||
else
|
||||
{
|
||||
RARCH_ERR("No address assigned to semantic.\n");
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -665,12 +712,19 @@ static bool video_shader_parse_imports(config_file_t *conf,
|
||||
var->equal = equal;
|
||||
}
|
||||
|
||||
if (config_get_path(conf, "import_script", tmp_str, sizeof(tmp_str)))
|
||||
if (config_get_path(conf, "import_script", tmp_str, path_size))
|
||||
strlcpy(shader->script_path, tmp_str, sizeof(shader->script_path));
|
||||
config_get_array(conf, "import_script_class",
|
||||
shader->script_class, sizeof(shader->script_class));
|
||||
|
||||
free(imports);
|
||||
free(tmp_str);
|
||||
return true;
|
||||
|
||||
error:
|
||||
free(imports);
|
||||
free(tmp_str);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -879,18 +933,21 @@ void video_shader_write_conf_cgp(config_file_t *conf,
|
||||
for (i = 0; i < shader->passes; i++)
|
||||
{
|
||||
char key[64];
|
||||
char tmp[PATH_MAX_LENGTH];
|
||||
size_t tmp_size = PATH_MAX_LENGTH * sizeof(char);
|
||||
char *tmp = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
const struct video_shader_pass *pass = &shader->pass[i];
|
||||
|
||||
key[0] = '\0';
|
||||
|
||||
snprintf(key, sizeof(key), "shader%u", i);
|
||||
strlcpy(tmp, pass->source.path, sizeof(tmp));
|
||||
strlcpy(tmp, pass->source.path, tmp_size);
|
||||
|
||||
if (!path_is_absolute(tmp))
|
||||
path_resolve_realpath(tmp, sizeof(tmp));
|
||||
path_resolve_realpath(tmp, tmp_size);
|
||||
config_set_string(conf, key, tmp);
|
||||
|
||||
free(tmp);
|
||||
|
||||
if (pass->filter != RARCH_FILTER_UNSPEC)
|
||||
{
|
||||
snprintf(key, sizeof(key), "filter_linear%u", i);
|
||||
@ -917,17 +974,18 @@ void video_shader_write_conf_cgp(config_file_t *conf,
|
||||
|
||||
if (shader->num_parameters)
|
||||
{
|
||||
char parameters[4096];
|
||||
size_t param_size = 4096 * sizeof(char);
|
||||
char *parameters = (char*)malloc(4096 * sizeof(char));
|
||||
|
||||
parameters[0] = '\0';
|
||||
|
||||
strlcpy(parameters, shader->parameters[0].id, sizeof(parameters));
|
||||
strlcpy(parameters, shader->parameters[0].id, param_size);
|
||||
|
||||
for (i = 1; i < shader->num_parameters; i++)
|
||||
{
|
||||
/* O(n^2), but number of parameters is very limited. */
|
||||
strlcat(parameters, ";", sizeof(parameters));
|
||||
strlcat(parameters, shader->parameters[i].id, sizeof(parameters));
|
||||
strlcat(parameters, ";", param_size);
|
||||
strlcat(parameters, shader->parameters[i].id, param_size);
|
||||
}
|
||||
|
||||
config_set_string(conf, "parameters", parameters);
|
||||
@ -935,24 +993,28 @@ void video_shader_write_conf_cgp(config_file_t *conf,
|
||||
for (i = 0; i < shader->num_parameters; i++)
|
||||
config_set_float(conf, shader->parameters[i].id,
|
||||
shader->parameters[i].current);
|
||||
free(parameters);
|
||||
}
|
||||
|
||||
if (shader->luts)
|
||||
{
|
||||
char textures[4096];
|
||||
size_t tex_size = 4096 * sizeof(char);
|
||||
char *textures = (char*)malloc(4096 * sizeof(char));
|
||||
|
||||
textures[0] = '\0';
|
||||
|
||||
strlcpy(textures, shader->lut[0].id, sizeof(textures));
|
||||
strlcpy(textures, shader->lut[0].id, tex_size);
|
||||
for (i = 1; i < shader->luts; i++)
|
||||
{
|
||||
/* O(n^2), but number of textures is very limited. */
|
||||
strlcat(textures, ";", sizeof(textures));
|
||||
strlcat(textures, shader->lut[i].id, sizeof(textures));
|
||||
strlcat(textures, ";", tex_size);
|
||||
strlcat(textures, shader->lut[i].id, tex_size);
|
||||
}
|
||||
|
||||
config_set_string(conf, "textures", textures);
|
||||
|
||||
free(textures);
|
||||
|
||||
for (i = 0; i < shader->luts; i++)
|
||||
{
|
||||
char key[64];
|
||||
@ -983,22 +1045,24 @@ void video_shader_write_conf_cgp(config_file_t *conf,
|
||||
|
||||
if (shader->variables)
|
||||
{
|
||||
char variables[4096];
|
||||
size_t var_tmp = 4096 * sizeof(char);
|
||||
char *variables = (char*)malloc(4096 * sizeof(char));
|
||||
|
||||
variables[0] = '\0';
|
||||
|
||||
strlcpy(variables, shader->variable[0].id, sizeof(variables));
|
||||
strlcpy(variables, shader->variable[0].id, var_tmp);
|
||||
|
||||
for (i = 1; i < shader->variables; i++)
|
||||
{
|
||||
strlcat(variables, ";", sizeof(variables));
|
||||
strlcat(variables, shader->variable[i].id, sizeof(variables));
|
||||
strlcat(variables, ";", var_tmp);
|
||||
strlcat(variables, shader->variable[i].id, var_tmp);
|
||||
}
|
||||
|
||||
config_set_string(conf, "imports", variables);
|
||||
|
||||
for (i = 0; i < shader->variables; i++)
|
||||
shader_write_variable(conf, &shader->variable[i]);
|
||||
free(variables);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1050,7 +1114,8 @@ void video_shader_resolve_relative(struct video_shader *shader,
|
||||
const char *ref_path)
|
||||
{
|
||||
unsigned i;
|
||||
char tmp_path[4096];
|
||||
size_t tmp_path_size = 4096 * sizeof(char);
|
||||
char *tmp_path = (char*)malloc(4096 * sizeof(char));
|
||||
|
||||
tmp_path[0] = '\0';
|
||||
|
||||
@ -1059,23 +1124,25 @@ void video_shader_resolve_relative(struct video_shader *shader,
|
||||
if (!*shader->pass[i].source.path)
|
||||
continue;
|
||||
|
||||
strlcpy(tmp_path, shader->pass[i].source.path, sizeof(tmp_path));
|
||||
strlcpy(tmp_path, shader->pass[i].source.path, tmp_path_size);
|
||||
fill_pathname_resolve_relative(shader->pass[i].source.path,
|
||||
ref_path, tmp_path, sizeof(shader->pass[i].source.path));
|
||||
}
|
||||
|
||||
for (i = 0; i < shader->luts; i++)
|
||||
{
|
||||
strlcpy(tmp_path, shader->lut[i].path, sizeof(tmp_path));
|
||||
strlcpy(tmp_path, shader->lut[i].path, tmp_path_size);
|
||||
fill_pathname_resolve_relative(shader->lut[i].path,
|
||||
ref_path, tmp_path, sizeof(shader->lut[i].path));
|
||||
}
|
||||
|
||||
if (*shader->script_path)
|
||||
{
|
||||
strlcpy(tmp_path, shader->script_path, sizeof(tmp_path));
|
||||
strlcpy(tmp_path, shader->script_path, tmp_path_size);
|
||||
fill_pathname_resolve_relative(shader->script_path,
|
||||
ref_path, tmp_path, sizeof(shader->script_path));
|
||||
}
|
||||
|
||||
free(tmp_path);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user