mirror of
https://github.com/libretro/RetroArch
synced 2025-04-17 02:43:03 +00:00
Preparation for new XML shader specs.
This commit is contained in:
parent
78c457b996
commit
8b241c3deb
39
gfx/gl.c
39
gfx/gl.c
@ -242,6 +242,24 @@ static inline void gl_shader_set_params(unsigned width, unsigned height,
|
||||
gl_glsl_set_params(width, height, tex_width, tex_height, out_width, out_height);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline unsigned gl_shader_num(void)
|
||||
{
|
||||
unsigned num = 0;
|
||||
#ifdef HAVE_CG
|
||||
unsigned cg_num = gl_cg_num();
|
||||
if (cg_num > num)
|
||||
num = cg_num;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
unsigned glsl_num = gl_glsl_num();
|
||||
if (glsl_num > num)
|
||||
num = glsl_num;
|
||||
#endif
|
||||
|
||||
return num;
|
||||
}
|
||||
///////////////////
|
||||
|
||||
//////////////// Message rendering
|
||||
@ -621,6 +639,9 @@ static void* gl_init(video_info_t *video, const input_driver_t **input, void **i
|
||||
if (!SDL_SetVideoMode(video->width, video->height, 0, SDL_OPENGL | SDL_RESIZABLE | (video->fullscreen ? SDL_FULLSCREEN : 0)))
|
||||
return NULL;
|
||||
|
||||
// Remove that ugly mouse :D
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
|
||||
int attr = 0;
|
||||
SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &attr);
|
||||
if (attr <= 0 && video->vsync)
|
||||
@ -651,13 +672,6 @@ static void* gl_init(video_info_t *video, const input_driver_t **input, void **i
|
||||
|
||||
SSNES_LOG("GL: Using resolution %ux%u\n", gl->win_width, gl->win_height);
|
||||
|
||||
// Set up render to texture.
|
||||
gl_init_fbo(gl, 256 * video->input_scale, 256 * video->input_scale);
|
||||
|
||||
gl->vsync = video->vsync;
|
||||
gl->keep_aspect = video->force_aspect;
|
||||
set_viewport(gl, gl->win_width, gl->win_height, false);
|
||||
|
||||
if (!gl_shader_init())
|
||||
{
|
||||
SSNES_ERR("Shader init failed.\n");
|
||||
@ -666,8 +680,15 @@ static void* gl_init(video_info_t *video, const input_driver_t **input, void **i
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Remove that ugly mouse :D
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
SSNES_LOG("GL: Loaded %u shader(s).\n", gl_shader_num());
|
||||
|
||||
// Set up render to texture.
|
||||
gl_init_fbo(gl, 256 * video->input_scale, 256 * video->input_scale);
|
||||
|
||||
gl->vsync = video->vsync;
|
||||
gl->keep_aspect = video->force_aspect;
|
||||
set_viewport(gl, gl->win_width, gl->win_height, false);
|
||||
|
||||
|
||||
if (video->smooth)
|
||||
gl->tex_filter = GL_LINEAR;
|
||||
|
@ -58,7 +58,6 @@ static const char* stock_cg_program =
|
||||
static CGcontext cgCtx;
|
||||
struct cg_program
|
||||
{
|
||||
CGprogram prg;
|
||||
CGprogram vprg;
|
||||
CGprogram fprg;
|
||||
CGparameter vid_size_f;
|
||||
@ -188,3 +187,16 @@ void gl_cg_use(unsigned index)
|
||||
cgGLBindProgram(prg[index].fprg);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned gl_cg_num(void)
|
||||
{
|
||||
if (cg_active)
|
||||
{
|
||||
if (prg[0].fprg == prg[2].fprg)
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -33,4 +33,6 @@ void gl_cg_set_params(unsigned width, unsigned height,
|
||||
|
||||
void gl_cg_use(unsigned index);
|
||||
|
||||
unsigned gl_cg_num(void);
|
||||
|
||||
#endif
|
||||
|
@ -79,13 +79,20 @@ static PFNGLGETPROGRAMIVPROC pglGetProgramiv = NULL;
|
||||
static PFNGLGETPROGRAMINFOLOGPROC pglGetProgramInfoLog = NULL;
|
||||
#endif
|
||||
|
||||
#define MAX_PROGRAMS 16
|
||||
|
||||
static bool glsl_enable = false;
|
||||
static GLuint gl_program[3] = {0};
|
||||
static GLuint fragment_shader;
|
||||
static GLuint vertex_shader;
|
||||
static GLuint gl_program[MAX_PROGRAMS] = {0};
|
||||
static unsigned gl_num_programs = 0;
|
||||
static unsigned active_index = 0;
|
||||
|
||||
static bool get_xml_shaders(const char *path, char **vertex_shader, char **fragment_shader)
|
||||
struct shader_program
|
||||
{
|
||||
char *vertex;
|
||||
char *fragment;
|
||||
};
|
||||
|
||||
static unsigned get_xml_shaders(const char *path, struct shader_program *prog, size_t size)
|
||||
{
|
||||
LIBXML_TEST_VERSION;
|
||||
|
||||
@ -125,10 +132,11 @@ static bool get_xml_shaders(const char *path, char **vertex_shader, char **fragm
|
||||
if (!cur) // We couldn't find any GLSL shader :(
|
||||
goto error;
|
||||
|
||||
bool vertex_found = false;
|
||||
bool fragment_found = false;
|
||||
unsigned num = 0;
|
||||
memset(prog, 0, sizeof(struct shader_program) * size);
|
||||
|
||||
// Iterate to check if we find fragment and/or vertex shaders.
|
||||
for (cur = cur->children; cur; cur = cur->next)
|
||||
for (cur = cur->children; cur && num < size; cur = cur->next)
|
||||
{
|
||||
if (cur->type != XML_ELEMENT_NODE)
|
||||
continue;
|
||||
@ -137,37 +145,39 @@ static bool get_xml_shaders(const char *path, char **vertex_shader, char **fragm
|
||||
if (!content)
|
||||
continue;
|
||||
|
||||
if (strcmp((const char*)cur->name, "vertex") == 0 && !vertex_found)
|
||||
if (strcmp((const char*)cur->name, "vertex") == 0)
|
||||
{
|
||||
*vertex_shader = malloc(xmlStrlen(content) + 1);
|
||||
strcpy(*vertex_shader, (const char*)content);
|
||||
vertex_found = true;
|
||||
if (prog[num].vertex)
|
||||
{
|
||||
SSNES_ERR("Cannot have more than one vertex shader in a program.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
prog[num].vertex = strdup((const char*)content);
|
||||
}
|
||||
else if (strcmp((const char*)cur->name, "fragment") == 0 && !fragment_found)
|
||||
else if (strcmp((const char*)cur->name, "fragment") == 0)
|
||||
{
|
||||
*fragment_shader = malloc(xmlStrlen(content) + 1);
|
||||
strcpy(*fragment_shader, (const char*)content);
|
||||
fragment_found = true;
|
||||
prog[num].fragment = strdup((const char*)content);
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vertex_found && !fragment_found)
|
||||
if (num == 0)
|
||||
{
|
||||
SSNES_ERR("Couldn't find vertex shader nor fragment shader in XML file.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
xmlFreeParserCtxt(ctx);
|
||||
return true;
|
||||
return num;
|
||||
|
||||
error:
|
||||
SSNES_ERR("Failed to load XML shader ...\n");
|
||||
if (doc)
|
||||
xmlFreeDoc(doc);
|
||||
xmlFreeParserCtxt(ctx);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_shader_log(GLuint obj)
|
||||
@ -198,9 +208,49 @@ static void print_linker_log(GLuint obj)
|
||||
SSNES_LOG("Linker log: %s\n", info_log);
|
||||
}
|
||||
|
||||
static void compile_programs(GLuint *gl_prog, struct shader_program *progs, size_t num)
|
||||
{
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
{
|
||||
gl_prog[i] = pglCreateProgram();
|
||||
|
||||
if (progs[i].vertex)
|
||||
{
|
||||
GLuint shader = pglCreateShader(GL_VERTEX_SHADER);
|
||||
pglShaderSource(shader, 1, (const char**)&progs[i].vertex, 0);
|
||||
pglCompileShader(shader);
|
||||
print_shader_log(shader);
|
||||
|
||||
pglAttachShader(gl_prog[i], shader);
|
||||
free(progs[i].vertex);
|
||||
}
|
||||
|
||||
if (progs[i].vertex)
|
||||
{
|
||||
GLuint shader = pglCreateShader(GL_FRAGMENT_SHADER);
|
||||
pglShaderSource(shader, 1, (const char**)&progs[i].fragment, 0);
|
||||
pglCompileShader(shader);
|
||||
print_shader_log(shader);
|
||||
|
||||
pglAttachShader(gl_prog[i], shader);
|
||||
free(progs[i].fragment);
|
||||
}
|
||||
|
||||
if (progs[i].vertex || progs[i].fragment)
|
||||
{
|
||||
pglLinkProgram(gl_prog[i]);
|
||||
pglUseProgram(gl_prog[i]);
|
||||
print_linker_log(gl_prog[i]);
|
||||
|
||||
GLint location = pglGetUniformLocation(gl_prog[i], "rubyTexture");
|
||||
pglUniform1i(location, 0);
|
||||
pglUseProgram(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool gl_glsl_init(const char *path)
|
||||
{
|
||||
|
||||
#ifndef __APPLE__
|
||||
// Load shader functions.
|
||||
pglCreateProgram = SDL_GL_GetProcAddress("glCreateProgram");
|
||||
@ -239,50 +289,30 @@ bool gl_glsl_init(const char *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *paths[] = {NULL, path,
|
||||
(strlen(g_settings.video.second_pass_shader) > 0) ? g_settings.video.second_pass_shader : NULL};
|
||||
struct shader_program progs[MAX_PROGRAMS];
|
||||
unsigned num_progs = get_xml_shaders(path, progs, MAX_PROGRAMS - 1);
|
||||
|
||||
for (int i = 1; i < 3; i++)
|
||||
if (num_progs == 0)
|
||||
{
|
||||
if (paths[i] == NULL)
|
||||
continue;
|
||||
SSNES_ERR("Couldn't find any valid shaders in XML file.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
gl_program[i] = pglCreateProgram();
|
||||
compile_programs(&gl_program[1], progs, num_progs);
|
||||
|
||||
char *vertex_prog = NULL;
|
||||
char *fragment_prog = NULL;
|
||||
if (!get_xml_shaders(paths[i], &vertex_prog, &fragment_prog))
|
||||
// SSNES custom two-pass with two different files.
|
||||
if (num_progs == 1 && *g_settings.video.second_pass_shader)
|
||||
{
|
||||
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
|
||||
{
|
||||
SSNES_ERR("Did not find valid shader in secondary shader file.\n");
|
||||
return false;
|
||||
|
||||
if (vertex_prog)
|
||||
{
|
||||
vertex_shader = pglCreateShader(GL_VERTEX_SHADER);
|
||||
pglShaderSource(vertex_shader, 1, (const char**)&vertex_prog, 0);
|
||||
pglCompileShader(vertex_shader);
|
||||
print_shader_log(vertex_shader);
|
||||
|
||||
pglAttachShader(gl_program[i], vertex_shader);
|
||||
free(vertex_prog);
|
||||
}
|
||||
if (fragment_prog)
|
||||
{
|
||||
fragment_shader = pglCreateShader(GL_FRAGMENT_SHADER);
|
||||
pglShaderSource(fragment_shader, 1, (const char**)&fragment_prog, 0);
|
||||
pglCompileShader(fragment_shader);
|
||||
print_shader_log(fragment_shader);
|
||||
|
||||
pglAttachShader(gl_program[i], fragment_shader);
|
||||
free(fragment_prog);
|
||||
}
|
||||
|
||||
if (vertex_prog || fragment_prog)
|
||||
{
|
||||
pglLinkProgram(gl_program[i]);
|
||||
pglUseProgram(gl_program[i]);
|
||||
print_linker_log(gl_program[i]);
|
||||
|
||||
GLint location = pglGetUniformLocation(gl_program[i], "rubyTexture");
|
||||
pglUniform1i(location, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,6 +320,7 @@ bool gl_glsl_init(const char *path)
|
||||
return false;
|
||||
|
||||
glsl_enable = true;
|
||||
gl_num_programs = num_progs;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -315,7 +346,6 @@ void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
float textureSize[2] = {tex_width, tex_height};
|
||||
location = pglGetUniformLocation(gl_program[active_index], "rubyTextureSize");
|
||||
pglUniform2fv(location, 1, textureSize);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,3 +360,8 @@ void gl_glsl_use(unsigned index)
|
||||
pglUseProgram(gl_program[index]);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned gl_glsl_num(void)
|
||||
{
|
||||
return gl_num_programs;
|
||||
}
|
||||
|
@ -33,4 +33,6 @@ void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
|
||||
void gl_glsl_use(unsigned index);
|
||||
|
||||
unsigned gl_glsl_num(void);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user