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:
Themaister 2013-03-25 14:47:33 +01:00
parent f004e98f85
commit a8dd5da5bb
2 changed files with 63 additions and 38 deletions

View File

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

View File

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