ddraw: Allow attaching surfaces other than depth buffers in ddraw_surface4_AddAttachedSurface().

This commit is contained in:
Henri Verbeet 2014-01-27 10:07:52 +01:00 committed by Alexandre Julliard
parent fffaf03c0d
commit 7c6ca2077f
2 changed files with 43 additions and 55 deletions

View File

@ -1670,106 +1670,94 @@ static HRESULT WINAPI ddraw_surface7_AddAttachedSurface(IDirectDrawSurface7 *ifa
static HRESULT WINAPI ddraw_surface4_AddAttachedSurface(IDirectDrawSurface4 *iface, IDirectDrawSurface4 *attachment)
{
struct ddraw_surface *This = impl_from_IDirectDrawSurface4(iface);
struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
struct ddraw_surface *attachment_impl = unsafe_impl_from_IDirectDrawSurface4(attachment);
HRESULT hr;
TRACE("iface %p, attachment %p.\n", iface, attachment);
hr = ddraw_surface7_AddAttachedSurface(&This->IDirectDrawSurface7_iface,
attachment_impl ? &attachment_impl->IDirectDrawSurface7_iface : NULL);
if (FAILED(hr))
{
return hr;
}
attachment_impl->attached_iface = (IUnknown *)attachment;
IUnknown_AddRef(attachment_impl->attached_iface);
ddraw_surface7_Release(&attachment_impl->IDirectDrawSurface7_iface);
return hr;
}
static HRESULT WINAPI ddraw_surface3_AddAttachedSurface(IDirectDrawSurface3 *iface, IDirectDrawSurface3 *attachment)
{
struct ddraw_surface *This = impl_from_IDirectDrawSurface3(iface);
struct ddraw_surface *attachment_impl = unsafe_impl_from_IDirectDrawSurface3(attachment);
HRESULT hr;
TRACE("iface %p, attachment %p.\n", iface, attachment);
/* 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)
if (surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN)
&& attachment_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN))
{
/* Sizes have to match */
if (attachment_impl->surface_desc.dwWidth != This->surface_desc.dwWidth
|| attachment_impl->surface_desc.dwHeight != This->surface_desc.dwHeight)
if (attachment_impl->surface_desc.dwWidth != surface->surface_desc.dwWidth
|| attachment_impl->surface_desc.dwHeight != surface->surface_desc.dwHeight)
{
WARN("Surface sizes do not match.\n");
return DDERR_CANNOTATTACHSURFACE;
}
/* OK */
}
else if (This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE)
&& attachment_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER))
{
/* OK */
}
else
else if (!(surface->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE))
|| !(attachment_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)))
{
WARN("Invalid attachment combination.\n");
return DDERR_CANNOTATTACHSURFACE;
}
hr = ddraw_surface_attach_surface(This, attachment_impl);
if (FAILED(hr))
{
if (FAILED(hr = ddraw_surface_attach_surface(surface, attachment_impl)))
return hr;
}
attachment_impl->attached_iface = (IUnknown *)attachment;
IUnknown_AddRef(attachment_impl->attached_iface);
return hr;
}
static HRESULT WINAPI ddraw_surface3_AddAttachedSurface(IDirectDrawSurface3 *iface, IDirectDrawSurface3 *attachment)
{
struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
struct ddraw_surface *attachment_impl = unsafe_impl_from_IDirectDrawSurface3(attachment);
HRESULT hr;
TRACE("iface %p, attachment %p.\n", iface, attachment);
if (FAILED(hr = ddraw_surface4_AddAttachedSurface(&surface->IDirectDrawSurface4_iface,
attachment_impl ? &attachment_impl->IDirectDrawSurface4_iface : NULL)))
return hr;
attachment_impl->attached_iface = (IUnknown *)attachment;
IUnknown_AddRef(attachment_impl->attached_iface);
ddraw_surface4_Release(&attachment_impl->IDirectDrawSurface4_iface);
return hr;
}
static HRESULT WINAPI ddraw_surface2_AddAttachedSurface(IDirectDrawSurface2 *iface, IDirectDrawSurface2 *attachment)
{
struct ddraw_surface *This = impl_from_IDirectDrawSurface2(iface);
struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
struct ddraw_surface *attachment_impl = unsafe_impl_from_IDirectDrawSurface2(attachment);
HRESULT hr;
TRACE("iface %p, attachment %p.\n", iface, attachment);
hr = ddraw_surface3_AddAttachedSurface(&This->IDirectDrawSurface3_iface,
attachment_impl ? &attachment_impl->IDirectDrawSurface3_iface : NULL);
if (FAILED(hr))
{
if (FAILED(hr = ddraw_surface4_AddAttachedSurface(&surface->IDirectDrawSurface4_iface,
attachment_impl ? &attachment_impl->IDirectDrawSurface4_iface : NULL)))
return hr;
}
attachment_impl->attached_iface = (IUnknown *)attachment;
IUnknown_AddRef(attachment_impl->attached_iface);
ddraw_surface3_Release(&attachment_impl->IDirectDrawSurface3_iface);
ddraw_surface4_Release(&attachment_impl->IDirectDrawSurface4_iface);
return hr;
}
static HRESULT WINAPI ddraw_surface1_AddAttachedSurface(IDirectDrawSurface *iface, IDirectDrawSurface *attachment)
{
struct ddraw_surface *This = impl_from_IDirectDrawSurface(iface);
struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
struct ddraw_surface *attachment_impl = unsafe_impl_from_IDirectDrawSurface(attachment);
HRESULT hr;
TRACE("iface %p, attachment %p.\n", iface, attachment);
hr = ddraw_surface3_AddAttachedSurface(&This->IDirectDrawSurface3_iface,
attachment_impl ? &attachment_impl->IDirectDrawSurface3_iface : NULL);
if (FAILED(hr))
{
if (FAILED(hr = ddraw_surface4_AddAttachedSurface(&surface->IDirectDrawSurface4_iface,
attachment_impl ? &attachment_impl->IDirectDrawSurface4_iface : NULL)))
return hr;
}
attachment_impl->attached_iface = (IUnknown *)attachment;
IUnknown_AddRef(attachment_impl->attached_iface);
ddraw_surface3_Release(&attachment_impl->IDirectDrawSurface3_iface);
ddraw_surface4_Release(&attachment_impl->IDirectDrawSurface4_iface);
return hr;
}

View File

@ -6005,25 +6005,25 @@ static void test_surface_attachment(void)
ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
hr = IDirectDrawSurface4_AddAttachedSurface(surface1, surface2);
todo_wine ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
/* Try the reverse without detaching first. */
hr = IDirectDrawSurface4_AddAttachedSurface(surface2, surface1);
todo_wine ok(hr == DDERR_SURFACEALREADYATTACHED, "Got unexpected hr %#x.\n", hr);
ok(hr == DDERR_SURFACEALREADYATTACHED, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface4_DeleteAttachedSurface(surface1, 0, surface2);
todo_wine ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
hr = IDirectDrawSurface4_AddAttachedSurface(surface2, surface1);
todo_wine ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
/* Try to detach reversed. */
hr = IDirectDrawSurface4_DeleteAttachedSurface(surface1, 0, surface2);
ok(hr == DDERR_CANNOTDETACHSURFACE, "Got unexpected hr %#x.\n", hr);
hr = IDirectDrawSurface4_DeleteAttachedSurface(surface2, 0, surface1);
todo_wine ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
hr = IDirectDrawSurface4_AddAttachedSurface(surface2, surface3);
todo_wine ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
ok(SUCCEEDED(hr), "Failed to attach surface, hr %#x.\n", hr);
hr = IDirectDrawSurface4_DeleteAttachedSurface(surface2, 0, surface3);
todo_wine ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x.\n", hr);
hr = IDirectDrawSurface4_AddAttachedSurface(surface1, surface4);
ok(hr == DDERR_CANNOTATTACHSURFACE, "Got unexpected hr %#x.\n", hr);