ddraw: More tests and fixes on surface attachments.

This commit is contained in:
Stefan Dösinger 2007-05-04 18:31:14 +02:00 committed by Alexandre Julliard
parent 28170f0474
commit bed50115ee
6 changed files with 344 additions and 45 deletions

View File

@ -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,
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,
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))
{ {

View File

@ -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)

View File

@ -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,

View File

@ -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,
* 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,
/* 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,
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 =
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,

View File

@ -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

View File

@ -965,11 +965,11 @@ HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc
return DDENUMRET_OK; return DDENUMRET_OK;
} }
static void AttachmentTest(void) static void AttachmentTest7(void)
{ {
HRESULT hr; HRESULT hr;
IDirectDraw7 *dd7; IDirectDraw7 *dd7;
IDirectDrawSurface7 *surface1, *surface2, *surface3; IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
DDSURFACEDESC2 ddsd; DDSURFACEDESC2 ddsd;
UINT num; UINT num;
DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0}; DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0};
@ -1031,6 +1031,26 @@ static void AttachmentTest(void)
hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3); hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr); ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
IDirectDrawSurface7_Release(surface2);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = 16;
ddsd.dwHeight = 16;
hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
IDirectDrawSurface7_Release(surface3); IDirectDrawSurface7_Release(surface3);
IDirectDrawSurface7_Release(surface2); IDirectDrawSurface7_Release(surface2);
IDirectDrawSurface7_Release(surface1); IDirectDrawSurface7_Release(surface1);
@ -1051,11 +1071,242 @@ static void AttachmentTest(void)
ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num); ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num);
IDirectDrawSurface7_Release(surface1); IDirectDrawSurface7_Release(surface1);
/* Those are some invalid descriptions, no need to test attachments with them */
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
/* Try a single primary and two offscreen plain surfaces */
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
/* This one has a different size */
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = 128;
ddsd.dwHeight = 128;
hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
IDirectDrawSurface7_Release(surface4);
IDirectDrawSurface7_Release(surface3);
IDirectDrawSurface7_Release(surface2);
IDirectDrawSurface7_Release(surface1);
hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL); hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr); ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
IDirectDraw7_Release(dd7); IDirectDraw7_Release(dd7);
} }
static void AttachmentTest(void)
{
HRESULT hr;
IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
DDSURFACEDESC ddsd;
DDSCAPS caps = {DDSCAPS_TEXTURE};
HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
ddsd.dwWidth = 128;
ddsd.dwHeight = 128;
hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
/* Try to attach a 16x16 miplevel - Should not work as far I can see */
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
ddsd.dwWidth = 16;
ddsd.dwHeight = 16;
hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
IDirectDrawSurface7_Release(surface4);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = 16;
ddsd.dwHeight = 16;
hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
IDirectDrawSurface7_Release(surface4);
IDirectDrawSurface7_Release(surface3);
IDirectDrawSurface7_Release(surface2);
IDirectDrawSurface7_Release(surface1);
hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
/* Creating a back buffer as-is is not allowed, no need to perform attachment tests */
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
/* This old ddraw version happily creates explicit front buffers */
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
IDirectDrawSurface_Release(surface1);
/* Try a single primary and two offscreen plain surfaces */
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
/* This one has a different size */
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = 128;
ddsd.dwHeight = 128;
hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
ok(hr == DD_OK, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
/* Try the reverse without detaching first */
hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
ok(hr == DD_OK, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
/* Try to detach reversed */
hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
/* Now the proper detach */
hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
ok(hr == DD_OK, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
IDirectDrawSurface_Release(surface4);
IDirectDrawSurface_Release(surface3);
IDirectDrawSurface_Release(surface2);
IDirectDrawSurface_Release(surface1);
hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
DestroyWindow(window);
}
struct compare struct compare
{ {
DWORD width, height; DWORD width, height;
@ -1831,6 +2082,7 @@ START_TEST(dsurface)
GetDDInterface_7(); GetDDInterface_7();
EnumTest(); EnumTest();
AttachmentTest(); AttachmentTest();
AttachmentTest7();
CubeMapTest(); CubeMapTest();
test_lockrect_invalid(); test_lockrect_invalid();
CompressedTest(); CompressedTest();