From 382fa588a91b6c55a64d230257f9920dee7546f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 14 Apr 2015 11:16:22 +0200 Subject: [PATCH] wined3d: Handle color key dirtification in wined3d_cs_exec_set_texture. --- dlls/wined3d/arb_program_shader.c | 1 + dlls/wined3d/ati_fragment_shader.c | 1 + dlls/wined3d/cs.c | 13 +++++++++++++ dlls/wined3d/glsl_shader.c | 7 +++++++ dlls/wined3d/nvidia_texture_shader.c | 1 + dlls/wined3d/state.c | 24 +++--------------------- dlls/wined3d/utils.c | 2 ++ dlls/wined3d/wined3d_private.h | 7 ++++++- 8 files changed, 34 insertions(+), 22 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index fca2d32351a..b9b55412df5 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -6784,6 +6784,7 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] = {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_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 }, diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index b698df37035..b41f5d9669f 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -1113,6 +1113,7 @@ static const struct StateEntryTemplate atifs_fragmentstate_template[] = { {STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), atifs_srgbwriteenable }, WINED3D_GL_EXT_NONE }, + {STATE_COLOR_KEY, { STATE_COLOR_KEY, state_nop }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 6bdf969b41e..8271634cb41 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -640,6 +640,7 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info; const struct wined3d_cs_set_texture *op = data; struct wined3d_texture *prev; + BOOL old_use_color_key = FALSE, new_use_color_key = FALSE; prev = cs->state.textures[op->stage]; cs->state.textures[op->stage] = op->texture; @@ -665,6 +666,9 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP)); device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP)); } + + if (!op->stage && op->texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT) + new_use_color_key = TRUE; } if (prev) @@ -692,9 +696,18 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data) device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP)); device_invalidate_state(cs->device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP)); } + + if (!op->stage && prev->async.color_key_flags & WINED3D_CKEY_SRC_BLT) + old_use_color_key = TRUE; } device_invalidate_state(cs->device, STATE_SAMPLER(op->stage)); + + if (new_use_color_key != old_use_color_key) + device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE)); + + if (new_use_color_key) + device_invalidate_state(cs->device, STATE_COLOR_KEY); } void wined3d_cs_emit_set_texture(struct wined3d_cs *cs, UINT stage, struct wined3d_texture *texture) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 2422982614f..e1867bf58c3 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -7610,6 +7610,12 @@ static void glsl_fragment_pipe_alpha_test(struct wined3d_context *context, } } +static void glsl_fragment_pipe_color_key(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_COLOR_KEY; +} + static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] = { {STATE_VDECL, {STATE_VDECL, glsl_fragment_pipe_vdecl }, WINED3D_GL_EXT_NONE }, @@ -7691,6 +7697,7 @@ static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] = {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), glsl_fragment_pipe_alpha_test }, 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, glsl_fragment_pipe_color_key }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), glsl_fragment_pipe_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 }, diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index 62451545e71..0dda7f5faf6 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -884,6 +884,7 @@ static const struct StateEntryTemplate nvrc_fragmentstate_template[] = { 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_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index b3ac4f178c5..39b02564c6e 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -45,7 +45,7 @@ static void state_undefined(struct wined3d_context *context, const struct wined3 ERR("Undefined state.\n"); } -static void state_nop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +void state_nop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state_id)); } @@ -3741,32 +3741,12 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state gl_tex->base_level = base_level; } - if (!use_ps(state) && sampler_idx < context->lowest_disabled_stage) - { - if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler_idx) - { - /* If color keying is enabled update the alpha test, it - * depends on the existence of a color key in stage 0. */ - context_apply_state(context, state, WINED3D_RS_COLORKEYENABLE); - } - } - /* Trigger shader constant reloading (for NP2 texcoord fixup) */ if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT)) context->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP; } else { - if (sampler_idx < context->lowest_disabled_stage) - { - /* TODO: What should I do with pixel shaders here ??? */ - if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler_idx) - { - /* If color keying is enabled update the alpha test, it - * depends on the existence of a color key in stage 0. */ - context_apply_state(context, state, WINED3D_RS_COLORKEYENABLE); - } - } /* Otherwise tex_colorop disables the stage */ context_bind_texture(context, GL_NONE, 0); } } @@ -5674,6 +5654,7 @@ static const struct StateEntryTemplate ffp_fragmentstate_template[] = { { 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_SRGBWRITEENABLE), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, @@ -5951,6 +5932,7 @@ static void validate_state_table(struct StateEntry *state_table) STATE_BASEVERTEXINDEX, STATE_FRAMEBUFFER, STATE_POINT_SIZE_ENABLE, + STATE_COLOR_KEY, }; unsigned int i, current; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 2f21b290491..1686e3072df 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -3001,6 +3001,8 @@ const char *debug_d3dstate(DWORD state) return "STATE_FRAMEBUFFER"; if (STATE_IS_POINT_SIZE_ENABLE(state)) return "STATE_POINT_SIZE_ENABLE"; + if (STATE_IS_COLOR_KEY(state)) + return "STATE_COLOR_KEY"; return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state); } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7a4b89083ac..df742681ab5 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1068,7 +1068,10 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; #define STATE_POINT_SIZE_ENABLE (STATE_FRAMEBUFFER + 1) #define STATE_IS_POINT_SIZE_ENABLE(a) ((a) == STATE_POINT_SIZE_ENABLE) -#define STATE_HIGHEST (STATE_POINT_SIZE_ENABLE) +#define STATE_COLOR_KEY (STATE_POINT_SIZE_ENABLE + 1) +#define STATE_IS_COLOR_KEY(a) ((a) == STATE_COLOR_KEY) + +#define STATE_HIGHEST (STATE_COLOR_KEY) enum fogsource { FOGSOURCE_FFP, @@ -2826,6 +2829,8 @@ void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; +void state_nop(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;