mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-03 15:54:39 +00:00
Add frame_count_mod to XML and Cg shaders.
Allows frame count shaders to avoid floating point inaccuracies when frame count gets large. Avoids having to mod manually in shader.
This commit is contained in:
parent
f004e98f85
commit
a8dd5da5bb
@ -123,6 +123,8 @@ struct cg_program
|
||||
CGparameter frame_dir_v;
|
||||
CGparameter mvp;
|
||||
|
||||
unsigned frame_count_mod;
|
||||
|
||||
struct cg_fbo_params fbo[RARCH_CG_MAX_SHADERS];
|
||||
struct cg_fbo_params orig;
|
||||
struct cg_fbo_params prev[PREV_TEXTURES];
|
||||
@ -211,15 +213,22 @@ void gl_cg_set_params(unsigned width, unsigned height,
|
||||
set_param_2f(prg[active_index].vid_size_f, width, height);
|
||||
set_param_2f(prg[active_index].tex_size_f, tex_width, tex_height);
|
||||
set_param_2f(prg[active_index].out_size_f, out_width, out_height);
|
||||
set_param_1f(prg[active_index].frame_cnt_f, (float)frame_count);
|
||||
set_param_1f(prg[active_index].frame_dir_f, g_extern.frame_is_reverse ? -1.0 : 1.0);
|
||||
|
||||
set_param_2f(prg[active_index].vid_size_v, width, height);
|
||||
set_param_2f(prg[active_index].tex_size_v, tex_width, tex_height);
|
||||
set_param_2f(prg[active_index].out_size_v, out_width, out_height);
|
||||
set_param_1f(prg[active_index].frame_cnt_v, (float)frame_count);
|
||||
set_param_1f(prg[active_index].frame_dir_v, g_extern.frame_is_reverse ? -1.0 : 1.0);
|
||||
|
||||
if (prg[active_index].frame_cnt_f || prg[active_index].frame_cnt_v)
|
||||
{
|
||||
if (prg[active_index].frame_count_mod)
|
||||
frame_count %= prg[active_index].frame_count_mod;
|
||||
|
||||
set_param_1f(prg[active_index].frame_cnt_f, (float)frame_count);
|
||||
set_param_1f(prg[active_index].frame_cnt_v, (float)frame_count);
|
||||
}
|
||||
|
||||
if (active_index == RARCH_CG_MENU_SHADER_INDEX)
|
||||
return;
|
||||
|
||||
@ -823,34 +832,35 @@ static bool load_shader(const char *cgp_path, unsigned i, config_file_t *conf)
|
||||
static bool load_shader_params(unsigned i, config_file_t *conf)
|
||||
{
|
||||
bool ret = true;
|
||||
char *scale_type = NULL;
|
||||
char *scale_type_x = NULL;
|
||||
char *scale_type_y = NULL;
|
||||
bool has_scale_type;
|
||||
bool has_scale_type_x;
|
||||
bool has_scale_type_y;
|
||||
char scale_type[64] = {0};
|
||||
char scale_type_x[64] = {0};
|
||||
char scale_type_y[64] = {0};
|
||||
|
||||
prg[i + 1].frame_count_mod = 0;
|
||||
char frame_count_mod[64] = {0};
|
||||
char frame_count_mod_buf[64];
|
||||
print_buf(frame_count_mod_buf, "frame_count_mod%u", i);
|
||||
if (config_get_array(conf, frame_count_mod_buf, frame_count_mod, sizeof(frame_count_mod)))
|
||||
prg[i + 1].frame_count_mod = strtoul(frame_count_mod, NULL, 0);
|
||||
|
||||
char scale_name_buf[64];
|
||||
print_buf(scale_name_buf, "scale_type%u", i);
|
||||
has_scale_type = config_get_string(conf, scale_name_buf, &scale_type);
|
||||
print_buf(scale_name_buf, "scale_type_x%u", i);
|
||||
has_scale_type_x = config_get_string(conf, scale_name_buf, &scale_type_x);
|
||||
print_buf(scale_name_buf, "scale_type_y%u", i);
|
||||
has_scale_type_y = config_get_string(conf, scale_name_buf, &scale_type_y);
|
||||
|
||||
if (!has_scale_type && !has_scale_type_x && !has_scale_type_y)
|
||||
print_buf(scale_name_buf, "scale_type%u", i);
|
||||
config_get_array(conf, scale_name_buf, scale_type, sizeof(scale_type));
|
||||
|
||||
print_buf(scale_name_buf, "scale_type_x%u", i);
|
||||
config_get_array(conf, scale_name_buf, scale_type_x, sizeof(scale_type_x));
|
||||
|
||||
print_buf(scale_name_buf, "scale_type_y%u", i);
|
||||
config_get_array(conf, scale_name_buf, scale_type_y, sizeof(scale_type_y));
|
||||
|
||||
if (!*scale_type && !*scale_type_x && !*scale_type_y)
|
||||
return true;
|
||||
|
||||
if (has_scale_type)
|
||||
if (*scale_type)
|
||||
{
|
||||
free(scale_type_x);
|
||||
free(scale_type_y);
|
||||
|
||||
scale_type_x = strdup(scale_type);
|
||||
scale_type_y = strdup(scale_type);
|
||||
|
||||
free(scale_type);
|
||||
scale_type = NULL;
|
||||
strlcpy(scale_type_x, scale_type, sizeof(scale_type_x));
|
||||
strlcpy(scale_type_y, scale_type, sizeof(scale_type_y));
|
||||
}
|
||||
|
||||
char attr_name_buf[64];
|
||||
@ -868,7 +878,7 @@ static bool load_shader_params(unsigned i, config_file_t *conf)
|
||||
scale->abs_x = geom->base_width;
|
||||
scale->abs_y = geom->base_height;
|
||||
|
||||
if (scale_type_x)
|
||||
if (*scale_type_x)
|
||||
{
|
||||
if (strcmp(scale_type_x, "source") == 0)
|
||||
scale->type_x = RARCH_SCALE_INPUT;
|
||||
@ -879,12 +889,11 @@ static bool load_shader_params(unsigned i, config_file_t *conf)
|
||||
else
|
||||
{
|
||||
RARCH_ERR("Invalid attribute.\n");
|
||||
ret = false;
|
||||
goto end;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (scale_type_y)
|
||||
if (*scale_type_y)
|
||||
{
|
||||
if (strcmp(scale_type_y, "source") == 0)
|
||||
scale->type_y = RARCH_SCALE_INPUT;
|
||||
@ -895,8 +904,7 @@ static bool load_shader_params(unsigned i, config_file_t *conf)
|
||||
else
|
||||
{
|
||||
RARCH_ERR("Invalid attribute.\n");
|
||||
ret = false;
|
||||
goto end;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -960,11 +968,7 @@ static bool load_shader_params(unsigned i, config_file_t *conf)
|
||||
}
|
||||
#endif
|
||||
|
||||
end:
|
||||
free(scale_type);
|
||||
free(scale_type_x);
|
||||
free(scale_type_y);
|
||||
return ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool load_preset(const char *path)
|
||||
|
@ -173,6 +173,7 @@ struct shader_program
|
||||
unsigned abs_y;
|
||||
enum gl_scale_type type_x;
|
||||
enum gl_scale_type type_y;
|
||||
unsigned frame_count_mod;
|
||||
|
||||
bool valid_scale;
|
||||
};
|
||||
@ -198,6 +199,7 @@ struct shader_uniforms
|
||||
int texture_size;
|
||||
|
||||
int frame_count;
|
||||
unsigned frame_count_mod;
|
||||
int frame_direction;
|
||||
|
||||
int lut_texture[MAX_TEXTURES];
|
||||
@ -300,6 +302,7 @@ static char *xml_replace_if_file(char *content, const char *path, xmlNodePtr nod
|
||||
|
||||
static bool get_xml_attrs(struct shader_program *prog, xmlNodePtr ptr)
|
||||
{
|
||||
prog->frame_count_mod = 0;
|
||||
prog->scale_x = 1.0;
|
||||
prog->scale_y = 1.0;
|
||||
prog->type_x = prog->type_y = RARCH_SCALE_INPUT;
|
||||
@ -329,6 +332,7 @@ static bool get_xml_attrs(struct shader_program *prog, xmlNodePtr ptr)
|
||||
char attr_scale[64], attr_scale_x[64], attr_scale_y[64];
|
||||
char attr_size[64], attr_size_x[64], attr_size_y[64];
|
||||
char attr_outscale[64], attr_outscale_x[64], attr_outscale_y[64];
|
||||
char frame_count_mod[64];
|
||||
|
||||
xml_get_prop(attr_scale, sizeof(attr_scale), ptr, "scale");
|
||||
xml_get_prop(attr_scale_x, sizeof(attr_scale_x), ptr, "scale_x");
|
||||
@ -339,9 +343,16 @@ static bool get_xml_attrs(struct shader_program *prog, xmlNodePtr ptr)
|
||||
xml_get_prop(attr_outscale, sizeof(attr_outscale), ptr, "outscale");
|
||||
xml_get_prop(attr_outscale_x, sizeof(attr_outscale_x), ptr, "outscale_x");
|
||||
xml_get_prop(attr_outscale_y, sizeof(attr_outscale_y), ptr, "outscale_y");
|
||||
xml_get_prop(frame_count_mod, sizeof(frame_count_mod), ptr, "frame_count_mod");
|
||||
|
||||
unsigned x_attr_cnt = 0, y_attr_cnt = 0;
|
||||
|
||||
if (*frame_count_mod)
|
||||
{
|
||||
prog->frame_count_mod = strtoul(frame_count_mod, NULL, 0);
|
||||
RARCH_LOG("Got frame count mod attr: %u\n", prog->frame_count_mod);
|
||||
}
|
||||
|
||||
if (*attr_scale)
|
||||
{
|
||||
float scale = strtod(attr_scale, NULL);
|
||||
@ -1069,6 +1080,7 @@ static bool gl_glsl_load_shader(unsigned index, const char *path)
|
||||
}
|
||||
|
||||
find_uniforms(gl_program[index], &gl_uniforms[index]);
|
||||
gl_uniforms[index].frame_count_mod = prog.frame_count_mod;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1192,10 +1204,10 @@ bool gl_glsl_init(const char *path)
|
||||
// RetroArch custom two-pass with two different files.
|
||||
if (num_progs == 1 && *g_settings.video.second_pass_shader && g_settings.video.render_to_texture)
|
||||
{
|
||||
unsigned secondary_progs = get_xml_shaders(g_settings.video.second_pass_shader, progs, 1);
|
||||
unsigned secondary_progs = get_xml_shaders(g_settings.video.second_pass_shader, progs + 1, 1);
|
||||
if (secondary_progs == 1)
|
||||
{
|
||||
if (!compile_programs(&gl_program[2], progs, 1))
|
||||
if (!compile_programs(&gl_program[2], progs + 1, 1))
|
||||
{
|
||||
RARCH_ERR("Failed to compile second pass shader.\n");
|
||||
return false;
|
||||
@ -1213,6 +1225,9 @@ bool gl_glsl_init(const char *path)
|
||||
for (unsigned i = 0; i <= num_progs; i++)
|
||||
find_uniforms(gl_program[i], &gl_uniforms[i]);
|
||||
|
||||
for (unsigned i = 1; i <= num_progs; i++)
|
||||
gl_uniforms[i].frame_count_mod = progs[i - 1].frame_count_mod;
|
||||
|
||||
#ifdef GLSL_DEBUG
|
||||
if (!gl_check_error())
|
||||
RARCH_WARN("Detected GL error in GLSL.\n");
|
||||
@ -1318,7 +1333,13 @@ void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
pglUniform2fv(uni->texture_size, 1, texture_size);
|
||||
|
||||
if (uni->frame_count >= 0)
|
||||
pglUniform1i(uni->frame_count, frame_count);
|
||||
{
|
||||
unsigned count = frame_count;
|
||||
if (uni->frame_count_mod)
|
||||
count %= uni->frame_count_mod;
|
||||
fprintf(stderr, "Count: %u\n", count);
|
||||
pglUniform1i(uni->frame_count, count);
|
||||
}
|
||||
|
||||
if (uni->frame_direction >= 0)
|
||||
pglUniform1i(uni->frame_direction, g_extern.frame_is_reverse ? -1 : 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user