Module: wine Branch: master Commit: f84d741cb3e639018e757d2f86c23117dca7d749 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f84d741cb3e639018e757d2f86...
Author: Stefan Dösinger stefan@codeweavers.com Date: Tue Apr 14 11:16:24 2015 +0200
wined3d: Implement color keying in the ARB fixed function pipeline.
---
dlls/wined3d/arb_program_shader.c | 104 +++++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 14 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index b9b5541..ef7f6ff 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -5762,7 +5762,8 @@ const struct wined3d_shader_backend_ops arb_program_shader_backend =
/* ARB_fragment_program fixed function pipeline replacement definitions */ #define ARB_FFP_CONST_TFACTOR 0 -#define ARB_FFP_CONST_SPECULAR_ENABLE ((ARB_FFP_CONST_TFACTOR) + 1) +#define ARB_FFP_CONST_COLOR_KEY ((ARB_FFP_CONST_TFACTOR) + 1) +#define ARB_FFP_CONST_SPECULAR_ENABLE ((ARB_FFP_CONST_COLOR_KEY) + 1) #define ARB_FFP_CONST_CONSTANT(i) ((ARB_FFP_CONST_SPECULAR_ENABLE) + 1 + i) #define ARB_FFP_CONST_BUMPMAT(i) ((ARB_FFP_CONST_CONSTANT(7)) + 1 + i) #define ARB_FFP_CONST_LUMINANCE(i) ((ARB_FFP_CONST_BUMPMAT(7)) + 1 + i) @@ -5841,7 +5842,8 @@ static void arbfp_free(struct wined3d_device *device) static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps) { caps->wined3d_caps = WINED3D_FRAGMENT_CAP_PROJ_CONTROL - | WINED3D_FRAGMENT_CAP_SRGB_WRITE; + | WINED3D_FRAGMENT_CAP_SRGB_WRITE + | WINED3D_FRAGMENT_CAP_COLOR_KEY; caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP; caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE | WINED3DTEXOPCAPS_SELECTARG1 | @@ -5995,6 +5997,66 @@ static void tex_bumpenvlum_arbfp(struct wined3d_context *context, checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_LUMINANCE(stage), param)"); }
+static void alpha_test_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + int glParm; + float ref; + + TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); + + if (state->render_states[WINED3D_RS_ALPHATESTENABLE]) + { + gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST); + checkGLcall("glEnable GL_ALPHA_TEST"); + } + else + { + gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST); + checkGLcall("glDisable GL_ALPHA_TEST"); + return; + } + + ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f; + glParm = wined3d_gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]); + + if (glParm) + { + gl_info->gl_ops.gl.p_glAlphaFunc(glParm, ref); + checkGLcall("glAlphaFunc"); + } +} + +static void color_key_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + struct wined3d_device *device = context->swapchain->device; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_color float_key; + const struct wined3d_texture *texture = state->textures[0]; + + if (!texture) + return; + + /* Don't load the parameter if we're using an arbfp pixel shader, + * otherwise we'll overwrite application provided constants. */ + if (device->shader_backend == &arb_program_shader_backend) + { + struct shader_arb_priv *priv; + + if (use_ps(state)) + return; + + priv = device->shader_priv; + priv->pshader_const_dirty[ARB_FFP_CONST_COLOR_KEY] = 1; + priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_COLOR_KEY + 1); + } + + wined3d_format_convert_color_to_float(texture->resource.format, NULL, + texture->async.src_blt_color_key.color_space_high_value, &float_key); + GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_COLOR_KEY, &float_key.r)); + checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_COLOR_KEY, &float_key.r)"); +} + static const char *get_argreg(struct wined3d_shader_buffer *buffer, DWORD argnum, unsigned int stage, DWORD arg) { const char *ret; @@ -6237,6 +6299,20 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con GLint pos; BOOL custom_linear_fog = FALSE;
+ if (!shader_buffer_init(&buffer)) + { + ERR("Failed to initialize shader buffer.\n"); + return 0; + } + + shader_addline(&buffer, "!!ARBfp1.0\n"); + + if (settings->color_key_enabled) + { + shader_addline(&buffer, "PARAM color_key = program.env[%u];\n", ARB_FFP_CONST_COLOR_KEY); + tex_read[0] = TRUE; + } + /* Find out which textures are read */ for (stage = 0; stage < MAX_TEXTURES; ++stage) { @@ -6296,15 +6372,6 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con } lowest_disabled_stage = stage;
- /* Shader header */ - if (!shader_buffer_init(&buffer)) - { - ERR("Failed to initialize shader buffer.\n"); - return 0; - } - - shader_addline(&buffer, "!!ARBfp1.0\n"); - switch (settings->fog) { case WINED3D_FFP_PS_FOG_OFF: break; @@ -6423,6 +6490,14 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con settings->op[stage].color_fixup); }
+ if (settings->color_key_enabled) + { + shader_addline(&buffer, "SUB TMP, tex0, color_key;\n"); + shader_addline(&buffer, "DP4 TMP.b, TMP, TMP;\n"); + shader_addline(&buffer, "SGE TMP, -TMP.b, 0.0;\n"); + shader_addline(&buffer, "KIL -TMP;\n"); + } + /* Generate the main shader */ for (stage = 0; stage < MAX_TEXTURES; ++stage) { @@ -6543,6 +6618,7 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi } state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR)); state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); + color_key_arbfp(context, state, STATE_COLOR_KEY); } else if (use_pshader) { @@ -6782,9 +6858,9 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] = {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), fragment_prog_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_alpha_test }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_COLOR_KEY, { STATE_COLOR_KEY, state_nop }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), alpha_test_arbfp }, WINED3D_GL_EXT_NONE }, + {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, + {STATE_COLOR_KEY, { STATE_COLOR_KEY, color_key_arbfp }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },