static bool gl_glsl_load_shader(unsigned index, const char *path) { pglUseProgram(0); if (gl_program[index] != gl_program[0]) { gl_glsl_delete_shader(gl_program[index]); gl_program[index] = 0; } if (path) { struct shader_program prog = {0}; unsigned progs = get_xml_shaders(path, &prog, 1); if (progs != 1) return false; if (!compile_programs(&gl_program[index], &prog, 1)) { RARCH_ERR("Failed to compile shader: %s.\n", path); return false; } find_uniforms(gl_program[index], &gl_uniforms[index]); } else { gl_program[index] = gl_program[0]; gl_uniforms[index] = gl_uniforms[0]; } pglUseProgram(gl_program[active_index]); return true; }
bool gl_glsl_init(const char *path) { #if !defined(HAVE_OPENGLES2) && !defined(HAVE_OPENGL_MODERN) && !defined(__APPLE__) // Load shader functions. LOAD_GL_SYM(CreateProgram); LOAD_GL_SYM(UseProgram); LOAD_GL_SYM(CreateShader); LOAD_GL_SYM(DeleteShader); LOAD_GL_SYM(ShaderSource); LOAD_GL_SYM(CompileShader); LOAD_GL_SYM(AttachShader); LOAD_GL_SYM(DetachShader); LOAD_GL_SYM(LinkProgram); LOAD_GL_SYM(GetUniformLocation); LOAD_GL_SYM(Uniform1i); LOAD_GL_SYM(Uniform1f); LOAD_GL_SYM(Uniform2fv); LOAD_GL_SYM(Uniform4fv); LOAD_GL_SYM(UniformMatrix4fv); LOAD_GL_SYM(GetShaderiv); LOAD_GL_SYM(GetShaderInfoLog); LOAD_GL_SYM(GetProgramiv); LOAD_GL_SYM(GetProgramInfoLog); LOAD_GL_SYM(DeleteProgram); LOAD_GL_SYM(GetAttachedShaders); LOAD_GL_SYM(GetAttribLocation); LOAD_GL_SYM(EnableVertexAttribArray); LOAD_GL_SYM(DisableVertexAttribArray); LOAD_GL_SYM(VertexAttribPointer); RARCH_LOG("Checking GLSL shader support ...\n"); bool shader_support = pglCreateProgram && pglUseProgram && pglCreateShader && pglDeleteShader && pglShaderSource && pglCompileShader && pglAttachShader && pglDetachShader && pglLinkProgram && pglGetUniformLocation && pglUniform1i && pglUniform1f && pglUniform2fv && pglUniform4fv && pglUniformMatrix4fv && pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog && pglDeleteProgram && pglGetAttachedShaders && pglGetAttribLocation && pglEnableVertexAttribArray && pglDisableVertexAttribArray && pglVertexAttribPointer; if (!shader_support) { RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n"); return false; } #endif unsigned num_progs = 0; struct shader_program progs[RARCH_GLSL_MAX_SHADERS] = {{0}}; if (path) { num_progs = get_xml_shaders(path, progs, RARCH_GLSL_MAX_SHADERS - 1); if (num_progs == 0) { RARCH_ERR("Couldn't find any valid shaders in XML file.\n"); return false; } } else { RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n"); num_progs = 1; progs[0].vertex = strdup(stock_vertex_modern); progs[0].fragment = strdup(stock_fragment_modern); glsl_modern = true; } #ifdef HAVE_OPENGLES2 if (!glsl_modern) { RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n"); return false; } #endif struct shader_program stock_prog = {0}; stock_prog.vertex = strdup(glsl_modern ? stock_vertex_modern : stock_vertex_legacy); stock_prog.fragment = strdup(glsl_modern ? stock_fragment_modern : stock_fragment_legacy); if (!compile_programs(&gl_program[0], &stock_prog, 1)) { RARCH_ERR("GLSL stock programs failed to compile.\n"); return false; } for (unsigned i = 0; i < num_progs; i++) { gl_filter_type[i + 1] = progs[i].filter; gl_scale[i + 1].type_x = progs[i].type_x; gl_scale[i + 1].type_y = progs[i].type_y; gl_scale[i + 1].scale_x = progs[i].scale_x; gl_scale[i + 1].scale_y = progs[i].scale_y; gl_scale[i + 1].abs_x = progs[i].abs_x; gl_scale[i + 1].abs_y = progs[i].abs_y; gl_scale[i + 1].valid = progs[i].valid_scale; } if (!compile_programs(&gl_program[1], progs, num_progs)) return false; // 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); if (secondary_progs == 1) { if (!compile_programs(&gl_program[2], progs, 1)) { RARCH_ERR("Failed to compile second pass shader.\n"); return false; } num_progs++; } else { RARCH_ERR("Did not find exactly one valid shader in secondary shader file.\n"); return false; } } for (unsigned i = 0; i <= num_progs; i++) find_uniforms(gl_program[i], &gl_uniforms[i]); #ifdef GLSL_DEBUG if (!gl_check_error()) RARCH_WARN("Detected GL error in GLSL.\n"); #endif if (gl_tracker_info_cnt > 0) { struct state_tracker_info info = {0}; info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); info.info = gl_tracker_info; info.info_elem = gl_tracker_info_cnt; #ifdef HAVE_PYTHON info.script = gl_script_program; info.script_class = *gl_tracker_script_class ? gl_tracker_script_class : NULL; info.script_is_file = false; #endif gl_state_tracker = state_tracker_init(&info); if (!gl_state_tracker) RARCH_WARN("Failed to init state tracker.\n"); } glsl_enable = true; gl_num_programs = num_progs; gl_program[gl_num_programs + 1] = gl_program[0]; gl_uniforms[gl_num_programs + 1] = gl_uniforms[0]; gl_glsl_reset_attrib(); return true; }
bool gl_glsl_init(const char *path) { #ifndef __APPLE__ // Load shader functions. LOAD_GL_SYM(CreateProgram); LOAD_GL_SYM(UseProgram); LOAD_GL_SYM(CreateShader); LOAD_GL_SYM(DeleteShader); LOAD_GL_SYM(ShaderSource); LOAD_GL_SYM(CompileShader); LOAD_GL_SYM(AttachShader); LOAD_GL_SYM(DetachShader); LOAD_GL_SYM(LinkProgram); LOAD_GL_SYM(GetUniformLocation); LOAD_GL_SYM(Uniform1i); LOAD_GL_SYM(Uniform1f); LOAD_GL_SYM(Uniform2fv); LOAD_GL_SYM(Uniform4fv); LOAD_GL_SYM(GetShaderiv); LOAD_GL_SYM(GetShaderInfoLog); LOAD_GL_SYM(GetProgramiv); LOAD_GL_SYM(GetProgramInfoLog); LOAD_GL_SYM(DeleteProgram); LOAD_GL_SYM(GetAttachedShaders); LOAD_GL_SYM(GetAttribLocation); LOAD_GL_SYM(EnableVertexAttribArray); LOAD_GL_SYM(DisableVertexAttribArray); LOAD_GL_SYM(VertexAttribPointer); #endif RARCH_LOG("Checking GLSL shader support ...\n"); #ifdef __APPLE__ const bool shader_support = true; #else bool shader_support = pglCreateProgram && pglUseProgram && pglCreateShader && pglDeleteShader && pglShaderSource && pglCompileShader && pglAttachShader && pglDetachShader && pglLinkProgram && pglGetUniformLocation && pglUniform1i && pglUniform1f && pglUniform2fv && pglUniform4fv && pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog && pglDeleteProgram && pglGetAttachedShaders && pglGetAttribLocation && pglEnableVertexAttribArray && pglDisableVertexAttribArray && pglVertexAttribPointer; #endif if (!shader_support) { RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n"); return false; } struct shader_program stock_prog = {0}; stock_prog.vertex = strdup(stock_vertex); stock_prog.fragment = strdup(stock_fragment); if (!compile_programs(&gl_program[0], &stock_prog, 1)) return false; struct shader_program progs[MAX_PROGRAMS]; unsigned num_progs = get_xml_shaders(path, progs, MAX_PROGRAMS - 1); if (num_progs == 0) { RARCH_ERR("Couldn't find any valid shaders in XML file.\n"); return false; } for (unsigned i = 0; i < num_progs; i++) { gl_filter_type[i + 1] = progs[i].filter; gl_scale[i + 1].type_x = progs[i].type_x; gl_scale[i + 1].type_y = progs[i].type_y; gl_scale[i + 1].scale_x = progs[i].scale_x; gl_scale[i + 1].scale_y = progs[i].scale_y; gl_scale[i + 1].abs_x = progs[i].abs_x; gl_scale[i + 1].abs_y = progs[i].abs_y; gl_scale[i + 1].valid = progs[i].valid_scale; } if (!compile_programs(&gl_program[1], progs, num_progs)) return false; // 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); if (secondary_progs == 1) { compile_programs(&gl_program[2], progs, 1); num_progs++; } else { RARCH_ERR("Did not find valid shader in secondary shader file.\n"); return false; } } //if (!gl_check_error()) // RARCH_WARN("Detected GL error.\n"); if (gl_tracker_info_cnt > 0) { struct state_tracker_info info = {0}; info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); info.info = gl_tracker_info; info.info_elem = gl_tracker_info_cnt; #ifdef HAVE_PYTHON if (*gl_tracker_script) info.script = gl_tracker_script; else if (gl_script_program) info.script = (const char*)gl_script_program; else info.script = NULL; info.script_class = *gl_tracker_script_class ? gl_tracker_script_class : NULL; info.script_is_file = *gl_tracker_script; #endif gl_state_tracker = state_tracker_init(&info); if (!gl_state_tracker) RARCH_WARN("Failed to init state tracker.\n"); } glsl_enable = true; gl_num_programs = num_progs; gl_program[gl_num_programs + 1] = gl_program[0]; gl_glsl_reset_attrib(); return true; }