diff --git a/gfx/gl.c b/gfx/gl.c index b5cd72cb8a..474235f047 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -978,6 +978,7 @@ static void gl_frame_fbo(void *data, const struct gl_tex_info *tex_info) fbo_info->tex_size[0] = prev_rect->width; fbo_info->tex_size[1] = prev_rect->height; memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); + fbo_tex_info_cnt++; glBindFramebuffer(RARCH_GL_FRAMEBUFFER, gl->fbo[i]); @@ -1002,8 +1003,6 @@ static void gl_frame_fbo(void *data, const struct gl_tex_info *tex_info) gl_shader_set_coords(gl, &gl->coords, &gl->mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - fbo_tex_info_cnt++; } #if defined(GL_FRAMEBUFFER_SRGB) && !defined(HAVE_OPENGLES) @@ -1018,6 +1017,16 @@ static void gl_frame_fbo(void *data, const struct gl_tex_info *tex_info) set_texture_coords(fbo_tex_coords, xamt, yamt); + // Push final FBO to list. + fbo_info = &fbo_tex_info[gl->fbo_pass - 1]; + fbo_info->tex = gl->fbo_texture[gl->fbo_pass - 1]; + fbo_info->input_size[0] = prev_rect->img_width; + fbo_info->input_size[1] = prev_rect->img_height; + fbo_info->tex_size[0] = prev_rect->width; + fbo_info->tex_size[1] = prev_rect->height; + memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); + fbo_tex_info_cnt++; + // Render our FBO texture to back buffer. gl_bind_backbuffer(); if (gl->shader) diff --git a/gfx/shader_cg.c b/gfx/shader_cg.c index 46ee003639..025ef42510 100644 --- a/gfx/shader_cg.c +++ b/gfx/shader_cg.c @@ -287,7 +287,7 @@ static void gl_cg_set_params(void *data, unsigned width, unsigned height, } // Set FBO textures. - if (active_index > 2) + if (active_index) { for (i = 0; i < fbo_info_cnt; i++) { @@ -756,13 +756,16 @@ static void set_program_attributes(unsigned i) prg[i].prev[j].coord = cgGetNamedParameter(prg[i].vprg, attr_buf_coord); } - for (j = 0; j < i - 1; j++) + for (j = 0; j + 1 < i; j++) { char pass_str[64]; snprintf(pass_str, sizeof(pass_str), "PASS%u", j + 1); set_pass_attrib(&prg[i], &prg[i].fbo[j], pass_str); snprintf(pass_str, sizeof(pass_str), "PASSPREV%u", i - (j + 1)); set_pass_attrib(&prg[i], &prg[i].fbo[j], pass_str); + + if (*cg_shader->pass[j].alias) + set_pass_attrib(&prg[i], &prg[i].fbo[j], cg_shader->pass[j].alias); } } diff --git a/gfx/shader_glsl.c b/gfx/shader_glsl.c index 6e0d0206c9..43cb9ea7a5 100644 --- a/gfx/shader_glsl.c +++ b/gfx/shader_glsl.c @@ -566,6 +566,9 @@ static void find_uniforms(unsigned pass, GLuint prog, struct shader_uniforms *un find_uniforms_frame(prog, &uni->pass[i], frame_base); snprintf(frame_base, sizeof(frame_base), "PassPrev%u", pass - (i + 1)); find_uniforms_frame(prog, &uni->pass[i], frame_base); + + if (*glsl_shader->pass[i].alias) + find_uniforms_frame(prog, &uni->pass[i], glsl_shader->pass[i].alias); } clear_uniforms_frame(&uni->prev[0]); @@ -818,12 +821,6 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height, const struct gl_tex_info *fbo_info, unsigned fbo_info_cnt) { (void)data; - // We enforce a certain layout for our various texture types in the texunits. - // - Regular frame (Texture) (always bound). - // - LUT textures (always bound). - // - Original texture (always bound if meaningful). - // - FBO textures (always bound if available). - // - Previous textures. if (!glsl_enable || (gl_program[active_index] == 0)) return; @@ -861,21 +858,22 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height, if (uni->frame_direction >= 0) glUniform1i(uni->frame_direction, g_extern.frame_is_reverse ? -1 : 1); + unsigned texunit = 1; + for (i = 0; i < glsl_shader->luts; i++) { if (uni->lut_texture[i] >= 0) { // Have to rebind as HW render could override this. - glActiveTexture(GL_TEXTURE0 + i + 1); + glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, gl_teximage[i]); - glUniform1i(uni->lut_texture[i], i + 1); + glUniform1i(uni->lut_texture[i], texunit); + texunit++; } } - unsigned texunit = glsl_shader->luts + 1; - - // Set original texture unless we're in first pass (pointless). - if (active_index > 1) + // Set original texture. + if (active_index) { if (uni->orig.texture >= 0) { @@ -883,10 +881,9 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height, glActiveTexture(GL_TEXTURE0 + texunit); glUniform1i(uni->orig.texture, texunit); glBindTexture(GL_TEXTURE_2D, info->tex); + texunit++; } - texunit++; - if (uni->orig.texture_size >= 0) glUniform2fv(uni->orig.texture_size, 1, info->tex_size); @@ -906,20 +903,16 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height, size += 8; } - // Bind new texture in the chain. - if (fbo_info_cnt > 0) - { - glActiveTexture(GL_TEXTURE0 + texunit + fbo_info_cnt - 1); - glBindTexture(GL_TEXTURE_2D, fbo_info[fbo_info_cnt - 1].tex); - } - // Bind FBO textures. for (i = 0; i < fbo_info_cnt; i++) { if (uni->pass[i].texture) + { + glActiveTexture(GL_TEXTURE0 + texunit); + glBindTexture(GL_TEXTURE_2D, fbo_info[i].tex); glUniform1i(uni->pass[i].texture, texunit); - - texunit++; + texunit++; + } if (uni->pass[i].texture_size >= 0) glUniform2fv(uni->pass[i].texture_size, 1, fbo_info[i].tex_size); @@ -940,23 +933,6 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height, } } } - else - { - // First pass, so unbind everything to avoid collitions. - // Unbind ORIG. - glActiveTexture(GL_TEXTURE0 + texunit); - glBindTexture(GL_TEXTURE_2D, 0); - - GLuint base_tex = texunit + 1; - // Unbind any lurking FBO passes. - // Rendering to a texture that is bound to a texture unit - // sounds very shaky ... ;) - for (i = 0; i < glsl_shader->passes; i++) - { - glActiveTexture(GL_TEXTURE0 + base_tex + i); - glBindTexture(GL_TEXTURE_2D, 0); - } - } // Set previous textures. Only bind if they're actually used. for (i = 0; i < PREV_TEXTURES; i++) @@ -965,11 +941,10 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height, { glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, prev_info[i].tex); - glUniform1i(uni->prev[i].texture, texunit++); + glUniform1i(uni->prev[i].texture, texunit); + texunit++; } - texunit++; - if (uni->prev[i].texture_size >= 0) glUniform2fv(uni->prev[i].texture_size, 1, prev_info[i].tex_size); diff --git a/gfx/shader_parse.c b/gfx/shader_parse.c index 4734f4106e..f869714b97 100644 --- a/gfx/shader_parse.c +++ b/gfx/shader_parse.c @@ -105,6 +105,11 @@ static bool shader_parse_pass(config_file_t *conf, struct gfx_shader_pass *pass, print_buf(mipmap_buf, "mipmap_input%u", i); config_get_bool(conf, mipmap_buf, &pass->mipmap); + char alias_buf[64]; + print_buf(alias_buf, "alias%u", i); + if (!config_get_array(conf, alias_buf, pass->alias, sizeof(pass->alias))) + *pass->alias = '\0'; + // Scale struct gfx_fbo_scale *scale = &pass->fbo; char scale_type[64] = {0}; @@ -615,6 +620,9 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, const struct gfx_shader *sha print_buf(key, "mipmap_input%u", i); config_set_bool(conf, key, pass->mipmap); + print_buf(key, "alias%u", i); + config_set_string(conf, key, pass->alias); + shader_write_fbo(conf, &pass->fbo, i); } diff --git a/gfx/shader_parse.h b/gfx/shader_parse.h index dd54535460..6ee8e12648 100644 --- a/gfx/shader_parse.h +++ b/gfx/shader_parse.h @@ -88,6 +88,7 @@ struct gfx_shader_pass } string; } source; + char alias[64]; struct gfx_fbo_scale fbo; enum gfx_filter_type filter; enum gfx_wrap_type wrap;