From 79275b28ff4af04e1eb04a725dcd4e2657b86579 Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 5 Jun 2013 10:42:39 +0200 Subject: [PATCH] Fallback when initial shader init fails. --- gfx/gl.c | 11 ++++- gfx/shader_cg.c | 13 +++--- gfx/shader_glsl.c | 102 +++++++++++++++++++++++----------------------- 3 files changed, 66 insertions(+), 60 deletions(-) diff --git a/gfx/gl.c b/gfx/gl.c index 5c790817b2..383e0db945 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -301,7 +301,14 @@ static bool gl_shader_init(void *data) } gl->shader = backend; - return gl->shader->init(shader_path); + bool ret = gl->shader->init(shader_path); + if (!ret) + { + RARCH_ERR("[GL]: Failed to init shader, falling back to stock.\n"); + ret = gl->shader->init(NULL); + } + + return ret; } static inline void gl_shader_deinit(void *data) @@ -1910,7 +1917,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo if (!gl_shader_init(gl)) { - RARCH_ERR("Shader init failed.\n"); + RARCH_ERR("[GL]: Shader init failed.\n"); context_destroy_func(); free(gl); return NULL; diff --git a/gfx/shader_cg.c b/gfx/shader_cg.c index 7b57be65f6..58b913dd38 100644 --- a/gfx/shader_cg.c +++ b/gfx/shader_cg.c @@ -388,9 +388,6 @@ static void gl_cg_deinit_context_state(void) // Full deinit. static void gl_cg_deinit(void) { - if (!cg_active) - return; - gl_cg_deinit_state(); gl_cg_deinit_context_state(); } @@ -786,7 +783,7 @@ static bool gl_cg_init(const char *path) if (cgFProf == CG_PROFILE_UNKNOWN || cgVProf == CG_PROFILE_UNKNOWN) { RARCH_ERR("Invalid profile type\n"); - return false; + goto error; } #ifndef HAVE_RGL RARCH_LOG("[Cg]: Vertex profile: %s\n", cgGetProfileString(cgVProf)); @@ -800,12 +797,12 @@ static bool gl_cg_init(const char *path) if (path && strcmp(path_get_extension(path), "cgp") == 0) { if (!load_preset(path)) - return false; + goto error; } else { if (!load_plain(path)) - return false; + goto error; } prg[0].mvp = cgGetNamedParameter(prg[0].vprg, "modelViewProj"); @@ -826,6 +823,10 @@ static bool gl_cg_init(const char *path) cg_active = true; return true; + +error: + gl_cg_deinit(); + return false; } static void gl_cg_use(unsigned index) diff --git a/gfx/shader_glsl.c b/gfx/shader_glsl.c index 48fda5280b..4b4c8a5a73 100644 --- a/gfx/shader_glsl.c +++ b/gfx/shader_glsl.c @@ -644,6 +644,42 @@ static void gl_glsl_free_shader(void) glsl_shader = NULL; } +static void gl_glsl_deinit(void) +{ + pglUseProgram(0); + for (unsigned i = 0; i < GFX_MAX_SHADERS; i++) + { + if (gl_program[i] == 0 || (i && gl_program[i] == gl_program[0])) + continue; + + gl_glsl_delete_shader(gl_program[i]); + } + + if (glsl_shader && glsl_shader->luts) + glDeleteTextures(glsl_shader->luts, gl_teximage); + + memset(gl_program, 0, sizeof(gl_program)); + glsl_enable = false; + active_index = 0; + + gl_glsl_free_shader(); + + if (gl_state_tracker) + state_tracker_free(gl_state_tracker); + gl_state_tracker = NULL; + + gl_glsl_reset_attrib(); + + for (unsigned i = 0; i < GFX_MAX_SHADERS; i++) + { + if (glsl_vbo[i].vbo_primary) + pglDeleteBuffers(1, &glsl_vbo[i].vbo_primary); + if (glsl_vbo[i].vbo_secondary) + pglDeleteBuffers(1, &glsl_vbo[i].vbo_secondary); + } + memset(&glsl_vbo, 0, sizeof(glsl_vbo)); +} + static bool gl_glsl_init(const char *path) { #if !defined(HAVE_OPENGLES2) && !defined(HAVE_OPENGL_MODERN) && !defined(__APPLE__) @@ -742,37 +778,32 @@ static bool gl_glsl_init(const char *path) gfx_shader_resolve_relative(glsl_shader, path); -#ifdef HAVE_OPENGLES2 - if (!glsl_shader->modern) - { - RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n"); - return false; - } -#endif - const char *stock_vertex = glsl_shader->modern ? stock_vertex_modern : stock_vertex_legacy; const char *stock_fragment = glsl_shader->modern ? stock_fragment_modern : stock_fragment_legacy; +#ifdef HAVE_OPENGLES2 + if (!glsl_shader->modern) + { + RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n"); + goto error; + } +#endif + if (!(gl_program[0] = compile_program(stock_vertex, stock_fragment, 0))) { RARCH_ERR("GLSL stock programs failed to compile.\n"); - gl_glsl_free_shader(); - return false; + goto error; } if (!compile_programs(&gl_program[1])) - { - gl_glsl_free_shader(); - return false; - } + goto error; if (!load_luts()) { RARCH_ERR("[GL]: Failed to load LUTs.\n"); - gl_glsl_free_shader(); - return false; + goto error; } for (unsigned i = 0; i <= glsl_shader->passes; i++) @@ -827,43 +858,10 @@ static bool gl_glsl_init(const char *path) } return true; -} -static void gl_glsl_deinit(void) -{ - if (glsl_enable) - { - pglUseProgram(0); - for (unsigned i = 0; i < GFX_MAX_SHADERS; i++) - { - if (gl_program[i] == 0 || (i && gl_program[i] == gl_program[0])) - continue; - - gl_glsl_delete_shader(gl_program[i]); - } - - if (glsl_shader) - glDeleteTextures(glsl_shader->luts, gl_teximage); - } - - memset(gl_program, 0, sizeof(gl_program)); - glsl_enable = false; - active_index = 0; - - gl_glsl_free_shader(); - - if (gl_state_tracker) - state_tracker_free(gl_state_tracker); - gl_state_tracker = NULL; - - gl_glsl_reset_attrib(); - - for (unsigned i = 0; i < GFX_MAX_SHADERS; i++) - { - pglDeleteBuffers(1, &glsl_vbo[i].vbo_primary); - pglDeleteBuffers(1, &glsl_vbo[i].vbo_secondary); - } - memset(&glsl_vbo, 0, sizeof(glsl_vbo)); +error: + gl_glsl_deinit(); + return false; } static void gl_glsl_set_params(unsigned width, unsigned height,