[PATCH 4/4] wined3d: Remove IWineD3DResource::UnLoad() from the public interface.

Henri Verbeet hverbeet at gmail.com
Mon Feb 28 01:05:39 CST 2011


---
 dlls/wined3d/basetexture.c     |    4 +-
 dlls/wined3d/buffer.c          |   28 +++---
 dlls/wined3d/cubetexture.c     |   54 ++++++------
 dlls/wined3d/device.c          |    4 +-
 dlls/wined3d/resource.c        |    4 +-
 dlls/wined3d/surface.c         |  203 +++++++++++++++++++++-------------------
 dlls/wined3d/surface_gdi.c     |   15 ---
 dlls/wined3d/texture.c         |   49 +++++-----
 dlls/wined3d/volume.c          |   31 ++++---
 dlls/wined3d/volumetexture.c   |   43 +++++----
 dlls/wined3d/wined3d_private.h |   14 ++-
 include/wine/wined3d.idl       |    2 -
 12 files changed, 231 insertions(+), 220 deletions(-)

diff --git a/dlls/wined3d/basetexture.c b/dlls/wined3d/basetexture.c
index 6d0f951..cb7227f 100644
--- a/dlls/wined3d/basetexture.c
+++ b/dlls/wined3d/basetexture.c
@@ -30,12 +30,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
 HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, const struct wined3d_texture_ops *texture_ops,
         UINT layer_count, UINT level_count, WINED3DRESOURCETYPE resource_type, IWineD3DDeviceImpl *device,
         DWORD usage, const struct wined3d_format *format, WINED3DPOOL pool, void *parent,
-        const struct wined3d_parent_ops *parent_ops)
+        const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops)
 {
     HRESULT hr;
 
     hr = resource_init((IWineD3DResourceImpl *)texture, resource_type, device,
-            0, usage, format, pool, parent, parent_ops);
+            0, usage, format, pool, parent, parent_ops, resource_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, returning %#x\n", hr);
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index ffc4511..04d8f2f 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -693,15 +693,15 @@ BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_inf
 }
 
 /* Do not call while under the GL lock. */
-static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface)
+static void buffer_unload(IWineD3DResourceImpl *resource)
 {
-    struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
+    struct wined3d_buffer *This = (struct wined3d_buffer *)resource;
 
-    TRACE("iface %p\n", iface);
+    TRACE("buffer %p.\n", This);
 
     if (This->buffer_object)
     {
-        IWineD3DDeviceImpl *device = This->resource.device;
+        IWineD3DDeviceImpl *device = resource->resource.device;
         struct wined3d_context *context;
 
         context = context_acquire(device, NULL);
@@ -728,7 +728,7 @@ static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface)
         This->flags &= ~WINED3D_BUFFER_HASDESC;
     }
 
-    resource_unload((IWineD3DResourceImpl *)This);
+    resource_unload(resource);
 }
 
 /* Do not call while under the GL lock. */
@@ -741,7 +741,7 @@ static ULONG STDMETHODCALLTYPE buffer_Release(IWineD3DBuffer *iface)
 
     if (!refcount)
     {
-        buffer_UnLoad(iface);
+        buffer_unload((IWineD3DResourceImpl *)This);
         resource_cleanup((IWineD3DResourceImpl *)iface);
         This->resource.parent_ops->wined3d_object_destroyed(This->resource.parent);
         HeapFree(GetProcessHeap(), 0, This->maps);
@@ -997,7 +997,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
         {
             FIXME("Too many declaration changes or converting dynamic buffer, stopping converting\n");
 
-            IWineD3DBuffer_UnLoad(iface);
+            buffer_unload((IWineD3DResourceImpl *)This);
             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");
-                IWineD3DBuffer_UnLoad(iface);
+                buffer_unload((IWineD3DResourceImpl *)This);
                 This->flags &= ~WINED3D_BUFFER_CREATEBO;
                 IWineD3DDeviceImpl_MarkStateDirty(device, STATE_STREAMSRC);
                 goto end;
@@ -1448,7 +1448,6 @@ static const struct IWineD3DBufferVtbl wined3d_buffer_vtbl =
     buffer_SetPriority,
     buffer_GetPriority,
     buffer_PreLoad,
-    buffer_UnLoad,
     buffer_GetType,
     /* IWineD3DBuffer methods */
     buffer_Map,
@@ -1456,6 +1455,11 @@ static const struct IWineD3DBufferVtbl wined3d_buffer_vtbl =
     buffer_GetDesc,
 };
 
+static const struct wined3d_resource_ops buffer_resource_ops =
+{
+    buffer_unload,
+};
+
 HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
         UINT size, DWORD usage, enum wined3d_format_id format_id, WINED3DPOOL pool, GLenum bind_hint,
         const char *data, void *parent, const struct wined3d_parent_ops *parent_ops)
@@ -1474,7 +1478,7 @@ 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);
+            device, size, usage, format, pool, parent, parent_ops, &buffer_resource_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, hr %#x\n", hr);
@@ -1520,7 +1524,7 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
         if (FAILED(hr))
         {
             ERR("Failed to map buffer, hr %#x\n", hr);
-            buffer_UnLoad((IWineD3DBuffer *)buffer);
+            buffer_unload((IWineD3DResourceImpl *)buffer);
             resource_cleanup((IWineD3DResourceImpl *)buffer);
             return hr;
         }
@@ -1534,7 +1538,7 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
     if (!buffer->maps)
     {
         ERR("Out of memory\n");
-        buffer_UnLoad((IWineD3DBuffer *)buffer);
+        buffer_unload((IWineD3DResourceImpl *)buffer);
         resource_cleanup((IWineD3DResourceImpl *)buffer);
         return E_OUTOFMEMORY;
     }
diff --git a/dlls/wined3d/cubetexture.c b/dlls/wined3d/cubetexture.c
index feefebc..bf54b07 100644
--- a/dlls/wined3d/cubetexture.c
+++ b/dlls/wined3d/cubetexture.c
@@ -136,12 +136,38 @@ static void cubetexture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSR
     if (context) context_release(context);
 }
 
+/* Do not call while under the GL lock. */
+static void cubetexture_unload(IWineD3DResourceImpl *resource)
+{
+    IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)resource;
+    UINT sub_count = texture->baseTexture.level_count * texture->baseTexture.layer_count;
+    UINT i;
+
+    TRACE("texture %p.\n", texture);
+
+    for (i = 0; i < sub_count; ++i)
+    {
+        IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i];
+
+        surface->resource.resource_ops->resource_unload((IWineD3DResourceImpl *)surface);
+        surface_set_texture_name(surface, 0, TRUE);
+        surface_set_texture_name(surface, 0, FALSE);
+    }
+
+    basetexture_unload(texture);
+}
+
 static const struct wined3d_texture_ops cubetexture_ops =
 {
     cubetexture_bind,
     cubetexture_preload,
 };
 
+static const struct wined3d_resource_ops cubetexture_resource_ops =
+{
+    cubetexture_unload,
+};
+
 static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This)
 {
     UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count;
@@ -245,31 +271,6 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface)
     cubetexture_preload((IWineD3DBaseTextureImpl *)iface, SRGB_ANY);
 }
 
-/* Do not call while under the GL lock. */
-static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface)
-{
-    IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
-    UINT sub_count = This->baseTexture.level_count * This->baseTexture.layer_count;
-    UINT i;
-
-    TRACE("iface %p.\n", iface);
-
-    /* Unload all the surfaces and reset the texture name. If UnLoad was called on the
-     * surface before, this one will be a NOP and vice versa. Unloading an unloaded
-     * surface is fine. */
-
-    for (i = 0; i < sub_count; ++i)
-    {
-        IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
-
-        IWineD3DSurface_UnLoad((IWineD3DSurface *)surface);
-        surface_set_texture_name(surface, 0, TRUE);
-        surface_set_texture_name(surface, 0, FALSE);
-    }
-
-    basetexture_unload((IWineD3DBaseTextureImpl *)This);
-}
-
 static WINED3DRESOURCETYPE WINAPI IWineD3DCubeTextureImpl_GetType(IWineD3DCubeTexture *iface)
 {
     return resource_get_type((IWineD3DResourceImpl *)iface);
@@ -436,7 +437,6 @@ static const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl =
     IWineD3DCubeTextureImpl_SetPriority,
     IWineD3DCubeTextureImpl_GetPriority,
     IWineD3DCubeTextureImpl_PreLoad,
-    IWineD3DCubeTextureImpl_UnLoad,
     IWineD3DCubeTextureImpl_GetType,
     /* IWineD3DBaseTexture */
     IWineD3DCubeTextureImpl_SetLOD,
@@ -506,7 +506,7 @@ HRESULT cubetexture_init(IWineD3DCubeTextureImpl *texture, UINT edge_length, UIN
 
     hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, &cubetexture_ops,
             6, levels, WINED3DRTYPE_CUBETEXTURE, device, usage, format, pool,
-            parent, parent_ops);
+            parent, parent_ops, &cubetexture_resource_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize basetexture, returning %#x\n", hr);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 365225b..d292813 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2106,7 +2106,7 @@ static HRESULT WINAPI device_unload_resource(IWineD3DResource *resource, void *d
 {
     TRACE("Unloading resource %p.\n", resource);
 
-    IWineD3DResource_UnLoad(resource);
+    ((IWineD3DResourceImpl *)resource)->resource.resource_ops->resource_unload((IWineD3DResourceImpl *)resource);
     IWineD3DResource_Release(resource);
 
     return S_OK;
@@ -6103,7 +6103,7 @@ static HRESULT WINAPI evict_managed_resource(IWineD3DResource *resource, void *d
     TRACE("checking resource %p for eviction\n", resource);
     if(((IWineD3DResourceImpl *) resource)->resource.pool == WINED3DPOOL_MANAGED) {
         TRACE("Evicting %p\n", resource);
-        IWineD3DResource_UnLoad(resource);
+        ((IWineD3DResourceImpl *)resource)->resource.resource_ops->resource_unload((IWineD3DResourceImpl *)resource);
     }
     IWineD3DResource_Release(resource);
     return S_OK;
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index edc3f8b..2f18550 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -45,7 +45,8 @@ struct private_data
 
 HRESULT resource_init(struct IWineD3DResourceImpl *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)
+        WINED3DPOOL pool, void *parent, const struct wined3d_parent_ops *parent_ops,
+        const struct wined3d_resource_ops *resource_ops)
 {
     struct IWineD3DResourceClass *r = &resource->resource;
 
@@ -59,6 +60,7 @@ HRESULT resource_init(struct IWineD3DResourceImpl *resource, WINED3DRESOURCETYPE
     r->priority = 0;
     r->parent = parent;
     r->parent_ops = parent_ops;
+    r->resource_ops = resource_ops;
     list_init(&r->privateData);
 
     if (size)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index b7f4b1c..1021c63 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -408,6 +408,109 @@ static HRESULT surface_draw_overlay(IWineD3DSurfaceImpl *surface)
     return hr;
 }
 
+/* Context activation is done by the caller. */
+static void surface_remove_pbo(IWineD3DSurfaceImpl *surface, const struct wined3d_gl_info *gl_info)
+{
+    if (!surface->resource.heapMemory)
+    {
+        surface->resource.heapMemory = HeapAlloc(GetProcessHeap(), 0, surface->resource.size + RESOURCE_ALIGNMENT);
+        surface->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)surface->resource.heapMemory
+                + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+    }
+
+    ENTER_GL();
+    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
+    checkGLcall("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, surface->pbo)");
+    GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0,
+            surface->resource.size, surface->resource.allocatedMemory));
+    checkGLcall("glGetBufferSubDataARB");
+    GL_EXTCALL(glDeleteBuffersARB(1, &surface->pbo));
+    checkGLcall("glDeleteBuffersARB");
+    LEAVE_GL();
+
+    surface->pbo = 0;
+    surface->flags &= ~SFLAG_PBO;
+}
+
+/* Do not call while under the GL lock. */
+static void surface_unload(IWineD3DResourceImpl *resource)
+{
+    IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)resource;
+    IWineD3DDeviceImpl *device = resource->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)
+    {
+        /* 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
+         * or depth stencil. The content may be destroyed, but we still have to tear down
+         * opengl resources, so we cannot leave early.
+         *
+         * Put the surfaces into sysmem, and reset the content. The D3D content is undefined,
+         * but we can't set the sysmem INDRAWABLE because when we're rendering the swapchain
+         * or the depth stencil into an FBO the texture or render buffer will be removed
+         * and all flags get lost
+         */
+        surface_init_sysmem(surface);
+    }
+    else
+    {
+        /* Load the surface into system memory */
+        surface_load_location(surface, SFLAG_INSYSMEM, NULL);
+        surface_modify_location(surface, SFLAG_INDRAWABLE, FALSE);
+    }
+    surface_modify_location(surface, SFLAG_INTEXTURE, FALSE);
+    surface_modify_location(surface, SFLAG_INSRGBTEX, FALSE);
+    surface->flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
+
+    context = context_acquire(device, NULL);
+    gl_info = context->gl_info;
+
+    /* Destroy PBOs, but load them into real sysmem before */
+    if (surface->flags & SFLAG_PBO)
+        surface_remove_pbo(surface, gl_info);
+
+    /* Destroy fbo render buffers. This is needed for implicit render targets, for
+     * all application-created targets the application has to release the surface
+     * before calling _Reset
+     */
+    LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, renderbuffer_entry_t, entry)
+    {
+        ENTER_GL();
+        gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
+        LEAVE_GL();
+        list_remove(&entry->entry);
+        HeapFree(GetProcessHeap(), 0, entry);
+    }
+    list_init(&surface->renderbuffers);
+    surface->current_renderbuffer = NULL;
+
+    /* If we're in a texture, the texture name belongs to the texture.
+     * Otherwise, destroy it. */
+    if (surface->container.type != WINED3D_CONTAINER_TEXTURE)
+    {
+        ENTER_GL();
+        glDeleteTextures(1, &surface->texture_name);
+        surface->texture_name = 0;
+        glDeleteTextures(1, &surface->texture_name_srgb);
+        surface->texture_name_srgb = 0;
+        LEAVE_GL();
+    }
+
+    context_release(context);
+
+    resource_unload(resource);
+}
+
+static const struct wined3d_resource_ops surface_resource_ops =
+{
+    surface_unload,
+};
+
 static const struct wined3d_surface_ops surface_ops =
 {
     surface_realize_palette,
@@ -494,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);
+    hr = resource_init((IWineD3DResourceImpl *)surface, 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);
@@ -1300,29 +1403,6 @@ static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface)
     surface_internal_preload((IWineD3DSurfaceImpl *)iface, SRGB_ANY);
 }
 
-/* Context activation is done by the caller. */
-static void surface_remove_pbo(IWineD3DSurfaceImpl *This, const struct wined3d_gl_info *gl_info)
-{
-    if (!This->resource.heapMemory)
-    {
-        This->resource.heapMemory = HeapAlloc(GetProcessHeap(), 0, This->resource.size + RESOURCE_ALIGNMENT);
-        This->resource.allocatedMemory =
-                (BYTE *)(((ULONG_PTR)This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
-    }
-
-    ENTER_GL();
-    GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
-    checkGLcall("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, This->pbo)");
-    GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0, This->resource.size, This->resource.allocatedMemory));
-    checkGLcall("glGetBufferSubDataARB");
-    GL_EXTCALL(glDeleteBuffersARB(1, &This->pbo));
-    checkGLcall("glDeleteBuffersARB");
-    LEAVE_GL();
-
-    This->pbo = 0;
-    This->flags &= ~SFLAG_PBO;
-}
-
 BOOL surface_init_sysmem(IWineD3DSurfaceImpl *surface)
 {
     if (!surface->resource.allocatedMemory)
@@ -1347,78 +1427,6 @@ BOOL surface_init_sysmem(IWineD3DSurfaceImpl *surface)
     return TRUE;
 }
 
-/* Do not call while under the GL lock. */
-static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface)
-{
-    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface;
-    IWineD3DDeviceImpl *device = This->resource.device;
-    const struct wined3d_gl_info *gl_info;
-    renderbuffer_entry_t *entry, *entry2;
-    struct wined3d_context *context;
-
-    TRACE("(%p)\n", iface);
-
-    if(This->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
-         * or depth stencil. The content may be destroyed, but we still have to tear down
-         * opengl resources, so we cannot leave early.
-         *
-         * Put the surfaces into sysmem, and reset the content. The D3D content is undefined,
-         * but we can't set the sysmem INDRAWABLE because when we're rendering the swapchain
-         * or the depth stencil into an FBO the texture or render buffer will be removed
-         * and all flags get lost
-         */
-        surface_init_sysmem(This);
-    }
-    else
-    {
-        /* Load the surface into system memory */
-        surface_load_location(This, SFLAG_INSYSMEM, NULL);
-        surface_modify_location(This, SFLAG_INDRAWABLE, FALSE);
-    }
-    surface_modify_location(This, SFLAG_INTEXTURE, FALSE);
-    surface_modify_location(This, SFLAG_INSRGBTEX, FALSE);
-    This->flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
-
-    context = context_acquire(device, NULL);
-    gl_info = context->gl_info;
-
-    /* Destroy PBOs, but load them into real sysmem before */
-    if (This->flags & SFLAG_PBO)
-        surface_remove_pbo(This, gl_info);
-
-    /* Destroy fbo render buffers. This is needed for implicit render targets, for
-     * all application-created targets the application has to release the surface
-     * before calling _Reset
-     */
-    LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &This->renderbuffers, renderbuffer_entry_t, entry) {
-        ENTER_GL();
-        gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
-        LEAVE_GL();
-        list_remove(&entry->entry);
-        HeapFree(GetProcessHeap(), 0, entry);
-    }
-    list_init(&This->renderbuffers);
-    This->current_renderbuffer = NULL;
-
-    /* If we're in a texture, the texture name belongs to the texture.
-     * Otherwise, destroy it. */
-    if (This->container.type != WINED3D_CONTAINER_TEXTURE)
-    {
-        ENTER_GL();
-        glDeleteTextures(1, &This->texture_name);
-        This->texture_name = 0;
-        glDeleteTextures(1, &This->texture_name_srgb);
-        This->texture_name_srgb = 0;
-        LEAVE_GL();
-    }
-
-    context_release(context);
-
-    resource_unload((IWineD3DResourceImpl *)This);
-}
-
 /* ******************************************************
    IWineD3DSurface IWineD3DSurface parts follow
    ****************************************************** */
@@ -4675,7 +4683,6 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl =
     IWineD3DBaseSurfaceImpl_SetPriority,
     IWineD3DBaseSurfaceImpl_GetPriority,
     IWineD3DSurfaceImpl_PreLoad,
-    IWineD3DSurfaceImpl_UnLoad,
     IWineD3DBaseSurfaceImpl_GetType,
     /* IWineD3DSurface */
     IWineD3DBaseSurfaceImpl_GetDesc,
diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c
index e523ea1..858dc9b 100644
--- a/dlls/wined3d/surface_gdi.c
+++ b/dlls/wined3d/surface_gdi.c
@@ -145,20 +145,6 @@ IWineGDISurfaceImpl_PreLoad(IWineD3DSurface *iface)
     ERR("(%p): Please report to wine-devel\n", iface);
 }
 
-/*****************************************************************************
- * IWineD3DSurface::UnLoad, GDI version
- *
- * This call is unsupported on GDI surfaces, if it's called something went
- * wrong in the parent library. Write an informative warning.
- *
- *****************************************************************************/
-static void WINAPI IWineGDISurfaceImpl_UnLoad(IWineD3DSurface *iface)
-{
-    ERR("(%p): UnLoad is not supported on X11 surfaces!\n", iface);
-    ERR("(%p): Most likely the parent library did something wrong.\n", iface);
-    ERR("(%p): Please report to wine-devel\n", iface);
-}
-
 static HRESULT WINAPI IWineGDISurfaceImpl_Map(IWineD3DSurface *iface,
         WINED3DLOCKED_RECT *pLockedRect, const RECT *pRect, DWORD flags)
 {
@@ -463,7 +449,6 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl =
     IWineD3DBaseSurfaceImpl_SetPriority,
     IWineD3DBaseSurfaceImpl_GetPriority,
     IWineGDISurfaceImpl_PreLoad,
-    IWineGDISurfaceImpl_UnLoad,
     IWineD3DBaseSurfaceImpl_GetType,
     /* IWineD3DSurface */
     IWineD3DBaseSurfaceImpl_GetDesc,
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 02909b3..1c629eb 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -160,12 +160,37 @@ static void texture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSRGB s
     *dirty = FALSE;
 }
 
+/* Do not call while under the GL lock. */
+static void texture_unload(IWineD3DResourceImpl *resource)
+{
+    IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)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];
+
+        surface->resource.resource_ops->resource_unload((IWineD3DResourceImpl *)surface);
+        surface_set_texture_name(surface, 0, FALSE); /* Delete rgb name */
+        surface_set_texture_name(surface, 0, TRUE); /* delete srgb name */
+    }
+
+    basetexture_unload(texture);
+}
+
 static const struct wined3d_texture_ops texture_ops =
 {
     texture_bind,
     texture_preload,
 };
 
+static const struct wined3d_resource_ops texture_resource_ops =
+{
+    texture_unload,
+};
+
 static void texture_cleanup(IWineD3DTextureImpl *This)
 {
     unsigned int i;
@@ -270,27 +295,6 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface)
     texture_preload((IWineD3DBaseTextureImpl *)iface, SRGB_ANY);
 }
 
-/* Do not call while under the GL lock. */
-static void WINAPI IWineD3DTextureImpl_UnLoad(IWineD3DTexture *iface) {
-    unsigned int i;
-    IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
-    TRACE("(%p)\n", This);
-
-    /* Unload all the surfaces and reset the texture name. If UnLoad was called on the
-     * surface before, this one will be a NOP and vice versa. Unloading an unloaded
-     * surface is fine
-     */
-    for (i = 0; i < This->baseTexture.level_count; ++i)
-    {
-        IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)This->baseTexture.sub_resources[i];
-        IWineD3DSurface_UnLoad((IWineD3DSurface *)surface);
-        surface_set_texture_name(surface, 0, FALSE); /* Delete rgb name */
-        surface_set_texture_name(surface, 0, TRUE); /* delete srgb name */
-    }
-
-    basetexture_unload((IWineD3DBaseTextureImpl *)This);
-}
-
 static WINED3DRESOURCETYPE WINAPI IWineD3DTextureImpl_GetType(IWineD3DTexture *iface)
 {
     return resource_get_type((IWineD3DResourceImpl *)iface);
@@ -451,7 +455,6 @@ static const IWineD3DTextureVtbl IWineD3DTexture_Vtbl =
     IWineD3DTextureImpl_SetPriority,
     IWineD3DTextureImpl_GetPriority,
     IWineD3DTextureImpl_PreLoad,
-    IWineD3DTextureImpl_UnLoad,
     IWineD3DTextureImpl_GetType,
     /* IWineD3DBaseTexture */
     IWineD3DTextureImpl_SetLOD,
@@ -539,7 +542,7 @@ HRESULT texture_init(IWineD3DTextureImpl *texture, UINT width, UINT height, UINT
 
     hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, &texture_ops,
             1, levels, WINED3DRTYPE_TEXTURE, device, usage, format, pool,
-            parent, parent_ops);
+            parent, parent_ops, &texture_resource_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize basetexture, returning %#x.\n", hr);
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 060e361..e5d3cd7 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -118,6 +118,17 @@ void volume_load(IWineD3DVolumeImpl *volume, UINT level, BOOL srgb_mode)
      * supported. */
 }
 
+/* Do not call while under the GL lock. */
+static void volume_unload(IWineD3DResourceImpl *resource)
+{
+    TRACE("texture %p.\n", resource);
+
+    /* The whole content is shadowed on This->resource.allocatedMemory, and
+     * the texture name is managed by the VolumeTexture container. */
+
+    resource_unload(resource);
+}
+
 /* *******************************************
    IWineD3DVolume IUnknown parts follow
    ******************************************* */
@@ -205,17 +216,6 @@ static void WINAPI IWineD3DVolumeImpl_PreLoad(IWineD3DVolume *iface) {
     FIXME("iface %p stub!\n", iface);
 }
 
-/* Do not call while under the GL lock. */
-static void WINAPI IWineD3DVolumeImpl_UnLoad(IWineD3DVolume *iface)
-{
-    TRACE("iface %p.\n", iface);
-
-    /* The whole content is shadowed on This->resource.allocatedMemory, and
-     * the texture name is managed by the VolumeTexture container. */
-
-    resource_unload((IWineD3DResourceImpl *)iface);
-}
-
 static WINED3DRESOURCETYPE WINAPI IWineD3DVolumeImpl_GetType(IWineD3DVolume *iface)
 {
     return resource_get_type((IWineD3DResourceImpl *)iface);
@@ -316,7 +316,6 @@ static const IWineD3DVolumeVtbl IWineD3DVolume_Vtbl =
     IWineD3DVolumeImpl_SetPriority,
     IWineD3DVolumeImpl_GetPriority,
     IWineD3DVolumeImpl_PreLoad,
-    IWineD3DVolumeImpl_UnLoad,
     IWineD3DVolumeImpl_GetType,
     /* IWineD3DVolume */
     IWineD3DVolumeImpl_GetDesc,
@@ -324,6 +323,11 @@ static const IWineD3DVolumeVtbl IWineD3DVolume_Vtbl =
     IWineD3DVolumeImpl_Unmap,
 };
 
+static const struct wined3d_resource_ops volume_resource_ops =
+{
+    volume_unload,
+};
+
 HRESULT volume_init(IWineD3DVolumeImpl *volume, IWineD3DDeviceImpl *device, UINT width,
         UINT height, UINT depth, DWORD usage, enum wined3d_format_id format_id, WINED3DPOOL pool,
         void *parent, const struct wined3d_parent_ops *parent_ops)
@@ -341,7 +345,8 @@ HRESULT volume_init(IWineD3DVolumeImpl *volume, IWineD3DDeviceImpl *device, UINT
     volume->lpVtbl = &IWineD3DVolume_Vtbl;
 
     hr = resource_init((IWineD3DResourceImpl *)volume, WINED3DRTYPE_VOLUME, device,
-            width * height * depth * format->byte_count, usage, format, pool, parent, parent_ops);
+            width * height * depth * format->byte_count, usage, format, pool,
+            parent, parent_ops, &volume_resource_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, returning %#x.\n", hr);
diff --git a/dlls/wined3d/volumetexture.c b/dlls/wined3d/volumetexture.c
index 37c51bb..757cd96 100644
--- a/dlls/wined3d/volumetexture.c
+++ b/dlls/wined3d/volumetexture.c
@@ -84,12 +84,34 @@ static void volumetexture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3D
     texture->baseTexture.texture_rgb.dirty = FALSE;
 }
 
+/* Do not call while under the GL lock. */
+static void volumetexture_unload(IWineD3DResourceImpl *resource)
+{
+    IWineD3DBaseTextureImpl *texture = (IWineD3DBaseTextureImpl *)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);
+    }
+
+    basetexture_unload(texture);
+}
+
 static const struct wined3d_texture_ops volumetexture_ops =
 {
     volumetexture_bind,
     volumetexture_preload,
 };
 
+static const struct wined3d_resource_ops volumetexture_resource_ops =
+{
+    volumetexture_unload,
+};
+
 static void volumetexture_cleanup(IWineD3DVolumeTextureImpl *This)
 {
     unsigned int i;
@@ -187,24 +209,6 @@ static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *ifac
     volumetexture_preload((IWineD3DBaseTextureImpl *)iface, SRGB_ANY);
 }
 
-/* Do not call while under the GL lock. */
-static void WINAPI IWineD3DVolumeTextureImpl_UnLoad(IWineD3DVolumeTexture *iface) {
-    unsigned int i;
-    IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
-    TRACE("(%p)\n", This);
-
-    /* Unload all the surfaces and reset the texture name. If UnLoad was called on the
-     * surface before, this one will be a NOP and vice versa. Unloading an unloaded
-     * surface is fine
-     */
-    for (i = 0; i < This->baseTexture.level_count; ++i)
-    {
-        IWineD3DVolume_UnLoad((IWineD3DVolume *)This->baseTexture.sub_resources[i]);
-    }
-
-    basetexture_unload((IWineD3DBaseTextureImpl *)This);
-}
-
 static WINED3DRESOURCETYPE WINAPI IWineD3DVolumeTextureImpl_GetType(IWineD3DVolumeTexture *iface)
 {
     return resource_get_type((IWineD3DResourceImpl *)iface);
@@ -365,7 +369,6 @@ static const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl =
     IWineD3DVolumeTextureImpl_SetPriority,
     IWineD3DVolumeTextureImpl_GetPriority,
     IWineD3DVolumeTextureImpl_PreLoad,
-    IWineD3DVolumeTextureImpl_UnLoad,
     IWineD3DVolumeTextureImpl_GetType,
     /* BaseTexture */
     IWineD3DVolumeTextureImpl_SetLOD,
@@ -435,7 +438,7 @@ HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT
 
     hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, &volumetexture_ops,
             1, levels, WINED3DRTYPE_VOLUMETEXTURE, device, usage, format, pool,
-            parent, parent_ops);
+            parent, parent_ops, &volumetexture_resource_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize basetexture, returning %#x.\n", hr);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 455fb1c..a7db1ec 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1793,9 +1793,11 @@ static inline BOOL isStateDirty(struct wined3d_context *context, DWORD state)
     return context->isStateDirty[idx] & (1 << shift);
 }
 
-/*****************************************************************************
- * IWineD3DResource implementation structure
- */
+struct wined3d_resource_ops
+{
+    void (*resource_unload)(struct IWineD3DResourceImpl *resource);
+};
+
 typedef struct IWineD3DResourceClass
 {
     /* IUnknown fields */
@@ -1816,6 +1818,7 @@ typedef struct IWineD3DResourceClass
 
     void *parent;
     const struct wined3d_parent_ops *parent_ops;
+    const struct wined3d_resource_ops *resource_ops;
 } IWineD3DResourceClass;
 
 typedef struct IWineD3DResourceImpl
@@ -1832,7 +1835,8 @@ HRESULT resource_get_private_data(struct IWineD3DResourceImpl *resource, REFGUID
         void *data, DWORD *data_size) DECLSPEC_HIDDEN;
 HRESULT resource_init(struct IWineD3DResourceImpl *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) DECLSPEC_HIDDEN;
+        WINED3DPOOL pool, void *parent, const struct wined3d_parent_ops *parent_ops,
+        const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN;
 WINED3DRESOURCETYPE resource_get_type(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,
@@ -1927,7 +1931,7 @@ IWineD3DResourceImpl *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *text
 HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, const struct wined3d_texture_ops *texture_ops,
         UINT layer_count, UINT level_count, WINED3DRESOURCETYPE resource_type, IWineD3DDeviceImpl *device,
         DWORD usage, const struct wined3d_format *format, WINED3DPOOL pool, void *parent,
-        const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+        const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops) DECLSPEC_HIDDEN;
 HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTextureImpl *texture,
         WINED3DTEXTUREFILTERTYPE filter_type) DECLSPEC_HIDDEN;
 BOOL basetexture_set_dirty(IWineD3DBaseTextureImpl *texture, BOOL dirty) DECLSPEC_HIDDEN;
diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl
index e6ecfff..ae34d1a 100644
--- a/include/wine/wined3d.idl
+++ b/include/wine/wined3d.idl
@@ -2219,8 +2219,6 @@ interface IWineD3DResource : IWineD3DBase
     );
     void PreLoad(
     );
-    void UnLoad(
-    );
     WINED3DRESOURCETYPE GetType(
     );
 }
-- 
1.7.3.4




More information about the wine-patches mailing list