[PATCH 04/12] ddraw: store wined3d_texture and sub_resource idx per ddraw_surface

Riccardo Bortolato rikyz619 at gmail.com
Wed Sep 23 03:27:28 CDT 2015


removed the wined3d_surface member from ddraw_surface
---
 dlls/ddraw/ddraw.c         |   2 +-
 dlls/ddraw/ddraw_private.h |  12 +--
 dlls/ddraw/device.c        |  17 +++-
 dlls/ddraw/surface.c       | 197 ++++++++++++++++++++++++++++++++++-----------
 4 files changed, 173 insertions(+), 55 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index c121780..465b1ef 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -4737,7 +4737,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, surface, wined3d_texture, sub_resource_idx, parent_ops);
     *parent = ddraw_surface;
     list_add_head(&ddraw->surface_list, &ddraw_surface->surface_list_entry);
 
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 62bdf85..f710a25 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -159,7 +159,6 @@ struct ddraw_surface
 
     /* Connections to other Objects */
     struct ddraw *ddraw;
-    struct wined3d_surface *wined3d_surface;
     struct wined3d_texture *wined3d_root_texture;
     struct wined3d_rendertarget_view *wined3d_rtv;
     struct wined3d_private_store private_store;
@@ -185,8 +184,9 @@ struct ddraw_surface
     /* Surface description, for GetAttachedSurface */
     DDSURFACEDESC2          surface_desc;
 
-    /* Misc things */
-    UINT                    mipmap_level;
+    /* Only related to a single ddraw surface */
+    struct wined3d_texture *wined3d_texture;
+    unsigned int sub_resource_idx;
 
     /* Clipper objects */
     struct ddraw_clipper *clipper;
@@ -209,8 +209,10 @@ 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,
-        struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
+void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw,
+        struct wined3d_surface *wined3d_surface,
+        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+        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,
         const RECT *rect, BOOL read) DECLSPEC_HIDDEN;
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 5df2123..45fa570 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -5618,6 +5618,8 @@ static HRESULT WINAPI d3d_device7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *if
 static HRESULT d3d_device7_PreLoad(IDirect3DDevice7 *iface, IDirectDrawSurface7 *texture)
 {
     struct ddraw_surface *surface = unsafe_impl_from_IDirectDrawSurface7(texture);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
 
     TRACE("iface %p, texture %p.\n", iface, texture);
 
@@ -5625,7 +5627,9 @@ static HRESULT d3d_device7_PreLoad(IDirect3DDevice7 *iface, IDirectDrawSurface7
         return DDERR_INVALIDPARAMS;
 
     wined3d_mutex_lock();
-    wined3d_surface_preload(surface->wined3d_surface);
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    wined3d_surface_preload(wined3d_surface);
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -5948,6 +5952,8 @@ static void copy_mipmap_chain(struct d3d_device *device, struct ddraw_surface *d
         struct ddraw_surface *src, const POINT *DestPoint, const RECT *SrcRect)
 {
     struct ddraw_surface *src_level, *dest_level;
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface_src, *wined3d_surface_dst;
     IDirectDrawSurface7 *temp;
     DDSURFACEDESC2 ddsd;
     POINT point;
@@ -5998,8 +6004,13 @@ static void copy_mipmap_chain(struct d3d_device *device, struct ddraw_surface *d
             UINT src_h = src_rect.bottom - src_rect.top;
             RECT dst_rect = {point.x, point.y, point.x + src_w, point.y + src_h};
 
-            if (FAILED(hr = wined3d_surface_blt(dest_level->wined3d_surface, &dst_rect,
-                    src_level->wined3d_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT)))
+            sub_resource = wined3d_texture_get_sub_resource(src_level->wined3d_texture, src_level->sub_resource_idx);
+            wined3d_surface_src = wined3d_surface_from_resource(sub_resource);
+            sub_resource = wined3d_texture_get_sub_resource(dest_level->wined3d_texture, dest_level->sub_resource_idx);
+            wined3d_surface_dst = wined3d_surface_from_resource(sub_resource);
+
+            if (FAILED(hr = wined3d_surface_blt(wined3d_surface_dst, &dst_rect,
+                    wined3d_surface_src, &src_rect, 0, NULL, WINED3D_TEXF_POINT)))
                 ERR("Blit failed, hr %#x.\n", hr);
 
             ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index bc82320..ae48214 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -42,6 +42,8 @@ static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDra
  * to support windowless rendering first. */
 HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read)
 {
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HDC surface_dc, screen_dc;
     int x, y, w, h;
     HRESULT hr;
@@ -65,6 +67,9 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE
     if (w <= 0 || h <= 0)
         return DD_OK;
 
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+
     if (surface->ddraw->swapchain_window)
     {
         /* Nothing to do, we control the frontbuffer, or at least the parts we
@@ -73,10 +78,10 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE
             return DD_OK;
 
         return wined3d_surface_blt(surface->ddraw->wined3d_frontbuffer, rect,
-                surface->wined3d_surface, rect, 0, NULL, WINED3D_TEXF_POINT);
+                wined3d_surface, rect, 0, NULL, WINED3D_TEXF_POINT);
     }
 
-    if (FAILED(hr = wined3d_surface_getdc(surface->wined3d_surface, &surface_dc)))
+    if (FAILED(hr = wined3d_surface_getdc(wined3d_surface, &surface_dc)))
     {
         ERR("Failed to get surface DC, hr %#x.\n", hr);
         return hr;
@@ -86,7 +91,7 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE
 
     if (!(screen_dc = GetDC(NULL)))
     {
-        wined3d_surface_releasedc(surface->wined3d_surface, surface_dc);
+        wined3d_surface_releasedc(wined3d_surface, surface_dc);
         ERR("Failed to get screen DC.\n");
         return E_FAIL;
     }
@@ -99,7 +104,7 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE
                 surface_dc, x, y, SRCCOPY);
 
     ReleaseDC(NULL, screen_dc);
-    wined3d_surface_releasedc(surface->wined3d_surface, surface_dc);
+    wined3d_surface_releasedc(wined3d_surface, surface_dc);
 
     if (!ret)
     {
@@ -317,6 +322,8 @@ static HRESULT WINAPI d3d_texture1_QueryInterface(IDirect3DTexture *iface, REFII
 static void ddraw_surface_add_iface(struct ddraw_surface *surface)
 {
     ULONG iface_count = InterlockedIncrement(&surface->iface_count);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     TRACE("%p increasing iface count to %u.\n", surface, iface_count);
 
     if (iface_count == 1)
@@ -326,8 +333,12 @@ 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);
+
+        sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+        wined3d_surface = wined3d_surface_from_resource(sub_resource);
+
+        if (wined3d_surface)
+            wined3d_surface_incref(wined3d_surface);
         if (surface->wined3d_root_texture)
             wined3d_texture_incref(surface->wined3d_root_texture);
         wined3d_mutex_unlock();
@@ -495,6 +506,8 @@ static HRESULT ddraw_surface_set_palette(struct ddraw_surface *surface, IDirectD
 static void ddraw_surface_cleanup(struct ddraw_surface *surface)
 {
     struct ddraw_surface *surf;
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     UINT i;
 
     TRACE("surface %p.\n", surface);
@@ -534,8 +547,10 @@ static void ddraw_surface_cleanup(struct ddraw_surface *surface)
         wined3d_rendertarget_view_decref(surface->wined3d_rtv);
     if (surface->wined3d_root_texture)
         wined3d_texture_decref(surface->wined3d_root_texture);
-    if (surface->wined3d_surface)
-        wined3d_surface_decref(surface->wined3d_surface);
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    if (wined3d_surface)
+        wined3d_surface_decref(wined3d_surface);
 }
 
 ULONG ddraw_surface_release_iface(struct ddraw_surface *This)
@@ -777,7 +792,6 @@ static HRESULT WINAPI ddraw_surface7_GetAttachedSurface(IDirectDrawSurface7 *ifa
              */
 
             TRACE("(%p): Returning surface %p\n", This, surf);
-            TRACE("(%p): mipmapcount=%d\n", This, surf->mipmap_level);
             *Surface = &surf->IDirectDrawSurface7_iface;
             ddraw_surface7_AddRef(*Surface);
             wined3d_mutex_unlock();
@@ -954,6 +968,8 @@ static HRESULT WINAPI ddraw_surface1_GetAttachedSurface(IDirectDrawSurface *ifac
 static HRESULT surface_lock(struct ddraw_surface *This,
         RECT *Rect, DDSURFACEDESC2 *DDSD, DWORD Flags, HANDLE h)
 {
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     struct wined3d_map_desc map_desc;
     HRESULT hr = DD_OK;
 
@@ -987,10 +1003,13 @@ static HRESULT surface_lock(struct ddraw_surface *This,
         }
     }
 
+    sub_resource = wined3d_texture_get_sub_resource(This->wined3d_texture, This->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+
     if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
         hr = ddraw_surface_update_frontbuffer(This, Rect, TRUE);
     if (SUCCEEDED(hr))
-        hr = wined3d_surface_map(This->wined3d_surface, &map_desc, Rect, Flags);
+        hr = wined3d_surface_map(wined3d_surface, &map_desc, Rect, Flags);
     if (FAILED(hr))
     {
         wined3d_mutex_unlock();
@@ -1158,12 +1177,16 @@ static HRESULT WINAPI ddraw_surface1_Lock(IDirectDrawSurface *iface, RECT *rect,
 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Unlock(IDirectDrawSurface7 *iface, RECT *pRect)
 {
     struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(pRect));
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_unmap(surface->wined3d_surface);
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_surface_unmap(wined3d_surface);
     if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
         hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE);
     wined3d_mutex_unlock();
@@ -1220,7 +1243,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7
     DDSCAPS2 caps = {DDSCAPS_FLIP, 0, 0, {0}};
     struct wined3d_texture *texture;
     IDirectDrawSurface7 *current;
-    struct wined3d_surface *tmp;
+    struct wined3d_texture *tmp;
+    unsigned int tmp_idx;
     HRESULT hr;
 
     TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
@@ -1234,7 +1258,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7
     wined3d_mutex_lock();
 
     tmp_rtv = ddraw_surface_get_rendertarget_view(dst_impl);
-    tmp = dst_impl->wined3d_surface;
+    tmp = dst_impl->wined3d_texture;
+    tmp_idx = dst_impl->sub_resource_idx;
     texture = dst_impl->wined3d_root_texture;
     rtv = wined3d_device_get_rendertarget_view(dst_impl->ddraw->wined3d_device, 0);
     ddraw_texture = wined3d_texture_get_parent(dst_impl->wined3d_root_texture);
@@ -1263,8 +1288,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7
             wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE);
         wined3d_rendertarget_view_set_parent(src_rtv, dst_impl);
         dst_impl->wined3d_rtv = src_rtv;
-        wined3d_resource_set_parent(wined3d_surface_get_resource(src_impl->wined3d_surface), dst_impl);
-        dst_impl->wined3d_surface = src_impl->wined3d_surface;
+        wined3d_resource_set_parent(wined3d_texture_get_sub_resource(src_impl->wined3d_texture, src_impl->sub_resource_idx), dst_impl);
+        dst_impl->wined3d_texture = src_impl->wined3d_texture;
+        dst_impl->sub_resource_idx = src_impl->sub_resource_idx;
         prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_root_texture);
         wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_root_texture), ddraw_texture);
         dst_impl->wined3d_root_texture = src_impl->wined3d_root_texture;
@@ -1293,8 +1319,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7
                 wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE);
             wined3d_rendertarget_view_set_parent(src_rtv, dst_impl);
             dst_impl->wined3d_rtv = src_rtv;
-            wined3d_resource_set_parent(wined3d_surface_get_resource(src_impl->wined3d_surface), dst_impl);
-            dst_impl->wined3d_surface = src_impl->wined3d_surface;
+            wined3d_resource_set_parent(wined3d_texture_get_sub_resource(src_impl->wined3d_texture, src_impl->sub_resource_idx), dst_impl);
+            dst_impl->wined3d_texture = src_impl->wined3d_texture;
+            dst_impl->sub_resource_idx = src_impl->sub_resource_idx;
             prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_root_texture);
             wined3d_resource_set_parent(wined3d_texture_get_resource(src_impl->wined3d_root_texture), ddraw_texture);
             ddraw_texture = prev_ddraw_texture;
@@ -1309,8 +1336,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7
         wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, tmp_rtv, FALSE);
     wined3d_rendertarget_view_set_parent(tmp_rtv, src_impl);
     src_impl->wined3d_rtv = tmp_rtv;
-    wined3d_resource_set_parent(wined3d_surface_get_resource(tmp), src_impl);
-    src_impl->wined3d_surface = tmp;
+    wined3d_resource_set_parent(wined3d_texture_get_sub_resource(tmp, tmp_idx), src_impl);
+    src_impl->wined3d_texture = tmp;
+    src_impl->sub_resource_idx = tmp_idx;
     wined3d_resource_set_parent(wined3d_texture_get_resource(texture), ddraw_texture);
     src_impl->wined3d_root_texture = texture;
 
@@ -1385,7 +1413,8 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons
         struct ddraw_surface *src_surface, const RECT *src_rect_in, DWORD flags,
         const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter)
 {
-    struct wined3d_surface *wined3d_src_surface = src_surface ? src_surface->wined3d_surface : NULL;
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_dst_surface, *wined3d_src_surface = NULL;
     RECT src_rect, dst_rect;
     float scale_x, scale_y;
     const RECT *clip_rect;
@@ -1394,12 +1423,21 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons
     HRESULT hr = DD_OK;
     UINT i;
 
+    sub_resource = wined3d_texture_get_sub_resource(dst_surface->wined3d_texture, dst_surface->sub_resource_idx);
+    wined3d_dst_surface = wined3d_surface_from_resource(sub_resource);
+
+    if (src_surface)
+    {
+        sub_resource = wined3d_texture_get_sub_resource(src_surface->wined3d_texture, src_surface->sub_resource_idx);
+        wined3d_src_surface = wined3d_surface_from_resource(sub_resource);
+    }
+
     if (!dst_surface->clipper)
     {
         if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
             hr = ddraw_surface_update_frontbuffer(src_surface, src_rect_in, TRUE);
         if (SUCCEEDED(hr))
-            hr = wined3d_surface_blt(dst_surface->wined3d_surface, dst_rect_in,
+            hr = wined3d_surface_blt(wined3d_dst_surface, dst_rect_in,
                     wined3d_src_surface, src_rect_in, flags, fx, filter);
         if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
             hr = ddraw_surface_update_frontbuffer(dst_surface, dst_rect_in, FALSE);
@@ -1487,7 +1525,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons
             }
         }
 
-        if (FAILED(hr = wined3d_surface_blt(dst_surface->wined3d_surface, &clip_rect[i],
+        if (FAILED(hr = wined3d_surface_blt(wined3d_dst_surface, &clip_rect[i],
                 wined3d_src_surface, &src_rect_clipped, flags, fx, filter)))
             break;
 
@@ -2097,6 +2135,8 @@ static HRESULT WINAPI ddraw_surface1_AddOverlayDirtyRect(IDirectDrawSurface *ifa
 static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *hdc)
 {
     struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr = DD_OK;
 
     TRACE("iface %p, dc %p.\n", iface, hdc);
@@ -2108,8 +2148,11 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *hdc)
     if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
         hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE);
     if (SUCCEEDED(hr))
-        hr = wined3d_surface_getdc(surface->wined3d_surface, hdc);
-
+    {
+        sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+        wined3d_surface = wined3d_surface_from_resource(sub_resource);
+        hr = wined3d_surface_getdc(wined3d_surface, hdc);
+    }
     if (SUCCEEDED(hr) && format_is_paletteindexed(&surface->surface_desc.u4.ddpfPixelFormat))
     {
         const struct ddraw_palette *palette;
@@ -2191,12 +2234,16 @@ static HRESULT WINAPI ddraw_surface1_GetDC(IDirectDrawSurface *iface, HDC *dc)
 static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC hdc)
 {
     struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p, dc %p.\n", iface, hdc);
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_releasedc(surface->wined3d_surface, hdc);
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_surface_releasedc(wined3d_surface, hdc);
     if (SUCCEEDED(hr) && (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
         hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE);
     wined3d_mutex_unlock();
@@ -3183,12 +3230,16 @@ static HRESULT WINAPI ddraw_surface1_GetFlipStatus(IDirectDrawSurface *iface, DW
 static HRESULT WINAPI ddraw_surface7_GetOverlayPosition(IDirectDrawSurface7 *iface, LONG *X, LONG *Y)
 {
     struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p, x %p, y %p.\n", iface, X, Y);
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_get_overlay_position(surface->wined3d_surface, X, Y);
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_surface_get_overlay_position(wined3d_surface, X, Y);
     wined3d_mutex_unlock();
 
     return hr;
@@ -3494,12 +3545,16 @@ static HRESULT WINAPI d3d_texture1_Initialize(IDirect3DTexture *iface,
 static HRESULT WINAPI ddraw_surface7_IsLost(IDirectDrawSurface7 *iface)
 {
     struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p.\n", iface);
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_is_lost(surface->wined3d_surface);
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_surface_is_lost(wined3d_surface);
     wined3d_mutex_unlock();
 
     switch(hr)
@@ -3562,12 +3617,16 @@ static HRESULT WINAPI ddraw_surface1_IsLost(IDirectDrawSurface *iface)
 static HRESULT WINAPI ddraw_surface7_Restore(IDirectDrawSurface7 *iface)
 {
     struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p.\n", iface);
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_restore(surface->wined3d_surface);
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_surface_restore(wined3d_surface);
     wined3d_mutex_unlock();
 
     return hr;
@@ -3624,12 +3683,16 @@ static HRESULT WINAPI ddraw_surface1_Restore(IDirectDrawSurface *iface)
 static HRESULT WINAPI ddraw_surface7_SetOverlayPosition(IDirectDrawSurface7 *iface, LONG X, LONG Y)
 {
     struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p, x %d, y %d.\n", iface, X, Y);
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_set_overlay_position(surface->wined3d_surface, X, Y);
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_surface_set_overlay_position(wined3d_surface, X, Y);
     wined3d_mutex_unlock();
 
     return hr;
@@ -3691,14 +3754,23 @@ static HRESULT WINAPI ddraw_surface7_UpdateOverlay(IDirectDrawSurface7 *iface, R
 {
     struct ddraw_surface *src_impl = impl_from_IDirectDrawSurface7(iface);
     struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface7(DstSurface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface_src, *wined3d_surface_dst;
     HRESULT hr;
 
     TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
             iface, wine_dbgstr_rect(SrcRect), DstSurface, wine_dbgstr_rect(DstRect), Flags, FX);
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_update_overlay(src_impl->wined3d_surface, SrcRect,
-            dst_impl ? dst_impl->wined3d_surface : NULL, DstRect, Flags, (WINEDDOVERLAYFX *)FX);
+    sub_resource = wined3d_texture_get_sub_resource(src_impl->wined3d_texture, src_impl->sub_resource_idx);
+    wined3d_surface_src = wined3d_surface_from_resource(sub_resource);
+    if (dst_impl)
+    {
+        sub_resource = wined3d_texture_get_sub_resource(dst_impl->wined3d_texture, dst_impl->sub_resource_idx);
+        wined3d_surface_dst = wined3d_surface_from_resource(sub_resource);
+    }
+    hr = wined3d_surface_update_overlay(wined3d_surface_src, SrcRect,
+            dst_impl ? wined3d_surface_dst : NULL, DstRect, Flags, (WINEDDOVERLAYFX *)FX);
     wined3d_mutex_unlock();
 
     switch(hr) {
@@ -3834,13 +3906,23 @@ static HRESULT WINAPI ddraw_surface7_UpdateOverlayZOrder(IDirectDrawSurface7 *if
 {
     struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
     struct ddraw_surface *reference_impl = unsafe_impl_from_IDirectDrawSurface7(DDSRef);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface, *wined3d_surface_refimpl;
     HRESULT hr;
 
     TRACE("iface %p, flags %#x, reference %p.\n", iface, Flags, DDSRef);
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_update_overlay_z_order(surface->wined3d_surface,
-            Flags, reference_impl ? reference_impl->wined3d_surface : NULL);
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+
+    if (reference_impl)
+    {
+        sub_resource = wined3d_texture_get_sub_resource(reference_impl->wined3d_texture, reference_impl->sub_resource_idx);
+        wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    }
+    hr = wined3d_surface_update_overlay_z_order(wined3d_surface,
+            Flags, reference_impl ? wined3d_surface_refimpl : NULL);
     wined3d_mutex_unlock();
 
     return hr;
@@ -4100,6 +4182,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurfac
 {
     struct ddraw_surface *This = impl_from_IDirectDrawSurface7(iface);
     struct ddraw_surface *src = unsafe_impl_from_IDirectDrawSurface7(Source);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface, *wined3d_surface_src;
     DWORD src_w, src_h, dst_w, dst_h;
     HRESULT hr = DD_OK;
     DWORD flags = 0;
@@ -4153,8 +4237,14 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_BltFast(IDirectDrawSurfac
     if (src->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
         hr = ddraw_surface_update_frontbuffer(src, rsrc, TRUE);
     if (SUCCEEDED(hr))
-        hr = wined3d_surface_blt(This->wined3d_surface, &dst_rect,
-                src->wined3d_surface, rsrc, flags, NULL, WINED3D_TEXF_POINT);
+    {
+        sub_resource = wined3d_texture_get_sub_resource(This->wined3d_texture, This->sub_resource_idx);
+        wined3d_surface = wined3d_surface_from_resource(sub_resource);
+        sub_resource = wined3d_texture_get_sub_resource(src->wined3d_texture, src->sub_resource_idx);
+        wined3d_surface_src = wined3d_surface_from_resource(sub_resource);
+        hr = wined3d_surface_blt(wined3d_surface, &dst_rect,
+                wined3d_surface_src, rsrc, flags, NULL, WINED3D_TEXF_POINT);
+    }
     if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
         hr = ddraw_surface_update_frontbuffer(This, &dst_rect, FALSE);
     wined3d_mutex_unlock();
@@ -5101,8 +5191,7 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
         struct ddraw_palette *dst_pal, *src_pal;
         DDSURFACEDESC *src_desc, *dst_desc;
 
-        TRACE("Copying surface %p to surface %p (mipmap level %d).\n",
-                src_surface, dst_surface, src_surface->mipmap_level);
+        TRACE("Copying surface %p to surface %p.\n", src_surface, dst_surface);
 
         /* Suppress the ALLOCONLOAD flag */
         dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
@@ -5137,8 +5226,15 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
         }
         else
         {
+            struct wined3d_resource *sub_resource;
+            struct wined3d_surface *wined3d_surface_src, *wined3d_surface_dst;
             struct wined3d_map_desc src_map_desc, dst_map_desc;
 
+            sub_resource = wined3d_texture_get_sub_resource(src_surface->wined3d_texture, src_surface->sub_resource_idx);
+            wined3d_surface_src = wined3d_surface_from_resource(sub_resource);
+            sub_resource = wined3d_texture_get_sub_resource(dst_surface->wined3d_texture, dst_surface->sub_resource_idx);
+            wined3d_surface_dst = wined3d_surface_from_resource(sub_resource);
+
             /* Copy the src blit color key if the source has one, don't erase
              * the destination's ckey if the source has none */
             if (src_desc->dwFlags & DDSD_CKSRCBLT)
@@ -5150,7 +5246,7 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
             /* Copy the main memory texture into the surface that corresponds
              * to the OpenGL texture object. */
 
-            hr = wined3d_surface_map(src_surface->wined3d_surface, &src_map_desc, NULL, 0);
+            hr = wined3d_surface_map(wined3d_surface_src, &src_map_desc, NULL, 0);
             if (FAILED(hr))
             {
                 ERR("Failed to lock source surface, hr %#x.\n", hr);
@@ -5158,11 +5254,11 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
                 return D3DERR_TEXTURE_LOAD_FAILED;
             }
 
-            hr = wined3d_surface_map(dst_surface->wined3d_surface, &dst_map_desc, NULL, 0);
+            hr = wined3d_surface_map(wined3d_surface_dst, &dst_map_desc, NULL, 0);
             if (FAILED(hr))
             {
                 ERR("Failed to lock destination surface, hr %#x.\n", hr);
-                wined3d_surface_unmap(src_surface->wined3d_surface);
+                wined3d_surface_unmap(wined3d_surface_src);
                 wined3d_mutex_unlock();
                 return D3DERR_TEXTURE_LOAD_FAILED;
             }
@@ -5172,8 +5268,8 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu
             else
                 memcpy(dst_map_desc.data, src_map_desc.data, src_map_desc.row_pitch * src_desc->dwHeight);
 
-            wined3d_surface_unmap(src_surface->wined3d_surface);
-            wined3d_surface_unmap(dst_surface->wined3d_surface);
+            wined3d_surface_unmap(wined3d_surface_src);
+            wined3d_surface_unmap(wined3d_surface_dst);
         }
 
         if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
@@ -6228,9 +6324,12 @@ fail:
     return hr;
 }
 
-void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, struct ddraw_texture *texture,
-        struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops)
+void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw,
+        struct wined3d_surface *wined3d_surface,
+        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+        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;
@@ -6246,6 +6345,8 @@ void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, stru
     surface->iface_count = 1;
     surface->version = version;
     surface->ddraw = ddraw;
+    surface->wined3d_texture = wined3d_texture;
+    surface->sub_resource_idx = sub_resource_idx;
 
     if (version == 7)
     {
@@ -6288,7 +6389,6 @@ 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;
     *parent_ops = &ddraw_surface_wined3d_parent_ops;
 
     wined3d_private_store_init(&surface->private_store);
@@ -6317,12 +6417,17 @@ static const struct wined3d_parent_ops ddraw_view_wined3d_parent_ops =
 
 struct wined3d_rendertarget_view *ddraw_surface_get_rendertarget_view(struct ddraw_surface *surface)
 {
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     if (surface->wined3d_rtv)
         return surface->wined3d_rtv;
 
-    if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(surface->wined3d_surface,
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+
+    if (FAILED(hr = wined3d_rendertarget_view_create_from_surface(wined3d_surface,
             surface, &ddraw_view_wined3d_parent_ops, &surface->wined3d_rtv)))
     {
         ERR("Failed to create rendertarget view, hr %#x.\n", hr);
-- 
1.9.1




More information about the wine-patches mailing list