mirror of
https://github.com/libretro/RetroArch
synced 2025-04-09 21:45:45 +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);
|
msg_queue_push(g_extern.msg_queue, msg, 1, 120);
|
||||||
RARCH_LOG("Applying shader \"%s\".\n", arg);
|
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[] = {
|
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
|
RARCH_SHADER_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum rarch_shader_mask
|
enum rarch_shader_index
|
||||||
{
|
{
|
||||||
RARCH_SHADER_MULTIPASS = 1,
|
RARCH_SHADER_INDEX_MULTIPASS = 0,
|
||||||
RARCH_SHADER_PASS0,
|
RARCH_SHADER_INDEX_PASS0 = 1,
|
||||||
RARCH_SHADER_PASS0_STOCK,
|
RARCH_SHADER_INDEX_PASS1 = 2
|
||||||
RARCH_SHADER_PASS1,
|
|
||||||
RARCH_SHADER_PASS1_STOCK
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct video_info
|
typedef struct video_info
|
||||||
@ -233,7 +231,7 @@ typedef struct video_driver
|
|||||||
// Is the window still active?
|
// Is the window still active?
|
||||||
bool (*alive)(void *data);
|
bool (*alive)(void *data);
|
||||||
bool (*focus)(void *data); // Does the window have focus?
|
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);
|
void (*free)(void *data);
|
||||||
const char *ident;
|
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)
|
#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;
|
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
|
#ifdef HAVE_FBO
|
||||||
gl_deinit_fbo(gl);
|
gl_deinit_fbo(gl);
|
||||||
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
|
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
|
||||||
#endif
|
#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
|
#ifdef HAVE_FBO
|
||||||
// Set up render to texture again.
|
// Set up render to texture again.
|
||||||
gl_init_fbo(gl, gl->tex_w, gl->tex_h);
|
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.
|
// Apparently need to set viewport for passes when we aren't using FBOs.
|
||||||
gl_set_shader_viewport(gl, 0);
|
gl_set_shader_viewport(gl, 0);
|
||||||
gl_set_shader_viewport(gl, 1);
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -477,21 +477,30 @@ static bool load_plain(const char *path)
|
|||||||
if (!load_stock())
|
if (!load_stock())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
RARCH_LOG("Loading Cg file: %s\n", path);
|
if (path)
|
||||||
|
|
||||||
if (!load_program(1, path, true))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (*g_settings.video.second_pass_shader && g_settings.video.render_to_texture)
|
|
||||||
{
|
{
|
||||||
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;
|
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
|
else
|
||||||
{
|
{
|
||||||
prg[2] = prg[0];
|
RARCH_LOG("Loading stock Cg file.\n");
|
||||||
|
prg[2] = prg[1] = prg[0];
|
||||||
cg_shader_num = 1;
|
cg_shader_num = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1360,5 +1369,8 @@ const gl_shader_backend_t gl_cg_backend = {
|
|||||||
gl_cg_shader_scale,
|
gl_cg_shader_scale,
|
||||||
gl_cg_set_coords,
|
gl_cg_set_coords,
|
||||||
gl_cg_set_mvp,
|
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);
|
void (*shader_scale)(unsigned index, struct gl_fbo_scale *scale);
|
||||||
bool (*set_coords)(const struct gl_coords *coords);
|
bool (*set_coords)(const struct gl_coords *coords);
|
||||||
bool (*set_mvp)(const math_matrix *mat);
|
bool (*set_mvp)(const math_matrix *mat);
|
||||||
|
|
||||||
|
bool (*load_shader)(unsigned index, const char *path);
|
||||||
|
enum rarch_shader_type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#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)
|
static bool compile_programs(GLuint *gl_prog, struct shader_program *progs, size_t num)
|
||||||
{
|
{
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
for (unsigned i = 0; i < num; i++)
|
for (unsigned i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
gl_prog[i] = pglCreateProgram();
|
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)
|
if (gl_prog[i] == 0)
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to create GL program #%u.\n", i);
|
RARCH_ERR("Failed to create GL program #%u.\n", i);
|
||||||
return false;
|
ret = false;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progs[i].vertex)
|
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))
|
if (!compile_shader(shader, progs[i].vertex))
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to compile vertex shader #%u\n", i);
|
RARCH_ERR("Failed to compile vertex shader #%u\n", i);
|
||||||
return false;
|
ret = false;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
pglAttachShader(gl_prog[i], shader);
|
pglAttachShader(gl_prog[i], shader);
|
||||||
free(progs[i].vertex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progs[i].fragment)
|
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))
|
if (!compile_shader(shader, progs[i].fragment))
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to compile fragment shader #%u\n", i);
|
RARCH_ERR("Failed to compile fragment shader #%u\n", i);
|
||||||
return false;
|
ret = false;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
pglAttachShader(gl_prog[i], shader);
|
pglAttachShader(gl_prog[i], shader);
|
||||||
free(progs[i].fragment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progs[i].vertex || 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]))
|
if (!link_program(gl_prog[i]))
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to link program #%u\n", i);
|
RARCH_ERR("Failed to link program #%u\n", i);
|
||||||
return false;
|
ret = false;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLint location = pglGetUniformLocation(gl_prog[i], "rubyTexture");
|
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)
|
static void gl_glsl_reset_attrib(void)
|
||||||
@ -1014,6 +1027,56 @@ static void find_uniforms(GLuint prog, struct shader_uniforms *uni)
|
|||||||
pglUseProgram(0);
|
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.
|
// Platforms with broken get_proc_address.
|
||||||
// Assume functions are available without proc_address.
|
// Assume functions are available without proc_address.
|
||||||
#undef LOAD_GL_SYM
|
#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);
|
unsigned secondary_progs = get_xml_shaders(g_settings.video.second_pass_shader, progs, 1);
|
||||||
if (secondary_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++;
|
num_progs++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1185,17 +1253,7 @@ void gl_glsl_deinit(void)
|
|||||||
if (gl_program[i] == 0 || (i && gl_program[i] == gl_program[0]))
|
if (gl_program[i] == 0 || (i && gl_program[i] == gl_program[0]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
GLsizei count;
|
gl_glsl_delete_shader(gl_program[i]);
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glDeleteTextures(gl_teximage_cnt, gl_teximage);
|
glDeleteTextures(gl_teximage_cnt, gl_teximage);
|
||||||
@ -1507,5 +1565,8 @@ const gl_shader_backend_t gl_glsl_backend = {
|
|||||||
gl_glsl_shader_scale,
|
gl_glsl_shader_scale,
|
||||||
gl_glsl_set_coords,
|
gl_glsl_set_coords,
|
||||||
gl_glsl_set_mvp,
|
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);
|
msg_queue_push(g_extern.msg_queue, msg, 1, 120);
|
||||||
RARCH_LOG("Applying shader \"%s\".\n", shader);
|
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");
|
RARCH_WARN("Failed to apply shader.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user