nv2a: Implement pvideo color keying

This commit is contained in:
Erik Abair 2022-01-22 12:11:54 -08:00 committed by mborgerson
parent b3f56db428
commit 6b821d2062
3 changed files with 30 additions and 2 deletions

View File

@ -265,6 +265,8 @@ typedef struct PGRAPHState {
GLint pvideo_enable_loc;
GLint pvideo_tex_loc;
GLint pvideo_pos_loc;
GLint pvideo_color_key_enable_loc;
GLint pvideo_color_key_loc;
GLint palette_loc[256];
} disp_rndr;

View File

@ -653,6 +653,12 @@
# define NV_PVIDEO_FORMAT_COLOR 0x00030000
# define NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8 1
# define NV_PVIDEO_FORMAT_DISPLAY (1 << 20)
# define NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY 1
#define NV_PVIDEO_COLOR_KEY 0x00000B00
# define NV_PVIDEO_COLOR_KEY_RED 0x00FF0000
# define NV_PVIDEO_COLOR_KEY_GREEN 0x0000FF00
# define NV_PVIDEO_COLOR_KEY_BLUE 0x000000FF
# define NV_PVIDEO_COLOR_KEY_ALPHA 0xFF000000
#define NV_PTIMER_INTR_0 0x00000100

View File

@ -4530,6 +4530,8 @@ static void pgraph_init_display_renderer(NV2AState *d)
"uniform bool pvideo_enable;\n"
"uniform sampler2D pvideo_tex;\n"
"uniform vec4 pvideo_pos;\n"
"uniform bool pvideo_color_key_enable;\n"
"uniform vec4 pvideo_color_key;\n"
"uniform vec2 display_size;\n"
"uniform float line_offset;\n"
"layout(location = 0) out vec4 out_Color;\n"
@ -4546,7 +4548,9 @@ static void pgraph_init_display_renderer(NV2AState *d)
" if (!any(clip)) {\n"
" vec2 spos = vec2(gl_FragCoord.x, textureSize(tex,0).y-gl_FragCoord.y);\n"
" vec2 coord = (spos-pvideo_pos.xy)/pvideo_pos.zw;\n"
" out_Color.rgba = texture(pvideo_tex, coord);\n"
" if (!pvideo_color_key_enable || out_Color.rgba == pvideo_color_key) {\n"
" out_Color.rgba = texture(pvideo_tex, coord);\n"
" }\n"
" }\n"
" }\n"
"}\n";
@ -4556,6 +4560,8 @@ static void pgraph_init_display_renderer(NV2AState *d)
pg->disp_rndr.pvideo_enable_loc = glGetUniformLocation(pg->disp_rndr.prog, "pvideo_enable");
pg->disp_rndr.pvideo_tex_loc = glGetUniformLocation(pg->disp_rndr.prog, "pvideo_tex");
pg->disp_rndr.pvideo_pos_loc = glGetUniformLocation(pg->disp_rndr.prog, "pvideo_pos");
pg->disp_rndr.pvideo_color_key_enable_loc = glGetUniformLocation(pg->disp_rndr.prog, "pvideo_color_key_enable");
pg->disp_rndr.pvideo_color_key_loc = glGetUniformLocation(pg->disp_rndr.prog, "pvideo_color_key");
pg->disp_rndr.display_size_loc = glGetUniformLocation(pg->disp_rndr.prog, "display_size");
pg->disp_rndr.line_offset_loc = glGetUniformLocation(pg->disp_rndr.prog, "line_offset");
@ -4630,7 +4636,21 @@ static void pgraph_render_display_pvideo_overlay(NV2AState *d)
unsigned int out_y =
GET_MASK(d->pvideo.regs[NV_PVIDEO_POINT_OUT], NV_PVIDEO_POINT_OUT_Y);
/* TODO: color keys */
unsigned int color_key_enabled =
GET_MASK(d->pvideo.regs[NV_PVIDEO_FORMAT], NV_PVIDEO_FORMAT_DISPLAY);
glUniform1ui(d->pgraph.disp_rndr.pvideo_color_key_enable_loc,
color_key_enabled);
// TODO: Verify that masking off the top byte is correct.
// SeaBlade sets a color key of 0x80000000 but the texture passed into the
// shader is cleared to 0 alpha.
unsigned int color_key = d->pvideo.regs[NV_PVIDEO_COLOR_KEY] & 0xFFFFFF;
glUniform4f(d->pgraph.disp_rndr.pvideo_color_key_loc,
GET_MASK(color_key, NV_PVIDEO_COLOR_KEY_RED) / 255.0,
GET_MASK(color_key, NV_PVIDEO_COLOR_KEY_GREEN) / 255.0,
GET_MASK(color_key, NV_PVIDEO_COLOR_KEY_BLUE) / 255.0,
GET_MASK(color_key, NV_PVIDEO_COLOR_KEY_ALPHA) / 255.0);
assert(offset + in_pitch * in_height <= limit);
hwaddr end = base + offset + in_pitch * in_height;
assert(end <= memory_region_size(d->vram));