Module: wine Branch: master Commit: 5f2fcfdd6b3b7ab9c15d2c450a87527d13d144c8 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5f2fcfdd6b3b7ab9c15d2c450a...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Sun Aug 15 23:21:42 2010 +0200
wined3d: Reattach FBO attachments when any of the corresponding surfaces is unloaded.
---
dlls/wined3d/basetexture.c | 2 + dlls/wined3d/buffer.c | 2 + dlls/wined3d/context.c | 92 ++++++++++++++++++++++++++-------------- dlls/wined3d/device.c | 2 +- dlls/wined3d/resource.c | 6 +++ dlls/wined3d/surface.c | 2 + dlls/wined3d/volume.c | 13 ++++-- dlls/wined3d/wined3d_private.h | 5 ++- 8 files changed, 85 insertions(+), 39 deletions(-)
diff --git a/dlls/wined3d/basetexture.c b/dlls/wined3d/basetexture.c index deab4fb..922550d 100644 --- a/dlls/wined3d/basetexture.c +++ b/dlls/wined3d/basetexture.c @@ -129,6 +129,8 @@ void basetexture_unload(IWineD3DBaseTexture *iface)
This->baseTexture.texture_rgb.dirty = TRUE; This->baseTexture.texture_srgb.dirty = TRUE; + + resource_unload((IWineD3DResourceImpl *)This); }
DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 7c898cd..31a1492 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -720,6 +720,8 @@ static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface) This->conversion_stride = 0; This->flags &= ~WINED3D_BUFFER_HASDESC; } + + resource_unload((IWineD3DResourceImpl *)This); }
static ULONG STDMETHODCALLTYPE buffer_Release(IWineD3DBuffer *iface) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 7e3e813..e22149c 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -650,50 +650,78 @@ void context_free_event_query(struct wined3d_event_query *query) context->free_event_queries[context->free_event_query_count++] = query->object; }
-void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type) +typedef void (context_fbo_entry_func_t)(struct wined3d_context *context, struct fbo_entry *entry); + +static void context_enum_surface_fbo_entries(IWineD3DDeviceImpl *device, + IWineD3DSurfaceImpl *surface, context_fbo_entry_func_t *callback) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; UINT i;
- if (!This->d3d_initialized) return; - - switch(type) + for (i = 0; i < device->numContexts; ++i) { - case WINED3DRTYPE_SURFACE: + struct wined3d_context *context = device->contexts[i]; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct fbo_entry *entry, *entry2; + + if (context->current_rt == surface) context->current_rt = NULL; + + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry) { - for (i = 0; i < This->numContexts; ++i) - { - struct wined3d_context *context = This->contexts[i]; - const struct wined3d_gl_info *gl_info = context->gl_info; - struct fbo_entry *entry, *entry2; + UINT j;
- if (context->current_rt == (IWineD3DSurfaceImpl *)resource) context->current_rt = NULL; + if (entry->depth_stencil == surface) + { + callback(context, entry); + continue; + }
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry) + for (j = 0; j < gl_info->limits.buffers; ++j) + { + if (entry->render_targets[j] == surface) { - UINT j; - - if (entry->depth_stencil == (IWineD3DSurfaceImpl *)resource) - { - list_remove(&entry->entry); - list_add_head(&context->fbo_destroy_list, &entry->entry); - continue; - } - - for (j = 0; j < gl_info->limits.buffers; ++j) - { - if (entry->render_targets[j] == (IWineD3DSurfaceImpl *)resource) - { - list_remove(&entry->entry); - list_add_head(&context->fbo_destroy_list, &entry->entry); - break; - } - } + callback(context, entry); + break; } } + } + } +}
+static void context_queue_fbo_entry_destruction(struct wined3d_context *context, struct fbo_entry *entry) +{ + list_remove(&entry->entry); + list_add_head(&context->fbo_destroy_list, &entry->entry); +} + +void context_resource_released(IWineD3DDeviceImpl *device, IWineD3DResource *resource, WINED3DRESOURCETYPE type) +{ + if (!device->d3d_initialized) return; + + switch (type) + { + case WINED3DRTYPE_SURFACE: + context_enum_surface_fbo_entries(device, (IWineD3DSurfaceImpl *)resource, + context_queue_fbo_entry_destruction); + break; + + default: + break; + } +} + +static void context_detach_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry) +{ + entry->attached = FALSE; +} + +void context_resource_unloaded(IWineD3DDeviceImpl *device, IWineD3DResource *resource, WINED3DRESOURCETYPE type) +{ + switch (type) + { + case WINED3DRTYPE_SURFACE: + context_enum_surface_fbo_entries(device, (IWineD3DSurfaceImpl *)resource, + context_detach_fbo_entry); break; - }
default: break; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index f4bce23..4b62170 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -6546,7 +6546,7 @@ void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resour
TRACE("(%p) : resource %p\n", This, resource);
- context_resource_released((IWineD3DDevice *)This, resource, type); + context_resource_released(This, resource, type);
switch (type) { /* TODO: check front and back buffers, rendertargets etc.. possibly swapchains? */ diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index 67622a3..11db1f8 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -105,6 +105,12 @@ void resource_cleanup(IWineD3DResource *iface) if (This->resource.device) device_resource_released(This->resource.device, iface); }
+void resource_unload(IWineD3DResourceImpl *resource) +{ + context_resource_unloaded(resource->resource.device, (IWineD3DResource *)resource, + resource->resource.resourceType); +} + static PrivateData* resource_find_private_data(IWineD3DResourceImpl *This, REFGUID tag) { PrivateData *data; diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 101c8c2..514c7b2 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1230,6 +1230,8 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { }
context_release(context); + + resource_unload((IWineD3DResourceImpl *)This); }
/* ****************************************************** diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c index 42e61e6..c22c263 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -166,11 +166,14 @@ static void WINAPI IWineD3DVolumeImpl_PreLoad(IWineD3DVolume *iface) { FIXME("iface %p stub!\n", iface); }
-static void WINAPI IWineD3DVolumeImpl_UnLoad(IWineD3DVolume *iface) { - /* The whole content is shadowed on This->resource.allocatedMemory, and the - * texture name is managed by the VolumeTexture container - */ - TRACE("(%p): Nothing to do\n", iface); +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) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 08104eb..cc54228 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1177,7 +1177,9 @@ void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPE 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(IWineD3DDevice *iface, +void context_resource_released(IWineD3DDeviceImpl *device, + IWineD3DResource *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN; +void context_resource_unloaded(IWineD3DDeviceImpl *device, IWineD3DResource *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; @@ -1776,6 +1778,7 @@ WINED3DRESOURCETYPE resource_get_type(IWineD3DResource *iface) DECLSPEC_HIDDEN; DWORD resource_set_priority(IWineD3DResource *iface, DWORD new_priority) DECLSPEC_HIDDEN; HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid, const void *data, DWORD data_size, DWORD flags) DECLSPEC_HIDDEN; +void resource_unload(IWineD3DResourceImpl *resource) DECLSPEC_HIDDEN;
/* Tests show that the start address of resources is 32 byte aligned */ #define RESOURCE_ALIGNMENT 16