[PATCH 4/9] wined3d: Implement color keying in the glsl fragment pipeline.
Stefan Dösinger
stefan at codeweavers.com
Thu Apr 9 15:48:14 CDT 2015
Note that state_alpha() currently always updates the alpha op and thus
the pixel shader when color keying is enabled or has been enabled in the
previous draw. That's not ideal, but right now I am using it to reduce
the complexity of this patch. The next patches will address this.
Changing texture 0 updates the colorkey state when pixel shaders are
disabled.
---
dlls/ddraw/tests/ddraw1.c | 22 ++++++----------------
dlls/ddraw/tests/ddraw2.c | 22 ++++++----------------
dlls/ddraw/tests/ddraw4.c | 22 ++++++----------------
dlls/ddraw/tests/ddraw7.c | 22 ++++++----------------
dlls/wined3d/arb_program_shader.c | 25 +++++++++----------------
dlls/wined3d/cs.c | 3 +++
dlls/wined3d/directx.c | 1 +
dlls/wined3d/glsl_shader.c | 29 +++++++++++++++++++++++++++--
dlls/wined3d/state.c | 3 +++
dlls/wined3d/texture.c | 18 ++++++++++++------
dlls/wined3d/utils.c | 9 +++++++++
dlls/wined3d/wined3d_private.h | 10 +++++++---
12 files changed, 95 insertions(+), 91 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index efb00b2..597251c 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -1329,14 +1329,9 @@ static void test_ck_rgba(void)
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
- if (i == 2)
- todo_wine ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result1, i, color);
- else
- ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result1, i, color);
+ ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
+ "Expected color 0x%08x for test %u, got 0x%08x.\n",
+ tests[i].result1, i, color);
U5(fx).dwFillColor = 0xff0000ff;
hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
@@ -1353,14 +1348,9 @@ static void test_ck_rgba(void)
/* This tests that fragments that are masked out by the color key are
* discarded, instead of just fully transparent. */
color = get_surface_color(rt, 320, 240);
- if (i == 2)
- todo_wine ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result2, i, color);
- else
- ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result2, i, color);
+ ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
+ "Expected color 0x%08x for test %u, got 0x%08x.\n",
+ tests[i].result2, i, color);
}
IDirectDrawSurface_Release(rt);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 5f59f06..104bf5b 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -1577,14 +1577,9 @@ static void test_ck_rgba(void)
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
- if (i == 2)
- todo_wine ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result1, i, color);
- else
- ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result1, i, color);
+ ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
+ "Expected color 0x%08x for test %u, got 0x%08x.\n",
+ tests[i].result1, i, color);
U5(fx).dwFillColor = 0xff0000ff;
hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
@@ -1600,14 +1595,9 @@ static void test_ck_rgba(void)
/* This tests that fragments that are masked out by the color key are
* discarded, instead of just fully transparent. */
color = get_surface_color(rt, 320, 240);
- if (i == 2)
- todo_wine ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result2, i, color);
- else
- ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result2, i, color);
+ ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
+ "Expected color 0x%08x for test %u, got 0x%08x.\n",
+ tests[i].result2, i, color);
}
IDirectDrawSurface_Release(rt);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 70ca117..ac31e24 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -1766,14 +1766,9 @@ static void test_ck_rgba(void)
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
- if (i == 2)
- todo_wine ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result1, i, color);
- else
- ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result1, i, color);
+ ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
+ "Expected color 0x%08x for test %u, got 0x%08x.\n",
+ tests[i].result1, i, color);
U5(fx).dwFillColor = 0xff0000ff;
hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
@@ -1789,14 +1784,9 @@ static void test_ck_rgba(void)
/* This tests that fragments that are masked out by the color key are
* discarded, instead of just fully transparent. */
color = get_surface_color(rt, 320, 240);
- if (i == 2)
- todo_wine ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result2, i, color);
- else
- ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result2, i, color);
+ ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
+ "Expected color 0x%08x for test %u, got 0x%08x.\n",
+ tests[i].result2, i, color);
}
IDirectDrawSurface4_Release(rt);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 21ba3390..8d679ca 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -1471,14 +1471,9 @@ static void test_ck_rgba(void)
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
- if (i == 2)
- todo_wine ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result1, i, color);
- else
- ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result1, i, color);
+ ok(compare_color(color, tests[i].result1, 1) || compare_color(color, tests[i].result1_broken, 1),
+ "Expected color 0x%08x for test %u, got 0x%08x.\n",
+ tests[i].result1, i, color);
U5(fx).dwFillColor = 0xff0000ff;
hr = IDirectDrawSurface7_Blt(texture, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
@@ -1494,14 +1489,9 @@ static void test_ck_rgba(void)
/* This tests that fragments that are masked out by the color key are
* discarded, instead of just fully transparent. */
color = get_surface_color(rt, 320, 240);
- if (i == 2)
- todo_wine ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result2, i, color);
- else
- ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
- "Expected color 0x%08x for test %u, got 0x%08x.\n",
- tests[i].result2, i, color);
+ ok(compare_color(color, tests[i].result2, 1) || compare_color(color, tests[i].result2_broken, 1),
+ "Expected color 0x%08x for test %u, got 0x%08x.\n",
+ tests[i].result2, i, color);
}
IDirectDrawSurface7_Release(rt);
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index f740123..5d7d975 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -7556,10 +7556,10 @@ static GLuint arbfp_gen_plain_shader(struct arbfp_blit_priv *priv,
shader_addline(&buffer, "TEMP compare;\n");
shader_addline(&buffer, "PARAM color_key = program.local[%u];\n", ARBFP_BLIT_PARAM_COLOR_KEY);
shader_addline(&buffer, "TEX color, fragment.texcoord[0], texture[0], %s;\n", tex_target);
- shader_addline(&buffer, "SGE compare.r, color.a, color_key.a;\n");
- shader_addline(&buffer, "SGE compare.g, -color.a, color_key.a;\n");
- shader_addline(&buffer, "MUL compare, compare.r, -compare.g;\n");
- shader_addline(&buffer, "KIL compare;\n");
+ shader_addline(&buffer, "SUB compare, color, color_key;\n");
+ shader_addline(&buffer, "DP4 compare.r, compare, compare;\n");
+ shader_addline(&buffer, "SGE compare, -compare.r, 0.0;\n");
+ shader_addline(&buffer, "KIL -compare;\n");
shader_addline(&buffer, "MOV result.color, color;\n");
}
else
@@ -7599,7 +7599,7 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context,
struct wine_rb_entry *entry;
struct arbfp_blit_type type;
struct arbfp_blit_desc *desc;
- float float_color_key[4] = {0, 0, 0, 0};
+ struct wined3d_color float_color_key;
if (is_complex_fixup(surface->resource.format->color_fixup))
fixup = get_complex_fixup(surface->resource.format->color_fixup);
@@ -7699,10 +7699,10 @@ err_out:
checkGLcall("glProgramLocalParameter4fvARB");
if (type.use_color_key)
{
- if (surface->resource.format->id == WINED3DFMT_P8_UINT)
- float_color_key[3] = color_key->color_space_low_value / 255.0f;
-
- GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARBFP_BLIT_PARAM_COLOR_KEY, float_color_key));
+ wined3d_format_convert_color_to_float(surface->resource.format, NULL,
+ surface->container->async.src_blt_color_key.color_space_high_value, &float_color_key);
+ GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
+ ARBFP_BLIT_PARAM_COLOR_KEY, &float_color_key.r));
checkGLcall("glProgramLocalParameter4fvARB");
}
@@ -7790,10 +7790,6 @@ HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter,
struct wined3d_context *context;
RECT src_rect = *src_rect_in;
RECT dst_rect = *dst_rect_in;
- struct wined3d_color_key old_color_key = src_surface->container->async.src_blt_color_key;
- DWORD old_color_key_flags = src_surface->container->async.color_key_flags;
-
- wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT, color_key);
/* Activate the destination context, set it up for blitting */
context = context_acquire(device, dst_surface);
@@ -7840,9 +7836,6 @@ HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter,
surface_validate_location(dst_surface, dst_surface->container->resource.draw_binding);
surface_invalidate_location(dst_surface, ~dst_surface->container->resource.draw_binding);
- wined3d_texture_set_color_key(src_surface->container, WINED3D_CKEY_SRC_BLT,
- (old_color_key_flags & WINED3D_CKEY_SRC_BLT) ? &old_color_key : NULL);
-
return WINED3D_OK;
}
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 4ed68f3..6bdf969 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -931,6 +931,9 @@ static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *dat
break;
}
}
+
+ if (texture->resource.bind_count && op->flags & WINED3D_CKEY_SRC_BLT)
+ device_invalidate_state(cs->device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
}
void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture,
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 13061f4..36fc4ed 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -3563,6 +3563,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages;
adapter->d3d_info.limits.ffp_textures = fragment_caps.MaxSimultaneousTextures;
+ adapter->d3d_info.shader_color_key = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_COLOR_KEY;
TRACE("Max texture stages: %u.\n", adapter->d3d_info.limits.ffp_blend_stages);
if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index f7edc0f..39c58cc 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -143,6 +143,7 @@ struct glsl_ps_program
GLint specular_enable_location;
GLint ycorrection_location;
GLint np2_fixup_location;
+ GLint color_key_location;
const struct ps_np2fixup_info *np2_fixup_info;
};
@@ -834,6 +835,18 @@ static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_con
}
/* Context activation is done by the caller (state handler). */
+static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps,
+ const struct wined3d_gl_info *gl_info, const struct wined3d_state *state)
+{
+ struct wined3d_color float_key;
+ const struct wined3d_texture *texture = state->textures[0];
+
+ wined3d_format_convert_color_to_float(texture->resource.format, NULL,
+ texture->async.src_blt_color_key.color_space_high_value, &float_key);
+ GL_EXTCALL(glUniform4fv(ps->color_key_location, 1, &float_key.r));
+}
+
+/* Context activation is done by the caller (state handler). */
static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *context,
const struct wined3d_state *state)
{
@@ -947,6 +960,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
if (update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP)
shader_glsl_load_np2fixup_constants(&prog->ps, gl_info, state);
+ if (update_mask & WINED3D_SHADER_CONST_FFP_COLOR_KEY)
+ shader_glsl_load_color_key_constant(&prog->ps, gl_info, state);
if (update_mask & WINED3D_SHADER_CONST_FFP_PS)
{
@@ -5499,7 +5514,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf
arg1 = settings->op[stage].carg1 & WINED3DTA_SELECTMASK;
arg2 = settings->op[stage].carg2 & WINED3DTA_SELECTMASK;
- if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE)
+ if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE
+ || (stage == 0 && settings->color_key_enabled))
tex_map |= 1 << stage;
if (arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR)
tfactor_used = TRUE;
@@ -5603,6 +5619,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf
}
if (tfactor_used)
shader_addline(buffer, "uniform vec4 tex_factor;\n");
+ if (settings->color_key_enabled)
+ shader_addline(buffer, "uniform vec4 color_key;\n");
shader_addline(buffer, "uniform vec4 specular_enable;\n");
if (settings->sRGB_write)
@@ -5759,6 +5777,9 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf
settings->op[stage].color_fixup);
}
+ if (settings->color_key_enabled)
+ shader_addline(buffer, "if (all(equal(tex0, color_key))) discard;\n");
+
/* Generate the main shader */
for (stage = 0; stage < MAX_TEXTURES; ++stage)
{
@@ -5949,6 +5970,7 @@ static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *
ps->specular_enable_location = GL_EXTCALL(glGetUniformLocation(program_id, "specular_enable"));
ps->np2_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "ps_samplerNP2Fixup"));
ps->ycorrection_location = GL_EXTCALL(glGetUniformLocation(program_id, "ycorrection"));
+ ps->color_key_location = GL_EXTCALL(glGetUniformLocation(program_id, "color_key"));
}
static void shader_glsl_init_uniform_block_bindings(const struct wined3d_gl_info *gl_info, GLuint program_id,
@@ -6245,6 +6267,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
if (entry->ps.np2_fixup_location != -1)
entry->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP;
+ if (entry->ps.color_key_location != -1)
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_COLOR_KEY;
}
}
@@ -7405,7 +7429,8 @@ static void glsl_fragment_pipe_enable(const struct wined3d_gl_info *gl_info, BOO
static void glsl_fragment_pipe_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
| WINED3DPMISCCAPS_PERSTAGECONSTANT;
caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index f5c1b4f..26bb7dd 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -528,6 +528,9 @@ static void state_alpha(struct wined3d_context *context, const struct wined3d_st
context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
context->last_was_ckey = enable_ckey;
+ if (context->d3d_info->shader_color_key)
+ enable_ckey = FALSE;
+
if (state->render_states[WINED3D_RS_ALPHATESTENABLE]
|| (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey))
{
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 7c47189..34c69d1 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -449,6 +449,7 @@ void wined3d_texture_load(struct wined3d_texture *texture,
{
UINT sub_count = texture->level_count * texture->layer_count;
const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
DWORD flag;
UINT i;
@@ -462,10 +463,11 @@ void wined3d_texture_load(struct wined3d_texture *texture,
else
flag = WINED3D_TEXTURE_RGB_VALID;
- if (!(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)
+ if (!d3d_info->shader_color_key
+ && (!(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)
!= !(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
|| (texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY
- && !color_key_equal(&texture->async.gl_color_key, &texture->async.src_blt_color_key)))
+ && !color_key_equal(&texture->async.gl_color_key, &texture->async.src_blt_color_key))))
{
unsigned int sub_count = texture->level_count * texture->layer_count;
unsigned int i;
@@ -664,17 +666,21 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
{
DWORD alloc_flag = srgb ? WINED3D_TEXTURE_SRGB_ALLOCATED : WINED3D_TEXTURE_RGB_ALLOCATED;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
- if (!(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)
+ if (!d3d_info->shader_color_key
+ && !(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)
!= !(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT))
+ {
wined3d_texture_force_reload(texture);
+ if (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
+ texture->async.flags |= WINED3D_TEXTURE_ASYNC_COLOR_KEY;
+ }
+
if (texture->flags & alloc_flag)
return;
- if (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
- texture->async.flags |= WINED3D_TEXTURE_ASYNC_COLOR_KEY;
-
texture->texture_ops->texture_prepare_texture(texture, context, srgb);
texture->flags |= alloc_flag;
}
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 41326de..4d9f88a 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -3688,6 +3688,8 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+ settings->padding = 0;
+
for (i = 0; i < d3d_info->limits.ffp_blend_stages; ++i)
{
const struct wined3d_texture *texture;
@@ -3915,6 +3917,13 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
} else {
settings->emul_clipplanes = 1;
}
+
+ if (state->render_states[WINED3D_RS_COLORKEYENABLE] && state->textures[0]
+ && state->textures[0]->async.color_key_flags & WINED3D_CKEY_SRC_BLT
+ && settings->op[0].cop != WINED3D_TOP_DISABLE)
+ settings->color_key_enabled = 1;
+ else
+ settings->color_key_enabled = 0;
}
const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 4a454a0..5ea4150 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -309,6 +309,7 @@ enum wined3d_shader_resource_type
#define WINED3D_SHADER_CONST_FFP_MODELVIEW 0x00000400
#define WINED3D_SHADER_CONST_FFP_PROJ 0x00000800
#define WINED3D_SHADER_CONST_FFP_PS 0x00001000
+#define WINED3D_SHADER_CONST_FFP_COLOR_KEY 0x00002000
enum wined3d_shader_register_type
{
@@ -1258,6 +1259,7 @@ struct StateEntryTemplate
#define WINED3D_FRAGMENT_CAP_PROJ_CONTROL 0x00000001
#define WINED3D_FRAGMENT_CAP_SRGB_WRITE 0x00000002
+#define WINED3D_FRAGMENT_CAP_COLOR_KEY 0x00000004
struct fragment_caps
{
@@ -1743,6 +1745,7 @@ struct wined3d_d3d_info
struct wined3d_ffp_attrib_ops ffp_attrib_ops;
BOOL xyzrhw;
BOOL vs_clipping;
+ BOOL shader_color_key;
DWORD valid_rt_mask;
};
@@ -1815,9 +1818,10 @@ struct ffp_frag_settings
{
struct texture_stage_op op[MAX_TEXTURES];
enum wined3d_ffp_ps_fog_mode fog;
- /* Use shorts instead of chars to get dword alignment */
- unsigned short sRGB_write;
- unsigned short emul_clipplanes;
+ unsigned char sRGB_write;
+ unsigned char emul_clipplanes;
+ unsigned char color_key_enabled;
+ unsigned char padding;
};
struct ffp_frag_desc
--
2.3.4
More information about the wine-patches
mailing list