[PATCH 4/5] wined3d: Store palettes in textures instead of in surfaces.

Stefan Dösinger stefan at codeweavers.com
Thu Apr 24 05:10:14 CDT 2014


Since palettes only really matter on frontbuffers we could also consider
removing them from wined3d entirely and performing the ddraw frontbuffer
present with a d3d draw and d3d shaders. This would mean that the shadow
frontbuffer remains in ddraw, and that Shader Model 2 cards are required
for hardware P8 conversion. (Unless we implement full d3d shader support
for older HW, which I consider unlikely.)
---
 dlls/ddraw/ddraw.c             |  4 ++-
 dlls/ddraw/ddraw_private.h     |  1 +
 dlls/ddraw/device.c            |  2 +-
 dlls/ddraw/surface.c           | 16 ++++++------
 dlls/wined3d/palette.c         | 10 +++++---
 dlls/wined3d/surface.c         | 55 ++++++++++++++----------------------------
 dlls/wined3d/texture.c         | 37 ++++++++++++++++++++++++++++
 dlls/wined3d/utils.c           |  9 ++++---
 dlls/wined3d/wined3d.spec      |  3 +--
 dlls/wined3d/wined3d_private.h |  5 +++-
 include/wine/wined3d.h         |  3 +--
 11 files changed, 85 insertions(+), 60 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index aa74a1e..3a43618 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -364,6 +364,8 @@ void ddraw_destroy_swapchain(struct ddraw *ddraw)
 {
     TRACE("Destroying the swapchain.\n");
 
+    wined3d_texture_decref(ddraw->wined3d_frontbuffer_texture);
+    ddraw->wined3d_frontbuffer_texture = NULL;
     wined3d_swapchain_decref(ddraw->wined3d_swapchain);
     ddraw->wined3d_swapchain = NULL;
 
@@ -4815,8 +4817,8 @@ static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_devic
 
     *surface = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(texture, 0));
     ddraw->wined3d_frontbuffer = *surface;
+    ddraw->wined3d_frontbuffer_texture = texture;
     wined3d_surface_incref(*surface);
-    wined3d_texture_decref(texture);
 
     return hr;
 }
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 2bf8132..e9a46db 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -80,6 +80,7 @@ struct ddraw
 
     struct ddraw_surface *primary;
     RECT primary_lock;
+    struct wined3d_texture *wined3d_frontbuffer_texture;
     struct wined3d_surface *wined3d_frontbuffer;
     struct wined3d_swapchain *wined3d_swapchain;
     HWND swapchain_window;
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index e6f40a0..31655ec 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -1802,7 +1802,7 @@ static BOOL validate_surface_palette(struct ddraw_surface *surface)
             & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2
             | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8
             | DDPF_PALETTEINDEXEDTO8))
-            || wined3d_surface_get_palette(surface->wined3d_surface);
+            || surface->palette;
 }
 
 static HRESULT d3d_device_set_render_target(struct d3d_device *device,
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index b561af4..a3a13f0 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -469,7 +469,7 @@ static HRESULT WINAPI ddraw_surface_set_palette(struct ddraw_surface *surface, I
             palette_impl->flags |= DDPCAPS_PRIMARYSURFACE;
         /* Update the wined3d frontbuffer if this is the primary. */
         if (surface->ddraw->wined3d_frontbuffer)
-            wined3d_surface_set_palette(surface->ddraw->wined3d_frontbuffer,
+            wined3d_texture_set_palette(surface->ddraw->wined3d_frontbuffer_texture,
                     palette_impl ? palette_impl->wineD3DPalette : NULL);
     }
     if (palette_impl)
@@ -477,7 +477,8 @@ static HRESULT WINAPI ddraw_surface_set_palette(struct ddraw_surface *surface, I
     if (prev)
         IDirectDrawPalette_Release(&prev->IDirectDrawPalette_iface);
     surface->palette = palette_impl;
-    wined3d_surface_set_palette(surface->wined3d_surface, palette_impl ? palette_impl->wineD3DPalette : NULL);
+    if (surface->wined3d_texture)
+        wined3d_texture_set_palette(surface->wined3d_texture, palette_impl ? palette_impl->wineD3DPalette : NULL);
 
     wined3d_mutex_unlock();
 
@@ -4975,7 +4976,6 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
 
     for (;;)
     {
-        struct wined3d_palette *wined3d_dst_pal, *wined3d_src_pal;
         DDSURFACEDESC *src_desc, *dst_desc;
 
         TRACE("Copying surface %p to surface %p (mipmap level %d).\n",
@@ -4984,19 +4984,19 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
         /* Suppress the ALLOCONLOAD flag */
         dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
 
-        /* Get the palettes */
-        wined3d_dst_pal = wined3d_surface_get_palette(dst_surface->wined3d_surface);
-        wined3d_src_pal = wined3d_surface_get_palette(src_surface->wined3d_surface);
 
-        if (wined3d_src_pal)
+        if (src_surface->palette)
         {
+            struct wined3d_palette *wined3d_dst_pal, *wined3d_src_pal;
             PALETTEENTRY palent[256];
 
-            if (!wined3d_dst_pal)
+            if (!dst_surface->palette)
             {
                 wined3d_mutex_unlock();
                 return DDERR_NOPALETTEATTACHED;
             }
+            wined3d_src_pal = src_surface->palette->wineD3DPalette;
+            wined3d_dst_pal = dst_surface->palette->wineD3DPalette;
             wined3d_palette_get_entries(wined3d_src_pal, 0, 0, 256, palent);
             wined3d_palette_set_entries(wined3d_dst_pal, 0, 0, 256, palent);
         }
diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c
index e659952..28fc650 100644
--- a/dlls/wined3d/palette.c
+++ b/dlls/wined3d/palette.c
@@ -119,11 +119,13 @@ HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette,
     /* If the palette is attached to the render target, update all render targets */
     LIST_FOR_EACH_ENTRY(resource, &palette->device->resources, struct wined3d_resource, resource_list_entry)
     {
-        if (resource->type == WINED3D_RTYPE_SURFACE)
+        enum wined3d_resource_type type = resource->type;
+        if (type == WINED3D_RTYPE_TEXTURE || type == WINED3D_RTYPE_CUBE_TEXTURE
+                || type == WINED3D_RTYPE_VOLUME_TEXTURE)
         {
-            struct wined3d_surface *surface = surface_from_resource(resource);
-            if (surface->palette == palette)
-                surface->surface_ops->surface_realize_palette(surface);
+            struct wined3d_texture *texture = wined3d_texture_from_resource(resource);
+            if (texture->palette == palette)
+                wined3d_texture_realize_palette(texture);
         }
     }
 
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 680a815..657bb16 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -391,6 +391,7 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface)
     BITMAPINFO *b_info;
     int extraline = 0;
     DWORD *masks;
+    const struct wined3d_palette *palette = surface->container->palette;
 
     TRACE("surface %p.\n", surface);
 
@@ -498,8 +499,8 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface)
     /* Now allocate a DC. */
     surface->hDC = CreateCompatibleDC(0);
     SelectObject(surface->hDC, surface->dib.DIBsection);
-    TRACE("Using wined3d palette %p.\n", surface->palette);
-    SelectPalette(surface->hDC, surface->palette ? surface->palette->hpal : 0, FALSE);
+    TRACE("Using wined3d palette %p.\n", palette);
+    SelectPalette(surface->hDC, palette ? palette->hpal : 0, FALSE);
 
     surface->flags |= SFLAG_DIBSECTION;
 
@@ -757,7 +758,7 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface)
 
 static void surface_realize_palette(struct wined3d_surface *surface)
 {
-    struct wined3d_palette *palette = surface->palette;
+    struct wined3d_palette *palette = surface->container->palette;
 
     TRACE("surface %p.\n", surface);
 
@@ -1117,15 +1118,17 @@ static BOOL surface_convert_color_to_float(const struct wined3d_surface *surface
 {
     const struct wined3d_format *format = surface->resource.format;
     const struct wined3d_device *device = surface->resource.device;
+    struct wined3d_palette *palette;
 
     switch (format->id)
     {
         case WINED3DFMT_P8_UINT:
-            if (surface->palette)
+            palette = surface->container->palette;
+            if (palette)
             {
-                float_color->r = surface->palette->palents[color].peRed / 255.0f;
-                float_color->g = surface->palette->palents[color].peGreen / 255.0f;
-                float_color->b = surface->palette->palents[color].peBlue / 255.0f;
+                float_color->r = palette->palents[color].peRed / 255.0f;
+                float_color->g = palette->palents[color].peGreen / 255.0f;
+                float_color->b = palette->palents[color].peBlue / 255.0f;
             }
             else
             {
@@ -1386,7 +1389,7 @@ static HRESULT gdi_surface_private_setup(struct wined3d_surface *surface)
 
 static void gdi_surface_realize_palette(struct wined3d_surface *surface)
 {
-    struct wined3d_palette *palette = surface->palette;
+    struct wined3d_palette *palette = surface->container->palette;
 
     TRACE("surface %p.\n", surface);
 
@@ -2389,28 +2392,6 @@ HRESULT CDECL wined3d_surface_restore(struct wined3d_surface *surface)
     return WINED3D_OK;
 }
 
-void CDECL wined3d_surface_set_palette(struct wined3d_surface *surface, struct wined3d_palette *palette)
-{
-    TRACE("surface %p, palette %p.\n", surface, palette);
-
-    if (surface->palette == palette)
-    {
-        TRACE("Nop palette change.\n");
-        return;
-    }
-
-    surface->palette = palette;
-    if (palette)
-        surface->surface_ops->surface_realize_palette(surface);
-}
-
-struct wined3d_palette * CDECL wined3d_surface_get_palette(const struct wined3d_surface *surface)
-{
-    TRACE("surface %p.\n", surface);
-
-    return surface->palette;
-}
-
 DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface)
 {
     unsigned int alignment;
@@ -3180,17 +3161,17 @@ HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc)
          * surfaces (with non-device palettes). */
         const PALETTEENTRY *pal = NULL;
 
-        if (surface->palette)
+        if (surface->container->palette)
         {
-            pal = surface->palette->palents;
+            pal = surface->container->palette->palents;
         }
         else
         {
             struct wined3d_swapchain *swapchain = surface->resource.device->swapchains[0];
             struct wined3d_surface *dds_primary = swapchain->front_buffer;
 
-            if (dds_primary && dds_primary->palette)
-                pal = dds_primary->palette->palents;
+            if (dds_primary && dds_primary->container->palette)
+                pal = dds_primary->container->palette->palents;
         }
 
         if (pal)
@@ -3411,9 +3392,9 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc
         DWORD width = pitch / 3;
         int x, y, c;
 
-        if (surface->palette)
+        if (surface->container->palette)
         {
-            pal = surface->palette->palents;
+            pal = surface->container->palette->palents;
         }
         else
         {
@@ -3553,7 +3534,7 @@ static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD colo
 void d3dfmt_p8_init_palette(const struct wined3d_surface *surface, BYTE table[256][4], BOOL colorkey)
 {
     const struct wined3d_device *device = surface->resource.device;
-    const struct wined3d_palette *pal = surface->palette;
+    const struct wined3d_palette *pal = surface->container->palette;
     BOOL index_in_alpha = FALSE;
     unsigned int i;
 
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 4291fd0..b9e571e 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -684,6 +684,30 @@ HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture,
     return WINED3D_OK;
 }
 
+void wined3d_texture_realize_palette(struct wined3d_texture *texture)
+{
+    UINT i, sub_count = texture->level_count * texture->layer_count;
+
+    for (i = 0; i < sub_count; ++i)
+        texture->texture_ops->texture_realize_palette(texture->sub_resources[i]);
+}
+
+void CDECL wined3d_texture_set_palette(struct wined3d_texture *texture,
+        struct wined3d_palette *palette)
+{
+    TRACE("texture %p, palette %p.\n", texture, palette);
+
+    if (texture->palette == palette)
+    {
+        TRACE("Nop palette change.\n");
+        return;
+    }
+
+    texture->palette = palette;
+    if (palette)
+        wined3d_texture_realize_palette(texture);
+}
+
 void CDECL wined3d_texture_generate_mipmaps(struct wined3d_texture *texture)
 {
     /* TODO: Implement filters using GL_SGI_generate_mipmaps. */
@@ -748,11 +772,18 @@ static void texture2d_sub_resource_cleanup(struct wined3d_resource *sub_resource
     wined3d_surface_decref(surface);
 }
 
+static void texture2d_sub_resource_realize_palette(struct wined3d_resource *sub_resource)
+{
+    struct wined3d_surface *surface = surface_from_resource(sub_resource);
+    surface->surface_ops->surface_realize_palette(surface);
+}
+
 static const struct wined3d_texture_ops texture2d_ops =
 {
     texture2d_sub_resource_load,
     texture2d_sub_resource_add_dirty_region,
     texture2d_sub_resource_cleanup,
+    texture2d_sub_resource_realize_palette,
 };
 
 static void wined3d_texture_unload(struct wined3d_resource *resource)
@@ -1071,11 +1102,17 @@ static void texture3d_sub_resource_cleanup(struct wined3d_resource *sub_resource
     wined3d_volume_decref(volume);
 }
 
+static void texture3d_sub_resource_realize_palette(struct wined3d_resource *sub_resource)
+{
+    FIXME("Palettized volumes are not implemented.\n");
+}
+
 static const struct wined3d_texture_ops texture3d_ops =
 {
     texture3d_sub_resource_load,
     texture3d_sub_resource_add_dirty_region,
     texture3d_sub_resource_cleanup,
+    texture3d_sub_resource_realize_palette,
 };
 
 static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 78060e2..dee84aa 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -3089,10 +3089,11 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, c
 
     if (format->id == WINED3DFMT_P8_UINT)
     {
-        PALETTEENTRY *e;
+        const PALETTEENTRY *e;
         BYTE r, g, b, a;
+        const struct wined3d_palette *palette = surface->container->palette;
 
-        if (!surface->palette)
+        if (!palette)
         {
             WARN("Surface doesn't have a palette, returning 0.\n");
             return 0;
@@ -3103,7 +3104,7 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, c
         b = (BYTE)((color->b * 255.0f) + 0.5f);
         a = (BYTE)((color->a * 255.0f) + 0.5f);
 
-        e = &surface->palette->palents[a];
+        e = &palette->palents[a];
         if (e->peRed == r && e->peGreen == g && e->peBlue == b)
             return a;
 
@@ -3111,7 +3112,7 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, c
 
         for (i = 0; i < 256; ++i)
         {
-            e = &surface->palette->palents[i];
+            e = &palette->palents[i];
             if (e->peRed == r && e->peGreen == g && e->peBlue == b)
                 return i;
         }
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 99cf6bf..e01c3b1 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -207,7 +207,6 @@
 @ cdecl wined3d_surface_get_blt_status(ptr long)
 @ cdecl wined3d_surface_get_flip_status(ptr long)
 @ cdecl wined3d_surface_get_overlay_position(ptr ptr ptr)
-@ cdecl wined3d_surface_get_palette(ptr)
 @ cdecl wined3d_surface_get_parent(ptr)
 @ cdecl wined3d_surface_get_pitch(ptr)
 @ cdecl wined3d_surface_get_priority(ptr)
@@ -221,7 +220,6 @@
 @ cdecl wined3d_surface_releasedc(ptr ptr)
 @ cdecl wined3d_surface_restore(ptr)
 @ cdecl wined3d_surface_set_overlay_position(ptr long long)
-@ cdecl wined3d_surface_set_palette(ptr ptr)
 @ cdecl wined3d_surface_set_priority(ptr long)
 @ cdecl wined3d_surface_unmap(ptr)
 @ cdecl wined3d_surface_update_desc(ptr long long long long long ptr long)
@@ -258,6 +256,7 @@
 @ cdecl wined3d_texture_preload(ptr)
 @ cdecl wined3d_texture_set_autogen_filter_type(ptr long)
 @ cdecl wined3d_texture_set_color_key(ptr long ptr)
+@ cdecl wined3d_texture_set_palette(ptr ptr)
 @ cdecl wined3d_texture_set_lod(ptr long)
 @ cdecl wined3d_texture_set_priority(ptr long)
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7e67f1e..25b9ac4 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2083,6 +2083,7 @@ struct wined3d_texture_ops
     void (*texture_sub_resource_add_dirty_region)(struct wined3d_resource *sub_resource,
             const struct wined3d_box *dirty_region);
     void (*texture_sub_resource_cleanup)(struct wined3d_resource *sub_resource);
+    void (*texture_realize_palette)(struct wined3d_resource *sub_resource);
 };
 
 #define WINED3D_TEXTURE_COND_NP2            0x00000001
@@ -2114,6 +2115,8 @@ struct wined3d_texture
     struct wined3d_color_key dst_overlay_color_key;
     struct wined3d_color_key src_overlay_color_key;
     DWORD color_key_flags;
+
+    struct wined3d_palette *palette;
 };
 
 static inline struct wined3d_texture *wined3d_texture_from_resource(struct wined3d_resource *resource)
@@ -2136,6 +2139,7 @@ void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture,
         struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
 void wined3d_texture_load(struct wined3d_texture *texture,
         struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
+void wined3d_texture_realize_palette(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
 void wined3d_texture_set_dirty(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
 
 #define WINED3D_VFLAG_ALLOCATED         0x00000001
@@ -2220,7 +2224,6 @@ struct wined3d_surface
     const struct wined3d_surface_ops *surface_ops;
     struct wined3d_texture *container;
     struct wined3d_swapchain *swapchain;
-    struct wined3d_palette *palette; /* D3D7 style palette handling */
     DWORD draw_binding, map_binding;
     void *user_memory;
     DWORD locations;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 56bedce..806a2c8 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2397,7 +2397,6 @@ struct wined3d_surface * __cdecl wined3d_surface_from_resource(struct wined3d_re
 HRESULT __cdecl wined3d_surface_get_blt_status(const struct wined3d_surface *surface, DWORD flags);
 HRESULT __cdecl wined3d_surface_get_flip_status(const struct wined3d_surface *surface, DWORD flags);
 HRESULT __cdecl wined3d_surface_get_overlay_position(const struct wined3d_surface *surface, LONG *x, LONG *y);
-struct wined3d_palette * __cdecl wined3d_surface_get_palette(const struct wined3d_surface *surface);
 void * __cdecl wined3d_surface_get_parent(const struct wined3d_surface *surface);
 DWORD __cdecl wined3d_surface_get_pitch(const struct wined3d_surface *surface);
 DWORD __cdecl wined3d_surface_get_priority(const struct wined3d_surface *surface);
@@ -2413,7 +2412,6 @@ void __cdecl wined3d_surface_preload(struct wined3d_surface *surface);
 HRESULT __cdecl wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc);
 HRESULT __cdecl wined3d_surface_restore(struct wined3d_surface *surface);
 HRESULT __cdecl wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y);
-void __cdecl wined3d_surface_set_palette(struct wined3d_surface *surface, struct wined3d_palette *palette);
 DWORD __cdecl wined3d_surface_set_priority(struct wined3d_surface *surface, DWORD new_priority);
 HRESULT __cdecl wined3d_surface_unmap(struct wined3d_surface *surface);
 HRESULT __cdecl wined3d_surface_update_desc(struct wined3d_surface *surface,
@@ -2472,6 +2470,7 @@ HRESULT __cdecl wined3d_texture_set_autogen_filter_type(struct wined3d_texture *
 HRESULT __cdecl wined3d_texture_set_color_key(struct wined3d_texture *texture,
         DWORD flags, const struct wined3d_color_key *color_key);
 DWORD __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod);
+void __cdecl wined3d_texture_set_palette(struct wined3d_texture *texture, struct wined3d_palette *palette);
 DWORD __cdecl wined3d_texture_set_priority(struct wined3d_texture *texture, DWORD priority);
 
 HRESULT __cdecl wined3d_vertex_declaration_create(struct wined3d_device *device,
-- 
1.8.3.2




More information about the wine-patches mailing list