From 39497ff4d19d5312fcc968a5166195450b6dddd3 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 28 Feb 2011 08:05:39 +0100 Subject: [PATCH] wined3d: Remove IWineD3DResource::UnLoad() from the public interface. --- 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 6d0f9514d73..cb7227f504f 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 ffc4511a1e0..04d8f2f1121 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 feefebc924e..bf54b074988 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 365225ba6c5..d292813243f 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 edc3f8b3ad3..2f1855061df 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 b7f4b1c4e08..1021c6382aa 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 e523ea1b950..858dc9b492e 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 02909b3a617..1c629ebbe6d 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 060e3613078..e5d3cd73542 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 37c51bbf6b4..757cd96377b 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 455fb1c476f..a7db1ecff73 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 e6ecfff7a14..ae34d1aed33 100644 --- a/include/wine/wined3d.idl +++ b/include/wine/wined3d.idl @@ -2219,8 +2219,6 @@ interface IWineD3DResource : IWineD3DBase ); void PreLoad( ); - void UnLoad( - ); WINED3DRESOURCETYPE GetType( ); }