Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}