diff --git a/gfx/fonts/freetype.c b/gfx/fonts/freetype.c index 548d4e9fab..0d8146d426 100644 --- a/gfx/fonts/freetype.c +++ b/gfx/fonts/freetype.c @@ -251,7 +251,7 @@ static void setup_font(void *data, const char *msg, GLfloat scale, GLfloat pos_x if (!gl->font) return; - gl_shader_use(0); + gl_shader_use(gl, 0); gl_set_viewport(gl, gl->win_width, gl->win_height, false, false); glEnable(GL_BLEND); @@ -288,12 +288,12 @@ static void setup_font(void *data, const char *msg, GLfloat scale, GLfloat pos_x gl->coords.vertex = font_vertex_dark; gl->coords.color = gl->font_color_dark; - gl_shader_set_coords(&gl->coords, &gl->mvp); + gl_shader_set_coords(gl, &gl->coords, &gl->mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gl->coords.vertex = font_vertex; gl->coords.color = gl->font_color; - gl_shader_set_coords(&gl->coords, &gl->mvp); + gl_shader_set_coords(gl, &gl->coords, &gl->mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Post - Go back to old rendering path. diff --git a/gfx/gl.c b/gfx/gl.c index a042d0935f..81785a2b44 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -186,18 +186,22 @@ static inline bool load_gl_proc_win32(gl_t *gl) ////////////////// Shaders #ifdef HAVE_OPENGLES2 -static bool gl_shader_init(void) // We always need a shader alive in GLES2. +static bool gl_shader_init(gl_t *gl) // We always need a shader alive in GLES2. { const char *shader_path = NULL; if ((g_settings.video.shader_type == RARCH_SHADER_AUTO || g_settings.video.shader_type == RARCH_SHADER_BSNES) && *g_settings.video.bsnes_shader_path) shader_path = g_settings.video.bsnes_shader_path; - return gl_glsl_init(shader_path); + gl->shader = &gl_glsl_backend; + return gl->shader->init(shader_path); } #else -static bool gl_shader_init(void) +static bool gl_shader_init(gl_t *gl) { + const gl_shader_backend_t *backend = NULL; + const char *shader_path = NULL; + switch (g_settings.video.shader_type) { case RARCH_SHADER_AUTO: @@ -207,54 +211,59 @@ static bool gl_shader_init(void) #ifdef HAVE_CG if (*g_settings.video.cg_shader_path) - return gl_cg_init(g_settings.video.cg_shader_path); + { + backend = &gl_cg_backend; + shader_path = g_settings.video.cg_shader_path; + } #endif #ifdef HAVE_XML if (*g_settings.video.bsnes_shader_path) - return gl_glsl_init(g_settings.video.bsnes_shader_path); + { + backend = &gl_glsl_backend; + shader_path = g_settings.video.bsnes_shader_path; + } #endif break; } #ifdef HAVE_CG case RARCH_SHADER_CG: - return gl_cg_init(g_settings.video.cg_shader_path); + backend = &gl_cg_backend; + shader_path = g_settings.video.cg_shader_path; + break; #endif #ifdef HAVE_XML case RARCH_SHADER_BSNES: - return gl_glsl_init(g_settings.video.bsnes_shader_path); + backend = &gl_glsl_backend; + shader_path = g_settings.video.bsnes_shader_path; + break; #endif default: break; } - return true; + if (!backend) + return true; + + gl->shader = backend; + return gl->shader->init(shader_path); } #endif -void gl_shader_use(unsigned index) +void gl_shader_use(gl_t *gl, unsigned index) { -#ifdef HAVE_CG - gl_cg_use(index); -#endif - -#ifdef HAVE_GLSL - gl_glsl_use(index); -#endif + if (gl->shader) + gl->shader->use(index); } -static inline void gl_shader_deinit(void) +static inline void gl_shader_deinit(gl_t *gl) { -#ifdef HAVE_CG - gl_cg_deinit(); -#endif - -#ifdef HAVE_GLSL - gl_glsl_deinit(); -#endif + if (gl->shader) + gl->shader->deinit(); + gl->shader = NULL; } #ifndef NO_GL_FF_VERTEX @@ -288,7 +297,7 @@ static void gl_set_mvp(const math_matrix *mat) } #endif -void gl_shader_set_coords(const struct gl_coords *coords, const math_matrix *mat) +void gl_shader_set_coords(gl_t *gl, const struct gl_coords *coords, const math_matrix *mat) { bool ret_coords = false; bool ret_mvp = false; @@ -296,19 +305,10 @@ void gl_shader_set_coords(const struct gl_coords *coords, const math_matrix *mat (void)ret_coords; (void)ret_mvp; -#ifdef HAVE_GLSL - if (!ret_coords) - ret_coords |= gl_glsl_set_coords(coords); - if (!ret_mvp) - ret_mvp |= gl_glsl_set_mvp(mat); -#endif - -#ifdef HAVE_CG - if (!ret_coords) - ret_coords |= gl_cg_set_coords(coords); - if (!ret_mvp) - ret_mvp |= gl_cg_set_mvp(mat); -#endif + if (!ret_coords && gl->shader) + ret_coords |= gl->shader->set_coords(coords); + if (!ret_mvp && gl->shader) + ret_mvp |= gl->shader->set_mvp(mat); // Fall back to FF-style if needed and possible. #ifndef NO_GL_FF_VERTEX @@ -322,7 +322,7 @@ void gl_shader_set_coords(const struct gl_coords *coords, const math_matrix *mat #endif } -static inline void gl_shader_set_params(unsigned width, unsigned height, +static inline void gl_shader_set_params(gl_t *gl, unsigned width, unsigned height, unsigned tex_width, unsigned tex_height, unsigned out_width, unsigned out_height, unsigned frame_count, @@ -330,69 +330,37 @@ static inline void gl_shader_set_params(unsigned width, unsigned height, const struct gl_tex_info *prev_info, const struct gl_tex_info *fbo_info, unsigned fbo_info_cnt) { -#ifdef HAVE_CG - gl_cg_set_params(width, height, - tex_width, tex_height, - out_width, out_height, - frame_count, info, prev_info, fbo_info, fbo_info_cnt); -#endif - -#ifdef HAVE_GLSL - gl_glsl_set_params(width, height, - tex_width, tex_height, - out_width, out_height, - frame_count, info, prev_info, fbo_info, fbo_info_cnt); -#endif + if (gl->shader) + { + gl->shader->set_params(width, height, + tex_width, tex_height, + out_width, out_height, + frame_count, info, prev_info, fbo_info, fbo_info_cnt); + } } -static unsigned gl_shader_num(void) +static inline unsigned gl_shader_num(gl_t *gl) { -#ifdef HAVE_CG - unsigned cg_num = gl_cg_num(); - if (cg_num) - return cg_num; -#endif - -#ifdef HAVE_GLSL - unsigned glsl_num = gl_glsl_num(); - if (glsl_num) - return glsl_num; -#endif - - return 0; + if (gl->shader) + return gl->shader->num_shaders(); + else + return 0; } -static bool gl_shader_filter_type(unsigned index, bool *smooth) +static bool gl_shader_filter_type(gl_t *gl, unsigned index, bool *smooth) { - bool valid = false; - -#ifdef HAVE_CG - if (!valid) - valid = gl_cg_filter_type(index, smooth); -#endif - -#ifdef HAVE_GLSL - if (!valid) - valid = gl_glsl_filter_type(index, smooth); -#endif - - return valid; + if (gl->shader) + return gl->shader->filter_type(index, smooth); + else + return false; } #ifdef HAVE_FBO -static void gl_shader_scale(unsigned index, struct gl_fbo_scale *scale) +static void gl_shader_scale(gl_t *gl, unsigned index, struct gl_fbo_scale *scale) { scale->valid = false; - -#ifdef HAVE_CG - if (!scale->valid) - gl_cg_shader_scale(index, scale); -#endif - -#ifdef HAVE_GLSL - if (!scale->valid) - gl_glsl_shader_scale(index, scale); -#endif + if (gl->shader) + gl->shader->shader_scale(index, scale); } #endif /////////////////// @@ -500,7 +468,7 @@ static void gl_create_fbo_textures(gl_t *gl) GLuint filter_type = base_filt; bool smooth = false; - if (gl_shader_filter_type(i + 2, &smooth)) + if (gl_shader_filter_type(gl, i + 2, &smooth)) filter_type = smooth ? GL_LINEAR : GL_NEAREST; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_type); @@ -553,15 +521,15 @@ void gl_deinit_fbo(gl_t *gl) void gl_init_fbo(gl_t *gl, unsigned width, unsigned height) { // No need to use FBOs. - if (!g_settings.video.render_to_texture && gl_shader_num() == 0) + if (!g_settings.video.render_to_texture && gl_shader_num(gl) == 0) return; struct gl_fbo_scale scale, scale_last; - gl_shader_scale(1, &scale); - gl_shader_scale(gl_shader_num(), &scale_last); + gl_shader_scale(gl, 1, &scale); + gl_shader_scale(gl, gl_shader_num(gl), &scale_last); // No need to use FBOs. - if (gl_shader_num() == 1 && !scale.valid && !g_settings.video.render_to_texture) + if (gl_shader_num(gl) == 1 && !scale.valid && !g_settings.video.render_to_texture) return; if (!load_fbo_proc(gl)) @@ -570,7 +538,7 @@ void gl_init_fbo(gl_t *gl, unsigned width, unsigned height) return; } - gl->fbo_pass = gl_shader_num() - 1; + gl->fbo_pass = gl_shader_num(gl) - 1; if (scale_last.valid) gl->fbo_pass++; @@ -589,7 +557,7 @@ void gl_init_fbo(gl_t *gl, unsigned width, unsigned height) for (int i = 1; i < gl->fbo_pass; i++) { - gl_shader_scale(i + 1, &gl->fbo_scale[i]); + gl_shader_scale(gl, i + 1, &gl->fbo_scale[i]); if (!gl->fbo_scale[i].valid) { @@ -645,7 +613,7 @@ void gl_set_projection(gl_t *gl, struct gl_ortho *ortho, bool allow_rotate) } gl->mvp = proj; - gl_shader_set_coords(&gl->coords, &gl->mvp); + gl_shader_set_coords(gl, &gl->coords, &gl->mvp); } void gl_set_viewport(gl_t *gl, unsigned width, unsigned height, bool force_full, bool allow_rotate) @@ -808,19 +776,19 @@ static void gl_frame_fbo(gl_t *gl, const struct gl_tex_info *tex_info) memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); pglBindFramebuffer(GL_FRAMEBUFFER, gl->fbo[i]); - gl_shader_use(i + 1); + gl_shader_use(gl, i + 1); glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i - 1]); glClear(GL_COLOR_BUFFER_BIT); // Render to FBO with certain size. gl_set_viewport(gl, rect->img_width, rect->img_height, true, false); - gl_shader_set_params(prev_rect->img_width, prev_rect->img_height, + gl_shader_set_params(gl, prev_rect->img_width, prev_rect->img_height, prev_rect->width, prev_rect->height, gl->vp.width, gl->vp.height, gl->frame_count, tex_info, gl->prev_info, fbo_tex_info, fbo_tex_info_cnt); - gl_shader_set_coords(&gl->coords, &gl->mvp); + gl_shader_set_coords(gl, &gl->coords, &gl->mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); fbo_tex_info_cnt++; @@ -835,21 +803,21 @@ static void gl_frame_fbo(gl_t *gl, const struct gl_tex_info *tex_info) // Render our FBO texture to back buffer. pglBindFramebuffer(GL_FRAMEBUFFER, 0); - gl_shader_use(gl->fbo_pass + 1); + gl_shader_use(gl, gl->fbo_pass + 1); glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[gl->fbo_pass - 1]); glClear(GL_COLOR_BUFFER_BIT); gl->render_to_tex = false; gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); - gl_shader_set_params(prev_rect->img_width, prev_rect->img_height, + gl_shader_set_params(gl, prev_rect->img_width, prev_rect->img_height, prev_rect->width, prev_rect->height, gl->vp.width, gl->vp.height, gl->frame_count, tex_info, gl->prev_info, fbo_tex_info, fbo_tex_info_cnt); gl->coords.vertex = vertex_ptr; - gl_shader_set_coords(&gl->coords, &gl->mvp); + gl_shader_set_coords(gl, &gl->coords, &gl->mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gl->coords.tex_coord = gl->tex_coords; @@ -1078,7 +1046,7 @@ static inline void gl_next_texture_index(gl_t *gl, const struct gl_tex_info *tex static inline void gl_set_shader_viewport(gl_t *gl, unsigned shader) { - gl_shader_use(shader); + gl_shader_use(gl, shader); gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); } @@ -1089,7 +1057,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei gl_t *gl = (gl_t*)data; - gl_shader_use(1); + gl_shader_use(gl, 1); gl->frame_count++; glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); @@ -1134,13 +1102,13 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei memcpy(tex_info.coord, gl->tex_coords, sizeof(gl->tex_coords)); glClear(GL_COLOR_BUFFER_BIT); - gl_shader_set_params(width, height, + gl_shader_set_params(gl, width, height, gl->tex_w, gl->tex_h, gl->vp.width, gl->vp.height, gl->frame_count, &tex_info, gl->prev_info, NULL, 0); - gl_shader_set_coords(&gl->coords, &gl->mvp); + gl_shader_set_coords(gl, &gl->coords, &gl->mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); #ifdef HAVE_FBO @@ -1201,7 +1169,7 @@ static void gl_free(void *data) gl_t *gl = (gl_t*)data; gl_deinit_font(gl); - gl_shader_deinit(); + gl_shader_deinit(gl); #ifndef NO_GL_FF_VERTEX gl_disable_client_arrays(); @@ -1374,7 +1342,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo gl_glsl_set_get_proc_address(gl->ctx_driver->get_proc_address); #endif - if (!gl_shader_init()) + if (!gl_shader_init(gl)) { RARCH_ERR("Shader init failed.\n"); context_destroy_func(); @@ -1382,7 +1350,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo return NULL; } - RARCH_LOG("GL: Loaded %u program(s).\n", gl_shader_num()); + RARCH_LOG("GL: Loaded %u program(s).\n", gl_shader_num(gl)); #ifdef HAVE_FBO // Set up render to texture. @@ -1397,7 +1365,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo gl_set_shader_viewport(gl, 1); bool force_smooth = false; - if (gl_shader_filter_type(1, &force_smooth)) + if (gl_shader_filter_type(gl, 1, &force_smooth)) gl->tex_filter = force_smooth ? GL_LINEAR : GL_NEAREST; else gl->tex_filter = video->smooth ? GL_LINEAR : GL_NEAREST; @@ -1419,7 +1387,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo gl->coords.tex_coord = gl->tex_coords; gl->coords.color = white_color; gl->coords.lut_tex_coord = tex_coords; - gl_shader_set_coords(&gl->coords, &gl->mvp); + gl_shader_set_coords(gl, &gl->coords, &gl->mvp); gl->tex_w = RARCH_SCALE_BASE * video->input_scale; gl->tex_h = RARCH_SCALE_BASE * video->input_scale; @@ -1501,7 +1469,7 @@ static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *p glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); #endif - gl_shader_deinit(); + gl_shader_deinit(gl); switch (type) { diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 66c759c4d9..de7bf26b87 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -187,6 +187,8 @@ struct gl_coords const GLfloat *lut_tex_coord; }; +typedef struct gl_shader_backend gl_shader_backend_t; + #define MAX_SHADERS 16 #if (defined(HAVE_GLSL) || defined(HAVE_CG)) @@ -199,6 +201,8 @@ struct gl_coords typedef struct gl { const gfx_ctx_driver_t *ctx_driver; + const gl_shader_backend_t *shader; + bool vsync; GLuint texture[TEXTURES]; unsigned tex_index; // For use with PREV. @@ -329,10 +333,10 @@ extern PFNGLACTIVETEXTUREPROC pglActiveTexture; extern const GLfloat vertexes_flipped[]; extern const GLfloat white_color[]; -void gl_shader_use(unsigned index); +void gl_shader_use(gl_t *gl, unsigned index); void gl_set_projection(gl_t *gl, struct gl_ortho *ortho, bool allow_rotate); void gl_set_viewport(gl_t *gl, unsigned width, unsigned height, bool force_full, bool allow_rotate); -void gl_shader_set_coords(const struct gl_coords *coords, const math_matrix *mat); +void gl_shader_set_coords(gl_t *gl, const struct gl_coords *coords, const math_matrix *mat); void gl_init_fbo(gl_t *gl, unsigned width, unsigned height); void gl_deinit_fbo(gl_t *gl); diff --git a/gfx/shader_cg.c b/gfx/shader_cg.c index 3b1041939d..9011a90ca8 100644 --- a/gfx/shader_cg.c +++ b/gfx/shader_cg.c @@ -1374,3 +1374,15 @@ unsigned gl_cg_get_lut_info(struct gl_cg_lut_info *info, unsigned elems) return elems; } +const gl_shader_backend_t gl_cg_backend = { + gl_cg_init, + gl_cg_deinit, + gl_cg_set_params, + gl_cg_use, + gl_cg_num, + gl_cg_filter_type, + gl_cg_shader_scale, + gl_cg_set_coords, + gl_cg_set_mvp, +}; + diff --git a/gfx/shader_cg.h b/gfx/shader_cg.h index 50d0911320..356f2ba4ee 100644 --- a/gfx/shader_cg.h +++ b/gfx/shader_cg.h @@ -17,14 +17,11 @@ #ifndef __RARCH_CG_H #define __RARCH_CG_H -#include "../boolean.h" -#include "gl_common.h" -#include "math/matrix.h" +#include "shader_common.h" #include bool gl_cg_init(const char *path); bool gl_cg_reinit(const char *path); - void gl_cg_deinit(void); void gl_cg_set_params(unsigned width, unsigned height, @@ -79,4 +76,6 @@ struct gl_cg_lut_info unsigned gl_cg_get_lut_info(struct gl_cg_lut_info *info, unsigned elems); +extern const gl_shader_backend_t gl_cg_backend; + #endif diff --git a/gfx/shader_common.h b/gfx/shader_common.h new file mode 100644 index 0000000000..404dfdab5b --- /dev/null +++ b/gfx/shader_common.h @@ -0,0 +1,45 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef SHADER_COMMON_H__ +#define SHADER_COMMON_H__ + +#include "../boolean.h" +#include "gl_common.h" +#include "gfx_context.h" +#include "math/matrix.h" + +struct gl_shader_backend +{ + bool (*init)(const char *path); + void (*deinit)(void); + void (*set_params)(unsigned width, unsigned height, + unsigned tex_width, unsigned tex_height, + unsigned out_width, unsigned out_height, + unsigned frame_counter, + const struct gl_tex_info *info, + const struct gl_tex_info *prev_info, + const struct gl_tex_info *fbo_info, unsigned fbo_info_cnt); + + void (*use)(unsigned index); + unsigned (*num_shaders)(void); + bool (*filter_type)(unsigned index, bool *smooth); + void (*shader_scale)(unsigned index, struct gl_fbo_scale *scale); + bool (*set_coords)(const struct gl_coords *coords); + bool (*set_mvp)(const math_matrix *mat); +}; + +#endif + diff --git a/gfx/shader_glsl.c b/gfx/shader_glsl.c index 0c832a8946..d5c258e310 100644 --- a/gfx/shader_glsl.c +++ b/gfx/shader_glsl.c @@ -1522,3 +1522,15 @@ void gl_glsl_set_get_proc_address(gfx_ctx_proc_t (*proc)(const char*)) glsl_get_proc_address = proc; } +const gl_shader_backend_t gl_glsl_backend = { + gl_glsl_init, + gl_glsl_deinit, + gl_glsl_set_params, + gl_glsl_use, + gl_glsl_num, + gl_glsl_filter_type, + gl_glsl_shader_scale, + gl_glsl_set_coords, + gl_glsl_set_mvp, +}; + diff --git a/gfx/shader_glsl.h b/gfx/shader_glsl.h index 93fe0accf8..8b04af6fce 100644 --- a/gfx/shader_glsl.h +++ b/gfx/shader_glsl.h @@ -18,12 +18,9 @@ #define __RARCH_GLSL_H #include "../boolean.h" -#include "gl_common.h" -#include "gfx_context.h" -#include "math/matrix.h" +#include "shader_common.h" bool gl_glsl_init(const char *path); - void gl_glsl_deinit(void); void gl_glsl_set_params(unsigned width, unsigned height, @@ -46,4 +43,6 @@ bool gl_glsl_set_mvp(const math_matrix *mat); void gl_glsl_set_get_proc_address(gfx_ctx_proc_t (*proc)(const char*)); +extern const gl_shader_backend_t gl_glsl_backend; + #endif