mirror of https://github.com/xemu-project/xemu.git
nv2a: Implement pvideo color keying
This commit is contained in:
parent
b3f56db428
commit
6b821d2062
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue