[PATCH 2/4] wined3d: Make IWineD3DResourceImpl an independent structure.

Henri Verbeet hverbeet at codeweavers.com
Tue Mar 1 02:47:56 CST 2011


---
 dlls/d3d10core/view.c          |   13 ++--
 dlls/d3d9/device.c             |   16 ++--
 dlls/wined3d/basetexture.c     |   10 +-
 dlls/wined3d/buffer.c          |   76 +++++++++--------
 dlls/wined3d/context.c         |    8 +-
 dlls/wined3d/cubetexture.c     |   64 +++++++-------
 dlls/wined3d/device.c          |  183 +++++++++++++++++++++-------------------
 dlls/wined3d/palette.c         |    8 +-
 dlls/wined3d/resource.c        |  102 ++++++++++++-----------
 dlls/wined3d/state.c           |    4 +-
 dlls/wined3d/surface.c         |   21 +++--
 dlls/wined3d/surface_base.c    |   19 +++--
 dlls/wined3d/surface_gdi.c     |    3 +-
 dlls/wined3d/texture.c         |   63 +++++++-------
 dlls/wined3d/utils.c           |    2 +-
 dlls/wined3d/view.c            |    9 +--
 dlls/wined3d/volume.c          |   18 ++--
 dlls/wined3d/volumetexture.c   |   61 +++++++-------
 dlls/wined3d/wined3d.spec      |    2 +
 dlls/wined3d/wined3d_private.h |   91 +++++++++++---------
 include/wine/wined3d.idl       |   14 ++-
 21 files changed, 417 insertions(+), 370 deletions(-)

diff --git a/dlls/d3d10core/view.c b/dlls/d3d10core/view.c
index 72b7f4e..fd19826 100644
--- a/dlls/d3d10core/view.c
+++ b/dlls/d3d10core/view.c
@@ -25,7 +25,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d10core);
 
-static IWineD3DResource *wined3d_resource_from_resource(ID3D10Resource *resource)
+static struct wined3d_resource *wined3d_resource_from_resource(ID3D10Resource *resource)
 {
     D3D10_RESOURCE_DIMENSION dimension;
 
@@ -34,10 +34,10 @@ static IWineD3DResource *wined3d_resource_from_resource(ID3D10Resource *resource
     switch(dimension)
     {
         case D3D10_RESOURCE_DIMENSION_BUFFER:
-            return (IWineD3DResource *)((struct d3d10_buffer *)resource)->wined3d_buffer;
+            return IWineD3DBuffer_GetResource(((struct d3d10_buffer *)resource)->wined3d_buffer);
 
         case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
-            return (IWineD3DResource *)((struct d3d10_texture2d *)resource)->wined3d_surface;
+            return IWineD3DSurface_GetResource(((struct d3d10_texture2d *)resource)->wined3d_surface);
 
         default:
             FIXME("Unhandled resource dimension %#x.\n", dimension);
@@ -374,7 +374,7 @@ static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetResource(ID3D10RenderTa
         ID3D10Resource **resource)
 {
     struct d3d10_rendertarget_view *This = (struct d3d10_rendertarget_view *)iface;
-    IWineD3DResource *wined3d_resource;
+    struct wined3d_resource *wined3d_resource;
     IUnknown *parent;
     HRESULT hr;
 
@@ -388,9 +388,8 @@ static void STDMETHODCALLTYPE d3d10_rendertarget_view_GetResource(ID3D10RenderTa
         return;
     }
 
-    parent = IWineD3DResource_GetParent(wined3d_resource);
+    parent = wined3d_resource_get_parent(wined3d_resource);
     hr = IUnknown_QueryInterface(parent, &IID_ID3D10Resource, (void **)&resource);
-    IWineD3DResource_Release(wined3d_resource);
     if (FAILED(hr))
     {
         ERR("Resource parent isn't a d3d10 resource, hr %#x\n", hr);
@@ -431,7 +430,7 @@ static const struct ID3D10RenderTargetViewVtbl d3d10_rendertarget_view_vtbl =
 HRESULT d3d10_rendertarget_view_init(struct d3d10_rendertarget_view *view, struct d3d10_device *device,
         ID3D10Resource *resource, const D3D10_RENDER_TARGET_VIEW_DESC *desc)
 {
-    IWineD3DResource *wined3d_resource;
+    struct wined3d_resource *wined3d_resource;
     HRESULT hr;
 
     view->vtbl = &d3d10_rendertarget_view_vtbl;
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 1b6592e..c6efc48 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -529,27 +529,28 @@ static UINT WINAPI IDirect3DDevice9Impl_GetNumberOfSwapChains(IDirect3DDevice9Ex
     return count;
 }
 
-static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data) {
+static HRESULT WINAPI reset_enum_callback(struct wined3d_resource *resource, void *data)
+{
     BOOL *resources_ok = data;
     D3DRESOURCETYPE type;
     HRESULT ret = S_OK;
-    WINED3DSURFACE_DESC surface_desc;
-    WINED3DVOLUME_DESC volume_desc;
+    D3DSURFACE_DESC surface_desc;
+    D3DVOLUME_DESC volume_desc;
     D3DINDEXBUFFER_DESC index_desc;
     D3DVERTEXBUFFER_DESC vertex_desc;
     WINED3DPOOL pool;
     IDirect3DResource9 *parent;
 
-    parent = IWineD3DResource_GetParent(resource);
+    parent = wined3d_resource_get_parent(resource);
     type = IDirect3DResource9_GetType(parent);
     switch(type) {
         case D3DRTYPE_SURFACE:
-            IWineD3DSurface_GetDesc((IWineD3DSurface *) resource, &surface_desc);
-            pool = surface_desc.pool;
+            IDirect3DSurface9_GetDesc((IDirect3DSurface9 *)parent, &surface_desc);
+            pool = surface_desc.Pool;
             break;
 
         case D3DRTYPE_VOLUME:
-            IWineD3DVolume_GetDesc((IWineD3DVolume *) resource, &volume_desc);
+            IDirect3DVolume9_GetDesc((IDirect3DVolume9 *)parent, &volume_desc);
             pool = volume_desc.Pool;
             break;
 
@@ -583,7 +584,6 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data
             *resources_ok = FALSE;
         }
     }
-    IWineD3DResource_Release(resource);
 
     return ret;
 }
diff --git a/dlls/wined3d/basetexture.c b/dlls/wined3d/basetexture.c
index cb7227f..8b2797e 100644
--- a/dlls/wined3d/basetexture.c
+++ b/dlls/wined3d/basetexture.c
@@ -34,7 +34,7 @@ HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, const struct wined3d_
 {
     HRESULT hr;
 
-    hr = resource_init((IWineD3DResourceImpl *)texture, resource_type, device,
+    hr = resource_init(&texture->resource, resource_type, device,
             0, usage, format, pool, parent, parent_ops, resource_ops);
     if (FAILED(hr))
     {
@@ -48,7 +48,7 @@ HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, const struct wined3d_
     if (!texture->baseTexture.sub_resources)
     {
         ERR("Failed to allocate sub-resource array.\n");
-        resource_cleanup((IWineD3DResourceImpl *)texture);
+        resource_cleanup(&texture->resource);
         return E_OUTOFMEMORY;
     }
 
@@ -79,10 +79,10 @@ void basetexture_cleanup(IWineD3DBaseTextureImpl *texture)
 {
     basetexture_unload(texture);
     HeapFree(GetProcessHeap(), 0, texture->baseTexture.sub_resources);
-    resource_cleanup((IWineD3DResourceImpl *)texture);
+    resource_cleanup(&texture->resource);
 }
 
-IWineD3DResourceImpl *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *texture, UINT sub_resource_idx)
+struct wined3d_resource *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *texture, UINT sub_resource_idx)
 {
     UINT sub_count = texture->baseTexture.level_count * texture->baseTexture.layer_count;
 
@@ -125,7 +125,7 @@ void basetexture_unload(IWineD3DBaseTextureImpl *texture)
     texture->baseTexture.texture_rgb.dirty = TRUE;
     texture->baseTexture.texture_srgb.dirty = TRUE;
 
-    resource_unload((IWineD3DResourceImpl *)texture);
+    resource_unload(&texture->resource);
 }
 
 DWORD basetexture_set_lod(IWineD3DBaseTextureImpl *texture, DWORD lod)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 04d8f2f..f17928d 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -693,39 +693,39 @@ BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_inf
 }
 
 /* Do not call while under the GL lock. */
-static void buffer_unload(IWineD3DResourceImpl *resource)
+static void buffer_unload(struct wined3d_resource *resource)
 {
-    struct wined3d_buffer *This = (struct wined3d_buffer *)resource;
+    struct wined3d_buffer *buffer = buffer_from_resource(resource);
 
-    TRACE("buffer %p.\n", This);
+    TRACE("buffer %p.\n", buffer);
 
-    if (This->buffer_object)
+    if (buffer->buffer_object)
     {
-        IWineD3DDeviceImpl *device = resource->resource.device;
+        IWineD3DDeviceImpl *device = resource->device;
         struct wined3d_context *context;
 
         context = context_acquire(device, NULL);
 
         /* Download the buffer, but don't permanently enable double buffering */
-        if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
+        if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER))
         {
-            buffer_get_sysmem(This, context->gl_info);
-            This->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER;
+            buffer_get_sysmem(buffer, context->gl_info);
+            buffer->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER;
         }
 
-        delete_gl_buffer(This, context->gl_info);
-        This->flags |= WINED3D_BUFFER_CREATEBO; /* Recreate the buffer object next load */
-        buffer_clear_dirty_areas(This);
+        delete_gl_buffer(buffer, context->gl_info);
+        buffer->flags |= WINED3D_BUFFER_CREATEBO; /* Recreate the buffer object next load */
+        buffer_clear_dirty_areas(buffer);
 
         context_release(context);
 
-        HeapFree(GetProcessHeap(), 0, This->conversion_shift);
-        This->conversion_shift = NULL;
-        HeapFree(GetProcessHeap(), 0, This->conversion_map);
-        This->conversion_map = NULL;
-        This->stride = 0;
-        This->conversion_stride = 0;
-        This->flags &= ~WINED3D_BUFFER_HASDESC;
+        HeapFree(GetProcessHeap(), 0, buffer->conversion_shift);
+        buffer->conversion_shift = NULL;
+        HeapFree(GetProcessHeap(), 0, buffer->conversion_map);
+        buffer->conversion_map = NULL;
+        buffer->stride = 0;
+        buffer->conversion_stride = 0;
+        buffer->flags &= ~WINED3D_BUFFER_HASDESC;
     }
 
     resource_unload(resource);
@@ -741,8 +741,8 @@ static ULONG STDMETHODCALLTYPE buffer_Release(IWineD3DBuffer *iface)
 
     if (!refcount)
     {
-        buffer_unload((IWineD3DResourceImpl *)This);
-        resource_cleanup((IWineD3DResourceImpl *)iface);
+        buffer_unload(&This->resource);
+        resource_cleanup(&This->resource);
         This->resource.parent_ops->wined3d_object_destroyed(This->resource.parent);
         HeapFree(GetProcessHeap(), 0, This->maps);
         HeapFree(GetProcessHeap(), 0, This);
@@ -764,28 +764,28 @@ static void * STDMETHODCALLTYPE buffer_GetParent(IWineD3DBuffer *iface)
 static HRESULT STDMETHODCALLTYPE buffer_SetPrivateData(IWineD3DBuffer *iface,
         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
 {
-    return resource_set_private_data((IWineD3DResourceImpl *)iface, guid, data, data_size, flags);
+    return resource_set_private_data(&((struct wined3d_buffer *)iface)->resource, guid, data, data_size, flags);
 }
 
 static HRESULT STDMETHODCALLTYPE buffer_GetPrivateData(IWineD3DBuffer *iface,
         REFGUID guid, void *data, DWORD *data_size)
 {
-    return resource_get_private_data((IWineD3DResourceImpl *)iface, guid, data, data_size);
+    return resource_get_private_data(&((struct wined3d_buffer *)iface)->resource, guid, data, data_size);
 }
 
 static HRESULT STDMETHODCALLTYPE buffer_FreePrivateData(IWineD3DBuffer *iface, REFGUID guid)
 {
-    return resource_free_private_data((IWineD3DResourceImpl *)iface, guid);
+    return resource_free_private_data(&((struct wined3d_buffer *)iface)->resource, guid);
 }
 
 static DWORD STDMETHODCALLTYPE buffer_SetPriority(IWineD3DBuffer *iface, DWORD priority)
 {
-    return resource_set_priority((IWineD3DResourceImpl *)iface, priority);
+    return resource_set_priority(&((struct wined3d_buffer *)iface)->resource, priority);
 }
 
 static DWORD STDMETHODCALLTYPE buffer_GetPriority(IWineD3DBuffer *iface)
 {
-    return resource_get_priority((IWineD3DResourceImpl *)iface);
+    return resource_get_priority(&((struct wined3d_buffer *)iface)->resource);
 }
 
 /* The caller provides a context and binds the buffer */
@@ -997,7 +997,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
         {
             FIXME("Too many declaration changes or converting dynamic buffer, stopping converting\n");
 
-            buffer_unload((IWineD3DResourceImpl *)This);
+            buffer_unload(&This->resource);
             This->flags &= ~WINED3D_BUFFER_CREATEBO;
 
             /* The stream source state handler might have read the memory of the vertex buffer already
@@ -1035,7 +1035,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
             if(This->full_conversion_count > VB_MAXFULLCONVERSIONS)
             {
                 FIXME("Too many full buffer conversions, stopping converting\n");
-                buffer_unload((IWineD3DResourceImpl *)This);
+                buffer_unload(&This->resource);
                 This->flags &= ~WINED3D_BUFFER_CREATEBO;
                 IWineD3DDeviceImpl_MarkStateDirty(device, STATE_STREAMSRC);
                 goto end;
@@ -1190,7 +1190,7 @@ end:
 
 static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *iface)
 {
-    return resource_get_type((IWineD3DResourceImpl *)iface);
+    return resource_get_type(&((struct wined3d_buffer *)iface)->resource);
 }
 
 /* IWineD3DBuffer methods */
@@ -1245,6 +1245,13 @@ static GLbitfield buffer_gl_map_flags(DWORD d3d_flags)
     return ret;
 }
 
+static struct wined3d_resource * STDMETHODCALLTYPE buffer_GetResource(IWineD3DBuffer *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return &((struct wined3d_buffer *)iface)->resource;
+}
+
 static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, UINT size, BYTE **data, DWORD flags)
 {
     struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
@@ -1450,6 +1457,7 @@ static const struct IWineD3DBufferVtbl wined3d_buffer_vtbl =
     buffer_PreLoad,
     buffer_GetType,
     /* IWineD3DBuffer methods */
+    buffer_GetResource,
     buffer_Map,
     buffer_Unmap,
     buffer_GetDesc,
@@ -1477,8 +1485,8 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
 
     buffer->vtbl = &wined3d_buffer_vtbl;
 
-    hr = resource_init((IWineD3DResourceImpl *)buffer, WINED3DRTYPE_BUFFER,
-            device, size, usage, format, pool, parent, parent_ops, &buffer_resource_ops);
+    hr = resource_init(&buffer->resource, WINED3DRTYPE_BUFFER, device, size,
+            usage, format, pool, parent, parent_ops, &buffer_resource_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, hr %#x\n", hr);
@@ -1524,8 +1532,8 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
         if (FAILED(hr))
         {
             ERR("Failed to map buffer, hr %#x\n", hr);
-            buffer_unload((IWineD3DResourceImpl *)buffer);
-            resource_cleanup((IWineD3DResourceImpl *)buffer);
+            buffer_unload(&buffer->resource);
+            resource_cleanup(&buffer->resource);
             return hr;
         }
 
@@ -1538,8 +1546,8 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
     if (!buffer->maps)
     {
         ERR("Out of memory\n");
-        buffer_unload((IWineD3DResourceImpl *)buffer);
-        resource_cleanup((IWineD3DResourceImpl *)buffer);
+        buffer_unload(&buffer->resource);
+        resource_cleanup(&buffer->resource);
         return E_OUTOFMEMORY;
     }
     buffer->maps_size = 1;
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index b7abc0f..cc0ad7e 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -690,14 +690,14 @@ static void context_queue_fbo_entry_destruction(struct wined3d_context *context,
 }
 
 void context_resource_released(struct IWineD3DDeviceImpl *device,
-        struct IWineD3DResourceImpl *resource, WINED3DRESOURCETYPE type)
+        struct wined3d_resource *resource, WINED3DRESOURCETYPE type)
 {
     if (!device->d3d_initialized) return;
 
     switch (type)
     {
         case WINED3DRTYPE_SURFACE:
-            context_enum_surface_fbo_entries(device, (IWineD3DSurfaceImpl *)resource,
+            context_enum_surface_fbo_entries(device, surface_from_resource(resource),
                     context_queue_fbo_entry_destruction);
             break;
 
@@ -712,12 +712,12 @@ static void context_detach_fbo_entry(struct wined3d_context *context, struct fbo
 }
 
 void context_resource_unloaded(struct IWineD3DDeviceImpl *device,
-        struct IWineD3DResourceImpl *resource, WINED3DRESOURCETYPE type)
+        struct wined3d_resource *resource, WINED3DRESOURCETYPE type)
 {
     switch (type)
     {
         case WINED3DRTYPE_SURFACE:
-            context_enum_surface_fbo_entries(device, (IWineD3DSurfaceImpl *)resource,
+            context_enum_surface_fbo_entries(device, surface_from_resource(resource),
                     context_detach_fbo_entry);
             break;
 
diff --git a/dlls/wined3d/cubetexture.c b/dlls/wined3d/cubetexture.c
index bf54b07..0fc5aba 100644
--- a/dlls/wined3d/cubetexture.c
+++ b/dlls/wined3d/cubetexture.c
@@ -43,7 +43,7 @@ static HRESULT cubetexture_bind(IWineD3DBaseTextureImpl *texture, BOOL srgb)
 
         for (i = 0; i < sub_count; ++i)
         {
-            IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i];
+            IWineD3DSurfaceImpl *surface = surface_from_resource(texture->baseTexture.sub_resources[i]);
 
             if (texture->baseTexture.is_srgb)
                 surface_set_texture_name(surface, texture->baseTexture.texture_srgb.name, TRUE);
@@ -102,7 +102,7 @@ static void cubetexture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSR
     {
         for (i = 0; i < sub_count; ++i)
         {
-            IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i];
+            IWineD3DSurfaceImpl *surface = surface_from_resource(texture->baseTexture.sub_resources[i]);
 
             if (palette9_changed(surface))
             {
@@ -122,7 +122,7 @@ static void cubetexture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSR
     {
         for (i = 0; i < sub_count; ++i)
         {
-            surface_load((IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i], srgb_mode);
+            surface_load(surface_from_resource(texture->baseTexture.sub_resources[i]), srgb_mode);
         }
     }
     else
@@ -137,9 +137,9 @@ static void cubetexture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSR
 }
 
 /* Do not call while under the GL lock. */
-static void cubetexture_unload(IWineD3DResourceImpl *resource)
+static void cubetexture_unload(struct wined3d_resource *resource)
 {
-    IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)resource;
+    IWineD3DBaseTextureImpl *texture = basetexture_from_resource(resource);
     UINT sub_count = texture->baseTexture.level_count * texture->baseTexture.layer_count;
     UINT i;
 
@@ -147,9 +147,10 @@ static void cubetexture_unload(IWineD3DResourceImpl *resource)
 
     for (i = 0; i < sub_count; ++i)
     {
-        IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i];
+        struct wined3d_resource *sub_resource = texture->baseTexture.sub_resources[i];
+        IWineD3DSurfaceImpl *surface = surface_from_resource(sub_resource);
 
-        surface->resource.resource_ops->resource_unload((IWineD3DResourceImpl *)surface);
+        resource->resource_ops->resource_unload(sub_resource);
         surface_set_texture_name(surface, 0, TRUE);
         surface_set_texture_name(surface, 0, FALSE);
     }
@@ -177,7 +178,7 @@ static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This)
 
     for (i = 0; i < sub_count; ++i)
     {
-        IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
+        IWineD3DSurfaceImpl *surface = surface_from_resource(This->baseTexture.sub_resources[i]);
 
         if (surface)
         {
@@ -241,28 +242,28 @@ static ULONG WINAPI IWineD3DCubeTextureImpl_Release(IWineD3DCubeTexture *iface)
 static HRESULT WINAPI IWineD3DCubeTextureImpl_SetPrivateData(IWineD3DCubeTexture *iface,
         REFGUID riid, const void *data, DWORD data_size, DWORD flags)
 {
-    return resource_set_private_data((IWineD3DResourceImpl *)iface, riid, data, data_size, flags);
+    return resource_set_private_data(&((IWineD3DCubeTextureImpl *)iface)->resource, riid, data, data_size, flags);
 }
 
 static HRESULT WINAPI IWineD3DCubeTextureImpl_GetPrivateData(IWineD3DCubeTexture *iface,
         REFGUID guid, void *data, DWORD *data_size)
 {
-    return resource_get_private_data((IWineD3DResourceImpl *)iface, guid, data, data_size);
+    return resource_get_private_data(&((IWineD3DCubeTextureImpl *)iface)->resource, guid, data, data_size);
 }
 
 static HRESULT WINAPI IWineD3DCubeTextureImpl_FreePrivateData(IWineD3DCubeTexture *iface, REFGUID refguid)
 {
-    return resource_free_private_data((IWineD3DResourceImpl *)iface, refguid);
+    return resource_free_private_data(&((IWineD3DCubeTextureImpl *)iface)->resource, refguid);
 }
 
 static DWORD WINAPI IWineD3DCubeTextureImpl_SetPriority(IWineD3DCubeTexture *iface, DWORD priority)
 {
-    return resource_set_priority((IWineD3DResourceImpl *)iface, priority);
+    return resource_set_priority(&((IWineD3DCubeTextureImpl *)iface)->resource, priority);
 }
 
 static DWORD WINAPI IWineD3DCubeTextureImpl_GetPriority(IWineD3DCubeTexture *iface)
 {
-    return resource_get_priority((IWineD3DResourceImpl *)iface);
+    return resource_get_priority(&((IWineD3DCubeTextureImpl *)iface)->resource);
 }
 
 /* Do not call while under the GL lock. */
@@ -273,7 +274,7 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface)
 
 static WINED3DRESOURCETYPE WINAPI IWineD3DCubeTextureImpl_GetType(IWineD3DCubeTexture *iface)
 {
-    return resource_get_type((IWineD3DResourceImpl *)iface);
+    return resource_get_type(&((IWineD3DCubeTextureImpl *)iface)->resource);
 }
 
 static void * WINAPI IWineD3DCubeTextureImpl_GetParent(IWineD3DCubeTexture *iface)
@@ -326,17 +327,17 @@ static HRESULT WINAPI IWineD3DCubeTextureImpl_GetLevelDesc(IWineD3DCubeTexture *
         UINT sub_resource_idx, WINED3DSURFACE_DESC *desc)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DSurface *surface;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u, desc %p.\n", iface, sub_resource_idx, desc);
 
-    if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    IWineD3DSurface_GetDesc(surface, desc);
+    IWineD3DSurface_GetDesc((IWineD3DSurface *)surface_from_resource(sub_resource), desc);
 
     return WINED3D_OK;
 }
@@ -345,19 +346,19 @@ static HRESULT WINAPI IWineD3DCubeTextureImpl_GetCubeMapSurface(IWineD3DCubeText
         UINT sub_resource_idx, IWineD3DSurface **surface)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DSurface *s;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u, surface %p.\n",
             iface, sub_resource_idx, surface);
 
-    if (!(s = (IWineD3DSurface *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    IWineD3DSurface_AddRef(s);
-    *surface = s;
+    *surface = (IWineD3DSurface *)surface_from_resource(sub_resource);
+    IWineD3DSurface_AddRef(*surface);
 
     TRACE("Returning surface %p.\n", *surface);
 
@@ -368,36 +369,37 @@ static HRESULT WINAPI IWineD3DCubeTextureImpl_Map(IWineD3DCubeTexture *iface,
         UINT sub_resource_idx, WINED3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DSurface *surface;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u, locked_rect %p, rect %s, flags %#x.\n",
             iface, sub_resource_idx, locked_rect, wine_dbgstr_rect(rect), flags);
 
-    if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    return IWineD3DSurface_Map(surface, locked_rect, rect, flags);
+    return IWineD3DSurface_Map((IWineD3DSurface *)surface_from_resource(sub_resource),
+            locked_rect, rect, flags);
 }
 
 static HRESULT WINAPI IWineD3DCubeTextureImpl_Unmap(IWineD3DCubeTexture *iface,
         UINT sub_resource_idx)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DSurface *surface;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u.\n",
             iface, sub_resource_idx);
 
-    if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    return IWineD3DSurface_Unmap(surface);
+    return IWineD3DSurface_Unmap((IWineD3DSurface *)surface_from_resource(sub_resource));
 }
 
 static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture *iface,
@@ -405,12 +407,12 @@ static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture *
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
     UINT sub_resource_idx = face * texture->baseTexture.level_count;
-    IWineD3DSurfaceImpl *surface;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, face %u, dirty_rect %s.\n",
             iface, face, wine_dbgstr_rect(dirty_rect));
 
-    if (!(surface = (IWineD3DSurfaceImpl *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
@@ -418,7 +420,7 @@ static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture *
 
     texture->baseTexture.texture_rgb.dirty = TRUE;
     texture->baseTexture.texture_srgb.dirty = TRUE;
-    surface_add_dirty_rect(surface, dirty_rect);
+    surface_add_dirty_rect(surface_from_resource(sub_resource), dirty_rect);
 
     return WINED3D_OK;
 }
@@ -566,7 +568,7 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN
 
             surface_set_container((IWineD3DSurfaceImpl *)surface, WINED3D_CONTAINER_TEXTURE, (IWineD3DBase *)texture);
             surface_set_texture_target((IWineD3DSurfaceImpl *)surface, cube_targets[j]);
-            texture->baseTexture.sub_resources[idx] = (IWineD3DResourceImpl *)surface;
+            texture->baseTexture.sub_resources[idx] = &((IWineD3DSurfaceImpl *)surface)->resource;
             TRACE("Created surface level %u @ %p.\n", i, surface);
         }
         tmp_w = max(1, tmp_w >> 1);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index d292813..6c4814d 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -867,14 +867,13 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) {
 
         if (!list_empty(&This->resources))
         {
-            IWineD3DResourceImpl *resource;
+            struct wined3d_resource *resource;
             FIXME("(%p) Device released with resources still bound, acceptable but unexpected\n", This);
 
-            LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry)
+            LIST_FOR_EACH_ENTRY(resource, &This->resources, struct wined3d_resource, resource_list_entry)
             {
-                WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource);
                 FIXME("Leftover resource %p with type %s (%#x).\n",
-                        resource, debug_d3dresourcetype(type), type);
+                        resource, debug_d3dresourcetype(resource->resourceType), resource->resourceType);
             }
         }
 
@@ -1079,7 +1078,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UI
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_CreateRendertargetView(IWineD3DDevice *iface,
-        IWineD3DResource *resource, void *parent, IWineD3DRendertargetView **rendertarget_view)
+        struct wined3d_resource *resource, void *parent, IWineD3DRendertargetView **rendertarget_view)
 {
     struct wined3d_rendertarget_view *object;
 
@@ -1093,7 +1092,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateRendertargetView(IWineD3DDevice *
         return E_OUTOFMEMORY;
     }
 
-    wined3d_rendertarget_view_init(object, (IWineD3DResourceImpl *)resource, parent);
+    wined3d_rendertarget_view_init(object, resource, parent);
 
     TRACE("Created render target view %p.\n", object);
     *rendertarget_view = (IWineD3DRendertargetView *)object;
@@ -2102,12 +2101,11 @@ err_out:
     return hr;
 }
 
-static HRESULT WINAPI device_unload_resource(IWineD3DResource *resource, void *data)
+static HRESULT WINAPI device_unload_resource(struct wined3d_resource *resource, void *data)
 {
     TRACE("Unloading resource %p.\n", resource);
 
-    ((IWineD3DResourceImpl *)resource)->resource.resource_ops->resource_unload((IWineD3DResourceImpl *)resource);
-    IWineD3DResource_Release(resource);
+    resource->resource_ops->resource_unload(resource);
 
     return S_OK;
 }
@@ -5726,7 +5724,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface,
 static void WINAPI IWineD3DDeviceImpl_ClearRendertargetView(IWineD3DDevice *iface,
         IWineD3DRendertargetView *rendertarget_view, const WINED3DCOLORVALUE *color)
 {
-    IWineD3DResource *resource;
+    struct wined3d_resource *resource;
     HRESULT hr;
 
     hr = IWineD3DRendertargetView_GetResource(rendertarget_view, &resource);
@@ -5736,17 +5734,14 @@ static void WINAPI IWineD3DDeviceImpl_ClearRendertargetView(IWineD3DDevice *ifac
         return;
     }
 
-    if (IWineD3DResource_GetType(resource) != WINED3DRTYPE_SURFACE)
+    if (resource->resourceType != WINED3DRTYPE_SURFACE)
     {
         FIXME("Only supported on surface resources\n");
-        IWineD3DResource_Release(resource);
         return;
     }
 
-    hr = surface_color_fill((IWineD3DSurfaceImpl *)resource, NULL, color);
+    hr = surface_color_fill(surface_from_resource(resource), NULL, color);
     if (FAILED(hr)) ERR("Color fill failed, hr %#x.\n", hr);
-
-    IWineD3DResource_Release(resource);
 }
 
 /* rendertarget and depth stencil functions */
@@ -6099,13 +6094,16 @@ static BOOL     WINAPI  IWineD3DDeviceImpl_ShowCursor(IWineD3DDevice* iface, BOO
     return oldVisible;
 }
 
-static HRESULT WINAPI evict_managed_resource(IWineD3DResource *resource, void *data) {
+static HRESULT WINAPI evict_managed_resource(struct wined3d_resource *resource, void *data)
+{
     TRACE("checking resource %p for eviction\n", resource);
-    if(((IWineD3DResourceImpl *) resource)->resource.pool == WINED3DPOOL_MANAGED) {
-        TRACE("Evicting %p\n", resource);
-        ((IWineD3DResourceImpl *)resource)->resource.resource_ops->resource_unload((IWineD3DResourceImpl *)resource);
+
+    if (resource->pool == WINED3DPOOL_MANAGED)
+    {
+        TRACE("Evicting %p.\n", resource);
+        resource->resource_ops->resource_unload(resource);
     }
-    IWineD3DResource_Release(resource);
+
     return S_OK;
 }
 
@@ -6626,23 +6624,23 @@ static void WINAPI IWineD3DDeviceImpl_GetGammaRamp(IWineD3DDevice *iface, UINT i
     }
 }
 
-void device_resource_add(struct IWineD3DDeviceImpl *device, struct IWineD3DResourceImpl *resource)
+void device_resource_add(struct IWineD3DDeviceImpl *device, struct wined3d_resource *resource)
 {
     TRACE("device %p, resource %p.\n", device, resource);
 
-    list_add_head(&device->resources, &resource->resource.resource_list_entry);
+    list_add_head(&device->resources, &resource->resource_list_entry);
 }
 
-static void device_resource_remove(struct IWineD3DDeviceImpl *device, struct IWineD3DResourceImpl *resource)
+static void device_resource_remove(struct IWineD3DDeviceImpl *device, struct wined3d_resource *resource)
 {
     TRACE("device %p, resource %p.\n", device, resource);
 
-    list_remove(&resource->resource.resource_list_entry);
+    list_remove(&resource->resource_list_entry);
 }
 
-void device_resource_released(struct IWineD3DDeviceImpl *device, struct IWineD3DResourceImpl *resource)
+void device_resource_released(struct IWineD3DDeviceImpl *device, struct wined3d_resource *resource)
 {
-    WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource);
+    WINED3DRESOURCETYPE type = resource->resourceType;
     unsigned int i;
 
     TRACE("device %p, resource %p, type %s.\n", device, resource, debug_d3dresourcetype(type));
@@ -6652,21 +6650,25 @@ void device_resource_released(struct IWineD3DDeviceImpl *device, struct IWineD3D
     switch (type)
     {
         case WINED3DRTYPE_SURFACE:
-            if (!device->d3d_initialized) break;
-
-            for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
             {
-                if (device->render_targets[i] == (IWineD3DSurfaceImpl *)resource)
+                IWineD3DSurfaceImpl *surface = surface_from_resource(resource);
+
+                if (!device->d3d_initialized) break;
+
+                for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
                 {
-                    ERR("Surface %p is still in use as render target %u.\n", resource, i);
-                    device->render_targets[i] = NULL;
+                    if (device->render_targets[i] == surface)
+                    {
+                        ERR("Surface %p is still in use as render target %u.\n", surface, i);
+                        device->render_targets[i] = NULL;
+                    }
                 }
-            }
 
-            if (device->depth_stencil == (IWineD3DSurfaceImpl *)resource)
-            {
-                ERR("Surface %p is still in use as depth/stencil buffer.\n", resource);
-                device->depth_stencil = NULL;
+                if (device->depth_stencil == surface)
+                {
+                    ERR("Surface %p is still in use as depth/stencil buffer.\n", surface);
+                    device->depth_stencil = NULL;
+                }
             }
             break;
 
@@ -6675,57 +6677,62 @@ void device_resource_released(struct IWineD3DDeviceImpl *device, struct IWineD3D
         case WINED3DRTYPE_VOLUMETEXTURE:
             for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
             {
-                if (device->stateBlock && device->stateBlock->state.textures[i] == (IWineD3DBaseTextureImpl *)resource)
+                IWineD3DBaseTextureImpl *texture = basetexture_from_resource(resource);
+
+                if (device->stateBlock && device->stateBlock->state.textures[i] == texture)
                 {
                     ERR("Texture %p is still in use by stateblock %p, stage %u.\n",
-                            resource, device->stateBlock, i);
+                            texture, device->stateBlock, i);
                     device->stateBlock->state.textures[i] = NULL;
                 }
 
                 if (device->updateStateBlock != device->stateBlock
-                        && device->updateStateBlock->state.textures[i] == (IWineD3DBaseTextureImpl *)resource)
+                        && device->updateStateBlock->state.textures[i] == texture)
                 {
                     ERR("Texture %p is still in use by stateblock %p, stage %u.\n",
-                            resource, device->updateStateBlock, i);
+                            texture, device->updateStateBlock, i);
                     device->updateStateBlock->state.textures[i] = NULL;
                 }
             }
             break;
 
         case WINED3DRTYPE_BUFFER:
-            for (i = 0; i < MAX_STREAMS; ++i)
             {
-                if (device->stateBlock
-                        && device->stateBlock->state.streams[i].buffer == (struct wined3d_buffer *)resource)
+                struct wined3d_buffer *buffer = buffer_from_resource(resource);
+
+                for (i = 0; i < MAX_STREAMS; ++i)
                 {
-                    ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
-                            resource, device->stateBlock, i);
-                    device->stateBlock->state.streams[i].buffer = NULL;
+                    if (device->stateBlock && device->stateBlock->state.streams[i].buffer == buffer)
+                    {
+                        ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
+                                buffer, device->stateBlock, i);
+                        device->stateBlock->state.streams[i].buffer = NULL;
+                    }
+
+                    if (device->updateStateBlock != device->stateBlock
+                            && device->updateStateBlock->state.streams[i].buffer == buffer)
+                    {
+                        ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
+                                buffer, device->updateStateBlock, i);
+                        device->updateStateBlock->state.streams[i].buffer = NULL;
+                    }
+
                 }
 
-                if (device->updateStateBlock != device->stateBlock
-                        && device->updateStateBlock->state.streams[i].buffer == (struct wined3d_buffer *)resource)
+                if (device->stateBlock && device->stateBlock->state.index_buffer == buffer)
                 {
-                    ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
-                            resource, device->updateStateBlock, i);
-                    device->updateStateBlock->state.streams[i].buffer = NULL;
+                    ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
+                            buffer, device->stateBlock);
+                    device->stateBlock->state.index_buffer =  NULL;
                 }
 
-            }
-
-            if (device->stateBlock && device->stateBlock->state.index_buffer == (struct wined3d_buffer *)resource)
-            {
-                ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
-                        resource, device->stateBlock);
-                device->stateBlock->state.index_buffer =  NULL;
-            }
-
-            if (device->updateStateBlock != device->stateBlock
-                    && device->updateStateBlock->state.index_buffer == (struct wined3d_buffer *)resource)
-            {
-                ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
-                        resource, device->updateStateBlock);
-                device->updateStateBlock->state.index_buffer =  NULL;
+                if (device->updateStateBlock != device->stateBlock
+                        && device->updateStateBlock->state.index_buffer == buffer)
+                {
+                    ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
+                            buffer, device->updateStateBlock);
+                    device->updateStateBlock->state.index_buffer =  NULL;
+                }
             }
             break;
 
@@ -6739,38 +6746,42 @@ void device_resource_released(struct IWineD3DDeviceImpl *device, struct IWineD3D
     TRACE("Resource released.\n");
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_EnumResources(IWineD3DDevice *iface, D3DCB_ENUMRESOURCES pCallback, void *pData) {
+static HRESULT WINAPI IWineD3DDeviceImpl_EnumResources(IWineD3DDevice *iface,
+        D3DCB_ENUMRESOURCES callback, void *data)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
-    IWineD3DResourceImpl *resource, *cursor;
-    HRESULT ret;
-    TRACE("(%p)->(%p,%p)\n", This, pCallback, pData);
-
-    LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry) {
-        TRACE("enumerating resource %p\n", resource);
-        IWineD3DResource_AddRef((IWineD3DResource *) resource);
-        ret = pCallback((IWineD3DResource *) resource, pData);
-        if(ret == S_FALSE) {
-            TRACE("Canceling enumeration\n");
+    struct wined3d_resource *resource, *cursor;
+
+    TRACE("iface %p, callback %p, data %p.\n", iface, callback, data);
+
+    LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &This->resources, struct wined3d_resource, resource_list_entry)
+    {
+        TRACE("enumerating resource %p.\n", resource);
+        if (callback(resource, data) == S_FALSE)
+        {
+            TRACE("Canceling enumeration.\n");
             break;
         }
     }
+
     return WINED3D_OK;
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_GetSurfaceFromDC(IWineD3DDevice *iface, HDC dc, IWineD3DSurface **surface)
 {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
-    IWineD3DResourceImpl *resource;
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    struct wined3d_resource *resource;
 
-    LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry)
+    LIST_FOR_EACH_ENTRY(resource, &This->resources, struct wined3d_resource, resource_list_entry)
     {
-        WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource);
-        if (type == WINED3DRTYPE_SURFACE)
+        if (resource->resourceType == WINED3DRTYPE_SURFACE)
         {
-            if (((IWineD3DSurfaceImpl *)resource)->hDC == dc)
+            IWineD3DSurfaceImpl *s = surface_from_resource(resource);
+
+            if (s->hDC == dc)
             {
-                TRACE("Found surface %p for dc %p.\n", resource, dc);
-                *surface = (IWineD3DSurface *)resource;
+                TRACE("Found surface %p for dc %p.\n", s, dc);
+                *surface = (IWineD3DSurface *)s;
                 return WINED3D_OK;
             }
         }
diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c
index d14587a..e70c2f1 100644
--- a/dlls/wined3d/palette.c
+++ b/dlls/wined3d/palette.c
@@ -95,7 +95,7 @@ HRESULT CDECL wined3d_palette_get_entries(const struct wined3d_palette *palette,
 HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette,
         DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries)
 {
-    IWineD3DResourceImpl *res;
+    struct wined3d_resource *resource;
 
     TRACE("palette %p, flags %#x, start %u, count %u, entries %p.\n",
             palette, flags, start, count, entries);
@@ -131,11 +131,11 @@ HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette,
     }
 
     /* If the palette is attached to the render target, update all render targets */
-    LIST_FOR_EACH_ENTRY(res, &palette->device->resources, IWineD3DResourceImpl, resource.resource_list_entry)
+    LIST_FOR_EACH_ENTRY(resource, &palette->device->resources, struct wined3d_resource, resource_list_entry)
     {
-        if (IWineD3DResource_GetType((IWineD3DResource *)res) == WINED3DRTYPE_SURFACE)
+        if (resource->resourceType == WINED3DRTYPE_SURFACE)
         {
-            IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)res;
+            IWineD3DSurfaceImpl *surface = surface_from_resource(resource);
             if (surface->palette == palette)
                 surface->surface_ops->surface_realize_palette(surface);
         }
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index d43cdfa..5a9d5d6 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -43,30 +43,28 @@ struct private_data
     DWORD size;
 };
 
-HRESULT resource_init(struct IWineD3DResourceImpl *resource, WINED3DRESOURCETYPE resource_type,
+HRESULT resource_init(struct wined3d_resource *resource, WINED3DRESOURCETYPE resource_type,
         IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct wined3d_format *format,
         WINED3DPOOL pool, void *parent, const struct wined3d_parent_ops *parent_ops,
         const struct wined3d_resource_ops *resource_ops)
 {
-    struct IWineD3DResourceClass *r = &resource->resource;
-
-    r->device = device;
-    r->resourceType = resource_type;
-    r->ref = 1;
-    r->pool = pool;
-    r->format = format;
-    r->usage = usage;
-    r->size = size;
-    r->priority = 0;
-    r->parent = parent;
-    r->parent_ops = parent_ops;
-    r->resource_ops = resource_ops;
-    list_init(&r->privateData);
+    resource->device = device;
+    resource->resourceType = resource_type;
+    resource->ref = 1;
+    resource->pool = pool;
+    resource->format = format;
+    resource->usage = usage;
+    resource->size = size;
+    resource->priority = 0;
+    resource->parent = parent;
+    resource->parent_ops = parent_ops;
+    resource->resource_ops = resource_ops;
+    list_init(&resource->privateData);
 
     if (size)
     {
-        r->heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + RESOURCE_ALIGNMENT);
-        if (!r->heapMemory)
+        resource->heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + RESOURCE_ALIGNMENT);
+        if (!resource->heapMemory)
         {
             ERR("Out of memory!\n");
             return WINED3DERR_OUTOFVIDEOMEMORY;
@@ -74,9 +72,10 @@ HRESULT resource_init(struct IWineD3DResourceImpl *resource, WINED3DRESOURCETYPE
     }
     else
     {
-        r->heapMemory = NULL;
+        resource->heapMemory = NULL;
     }
-    r->allocatedMemory = (BYTE *)(((ULONG_PTR)r->heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+    resource->allocatedMemory = (BYTE *)(((ULONG_PTR)resource->heapMemory
+            + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
 
     /* Check that we have enough video ram left */
     if (pool == WINED3DPOOL_DEFAULT)
@@ -84,7 +83,7 @@ HRESULT resource_init(struct IWineD3DResourceImpl *resource, WINED3DRESOURCETYPE
         if (size > IWineD3DDevice_GetAvailableTextureMem((IWineD3DDevice *)device))
         {
             ERR("Out of adapter memory\n");
-            HeapFree(GetProcessHeap(), 0, r->heapMemory);
+            HeapFree(GetProcessHeap(), 0, resource->heapMemory);
             return WINED3DERR_OUTOFVIDEOMEMORY;
         }
         WineD3DAdapterChangeGLRam(device, size);
@@ -95,7 +94,7 @@ HRESULT resource_init(struct IWineD3DResourceImpl *resource, WINED3DRESOURCETYPE
     return WINED3D_OK;
 }
 
-void resource_cleanup(struct IWineD3DResourceImpl *resource)
+void resource_cleanup(struct wined3d_resource *resource)
 {
     struct private_data *data;
     struct list *e1, *e2;
@@ -103,13 +102,13 @@ void resource_cleanup(struct IWineD3DResourceImpl *resource)
 
     TRACE("Cleaning up resource %p.\n", resource);
 
-    if (resource->resource.pool == WINED3DPOOL_DEFAULT)
+    if (resource->pool == WINED3DPOOL_DEFAULT)
     {
-        TRACE("Decrementing device memory pool by %u.\n", resource->resource.size);
-        WineD3DAdapterChangeGLRam(resource->resource.device, -resource->resource.size);
+        TRACE("Decrementing device memory pool by %u.\n", resource->size);
+        WineD3DAdapterChangeGLRam(resource->device, -resource->size);
     }
 
-    LIST_FOR_EACH_SAFE(e1, e2, &resource->resource.privateData)
+    LIST_FOR_EACH_SAFE(e1, e2, &resource->privateData)
     {
         data = LIST_ENTRY(e1, struct private_data, entry);
         hr = resource_free_private_data(resource, &data->tag);
@@ -117,27 +116,27 @@ void resource_cleanup(struct IWineD3DResourceImpl *resource)
             ERR("Failed to free private data when destroying resource %p, hr = %#x.\n", resource, hr);
     }
 
-    HeapFree(GetProcessHeap(), 0, resource->resource.heapMemory);
-    resource->resource.allocatedMemory = 0;
-    resource->resource.heapMemory = 0;
+    HeapFree(GetProcessHeap(), 0, resource->heapMemory);
+    resource->allocatedMemory = 0;
+    resource->heapMemory = 0;
 
-    if (resource->resource.device)
-        device_resource_released(resource->resource.device, resource);
+    if (resource->device)
+        device_resource_released(resource->device, resource);
 }
 
-void resource_unload(IWineD3DResourceImpl *resource)
+void resource_unload(struct wined3d_resource *resource)
 {
-    context_resource_unloaded(resource->resource.device,
-            resource, resource->resource.resourceType);
+    context_resource_unloaded(resource->device,
+            resource, resource->resourceType);
 }
 
-static struct private_data *resource_find_private_data(const struct IWineD3DResourceImpl *This, REFGUID tag)
+static struct private_data *resource_find_private_data(const struct wined3d_resource *resource, REFGUID tag)
 {
     struct private_data *data;
     struct list *entry;
 
     TRACE("Searching for private data %s\n", debugstr_guid(tag));
-    LIST_FOR_EACH(entry, &This->resource.privateData)
+    LIST_FOR_EACH(entry, &resource->privateData)
     {
         data = LIST_ENTRY(entry, struct private_data, entry);
         if (IsEqualGUID(&data->tag, tag)) {
@@ -149,7 +148,7 @@ static struct private_data *resource_find_private_data(const struct IWineD3DReso
     return NULL;
 }
 
-HRESULT resource_set_private_data(struct IWineD3DResourceImpl *resource, REFGUID guid,
+HRESULT resource_set_private_data(struct wined3d_resource *resource, REFGUID guid,
         const void *data, DWORD data_size, DWORD flags)
 {
     struct private_data *d;
@@ -188,12 +187,12 @@ HRESULT resource_set_private_data(struct IWineD3DResourceImpl *resource, REFGUID
         d->size = data_size;
         memcpy(d->ptr.data, data, data_size);
     }
-    list_add_tail(&resource->resource.privateData, &d->entry);
+    list_add_tail(&resource->privateData, &d->entry);
 
     return WINED3D_OK;
 }
 
-HRESULT resource_get_private_data(const struct IWineD3DResourceImpl *resource, REFGUID guid, void *data, DWORD *data_size)
+HRESULT resource_get_private_data(const struct wined3d_resource *resource, REFGUID guid, void *data, DWORD *data_size)
 {
     const struct private_data *d;
 
@@ -212,7 +211,7 @@ HRESULT resource_get_private_data(const struct IWineD3DResourceImpl *resource, R
     if (d->flags & WINED3DSPD_IUNKNOWN)
     {
         *(IUnknown **)data = d->ptr.object;
-        if (resource->resource.device->wined3d->dxVersion != 7)
+        if (resource->device->wined3d->dxVersion != 7)
         {
             /* D3D8 and D3D9 addref the private data, DDraw does not. This
              * can't be handled in ddraw because it doesn't know if the
@@ -227,7 +226,7 @@ HRESULT resource_get_private_data(const struct IWineD3DResourceImpl *resource, R
 
     return WINED3D_OK;
 }
-HRESULT resource_free_private_data(struct IWineD3DResourceImpl *resource, REFGUID guid)
+HRESULT resource_free_private_data(struct wined3d_resource *resource, REFGUID guid)
 {
     struct private_data *data;
 
@@ -252,22 +251,27 @@ HRESULT resource_free_private_data(struct IWineD3DResourceImpl *resource, REFGUI
     return WINED3D_OK;
 }
 
-DWORD resource_set_priority(struct IWineD3DResourceImpl *resource, DWORD priority)
+DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority)
 {
-    DWORD prev = resource->resource.priority;
-    resource->resource.priority = priority;
+    DWORD prev = resource->priority;
+    resource->priority = priority;
     TRACE("resource %p, new priority %u, returning old priority %u.\n", resource, priority, prev);
     return prev;
 }
 
-DWORD resource_get_priority(const struct IWineD3DResourceImpl *resource)
+DWORD resource_get_priority(const struct wined3d_resource *resource)
 {
-    TRACE("resource %p, returning %u.\n", resource, resource->resource.priority);
-    return resource->resource.priority;
+    TRACE("resource %p, returning %u.\n", resource, resource->priority);
+    return resource->priority;
 }
 
-WINED3DRESOURCETYPE resource_get_type(const struct IWineD3DResourceImpl *resource)
+WINED3DRESOURCETYPE resource_get_type(const struct wined3d_resource *resource)
 {
-    TRACE("resource %p, returning %#x.\n", resource, resource->resource.resourceType);
-    return resource->resource.resourceType;
+    TRACE("resource %p, returning %#x.\n", resource, resource->resourceType);
+    return resource->resourceType;
+}
+
+void * CDECL wined3d_resource_get_parent(const struct wined3d_resource *resource)
+{
+    return resource->parent;
 }
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 2761ca4..1f9a7fd 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -503,7 +503,7 @@ static void state_alpha(DWORD state, struct wined3d_stateblock *stateblock, stru
 
         if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
         {
-            IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
+            IWineD3DSurfaceImpl *surf = surface_from_resource(texture->baseTexture.sub_resources[0]);
 
             if (surf->CKeyFlags & WINEDDSD_CKSRCBLT)
             {
@@ -3196,7 +3196,7 @@ void tex_alphaop(DWORD state, struct wined3d_stateblock *stateblock, struct wine
 
         if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
         {
-            IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
+            IWineD3DSurfaceImpl *surf = surface_from_resource(texture->baseTexture.sub_resources[0]);
 
             if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
             {
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 1021c63..b0f9dc6 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -89,7 +89,7 @@ static void surface_cleanup(IWineD3DSurfaceImpl *This)
 
     HeapFree(GetProcessHeap(), 0, This->palette9);
 
-    resource_cleanup((IWineD3DResourceImpl *)This);
+    resource_cleanup(&This->resource);
 }
 
 void surface_set_container(IWineD3DSurfaceImpl *surface, enum wined3d_container_type type, IWineD3DBase *container)
@@ -433,17 +433,17 @@ static void surface_remove_pbo(IWineD3DSurfaceImpl *surface, const struct wined3
 }
 
 /* Do not call while under the GL lock. */
-static void surface_unload(IWineD3DResourceImpl *resource)
+static void surface_unload(struct wined3d_resource *resource)
 {
-    IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)resource;
-    IWineD3DDeviceImpl *device = resource->resource.device;
+    IWineD3DSurfaceImpl *surface = surface_from_resource(resource);
+    IWineD3DDeviceImpl *device = resource->device;
     const struct wined3d_gl_info *gl_info;
     renderbuffer_entry_t *entry, *entry2;
     struct wined3d_context *context;
 
     TRACE("surface %p.\n", surface);
 
-    if (resource->resource.pool == WINED3DPOOL_DEFAULT)
+    if (resource->pool == WINED3DPOOL_DEFAULT)
     {
         /* Default pool resources are supposed to be destroyed before Reset is called.
          * Implicit resources stay however. So this means we have an implicit render target
@@ -597,8 +597,8 @@ HRESULT surface_init(IWineD3DSurfaceImpl *surface, WINED3DSURFTYPE surface_type,
             return WINED3DERR_INVALIDCALL;
     }
 
-    hr = resource_init((IWineD3DResourceImpl *)surface, WINED3DRTYPE_SURFACE, device,
-            resource_size, usage, format, pool, parent, parent_ops, &surface_resource_ops);
+    hr = resource_init(&surface->resource, WINED3DRTYPE_SURFACE, device, resource_size,
+            usage, format, pool, parent, parent_ops, &surface_resource_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, returning %#x.\n", hr);
@@ -1751,7 +1751,7 @@ void surface_prepare_texture(IWineD3DSurfaceImpl *surface, const struct wined3d_
 
         for (i = 0; i < sub_count; ++i)
         {
-            IWineD3DSurfaceImpl *s = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i];
+            IWineD3DSurfaceImpl *s = surface_from_resource(texture->baseTexture.sub_resources[i]);
             surface_prepare_texture_internal(s, gl_info, srgb);
         }
 
@@ -2761,8 +2761,8 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) {
         back->texture_name_srgb = front->texture_name_srgb;
         front->texture_name_srgb = tmp;
 
-        resource_unload((IWineD3DResourceImpl *)back);
-        resource_unload((IWineD3DResourceImpl *)front);
+        resource_unload(&back->resource);
+        resource_unload(&front->resource);
     }
 
     {
@@ -4685,6 +4685,7 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
     IWineD3DSurfaceImpl_PreLoad,
     IWineD3DBaseSurfaceImpl_GetType,
     /* IWineD3DSurface */
+    IWineD3DBaseSurfaceImpl_GetResource,
     IWineD3DBaseSurfaceImpl_GetDesc,
     IWineD3DSurfaceImpl_Map,
     IWineD3DSurfaceImpl_Unmap,
diff --git a/dlls/wined3d/surface_base.c b/dlls/wined3d/surface_base.c
index 65d6327..37a1309 100644
--- a/dlls/wined3d/surface_base.c
+++ b/dlls/wined3d/surface_base.c
@@ -114,33 +114,33 @@ ULONG WINAPI IWineD3DBaseSurfaceImpl_AddRef(IWineD3DSurface *iface) {
 HRESULT WINAPI IWineD3DBaseSurfaceImpl_SetPrivateData(IWineD3DSurface *iface,
         REFGUID riid, const void *data, DWORD data_size, DWORD flags)
 {
-    return resource_set_private_data((IWineD3DResourceImpl *)iface, riid, data, data_size, flags);
+    return resource_set_private_data(&((IWineD3DSurfaceImpl *)iface)->resource, riid, data, data_size, flags);
 }
 
 HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetPrivateData(IWineD3DSurface *iface,
         REFGUID guid, void *data, DWORD *data_size)
 {
-    return resource_get_private_data((IWineD3DResourceImpl *)iface, guid, data, data_size);
+    return resource_get_private_data(&((IWineD3DSurfaceImpl *)iface)->resource, guid, data, data_size);
 }
 
 HRESULT WINAPI IWineD3DBaseSurfaceImpl_FreePrivateData(IWineD3DSurface *iface, REFGUID refguid)
 {
-    return resource_free_private_data((IWineD3DResourceImpl *)iface, refguid);
+    return resource_free_private_data(&((IWineD3DSurfaceImpl *)iface)->resource, refguid);
 }
 
 DWORD WINAPI IWineD3DBaseSurfaceImpl_SetPriority(IWineD3DSurface *iface, DWORD priority)
 {
-    return resource_set_priority((IWineD3DResourceImpl *)iface, priority);
+    return resource_set_priority(&((IWineD3DSurfaceImpl *)iface)->resource, priority);
 }
 
 DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPriority(IWineD3DSurface *iface)
 {
-    return resource_get_priority((IWineD3DResourceImpl *)iface);
+    return resource_get_priority(&((IWineD3DSurfaceImpl *)iface)->resource);
 }
 
 WINED3DRESOURCETYPE WINAPI IWineD3DBaseSurfaceImpl_GetType(IWineD3DSurface *iface)
 {
-    return resource_get_type((IWineD3DResourceImpl *)iface);
+    return resource_get_type(&((IWineD3DSurfaceImpl *)iface)->resource);
 }
 
 void * WINAPI IWineD3DBaseSurfaceImpl_GetParent(IWineD3DSurface *iface)
@@ -150,6 +150,13 @@ void * WINAPI IWineD3DBaseSurfaceImpl_GetParent(IWineD3DSurface *iface)
     return ((IWineD3DSurfaceImpl *)iface)->resource.parent;
 }
 
+struct wined3d_resource * WINAPI IWineD3DBaseSurfaceImpl_GetResource(IWineD3DSurface *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return &((IWineD3DSurfaceImpl *)iface)->resource;
+}
+
 void WINAPI IWineD3DBaseSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSURFACE_DESC *desc)
 {
     IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)iface;
diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c
index 858dc9b..d91bb00 100644
--- a/dlls/wined3d/surface_gdi.c
+++ b/dlls/wined3d/surface_gdi.c
@@ -54,7 +54,7 @@ void surface_gdi_cleanup(IWineD3DSurfaceImpl *This)
 
     HeapFree(GetProcessHeap(), 0, This->palette9);
 
-    resource_cleanup((IWineD3DResourceImpl *)This);
+    resource_cleanup(&This->resource);
 }
 
 static void gdi_surface_realize_palette(IWineD3DSurfaceImpl *surface)
@@ -451,6 +451,7 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl =
     IWineGDISurfaceImpl_PreLoad,
     IWineD3DBaseSurfaceImpl_GetType,
     /* IWineD3DSurface */
+    IWineD3DBaseSurfaceImpl_GetResource,
     IWineD3DBaseSurfaceImpl_GetDesc,
     IWineGDISurfaceImpl_Map,
     IWineGDISurfaceImpl_Unmap,
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 1c629eb..df52996 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -48,7 +48,7 @@ static HRESULT texture_bind(IWineD3DBaseTextureImpl *texture, BOOL srgb)
 
         for (i = 0; i < texture->baseTexture.level_count; ++i)
         {
-            IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i];
+            IWineD3DSurfaceImpl *surface = surface_from_resource(texture->baseTexture.sub_resources[i]);
             surface_set_texture_name(surface, gl_tex->name, texture->baseTexture.is_srgb);
         }
 
@@ -128,7 +128,7 @@ static void texture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSRGB s
     {
         for (i = 0; i < texture->baseTexture.level_count; ++i)
         {
-            IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i];
+            IWineD3DSurfaceImpl *surface = surface_from_resource(texture->baseTexture.sub_resources[i]);
             if (palette9_changed(surface))
             {
                 TRACE("Reloading surface because the d3d8/9 palette was changed.\n");
@@ -146,7 +146,7 @@ static void texture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSRGB s
     {
         for (i = 0; i < texture->baseTexture.level_count; ++i)
         {
-            surface_load((IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i], srgb_mode);
+            surface_load(surface_from_resource(texture->baseTexture.sub_resources[i]), srgb_mode);
         }
     }
     else
@@ -161,18 +161,19 @@ static void texture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSRGB s
 }
 
 /* Do not call while under the GL lock. */
-static void texture_unload(IWineD3DResourceImpl *resource)
+static void texture_unload(struct wined3d_resource *resource)
 {
-    IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)resource;
+    IWineD3DBaseTextureImpl *texture = basetexture_from_resource(resource);
     unsigned int i;
 
     TRACE("texture %p.\n", texture);
 
     for (i = 0; i < texture->baseTexture.level_count; ++i)
     {
-        IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i];
+        struct wined3d_resource *sub_resource = texture->baseTexture.sub_resources[i];
+        IWineD3DSurfaceImpl *surface = surface_from_resource(sub_resource);
 
-        surface->resource.resource_ops->resource_unload((IWineD3DResourceImpl *)surface);
+        sub_resource->resource_ops->resource_unload(sub_resource);
         surface_set_texture_name(surface, 0, FALSE); /* Delete rgb name */
         surface_set_texture_name(surface, 0, TRUE); /* delete srgb name */
     }
@@ -199,7 +200,7 @@ static void texture_cleanup(IWineD3DTextureImpl *This)
 
     for (i = 0; i < This->baseTexture.level_count; ++i)
     {
-        IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
+        IWineD3DSurfaceImpl *surface = surface_from_resource(This->baseTexture.sub_resources[i]);
         if (surface)
         {
             /* Clean out the texture name we gave to the surface so that the
@@ -265,28 +266,28 @@ static ULONG WINAPI IWineD3DTextureImpl_Release(IWineD3DTexture *iface) {
 static HRESULT WINAPI IWineD3DTextureImpl_SetPrivateData(IWineD3DTexture *iface,
         REFGUID riid, const void *data, DWORD data_size, DWORD flags)
 {
-    return resource_set_private_data((IWineD3DResourceImpl *)iface, riid, data, data_size, flags);
+    return resource_set_private_data(&((IWineD3DTextureImpl *)iface)->resource, riid, data, data_size, flags);
 }
 
 static HRESULT WINAPI IWineD3DTextureImpl_GetPrivateData(IWineD3DTexture *iface,
         REFGUID guid, void *data, DWORD *data_size)
 {
-    return resource_get_private_data((IWineD3DResourceImpl *)iface, guid, data, data_size);
+    return resource_get_private_data(&((IWineD3DTextureImpl *)iface)->resource, guid, data, data_size);
 }
 
 static HRESULT WINAPI IWineD3DTextureImpl_FreePrivateData(IWineD3DTexture *iface, REFGUID refguid)
 {
-    return resource_free_private_data((IWineD3DResourceImpl *)iface, refguid);
+    return resource_free_private_data(&((IWineD3DTextureImpl *)iface)->resource, refguid);
 }
 
 static DWORD WINAPI IWineD3DTextureImpl_SetPriority(IWineD3DTexture *iface, DWORD priority)
 {
-    return resource_set_priority((IWineD3DResourceImpl *)iface, priority);
+    return resource_set_priority(&((IWineD3DTextureImpl *)iface)->resource, priority);
 }
 
 static DWORD WINAPI IWineD3DTextureImpl_GetPriority(IWineD3DTexture *iface)
 {
-    return resource_get_priority((IWineD3DResourceImpl *)iface);
+    return resource_get_priority(&((IWineD3DTextureImpl *)iface)->resource);
 }
 
 /* Do not call while under the GL lock. */
@@ -297,7 +298,7 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface)
 
 static WINED3DRESOURCETYPE WINAPI IWineD3DTextureImpl_GetType(IWineD3DTexture *iface)
 {
-    return resource_get_type((IWineD3DResourceImpl *)iface);
+    return resource_get_type(&((IWineD3DTextureImpl *)iface)->resource);
 }
 
 static void * WINAPI IWineD3DTextureImpl_GetParent(IWineD3DTexture *iface)
@@ -350,17 +351,17 @@ static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface,
         UINT sub_resource_idx, WINED3DSURFACE_DESC *desc)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DSurface *surface;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u, desc %p.\n", iface, sub_resource_idx, desc);
 
-    if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    IWineD3DSurface_GetDesc(surface, desc);
+    IWineD3DSurface_GetDesc((IWineD3DSurface *)surface_from_resource(sub_resource), desc);
 
     return WINED3D_OK;
 }
@@ -369,18 +370,18 @@ static HRESULT WINAPI IWineD3DTextureImpl_GetSurfaceLevel(IWineD3DTexture *iface
         UINT sub_resource_idx, IWineD3DSurface **surface)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DSurface *s;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u, surface %p.\n", iface, sub_resource_idx, surface);
 
-    if (!(s = (IWineD3DSurface *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    IWineD3DSurface_AddRef(s);
-    *surface = s;
+    *surface = (IWineD3DSurface *)surface_from_resource(sub_resource);
+    IWineD3DSurface_AddRef(*surface);
 
     TRACE("Returning surface %p.\n", *surface);
 
@@ -391,44 +392,44 @@ static HRESULT WINAPI IWineD3DTextureImpl_Map(IWineD3DTexture *iface,
         UINT sub_resource_idx, WINED3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DSurface *surface;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u, locked_rect %p, rect %s, flags %#x.\n",
             iface, sub_resource_idx, locked_rect, wine_dbgstr_rect(rect), flags);
 
-    if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    return IWineD3DSurface_Map(surface, locked_rect, rect, flags);
+    return IWineD3DSurface_Map((IWineD3DSurface *)surface_from_resource(sub_resource), locked_rect, rect, flags);
 }
 
 static HRESULT WINAPI IWineD3DTextureImpl_Unmap(IWineD3DTexture *iface, UINT sub_resource_idx)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DSurface *surface;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx);
 
-    if (!(surface = (IWineD3DSurface *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    return IWineD3DSurface_Unmap(surface);
+    return IWineD3DSurface_Unmap((IWineD3DSurface *)surface_from_resource(sub_resource));
 }
 
 static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, const RECT *dirty_rect)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DSurfaceImpl *surface;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, dirty_rect %s.\n", iface, wine_dbgstr_rect(dirty_rect));
 
-    if (!(surface = (IWineD3DSurfaceImpl *)basetexture_get_sub_resource(texture, 0)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, 0)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
@@ -436,7 +437,7 @@ static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, c
 
     texture->baseTexture.texture_rgb.dirty = TRUE;
     texture->baseTexture.texture_srgb.dirty = TRUE;
-    surface_add_dirty_rect(surface, dirty_rect);
+    surface_add_dirty_rect(surface_from_resource(sub_resource), dirty_rect);
 
     return WINED3D_OK;
 }
@@ -625,7 +626,7 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT
 
         surface_set_container((IWineD3DSurfaceImpl *)surface, WINED3D_CONTAINER_TEXTURE, (IWineD3DBase *)texture);
         surface_set_texture_target((IWineD3DSurfaceImpl *)surface, texture->baseTexture.target);
-        texture->baseTexture.sub_resources[i] = (IWineD3DResourceImpl *)surface;
+        texture->baseTexture.sub_resources[i] = &((IWineD3DSurfaceImpl *)surface)->resource;
         TRACE("Created surface level %u @ %p.\n", i, surface);
         /* Calculate the next mipmap level. */
         tmp_w = max(1, tmp_w >> 1);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 4c91644..07a2a74 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -2858,7 +2858,7 @@ void gen_ffp_frag_op(struct wined3d_stateblock *stateblock, struct ffp_frag_sett
 
             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
             {
-                IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
+                IWineD3DSurfaceImpl *surf = surface_from_resource(texture->baseTexture.sub_resources[0]);
 
                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
                 {
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 2b98de3..ab1c831 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -65,7 +65,6 @@ static ULONG STDMETHODCALLTYPE rendertarget_view_Release(IWineD3DRendertargetVie
 
     if (!refcount)
     {
-        IWineD3DResource_Release((IWineD3DResource *)This->resource);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -84,12 +83,11 @@ static void * STDMETHODCALLTYPE rendertarget_view_GetParent(IWineD3DRendertarget
 /* IWineD3DRendertargetView methods */
 
 static HRESULT STDMETHODCALLTYPE rendertarget_view_GetResource(IWineD3DRendertargetView *iface,
-        IWineD3DResource **resource)
+        struct wined3d_resource **resource)
 {
     struct wined3d_rendertarget_view *This = (struct wined3d_rendertarget_view *)iface;
 
-    IWineD3DResource_AddRef((IWineD3DResource *)This->resource);
-    *resource = (IWineD3DResource *)This->resource;
+    *resource = This->resource;
 
     return WINED3D_OK;
 }
@@ -107,11 +105,10 @@ static const struct IWineD3DRendertargetViewVtbl wined3d_rendertarget_view_vtbl
 };
 
 void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view,
-        struct IWineD3DResourceImpl *resource, void *parent)
+        struct wined3d_resource *resource, void *parent)
 {
     view->vtbl = &wined3d_rendertarget_view_vtbl;
     view->refcount = 1;
-    IWineD3DResource_AddRef((IWineD3DResource *)resource);
     view->resource = resource;
     view->parent = parent;
 }
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index e5d3cd7..7c98cc9 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -119,7 +119,7 @@ void volume_load(IWineD3DVolumeImpl *volume, UINT level, BOOL srgb_mode)
 }
 
 /* Do not call while under the GL lock. */
-static void volume_unload(IWineD3DResourceImpl *resource)
+static void volume_unload(struct wined3d_resource *resource)
 {
     TRACE("texture %p.\n", resource);
 
@@ -167,7 +167,7 @@ static ULONG WINAPI IWineD3DVolumeImpl_Release(IWineD3DVolume *iface) {
 
     if (!ref)
     {
-        resource_cleanup((IWineD3DResourceImpl *)iface);
+        resource_cleanup(&This->resource);
         This->resource.parent_ops->wined3d_object_destroyed(This->resource.parent);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -187,28 +187,28 @@ static void * WINAPI IWineD3DVolumeImpl_GetParent(IWineD3DVolume *iface)
 static HRESULT WINAPI IWineD3DVolumeImpl_SetPrivateData(IWineD3DVolume *iface,
         REFGUID riid, const void *data, DWORD data_size, DWORD flags)
 {
-    return resource_set_private_data((IWineD3DResourceImpl *)iface, riid, data, data_size, flags);
+    return resource_set_private_data(&((IWineD3DVolumeImpl *)iface)->resource, riid, data, data_size, flags);
 }
 
 static HRESULT WINAPI IWineD3DVolumeImpl_GetPrivateData(IWineD3DVolume *iface,
         REFGUID guid, void *data, DWORD *data_size)
 {
-    return resource_get_private_data((IWineD3DResourceImpl *)iface, guid, data, data_size);
+    return resource_get_private_data(&((IWineD3DVolumeImpl *)iface)->resource, guid, data, data_size);
 }
 
 static HRESULT WINAPI IWineD3DVolumeImpl_FreePrivateData(IWineD3DVolume *iface, REFGUID refguid)
 {
-    return resource_free_private_data((IWineD3DResourceImpl *)iface, refguid);
+    return resource_free_private_data(&((IWineD3DVolumeImpl *)iface)->resource, refguid);
 }
 
 static DWORD WINAPI IWineD3DVolumeImpl_SetPriority(IWineD3DVolume *iface, DWORD priority)
 {
-    return resource_set_priority((IWineD3DResourceImpl *)iface, priority);
+    return resource_set_priority(&((IWineD3DVolumeImpl *)iface)->resource, priority);
 }
 
 static DWORD WINAPI IWineD3DVolumeImpl_GetPriority(IWineD3DVolume *iface)
 {
-    return resource_get_priority((IWineD3DResourceImpl *)iface);
+    return resource_get_priority(&((IWineD3DVolumeImpl *)iface)->resource);
 }
 
 /* Do not call while under the GL lock. */
@@ -218,7 +218,7 @@ static void WINAPI IWineD3DVolumeImpl_PreLoad(IWineD3DVolume *iface) {
 
 static WINED3DRESOURCETYPE WINAPI IWineD3DVolumeImpl_GetType(IWineD3DVolume *iface)
 {
-    return resource_get_type((IWineD3DResourceImpl *)iface);
+    return resource_get_type(&((IWineD3DVolumeImpl *)iface)->resource);
 }
 
 static void WINAPI IWineD3DVolumeImpl_GetDesc(IWineD3DVolume *iface, WINED3DVOLUME_DESC *desc)
@@ -344,7 +344,7 @@ HRESULT volume_init(IWineD3DVolumeImpl *volume, IWineD3DDeviceImpl *device, UINT
 
     volume->lpVtbl = &IWineD3DVolume_Vtbl;
 
-    hr = resource_init((IWineD3DResourceImpl *)volume, WINED3DRTYPE_VOLUME, device,
+    hr = resource_init(&volume->resource, WINED3DRTYPE_VOLUME, device,
             width * height * depth * format->byte_count, usage, format, pool,
             parent, parent_ops, &volume_resource_ops);
     if (FAILED(hr))
diff --git a/dlls/wined3d/volumetexture.c b/dlls/wined3d/volumetexture.c
index 757cd96..6ebd1c2 100644
--- a/dlls/wined3d/volumetexture.c
+++ b/dlls/wined3d/volumetexture.c
@@ -61,14 +61,14 @@ static void volumetexture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3D
     {
         for (i = 0; i < texture->baseTexture.level_count; ++i)
         {
-            volume_load((IWineD3DVolumeImpl *)texture->baseTexture.sub_resources[i], i, srgb_mode);
+            volume_load(volume_from_resource(texture->baseTexture.sub_resources[i]), i, srgb_mode);
         }
     }
     else if (srgb_was_toggled)
     {
         for (i = 0; i < texture->baseTexture.level_count; ++i)
         {
-            IWineD3DVolumeImpl *volume = (IWineD3DVolumeImpl *)texture->baseTexture.sub_resources[i];
+            IWineD3DVolumeImpl *volume = volume_from_resource(texture->baseTexture.sub_resources[i]);
             volume_add_dirty_box(volume, NULL);
             volume_load(volume, i, srgb_mode);
         }
@@ -85,17 +85,17 @@ static void volumetexture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3D
 }
 
 /* Do not call while under the GL lock. */
-static void volumetexture_unload(IWineD3DResourceImpl *resource)
+static void volumetexture_unload(struct wined3d_resource *resource)
 {
-    IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)resource;
+    IWineD3DBaseTextureImpl *texture = basetexture_from_resource(resource);
     unsigned int i;
 
     TRACE("texture %p.\n", texture);
 
     for (i = 0; i < texture->baseTexture.level_count; ++i)
     {
-        IWineD3DResourceImpl *resource = texture->baseTexture.sub_resources[i];
-        resource->resource.resource_ops->resource_unload(resource);
+        struct wined3d_resource *sub_resource = texture->baseTexture.sub_resources[i];
+        sub_resource->resource_ops->resource_unload(sub_resource);
     }
 
     basetexture_unload(texture);
@@ -120,7 +120,7 @@ static void volumetexture_cleanup(IWineD3DVolumeTextureImpl *This)
 
     for (i = 0; i < This->baseTexture.level_count; ++i)
     {
-        IWineD3DVolumeImpl *volume = (IWineD3DVolumeImpl *)This->baseTexture.sub_resources[i];
+        IWineD3DVolumeImpl *volume = volume_from_resource(This->baseTexture.sub_resources[i]);
 
         if (volume)
         {
@@ -180,28 +180,28 @@ static ULONG WINAPI IWineD3DVolumeTextureImpl_Release(IWineD3DVolumeTexture *ifa
 static HRESULT WINAPI IWineD3DVolumeTextureImpl_SetPrivateData(IWineD3DVolumeTexture *iface,
         REFGUID riid, const void *data, DWORD data_size, DWORD flags)
 {
-    return resource_set_private_data((IWineD3DResourceImpl *)iface, riid, data, data_size, flags);
+    return resource_set_private_data(&((IWineD3DVolumeTextureImpl *)iface)->resource, riid, data, data_size, flags);
 }
 
 static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetPrivateData(IWineD3DVolumeTexture *iface,
         REFGUID guid, void *data, DWORD *data_size)
 {
-    return resource_get_private_data((IWineD3DResourceImpl *)iface, guid, data, data_size);
+    return resource_get_private_data(&((IWineD3DVolumeTextureImpl *)iface)->resource, guid, data, data_size);
 }
 
 static HRESULT WINAPI IWineD3DVolumeTextureImpl_FreePrivateData(IWineD3DVolumeTexture *iface, REFGUID refguid)
 {
-    return resource_free_private_data((IWineD3DResourceImpl *)iface, refguid);
+    return resource_free_private_data(&((IWineD3DVolumeTextureImpl *)iface)->resource, refguid);
 }
 
 static DWORD WINAPI IWineD3DVolumeTextureImpl_SetPriority(IWineD3DVolumeTexture *iface, DWORD priority)
 {
-    return resource_set_priority((IWineD3DResourceImpl *)iface, priority);
+    return resource_set_priority(&((IWineD3DVolumeTextureImpl *)iface)->resource, priority);
 }
 
 static DWORD WINAPI IWineD3DVolumeTextureImpl_GetPriority(IWineD3DVolumeTexture *iface)
 {
-    return resource_get_priority((IWineD3DResourceImpl *)iface);
+    return resource_get_priority(&((IWineD3DVolumeTextureImpl *)iface)->resource);
 }
 
 static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *iface)
@@ -211,7 +211,7 @@ static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *ifac
 
 static WINED3DRESOURCETYPE WINAPI IWineD3DVolumeTextureImpl_GetType(IWineD3DVolumeTexture *iface)
 {
-    return resource_get_type((IWineD3DResourceImpl *)iface);
+    return resource_get_type(&((IWineD3DVolumeTextureImpl *)iface)->resource);
 }
 
 static void * WINAPI IWineD3DVolumeTextureImpl_GetParent(IWineD3DVolumeTexture *iface)
@@ -264,17 +264,17 @@ static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetLevelDesc(IWineD3DVolumeTextu
         UINT sub_resource_idx, WINED3DVOLUME_DESC *desc)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DVolume *volume;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u, desc %p.\n", iface, sub_resource_idx, desc);
 
-    if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    IWineD3DVolume_GetDesc(volume, desc);
+    IWineD3DVolume_GetDesc((IWineD3DVolume *)volume_from_resource(sub_resource), desc);
 
     return WINED3D_OK;
 }
@@ -283,18 +283,18 @@ static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetVolumeLevel(IWineD3DVolumeTex
         UINT sub_resource_idx, IWineD3DVolume **volume)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DVolume *v;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u, volume %p.\n", iface, sub_resource_idx, volume);
 
-    if (!(v= (IWineD3DVolume *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    IWineD3DVolume_AddRef(v);
-    *volume = v;
+    *volume = (IWineD3DVolume *)volume_from_resource(sub_resource);
+    IWineD3DVolume_AddRef(*volume);
 
     TRACE("Returning volume %p.\n", *volume);
 
@@ -305,44 +305,45 @@ static HRESULT WINAPI IWineD3DVolumeTextureImpl_Map(IWineD3DVolumeTexture *iface
         UINT sub_resource_idx, WINED3DLOCKED_BOX *locked_box, const WINED3DBOX *box, DWORD flags)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DVolume *volume;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u, locked_box %p, box %p, flags %#x.\n",
             iface, sub_resource_idx, locked_box, box, flags);
 
-    if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    return IWineD3DVolume_Map(volume, locked_box, box, flags);
+    return IWineD3DVolume_Map((IWineD3DVolume *)volume_from_resource(sub_resource),
+            locked_box, box, flags);
 }
 
 static HRESULT WINAPI IWineD3DVolumeTextureImpl_Unmap(IWineD3DVolumeTexture *iface, UINT sub_resource_idx)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DVolume *volume;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, sub_resource_idx %u.\n", iface, sub_resource_idx);
 
-    if (!(volume = (IWineD3DVolume *)basetexture_get_sub_resource(texture, sub_resource_idx)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, sub_resource_idx)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
     }
 
-    return IWineD3DVolume_Unmap(volume);
+    return IWineD3DVolume_Unmap((IWineD3DVolume *)volume_from_resource(sub_resource));
 }
 
 static HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTexture *iface, const WINED3DBOX *dirty_box)
 {
     IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)iface;
-    IWineD3DVolumeImpl *volume;
+    struct wined3d_resource *sub_resource;
 
     TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
 
-    if (!(volume = (IWineD3DVolumeImpl *)basetexture_get_sub_resource(texture, 0)))
+    if (!(sub_resource = basetexture_get_sub_resource(texture, 0)))
     {
         WARN("Failed to get sub-resource.\n");
         return WINED3DERR_INVALIDCALL;
@@ -350,7 +351,7 @@ static HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTextur
 
     texture->baseTexture.texture_rgb.dirty = TRUE;
     texture->baseTexture.texture_srgb.dirty = TRUE;
-    volume_add_dirty_box(volume, dirty_box);
+    volume_add_dirty_box(volume_from_resource(sub_resource), dirty_box);
 
     return WINED3D_OK;
 }
@@ -473,7 +474,7 @@ HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT
 
         /* Set its container to this texture. */
         volume_set_container((IWineD3DVolumeImpl *)volume, texture);
-        texture->baseTexture.sub_resources[i] = (IWineD3DResourceImpl *)volume;
+        texture->baseTexture.sub_resources[i] = &((IWineD3DVolumeImpl *)volume)->resource;
 
         /* Calculate the next mipmap level. */
         tmp_w = max(1, tmp_w >> 1);
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index b6562ee..971bf25 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -44,6 +44,8 @@
 @ cdecl wined3d_query_incref(ptr)
 @ cdecl wined3d_query_issue(ptr long)
 
+@ cdecl wined3d_resource_get_parent(ptr)
+
 @ cdecl wined3d_stateblock_apply(ptr)
 @ cdecl wined3d_stateblock_capture(ptr)
 @ cdecl wined3d_stateblock_decref(ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0cc9aaf..3b09fee 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -57,7 +57,6 @@ typedef struct IWineD3DDeviceImpl     IWineD3DDeviceImpl;
 typedef struct IWineD3DSwapChainImpl  IWineD3DSwapChainImpl;
 struct IWineD3DBaseShaderImpl;
 struct IWineD3DBaseTextureImpl;
-struct IWineD3DResourceImpl;
 
 /* Texture format fixups */
 
@@ -1227,9 +1226,9 @@ struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN;
 DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN;
 void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN;
 void context_resource_released(struct IWineD3DDeviceImpl *device,
-        struct IWineD3DResourceImpl *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN;
+        struct wined3d_resource *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN;
 void context_resource_unloaded(struct IWineD3DDeviceImpl *device,
-        struct IWineD3DResourceImpl *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN;
+        struct wined3d_resource *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN;
 BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN;
 void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN;
 void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN;
@@ -1776,8 +1775,8 @@ HRESULT device_init(IWineD3DDeviceImpl *device, struct wined3d *wined3d,
 void device_preload_textures(IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
 LRESULT device_process_message(IWineD3DDeviceImpl *device, HWND window, BOOL unicode,
         UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN;
-void device_resource_add(struct IWineD3DDeviceImpl *device, struct IWineD3DResourceImpl *resource) DECLSPEC_HIDDEN;
-void device_resource_released(struct IWineD3DDeviceImpl *device, struct IWineD3DResourceImpl *resource) DECLSPEC_HIDDEN;
+void device_resource_add(struct IWineD3DDeviceImpl *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+void device_resource_released(struct IWineD3DDeviceImpl *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
         BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup) DECLSPEC_HIDDEN;
 void device_switch_onscreen_ds(IWineD3DDeviceImpl *device, struct wined3d_context *context,
@@ -1795,15 +1794,12 @@ static inline BOOL isStateDirty(struct wined3d_context *context, DWORD state)
 
 struct wined3d_resource_ops
 {
-    void (*resource_unload)(struct IWineD3DResourceImpl *resource);
+    void (*resource_unload)(struct wined3d_resource *resource);
 };
 
-typedef struct IWineD3DResourceClass
+struct wined3d_resource
 {
-    /* IUnknown fields */
-    LONG                    ref;     /* Note: Ref counting not required */
-
-    /* WineD3DResource Information */
+    LONG ref;
     WINED3DRESOURCETYPE     resourceType;
     IWineD3DDeviceImpl *device;
     WINED3DPOOL             pool;
@@ -1819,29 +1815,22 @@ typedef struct IWineD3DResourceClass
     void *parent;
     const struct wined3d_parent_ops *parent_ops;
     const struct wined3d_resource_ops *resource_ops;
-} IWineD3DResourceClass;
+};
 
-typedef struct IWineD3DResourceImpl
-{
-    /* IUnknown & WineD3DResource Information     */
-    const IWineD3DResourceVtbl *lpVtbl;
-    IWineD3DResourceClass   resource;
-} IWineD3DResourceImpl;
-
-void resource_cleanup(struct IWineD3DResourceImpl *resource) DECLSPEC_HIDDEN;
-HRESULT resource_free_private_data(struct IWineD3DResourceImpl *resource, REFGUID guid) DECLSPEC_HIDDEN;
-DWORD resource_get_priority(const struct IWineD3DResourceImpl *resource) DECLSPEC_HIDDEN;
-HRESULT resource_get_private_data(const struct IWineD3DResourceImpl *resource, REFGUID guid,
+void resource_cleanup(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+HRESULT resource_free_private_data(struct wined3d_resource *resource, REFGUID guid) DECLSPEC_HIDDEN;
+DWORD resource_get_priority(const struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+HRESULT resource_get_private_data(const struct wined3d_resource *resource, REFGUID guid,
         void *data, DWORD *data_size) DECLSPEC_HIDDEN;
-HRESULT resource_init(struct IWineD3DResourceImpl *resource, WINED3DRESOURCETYPE resource_type,
+HRESULT resource_init(struct wined3d_resource *resource, WINED3DRESOURCETYPE resource_type,
         IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct wined3d_format *format,
         WINED3DPOOL pool, void *parent, const struct wined3d_parent_ops *parent_ops,
         const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN;
-WINED3DRESOURCETYPE resource_get_type(const struct IWineD3DResourceImpl *resource) DECLSPEC_HIDDEN;
-DWORD resource_set_priority(struct IWineD3DResourceImpl *resource, DWORD priority) DECLSPEC_HIDDEN;
-HRESULT resource_set_private_data(struct IWineD3DResourceImpl *resource, REFGUID guid,
+WINED3DRESOURCETYPE resource_get_type(const struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority) DECLSPEC_HIDDEN;
+HRESULT resource_set_private_data(struct wined3d_resource *resource, REFGUID guid,
         const void *data, DWORD data_size, DWORD flags) DECLSPEC_HIDDEN;
-void resource_unload(IWineD3DResourceImpl *resource) DECLSPEC_HIDDEN;
+void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 
 /* Tests show that the start address of resources is 32 byte aligned */
 #define RESOURCE_ALIGNMENT 16
@@ -1886,14 +1875,11 @@ struct wined3d_texture_ops
     void (*texture_preload)(struct IWineD3DBaseTextureImpl *texture, enum WINED3DSRGB srgb);
 };
 
-/*****************************************************************************
- * IWineD3DBaseTexture implementation structure (extends IWineD3DResourceImpl)
- */
 typedef struct IWineD3DBaseTextureClass
 {
     const struct wined3d_texture_ops *texture_ops;
     struct gl_texture       texture_rgb, texture_srgb;
-    IWineD3DResourceImpl **sub_resources;
+    struct wined3d_resource **sub_resources;
     UINT layer_count;
     UINT level_count;
     float                   pow2Matrix[16];
@@ -1912,11 +1898,16 @@ typedef struct IWineD3DBaseTextureImpl
 {
     /* IUnknown & WineD3DResource Information     */
     const IWineD3DBaseTextureVtbl *lpVtbl;
-    IWineD3DResourceClass     resource;
+    struct wined3d_resource resource;
     IWineD3DBaseTextureClass  baseTexture;
 
 } IWineD3DBaseTextureImpl;
 
+static inline IWineD3DBaseTextureImpl *basetexture_from_resource(struct wined3d_resource *resource)
+{
+    return CONTAINING_RECORD(resource, IWineD3DBaseTextureImpl, resource);
+}
+
 void basetexture_apply_state_changes(IWineD3DBaseTextureImpl *texture,
         const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1],
         const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
@@ -1926,7 +1917,7 @@ void basetexture_generate_mipmaps(IWineD3DBaseTextureImpl *texture) DECLSPEC_HID
 WINED3DTEXTUREFILTERTYPE basetexture_get_autogen_filter_type(IWineD3DBaseTextureImpl *texture) DECLSPEC_HIDDEN;
 DWORD basetexture_get_level_count(IWineD3DBaseTextureImpl *texture) DECLSPEC_HIDDEN;
 DWORD basetexture_get_lod(IWineD3DBaseTextureImpl *texture) DECLSPEC_HIDDEN;
-IWineD3DResourceImpl *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *texture,
+struct wined3d_resource *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *texture,
         UINT sub_resource_idx) DECLSPEC_HIDDEN;
 HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, const struct wined3d_texture_ops *texture_ops,
         UINT layer_count, UINT level_count, WINED3DRESOURCETYPE resource_type, IWineD3DDeviceImpl *device,
@@ -1945,7 +1936,7 @@ typedef struct IWineD3DTextureImpl
 {
     /* IUnknown & WineD3DResource/WineD3DBaseTexture Information     */
     const IWineD3DTextureVtbl *lpVtbl;
-    IWineD3DResourceClass     resource;
+    struct wined3d_resource resource;
     IWineD3DBaseTextureClass  baseTexture;
 
     /* IWineD3DTexture */
@@ -1964,7 +1955,7 @@ typedef struct IWineD3DCubeTextureImpl
 {
     /* IUnknown & WineD3DResource/WineD3DBaseTexture Information     */
     const IWineD3DCubeTextureVtbl *lpVtbl;
-    IWineD3DResourceClass     resource;
+    struct wined3d_resource resource;
     IWineD3DBaseTextureClass  baseTexture;
 } IWineD3DCubeTextureImpl;
 
@@ -1986,7 +1977,7 @@ typedef struct IWineD3DVolumeImpl
 {
     /* IUnknown & WineD3DResource fields */
     const IWineD3DVolumeVtbl  *lpVtbl;
-    IWineD3DResourceClass      resource;
+    struct wined3d_resource resource;
 
     /* WineD3DVolume Information */
     WINED3DVOLUMET_DESC      currentDesc;
@@ -1998,6 +1989,11 @@ typedef struct IWineD3DVolumeImpl
     BOOL                    dirty;
 } IWineD3DVolumeImpl;
 
+static inline IWineD3DVolumeImpl *volume_from_resource(struct wined3d_resource *resource)
+{
+    return CONTAINING_RECORD(resource, IWineD3DVolumeImpl, resource);
+}
+
 void volume_add_dirty_box(struct IWineD3DVolumeImpl *volume, const WINED3DBOX *dirty_box) DECLSPEC_HIDDEN;
 HRESULT volume_init(IWineD3DVolumeImpl *volume, IWineD3DDeviceImpl *device, UINT width,
         UINT height, UINT depth, DWORD usage, enum wined3d_format_id format_id, WINED3DPOOL pool,
@@ -2012,7 +2008,7 @@ typedef struct IWineD3DVolumeTextureImpl
 {
     /* IUnknown & WineD3DResource/WineD3DBaseTexture Information     */
     const IWineD3DVolumeTextureVtbl *lpVtbl;
-    IWineD3DResourceClass     resource;
+    struct wined3d_resource resource;
     IWineD3DBaseTextureClass  baseTexture;
 } IWineD3DVolumeTextureImpl;
 
@@ -2094,7 +2090,7 @@ struct IWineD3DSurfaceImpl
 {
     /* IUnknown & IWineD3DResource Information     */
     const IWineD3DSurfaceVtbl *lpVtbl;
-    IWineD3DResourceClass     resource;
+    struct wined3d_resource resource;
 
     /* IWineD3DSurface fields */
     const struct wined3d_surface_ops *surface_ops;
@@ -2154,6 +2150,11 @@ struct IWineD3DSurfaceImpl
 extern const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl DECLSPEC_HIDDEN;
 extern const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl DECLSPEC_HIDDEN;
 
+static inline IWineD3DSurfaceImpl *surface_from_resource(struct wined3d_resource *resource)
+{
+    return CONTAINING_RECORD(resource, IWineD3DSurfaceImpl, resource);
+}
+
 void surface_add_dirty_rect(IWineD3DSurfaceImpl *surface, const RECT *dirty_rect) DECLSPEC_HIDDEN;
 void surface_bind(IWineD3DSurfaceImpl *surface, BOOL srgb) DECLSPEC_HIDDEN;
 HRESULT surface_color_fill(IWineD3DSurfaceImpl *s, const RECT *rect, const WINED3DCOLORVALUE *color) DECLSPEC_HIDDEN;
@@ -2195,6 +2196,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_FreePrivateData(IWineD3DSurface *iface, R
 DWORD WINAPI IWineD3DBaseSurfaceImpl_SetPriority(IWineD3DSurface *iface, DWORD PriorityNew) DECLSPEC_HIDDEN;
 DWORD WINAPI IWineD3DBaseSurfaceImpl_GetPriority(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
 WINED3DRESOURCETYPE WINAPI IWineD3DBaseSurfaceImpl_GetType(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
+struct wined3d_resource * WINAPI IWineD3DBaseSurfaceImpl_GetResource(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
 void WINAPI IWineD3DBaseSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSURFACE_DESC *desc) DECLSPEC_HIDDEN;
 HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetBltStatus(IWineD3DSurface *iface, DWORD flags) DECLSPEC_HIDDEN;
 HRESULT WINAPI IWineD3DBaseSurfaceImpl_GetFlipStatus(IWineD3DSurface *iface, DWORD flags) DECLSPEC_HIDDEN;
@@ -2524,7 +2526,7 @@ struct wined3d_map_range
 struct wined3d_buffer
 {
     const struct IWineD3DBufferVtbl *vtbl;
-    IWineD3DResourceClass resource;
+    struct wined3d_resource resource;
 
     struct wined3d_buffer_desc desc;
 
@@ -2550,6 +2552,11 @@ struct wined3d_buffer
     UINT *conversion_shift;                                 /* NULL if no shifted conversion */
 };
 
+static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resource *resource)
+{
+    return CONTAINING_RECORD(resource, struct wined3d_buffer, resource);
+}
+
 const BYTE *buffer_get_memory(struct wined3d_buffer *buffer, const struct wined3d_gl_info *gl_info,
         GLuint *buffer_object) DECLSPEC_HIDDEN;
 BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
@@ -2563,12 +2570,12 @@ struct wined3d_rendertarget_view
     const struct IWineD3DRendertargetViewVtbl *vtbl;
     LONG refcount;
 
-    struct IWineD3DResourceImpl *resource;
+    struct wined3d_resource *resource;
     void *parent;
 };
 
 void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view,
-        struct IWineD3DResourceImpl *resource, void *parent) DECLSPEC_HIDDEN;
+        struct wined3d_resource *resource, void *parent) DECLSPEC_HIDDEN;
 
 /*****************************************************************************
  * IWineD3DSwapChainImpl implementation structure (extends IUnknown)
diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl
index ae34d1a..6ba3ffd 100644
--- a/include/wine/wined3d.idl
+++ b/include/wine/wined3d.idl
@@ -2105,7 +2105,6 @@ struct wined3d_parent_ops
     void (__stdcall *wined3d_object_destroyed)(void *parent);
 };
 
-interface IWineD3DResource;
 interface IWineD3DSurface;
 interface IWineD3DVolume;
 interface IWineD3DSwapChain;
@@ -2114,6 +2113,7 @@ struct wined3d;
 struct wined3d_clipper;
 struct wined3d_palette;
 struct wined3d_query;
+struct wined3d_resource;
 struct wined3d_stateblock;
 struct wined3d_vertex_declaration;
 
@@ -2178,7 +2178,7 @@ interface IWineD3DDeviceParent : IUnknown
     );
 }
 typedef ULONG (__stdcall *D3DCB_DESTROYSWAPCHAINFN)(IWineD3DSwapChain *pSwapChain);
-typedef HRESULT (__stdcall *D3DCB_ENUMRESOURCES)(IWineD3DResource *resource, void *pData);
+typedef HRESULT (__stdcall *D3DCB_ENUMRESOURCES)(struct wined3d_resource *resource, void *pData);
 
 [
     object,
@@ -2231,7 +2231,7 @@ interface IWineD3DResource : IWineD3DBase
 interface IWineD3DRendertargetView : IWineD3DBase
 {
     HRESULT GetResource(
-        [out] IWineD3DResource **resource
+        [out] struct wined3d_resource **resource
     );
 }
 
@@ -2242,6 +2242,8 @@ interface IWineD3DRendertargetView : IWineD3DBase
 ]
 interface IWineD3DSurface : IWineD3DResource
 {
+    struct wined3d_resource *GetResource(
+    );
     void GetDesc(
         [out] WINED3DSURFACE_DESC *desc
     );
@@ -2523,6 +2525,8 @@ interface IWineD3DSwapChain : IWineD3DBase
 ]
 interface IWineD3DBuffer : IWineD3DResource
 {
+    struct wined3d_resource *GetResource(
+    );
     HRESULT Map(
         [in] UINT offset,
         [in] UINT size,
@@ -2632,7 +2636,7 @@ interface IWineD3DDevice : IUnknown
         [out] IWineD3DSurface **surface
     );
     HRESULT CreateRendertargetView(
-        [in] IWineD3DResource *resource,
+        [in] struct wined3d_resource *resource,
         [in] void *parent,
         [out] IWineD3DRendertargetView **rendertarget_view
     );
@@ -3251,6 +3255,8 @@ WINED3DQUERYTYPE __cdecl wined3d_query_get_type(const struct wined3d_query *quer
 ULONG __cdecl wined3d_query_incref(struct wined3d_query *query);
 HRESULT __cdecl wined3d_query_issue(struct wined3d_query *query, DWORD flags);
 
+void * __cdecl wined3d_resource_get_parent(const struct wined3d_resource *resource);
+
 HRESULT __cdecl wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock);
 HRESULT __cdecl wined3d_stateblock_capture(struct wined3d_stateblock *stateblock);
 ULONG __cdecl wined3d_stateblock_decref(struct wined3d_stateblock *stateblock);
-- 
1.7.3.4




More information about the wine-patches mailing list