[PATCH 02/12] wined3d: store wined3d_texture and sub_resource_idx in d3dX surfaces

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


also removed the wined3d_surface member.
ddraw still needs wined3d_surface until I find a way to do a wined3d_resource_get_desc from within ddraw_surface_init
---
 dlls/d3d11/device.c      |   9 ++--
 dlls/d3d8/d3d8_private.h |   7 ++--
 dlls/d3d8/device.c       |  67 ++++++++++++++++++-----------
 dlls/d3d8/surface.c      |  48 +++++++++++++++------
 dlls/d3d9/d3d9_private.h |   8 ++--
 dlls/d3d9/device.c       |  64 +++++++++++++++++++---------
 dlls/d3d9/surface.c      | 107 +++++++++++++++++++++++++++++------------------
 dlls/d3d9/swapchain.c    |   6 ++-
 dlls/ddraw/ddraw.c       |  11 ++---
 dlls/wined3d/surface.c   |   2 +-
 include/wine/wined3d.h   |   5 ++-
 11 files changed, 217 insertions(+), 117 deletions(-)

diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 8e50918..c9fda88 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -2928,11 +2928,12 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa
 }
 
 static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
-        void *container_parent, struct wined3d_surface *surface, void **parent,
-        const struct wined3d_parent_ops **parent_ops)
+        struct wined3d_surface *surface,
+        struct wined3d_texture* wined3d_texture, unsigned int sub_resource_idx,
+        void **parent, const struct wined3d_parent_ops **parent_ops)
 {
-    TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n",
-            device_parent, container_parent, surface, parent, parent_ops);
+    TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
     *parent = NULL;
     *parent_ops = &d3d10_null_wined3d_parent_ops;
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index ab6a3d4..ce7a06a 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -227,7 +227,8 @@ struct d3d8_surface
 {
     IDirect3DSurface8 IDirect3DSurface8_iface;
     struct d3d8_resource resource;
-    struct wined3d_surface *wined3d_surface;
+    struct wined3d_texture *wined3d_texture;
+    unsigned int sub_resource_idx;
     struct list rtv_entry;
     struct wined3d_rendertarget_view *wined3d_rtv;
     IDirect3DDevice8 *parent_device;
@@ -236,8 +237,8 @@ struct d3d8_surface
 };
 
 struct wined3d_rendertarget_view *d3d8_surface_get_rendertarget_view(struct d3d8_surface *surface) DECLSPEC_HIDDEN;
-void surface_init(struct d3d8_surface *surface, IUnknown *container_parent,
-        struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
+void surface_init(struct d3d8_surface *surface, struct wined3d_texture *wined3d_texture,
+        unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
 struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) DECLSPEC_HIDDEN;
 
 struct d3d8_vertexbuffer
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index 0eebd8d..8f66ec2 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -520,6 +520,8 @@ static HRESULT WINAPI d3d8_device_SetCursorProperties(IDirect3DDevice8 *iface,
 {
     struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
     struct d3d8_surface *bitmap_impl = unsafe_impl_from_IDirect3DSurface8(bitmap);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p, hotspot_x %u, hotspot_y %u, bitmap %p.\n",
@@ -532,8 +534,10 @@ static HRESULT WINAPI d3d8_device_SetCursorProperties(IDirect3DDevice8 *iface,
     }
 
     wined3d_mutex_lock();
+    sub_resource = wined3d_texture_get_sub_resource(bitmap_impl->wined3d_texture, bitmap_impl->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
     hr = wined3d_device_set_cursor_properties(device->wined3d_device,
-            hotspot_x, hotspot_y, bitmap_impl->wined3d_surface);
+            hotspot_x, hotspot_y, wined3d_surface);
     wined3d_mutex_unlock();
 
     return hr;
@@ -981,6 +985,8 @@ static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width
     sub_resource = wined3d_texture_get_sub_resource(texture, 0);
     surface_impl = wined3d_resource_get_parent(sub_resource);
     surface_impl->parent_device = &device->IDirect3DDevice8_iface;
+    surface_impl->wined3d_texture = texture;
+    surface_impl->sub_resource_idx = 0;
     *surface = &surface_impl->IDirect3DSurface8_iface;
     IDirect3DSurface8_AddRef(*surface);
     wined3d_texture_decref(texture);
@@ -1047,7 +1053,8 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
     struct d3d8_surface *dst = unsafe_impl_from_IDirect3DSurface8(dst_surface);
     enum wined3d_format_id src_format, dst_format;
     struct wined3d_resource_desc wined3d_desc;
-    struct wined3d_resource *wined3d_resource;
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_dst_surface, *wined3d_src_surface;
     UINT src_w, src_h;
 
     TRACE("iface %p, src_surface %p, src_rects %p, rect_count %u, dst_surface %p, dst_points %p.\n",
@@ -1057,8 +1064,8 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
      * destination texture is in WINED3D_POOL_DEFAULT. */
 
     wined3d_mutex_lock();
-    wined3d_resource = wined3d_surface_get_resource(src->wined3d_surface);
-    wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+    sub_resource = wined3d_texture_get_sub_resource(src->wined3d_texture, src->sub_resource_idx);
+    wined3d_resource_get_desc(sub_resource, &wined3d_desc);
     if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
     {
         WARN("Source %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", src_surface);
@@ -1069,8 +1076,8 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
     src_w = wined3d_desc.width;
     src_h = wined3d_desc.height;
 
-    wined3d_resource = wined3d_surface_get_resource(dst->wined3d_surface);
-    wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+    sub_resource = wined3d_texture_get_sub_resource(dst->wined3d_texture, dst->sub_resource_idx);
+    wined3d_resource_get_desc(sub_resource, &wined3d_desc);
     if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
     {
         WARN("Destination %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", dst_surface);
@@ -1088,12 +1095,17 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
         return D3DERR_INVALIDCALL;
     }
 
+    sub_resource = wined3d_texture_get_sub_resource(dst->wined3d_texture, dst->sub_resource_idx);
+    wined3d_dst_surface = wined3d_surface_from_resource(sub_resource);
+    sub_resource = wined3d_texture_get_sub_resource(src->wined3d_texture, src->sub_resource_idx);
+    wined3d_src_surface = wined3d_surface_from_resource(sub_resource);
+
     /* Quick if complete copy ... */
     if (!rect_count && !src_rects && !dst_points)
     {
         RECT rect = {0, 0, src_w, src_h};
-        wined3d_surface_blt(dst->wined3d_surface, &rect,
-                src->wined3d_surface, &rect, 0, NULL, WINED3D_TEXF_POINT);
+        wined3d_surface_blt(wined3d_dst_surface, &rect,
+                wined3d_src_surface, &rect, 0, NULL, WINED3D_TEXF_POINT);
     }
     else
     {
@@ -1108,8 +1120,8 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
                 RECT dst_rect = {dst_points[i].x, dst_points[i].y,
                         dst_points[i].x + w, dst_points[i].y + h};
 
-                wined3d_surface_blt(dst->wined3d_surface, &dst_rect,
-                        src->wined3d_surface, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
+                wined3d_surface_blt(wined3d_dst_surface, &dst_rect,
+                        wined3d_src_surface, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
             }
         }
         else
@@ -1120,8 +1132,8 @@ static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
                 UINT h = src_rects[i].bottom - src_rects[i].top;
                 RECT dst_rect = {0, 0, w, h};
 
-                wined3d_surface_blt(dst->wined3d_surface, &dst_rect,
-                        src->wined3d_surface, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
+                wined3d_surface_blt(wined3d_dst_surface, &dst_rect,
+                        wined3d_src_surface, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
             }
         }
     }
@@ -1154,6 +1166,8 @@ static HRESULT WINAPI d3d8_device_GetFrontBuffer(IDirect3DDevice8 *iface, IDirec
 {
     struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
     struct d3d8_surface *dst_impl = unsafe_impl_from_IDirect3DSurface8(dst_surface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p, dst_surface %p.\n", iface, dst_surface);
@@ -1165,7 +1179,9 @@ static HRESULT WINAPI d3d8_device_GetFrontBuffer(IDirect3DDevice8 *iface, IDirec
     }
 
     wined3d_mutex_lock();
-    hr = wined3d_device_get_front_buffer_data(device->wined3d_device, 0, dst_impl->wined3d_surface);
+    sub_resource = wined3d_texture_get_sub_resource(dst_impl->wined3d_texture, dst_impl->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_device_get_front_buffer_data(device->wined3d_device, 0, wined3d_surface);
     wined3d_mutex_unlock();
 
     return hr;
@@ -1188,7 +1204,7 @@ static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface,
     {
         struct wined3d_rendertarget_view *original_rtv;
         struct wined3d_resource_desc ds_desc, rt_desc;
-        struct wined3d_resource *wined3d_resource;
+        struct wined3d_resource *sub_resource;
         struct d3d8_surface *original_surface;
 
         /* If no render target is passed in check the size against the current RT */
@@ -1201,14 +1217,14 @@ static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface,
                 return D3DERR_NOTFOUND;
             }
             original_surface = wined3d_rendertarget_view_get_sub_resource_parent(original_rtv);
-            wined3d_resource = wined3d_surface_get_resource(original_surface->wined3d_surface);
+            sub_resource = wined3d_texture_get_sub_resource(original_surface->wined3d_texture, original_surface->sub_resource_idx);
         }
         else
-            wined3d_resource = wined3d_surface_get_resource(rt_impl->wined3d_surface);
-        wined3d_resource_get_desc(wined3d_resource, &rt_desc);
+            sub_resource = wined3d_texture_get_sub_resource(rt_impl->wined3d_texture, rt_impl->sub_resource_idx);
+        wined3d_resource_get_desc(sub_resource, &rt_desc);
 
-        wined3d_resource = wined3d_surface_get_resource(ds_impl->wined3d_surface);
-        wined3d_resource_get_desc(wined3d_resource, &ds_desc);
+        sub_resource = wined3d_texture_get_sub_resource(ds_impl->wined3d_texture, ds_impl->sub_resource_idx);
+        wined3d_resource_get_desc(sub_resource, &ds_desc);
 
         if (ds_desc.width < rt_desc.width || ds_desc.height < rt_desc.height)
         {
@@ -2998,18 +3014,19 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa
 }
 
 static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
-        void *container_parent, struct wined3d_surface *surface, void **parent,
-        const struct wined3d_parent_ops **parent_ops)
+        struct wined3d_surface *wined3d_surface,
+        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+        void **parent, const struct wined3d_parent_ops **parent_ops)
 {
     struct d3d8_surface *d3d_surface;
 
-    TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n",
-            device_parent, container_parent, surface, parent, parent_ops);
+    TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
     if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface))))
         return E_OUTOFMEMORY;
 
-    surface_init(d3d_surface, container_parent, surface, parent_ops);
+    surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
     *parent = d3d_surface;
     TRACE("Created surface %p.\n", d3d_surface);
 
@@ -3022,7 +3039,7 @@ static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *
 {
     struct d3d8_volume *d3d_volume;
 
-    TRACE("device_parent %p, texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+    TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
             device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
     if (!(d3d_volume = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_volume))))
diff --git a/dlls/d3d8/surface.c b/dlls/d3d8/surface.c
index 7779a56..0ed2dd2 100644
--- a/dlls/d3d8/surface.c
+++ b/dlls/d3d8/surface.c
@@ -50,6 +50,8 @@ static HRESULT WINAPI d3d8_surface_QueryInterface(IDirect3DSurface8 *iface, REFI
 static ULONG WINAPI d3d8_surface_AddRef(IDirect3DSurface8 *iface)
 {
     struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     ULONG refcount;
 
     TRACE("iface %p.\n", iface);
@@ -70,7 +72,9 @@ static ULONG WINAPI d3d8_surface_AddRef(IDirect3DSurface8 *iface)
         wined3d_mutex_lock();
         if (surface->wined3d_rtv)
             wined3d_rendertarget_view_incref(surface->wined3d_rtv);
-        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);
+        wined3d_surface_incref(wined3d_surface);
         wined3d_mutex_unlock();
     }
 
@@ -80,6 +84,8 @@ static ULONG WINAPI d3d8_surface_AddRef(IDirect3DSurface8 *iface)
 static ULONG WINAPI d3d8_surface_Release(IDirect3DSurface8 *iface)
 {
     struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     ULONG refcount;
 
     TRACE("iface %p.\n", iface);
@@ -100,7 +106,9 @@ static ULONG WINAPI d3d8_surface_Release(IDirect3DSurface8 *iface)
         wined3d_mutex_lock();
         if (surface->wined3d_rtv)
             wined3d_rendertarget_view_decref(surface->wined3d_rtv);
-        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);
+        wined3d_surface_decref(wined3d_surface);
         wined3d_mutex_unlock();
 
         if (parent_device)
@@ -176,13 +184,13 @@ static HRESULT WINAPI d3d8_surface_GetDesc(IDirect3DSurface8 *iface, D3DSURFACE_
 {
     struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
     struct wined3d_resource_desc wined3d_desc;
-    struct wined3d_resource *wined3d_resource;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, desc %p.\n", iface, desc);
 
     wined3d_mutex_lock();
-    wined3d_resource = wined3d_surface_get_resource(surface->wined3d_surface);
-    wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_resource_get_desc(sub_resource, &wined3d_desc);
     wined3d_mutex_unlock();
 
     desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
@@ -201,6 +209,8 @@ static HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface,
         D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
 {
     struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     struct wined3d_map_desc map_desc;
     HRESULT hr;
 
@@ -227,7 +237,9 @@ static HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface,
         }
     }
 
-    hr = wined3d_surface_map(surface->wined3d_surface, &map_desc, rect, flags);
+    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_map(wined3d_surface, &map_desc, rect, flags);
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
@@ -247,12 +259,16 @@ static HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface,
 static HRESULT WINAPI d3d8_surface_UnlockRect(IDirect3DSurface8 *iface)
 {
     struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p.\n", iface);
 
     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);
     wined3d_mutex_unlock();
 
     switch(hr)
@@ -292,19 +308,20 @@ static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops =
     surface_wined3d_object_destroyed,
 };
 
-void surface_init(struct d3d8_surface *surface, IUnknown *container_parent,
-        struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops)
+void surface_init(struct d3d8_surface *surface, struct wined3d_texture *wined3d_texture,
+        unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops)
 {
     IDirect3DBaseTexture8 *texture;
 
     surface->IDirect3DSurface8_iface.lpVtbl = &d3d8_surface_vtbl;
     d3d8_resource_init(&surface->resource);
     surface->resource.refcount = 0;
-    surface->wined3d_surface = wined3d_surface;
     list_init(&surface->rtv_entry);
-    surface->container = container_parent;
+    surface->container = wined3d_texture_get_parent(wined3d_texture);
+    surface->wined3d_texture = wined3d_texture;
+    surface->sub_resource_idx = sub_resource_idx;
 
-    if (container_parent && SUCCEEDED(IUnknown_QueryInterface(container_parent,
+    if (surface->container && SUCCEEDED(IUnknown_QueryInterface(surface->container,
             &IID_IDirect3DBaseTexture8, (void **)&texture)))
     {
         surface->texture = unsafe_impl_from_IDirect3DBaseTexture8(texture);
@@ -338,12 +355,17 @@ static const struct wined3d_parent_ops d3d8_view_wined3d_parent_ops =
 
 struct wined3d_rendertarget_view *d3d8_surface_get_rendertarget_view(struct d3d8_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, &d3d8_view_wined3d_parent_ops, &surface->wined3d_rtv)))
     {
         ERR("Failed to create rendertarget view, hr %#x.\n", hr);
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index ea0d3e6..bdf3b09 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -214,18 +214,18 @@ struct d3d9_surface
 {
     IDirect3DSurface9 IDirect3DSurface9_iface;
     struct d3d9_resource resource;
-    struct wined3d_surface *wined3d_surface;
+    struct wined3d_texture *wined3d_texture;
+    unsigned int sub_resource_idx;
     struct list rtv_entry;
     struct wined3d_rendertarget_view *wined3d_rtv;
     IDirect3DDevice9Ex *parent_device;
     IUnknown *container;
     struct d3d9_texture *texture;
-    BOOL getdc_supported;
 };
 
 struct wined3d_rendertarget_view *d3d9_surface_get_rendertarget_view(struct d3d9_surface *surface) DECLSPEC_HIDDEN;
-void surface_init(struct d3d9_surface *surface, IUnknown *container_parent,
-        struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
+void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture,
+        unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
 struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface) DECLSPEC_HIDDEN;
 
 struct d3d9_vertexbuffer
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 608c341..a8443f6 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -471,6 +471,8 @@ static HRESULT WINAPI d3d9_device_SetCursorProperties(IDirect3DDevice9Ex *iface,
 {
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
     struct d3d9_surface *bitmap_impl = unsafe_impl_from_IDirect3DSurface9(bitmap);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p, hotspot_x %u, hotspot_y %u, bitmap %p.\n",
@@ -483,8 +485,10 @@ static HRESULT WINAPI d3d9_device_SetCursorProperties(IDirect3DDevice9Ex *iface,
     }
 
     wined3d_mutex_lock();
+    sub_resource = wined3d_texture_get_sub_resource(bitmap_impl->wined3d_texture, bitmap_impl->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
     hr = wined3d_device_set_cursor_properties(device->wined3d_device,
-            hotspot_x, hotspot_y, bitmap_impl->wined3d_surface);
+            hotspot_x, hotspot_y, wined3d_surface);
     wined3d_mutex_unlock();
 
     return hr;
@@ -1121,6 +1125,8 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width
     sub_resource = wined3d_texture_get_sub_resource(texture, 0);
     surface_impl = wined3d_resource_get_parent(sub_resource);
     surface_impl->parent_device = &device->IDirect3DDevice9Ex_iface;
+    surface_impl->wined3d_texture = texture;
+    surface_impl->sub_resource_idx = 0;
     *surface = &surface_impl->IDirect3DSurface9_iface;
     IDirect3DSurface9_AddRef(*surface);
 
@@ -1205,14 +1211,20 @@ static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex *iface,
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
     struct d3d9_surface *src = unsafe_impl_from_IDirect3DSurface9(src_surface);
     struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(dst_surface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_dst_surface, *wined3d_src_surface;
     HRESULT hr;
 
     TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_point %p.\n",
             iface, src_surface, src_rect, dst_surface, dst_point);
 
     wined3d_mutex_lock();
-    hr = wined3d_device_update_surface(device->wined3d_device, src->wined3d_surface, src_rect,
-            dst->wined3d_surface, dst_point);
+    sub_resource = wined3d_texture_get_sub_resource(src->wined3d_texture, src->sub_resource_idx);
+    wined3d_src_surface = wined3d_surface_from_resource(sub_resource);
+    sub_resource = wined3d_texture_get_sub_resource(dst->wined3d_texture, dst->sub_resource_idx);
+    wined3d_dst_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_device_update_surface(device->wined3d_device, wined3d_src_surface, src_rect,
+            wined3d_dst_surface, dst_point);
     wined3d_mutex_unlock();
 
     return hr;
@@ -1243,12 +1255,18 @@ static HRESULT WINAPI d3d9_device_GetRenderTargetData(IDirect3DDevice9Ex *iface,
 {
     struct d3d9_surface *rt_impl = unsafe_impl_from_IDirect3DSurface9(render_target);
     struct d3d9_surface *dst_impl = unsafe_impl_from_IDirect3DSurface9(dst_surface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_dst_surface, *wined3d_rt_surface;
     HRESULT hr;
 
     TRACE("iface %p, render_target %p, dst_surface %p.\n", iface, render_target, dst_surface);
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_get_render_target_data(dst_impl->wined3d_surface, rt_impl->wined3d_surface);
+    sub_resource = wined3d_texture_get_sub_resource(rt_impl->wined3d_texture, rt_impl->sub_resource_idx);
+    wined3d_rt_surface = wined3d_surface_from_resource(sub_resource);
+    sub_resource = wined3d_texture_get_sub_resource(dst_impl->wined3d_texture, dst_impl->sub_resource_idx);
+    wined3d_dst_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_surface_get_render_target_data(wined3d_dst_surface, wined3d_rt_surface);
     wined3d_mutex_unlock();
 
     return hr;
@@ -1259,12 +1277,16 @@ static HRESULT WINAPI d3d9_device_GetFrontBufferData(IDirect3DDevice9Ex *iface,
 {
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
     struct d3d9_surface *dst_impl = unsafe_impl_from_IDirect3DSurface9(dst_surface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_dst_surface;
     HRESULT hr;
 
     TRACE("iface %p, swapchain %u, dst_surface %p.\n", iface, swapchain, dst_surface);
 
     wined3d_mutex_lock();
-    hr = wined3d_device_get_front_buffer_data(device->wined3d_device, swapchain, dst_impl->wined3d_surface);
+    sub_resource = wined3d_texture_get_sub_resource(dst_impl->wined3d_texture, dst_impl->sub_resource_idx);
+    wined3d_dst_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_device_get_front_buffer_data(device->wined3d_device, swapchain, wined3d_dst_surface);
     wined3d_mutex_unlock();
 
     return hr;
@@ -1278,17 +1300,20 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect
     struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(dst_surface);
     HRESULT hr = D3DERR_INVALIDCALL;
     struct wined3d_resource_desc src_desc, dst_desc;
-    struct wined3d_resource *wined3d_resource;
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_dst_surface, *wined3d_src_surface;
 
     TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n",
             iface, src_surface, src_rect, dst_surface, dst_rect, filter);
 
     wined3d_mutex_lock();
-    wined3d_resource = wined3d_surface_get_resource(dst->wined3d_surface);
-    wined3d_resource_get_desc(wined3d_resource, &dst_desc);
+    sub_resource = wined3d_texture_get_sub_resource(dst->wined3d_texture, dst->sub_resource_idx);
+    wined3d_dst_surface = wined3d_surface_from_resource(sub_resource);
+    wined3d_resource_get_desc(sub_resource, &dst_desc);
 
-    wined3d_resource = wined3d_surface_get_resource(src->wined3d_surface);
-    wined3d_resource_get_desc(wined3d_resource, &src_desc);
+    sub_resource = wined3d_texture_get_sub_resource(src->wined3d_texture, src->sub_resource_idx);
+    wined3d_src_surface = wined3d_surface_from_resource(sub_resource);
+    wined3d_resource_get_desc(sub_resource, &src_desc);
 
     if (src_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
     {
@@ -1325,7 +1350,7 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect
         }
     }
 
-    hr = wined3d_surface_blt(dst->wined3d_surface, dst_rect, src->wined3d_surface, src_rect, 0, NULL, filter);
+    hr = wined3d_surface_blt(wined3d_dst_surface, dst_rect, wined3d_src_surface, src_rect, 0, NULL, filter);
     if (hr == WINEDDERR_INVALIDRECT)
         hr = D3DERR_INVALIDCALL;
 
@@ -1346,7 +1371,7 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface,
     };
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
     struct d3d9_surface *surface_impl = unsafe_impl_from_IDirect3DSurface9(surface);
-    struct wined3d_resource *wined3d_resource;
+    struct wined3d_resource *sub_resource;
     struct wined3d_resource_desc desc;
     HRESULT hr;
 
@@ -1354,8 +1379,8 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface,
 
     wined3d_mutex_lock();
 
-    wined3d_resource = wined3d_surface_get_resource(surface_impl->wined3d_surface);
-    wined3d_resource_get_desc(wined3d_resource, &desc);
+    sub_resource = wined3d_texture_get_sub_resource(surface_impl->wined3d_texture, surface_impl->sub_resource_idx);
+    wined3d_resource_get_desc(sub_resource, &desc);
 
     if (desc.pool != WINED3D_POOL_DEFAULT)
     {
@@ -3534,18 +3559,19 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa
 }
 
 static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
-        void *container_parent, struct wined3d_surface *surface, void **parent,
-        const struct wined3d_parent_ops **parent_ops)
+        struct wined3d_surface *wined3d_surface,
+        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
+        void **parent, const struct wined3d_parent_ops **parent_ops)
 {
     struct d3d9_surface *d3d_surface;
 
-    TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n",
-            device_parent, container_parent, surface, parent, parent_ops);
+    TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
     if (!(d3d_surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d3d_surface))))
         return E_OUTOFMEMORY;
 
-    surface_init(d3d_surface, container_parent, surface, parent_ops);
+    surface_init(d3d_surface, wined3d_texture, sub_resource_idx, parent_ops);
     *parent = d3d_surface;
     TRACE("Created surface %p.\n", d3d_surface);
 
diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c
index e5eb11f..859ab88 100644
--- a/dlls/d3d9/surface.c
+++ b/dlls/d3d9/surface.c
@@ -51,6 +51,8 @@ static HRESULT WINAPI d3d9_surface_QueryInterface(IDirect3DSurface9 *iface, REFI
 static ULONG WINAPI d3d9_surface_AddRef(IDirect3DSurface9 *iface)
 {
     struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     ULONG refcount;
 
     TRACE("iface %p.\n", iface);
@@ -71,7 +73,9 @@ static ULONG WINAPI d3d9_surface_AddRef(IDirect3DSurface9 *iface)
         wined3d_mutex_lock();
         if (surface->wined3d_rtv)
             wined3d_rendertarget_view_incref(surface->wined3d_rtv);
-        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);
+        wined3d_surface_incref(wined3d_surface);
         wined3d_mutex_unlock();
     }
 
@@ -81,6 +85,8 @@ static ULONG WINAPI d3d9_surface_AddRef(IDirect3DSurface9 *iface)
 static ULONG WINAPI d3d9_surface_Release(IDirect3DSurface9 *iface)
 {
     struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     ULONG refcount;
 
     TRACE("iface %p.\n", iface);
@@ -101,7 +107,9 @@ static ULONG WINAPI d3d9_surface_Release(IDirect3DSurface9 *iface)
         wined3d_mutex_lock();
         if (surface->wined3d_rtv)
             wined3d_rendertarget_view_decref(surface->wined3d_rtv);
-        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);
+        wined3d_surface_decref(wined3d_surface);
         wined3d_mutex_unlock();
 
         /* Release the device last, as it may cause the device to be destroyed. */
@@ -172,11 +180,15 @@ static DWORD WINAPI d3d9_surface_GetPriority(IDirect3DSurface9 *iface)
 static void WINAPI d3d9_surface_PreLoad(IDirect3DSurface9 *iface)
 {
     struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
 
     TRACE("iface %p.\n", iface);
 
     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();
 }
 
@@ -208,13 +220,13 @@ static HRESULT WINAPI d3d9_surface_GetDesc(IDirect3DSurface9 *iface, D3DSURFACE_
 {
     struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
     struct wined3d_resource_desc wined3d_desc;
-    struct wined3d_resource *wined3d_resource;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, desc %p.\n", iface, desc);
 
     wined3d_mutex_lock();
-    wined3d_resource = wined3d_surface_get_resource(surface->wined3d_surface);
-    wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_resource_get_desc(sub_resource, &wined3d_desc);
     wined3d_mutex_unlock();
 
     desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
@@ -233,6 +245,8 @@ static HRESULT WINAPI d3d9_surface_LockRect(IDirect3DSurface9 *iface,
         D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
 {
     struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     struct wined3d_map_desc map_desc;
     HRESULT hr;
 
@@ -240,7 +254,9 @@ static HRESULT WINAPI d3d9_surface_LockRect(IDirect3DSurface9 *iface,
             iface, locked_rect, wine_dbgstr_rect(rect), flags);
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_map(surface->wined3d_surface, &map_desc, rect, flags);
+    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_map(wined3d_surface, &map_desc, rect, flags);
     wined3d_mutex_unlock();
 
     if (SUCCEEDED(hr))
@@ -255,12 +271,16 @@ static HRESULT WINAPI d3d9_surface_LockRect(IDirect3DSurface9 *iface,
 static HRESULT WINAPI d3d9_surface_UnlockRect(IDirect3DSurface9 *iface)
 {
     struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p.\n", iface);
 
     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);
     wined3d_mutex_unlock();
 
     switch(hr)
@@ -273,19 +293,34 @@ static HRESULT WINAPI d3d9_surface_UnlockRect(IDirect3DSurface9 *iface)
 static HRESULT WINAPI d3d9_surface_GetDC(IDirect3DSurface9 *iface, HDC *dc)
 {
     struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
+    struct wined3d_resource_desc desc;
     HRESULT hr;
 
     TRACE("iface %p, dc %p.\n", iface, dc);
 
-    if (!surface->getdc_supported)
+    wined3d_mutex_lock();
+    sub_resource = wined3d_texture_get_sub_resource(surface->wined3d_texture, surface->sub_resource_idx);
+    wined3d_resource_get_desc(sub_resource, &desc);
+    switch (d3dformat_from_wined3dformat(desc.format))
     {
-        WARN("Surface does not support GetDC, returning D3DERR_INVALIDCALL\n");
-        /* Don't touch the DC */
-        return D3DERR_INVALIDCALL;
-    }
+        case D3DFMT_A8R8G8B8:
+        case D3DFMT_X8R8G8B8:
+        case D3DFMT_R5G6B5:
+        case D3DFMT_X1R5G5B5:
+        case D3DFMT_A1R5G5B5:
+        case D3DFMT_R8G8B8:
+            break;
 
-    wined3d_mutex_lock();
-    hr = wined3d_surface_getdc(surface->wined3d_surface, dc);
+        default:
+            WARN("Surface does not support GetDC, returning D3DERR_INVALIDCALL\n");
+            /* Don't touch the DC */
+            wined3d_mutex_unlock();
+            return D3DERR_INVALIDCALL;
+    }
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_surface_getdc(wined3d_surface, dc);
     wined3d_mutex_unlock();
 
     return hr;
@@ -294,12 +329,16 @@ static HRESULT WINAPI d3d9_surface_GetDC(IDirect3DSurface9 *iface, HDC *dc)
 static HRESULT WINAPI d3d9_surface_ReleaseDC(IDirect3DSurface9 *iface, HDC dc)
 {
     struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p, dc %p.\n", iface, dc);
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_releasedc(surface->wined3d_surface, dc);
+    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, dc);
     wined3d_mutex_unlock();
 
     switch (hr)
@@ -345,43 +384,26 @@ static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops =
     surface_wined3d_object_destroyed,
 };
 
-void surface_init(struct d3d9_surface *surface, IUnknown *container_parent,
-        struct wined3d_surface *wined3d_surface, const struct wined3d_parent_ops **parent_ops)
+void surface_init(struct d3d9_surface *surface, struct wined3d_texture *wined3d_texture,
+        unsigned int sub_resource_idx, const struct wined3d_parent_ops **parent_ops)
 {
-    struct wined3d_resource_desc desc;
     IDirect3DBaseTexture9 *texture;
 
     surface->IDirect3DSurface9_iface.lpVtbl = &d3d9_surface_vtbl;
     d3d9_resource_init(&surface->resource);
     surface->resource.refcount = 0;
-    surface->wined3d_surface = wined3d_surface;
     list_init(&surface->rtv_entry);
-    surface->container = container_parent;
+    surface->container = wined3d_texture_get_parent(wined3d_texture);
+    surface->wined3d_texture = wined3d_texture;
+    surface->sub_resource_idx = sub_resource_idx;
 
-    if (container_parent && SUCCEEDED(IUnknown_QueryInterface(container_parent,
+    if (surface->container && SUCCEEDED(IUnknown_QueryInterface(surface->container,
             &IID_IDirect3DBaseTexture9, (void **)&texture)))
     {
         surface->texture = unsafe_impl_from_IDirect3DBaseTexture9(texture);
         IDirect3DBaseTexture9_Release(texture);
     }
 
-    wined3d_resource_get_desc(wined3d_surface_get_resource(wined3d_surface), &desc);
-    switch (d3dformat_from_wined3dformat(desc.format))
-    {
-        case D3DFMT_A8R8G8B8:
-        case D3DFMT_X8R8G8B8:
-        case D3DFMT_R5G6B5:
-        case D3DFMT_X1R5G5B5:
-        case D3DFMT_A1R5G5B5:
-        case D3DFMT_R8G8B8:
-            surface->getdc_supported = TRUE;
-            break;
-
-        default:
-            surface->getdc_supported = FALSE;
-            break;
-    }
-
     *parent_ops = &d3d9_surface_wined3d_parent_ops;
 }
 
@@ -409,12 +431,17 @@ static const struct wined3d_parent_ops d3d9_view_wined3d_parent_ops =
 
 struct wined3d_rendertarget_view *d3d9_surface_get_rendertarget_view(struct d3d9_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, &d3d9_view_wined3d_parent_ops, &surface->wined3d_rtv)))
     {
         ERR("Failed to create rendertarget view, hr %#x.\n", hr);
diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c
index c995afb..8a1a752 100644
--- a/dlls/d3d9/swapchain.c
+++ b/dlls/d3d9/swapchain.c
@@ -137,12 +137,16 @@ static HRESULT WINAPI d3d9_swapchain_GetFrontBufferData(IDirect3DSwapChain9Ex *i
 {
     struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface);
     struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(surface);
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
     HRESULT hr;
 
     TRACE("iface %p, surface %p.\n", iface, surface);
 
     wined3d_mutex_lock();
-    hr = wined3d_swapchain_get_front_buffer_data(swapchain->wined3d_swapchain, dst->wined3d_surface);
+    sub_resource = wined3d_texture_get_sub_resource(dst->wined3d_texture, dst->sub_resource_idx);
+    wined3d_surface = wined3d_surface_from_resource(sub_resource);
+    hr = wined3d_swapchain_get_front_buffer_data(swapchain->wined3d_swapchain, wined3d_surface);
     wined3d_mutex_unlock();
 
     return hr;
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 0aaccd8..c121780 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -4712,17 +4712,18 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa
 }
 
 static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent *device_parent,
-        void *container_parent, struct wined3d_surface *surface,
+        struct wined3d_surface *surface,
+        struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
         void **parent, const struct wined3d_parent_ops **parent_ops)
 {
     struct ddraw *ddraw = ddraw_from_device_parent(device_parent);
     struct ddraw_surface *ddraw_surface;
 
-    TRACE("device_parent %p, container_parent %p, surface %p, parent %p, parent_ops %p.\n",
-            device_parent, container_parent, surface, parent, parent_ops);
+    TRACE("device_parent %p, wined3d_texture %p, sub_resource_idx %u, parent %p, parent_ops %p.\n",
+            device_parent, wined3d_texture, sub_resource_idx, parent, parent_ops);
 
     /* We have a swapchain or wined3d internal texture. */
-    if (!container_parent || container_parent == ddraw)
+    if (!wined3d_texture_get_parent(wined3d_texture) || wined3d_texture_get_parent(wined3d_texture) == ddraw)
     {
         *parent = NULL;
         *parent_ops = &ddraw_null_wined3d_parent_ops;
@@ -4736,7 +4737,7 @@ static HRESULT CDECL device_parent_surface_created(struct wined3d_device_parent
         return DDERR_OUTOFVIDEOMEMORY;
     }
 
-    ddraw_surface_init(ddraw_surface, ddraw, container_parent, surface, parent_ops);
+    ddraw_surface_init(ddraw_surface, ddraw, wined3d_texture_get_parent(wined3d_texture), surface, parent_ops);
     *parent = ddraw_surface;
     list_add_head(&ddraw->surface_list, &ddraw_surface->surface_list_entry);
 
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 999423d..8cbf44a 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -5413,7 +5413,7 @@ HRESULT wined3d_surface_create(struct wined3d_texture *container, const struct w
     }
 
     if (FAILED(hr = device_parent->ops->surface_created(device_parent,
-            wined3d_texture_get_parent(container), object, &parent, &parent_ops)))
+            object, container, layer * container->level_count + level, &parent, &parent_ops)))
     {
         WARN("Failed to create surface parent, hr %#x.\n", hr);
         wined3d_surface_destroy(object);
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 995f31f..82d47ad 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2030,8 +2030,9 @@ struct wined3d_device_parent_ops
     void (__cdecl *wined3d_device_created)(struct wined3d_device_parent *device_parent, struct wined3d_device *device);
     void (__cdecl *mode_changed)(struct wined3d_device_parent *device_parent);
     void (__cdecl *activate)(struct wined3d_device_parent *device_parent, BOOL activate);
-    HRESULT (__cdecl *surface_created)(struct wined3d_device_parent *device_parent, void *container_parent,
-            struct wined3d_surface *surface, void **parent, const struct wined3d_parent_ops **parent_ops);
+    HRESULT (__cdecl *surface_created)(struct wined3d_device_parent *device_parent, struct wined3d_surface *wined3d_surface,
+            struct wined3d_texture *texture, unsigned int sub_resource_idx,
+            void **parent, const struct wined3d_parent_ops **parent_ops);
     HRESULT (__cdecl *volume_created)(struct wined3d_device_parent *device_parent,
             struct wined3d_texture *texture, unsigned int sub_resource_idx,
             void **parent, const struct wined3d_parent_ops **parent_ops);
-- 
1.9.1




More information about the wine-patches mailing list