From d0340d0f80a4130022e0ba69ba7fc3e5c7ab335d Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 1 Dec 2015 07:12:26 +0100 Subject: [PATCH] (GLSL) Fix regression --- driver.h | 1 + gfx/drivers_shader/shader_glsl.c | 436 +++++++++++++++++-------------- 2 files changed, 239 insertions(+), 198 deletions(-) diff --git a/driver.h b/driver.h index 0738fb8228..a6a926a174 100644 --- a/driver.h +++ b/driver.h @@ -205,6 +205,7 @@ typedef struct driver void *camera_data; void *location_data; void *recording_data; + void *video_shader_data; void *netplay_data; void *ui_companion_data; diff --git a/gfx/drivers_shader/shader_glsl.c b/gfx/drivers_shader/shader_glsl.c index 904091c893..efe59b8a38 100644 --- a/gfx/drivers_shader/shader_glsl.c +++ b/gfx/drivers_shader/shader_glsl.c @@ -221,19 +221,18 @@ typedef struct glsl_shader_data state_tracker_t *gl_state_tracker; } glsl_shader_data_t; -static glsl_shader_data_t *glsl_data; - static bool glsl_core; static unsigned glsl_major; static unsigned glsl_minor; -static GLint glsl_get_uniform(GLuint prog, const char *base) +static GLint get_uniform(glsl_shader_data_t *glsl, + GLuint prog, const char *base) { unsigned i; GLint loc; char buf[64] = {0}; - snprintf(buf, sizeof(buf), "%s%s", glsl_data->shader->prefix, base); + snprintf(buf, sizeof(buf), "%s%s", glsl->shader->prefix, base); loc = glGetUniformLocation(prog, buf); if (loc >= 0) return loc; @@ -249,13 +248,14 @@ static GLint glsl_get_uniform(GLuint prog, const char *base) return -1; } -static GLint glsl_get_attrib(GLuint prog, const char *base) +static GLint get_attrib(glsl_shader_data_t *glsl, + GLuint prog, const char *base) { unsigned i; GLint loc; char buf[64] = {0}; - snprintf(buf, sizeof(buf), "%s%s", glsl_data->shader->prefix, base); + snprintf(buf, sizeof(buf), "%s%s", glsl->shader->prefix, base); loc = glGetUniformLocation(prog, buf); if (loc >= 0) return loc; @@ -293,7 +293,7 @@ static void print_shader_log(GLuint obj) free(info_log); } -static void glsl_print_linker_log(GLuint obj) +static void print_linker_log(GLuint obj) { char *info_log = NULL; GLint max_len, info_len = 0; @@ -315,7 +315,9 @@ static void glsl_print_linker_log(GLuint obj) free(info_log); } -static bool glsl_compile_shader(GLuint shader, const char *define, const char *program) +static bool compile_shader(glsl_shader_data_t *glsl, + GLuint shader, + const char *define, const char *program) { GLint status; const char *source[4]; @@ -346,9 +348,9 @@ static bool glsl_compile_shader(GLuint shader, const char *define, const char *p RARCH_LOG("[GL]: Using GLSL version %u.\n", version_no); } - source[0] = version; + source[0]= version; source[1] = define; - source[2] = glsl_data->glsl_alias_define; + source[2] = glsl->glsl_alias_define; source[3] = program; glShaderSource(shader, ARRAY_SIZE(source), source, NULL); @@ -367,7 +369,7 @@ static bool link_program(GLuint prog) glLinkProgram(prog); glGetProgramiv(prog, GL_LINK_STATUS, &status); - glsl_print_linker_log(prog); + print_linker_log(prog); if (status != GL_TRUE) return false; @@ -376,7 +378,9 @@ static bool link_program(GLuint prog) return true; } -static GLuint glsl_compile_program(const char *vertex, const char *fragment, unsigned i) +static GLuint compile_program(glsl_shader_data_t *glsl, + const char *vertex, + const char *fragment, unsigned i) { GLuint vert = 0, frag = 0, prog = glCreateProgram(); if (!prog) @@ -386,7 +390,8 @@ static GLuint glsl_compile_program(const char *vertex, const char *fragment, uns { RARCH_LOG("Found GLSL vertex shader.\n"); vert = glCreateShader(GL_VERTEX_SHADER); - if (!glsl_compile_shader( + if (!compile_shader( + glsl, vert, "#define VERTEX\n#define PARAMETER_UNIFORM\n", vertex)) { RARCH_ERR("Failed to compile vertex shader #%u\n", i); @@ -400,7 +405,7 @@ static GLuint glsl_compile_program(const char *vertex, const char *fragment, uns { RARCH_LOG("Found GLSL fragment shader.\n"); frag = glCreateShader(GL_FRAGMENT_SHADER); - if (!glsl_compile_shader(frag, + if (!compile_shader(glsl, frag, "#define FRAGMENT\n#define PARAMETER_UNIFORM\n", fragment)) { RARCH_ERR("Failed to compile fragment shader #%u\n", i); @@ -428,7 +433,7 @@ static GLuint glsl_compile_program(const char *vertex, const char *fragment, uns glDeleteShader(frag); glUseProgram(prog); - glUniform1i(glsl_get_uniform(prog, "Texture"), 0); + glUniform1i(get_uniform(glsl, prog, "Texture"), 0); glUseProgram(0); } @@ -447,16 +452,16 @@ static bool load_source_path(struct video_shader_pass *pass, return pass->source.string.fragment && pass->source.string.vertex; } -static bool glsl_compile_programs(GLuint *gl_prog) +static bool compile_programs(glsl_shader_data_t *glsl, GLuint *gl_prog) { unsigned i; - for (i = 0; i < glsl_data->shader->passes; i++) + for (i = 0; i < glsl->shader->passes; i++) { const char *vertex = NULL; const char *fragment = NULL; struct video_shader_pass *pass = (struct video_shader_pass*) - &glsl_data->shader->pass[i]; + &glsl->shader->pass[i]; /* If we load from GLSLP (CGP), * load the file here, and pretend @@ -472,7 +477,7 @@ static bool glsl_compile_programs(GLuint *gl_prog) vertex = pass->source.string.vertex; fragment = pass->source.string.fragment; - gl_prog[i] = glsl_compile_program(vertex, fragment, i); + gl_prog[i] = compile_program(glsl, vertex, fragment, i); if (!gl_prog[i]) { @@ -484,16 +489,16 @@ static bool glsl_compile_programs(GLuint *gl_prog) return true; } -static void gl_glsl_reset_attrib(void) +static void gl_glsl_reset_attrib(glsl_shader_data_t *glsl) { unsigned i; /* Add sanity check that we did not overflow. */ - retro_assert(glsl_data->gl_attrib_index <= ARRAY_SIZE(glsl_data->gl_attribs)); + retro_assert(glsl->gl_attrib_index <= ARRAY_SIZE(glsl->gl_attribs)); - for (i = 0; i < glsl_data->gl_attrib_index; i++) - glDisableVertexAttribArray(glsl_data->gl_attribs[i]); - glsl_data->gl_attrib_index = 0; + for (i = 0; i < glsl->gl_attrib_index; i++) + glDisableVertexAttribArray(glsl->gl_attribs[i]); + glsl->gl_attrib_index = 0; } static void gl_glsl_set_vbo(GLfloat **buffer, size_t *buffer_elems, @@ -517,7 +522,7 @@ static void gl_glsl_set_vbo(GLfloat **buffer, size_t *buffer_elems, } } -static void gl_glsl_set_attribs( +static void gl_glsl_set_attribs(glsl_shader_data_t *glsl, GLuint vbo, GLfloat **buffer, size_t *buffer_elems, const GLfloat *data, size_t elems, @@ -533,12 +538,12 @@ static void gl_glsl_set_attribs( { GLint loc = attrs[i].loc; - if (glsl_data->gl_attrib_index < ARRAY_SIZE(glsl_data->gl_attribs)) + if (glsl->gl_attrib_index < ARRAY_SIZE(glsl->gl_attribs)) { glEnableVertexAttribArray(loc); glVertexAttribPointer(loc, attrs[i].size, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)(uintptr_t)attrs[i].offset); - glsl_data->gl_attribs[glsl_data->gl_attrib_index++] = loc; + glsl->gl_attribs[glsl->gl_attrib_index++] = loc; } else RARCH_WARN("Attrib array buffer was overflown!\n"); @@ -555,7 +560,8 @@ static void clear_uniforms_frame(struct shader_uniforms_frame *frame) frame->tex_coord = -1; } -static void glsl_find_uniforms_frame(GLuint prog, +static void find_uniforms_frame(glsl_shader_data_t *glsl, + GLuint prog, struct shader_uniforms_frame *frame, const char *base) { char texture[64] = {0}; @@ -569,16 +575,16 @@ static void glsl_find_uniforms_frame(GLuint prog, snprintf(tex_coord, sizeof(tex_coord), "%s%s", base, "TexCoord"); if (frame->texture < 0) - frame->texture = glsl_get_uniform(prog, texture); + frame->texture = get_uniform(glsl, prog, texture); if (frame->texture_size < 0) - frame->texture_size = glsl_get_uniform(prog, texture_size); + frame->texture_size = get_uniform(glsl, prog, texture_size); if (frame->input_size < 0) - frame->input_size = glsl_get_uniform(prog, input_size); + frame->input_size = get_uniform(glsl, prog, input_size); if (frame->tex_coord < 0) - frame->tex_coord = glsl_get_attrib(prog, tex_coord); + frame->tex_coord = get_attrib(glsl, prog, tex_coord); } -static void glsl_find_uniforms( +static void find_uniforms(glsl_shader_data_t *glsl, unsigned pass, GLuint prog, struct shader_uniforms *uni) { @@ -587,141 +593,148 @@ static void glsl_find_uniforms( glUseProgram(prog); - uni->mvp = glsl_get_uniform(prog, "MVPMatrix"); - uni->tex_coord = glsl_get_attrib(prog, "TexCoord"); - uni->vertex_coord = glsl_get_attrib(prog, "VertexCoord"); - uni->color = glsl_get_attrib(prog, "Color"); - uni->lut_tex_coord = glsl_get_attrib(prog, "LUTTexCoord"); + uni->mvp = get_uniform(glsl, prog, "MVPMatrix"); + uni->tex_coord = get_attrib(glsl, prog, "TexCoord"); + uni->vertex_coord = get_attrib(glsl, prog, "VertexCoord"); + uni->color = get_attrib(glsl, prog, "Color"); + uni->lut_tex_coord = get_attrib(glsl, prog, "LUTTexCoord"); - uni->input_size = glsl_get_uniform(prog, "InputSize"); - uni->output_size = glsl_get_uniform(prog, "OutputSize"); - uni->texture_size = glsl_get_uniform(prog, "TextureSize"); + uni->input_size = get_uniform(glsl, prog, "InputSize"); + uni->output_size = get_uniform(glsl, prog, "OutputSize"); + uni->texture_size = get_uniform(glsl, prog, "TextureSize"); - uni->frame_count = glsl_get_uniform(prog, "FrameCount"); - uni->frame_direction = glsl_get_uniform(prog, "FrameDirection"); + uni->frame_count = get_uniform(glsl, prog, "FrameCount"); + uni->frame_direction = get_uniform(glsl, prog, "FrameDirection"); - for (i = 0; i < glsl_data->shader->luts; i++) - uni->lut_texture[i] = glGetUniformLocation(prog, glsl_data->shader->lut[i].id); + for (i = 0; i < glsl->shader->luts; i++) + uni->lut_texture[i] = glGetUniformLocation(prog, glsl->shader->lut[i].id); clear_uniforms_frame(&uni->orig); - glsl_find_uniforms_frame(prog, &uni->orig, "Orig"); + find_uniforms_frame(glsl, prog, &uni->orig, "Orig"); clear_uniforms_frame(&uni->feedback); - glsl_find_uniforms_frame(prog, &uni->feedback, "Feedback"); + find_uniforms_frame(glsl, prog, &uni->feedback, "Feedback"); if (pass > 1) { snprintf(frame_base, sizeof(frame_base), "PassPrev%u", pass); - glsl_find_uniforms_frame(prog, &uni->orig, frame_base); + find_uniforms_frame(glsl, prog, &uni->orig, frame_base); } for (i = 0; i + 1 < pass; i++) { snprintf(frame_base, sizeof(frame_base), "Pass%u", i + 1); clear_uniforms_frame(&uni->pass[i]); - glsl_find_uniforms_frame(prog, &uni->pass[i], frame_base); + find_uniforms_frame(glsl, prog, &uni->pass[i], frame_base); snprintf(frame_base, sizeof(frame_base), "PassPrev%u", pass - (i + 1)); - glsl_find_uniforms_frame(prog, &uni->pass[i], frame_base); + find_uniforms_frame(glsl, prog, &uni->pass[i], frame_base); - if (*glsl_data->shader->pass[i].alias) - glsl_find_uniforms_frame(prog, &uni->pass[i], glsl_data->shader->pass[i].alias); + if (*glsl->shader->pass[i].alias) + find_uniforms_frame(glsl, prog, &uni->pass[i], glsl->shader->pass[i].alias); } clear_uniforms_frame(&uni->prev[0]); - glsl_find_uniforms_frame(prog, &uni->prev[0], "Prev"); + find_uniforms_frame(glsl, prog, &uni->prev[0], "Prev"); for (i = 1; i < PREV_TEXTURES; i++) { snprintf(frame_base, sizeof(frame_base), "Prev%u", i); clear_uniforms_frame(&uni->prev[i]); - glsl_find_uniforms_frame(prog, &uni->prev[i], frame_base); + find_uniforms_frame(glsl, prog, &uni->prev[i], frame_base); } glUseProgram(0); } -static void gl_glsl_deinit_shader(void) +static void gl_glsl_deinit_shader(glsl_shader_data_t *glsl) { unsigned i; - if (!glsl_data || !glsl_data->shader) + if (!glsl || !glsl->shader) return; - for (i = 0; i < glsl_data->shader->passes; i++) + for (i = 0; i < glsl->shader->passes; i++) { - free(glsl_data->shader->pass[i].source.string.vertex); - free(glsl_data->shader->pass[i].source.string.fragment); + free(glsl->shader->pass[i].source.string.vertex); + free(glsl->shader->pass[i].source.string.fragment); } - free(glsl_data->shader->script); - free(glsl_data->shader); - glsl_data->shader = NULL; + free(glsl->shader->script); + free(glsl->shader); + glsl->shader = NULL; } -static void gl_glsl_destroy_resources(void) +static void gl_glsl_destroy_resources(glsl_shader_data_t *glsl) { unsigned i; - if (!glsl_data) + if (!glsl) return; glUseProgram(0); for (i = 0; i < GFX_MAX_SHADERS; i++) { - if (glsl_data->gl_program[i] == 0 || (i && glsl_data->gl_program[i] == glsl_data->gl_program[0])) + if (glsl->gl_program[i] == 0 || (i && glsl->gl_program[i] == glsl->gl_program[0])) continue; - glDeleteProgram(glsl_data->gl_program[i]); + glDeleteProgram(glsl->gl_program[i]); } - if (glsl_data->shader && glsl_data->shader->luts) - glDeleteTextures(glsl_data->shader->luts, glsl_data->gl_teximage); + if (glsl->shader && glsl->shader->luts) + glDeleteTextures(glsl->shader->luts, glsl->gl_teximage); - memset(glsl_data->gl_program, 0, sizeof(glsl_data->gl_program)); - memset(glsl_data->gl_uniforms, 0, sizeof(glsl_data->gl_uniforms)); - glsl_data->glsl_active_index = 0; + memset(glsl->gl_program, 0, sizeof(glsl->gl_program)); + memset(glsl->gl_uniforms, 0, sizeof(glsl->gl_uniforms)); + glsl->glsl_active_index = 0; - gl_glsl_deinit_shader(); + gl_glsl_deinit_shader(glsl); - if (glsl_data->gl_state_tracker) - state_tracker_free(glsl_data->gl_state_tracker); - glsl_data->gl_state_tracker = NULL; + if (glsl->gl_state_tracker) + state_tracker_free(glsl->gl_state_tracker); + glsl->gl_state_tracker = NULL; - gl_glsl_reset_attrib(); + gl_glsl_reset_attrib(glsl); for (i = 0; i < GFX_MAX_SHADERS; i++) { - if (glsl_data->glsl_vbo[i].vbo_primary) - glDeleteBuffers(1, &glsl_data->glsl_vbo[i].vbo_primary); - if (glsl_data->glsl_vbo[i].vbo_secondary) - glDeleteBuffers(1, &glsl_data->glsl_vbo[i].vbo_secondary); + if (glsl->glsl_vbo[i].vbo_primary) + glDeleteBuffers(1, &glsl->glsl_vbo[i].vbo_primary); + if (glsl->glsl_vbo[i].vbo_secondary) + glDeleteBuffers(1, &glsl->glsl_vbo[i].vbo_secondary); - free(glsl_data->glsl_vbo[i].buffer_primary); - free(glsl_data->glsl_vbo[i].buffer_secondary); + free(glsl->glsl_vbo[i].buffer_primary); + free(glsl->glsl_vbo[i].buffer_secondary); } - memset(&glsl_data->glsl_vbo, 0, sizeof(glsl_data->glsl_vbo)); + memset(&glsl->glsl_vbo, 0, sizeof(glsl->glsl_vbo)); } static void gl_glsl_deinit(void) { - if (!glsl_data) + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; + + if (!glsl) return; - gl_glsl_destroy_resources(); + gl_glsl_destroy_resources(glsl); - if (glsl_data) - free(glsl_data); - glsl_data = NULL; + if (driver->video_shader_data) + free(driver->video_shader_data); + driver->video_shader_data = NULL; } static bool gl_glsl_init(void *data, const char *path) { unsigned i; config_file_t *conf = NULL; + glsl_shader_data_t *glsl = NULL; const char *stock_vertex = NULL; const char *stock_fragment = NULL; + driver_t *driver = driver_get_ptr(); - glsl_data = (glsl_shader_data_t*)calloc(1, sizeof(glsl_shader_data_t)); + (void)data; - if (!glsl_data) + glsl = (glsl_shader_data_t*)calloc(1, sizeof(glsl_shader_data_t)); + + if (!glsl) return false; #ifndef HAVE_OPENGLES2 @@ -742,17 +755,15 @@ static bool gl_glsl_init(void *data, const char *path) if (!shader_support) { RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n"); - free(glsl_data); - glsl_data = NULL; + free(glsl); return false; } #endif - glsl_data->shader = (struct video_shader*)calloc(1, sizeof(*glsl_data->shader)); - if (!glsl_data->shader) + glsl->shader = (struct video_shader*)calloc(1, sizeof(*glsl->shader)); + if (!glsl->shader) { - free(glsl_data); - glsl_data = NULL; + free(glsl); return false; } @@ -763,10 +774,10 @@ static bool gl_glsl_init(void *data, const char *path) if (!strcmp(path_ext, "glsl")) { - strlcpy(glsl_data->shader->pass[0].source.path, path, - sizeof(glsl_data->shader->pass[0].source.path)); - glsl_data->shader->passes = 1; - glsl_data->shader->modern = true; + strlcpy(glsl->shader->pass[0].source.path, path, + sizeof(glsl->shader->pass[0].source.path)); + glsl->shader->passes = 1; + glsl->shader->modern = true; ret = true; } else if (!strcmp(path_ext, "glslp")) @@ -774,8 +785,8 @@ static bool gl_glsl_init(void *data, const char *path) conf = config_file_new(path); if (conf) { - ret = video_shader_read_conf_cgp(conf, glsl_data->shader); - glsl_data->shader->modern = true; + ret = video_shader_read_conf_cgp(conf, glsl->shader); + glsl->shader->modern = true; } else ret = false; @@ -786,25 +797,24 @@ static bool gl_glsl_init(void *data, const char *path) if (!ret) { RARCH_ERR("[GL]: Failed to parse GLSL shader.\n"); - free(glsl_data->shader); - free(glsl_data); - glsl_data = NULL; + free(glsl->shader); + free(glsl); return false; } } else { RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n"); - glsl_data->shader->passes = 1; - glsl_data->shader->pass[0].source.string.vertex = + glsl->shader->passes = 1; + glsl->shader->pass[0].source.string.vertex = strdup(glsl_core ? stock_vertex_core : stock_vertex_modern); - glsl_data->shader->pass[0].source.string.fragment = + glsl->shader->pass[0].source.string.fragment = strdup(glsl_core ? stock_fragment_core : stock_fragment_modern); - glsl_data->shader->modern = true; + glsl->shader->modern = true; } - video_shader_resolve_relative(glsl_data->shader, path); - video_shader_resolve_parameters(conf, glsl_data->shader); + video_shader_resolve_relative(glsl->shader, path); + video_shader_resolve_parameters(conf, glsl->shader); if (conf) { @@ -812,9 +822,9 @@ static bool gl_glsl_init(void *data, const char *path) conf = NULL; } - stock_vertex = (glsl_data->shader->modern) ? + stock_vertex = (glsl->shader->modern) ? stock_vertex_modern : stock_vertex_legacy; - stock_fragment = (glsl_data->shader->modern) ? + stock_fragment = (glsl->shader->modern) ? stock_fragment_modern : stock_fragment_legacy; if (glsl_core) @@ -824,13 +834,13 @@ static bool gl_glsl_init(void *data, const char *path) } #ifdef HAVE_OPENGLES2 - if (!glsl_data->shader->modern) + if (!glsl->shader->modern) { RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n"); goto error; } #else - if (glsl_core && !glsl_data->shader->modern) + if (glsl_core && !glsl->shader->modern) { RARCH_ERR("[GL]: GL core context is used, but shader is not core compatible. Cannot use it.\n"); goto error; @@ -839,97 +849,99 @@ static bool gl_glsl_init(void *data, const char *path) /* Find all aliases we use in our GLSLP and add #defines for them so * that a shader can choose a fallback if we are not using a preset. */ - *glsl_data->glsl_alias_define = '\0'; - for (i = 0; i < glsl_data->shader->passes; i++) + *glsl->glsl_alias_define = '\0'; + for (i = 0; i < glsl->shader->passes; i++) { - if (*glsl_data->shader->pass[i].alias) + if (*glsl->shader->pass[i].alias) { char define[128] = {0}; snprintf(define, sizeof(define), "#define %s_ALIAS\n", - glsl_data->shader->pass[i].alias); - strlcat(glsl_data->glsl_alias_define, define, sizeof(glsl_data->glsl_alias_define)); + glsl->shader->pass[i].alias); + strlcat(glsl->glsl_alias_define, define, sizeof(glsl->glsl_alias_define)); } } - if (!(glsl_data->gl_program[0] = glsl_compile_program(stock_vertex, stock_fragment, 0))) + if (!(glsl->gl_program[0] = compile_program(glsl, stock_vertex, stock_fragment, 0))) { RARCH_ERR("GLSL stock programs failed to compile.\n"); goto error; } - if (!glsl_compile_programs(&glsl_data->gl_program[1])) + if (!compile_programs(glsl, &glsl->gl_program[1])) goto error; - if (!gl_load_luts(glsl_data->shader, glsl_data->gl_teximage)) + if (!gl_load_luts(glsl->shader, glsl->gl_teximage)) { RARCH_ERR("[GL]: Failed to load LUTs.\n"); goto error; } - for (i = 0; i <= glsl_data->shader->passes; i++) - glsl_find_uniforms(i, glsl_data->gl_program[i], &glsl_data->gl_uniforms[i]); + for (i = 0; i <= glsl->shader->passes; i++) + find_uniforms(glsl, i, glsl->gl_program[i], &glsl->gl_uniforms[i]); #ifdef GLSL_DEBUG if (!gl_check_error()) RARCH_WARN("Detected GL error in GLSL.\n"); #endif - if (glsl_data->shader->variables) + if (glsl->shader->variables) { struct state_tracker_info info = {0}; info.wram = (uint8_t*)core.retro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); - info.info = glsl_data->shader->variable; - info.info_elem = glsl_data->shader->variables; + info.info = glsl->shader->variable; + info.info_elem = glsl->shader->variables; #ifdef HAVE_PYTHON - info.script = glsl_data->shader->script; - info.script_class = *glsl_data->shader->script_class ? - glsl_data->shader->script_class : NULL; + info.script = glsl->shader->script; + info.script_class = *glsl->shader->script_class ? + glsl->shader->script_class : NULL; #endif - glsl_data->gl_state_tracker = state_tracker_init(&info); - if (!glsl_data->gl_state_tracker) + glsl->gl_state_tracker = state_tracker_init(&info); + if (!glsl->gl_state_tracker) RARCH_WARN("Failed to init state tracker.\n"); } - glsl_data->gl_program[glsl_data->shader->passes + 1] = glsl_data->gl_program[0]; - glsl_data->gl_uniforms[glsl_data->shader->passes + 1] = glsl_data->gl_uniforms[0]; + glsl->gl_program[glsl->shader->passes + 1] = glsl->gl_program[0]; + glsl->gl_uniforms[glsl->shader->passes + 1] = glsl->gl_uniforms[0]; - if (glsl_data->shader->modern) + if (glsl->shader->modern) { - glsl_data->gl_program[GL_SHADER_STOCK_BLEND] = glsl_compile_program( + glsl->gl_program[GL_SHADER_STOCK_BLEND] = compile_program( + glsl, glsl_core ? stock_vertex_core_blend : stock_vertex_modern_blend, glsl_core ? stock_fragment_core_blend : stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND); - glsl_find_uniforms(0, glsl_data->gl_program[GL_SHADER_STOCK_BLEND], - &glsl_data->gl_uniforms[GL_SHADER_STOCK_BLEND]); + find_uniforms(glsl, 0, glsl->gl_program[GL_SHADER_STOCK_BLEND], + &glsl->gl_uniforms[GL_SHADER_STOCK_BLEND]); } else { - glsl_data->gl_program [GL_SHADER_STOCK_BLEND] = glsl_data->gl_program[0]; - glsl_data->gl_uniforms[GL_SHADER_STOCK_BLEND] = glsl_data->gl_uniforms[0]; + glsl->gl_program [GL_SHADER_STOCK_BLEND] = glsl->gl_program[0]; + glsl->gl_uniforms[GL_SHADER_STOCK_BLEND] = glsl->gl_uniforms[0]; } - gl_glsl_reset_attrib(); + gl_glsl_reset_attrib(glsl); for (i = 0; i < GFX_MAX_SHADERS; i++) { - glGenBuffers(1, &glsl_data->glsl_vbo[i].vbo_primary); - glGenBuffers(1, &glsl_data->glsl_vbo[i].vbo_secondary); + glGenBuffers(1, &glsl->glsl_vbo[i].vbo_primary); + glGenBuffers(1, &glsl->glsl_vbo[i].vbo_secondary); } + driver->video_shader_data = glsl; + return true; error: - gl_glsl_destroy_resources(); + gl_glsl_destroy_resources(glsl); - if (glsl_data) - free(glsl_data); - glsl_data = NULL; + if (glsl) + free(glsl); return false; } @@ -954,15 +966,17 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height, const struct gfx_tex_info *feedback_info = (const struct gfx_tex_info*)_feedback_info; const struct gfx_tex_info *fbo_info = (const struct gfx_tex_info*)_fbo_info; struct glsl_attrib *attr = (struct glsl_attrib*)attribs; + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; - if (!glsl_data) + if (!glsl) return; - uni = (const struct shader_uniforms*)&glsl_data->gl_uniforms[glsl_data->glsl_active_index]; + uni = (const struct shader_uniforms*)&glsl->gl_uniforms[glsl->glsl_active_index]; (void)data; - if (glsl_data->gl_program[glsl_data->glsl_active_index] == 0) + if (glsl->gl_program[glsl->glsl_active_index] == 0) return; input_size [0] = (float)width; @@ -981,9 +995,9 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height, if (uni->texture_size >= 0) glUniform2fv(uni->texture_size, 1, texture_size); - if (uni->frame_count >= 0 && glsl_data->glsl_active_index) + if (uni->frame_count >= 0 && glsl->glsl_active_index) { - unsigned modulo = glsl_data->shader->pass[glsl_data->glsl_active_index - 1].frame_count_mod; + unsigned modulo = glsl->shader->pass[glsl->glsl_active_index - 1].frame_count_mod; if (modulo) frame_count %= modulo; @@ -994,19 +1008,19 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height, glUniform1i(uni->frame_direction, state_manager_frame_is_reversed() ? -1 : 1); - for (i = 0; i < glsl_data->shader->luts; i++) + for (i = 0; i < glsl->shader->luts; i++) { if (uni->lut_texture[i] < 0) continue; /* Have to rebind as HW render could override this. */ glActiveTexture(GL_TEXTURE0 + texunit); - glBindTexture(GL_TEXTURE_2D, glsl_data->gl_teximage[i]); + glBindTexture(GL_TEXTURE_2D, glsl->gl_teximage[i]); glUniform1i(uni->lut_texture[i], texunit); texunit++; } - if (glsl_data->glsl_active_index) + if (glsl->glsl_active_index) { /* Set original texture. */ if (uni->orig.texture >= 0) @@ -1130,37 +1144,37 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height, if (size) { - gl_glsl_set_attribs(glsl_data->glsl_vbo[glsl_data->glsl_active_index].vbo_secondary, - &glsl_data->glsl_vbo[glsl_data->glsl_active_index].buffer_secondary, - &glsl_data->glsl_vbo[glsl_data->glsl_active_index].size_secondary, + gl_glsl_set_attribs(glsl, glsl->glsl_vbo[glsl->glsl_active_index].vbo_secondary, + &glsl->glsl_vbo[glsl->glsl_active_index].buffer_secondary, + &glsl->glsl_vbo[glsl->glsl_active_index].size_secondary, buffer, size, attribs, attribs_size); } glActiveTexture(GL_TEXTURE0); /* #pragma parameters. */ - for (i = 0; i < glsl_data->shader->num_parameters; i++) + for (i = 0; i < glsl->shader->num_parameters; i++) { int location = glGetUniformLocation( - glsl_data->gl_program[glsl_data->glsl_active_index], - glsl_data->shader->parameters[i].id); - glUniform1f(location, glsl_data->shader->parameters[i].current); + glsl->gl_program[glsl->glsl_active_index], + glsl->shader->parameters[i].id); + glUniform1f(location, glsl->shader->parameters[i].current); } /* Set state parameters. */ - if (glsl_data->gl_state_tracker) + if (glsl->gl_state_tracker) { static struct state_tracker_uniform state_info[GFX_MAX_VARIABLES]; static unsigned cnt = 0; - if (glsl_data->glsl_active_index == 1) - cnt = state_tracker_get_uniform(glsl_data->gl_state_tracker, state_info, + if (glsl->glsl_active_index == 1) + cnt = state_tracker_get_uniform(glsl->gl_state_tracker, state_info, GFX_MAX_VARIABLES, frame_count); for (i = 0; i < cnt; i++) { int location = glGetUniformLocation( - glsl_data->gl_program[glsl_data->glsl_active_index], + glsl->gl_program[glsl->glsl_active_index], state_info[i].id); glUniform1f(location, state_info[i].value); } @@ -1170,14 +1184,18 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height, static bool gl_glsl_set_mvp(void *data, const math_matrix_4x4 *mat) { int loc; + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; - if (!glsl_data || !glsl_data->shader->modern) + (void)data; + + if (!glsl || !glsl->shader->modern) { gl_ff_matrix(mat); return false; } - loc = glsl_data->gl_uniforms[glsl_data->glsl_active_index].mvp; + loc = glsl->gl_uniforms[glsl->glsl_active_index].mvp; if (loc >= 0) glUniformMatrix4fv(loc, 1, GL_FALSE, mat->data); @@ -1194,8 +1212,10 @@ static bool gl_glsl_set_coords(const void *data) struct glsl_attrib *attr = NULL; const struct shader_uniforms *uni = NULL; const struct gfx_coords *coords = (const struct gfx_coords*)data; + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; - if (!glsl_data || !glsl_data->shader->modern || !coords) + if (!glsl || !glsl->shader->modern || !coords) { gl_ff_vertex(coords); return false; @@ -1213,7 +1233,7 @@ static bool gl_glsl_set_coords(const void *data) } attr = attribs; - uni = &glsl_data->gl_uniforms[glsl_data->glsl_active_index]; + uni = &glsl->gl_uniforms[glsl->glsl_active_index]; if (uni->tex_coord >= 0) { @@ -1269,10 +1289,10 @@ static bool gl_glsl_set_coords(const void *data) if (size) { - gl_glsl_set_attribs( - glsl_data->glsl_vbo[glsl_data->glsl_active_index].vbo_primary, - &glsl_data->glsl_vbo[glsl_data->glsl_active_index].buffer_primary, - &glsl_data->glsl_vbo[glsl_data->glsl_active_index].size_primary, + gl_glsl_set_attribs(glsl, + glsl->glsl_vbo[glsl->glsl_active_index].vbo_primary, + &glsl->glsl_vbo[glsl->glsl_active_index].buffer_primary, + &glsl->glsl_vbo[glsl->glsl_active_index].size_primary, buffer, size, attribs, attribs_size); } @@ -1285,29 +1305,38 @@ static bool gl_glsl_set_coords(const void *data) static void gl_glsl_use(void *data, unsigned idx) { - if (!glsl_data) + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; + + (void)data; + + if (!glsl) return; - gl_glsl_reset_attrib(); + gl_glsl_reset_attrib(glsl); - glsl_data->glsl_active_index = idx; - glUseProgram(glsl_data->gl_program[idx]); + glsl->glsl_active_index = idx; + glUseProgram(glsl->gl_program[idx]); } static unsigned gl_glsl_num(void) { - if (glsl_data && glsl_data->shader) - return glsl_data->shader->passes; + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; + if (glsl && glsl->shader) + return glsl->shader->passes; return 0; } static bool gl_glsl_filter_type(unsigned idx, bool *smooth) { - if (glsl_data && idx - && (glsl_data->shader->pass[idx - 1].filter != RARCH_FILTER_UNSPEC) + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; + if (glsl && idx + && (glsl->shader->pass[idx - 1].filter != RARCH_FILTER_UNSPEC) ) { - *smooth = (glsl_data->shader->pass[idx - 1].filter == RARCH_FILTER_LINEAR); + *smooth = (glsl->shader->pass[idx - 1].filter == RARCH_FILTER_LINEAR); return true; } return false; @@ -1315,15 +1344,19 @@ static bool gl_glsl_filter_type(unsigned idx, bool *smooth) static enum gfx_wrap_type gl_glsl_wrap_type(unsigned idx) { - if (glsl_data && idx) - return glsl_data->shader->pass[idx - 1].wrap; + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; + if (glsl && idx) + return glsl->shader->pass[idx - 1].wrap; return RARCH_WRAP_BORDER; } static void gl_glsl_shader_scale(unsigned idx, struct gfx_fbo_scale *scale) { - if (glsl_data && idx) - *scale = glsl_data->shader->pass[idx - 1].fbo; + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; + if (glsl && idx) + *scale = glsl->shader->pass[idx - 1].fbo; else scale->valid = false; } @@ -1332,13 +1365,15 @@ static unsigned gl_glsl_get_prev_textures(void) { unsigned i, j; unsigned max_prev = 0; + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; - if (!glsl_data) + if (!glsl) return 0; - for (i = 1; i <= glsl_data->shader->passes; i++) + for (i = 1; i <= glsl->shader->passes; i++) for (j = 0; j < PREV_TEXTURES; j++) - if (glsl_data->gl_uniforms[i].prev[j].texture >= 0) + if (glsl->gl_uniforms[i].prev[j].texture >= 0) max_prev = max(j + 1, max_prev); return max_prev; @@ -1346,25 +1381,31 @@ static unsigned gl_glsl_get_prev_textures(void) static bool gl_glsl_mipmap_input(unsigned idx) { - if (glsl_data && idx) - return glsl_data->shader->pass[idx - 1].mipmap; + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; + if (glsl && idx) + return glsl->shader->pass[idx - 1].mipmap; return false; } static bool gl_glsl_get_feedback_pass(unsigned *index) { - if (!glsl_data || glsl_data->shader->feedback_pass < 0) + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; + if (!glsl || glsl->shader->feedback_pass < 0) return false; - *index = glsl_data->shader->feedback_pass; + *index = glsl->shader->feedback_pass; return true; } static struct video_shader *gl_glsl_get_current_shader(void) { - if (!glsl_data) + driver_t *driver = driver_get_ptr(); + glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; + if (!glsl) return NULL; - return glsl_data->shader; + return glsl->shader; } void gl_glsl_set_get_proc_address(gfx_ctx_proc_t (*proc)(const char*)) @@ -1399,4 +1440,3 @@ const shader_backend_t gl_glsl_backend = { RARCH_SHADER_GLSL, "glsl" }; -