From: Riccardo Bortolato Subject: [v5 (rebased) 3/5] ddraw: Do refcounting only through wined3d_texture_{inc, dec}ref(). Message-Id: <1453920354-24353-3-git-send-email-rikyz619@gmail.com> Date: Wed, 27 Jan 2016 19:45:52 +0100 In-Reply-To: <1453920354-24353-1-git-send-email-rikyz619@gmail.com> References: <1453920354-24353-1-git-send-email-rikyz619@gmail.com> Store in every ddraw_surface a wined3d_texture and the corresponding sub_resource_index. Signed-off-by: Riccardo Bortolato --- dlls/ddraw/ddraw.c | 2 +- dlls/ddraw/ddraw_private.h | 4 +++- dlls/ddraw/surface.c | 47 ++++++++++++++++++++++++++++++++++------------ 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index f17bb64..d7bf099 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -4765,7 +4765,7 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent return DDERR_OUTOFVIDEOMEMORY; } - ddraw_surface_init(ddraw_surface, ddraw, wined3d_texture_get_parent(wined3d_texture), surface, parent_ops); + ddraw_surface_init(ddraw_surface, ddraw, wined3d_texture, sub_resource_idx, surface, parent_ops); *parent = ddraw_surface; ddraw_update_lost_surfaces(ddraw); diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 38139f8..4fb1820 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -163,6 +163,7 @@ struct ddraw_surface struct ddraw *ddraw; struct wined3d_surface *wined3d_surface; struct wined3d_texture *wined3d_texture; + unsigned int sub_resource_idx; struct wined3d_rendertarget_view *wined3d_rtv; struct wined3d_private_store private_store; struct d3d_device *device1; @@ -209,7 +210,8 @@ struct ddraw_texture HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_desc, struct ddraw_surface **surface, IUnknown *outer_unknown, unsigned int version) DECLSPEC_HIDDEN; struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddraw_surface *surface) DECLSPEC_HIDDEN; -void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture, +void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN; ULONG ddraw_surface_release_iface(struct ddraw_surface *This) DECLSPEC_HIDDEN; HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index b4fa5de..0b774a2 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -326,10 +326,7 @@ static void ddraw_surface_add_iface(struct ddraw_surface *surface) wined3d_mutex_lock(); if (surface->wined3d_rtv) wined3d_rendertarget_view_incref(surface->wined3d_rtv); - if (surface->wined3d_surface) - wined3d_surface_incref(surface->wined3d_surface); - if (surface->wined3d_texture) - wined3d_texture_incref(surface->wined3d_texture); + wined3d_texture_incref(surface->wined3d_texture); wined3d_mutex_unlock(); } } @@ -532,10 +529,7 @@ static void ddraw_surface_cleanup(struct ddraw_surface *surface) if (surface->wined3d_rtv) wined3d_rendertarget_view_decref(surface->wined3d_rtv); - if (surface->wined3d_texture) - wined3d_texture_decref(surface->wined3d_texture); - if (surface->wined3d_surface) - wined3d_surface_decref(surface->wined3d_surface); + wined3d_texture_decref(surface->wined3d_texture); } ULONG ddraw_surface_release_iface(struct ddraw_surface *This) @@ -1246,6 +1240,14 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 return DDERR_NOEXCLUSIVEMODE; } + if (dst_impl->sub_resource_idx) + { + ERR("Destination surface is a mip level, cannot flip (sub_resource_idx: %u).", + dst_impl->sub_resource_idx); + wined3d_mutex_unlock(); + return DDERR_NOTFLIPPABLE; + } + tmp_rtv = ddraw_surface_get_rendertarget_view(dst_impl); tmp = dst_impl->wined3d_surface; texture = dst_impl->wined3d_texture; @@ -1271,6 +1273,14 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 } } + if (src_impl->sub_resource_idx) + { + ERR("Source surface is a mip level, cannot flip (sub_resource_idx: %u).", + src_impl->sub_resource_idx); + wined3d_mutex_unlock(); + return DDERR_NOTFLIPPABLE; + } + src_rtv = ddraw_surface_get_rendertarget_view(src_impl); if (rtv == dst_impl->wined3d_rtv) wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE); @@ -1301,6 +1311,15 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 } src_impl = impl_from_IDirectDrawSurface7(current); + + if (src_impl->sub_resource_idx) + { + ERR("Source surface is a mip level, cannot flip (sub_resource_idx: %u).", + src_impl->sub_resource_idx); + wined3d_mutex_unlock(); + return DDERR_NOTFLIPPABLE; + } + src_rtv = ddraw_surface_get_rendertarget_view(src_impl); if (rtv == dst_impl->wined3d_rtv) wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE); @@ -6085,7 +6104,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ resource = wined3d_texture_get_sub_resource(wined3d_texture, 0); root = wined3d_resource_get_parent(resource); - root->wined3d_texture = wined3d_texture; + wined3d_texture_decref(wined3d_texture); root->is_complex_root = TRUE; texture->root = root; @@ -6198,7 +6217,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ resource = wined3d_texture_get_sub_resource(wined3d_texture, 0); last = wined3d_resource_get_parent(resource); - last->wined3d_texture = wined3d_texture; + wined3d_texture_decref(wined3d_texture); texture->root = last; if (desc->dwFlags & DDSD_CKDESTOVERLAY) @@ -6237,9 +6256,11 @@ fail: return hr; } -void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture, +void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, + struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx, struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) { + struct ddraw_texture *texture = wined3d_texture_get_parent(wined3d_texture); DDSURFACEDESC2 *desc = &surface->surface_desc; struct wined3d_resource_desc wined3d_desc; unsigned int version = texture->version; @@ -6296,8 +6317,10 @@ void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, stru } desc->lpSurface = NULL; - wined3d_surface_incref(wined3d_surface); surface->wined3d_surface = wined3d_surface; + wined3d_texture_incref(wined3d_texture); + surface->wined3d_texture = wined3d_texture; + surface->sub_resource_idx = sub_resource_idx; *parent_ops = &ddraw_surface_wined3d_parent_ops; wined3d_private_store_init(&surface->private_store); -- 1.9.1