wined3d: Set color keys through the command stream.

This commit is contained in:
Stefan Dösinger 2015-04-09 22:48:11 +02:00 committed by Alexandre Julliard
parent 086d2af629
commit 82db5954c4
6 changed files with 141 additions and 75 deletions

View File

@ -49,6 +49,7 @@ enum wined3d_cs_op
WINED3D_CS_OP_SET_SAMPLER_STATE,
WINED3D_CS_OP_SET_TRANSFORM,
WINED3D_CS_OP_SET_CLIP_PLANE,
WINED3D_CS_OP_SET_COLOR_KEY,
WINED3D_CS_OP_SET_MATERIAL,
WINED3D_CS_OP_RESET_STATE,
};
@ -170,6 +171,15 @@ struct wined3d_cs_set_texture
struct wined3d_texture *texture;
};
struct wined3d_cs_set_color_key
{
enum wined3d_cs_op opcode;
struct wined3d_texture *texture;
WORD flags;
WORD set;
struct wined3d_color_key color_key;
};
struct wined3d_cs_set_shader_resource_view
{
enum wined3d_cs_op opcode;
@ -870,6 +880,79 @@ void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, const
cs->ops->submit(cs);
}
static void wined3d_cs_exec_set_color_key(struct wined3d_cs *cs, const void *data)
{
const struct wined3d_cs_set_color_key *op = data;
struct wined3d_texture *texture = op->texture;
if (op->set)
{
switch (op->flags & ~WINED3D_CKEY_COLORSPACE)
{
case WINED3D_CKEY_DST_BLT:
texture->async.dst_blt_color_key = op->color_key;
texture->async.color_key_flags |= WINED3D_CKEY_DST_BLT;
break;
case WINED3D_CKEY_DST_OVERLAY:
texture->async.dst_overlay_color_key = op->color_key;
texture->async.color_key_flags |= WINED3D_CKEY_DST_OVERLAY;
break;
case WINED3D_CKEY_SRC_BLT:
texture->async.src_blt_color_key = op->color_key;
texture->async.color_key_flags |= WINED3D_CKEY_SRC_BLT;
break;
case WINED3D_CKEY_SRC_OVERLAY:
texture->async.src_overlay_color_key = op->color_key;
texture->async.color_key_flags |= WINED3D_CKEY_SRC_OVERLAY;
break;
}
}
else
{
switch (op->flags & ~WINED3D_CKEY_COLORSPACE)
{
case WINED3D_CKEY_DST_BLT:
texture->async.color_key_flags &= ~WINED3D_CKEY_DST_BLT;
break;
case WINED3D_CKEY_DST_OVERLAY:
texture->async.color_key_flags &= ~WINED3D_CKEY_DST_OVERLAY;
break;
case WINED3D_CKEY_SRC_BLT:
texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_BLT;
break;
case WINED3D_CKEY_SRC_OVERLAY:
texture->async.color_key_flags &= ~WINED3D_CKEY_SRC_OVERLAY;
break;
}
}
}
void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture,
WORD flags, const struct wined3d_color_key *color_key)
{
struct wined3d_cs_set_color_key *op;
op = cs->ops->require_space(cs, sizeof(*op));
op->opcode = WINED3D_CS_OP_SET_COLOR_KEY;
op->texture = texture;
op->flags = flags;
if (color_key)
{
op->color_key = *color_key;
op->set = 1;
}
else
op->set = 0;
cs->ops->submit(cs);
}
static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data)
{
const struct wined3d_cs_set_material *op = data;
@ -936,6 +1019,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
/* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state,
/* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform,
/* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane,
/* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key,
/* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material,
/* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state,
};

View File

@ -521,7 +521,7 @@ static void state_alpha(struct wined3d_context *context, const struct wined3d_st
* WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture
* function will call alpha in case it finds some texture + colorkeyenable
* combination which needs extra care. */
if (state->textures[0] && (state->textures[0]->color_key_flags & WINED3D_CKEY_SRC_BLT))
if (state->textures[0] && (state->textures[0]->async.color_key_flags & WINED3D_CKEY_SRC_BLT))
enable_ckey = TRUE;
if (enable_ckey || context->last_was_ckey)
@ -3210,7 +3210,7 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st
if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
{
if (texture->color_key_flags & WINED3D_CKEY_SRC_BLT && !texture->resource.format->alpha_size)
if (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT && !texture->resource.format->alpha_size)
{
/* Color keying needs to pass alpha values from the texture through to have the alpha test work
* properly. On the other hand applications can still use texture combiners apparently. This code

View File

@ -3410,7 +3410,7 @@ static void surface_blt_to_drawable(const struct wined3d_device *device,
* other cases pixels that should be masked away have alpha set to 0. */
if (src_surface->resource.format->id == WINED3DFMT_P8_UINT)
gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL,
(float)src_surface->container->src_blt_color_key.color_space_low_value / 255.0f);
(float)src_surface->container->async.src_blt_color_key.color_space_low_value / 255.0f);
else
gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, 0.0f);
checkGLcall("glAlphaFunc");
@ -3586,8 +3586,8 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
else if (src_surface)
{
/* Blit from offscreen surface to render target */
struct wined3d_color_key old_blt_key = src_surface->container->src_blt_color_key;
DWORD old_color_key_flags = src_surface->container->color_key_flags;
struct wined3d_color_key old_blt_key = src_surface->container->async.src_blt_color_key;
DWORD old_color_key_flags = src_surface->container->async.color_key_flags;
TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface);
@ -4168,7 +4168,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
if (texture->swapchain && texture->swapchain->palette)
palette = texture->swapchain->palette;
conversion->convert(data.addr, src_pitch, mem, dst_pitch,
width, height, palette, &texture->gl_color_key);
width, height, palette, &texture->async.gl_color_key);
src_pitch = dst_pitch;
data.addr = mem;
}
@ -4830,8 +4830,8 @@ do { \
/* The color keying flags are checked for correctness in ddraw */
if (flags & WINEDDBLT_KEYSRC)
{
keylow = src_surface->container->src_blt_color_key.color_space_low_value;
keyhigh = src_surface->container->src_blt_color_key.color_space_high_value;
keylow = src_surface->container->async.src_blt_color_key.color_space_low_value;
keyhigh = src_surface->container->async.src_blt_color_key.color_space_high_value;
}
else if (flags & WINEDDBLT_KEYSRCOVERRIDE)
{
@ -4842,8 +4842,8 @@ do { \
if (flags & WINEDDBLT_KEYDEST)
{
/* Destination color keys are taken from the source surface! */
destkeylow = src_surface->container->dst_blt_color_key.color_space_low_value;
destkeyhigh = src_surface->container->dst_blt_color_key.color_space_high_value;
destkeylow = src_surface->container->async.dst_blt_color_key.color_space_low_value;
destkeyhigh = src_surface->container->async.dst_blt_color_key.color_space_high_value;
}
else if (flags & WINEDDBLT_KEYDESTOVERRIDE)
{

View File

@ -437,6 +437,12 @@ struct wined3d_resource * CDECL wined3d_texture_get_resource(struct wined3d_text
return &texture->resource;
}
static BOOL color_key_equal(const struct wined3d_color_key *c1, struct wined3d_color_key *c2)
{
return c1->color_space_low_value == c2->color_space_low_value
&& c1->color_space_high_value == c2->color_space_high_value;
}
/* Context activation is done by the caller */
void wined3d_texture_load(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb)
@ -456,10 +462,10 @@ void wined3d_texture_load(struct wined3d_texture *texture,
else
flag = WINED3D_TEXTURE_RGB_VALID;
if (!(texture->flags & WINED3D_TEXTURE_COLOR_KEY) != !(texture->color_key_flags & WINED3D_CKEY_SRC_BLT)
|| (texture->flags & WINED3D_TEXTURE_COLOR_KEY
&& (texture->gl_color_key.color_space_low_value != texture->src_blt_color_key.color_space_low_value
|| texture->gl_color_key.color_space_high_value != texture->src_blt_color_key.color_space_high_value)))
if (!(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)))
{
unsigned int sub_count = texture->level_count * texture->layer_count;
unsigned int i;
@ -469,7 +475,7 @@ void wined3d_texture_load(struct wined3d_texture *texture,
texture->texture_ops->texture_sub_resource_add_dirty_region(texture->sub_resources[i], NULL);
wined3d_texture_set_dirty(texture);
texture->gl_color_key = texture->src_blt_color_key;
texture->async.gl_color_key = texture->async.src_blt_color_key;
}
if (texture->flags & flag)
@ -571,60 +577,25 @@ enum wined3d_texture_filter_type CDECL wined3d_texture_get_autogen_filter_type(c
HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
DWORD flags, const struct wined3d_color_key *color_key)
{
struct wined3d_device *device = texture->resource.device;
static const DWORD all_flags = WINED3D_CKEY_COLORSPACE | WINED3D_CKEY_DST_BLT
| WINED3D_CKEY_DST_OVERLAY | WINED3D_CKEY_SRC_BLT | WINED3D_CKEY_SRC_OVERLAY;
TRACE("texture %p, flags %#x, color_key %p.\n", texture, flags, color_key);
if (flags & ~all_flags)
{
WARN("Invalid flags passed, returning WINED3DERR_INVALIDCALL.\n");
return WINED3DERR_INVALIDCALL;
}
if (flags & WINED3D_CKEY_COLORSPACE)
{
FIXME("Unhandled flags %#x.\n", flags);
return WINED3DERR_INVALIDCALL;
}
if (color_key)
{
switch (flags & ~WINED3D_CKEY_COLORSPACE)
{
case WINED3D_CKEY_DST_BLT:
texture->dst_blt_color_key = *color_key;
texture->color_key_flags |= WINED3D_CKEY_DST_BLT;
break;
case WINED3D_CKEY_DST_OVERLAY:
texture->dst_overlay_color_key = *color_key;
texture->color_key_flags |= WINED3D_CKEY_DST_OVERLAY;
break;
case WINED3D_CKEY_SRC_BLT:
texture->src_blt_color_key = *color_key;
texture->color_key_flags |= WINED3D_CKEY_SRC_BLT;
break;
case WINED3D_CKEY_SRC_OVERLAY:
texture->src_overlay_color_key = *color_key;
texture->color_key_flags |= WINED3D_CKEY_SRC_OVERLAY;
break;
}
}
else
{
switch (flags & ~WINED3D_CKEY_COLORSPACE)
{
case WINED3D_CKEY_DST_BLT:
texture->color_key_flags &= ~WINED3D_CKEY_DST_BLT;
break;
case WINED3D_CKEY_DST_OVERLAY:
texture->color_key_flags &= ~WINED3D_CKEY_DST_OVERLAY;
break;
case WINED3D_CKEY_SRC_BLT:
texture->color_key_flags &= ~WINED3D_CKEY_SRC_BLT;
break;
case WINED3D_CKEY_SRC_OVERLAY:
texture->color_key_flags &= ~WINED3D_CKEY_SRC_OVERLAY;
break;
}
}
wined3d_cs_emit_set_color_key(device->cs, texture, flags, color_key);
return WINED3D_OK;
}
@ -694,14 +665,15 @@ void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct win
{
DWORD alloc_flag = srgb ? WINED3D_TEXTURE_SRGB_ALLOCATED : WINED3D_TEXTURE_RGB_ALLOCATED;
if (!(texture->flags & WINED3D_TEXTURE_COLOR_KEY) != !(texture->color_key_flags & WINED3D_CKEY_SRC_BLT))
if (!(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)
!= !(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT))
wined3d_texture_force_reload(texture);
if (texture->flags & alloc_flag)
return;
if (texture->color_key_flags & WINED3D_CKEY_SRC_BLT)
texture->flags |= WINED3D_TEXTURE_COLOR_KEY;
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;
@ -713,7 +685,8 @@ void wined3d_texture_force_reload(struct wined3d_texture *texture)
unsigned int i;
texture->flags &= ~(WINED3D_TEXTURE_RGB_ALLOCATED | WINED3D_TEXTURE_SRGB_ALLOCATED
| WINED3D_TEXTURE_CONVERTED | WINED3D_TEXTURE_COLOR_KEY);
| WINED3D_TEXTURE_CONVERTED);
texture->async.flags &= ~WINED3D_TEXTURE_ASYNC_COLOR_KEY;
for (i = 0; i < sub_count; ++i)
{
texture->texture_ops->texture_sub_resource_invalidate_location(texture->sub_resources[i],

View File

@ -843,7 +843,7 @@ const struct wined3d_color_key_conversion * wined3d_format_get_color_key_convers
WINED3DFMT_B8G8R8A8_UNORM, convert_p8_uint_b8g8r8a8_unorm
};
if (need_alpha_ck && (texture->flags & WINED3D_TEXTURE_COLOR_KEY))
if (need_alpha_ck && (texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY))
{
for (i = 0; i < sizeof(color_key_info) / sizeof(*color_key_info); ++i)
{
@ -3781,7 +3781,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
{
if (texture->color_key_flags & WINED3D_CKEY_SRC_BLT && !texture->resource.format->alpha_size)
if (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT && !texture->resource.format->alpha_size)
{
if (aop == WINED3D_TOP_DISABLE)
{

View File

@ -2187,7 +2187,8 @@ struct wined3d_texture_ops
#define WINED3D_TEXTURE_PIN_SYSMEM 0x00000100
#define WINED3D_TEXTURE_DYNAMIC_MAP 0x00000200
#define WINED3D_TEXTURE_NORMALIZED_COORDS 0x00000400
#define WINED3D_TEXTURE_COLOR_KEY 0x00000800
#define WINED3D_TEXTURE_ASYNC_COLOR_KEY 0x00000001
struct wined3d_texture
{
@ -2205,13 +2206,19 @@ struct wined3d_texture
DWORD flags;
GLenum target;
/* Color keys for DDraw */
struct wined3d_color_key dst_blt_color_key;
struct wined3d_color_key src_blt_color_key;
struct wined3d_color_key dst_overlay_color_key;
struct wined3d_color_key src_overlay_color_key;
struct wined3d_color_key gl_color_key;
DWORD color_key_flags;
/* May only be accessed from the command stream worker thread. */
struct wined3d_texture_async
{
DWORD flags;
/* Color keys for DDraw */
struct wined3d_color_key dst_blt_color_key;
struct wined3d_color_key src_blt_color_key;
struct wined3d_color_key dst_overlay_color_key;
struct wined3d_color_key src_overlay_color_key;
struct wined3d_color_key gl_color_key;
DWORD color_key_flags;
} async;
};
static inline struct wined3d_texture *wined3d_texture_from_resource(struct wined3d_resource *resource)
@ -2553,6 +2560,8 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw
void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx,
const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture,
WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type,
UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs,