[PATCH 7/8] ddraw: Add a separate function for surface initialization.

Henri Verbeet hverbeet at codeweavers.com
Thu Aug 19 11:57:49 CDT 2010


---
 dlls/ddraw/ddraw.c         |  185 ++------------------------------------------
 dlls/ddraw/ddraw_private.h |    9 +--
 dlls/ddraw/surface.c       |  167 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 171 insertions(+), 190 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 83d271b..032b15c 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -2487,13 +2487,8 @@ ULONG WINAPI D3D7CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
 static HRESULT ddraw_create_surface(IDirectDrawImpl *This, DDSURFACEDESC2 *pDDSD,
         IDirectDrawSurfaceImpl **ppSurf, UINT level)
 {
-    HRESULT hr;
-    UINT Width, Height;
-    WINED3DFORMAT Format = WINED3DFMT_UNKNOWN;
-    DWORD Usage = 0;
     WINED3DSURFTYPE ImplType = This->ImplType;
-    WINED3DSURFACE_DESC Desc;
-    WINED3DPOOL Pool = WINED3DPOOL_DEFAULT;
+    HRESULT hr;
 
     if (TRACE_ON(ddraw))
     {
@@ -2556,57 +2551,6 @@ static HRESULT ddraw_create_surface(IDirectDrawImpl *This, DDSURFACEDESC2 *pDDSD
         }
     }
 
-    if (!(pDDSD->ddsCaps.dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY)) &&
-        !((pDDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE) && (pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)) )
-    {
-        /* Tests show surfaces without memory flags get these flags added right after creation. */
-        pDDSD->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
-    }
-    /* Get the correct wined3d usage */
-    if (pDDSD->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE |
-                                 DDSCAPS_3DDEVICE       ) )
-    {
-        Usage |= WINED3DUSAGE_RENDERTARGET;
-
-        pDDSD->ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
-    }
-    if (pDDSD->ddsCaps.dwCaps & (DDSCAPS_OVERLAY))
-    {
-        Usage |= WINED3DUSAGE_OVERLAY;
-    }
-    if(This->depthstencil || (pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) )
-    {
-        /* The depth stencil creation callback sets this flag.
-         * Set the WineD3D usage to let it know that it's a depth
-         * Stencil surface.
-         */
-        Usage |= WINED3DUSAGE_DEPTHSTENCIL;
-    }
-    if(pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
-    {
-        Pool = WINED3DPOOL_SYSTEMMEM;
-    }
-    else if(pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
-    {
-        Pool = WINED3DPOOL_MANAGED;
-        /* Managed textures have the system memory flag set */
-        pDDSD->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
-    }
-    else if(pDDSD->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
-    {
-        /* Videomemory adds localvidmem, this is mutually exclusive with systemmemory
-         * and texturemanage
-         */
-        pDDSD->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM;
-    }
-
-    Format = PixelFormat_DD2WineD3D(&pDDSD->u4.ddpfPixelFormat);
-    if(Format == WINED3DFMT_UNKNOWN)
-    {
-        ERR("Unsupported / Unknown pixelformat\n");
-        return DDERR_INVALIDPIXELFORMAT;
-    }
-
     /* Create the Surface object */
     *ppSurf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl));
     if(!*ppSurf)
@@ -2614,41 +2558,12 @@ static HRESULT ddraw_create_surface(IDirectDrawImpl *This, DDSURFACEDESC2 *pDDSD
         ERR("(%p) Error allocating memory for a surface\n", This);
         return DDERR_OUTOFVIDEOMEMORY;
     }
-    (*ppSurf)->lpVtbl = &IDirectDrawSurface7_Vtbl;
-    (*ppSurf)->IDirectDrawSurface3_vtbl = &IDirectDrawSurface3_Vtbl;
-    (*ppSurf)->IDirectDrawGammaControl_vtbl = &IDirectDrawGammaControl_Vtbl;
-    (*ppSurf)->IDirect3DTexture2_vtbl = &IDirect3DTexture2_Vtbl;
-    (*ppSurf)->IDirect3DTexture_vtbl = &IDirect3DTexture1_Vtbl;
-    (*ppSurf)->ref = 1;
-    (*ppSurf)->version = 7;
-    TRACE("%p->version = %d\n", (*ppSurf), (*ppSurf)->version);
-    (*ppSurf)->ddraw = This;
-    (*ppSurf)->surface_desc.dwSize = sizeof(DDSURFACEDESC2);
-    (*ppSurf)->surface_desc.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
-    DD_STRUCT_COPY_BYSIZE(&(*ppSurf)->surface_desc, pDDSD);
-
-    /* Surface attachments */
-    (*ppSurf)->next_attached = NULL;
-    (*ppSurf)->first_attached = *ppSurf;
-
-    /* Needed to re-create the surface on an implementation change */
-    (*ppSurf)->ImplType = ImplType;
-
-    /* For D3DDevice creation */
-    (*ppSurf)->isRenderTarget = FALSE;
-
-    /* A trace message for debugging */
-    TRACE("(%p) Created IDirectDrawSurface implementation structure at %p\n", This, *ppSurf);
-
-    /* Now create the WineD3D Surface */
-    hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, pDDSD->dwWidth, pDDSD->dwHeight, Format,
-            TRUE /* Lockable */, FALSE /* Discard */, level, &(*ppSurf)->WineD3DSurface,
-            Usage, Pool, WINED3DMULTISAMPLE_NONE, 0 /* MultiSampleQuality */, ImplType,
-            (IUnknown *)*ppSurf, &ddraw_null_wined3d_parent_ops);
-
-    if(hr != D3D_OK)
-    {
-        ERR("IWineD3DDevice::CreateSurface failed. hr = %08x\n", hr);
+
+    hr = ddraw_surface_init(*ppSurf, This, pDDSD, level, ImplType);
+    if (FAILED(hr))
+    {
+        WARN("Failed to initialize surface, hr %#x.\n", hr);
+        HeapFree(GetProcessHeap(), 0, *ppSurf);
         return hr;
     }
 
@@ -2656,93 +2571,7 @@ static HRESULT ddraw_create_surface(IDirectDrawImpl *This, DDSURFACEDESC2 *pDDSD
     InterlockedIncrement(&This->surfaces);
     list_add_head(&This->surface_list, &(*ppSurf)->surface_list_entry);
 
-    /* Here we could store all created surfaces in the DirectDrawImpl structure,
-     * But this could also be delegated to WineDDraw, as it keeps track of all its
-     * resources. Not implemented for now, as there are more important things ;)
-     */
-
-    /* Get the pixel format of the WineD3DSurface and store it.
-     * Don't use the Format choosen above, WineD3D might have
-     * changed it
-     */
-    (*ppSurf)->surface_desc.dwFlags |= DDSD_PIXELFORMAT;
-    hr = IWineD3DSurface_GetDesc((*ppSurf)->WineD3DSurface, &Desc);
-    if(hr != D3D_OK)
-    {
-        ERR("IWineD3DSurface::GetDesc failed\n");
-        IDirectDrawSurface7_Release( (IDirectDrawSurface7 *) *ppSurf);
-        return hr;
-    }
-
-    Format = Desc.format;
-    Width = Desc.width;
-    Height = Desc.height;
-
-    if(Format == WINED3DFMT_UNKNOWN)
-    {
-        FIXME("IWineD3DSurface::GetDesc returned WINED3DFMT_UNKNOWN\n");
-    }
-    PixelFormat_WineD3DtoDD( &(*ppSurf)->surface_desc.u4.ddpfPixelFormat, Format);
-
-    /* Anno 1602 stores the pitch right after surface creation, so make sure it's there.
-     * I can't LockRect() the surface here because if OpenGL surfaces are in use, the
-     * WineD3DDevice might not be usable for 3D yet, so an extra method was created.
-     * TODO: Test other fourcc formats
-     */
-    if(Format == WINED3DFMT_DXT1 || Format == WINED3DFMT_DXT2 || Format == WINED3DFMT_DXT3 ||
-       Format == WINED3DFMT_DXT4 || Format == WINED3DFMT_DXT5)
-    {
-        (*ppSurf)->surface_desc.dwFlags |= DDSD_LINEARSIZE;
-        if(Format == WINED3DFMT_DXT1)
-        {
-            (*ppSurf)->surface_desc.u1.dwLinearSize = max(4, Width) * max(4, Height) / 2;
-        }
-        else
-        {
-            (*ppSurf)->surface_desc.u1.dwLinearSize = max(4, Width) * max(4, Height);
-        }
-    }
-    else
-    {
-        (*ppSurf)->surface_desc.dwFlags |= DDSD_PITCH;
-        (*ppSurf)->surface_desc.u1.lPitch = IWineD3DSurface_GetPitch((*ppSurf)->WineD3DSurface);
-    }
-
-    /* Application passed a color key? Set it! */
-    if(pDDSD->dwFlags & DDSD_CKDESTOVERLAY)
-    {
-        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
-                                    DDCKEY_DESTOVERLAY,
-                                    (WINEDDCOLORKEY *) &pDDSD->u3.ddckCKDestOverlay);
-    }
-    if(pDDSD->dwFlags & DDSD_CKDESTBLT)
-    {
-        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
-                                    DDCKEY_DESTBLT,
-                                    (WINEDDCOLORKEY *) &pDDSD->ddckCKDestBlt);
-    }
-    if(pDDSD->dwFlags & DDSD_CKSRCOVERLAY)
-    {
-        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
-                                    DDCKEY_SRCOVERLAY,
-                                    (WINEDDCOLORKEY *) &pDDSD->ddckCKSrcOverlay);
-    }
-    if(pDDSD->dwFlags & DDSD_CKSRCBLT)
-    {
-        IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface,
-                                    DDCKEY_SRCBLT,
-                                    (WINEDDCOLORKEY *) &pDDSD->ddckCKSrcBlt);
-    }
-    if ( pDDSD->dwFlags & DDSD_LPSURFACE)
-    {
-        hr = IWineD3DSurface_SetMem((*ppSurf)->WineD3DSurface, pDDSD->lpSurface);
-        if(hr != WINED3D_OK)
-        {
-            /* No need for a trace here, wined3d does that for us */
-            IDirectDrawSurface7_Release((IDirectDrawSurface7 *)*ppSurf);
-            return hr;
-        }
-    }
+    TRACE("Created surface %p.\n", *ppSurf);
 
     return DD_OK;
 }
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 9c2bb14..5c85e26 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -271,14 +271,9 @@ struct IDirectDrawSurfaceImpl
     DWORD                   Handle;
 };
 
-/* VTable declaration. It's located in surface.c / surface_thunks.c */
-extern const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl DECLSPEC_HIDDEN;
-extern const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl DECLSPEC_HIDDEN;
-extern const IDirectDrawGammaControlVtbl IDirectDrawGammaControl_Vtbl DECLSPEC_HIDDEN;
-extern const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl DECLSPEC_HIDDEN;
-extern const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl DECLSPEC_HIDDEN;
-
 void ddraw_surface_destroy(IDirectDrawSurfaceImpl *surface) DECLSPEC_HIDDEN;
+HRESULT ddraw_surface_init(IDirectDrawSurfaceImpl *surface, IDirectDrawImpl *ddraw,
+        DDSURFACEDESC2 *desc, UINT mip_level, WINED3DSURFTYPE surface_type) DECLSPEC_HIDDEN;
 
 static inline IDirectDrawSurfaceImpl *surface_from_texture1(IDirect3DTexture *iface)
 {
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 46c166a..a4d6c3c 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -3347,7 +3347,7 @@ static HRESULT WINAPI d3d_texture1_Load(IDirect3DTexture *iface, IDirect3DTextur
  * The VTable
  *****************************************************************************/
 
-const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl =
+static const struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl =
 {
     /* IUnknown */
     ddraw_surface7_QueryInterface,
@@ -3406,7 +3406,7 @@ const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl =
     ddraw_surface7_GetLOD,
 };
 
-const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl =
+static const struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl =
 {
     /* IUnknown */
     ddraw_surface3_QueryInterface,
@@ -3454,7 +3454,7 @@ const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl =
     ddraw_surface3_SetSurfaceDesc,
 };
 
-const IDirectDrawGammaControlVtbl IDirectDrawGammaControl_Vtbl =
+static const struct IDirectDrawGammaControlVtbl ddraw_gamma_control_vtbl =
 {
     ddraw_gamma_control_QueryInterface,
     ddraw_gamma_control_AddRef,
@@ -3463,7 +3463,7 @@ const IDirectDrawGammaControlVtbl IDirectDrawGammaControl_Vtbl =
     ddraw_gamma_control_SetGammaRamp,
 };
 
-const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl =
+static const struct IDirect3DTexture2Vtbl d3d_texture2_vtbl =
 {
     d3d_texture2_QueryInterface,
     d3d_texture2_AddRef,
@@ -3473,7 +3473,7 @@ const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl =
     d3d_texture2_Load,
 };
 
-const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl =
+static const struct IDirect3DTextureVtbl d3d_texture1_vtbl =
 {
     d3d_texture1_QueryInterface,
     d3d_texture1_AddRef,
@@ -3484,3 +3484,160 @@ const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl =
     d3d_texture1_Load,
     d3d_texture1_Unload,
 };
+
+HRESULT ddraw_surface_init(IDirectDrawSurfaceImpl *surface, IDirectDrawImpl *ddraw,
+        DDSURFACEDESC2 *desc, UINT mip_level, WINED3DSURFTYPE surface_type)
+{
+    WINED3DPOOL pool = WINED3DPOOL_DEFAULT;
+    WINED3DSURFACE_DESC wined3d_desc;
+    WINED3DFORMAT format;
+    DWORD usage = 0;
+    HRESULT hr;
+
+    if (!(desc->ddsCaps.dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY))
+            && !((desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
+            && (desc->ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)))
+    {
+        /* Tests show surfaces without memory flags get these flags added
+         * right after creation. */
+        desc->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
+    }
+
+    if (desc->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE))
+    {
+        usage |= WINED3DUSAGE_RENDERTARGET;
+        desc->ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
+    }
+
+    if (desc->ddsCaps.dwCaps & (DDSCAPS_OVERLAY))
+    {
+        usage |= WINED3DUSAGE_OVERLAY;
+    }
+
+    if (ddraw->depthstencil || (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
+    {
+        /* The depth stencil creation callback sets this flag. Set the
+         * wined3d usage to let it know it's a depth/stencil surface. */
+        usage |= WINED3DUSAGE_DEPTHSTENCIL;
+    }
+
+    if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
+    {
+        pool = WINED3DPOOL_SYSTEMMEM;
+    }
+    else if (desc->ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
+    {
+        pool = WINED3DPOOL_MANAGED;
+        /* Managed textures have the system memory flag set. */
+        desc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
+    }
+    else if (desc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
+    {
+        /* Videomemory adds localvidmem. This is mutually exclusive with
+         * systemmemory and texturemanage. */
+        desc->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM;
+    }
+
+    format = PixelFormat_DD2WineD3D(&desc->u4.ddpfPixelFormat);
+    if (format == WINED3DFMT_UNKNOWN)
+    {
+        WARN("Unsupported / unknown pixelformat.\n");
+        return DDERR_INVALIDPIXELFORMAT;
+    }
+
+    surface->lpVtbl = &ddraw_surface7_vtbl;
+    surface->IDirectDrawSurface3_vtbl = &ddraw_surface3_vtbl;
+    surface->IDirectDrawGammaControl_vtbl = &ddraw_gamma_control_vtbl;
+    surface->IDirect3DTexture2_vtbl = &d3d_texture2_vtbl;
+    surface->IDirect3DTexture_vtbl = &d3d_texture1_vtbl;
+    surface->ref = 1;
+    surface->version = 7;
+    surface->ddraw = ddraw;
+
+    surface->surface_desc.dwSize = sizeof(DDSURFACEDESC2);
+    surface->surface_desc.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+    DD_STRUCT_COPY_BYSIZE(&surface->surface_desc, desc);
+
+    surface->first_attached = surface;
+    surface->ImplType = surface_type;
+
+    hr = IWineD3DDevice_CreateSurface(ddraw->wineD3DDevice, desc->dwWidth, desc->dwHeight, format,
+            TRUE /* Lockable */, FALSE /* Discard */, mip_level, &surface->WineD3DSurface,
+            usage, pool, WINED3DMULTISAMPLE_NONE, 0 /* MultiSampleQuality */, surface_type,
+            (IUnknown *)surface, &ddraw_null_wined3d_parent_ops);
+    if (FAILED(hr))
+    {
+        WARN("Failed to create wined3d surface, hr %#x.\n", hr);
+        return hr;
+    }
+
+    surface->surface_desc.dwFlags |= DDSD_PIXELFORMAT;
+    hr = IWineD3DSurface_GetDesc(surface->WineD3DSurface, &wined3d_desc);
+    if (FAILED(hr))
+    {
+        ERR("Failed to get wined3d surface desc, hr %#x.\n", hr);
+        IWineD3DSurface_Release(surface->WineD3DSurface);
+        return hr;
+    }
+
+    format = wined3d_desc.format;
+    if (format == WINED3DFMT_UNKNOWN)
+    {
+        FIXME("IWineD3DSurface::GetDesc returned WINED3DFMT_UNKNOWN.\n");
+    }
+    PixelFormat_WineD3DtoDD(&surface->surface_desc.u4.ddpfPixelFormat, format);
+
+    /* Anno 1602 stores the pitch right after surface creation, so make sure
+     * it's there. TODO: Test other fourcc formats. */
+    if (format == WINED3DFMT_DXT1 || format == WINED3DFMT_DXT2 || format == WINED3DFMT_DXT3
+            || format == WINED3DFMT_DXT4 || format == WINED3DFMT_DXT5)
+    {
+        surface->surface_desc.dwFlags |= DDSD_LINEARSIZE;
+        if (format == WINED3DFMT_DXT1)
+        {
+            surface->surface_desc.u1.dwLinearSize = max(4, wined3d_desc.width) * max(4, wined3d_desc.height) / 2;
+        }
+        else
+        {
+            surface->surface_desc.u1.dwLinearSize = max(4, wined3d_desc.width) * max(4, wined3d_desc.height);
+        }
+    }
+    else
+    {
+        surface->surface_desc.dwFlags |= DDSD_PITCH;
+        surface->surface_desc.u1.lPitch = IWineD3DSurface_GetPitch(surface->WineD3DSurface);
+    }
+
+    if (desc->dwFlags & DDSD_CKDESTOVERLAY)
+    {
+        IWineD3DSurface_SetColorKey(surface->WineD3DSurface,
+                DDCKEY_DESTOVERLAY, (WINEDDCOLORKEY *)&desc->u3.ddckCKDestOverlay);
+    }
+    if (desc->dwFlags & DDSD_CKDESTBLT)
+    {
+        IWineD3DSurface_SetColorKey(surface->WineD3DSurface,
+                DDCKEY_DESTBLT, (WINEDDCOLORKEY *)&desc->ddckCKDestBlt);
+    }
+    if (desc->dwFlags & DDSD_CKSRCOVERLAY)
+    {
+        IWineD3DSurface_SetColorKey(surface->WineD3DSurface,
+                DDCKEY_SRCOVERLAY, (WINEDDCOLORKEY *)&desc->ddckCKSrcOverlay);
+    }
+    if (desc->dwFlags & DDSD_CKSRCBLT)
+    {
+        IWineD3DSurface_SetColorKey(surface->WineD3DSurface,
+                DDCKEY_SRCBLT, (WINEDDCOLORKEY *)&desc->ddckCKSrcBlt);
+    }
+    if (desc->dwFlags & DDSD_LPSURFACE)
+    {
+        hr = IWineD3DSurface_SetMem(surface->WineD3DSurface, desc->lpSurface);
+        if (FAILED(hr))
+        {
+            ERR("Failed to set surface memory, hr %#x.\n", hr);
+            IWineD3DSurface_Release(surface->WineD3DSurface);
+            return hr;
+        }
+    }
+
+    return DD_OK;
+}
-- 
1.7.1




More information about the wine-patches mailing list