[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