[AMSTREAM] We don't need to define WIDL_C_INLINE_WRAPPERS here anymore.
[reactos.git] / dll / directx / wine / d3d9 / texture.c
index 2cddc57..5e9979a 100644 (file)
 
 static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface)
 {
-    return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
+    return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
 }
 
 static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface)
 {
-    return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
+    return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
 }
 
 static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
 {
-    return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
+    return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
 }
 
 static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out)
@@ -58,14 +58,20 @@ static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, R
 static ULONG WINAPI d3d9_texture_2d_AddRef(IDirect3DTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-    ULONG ref = InterlockedIncrement(&texture->refcount);
+    ULONG ref = InterlockedIncrement(&texture->resource.refcount);
 
     TRACE("%p increasing refcount to %u.\n", iface, ref);
 
     if (ref == 1)
     {
+        struct d3d9_surface *surface;
+
         IDirect3DDevice9Ex_AddRef(texture->parent_device);
         wined3d_mutex_lock();
+        LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
+        {
+            wined3d_rendertarget_view_incref(surface->wined3d_rtv);
+        }
         wined3d_texture_incref(texture->wined3d_texture);
         wined3d_mutex_unlock();
     }
@@ -76,15 +82,20 @@ static ULONG WINAPI d3d9_texture_2d_AddRef(IDirect3DTexture9 *iface)
 static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-    ULONG ref = InterlockedDecrement(&texture->refcount);
+    ULONG ref = InterlockedDecrement(&texture->resource.refcount);
 
     TRACE("%p decreasing refcount to %u.\n", iface, ref);
 
     if (!ref)
     {
         IDirect3DDevice9Ex *parent_device = texture->parent_device;
+        struct d3d9_surface *surface;
 
         wined3d_mutex_lock();
+        LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
+        {
+            wined3d_rendertarget_view_decref(surface->wined3d_rtv);
+        }
         wined3d_texture_decref(texture->wined3d_texture);
         wined3d_mutex_unlock();
 
@@ -112,63 +123,41 @@ static HRESULT WINAPI d3d9_texture_2d_SetPrivateData(IDirect3DTexture9 *iface,
         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-    struct wined3d_resource *resource;
-    HRESULT hr;
-
     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
             iface, debugstr_guid(guid), data, data_size, flags);
 
-    wined3d_mutex_lock();
-    resource = wined3d_texture_get_resource(texture->wined3d_texture);
-    hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
-    wined3d_mutex_unlock();
-
-    return hr;
+    return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
 }
 
 static HRESULT WINAPI d3d9_texture_2d_GetPrivateData(IDirect3DTexture9 *iface,
         REFGUID guid, void *data, DWORD *data_size)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-    struct wined3d_resource *resource;
-    HRESULT hr;
-
     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
             iface, debugstr_guid(guid), data, data_size);
 
-    wined3d_mutex_lock();
-    resource = wined3d_texture_get_resource(texture->wined3d_texture);
-    hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
-    wined3d_mutex_unlock();
-
-    return hr;
+    return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
 }
 
 static HRESULT WINAPI d3d9_texture_2d_FreePrivateData(IDirect3DTexture9 *iface, REFGUID guid)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-    struct wined3d_resource *resource;
-    HRESULT hr;
-
     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
 
-    wined3d_mutex_lock();
-    resource = wined3d_texture_get_resource(texture->wined3d_texture);
-    hr = wined3d_resource_free_private_data(resource, guid);
-    wined3d_mutex_unlock();
-
-    return hr;
+    return d3d9_resource_free_private_data(&texture->resource, guid);
 }
 
 static DWORD WINAPI d3d9_texture_2d_SetPriority(IDirect3DTexture9 *iface, DWORD priority)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+    struct wined3d_resource *resource;
     DWORD ret;
 
     TRACE("iface %p, priority %u.\n", iface, priority);
 
     wined3d_mutex_lock();
-    ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
+    resource = wined3d_texture_get_resource(texture->wined3d_texture);
+    ret = wined3d_resource_set_priority(resource, priority);
     wined3d_mutex_unlock();
 
     return ret;
@@ -177,12 +166,14 @@ static DWORD WINAPI d3d9_texture_2d_SetPriority(IDirect3DTexture9 *iface, DWORD
 static DWORD WINAPI d3d9_texture_2d_GetPriority(IDirect3DTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+    const struct wined3d_resource *resource;
     DWORD ret;
 
     TRACE("iface %p.\n", iface);
 
     wined3d_mutex_lock();
-    ret = wined3d_texture_get_priority(texture->wined3d_texture);
+    resource = wined3d_texture_get_resource(texture->wined3d_texture);
+    ret = wined3d_resource_get_priority(resource);
     wined3d_mutex_unlock();
 
     return ret;
@@ -195,7 +186,7 @@ static void WINAPI d3d9_texture_2d_PreLoad(IDirect3DTexture9 *iface)
     TRACE("iface %p.\n", iface);
 
     wined3d_mutex_lock();
-    wined3d_texture_preload(texture->wined3d_texture);
+    wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
     wined3d_mutex_unlock();
 }
 
@@ -291,21 +282,16 @@ static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface
 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-    struct wined3d_resource *sub_resource;
-    HRESULT hr = D3D_OK;
+    struct wined3d_sub_resource_desc wined3d_desc;
+    HRESULT hr;
 
     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
 
     wined3d_mutex_lock();
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
-        hr = D3DERR_INVALIDCALL;
-    else
+    if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
     {
-        struct wined3d_resource_desc wined3d_desc;
-
-        wined3d_resource_get_desc(sub_resource, &wined3d_desc);
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
-        desc->Type = wined3d_desc.resource_type;
+        desc->Type = D3DRTYPE_SURFACE;
         desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
         desc->Pool = wined3d_desc.pool;
         desc->MultiSampleType = wined3d_desc.multisample_type;
@@ -322,19 +308,17 @@ static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
         UINT level, IDirect3DSurface9 **surface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-    struct wined3d_resource *sub_resource;
     struct d3d9_surface *surface_impl;
 
     TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
 
     wined3d_mutex_lock();
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+    if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
     {
         wined3d_mutex_unlock();
         return D3DERR_INVALIDCALL;
     }
 
-    surface_impl = wined3d_resource_get_parent(sub_resource);
     *surface = &surface_impl->IDirect3DSurface9_iface;
     IDirect3DSurface9_AddRef(*surface);
     wined3d_mutex_unlock();
@@ -346,7 +330,6 @@ static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
         UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-    struct wined3d_resource *sub_resource;
     struct d3d9_surface *surface_impl;
     HRESULT hr;
 
@@ -354,13 +337,10 @@ static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
             iface, level, locked_rect, rect, flags);
 
     wined3d_mutex_lock();
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+    if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
         hr = D3DERR_INVALIDCALL;
     else
-    {
-        surface_impl = wined3d_resource_get_parent(sub_resource);
         hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
-    }
     wined3d_mutex_unlock();
 
     return hr;
@@ -369,20 +349,16 @@ static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
 static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT level)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
-    struct wined3d_resource *sub_resource;
     struct d3d9_surface *surface_impl;
     HRESULT hr;
 
     TRACE("iface %p, level %u.\n", iface, level);
 
     wined3d_mutex_lock();
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+    if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
         hr = D3DERR_INVALIDCALL;
     else
-    {
-        surface_impl = wined3d_resource_get_parent(sub_resource);
         hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
-    }
     wined3d_mutex_unlock();
 
     return hr;
@@ -403,12 +379,7 @@ static HRESULT WINAPI d3d9_texture_2d_AddDirtyRect(IDirect3DTexture9 *iface, con
     {
         struct wined3d_box dirty_region;
 
-        dirty_region.left = dirty_rect->left;
-        dirty_region.top = dirty_rect->top;
-        dirty_region.right = dirty_rect->right;
-        dirty_region.bottom = dirty_rect->bottom;
-        dirty_region.front = 0;
-        dirty_region.back = 1;
+        wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
         hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
     }
     wined3d_mutex_unlock();
@@ -469,14 +440,20 @@ static HRESULT WINAPI d3d9_texture_cube_QueryInterface(IDirect3DCubeTexture9 *if
 static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-    ULONG ref = InterlockedIncrement(&texture->refcount);
+    ULONG ref = InterlockedIncrement(&texture->resource.refcount);
 
     TRACE("%p increasing refcount to %u.\n", iface, ref);
 
     if (ref == 1)
     {
+        struct d3d9_surface *surface;
+
         IDirect3DDevice9Ex_AddRef(texture->parent_device);
         wined3d_mutex_lock();
+        LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
+        {
+            wined3d_rendertarget_view_decref(surface->wined3d_rtv);
+        }
         wined3d_texture_incref(texture->wined3d_texture);
         wined3d_mutex_unlock();
     }
@@ -487,17 +464,22 @@ static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface)
 static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-    ULONG ref = InterlockedDecrement(&texture->refcount);
+    ULONG ref = InterlockedDecrement(&texture->resource.refcount);
 
     TRACE("%p decreasing refcount to %u.\n", iface, ref);
 
     if (!ref)
     {
         IDirect3DDevice9Ex *parent_device = texture->parent_device;
+        struct d3d9_surface *surface;
 
         TRACE("Releasing child %p.\n", texture->wined3d_texture);
 
         wined3d_mutex_lock();
+        LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
+        {
+            wined3d_rendertarget_view_decref(surface->wined3d_rtv);
+        }
         wined3d_texture_decref(texture->wined3d_texture);
         wined3d_mutex_unlock();
 
@@ -525,63 +507,41 @@ static HRESULT WINAPI d3d9_texture_cube_SetPrivateData(IDirect3DCubeTexture9 *if
         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-    struct wined3d_resource *resource;
-    HRESULT hr;
-
     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
             iface, debugstr_guid(guid), data, data_size, flags);
 
-    wined3d_mutex_lock();
-    resource = wined3d_texture_get_resource(texture->wined3d_texture);
-    hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
-    wined3d_mutex_unlock();
-
-    return hr;
+    return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
 }
 
 static HRESULT WINAPI d3d9_texture_cube_GetPrivateData(IDirect3DCubeTexture9 *iface,
         REFGUID guid, void *data, DWORD *data_size)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-    struct wined3d_resource *resource;
-    HRESULT hr;
-
     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
             iface, debugstr_guid(guid), data, data_size);
 
-    wined3d_mutex_lock();
-    resource = wined3d_texture_get_resource(texture->wined3d_texture);
-    hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
-    wined3d_mutex_unlock();
-
-    return hr;
+    return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
 }
 
 static HRESULT WINAPI d3d9_texture_cube_FreePrivateData(IDirect3DCubeTexture9 *iface, REFGUID guid)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-    struct wined3d_resource *resource;
-    HRESULT hr;
-
     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
 
-    wined3d_mutex_lock();
-    resource = wined3d_texture_get_resource(texture->wined3d_texture);
-    hr = wined3d_resource_free_private_data(resource, guid);
-    wined3d_mutex_unlock();
-
-    return hr;
+    return d3d9_resource_free_private_data(&texture->resource, guid);
 }
 
 static DWORD WINAPI d3d9_texture_cube_SetPriority(IDirect3DCubeTexture9 *iface, DWORD priority)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+    struct wined3d_resource *resource;
     DWORD ret;
 
     TRACE("iface %p, priority %u.\n", iface, priority);
 
     wined3d_mutex_lock();
-    ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
+    resource = wined3d_texture_get_resource(texture->wined3d_texture);
+    ret = wined3d_resource_set_priority(resource, priority);
     wined3d_mutex_unlock();
 
     return ret;
@@ -590,12 +550,14 @@ static DWORD WINAPI d3d9_texture_cube_SetPriority(IDirect3DCubeTexture9 *iface,
 static DWORD WINAPI d3d9_texture_cube_GetPriority(IDirect3DCubeTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+    const struct wined3d_resource *resource;
     DWORD ret;
 
     TRACE("iface %p.\n", iface);
 
     wined3d_mutex_lock();
-    ret = wined3d_texture_get_priority(texture->wined3d_texture);
+    resource = wined3d_texture_get_resource(texture->wined3d_texture);
+    ret = wined3d_resource_get_priority(resource);
     wined3d_mutex_unlock();
 
     return ret;
@@ -608,7 +570,7 @@ static void WINAPI d3d9_texture_cube_PreLoad(IDirect3DCubeTexture9 *iface)
     TRACE("iface %p.\n", iface);
 
     wined3d_mutex_lock();
-    wined3d_texture_preload(texture->wined3d_texture);
+    wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
     wined3d_mutex_unlock();
 }
 
@@ -705,9 +667,9 @@ static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9
 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-    struct wined3d_resource *sub_resource;
-    HRESULT hr = D3D_OK;
+    struct wined3d_sub_resource_desc wined3d_desc;
     DWORD level_count;
+    HRESULT hr;
 
     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
 
@@ -719,15 +681,10 @@ static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *ifac
         return D3DERR_INVALIDCALL;
     }
 
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
-        hr = D3DERR_INVALIDCALL;
-    else
+    if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
     {
-        struct wined3d_resource_desc wined3d_desc;
-
-        wined3d_resource_get_desc(sub_resource, &wined3d_desc);
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
-        desc->Type = wined3d_desc.resource_type;
+        desc->Type = D3DRTYPE_SURFACE;
         desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
         desc->Pool = wined3d_desc.pool;
         desc->MultiSampleType = wined3d_desc.multisample_type;
@@ -744,7 +701,6 @@ static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9
         D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-    struct wined3d_resource *sub_resource;
     struct d3d9_surface *surface_impl;
     UINT sub_resource_idx;
     DWORD level_count;
@@ -760,13 +716,12 @@ static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9
     }
 
     sub_resource_idx = level_count * face + level;
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
+    if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
     {
         wined3d_mutex_unlock();
         return D3DERR_INVALIDCALL;
     }
 
-    surface_impl = wined3d_resource_get_parent(sub_resource);
     *surface = &surface_impl->IDirect3DSurface9_iface;
     IDirect3DSurface9_AddRef(*surface);
     wined3d_mutex_unlock();
@@ -779,7 +734,6 @@ static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface,
         DWORD flags)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-    struct wined3d_resource *sub_resource;
     struct d3d9_surface *surface_impl;
     UINT sub_resource_idx;
     HRESULT hr;
@@ -789,13 +743,10 @@ static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface,
 
     wined3d_mutex_lock();
     sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
+    if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
         hr = D3DERR_INVALIDCALL;
     else
-    {
-        surface_impl = wined3d_resource_get_parent(sub_resource);
         hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
-    }
     wined3d_mutex_unlock();
 
     return hr;
@@ -805,7 +756,6 @@ static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
         D3DCUBEMAP_FACES face, UINT level)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
-    struct wined3d_resource *sub_resource;
     struct d3d9_surface *surface_impl;
     UINT sub_resource_idx;
     HRESULT hr;
@@ -814,13 +764,10 @@ static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
 
     wined3d_mutex_lock();
     sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
+    if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
         hr = D3DERR_INVALIDCALL;
     else
-    {
-        surface_impl = wined3d_resource_get_parent(sub_resource);
         hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
-    }
     wined3d_mutex_unlock();
 
     return hr;
@@ -842,12 +789,7 @@ static HRESULT  WINAPI d3d9_texture_cube_AddDirtyRect(IDirect3DCubeTexture9 *ifa
     {
         struct wined3d_box dirty_region;
 
-        dirty_region.left = dirty_rect->left;
-        dirty_region.top = dirty_rect->top;
-        dirty_region.right = dirty_rect->right;
-        dirty_region.bottom = dirty_rect->bottom;
-        dirty_region.front = 0;
-        dirty_region.back = 1;
+        wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
         hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
     }
     wined3d_mutex_unlock();
@@ -908,7 +850,7 @@ static HRESULT WINAPI d3d9_texture_3d_QueryInterface(IDirect3DVolumeTexture9 *if
 static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-    ULONG ref = InterlockedIncrement(&texture->refcount);
+    ULONG ref = InterlockedIncrement(&texture->resource.refcount);
 
     TRACE("%p increasing refcount to %u.\n", iface, ref);
 
@@ -926,7 +868,7 @@ static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface)
 static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-    ULONG ref = InterlockedDecrement(&texture->refcount);
+    ULONG ref = InterlockedDecrement(&texture->resource.refcount);
 
     TRACE("%p decreasing refcount to %u.\n", iface, ref);
 
@@ -962,63 +904,41 @@ static HRESULT WINAPI d3d9_texture_3d_SetPrivateData(IDirect3DVolumeTexture9 *if
         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-    struct wined3d_resource *resource;
-    HRESULT hr;
-
     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
             iface, debugstr_guid(guid), data, data_size, flags);
 
-    wined3d_mutex_lock();
-    resource = wined3d_texture_get_resource(texture->wined3d_texture);
-    hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
-    wined3d_mutex_unlock();
-
-    return hr;
+    return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
 }
 
 static HRESULT WINAPI d3d9_texture_3d_GetPrivateData(IDirect3DVolumeTexture9 *iface,
         REFGUID guid, void *data, DWORD *data_size)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-    struct wined3d_resource *resource;
-    HRESULT hr;
-
     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
             iface, debugstr_guid(guid), data, data_size);
 
-    wined3d_mutex_lock();
-    resource = wined3d_texture_get_resource(texture->wined3d_texture);
-    hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
-    wined3d_mutex_unlock();
-
-    return hr;
+    return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
 }
 
 static HRESULT WINAPI d3d9_texture_3d_FreePrivateData(IDirect3DVolumeTexture9 *iface, REFGUID guid)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-    struct wined3d_resource *resource;
-    HRESULT hr;
-
     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
 
-    wined3d_mutex_lock();
-    resource = wined3d_texture_get_resource(texture->wined3d_texture);
-    hr = wined3d_resource_free_private_data(resource, guid);
-    wined3d_mutex_unlock();
-
-    return hr;
+    return d3d9_resource_free_private_data(&texture->resource, guid);
 }
 
 static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface, DWORD priority)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+    struct wined3d_resource *resource;
     DWORD ret;
 
     TRACE("iface %p, priority %u.\n", iface, priority);
 
     wined3d_mutex_lock();
-    ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
+    resource = wined3d_texture_get_resource(texture->wined3d_texture);
+    ret = wined3d_resource_set_priority(resource, priority);
     wined3d_mutex_unlock();
 
     return ret;
@@ -1027,12 +947,14 @@ static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface,
 static DWORD WINAPI d3d9_texture_3d_GetPriority(IDirect3DVolumeTexture9 *iface)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+    const struct wined3d_resource *resource;
     DWORD ret;
 
     TRACE("iface %p.\n", iface);
 
     wined3d_mutex_lock();
-    ret = wined3d_texture_get_priority(texture->wined3d_texture);
+    resource = wined3d_texture_get_resource(texture->wined3d_texture);
+    ret = wined3d_resource_get_priority(resource);
     wined3d_mutex_unlock();
 
     return ret;
@@ -1045,7 +967,7 @@ static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface)
     TRACE("iface %p.\n", iface);
 
     wined3d_mutex_lock();
-    wined3d_texture_preload(texture->wined3d_texture);
+    wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
     wined3d_mutex_unlock();
 }
 
@@ -1142,21 +1064,16 @@ static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9
 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-    struct wined3d_resource *sub_resource;
-    HRESULT hr = D3D_OK;
+    struct wined3d_sub_resource_desc wined3d_desc;
+    HRESULT hr;
 
     TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
 
     wined3d_mutex_lock();
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
-        hr = D3DERR_INVALIDCALL;
-    else
+    if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
     {
-        struct wined3d_resource_desc wined3d_desc;
-
-        wined3d_resource_get_desc(sub_resource, &wined3d_desc);
         desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
-        desc->Type = wined3d_desc.resource_type;
+        desc->Type = D3DRTYPE_VOLUME;
         desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
         desc->Pool = wined3d_desc.pool;
         desc->Width = wined3d_desc.width;
@@ -1172,19 +1089,17 @@ static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *if
         UINT level, IDirect3DVolume9 **volume)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-    struct wined3d_resource *sub_resource;
     struct d3d9_volume *volume_impl;
 
     TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
 
     wined3d_mutex_lock();
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+    if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
     {
         wined3d_mutex_unlock();
         return D3DERR_INVALIDCALL;
     }
 
-    volume_impl = wined3d_resource_get_parent(sub_resource);
     *volume = &volume_impl->IDirect3DVolume9_iface;
     IDirect3DVolume9_AddRef(*volume);
     wined3d_mutex_unlock();
@@ -1196,7 +1111,6 @@ static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
         UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-    struct wined3d_resource *sub_resource;
     struct d3d9_volume *volume_impl;
     HRESULT hr;
 
@@ -1204,13 +1118,10 @@ static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
             iface, level, locked_box, box, flags);
 
     wined3d_mutex_lock();
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+    if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
         hr = D3DERR_INVALIDCALL;
     else
-    {
-        volume_impl = wined3d_resource_get_parent(sub_resource);
         hr = IDirect3DVolume9_LockBox(&volume_impl->IDirect3DVolume9_iface, locked_box, box, flags);
-    }
     wined3d_mutex_unlock();
 
     return hr;
@@ -1219,20 +1130,16 @@ static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
 static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level)
 {
     struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
-    struct wined3d_resource *sub_resource;
     struct d3d9_volume *volume_impl;
     HRESULT hr;
 
     TRACE("iface %p, level %u.\n", iface, level);
 
     wined3d_mutex_lock();
-    if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+    if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
         hr = D3DERR_INVALIDCALL;
     else
-    {
-        volume_impl = wined3d_resource_get_parent(sub_resource);
         hr = IDirect3DVolume9_UnlockBox(&volume_impl->IDirect3DVolume9_iface);
-    }
     wined3d_mutex_unlock();
 
     return hr;
@@ -1287,15 +1194,23 @@ struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture
 {
     if (!iface)
         return NULL;
-    assert(iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
-            || iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
-            || iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl);
+
+    if (iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
+            && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
+            && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl)
+    {
+        WARN("%p is not a valid IDirect3DBaseTexture9 interface.\n", iface);
+        return NULL;
+    }
+
     return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
 }
 
 static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent)
 {
-    HeapFree(GetProcessHeap(), 0, parent);
+    struct d3d9_texture *texture = parent;
+    d3d9_resource_cleanup(&texture->resource);
+    HeapFree(GetProcessHeap(), 0, texture);
 }
 
 static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
@@ -1307,13 +1222,14 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
         UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
 {
     struct wined3d_resource_desc desc;
-    DWORD surface_flags = 0;
+    DWORD flags = 0;
     HRESULT hr;
 
     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
-    texture->refcount = 1;
+    d3d9_resource_init(&texture->resource);
+    list_init(&texture->rtv_list);
 
-    desc.resource_type = WINED3D_RTYPE_TEXTURE;
+    desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
     desc.format = wined3dformat_from_d3dformat(format);
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
@@ -1326,11 +1242,22 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
     desc.size = 0;
 
     if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
-        surface_flags |= WINED3D_SURFACE_MAPPABLE;
+        flags |= WINED3D_TEXTURE_CREATE_MAPPABLE;
+
+    if (is_gdi_compat_wined3dformat(desc.format))
+        flags |= WINED3D_TEXTURE_CREATE_GET_DC;
+
+    if (!levels)
+    {
+        if (usage & D3DUSAGE_AUTOGENMIPMAP)
+            levels = 1;
+        else
+            levels = wined3d_log2i(max(width, height)) + 1;
+    }
 
     wined3d_mutex_lock();
-    hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
-            texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
+    hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
+            NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
@@ -1348,18 +1275,19 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic
         UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
 {
     struct wined3d_resource_desc desc;
-    DWORD surface_flags = 0;
+    DWORD flags = 0;
     HRESULT hr;
 
     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
-    texture->refcount = 1;
+    d3d9_resource_init(&texture->resource);
+    list_init(&texture->rtv_list);
 
-    desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE;
+    desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
     desc.format = wined3dformat_from_d3dformat(format);
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
     desc.usage = usage & WINED3DUSAGE_MASK;
-    desc.usage |= WINED3DUSAGE_TEXTURE;
+    desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE;
     desc.pool = pool;
     desc.width = edge_length;
     desc.height = edge_length;
@@ -1367,11 +1295,22 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic
     desc.size = 0;
 
     if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
-        surface_flags |= WINED3D_SURFACE_MAPPABLE;
+        flags |= WINED3D_TEXTURE_CREATE_MAPPABLE;
+
+    if (is_gdi_compat_wined3dformat(desc.format))
+        flags |= WINED3D_TEXTURE_CREATE_GET_DC;
+
+    if (!levels)
+    {
+        if (usage & D3DUSAGE_AUTOGENMIPMAP)
+            levels = 1;
+        else
+            levels = wined3d_log2i(edge_length) + 1;
+    }
 
     wined3d_mutex_lock();
-    hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
-            texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
+    hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags,
+            NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {
@@ -1392,9 +1331,10 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev
     HRESULT hr;
 
     texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
-    texture->refcount = 1;
+    d3d9_resource_init(&texture->resource);
+    list_init(&texture->rtv_list);
 
-    desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE;
+    desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
     desc.format = wined3dformat_from_d3dformat(format);
     desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
     desc.multisample_quality = 0;
@@ -1406,9 +1346,17 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev
     desc.depth = depth;
     desc.size = 0;
 
+    if (!levels)
+    {
+        if (usage & D3DUSAGE_AUTOGENMIPMAP)
+            levels = 1;
+        else
+            levels = wined3d_log2i(max(max(width, height), depth)) + 1;
+    }
+
     wined3d_mutex_lock();
-    hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0,
-            texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
+    hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0,
+            NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
     wined3d_mutex_unlock();
     if (FAILED(hr))
     {