=?UTF-8?Q?Stefan=20D=C3=B6singer=20?=: wined3d: Manage color key changes in the texture.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Feb 18 09:57:19 CST 2015


Module: wine
Branch: master
Commit: e53d22b0c002bbea2dfa3fc40d9587ee8b905018
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e53d22b0c002bbea2dfa3fc40d9587ee8b905018

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Feb 17 23:09:36 2015 +0100

wined3d: Manage color key changes in the texture.

This fixes a regression with color keyed mipmaps that was introduced by
ee8a5b7dd1e554ef32229c766715f23ba17c9f6c. surface_load for level n+1
would call texture_force_reload, thus removing level n from the GL
texture.

---

 dlls/wined3d/surface.c         | 36 ++----------------------------------
 dlls/wined3d/texture.c         | 25 ++++++++++++++++++++++++-
 dlls/wined3d/wined3d_private.h |  9 ++++-----
 3 files changed, 30 insertions(+), 40 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 8f60769..06d8433 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1814,43 +1814,18 @@ GLenum surface_get_gl_buffer(const struct wined3d_surface *surface)
 void surface_load(struct wined3d_surface *surface, BOOL srgb)
 {
     DWORD location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB;
-    BOOL ck_changed;
 
     TRACE("surface %p, srgb %#x.\n", surface, srgb);
 
     if (surface->resource.pool == WINED3D_POOL_SCRATCH)
         ERR("Not supported on scratch surfaces.\n");
 
-    ck_changed = !(surface->flags & SFLAG_GLCKEY) != !(surface->container->color_key_flags & WINED3D_CKEY_SRC_BLT);
-
-    /* Reload if either the texture and sysmem have different ideas about the
-     * color key, or the actual key values changed. */
-    if (ck_changed || ((surface->container->color_key_flags & WINED3D_CKEY_SRC_BLT)
-            && (surface->gl_color_key.color_space_low_value
-            != surface->container->src_blt_color_key.color_space_low_value
-            || surface->gl_color_key.color_space_high_value
-            != surface->container->src_blt_color_key.color_space_high_value)))
-    {
-        TRACE("Reloading because of color keying\n");
-        /* To perform the color key conversion we need a sysmem copy of
-         * the surface. Make sure we have it. */
-
-        surface_prepare_map_memory(surface);
-        surface_load_location(surface, surface->resource.map_binding);
-        surface_invalidate_location(surface, ~surface->resource.map_binding);
-        /* Switching color keying on / off may change the internal format. */
-        if (ck_changed)
-            wined3d_texture_force_reload(surface->container);
-    }
-    else if (!(surface->locations & location))
-    {
-        TRACE("Reloading because surface is dirty.\n");
-    }
-    else
+    if (surface->locations & location)
     {
         TRACE("surface is already in texture\n");
         return;
     }
+    TRACE("Reloading because surface is dirty.\n");
 
     surface_load_location(surface, location);
     surface_evict_sysmem(surface);
@@ -4179,13 +4154,6 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
     wined3d_texture_prepare_texture(texture, context, srgb);
     wined3d_texture_bind_and_dirtify(texture, context, srgb);
 
-    if (texture->color_key_flags & WINED3D_CKEY_SRC_BLT)
-    {
-        surface->flags |= SFLAG_GLCKEY;
-        surface->gl_color_key = texture->src_blt_color_key;
-    }
-    else surface->flags &= ~SFLAG_GLCKEY;
-
     width = surface->resource.width;
     src_pitch = wined3d_surface_get_pitch(surface);
 
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 57c8ef7..675ca9e 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -456,6 +456,22 @@ 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)))
+    {
+        unsigned int sub_count = texture->level_count * texture->layer_count;
+        unsigned int i;
+
+        TRACE("Reloading because of color key value change.\n");
+        for (i = 0; i < sub_count; i++)
+            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;
+    }
+
     if (texture->flags & flag)
     {
         TRACE("Texture %p not dirty, nothing to do.\n", texture);
@@ -665,9 +681,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))
+        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;
+
     texture->texture_ops->texture_prepare_texture(texture, context, srgb);
     texture->flags |= alloc_flag;
 }
@@ -677,7 +699,8 @@ void wined3d_texture_force_reload(struct wined3d_texture *texture)
     unsigned int sub_count = texture->level_count * texture->layer_count;
     unsigned int i;
 
-    texture->flags &= ~(WINED3D_TEXTURE_RGB_ALLOCATED | WINED3D_TEXTURE_SRGB_ALLOCATED | WINED3D_TEXTURE_CONVERTED);
+    texture->flags &= ~(WINED3D_TEXTURE_RGB_ALLOCATED | WINED3D_TEXTURE_SRGB_ALLOCATED
+            | WINED3D_TEXTURE_CONVERTED | WINED3D_TEXTURE_COLOR_KEY);
     for (i = 0; i < sub_count; ++i)
     {
         texture->texture_ops->texture_sub_resource_invalidate_location(texture->sub_resources[i],
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d924271..b0c7a53 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2181,6 +2181,7 @@ 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
 
 struct wined3d_texture
 {
@@ -2203,6 +2204,7 @@ struct wined3d_texture
     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;
 };
 
@@ -2336,8 +2338,6 @@ struct wined3d_surface
     struct wined3d_surface_dib dib;
     HDC                       hDC;
 
-    struct wined3d_color_key gl_color_key;
-
     struct list               renderbuffers;
     const struct wined3d_renderbuffer_entry *current_renderbuffer;
     SIZE ds_current_size;
@@ -2404,9 +2404,8 @@ void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) D
 #define SFLAG_DISCARD           0x00000002 /* ??? */
 #define SFLAG_NONPOW2           0x00000004 /* Surface sizes are not a power of 2 */
 #define SFLAG_LOST              0x00000008 /* Surface lost flag for ddraw. */
-#define SFLAG_GLCKEY            0x00000010 /* The GL texture was created with a color key. */
-#define SFLAG_CLIENT            0x00000020 /* GL_APPLE_client_storage is used with this surface. */
-#define SFLAG_DCINUSE           0x00000040 /* Set between GetDC and ReleaseDC calls. */
+#define SFLAG_CLIENT            0x00000010 /* GL_APPLE_client_storage is used with this surface. */
+#define SFLAG_DCINUSE           0x00000020 /* Set between GetDC and ReleaseDC calls. */
 
 struct wined3d_sampler
 {




More information about the wine-cvs mailing list