Commit bed50115 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

ddraw: More tests and fixes on surface attachments.

parent 28170f04
...@@ -1798,7 +1798,7 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This, ...@@ -1798,7 +1798,7 @@ IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This,
{ {
Usage |= WINED3DUSAGE_OVERLAY; Usage |= WINED3DUSAGE_OVERLAY;
} }
if(This->depthstencil) if(This->depthstencil || (pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) )
{ {
/* The depth stencil creation callback sets this flag. /* The depth stencil creation callback sets this flag.
* Set the WineD3D usage to let it know that it's a depth * Set the WineD3D usage to let it know that it's a depth
...@@ -2198,6 +2198,12 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface, ...@@ -2198,6 +2198,12 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
return CLASS_E_NOAGGREGATION; /* unchecked */ return CLASS_E_NOAGGREGATION; /* unchecked */
} }
if (Surf == NULL)
{
FIXME("(%p) You want to get back a surface? Don't give NULL ptrs!\n", This);
return E_POINTER; /* unchecked */
}
if (!(DDSD->dwFlags & DDSD_CAPS)) if (!(DDSD->dwFlags & DDSD_CAPS))
{ {
/* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */ /* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */
...@@ -2230,12 +2236,10 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface, ...@@ -2230,12 +2236,10 @@ IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface,
return DDERR_NOEXCLUSIVEMODE; return DDERR_NOEXCLUSIVEMODE;
} }
if (Surf == NULL) if(DDSD->ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER)) {
{ WARN("Application tried to create an explicit front or back buffer\n");
FIXME("(%p) You want to get back a surface? Don't give NULL ptrs!\n", This); return DDERR_INVALIDCAPS;
return E_POINTER; /* unchecked */
} }
/* Check cube maps but only if the size includes them */ /* Check cube maps but only if the size includes them */
if (DDSD->dwSize >= sizeof(DDSURFACEDESC2)) if (DDSD->dwSize >= sizeof(DDSURFACEDESC2))
{ {
......
...@@ -272,6 +272,8 @@ const IDirectDrawGammaControlVtbl IDirectDrawGammaControl_Vtbl; ...@@ -272,6 +272,8 @@ const IDirectDrawGammaControlVtbl IDirectDrawGammaControl_Vtbl;
const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl; const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl;
const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl; const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl;
HRESULT WINAPI IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurfaceImpl *This, IDirectDrawSurfaceImpl *Surf);
/* Get the number of bytes per pixel for a given surface */ /* Get the number of bytes per pixel for a given surface */
#define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:((pf.dwRGBBitCount+7)/8)) #define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:((pf.dwRGBBitCount+7)/8))
#define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat) #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
......
...@@ -386,6 +386,10 @@ IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc, ...@@ -386,6 +386,10 @@ IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc,
IDirectDrawSurfaceImpl *impl; IDirectDrawSurfaceImpl *impl;
HRESULT hr; HRESULT hr;
/* Remove front buffer flag, this causes failure in v7, and its added to normal
* primaries anyway
*/
pSDesc->ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER;
/* the LPDDSURFACEDESC -> LPDDSURFACEDESC2 conversion should be ok, /* the LPDDSURFACEDESC -> LPDDSURFACEDESC2 conversion should be ok,
* since the data layout is the same */ * since the data layout is the same */
hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl, hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl,
......
...@@ -780,11 +780,16 @@ IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface, ...@@ -780,11 +780,16 @@ IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface,
* *
* So far only Z-Buffer attachments are tested, and they are activated in * So far only Z-Buffer attachments are tested, and they are activated in
* WineD3D. Mipmaps could be tricky to activate in WineD3D. * WineD3D. Mipmaps could be tricky to activate in WineD3D.
* Back buffers should work in 2D mode, but they are not tested(Not sure if * Back buffers should work in 2D mode, but they are not tested(They can be
* they can be attached at all). Rendering to the primary surface and * attached in older iface versions). Rendering to the front buffer and
* switching between that and double buffering is not yet implemented in * switching between that and double buffering is not yet implemented in
* WineD3D, so for 3D it might have unexpected results. * WineD3D, so for 3D it might have unexpected results.
* *
* IDirectDrawSurfaceImpl_AddAttachedSurface is the real thing,
* IDirectDrawSurface7Impl_AddAttachedSurface is a wrapper around it that
* performs additional checks. Version 7 of this interface is much more restrictive
* than its predecessors.
*
* Params: * Params:
* Attach: Surface to attach to iface * Attach: Surface to attach to iface
* *
...@@ -793,45 +798,24 @@ IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface, ...@@ -793,45 +798,24 @@ IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface,
* DDERR_CANNOTATTACHSURFACE if the surface can't be attached for some reason * DDERR_CANNOTATTACHSURFACE if the surface can't be attached for some reason
* *
*****************************************************************************/ *****************************************************************************/
static HRESULT WINAPI HRESULT WINAPI
IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurface7 *iface, IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurfaceImpl *This,
IDirectDrawSurface7 *Attach) IDirectDrawSurfaceImpl *Surf)
{ {
ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
IDirectDrawSurfaceImpl *Surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Attach);
TRACE("(%p)->(%p)\n", This, Surf); TRACE("(%p)->(%p)\n", This, Surf);
/* Should I make sure to add it to the first complex surface? */
if(Surf == This) if(Surf == This)
return DDERR_CANNOTATTACHSURFACE; /* unchecked */ return DDERR_CANNOTATTACHSURFACE; /* unchecked */
/* MSDN: Only Z buffer surfaces can be attached. An old comment said that apparently
* mipmaps and back buffers can be attached too, although our tests say no.
*/
if(!(Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
{
/* Write a fixme until we know for sure what is going on */
FIXME("Application tries to attach a non Z buffer surface. caps %08x\n",
Surf->surface_desc.ddsCaps.dwCaps);
return DDERR_CANNOTATTACHSURFACE;
}
/* Set MIPMAPSUBLEVEL if this seems to be one */
if (This->surface_desc.ddsCaps.dwCaps &
Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
{
Surf->surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL;
/* FIXME: we should probably also add to dwMipMapCount of this
* and all parent surfaces (update create_texture if you do) */
}
/* Check if the surface is already attached somewhere */ /* Check if the surface is already attached somewhere */
if( (Surf->next_attached != NULL) || if( (Surf->next_attached != NULL) ||
(Surf->first_attached != Surf) ) (Surf->first_attached != Surf) )
{ {
ERR("(%p) The Surface %p is already attached somewhere else: next_attached = %p, first_attached = %p, can't handle by now\n", This, Surf, Surf->next_attached, Surf->first_attached); /* TODO: Test for the structure of the manual attachment. Is it a chain or a list?
return DDERR_CANNOTATTACHSURFACE; * What happens if one surface is attached to 2 different surfaces?
*/
FIXME("(%p) The Surface %p is already attached somewhere else: next_attached = %p, first_attached = %p, can't handle by now\n", This, Surf, Surf->next_attached, Surf->first_attached);
return DDERR_SURFACEALREADYATTACHED;
} }
/* This inserts the new surface at the 2nd position in the chain, right after the root surface */ /* This inserts the new surface at the 2nd position in the chain, right after the root surface */
...@@ -848,10 +832,29 @@ IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurface7 *iface, ...@@ -848,10 +832,29 @@ IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurface7 *iface,
/* MSDN: /* MSDN:
* "This method increments the reference count of the surface being attached." * "This method increments the reference count of the surface being attached."
*/ */
IDirectDrawSurface7_AddRef(Attach); IDirectDrawSurface7_AddRef(ICOM_INTERFACE(Surf, IDirectDrawSurface7));
return DD_OK; return DD_OK;
} }
static HRESULT WINAPI
IDirectDrawSurface7Impl_AddAttachedSurface(IDirectDrawSurface7 *iface,
IDirectDrawSurface7 *Attach)
{
ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface);
IDirectDrawSurfaceImpl *Surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Attach);
/* Version 7 of this interface seems to refuse everything except z buffers, as per msdn */
if(!(Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
{
WARN("Application tries to attach a non Z buffer surface. caps %08x\n",
Surf->surface_desc.ddsCaps.dwCaps);
return DDERR_CANNOTATTACHSURFACE;
}
return IDirectDrawSurfaceImpl_AddAttachedSurface(This,
Surf);
}
/***************************************************************************** /*****************************************************************************
* IDirectDrawSurface7::DeleteAttachedSurface * IDirectDrawSurface7::DeleteAttachedSurface
* *
...@@ -878,7 +881,7 @@ IDirectDrawSurfaceImpl_DeleteAttachedSurface(IDirectDrawSurface7 *iface, ...@@ -878,7 +881,7 @@ IDirectDrawSurfaceImpl_DeleteAttachedSurface(IDirectDrawSurface7 *iface,
TRACE("(%p)->(%08x,%p)\n", This, Flags, Surf); TRACE("(%p)->(%08x,%p)\n", This, Flags, Surf);
if (!Surf || (Surf->first_attached != This) || (Surf == This) ) if (!Surf || (Surf->first_attached != This) || (Surf == This) )
return DDERR_SURFACENOTATTACHED; /* unchecked */ return DDERR_CANNOTDETACHSURFACE;
/* Remove MIPMAPSUBLEVEL if this seemed to be one */ /* Remove MIPMAPSUBLEVEL if this seemed to be one */
if (This->surface_desc.ddsCaps.dwCaps & if (This->surface_desc.ddsCaps.dwCaps &
...@@ -2309,7 +2312,7 @@ const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl = ...@@ -2309,7 +2312,7 @@ const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl =
IDirectDrawSurfaceImpl_AddRef, IDirectDrawSurfaceImpl_AddRef,
IDirectDrawSurfaceImpl_Release, IDirectDrawSurfaceImpl_Release,
/*** IDirectDrawSurface ***/ /*** IDirectDrawSurface ***/
IDirectDrawSurfaceImpl_AddAttachedSurface, IDirectDrawSurface7Impl_AddAttachedSurface,
IDirectDrawSurfaceImpl_AddOverlayDirtyRect, IDirectDrawSurfaceImpl_AddOverlayDirtyRect,
IDirectDrawSurfaceImpl_Blt, IDirectDrawSurfaceImpl_Blt,
IDirectDrawSurfaceImpl_BltBatch, IDirectDrawSurfaceImpl_BltBatch,
......
...@@ -64,11 +64,45 @@ IDirectDrawSurface3Impl_Release(LPDIRECTDRAWSURFACE3 iface) ...@@ -64,11 +64,45 @@ IDirectDrawSurface3Impl_Release(LPDIRECTDRAWSURFACE3 iface)
} }
static HRESULT WINAPI static HRESULT WINAPI
IDirectDrawSurface3Impl_AddAttachedSurface(LPDIRECTDRAWSURFACE3 This, IDirectDrawSurface3Impl_AddAttachedSurface(LPDIRECTDRAWSURFACE3 iface,
LPDIRECTDRAWSURFACE3 pAttach) LPDIRECTDRAWSURFACE3 pAttach)
{ {
return IDirectDrawSurface7_AddAttachedSurface(CONVERT(This), ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface3, iface);
CONVERT(pAttach)); IDirectDrawSurfaceImpl *Surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, pAttach);
TRACE("(%p)->(%p)\n", This, Surf);
/* Tests suggest that
* -> offscreen plain surfaces can be attached to other offscreen plain surfaces
* -> offscreen plain surfaces can be attached to primaries
* -> primaries can be attached to offscreen plain surfaces
* -> z buffers can be attached to primaries
*
*/
if(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN) &&
Surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN))
{
/* Sizes have to match */
if(Surf->surface_desc.dwWidth != This->surface_desc.dwWidth ||
Surf->surface_desc.dwHeight != This->surface_desc.dwHeight)
{
WARN("Surface sizes do not match\n");
return DDERR_CANNOTATTACHSURFACE;
}
/* OK */
}
else if(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE) &&
Surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER))
{
/* OK */
}
else
{
WARN("Invalid attachment combination\n");
return DDERR_CANNOTATTACHSURFACE;
}
return IDirectDrawSurfaceImpl_AddAttachedSurface(This,
Surf);
} }
static HRESULT WINAPI static HRESULT WINAPI
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment