[4/10] WineD3D: Fix d3d8/9 style palettes

Stefan Dösinger stefan at codeweavers.com
Mon Feb 19 08:23:36 CST 2007


This patch is untested because I do not have any of the applications that have 
issues now since D3DFMT_P8 is enabled.

The ddraw and d3d8/9 style palette management are a bit different. None can be 
mapped to the other in ddraw / d3d8 / d3d9 efficiently, so wined3d has to 
support both. If no ddraw palette is attached the surface uses the d3d9 
palette from the device. This patch keeps track of palette changes to reload 
the surface.
-------------- next part --------------
From db662d986e1a23531c0fe1f69f610142ac9e236b Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Sun, 18 Feb 2007 19:01:08 +0100
Subject: [PATCH] WineD3D: Fix d3d8/9 style palettes

---
 dlls/wined3d/surface.c         |   25 +++++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h |    3 ++-
 2 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index b090366..562adcd 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -297,6 +297,8 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {
         }
         if(This->Flags & SFLAG_USERPTR) IWineD3DSurface_SetMem(iface, NULL);
 
+        HeapFree(GetProcessHeap(), 0, This->palette9);
+
         IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);
         if(iface == device->ddraw_primary)
             device->ddraw_primary = NULL;
@@ -1649,6 +1651,27 @@ void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES convert) {
     GL_EXTCALL(glColorTableEXT(GL_TEXTURE_2D,GL_RGBA,256,GL_RGBA,GL_UNSIGNED_BYTE, table));
 }
 
+static BOOL palette9_changed(IWineD3DSurfaceImpl *This) {
+    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+
+    if(This->palette || (This->resource.format != WINED3DFMT_P8 && This->resource.format != WINED3DFMT_A8P8)) {
+        /* If a ddraw-style palette is attached assume no d3d9 palette change.
+         * Also the palette isn't interesting if the surface format isn't P8 or A8P8
+         */
+        return FALSE;
+    }
+
+    if(This->palette9) {
+        if(memcmp(This->palette9, &device->palettes[device->currentPalette], sizeof(PALETTEENTRY) * 256) == 0) {
+            return FALSE;
+        }
+    } else {
+        This->palette9 = (PALETTEENTRY *) HeapAlloc(GetProcessHeap(), 0, sizeof(PALETTEENTRY) * 256);
+    }
+    memcpy(This->palette9, &device->palettes[device->currentPalette], sizeof(PALETTEENTRY) * 256);
+    return TRUE;
+}
+
 static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
     IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
     GLenum format, internal, type;
@@ -1672,6 +1695,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
                 (This->glCKey.dwColorSpaceLowValue != This->SrcBltCKey.dwColorSpaceLowValue) ||
                 (This->glCKey.dwColorSpaceHighValue != This->SrcBltCKey.dwColorSpaceHighValue)))) {
         TRACE("Reloading because of color keying\n");
+    } else if(palette9_changed(This)) {
+        TRACE("Reloading surface because the d3d8/9 palette was changed\n");
     } else {
         TRACE("surface isn't dirty\n");
         return WINED3D_OK;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9454a38..7fea727 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -973,7 +973,8 @@ struct IWineD3DSurfaceImpl
     /* IWineD3DSurface fields */
     IWineD3DBase              *container;
     WINED3DSURFACET_DESC      currentDesc;
-    IWineD3DPaletteImpl      *palette;
+    IWineD3DPaletteImpl       *palette; /* D3D7 style palette handling */
+    PALETTEENTRY              *palette9; /* D3D8/9 style palette handling */
 
     UINT                      bytesPerPixel;
 
-- 
1.4.4.3



More information about the wine-patches mailing list