mirror of
https://github.com/libretro/RetroArch.git
synced 2025-01-31 14:04:21 +00:00
Rework index parameter to set_shader().
This commit is contained in:
parent
8887eb4680
commit
551a464978
@ -229,7 +229,7 @@ static bool cmd_set_shader(const char *arg)
|
||||
msg_queue_push(g_extern.msg_queue, msg, 1, 120);
|
||||
RARCH_LOG("Applying shader \"%s\".\n", arg);
|
||||
|
||||
return video_set_shader_func(type, arg, (1ULL << RARCH_SHADER_MULTIPASS));
|
||||
return video_set_shader_func(type, arg, RARCH_SHADER_INDEX_MULTIPASS);
|
||||
}
|
||||
|
||||
static const struct cmd_action_map action_map[] = {
|
||||
|
12
driver.h
12
driver.h
@ -136,13 +136,11 @@ enum rarch_shader_type
|
||||
RARCH_SHADER_NONE
|
||||
};
|
||||
|
||||
enum rarch_shader_mask
|
||||
enum rarch_shader_index
|
||||
{
|
||||
RARCH_SHADER_MULTIPASS = 1,
|
||||
RARCH_SHADER_PASS0,
|
||||
RARCH_SHADER_PASS0_STOCK,
|
||||
RARCH_SHADER_PASS1,
|
||||
RARCH_SHADER_PASS1_STOCK
|
||||
RARCH_SHADER_INDEX_MULTIPASS = 0,
|
||||
RARCH_SHADER_INDEX_PASS0 = 1,
|
||||
RARCH_SHADER_INDEX_PASS1 = 2
|
||||
};
|
||||
|
||||
typedef struct video_info
|
||||
@ -233,7 +231,7 @@ typedef struct video_driver
|
||||
// Is the window still active?
|
||||
bool (*alive)(void *data);
|
||||
bool (*focus)(void *data); // Does the window have focus?
|
||||
bool (*set_shader)(void *data, enum rarch_shader_type type, const char *path, unsigned mask); // Sets shader. Might not be implemented.
|
||||
bool (*set_shader)(void *data, enum rarch_shader_type type, const char *path, unsigned index); // Sets shader. Might not be implemented.
|
||||
void (*free)(void *data);
|
||||
const char *ident;
|
||||
|
||||
|
128
gfx/gl.c
128
gfx/gl.c
@ -1709,75 +1709,73 @@ static bool gl_focus(void *data)
|
||||
}
|
||||
|
||||
#if defined(HAVE_GLSL) || defined(HAVE_CG)
|
||||
static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *path, unsigned mask)
|
||||
static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *path, unsigned index)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
|
||||
if (mask & (1ULL << RARCH_SHADER_MULTIPASS))
|
||||
if (type == RARCH_SHADER_NONE)
|
||||
return false;
|
||||
|
||||
if (index == RARCH_SHADER_INDEX_MULTIPASS && !path)
|
||||
{
|
||||
RARCH_ERR("[GL]: Cannot set stock shader to multipass.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gl->shader && index != RARCH_SHADER_INDEX_MULTIPASS)
|
||||
{
|
||||
RARCH_ERR("[GL]: No shader core is init. Cannot set shader %s to pass %u.\n", path, index);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gl->shader && gl->shader->type != type)
|
||||
{
|
||||
RARCH_ERR("[GL]: Trying to set a specific shader pass %u, but that particular shader core is not initialized.\n", index);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Need full teardown for multipass.
|
||||
if (index == RARCH_SHADER_INDEX_MULTIPASS)
|
||||
{
|
||||
gl_shader_deinit(gl);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
#ifdef HAVE_GLSL
|
||||
case RARCH_SHADER_GLSL:
|
||||
gl->shader = &gl_glsl_backend;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_CG
|
||||
case RARCH_SHADER_CG:
|
||||
gl->shader = &gl_cg_backend;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
gl->shader = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gl->shader)
|
||||
{
|
||||
RARCH_ERR("[GL]: Cannot find shader core for path: %s.\n", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FBO
|
||||
gl_deinit_fbo(gl);
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
|
||||
#endif
|
||||
|
||||
gl_shader_deinit(gl);
|
||||
}
|
||||
bool ret = gl->shader->init(path);
|
||||
if (!ret)
|
||||
{
|
||||
gl->shader = NULL;
|
||||
RARCH_WARN("[GL]: Failed to set multipass shader. Falling back to stock.\n");
|
||||
return gl->shader->init(NULL);
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
#ifdef HAVE_GLSL
|
||||
case RARCH_SHADER_GLSL:
|
||||
if (mask & (1ULL << RARCH_SHADER_MULTIPASS))
|
||||
{
|
||||
if (!gl_glsl_init(path))
|
||||
return false;
|
||||
}
|
||||
else if (mask & (1ULL << RARCH_SHADER_PASS0))
|
||||
{
|
||||
#if 0
|
||||
/* TODO - doesn't seem to be added yet? */
|
||||
if (!gl_glsl_load_shader(1, (mask & (1ULL << RARCH_SHADER_PASS0_STOCK)) ? NULL : path))
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
else if (mask & (1ULL << RARCH_SHADER_PASS1))
|
||||
{
|
||||
#if 0
|
||||
/* TODO - doesn't seem to be added yet? */
|
||||
if (!gl_glsl_load_shader(2, (mask & (1ULL << RARCH_SHADER_PASS1_STOCK)) ? NULL : path))
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CG
|
||||
case RARCH_SHADER_CG:
|
||||
if (mask & (1ULL << RARCH_SHADER_MULTIPASS))
|
||||
{
|
||||
if (!gl_cg_init(path))
|
||||
return false;
|
||||
}
|
||||
else if (mask & (1ULL << RARCH_SHADER_PASS0))
|
||||
{
|
||||
if (!gl_cg_load_shader(1, (mask & (1ULL << RARCH_SHADER_PASS0_STOCK)) ? NULL : path))
|
||||
return false;
|
||||
}
|
||||
else if (mask & (1ULL << RARCH_SHADER_PASS1))
|
||||
{
|
||||
if (!gl_cg_load_shader(2, (mask & (1ULL << RARCH_SHADER_PASS1_STOCK)) ? NULL : path))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
RARCH_ERR("Invalid shader type in gl_set_shader().\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mask & (1ULL << RARCH_SHADER_MULTIPASS))
|
||||
{
|
||||
#ifdef HAVE_FBO
|
||||
// Set up render to texture again.
|
||||
gl_init_fbo(gl, gl->tex_w, gl->tex_h);
|
||||
@ -1786,9 +1784,19 @@ static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *p
|
||||
// Apparently need to set viewport for passes when we aren't using FBOs.
|
||||
gl_set_shader_viewport(gl, 0);
|
||||
gl_set_shader_viewport(gl, 1);
|
||||
return true;
|
||||
}
|
||||
else // Replace a currently loaded shader directly.
|
||||
{
|
||||
if (index > gl->shader->num_shaders())
|
||||
{
|
||||
RARCH_ERR("Can only load shader for passes that already exist. "
|
||||
"Attempted to set pass %u, but only %u passes exist.\n", index, gl->shader->num_shaders());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return gl->shader->load_shader(index, path);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -477,21 +477,30 @@ static bool load_plain(const char *path)
|
||||
if (!load_stock())
|
||||
return false;
|
||||
|
||||
RARCH_LOG("Loading Cg file: %s\n", path);
|
||||
|
||||
if (!load_program(1, path, true))
|
||||
return false;
|
||||
|
||||
if (*g_settings.video.second_pass_shader && g_settings.video.render_to_texture)
|
||||
if (path)
|
||||
{
|
||||
if (!load_program(2, g_settings.video.second_pass_shader, true))
|
||||
RARCH_LOG("Loading Cg file: %s\n", path);
|
||||
|
||||
if (!load_program(1, path, true))
|
||||
return false;
|
||||
|
||||
cg_shader_num = 2;
|
||||
if (*g_settings.video.second_pass_shader && g_settings.video.render_to_texture)
|
||||
{
|
||||
if (!load_program(2, g_settings.video.second_pass_shader, true))
|
||||
return false;
|
||||
|
||||
cg_shader_num = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
prg[2] = prg[0];
|
||||
cg_shader_num = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prg[2] = prg[0];
|
||||
RARCH_LOG("Loading stock Cg file.\n");
|
||||
prg[2] = prg[1] = prg[0];
|
||||
cg_shader_num = 1;
|
||||
}
|
||||
|
||||
@ -1360,5 +1369,8 @@ const gl_shader_backend_t gl_cg_backend = {
|
||||
gl_cg_shader_scale,
|
||||
gl_cg_set_coords,
|
||||
gl_cg_set_mvp,
|
||||
|
||||
gl_cg_load_shader,
|
||||
RARCH_SHADER_CG,
|
||||
};
|
||||
|
||||
|
@ -39,6 +39,9 @@ struct gl_shader_backend
|
||||
void (*shader_scale)(unsigned index, struct gl_fbo_scale *scale);
|
||||
bool (*set_coords)(const struct gl_coords *coords);
|
||||
bool (*set_mvp)(const math_matrix *mat);
|
||||
|
||||
bool (*load_shader)(unsigned index, const char *path);
|
||||
enum rarch_shader_type type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -894,6 +894,8 @@ static bool link_program(GLuint prog)
|
||||
|
||||
static bool compile_programs(GLuint *gl_prog, struct shader_program *progs, size_t num)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
{
|
||||
gl_prog[i] = pglCreateProgram();
|
||||
@ -901,7 +903,8 @@ static bool compile_programs(GLuint *gl_prog, struct shader_program *progs, size
|
||||
if (gl_prog[i] == 0)
|
||||
{
|
||||
RARCH_ERR("Failed to create GL program #%u.\n", i);
|
||||
return false;
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (progs[i].vertex)
|
||||
@ -911,11 +914,11 @@ static bool compile_programs(GLuint *gl_prog, struct shader_program *progs, size
|
||||
if (!compile_shader(shader, progs[i].vertex))
|
||||
{
|
||||
RARCH_ERR("Failed to compile vertex shader #%u\n", i);
|
||||
return false;
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
pglAttachShader(gl_prog[i], shader);
|
||||
free(progs[i].vertex);
|
||||
}
|
||||
|
||||
if (progs[i].fragment)
|
||||
@ -925,11 +928,11 @@ static bool compile_programs(GLuint *gl_prog, struct shader_program *progs, size
|
||||
if (!compile_shader(shader, progs[i].fragment))
|
||||
{
|
||||
RARCH_ERR("Failed to compile fragment shader #%u\n", i);
|
||||
return false;
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
pglAttachShader(gl_prog[i], shader);
|
||||
free(progs[i].fragment);
|
||||
}
|
||||
|
||||
if (progs[i].vertex || progs[i].fragment)
|
||||
@ -938,7 +941,8 @@ static bool compile_programs(GLuint *gl_prog, struct shader_program *progs, size
|
||||
if (!link_program(gl_prog[i]))
|
||||
{
|
||||
RARCH_ERR("Failed to link program #%u\n", i);
|
||||
return false;
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
GLint location = pglGetUniformLocation(gl_prog[i], "rubyTexture");
|
||||
@ -947,7 +951,16 @@ static bool compile_programs(GLuint *gl_prog, struct shader_program *progs, size
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
end:
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
{
|
||||
free(progs[i].vertex);
|
||||
free(progs[i].fragment);
|
||||
progs[i].vertex = NULL;
|
||||
progs[i].fragment = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void gl_glsl_reset_attrib(void)
|
||||
@ -1014,6 +1027,56 @@ static void find_uniforms(GLuint prog, struct shader_uniforms *uni)
|
||||
pglUseProgram(0);
|
||||
}
|
||||
|
||||
static void gl_glsl_delete_shader(GLuint prog)
|
||||
{
|
||||
GLsizei count;
|
||||
GLuint shaders[2] = {0};
|
||||
|
||||
pglGetAttachedShaders(prog, 2, &count, shaders);
|
||||
for (GLsizei i = 0; i < count; i++)
|
||||
{
|
||||
pglDetachShader(prog, shaders[i]);
|
||||
pglDeleteShader(shaders[i]);
|
||||
}
|
||||
|
||||
pglDeleteProgram(prog);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Platforms with broken get_proc_address.
|
||||
// Assume functions are available without proc_address.
|
||||
#undef LOAD_GL_SYM
|
||||
@ -1129,7 +1192,12 @@ bool gl_glsl_init(const char *path)
|
||||
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);
|
||||
if (!compile_programs(&gl_program[2], progs, 1))
|
||||
{
|
||||
RARCH_ERR("Failed to compile second pass shader.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
num_progs++;
|
||||
}
|
||||
else
|
||||
@ -1185,17 +1253,7 @@ void gl_glsl_deinit(void)
|
||||
if (gl_program[i] == 0 || (i && gl_program[i] == gl_program[0]))
|
||||
continue;
|
||||
|
||||
GLsizei count;
|
||||
GLuint shaders[2];
|
||||
|
||||
pglGetAttachedShaders(gl_program[i], 2, &count, shaders);
|
||||
for (GLsizei j = 0; j < count; j++)
|
||||
{
|
||||
pglDetachShader(gl_program[i], shaders[j]);
|
||||
pglDeleteShader(shaders[j]);
|
||||
}
|
||||
|
||||
pglDeleteProgram(gl_program[i]);
|
||||
gl_glsl_delete_shader(gl_program[i]);
|
||||
}
|
||||
|
||||
glDeleteTextures(gl_teximage_cnt, gl_teximage);
|
||||
@ -1507,5 +1565,8 @@ const gl_shader_backend_t gl_glsl_backend = {
|
||||
gl_glsl_shader_scale,
|
||||
gl_glsl_set_coords,
|
||||
gl_glsl_set_mvp,
|
||||
|
||||
gl_glsl_load_shader,
|
||||
RARCH_SHADER_GLSL,
|
||||
};
|
||||
|
||||
|
@ -2342,7 +2342,7 @@ static void check_shader_dir(void)
|
||||
msg_queue_push(g_extern.msg_queue, msg, 1, 120);
|
||||
RARCH_LOG("Applying shader \"%s\".\n", shader);
|
||||
|
||||
if (!video_set_shader_func(type, shader, (1ULL << RARCH_SHADER_MULTIPASS)))
|
||||
if (!video_set_shader_func(type, shader, RARCH_SHADER_INDEX_MULTIPASS))
|
||||
RARCH_WARN("Failed to apply shader.\n");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user