mirror of
https://github.com/libretro/RetroArch
synced 2025-03-27 23:37:39 +00:00
Experimental support for PassPrev/PASSPREV.
Allows to access passes in a "negative index" way. Helps stitching together multipass shaders from other multipass shaders. Also adds new, cleaner symbols, IN.mvp_matrix, IN.tex_coord, etc.
This commit is contained in:
parent
f00394e0af
commit
b292caf92b
@ -37,27 +37,33 @@
|
||||
|
||||
// Used when we call deactivate() since just unbinding the program didn't seem to work... :(
|
||||
static const char *stock_cg_program =
|
||||
"struct input"
|
||||
"{"
|
||||
" float2 tex_coord;"
|
||||
" float4 color;"
|
||||
" float4 vertex_coord;"
|
||||
" uniform float4x4 mvp_matrix;"
|
||||
" uniform sampler2D texture;"
|
||||
"};"
|
||||
"struct vertex_data"
|
||||
"{"
|
||||
" float2 tex;"
|
||||
" float4 color;"
|
||||
"};"
|
||||
"void main_vertex"
|
||||
"("
|
||||
" float4 position : POSITION,"
|
||||
" float2 texCoord : TEXCOORD0,"
|
||||
" float4 color : COLOR,"
|
||||
""
|
||||
" uniform float4x4 modelViewProj,"
|
||||
""
|
||||
" out float4 oPosition : POSITION,"
|
||||
" out float2 otexCoord : TEXCOORD0,"
|
||||
" out float4 oColor : COLOR"
|
||||
" input IN,"
|
||||
" out vertex_data vert"
|
||||
")"
|
||||
"{"
|
||||
" oPosition = mul(modelViewProj, position);"
|
||||
" otexCoord = texCoord;"
|
||||
" oColor = color;"
|
||||
" oPosition = mul(IN.mvp_matrix, IN.vertex_coord);"
|
||||
" vert = vertex_data(IN.tex_coord, IN.color);"
|
||||
"}"
|
||||
""
|
||||
"float4 main_fragment(in float4 color : COLOR, float2 tex : TEXCOORD0, uniform sampler2D s0 : TEXUNIT0) : COLOR"
|
||||
"float4 main_fragment(input IN, vertex_data vert, uniform sampler2D s0 : TEXUNIT0) : COLOR"
|
||||
"{"
|
||||
" return color * tex2D(s0, tex);"
|
||||
" return vert.color * tex2D(s0, vert.tex);"
|
||||
"}";
|
||||
|
||||
#ifdef RARCH_CG_DEBUG
|
||||
@ -678,6 +684,41 @@ static void set_program_base_attrib(unsigned i)
|
||||
else if (strcmp(semantic, "TEXCOORD1") == 0)
|
||||
prg[i].lut_tex = param;
|
||||
}
|
||||
|
||||
if (!prg[i].tex)
|
||||
prg[i].tex = cgGetNamedParameter(prg[i].vprg, "IN.tex_coord");
|
||||
if (!prg[i].color)
|
||||
prg[i].color = cgGetNamedParameter(prg[i].vprg, "IN.color");
|
||||
if (!prg[i].vertex)
|
||||
prg[i].vertex = cgGetNamedParameter(prg[i].vprg, "IN.vertex_coord");
|
||||
if (!prg[i].lut_tex)
|
||||
prg[i].lut_tex = cgGetNamedParameter(prg[i].vprg, "IN.lut_tex_coord");
|
||||
}
|
||||
|
||||
static void set_pass_attrib(struct cg_program *prg, struct cg_fbo_params *fbo,
|
||||
const char *attr)
|
||||
{
|
||||
char attr_buf[64];
|
||||
|
||||
snprintf(attr_buf, sizeof(attr_buf), "%s.texture", attr);
|
||||
if (!fbo->tex)
|
||||
fbo->tex = cgGetNamedParameter(prg->fprg, attr_buf);
|
||||
|
||||
snprintf(attr_buf, sizeof(attr_buf), "%s.video_size", attr);
|
||||
if (!fbo->vid_size_v)
|
||||
fbo->vid_size_v = cgGetNamedParameter(prg->vprg, attr_buf);
|
||||
if (!fbo->vid_size_f)
|
||||
fbo->vid_size_f = cgGetNamedParameter(prg->fprg, attr_buf);
|
||||
|
||||
snprintf(attr_buf, sizeof(attr_buf), "%s.texture_size", attr);
|
||||
if (!fbo->tex_size_v)
|
||||
fbo->tex_size_v = cgGetNamedParameter(prg->vprg, attr_buf);
|
||||
if (!fbo->tex_size_f)
|
||||
fbo->tex_size_f = cgGetNamedParameter(prg->fprg, attr_buf);
|
||||
|
||||
snprintf(attr_buf, sizeof(attr_buf), "%s.tex_coord", attr);
|
||||
if (!fbo->coord)
|
||||
fbo->coord = cgGetNamedParameter(prg->vprg, attr_buf);
|
||||
}
|
||||
|
||||
static void set_program_attributes(unsigned i)
|
||||
@ -697,7 +738,10 @@ static void set_program_attributes(unsigned i)
|
||||
prg[i].out_size_v = cgGetNamedParameter(prg[i].vprg, "IN.output_size");
|
||||
prg[i].frame_cnt_v = cgGetNamedParameter(prg[i].vprg, "IN.frame_count");
|
||||
prg[i].frame_dir_v = cgGetNamedParameter(prg[i].vprg, "IN.frame_direction");
|
||||
|
||||
prg[i].mvp = cgGetNamedParameter(prg[i].vprg, "modelViewProj");
|
||||
if (!prg[i].mvp)
|
||||
prg[i].mvp = cgGetNamedParameter(prg[i].vprg, "IN.mvp_matrix");
|
||||
|
||||
prg[i].orig.tex = cgGetNamedParameter(prg[i].fprg, "ORIG.texture");
|
||||
prg[i].orig.vid_size_v = cgGetNamedParameter(prg[i].vprg, "ORIG.video_size");
|
||||
@ -706,6 +750,13 @@ static void set_program_attributes(unsigned i)
|
||||
prg[i].orig.tex_size_f = cgGetNamedParameter(prg[i].fprg, "ORIG.texture_size");
|
||||
prg[i].orig.coord = cgGetNamedParameter(prg[i].vprg, "ORIG.tex_coord");
|
||||
|
||||
if (i > 1)
|
||||
{
|
||||
char pass_str[64];
|
||||
snprintf(pass_str, sizeof(pass_str), "PASSPREV%u", i);
|
||||
set_pass_attrib(&prg[i], &prg[i].orig, pass_str);
|
||||
}
|
||||
|
||||
for (unsigned j = 0; j < PREV_TEXTURES; j++)
|
||||
{
|
||||
char attr_buf_tex[64];
|
||||
@ -740,21 +791,11 @@ static void set_program_attributes(unsigned i)
|
||||
|
||||
for (unsigned j = 0; j < i - 1; j++)
|
||||
{
|
||||
char attr_buf[64];
|
||||
|
||||
snprintf(attr_buf, sizeof(attr_buf), "PASS%u.texture", j + 1);
|
||||
prg[i].fbo[j].tex = cgGetNamedParameter(prg[i].fprg, attr_buf);
|
||||
|
||||
snprintf(attr_buf, sizeof(attr_buf), "PASS%u.video_size", j + 1);
|
||||
prg[i].fbo[j].vid_size_v = cgGetNamedParameter(prg[i].vprg, attr_buf);
|
||||
prg[i].fbo[j].vid_size_f = cgGetNamedParameter(prg[i].fprg, attr_buf);
|
||||
|
||||
snprintf(attr_buf, sizeof(attr_buf), "PASS%u.texture_size", j + 1);
|
||||
prg[i].fbo[j].tex_size_v = cgGetNamedParameter(prg[i].vprg, attr_buf);
|
||||
prg[i].fbo[j].tex_size_f = cgGetNamedParameter(prg[i].fprg, attr_buf);
|
||||
|
||||
snprintf(attr_buf, sizeof(attr_buf), "PASS%u.tex_coord", j + 1);
|
||||
prg[i].fbo[j].coord = cgGetNamedParameter(prg[i].vprg, attr_buf);
|
||||
char pass_str[64];
|
||||
snprintf(pass_str, sizeof(pass_str), "PASS%u", j + 1);
|
||||
set_pass_attrib(&prg[i], &prg[i].fbo[j], pass_str);
|
||||
snprintf(pass_str, sizeof(pass_str), "PASSPREV%u", i - j);
|
||||
set_pass_attrib(&prg[i], &prg[i].fbo[j], pass_str);
|
||||
}
|
||||
}
|
||||
|
||||
@ -805,7 +846,7 @@ static bool gl_cg_init(const char *path)
|
||||
goto error;
|
||||
}
|
||||
|
||||
prg[0].mvp = cgGetNamedParameter(prg[0].vprg, "modelViewProj");
|
||||
prg[0].mvp = cgGetNamedParameter(prg[0].vprg, "IN.mvp_matrix");
|
||||
for (unsigned i = 1; i <= cg_shader->passes; i++)
|
||||
set_program_attributes(i);
|
||||
|
||||
|
@ -548,6 +548,14 @@ static void gl_glsl_set_attribs(GLuint vbo, GLfloat *buffer, size_t *buffer_elem
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
static void clear_uniforms_frame(struct shader_uniforms_frame *frame)
|
||||
{
|
||||
frame->texture = -1;
|
||||
frame->texture_size = -1;
|
||||
frame->input_size = -1;
|
||||
frame->tex_coord = -1;
|
||||
}
|
||||
|
||||
static void find_uniforms_frame(GLuint prog, struct shader_uniforms_frame *frame, const char *base)
|
||||
{
|
||||
char texture[64];
|
||||
@ -560,13 +568,17 @@ static void find_uniforms_frame(GLuint prog, struct shader_uniforms_frame *frame
|
||||
snprintf(input_size, sizeof(input_size), "%s%s", base, "InputSize");
|
||||
snprintf(tex_coord, sizeof(tex_coord), "%s%s", base, "TexCoord");
|
||||
|
||||
frame->texture = get_uniform(prog, texture);
|
||||
frame->texture_size = get_uniform(prog, texture_size);
|
||||
frame->input_size = get_uniform(prog, input_size);
|
||||
frame->tex_coord = get_attrib(prog, tex_coord);
|
||||
if (frame->texture < 0)
|
||||
frame->texture = get_uniform(prog, texture);
|
||||
if (frame->texture_size < 0)
|
||||
frame->texture_size = get_uniform(prog, texture_size);
|
||||
if (frame->input_size < 0)
|
||||
frame->input_size = get_uniform(prog, input_size);
|
||||
if (frame->tex_coord < 0)
|
||||
frame->tex_coord = get_attrib(prog, tex_coord);
|
||||
}
|
||||
|
||||
static void find_uniforms(GLuint prog, struct shader_uniforms *uni)
|
||||
static void find_uniforms(unsigned pass, GLuint prog, struct shader_uniforms *uni)
|
||||
{
|
||||
glUseProgram(prog);
|
||||
|
||||
@ -586,19 +598,31 @@ static void find_uniforms(GLuint prog, struct shader_uniforms *uni)
|
||||
for (unsigned i = 0; i < glsl_shader->luts; i++)
|
||||
uni->lut_texture[i] = glGetUniformLocation(prog, glsl_shader->lut[i].id);
|
||||
|
||||
find_uniforms_frame(prog, &uni->orig, "Orig");
|
||||
|
||||
char frame_base[64];
|
||||
clear_uniforms_frame(&uni->orig);
|
||||
find_uniforms_frame(prog, &uni->orig, "Orig");
|
||||
if (pass > 1)
|
||||
{
|
||||
snprintf(frame_base, sizeof(frame_base), "PassPrev%u", pass);
|
||||
find_uniforms_frame(prog, &uni->orig, frame_base);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < GFX_MAX_SHADERS; i++)
|
||||
{
|
||||
snprintf(frame_base, sizeof(frame_base), "Pass%u", i + 1);
|
||||
find_uniforms_frame(prog, &uni->pass[i], frame_base);
|
||||
if (i && pass > i + 1)
|
||||
{
|
||||
snprintf(frame_base, sizeof(frame_base), "PassPrev%u", pass - i);
|
||||
find_uniforms_frame(prog, &uni->pass[i], frame_base);
|
||||
}
|
||||
}
|
||||
|
||||
find_uniforms_frame(prog, &uni->prev[0], "Prev");
|
||||
for (unsigned i = 1; i < PREV_TEXTURES; i++)
|
||||
{
|
||||
snprintf(frame_base, sizeof(frame_base), "Prev%u", i);
|
||||
clear_uniforms_frame(&uni->prev[i]);
|
||||
find_uniforms_frame(prog, &uni->prev[i], frame_base);
|
||||
}
|
||||
|
||||
@ -774,7 +798,7 @@ static bool gl_glsl_init(const char *path)
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i <= glsl_shader->passes; i++)
|
||||
find_uniforms(gl_program[i], &gl_uniforms[i]);
|
||||
find_uniforms(i, gl_program[i], &gl_uniforms[i]);
|
||||
|
||||
#ifdef GLSL_DEBUG
|
||||
if (!gl_check_error())
|
||||
@ -813,7 +837,7 @@ static bool gl_glsl_init(const char *path)
|
||||
glsl_core ? stock_fragment_modern_blend : stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND);
|
||||
#endif
|
||||
|
||||
find_uniforms(gl_program[GL_SHADER_STOCK_BLEND], &gl_uniforms[GL_SHADER_STOCK_BLEND]);
|
||||
find_uniforms(0, gl_program[GL_SHADER_STOCK_BLEND], &gl_uniforms[GL_SHADER_STOCK_BLEND]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user