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_SAMPLER_STATE,
WINED3D_CS_OP_SET_TRANSFORM, WINED3D_CS_OP_SET_TRANSFORM,
WINED3D_CS_OP_SET_CLIP_PLANE, WINED3D_CS_OP_SET_CLIP_PLANE,
WINED3D_CS_OP_SET_COLOR_KEY,
WINED3D_CS_OP_SET_MATERIAL, WINED3D_CS_OP_SET_MATERIAL,
WINED3D_CS_OP_RESET_STATE, WINED3D_CS_OP_RESET_STATE,
}; };
@ -170,6 +171,15 @@ struct wined3d_cs_set_texture
struct wined3d_texture *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 struct wined3d_cs_set_shader_resource_view
{ {
enum wined3d_cs_op opcode; 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); 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) static void wined3d_cs_exec_set_material(struct wined3d_cs *cs, const void *data)
{ {
const struct wined3d_cs_set_material *op = 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_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state,
/* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, /* 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_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_SET_MATERIAL */ wined3d_cs_exec_set_material,
/* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, /* 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 * WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture
* function will call alpha in case it finds some texture + colorkeyenable * function will call alpha in case it finds some texture + colorkeyenable
* combination which needs extra care. */ * 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; enable_ckey = TRUE;
if (enable_ckey || context->last_was_ckey) 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_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 /* 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 * 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. */ * other cases pixels that should be masked away have alpha set to 0. */
if (src_surface->resource.format->id == WINED3DFMT_P8_UINT) if (src_surface->resource.format->id == WINED3DFMT_P8_UINT)
gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, 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 else
gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, 0.0f); gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, 0.0f);
checkGLcall("glAlphaFunc"); checkGLcall("glAlphaFunc");
@ -3586,8 +3586,8 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
else if (src_surface) else if (src_surface)
{ {
/* Blit from offscreen surface to render target */ /* Blit from offscreen surface to render target */
struct wined3d_color_key old_blt_key = src_surface->container->src_blt_color_key; struct wined3d_color_key old_blt_key = src_surface->container->async.src_blt_color_key;
DWORD old_color_key_flags = src_surface->container->color_key_flags; 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); 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) if (texture->swapchain && texture->swapchain->palette)
palette = texture->swapchain->palette; palette = texture->swapchain->palette;
conversion->convert(data.addr, src_pitch, mem, dst_pitch, 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; src_pitch = dst_pitch;
data.addr = mem; data.addr = mem;
} }
@ -4830,8 +4830,8 @@ do { \
/* The color keying flags are checked for correctness in ddraw */ /* The color keying flags are checked for correctness in ddraw */
if (flags & WINEDDBLT_KEYSRC) if (flags & WINEDDBLT_KEYSRC)
{ {
keylow = src_surface->container->src_blt_color_key.color_space_low_value; keylow = src_surface->container->async.src_blt_color_key.color_space_low_value;
keyhigh = src_surface->container->src_blt_color_key.color_space_high_value; keyhigh = src_surface->container->async.src_blt_color_key.color_space_high_value;
} }
else if (flags & WINEDDBLT_KEYSRCOVERRIDE) else if (flags & WINEDDBLT_KEYSRCOVERRIDE)
{ {
@ -4842,8 +4842,8 @@ do { \
if (flags & WINEDDBLT_KEYDEST) if (flags & WINEDDBLT_KEYDEST)
{ {
/* Destination color keys are taken from the source surface! */ /* Destination color keys are taken from the source surface! */
destkeylow = src_surface->container->dst_blt_color_key.color_space_low_value; destkeylow = src_surface->container->async.dst_blt_color_key.color_space_low_value;
destkeyhigh = src_surface->container->dst_blt_color_key.color_space_high_value; destkeyhigh = src_surface->container->async.dst_blt_color_key.color_space_high_value;
} }
else if (flags & WINEDDBLT_KEYDESTOVERRIDE) 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; 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 */ /* Context activation is done by the caller */
void wined3d_texture_load(struct wined3d_texture *texture, void wined3d_texture_load(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) struct wined3d_context *context, BOOL srgb)
@ -456,10 +462,10 @@ void wined3d_texture_load(struct wined3d_texture *texture,
else else
flag = WINED3D_TEXTURE_RGB_VALID; flag = WINED3D_TEXTURE_RGB_VALID;
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->flags & WINED3D_TEXTURE_COLOR_KEY != !(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
&& (texture->gl_color_key.color_space_low_value != texture->src_blt_color_key.color_space_low_value || (texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY
|| texture->gl_color_key.color_space_high_value != texture->src_blt_color_key.color_space_high_value))) && !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 sub_count = texture->level_count * texture->layer_count;
unsigned int i; 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); texture->texture_ops->texture_sub_resource_add_dirty_region(texture->sub_resources[i], NULL);
wined3d_texture_set_dirty(texture); 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) 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, HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
DWORD flags, const struct wined3d_color_key *color_key) 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); 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) if (flags & WINED3D_CKEY_COLORSPACE)
{ {
FIXME("Unhandled flags %#x.\n", flags); FIXME("Unhandled flags %#x.\n", flags);
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
if (color_key) wined3d_cs_emit_set_color_key(device->cs, texture, flags, 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;
}
}
return WINED3D_OK; 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; 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); wined3d_texture_force_reload(texture);
if (texture->flags & alloc_flag) if (texture->flags & alloc_flag)
return; return;
if (texture->color_key_flags & WINED3D_CKEY_SRC_BLT) if (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
texture->flags |= WINED3D_TEXTURE_COLOR_KEY; texture->async.flags |= WINED3D_TEXTURE_ASYNC_COLOR_KEY;
texture->texture_ops->texture_prepare_texture(texture, context, srgb); texture->texture_ops->texture_prepare_texture(texture, context, srgb);
texture->flags |= alloc_flag; texture->flags |= alloc_flag;
@ -713,7 +685,8 @@ void wined3d_texture_force_reload(struct wined3d_texture *texture)
unsigned int i; unsigned int i;
texture->flags &= ~(WINED3D_TEXTURE_RGB_ALLOCATED | WINED3D_TEXTURE_SRGB_ALLOCATED 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) for (i = 0; i < sub_count; ++i)
{ {
texture->texture_ops->texture_sub_resource_invalidate_location(texture->sub_resources[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 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) 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_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) if (aop == WINED3D_TOP_DISABLE)
{ {

View File

@ -2187,7 +2187,8 @@ struct wined3d_texture_ops
#define WINED3D_TEXTURE_PIN_SYSMEM 0x00000100 #define WINED3D_TEXTURE_PIN_SYSMEM 0x00000100
#define WINED3D_TEXTURE_DYNAMIC_MAP 0x00000200 #define WINED3D_TEXTURE_DYNAMIC_MAP 0x00000200
#define WINED3D_TEXTURE_NORMALIZED_COORDS 0x00000400 #define WINED3D_TEXTURE_NORMALIZED_COORDS 0x00000400
#define WINED3D_TEXTURE_COLOR_KEY 0x00000800
#define WINED3D_TEXTURE_ASYNC_COLOR_KEY 0x00000001
struct wined3d_texture struct wined3d_texture
{ {
@ -2205,13 +2206,19 @@ struct wined3d_texture
DWORD flags; DWORD flags;
GLenum target; GLenum target;
/* Color keys for DDraw */ /* May only be accessed from the command stream worker thread. */
struct wined3d_color_key dst_blt_color_key; struct wined3d_texture_async
struct wined3d_color_key src_blt_color_key; {
struct wined3d_color_key dst_overlay_color_key; DWORD flags;
struct wined3d_color_key src_overlay_color_key;
struct wined3d_color_key gl_color_key; /* Color keys for DDraw */
DWORD color_key_flags; 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) 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_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx, void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx,
const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN; 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, 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; UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs,