wined3d: Reattach FBO attachments when any of the corresponding surfaces is unloaded.
This commit is contained in:
parent
7bef239bc4
commit
5f2fcfdd6b
|
@ -129,6 +129,8 @@ void basetexture_unload(IWineD3DBaseTexture *iface)
|
||||||
|
|
||||||
This->baseTexture.texture_rgb.dirty = TRUE;
|
This->baseTexture.texture_rgb.dirty = TRUE;
|
||||||
This->baseTexture.texture_srgb.dirty = TRUE;
|
This->baseTexture.texture_srgb.dirty = TRUE;
|
||||||
|
|
||||||
|
resource_unload((IWineD3DResourceImpl *)This);
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew)
|
DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD LODNew)
|
||||||
|
|
|
@ -720,6 +720,8 @@ static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface)
|
||||||
This->conversion_stride = 0;
|
This->conversion_stride = 0;
|
||||||
This->flags &= ~WINED3D_BUFFER_HASDESC;
|
This->flags &= ~WINED3D_BUFFER_HASDESC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource_unload((IWineD3DResourceImpl *)This);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG STDMETHODCALLTYPE buffer_Release(IWineD3DBuffer *iface)
|
static ULONG STDMETHODCALLTYPE buffer_Release(IWineD3DBuffer *iface)
|
||||||
|
|
|
@ -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;
|
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;
|
UINT i;
|
||||||
|
|
||||||
if (!This->d3d_initialized) return;
|
for (i = 0; i < device->numContexts; ++i)
|
||||||
|
|
||||||
switch(type)
|
|
||||||
{
|
{
|
||||||
case WINED3DRTYPE_SURFACE:
|
struct wined3d_context *context = device->contexts[i];
|
||||||
{
|
|
||||||
for (i = 0; i < This->numContexts; ++i)
|
|
||||||
{
|
|
||||||
struct wined3d_context *context = This->contexts[i];
|
|
||||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||||
struct fbo_entry *entry, *entry2;
|
struct fbo_entry *entry, *entry2;
|
||||||
|
|
||||||
if (context->current_rt == (IWineD3DSurfaceImpl *)resource) context->current_rt = NULL;
|
if (context->current_rt == surface) context->current_rt = NULL;
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry)
|
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry)
|
||||||
{
|
{
|
||||||
UINT j;
|
UINT j;
|
||||||
|
|
||||||
if (entry->depth_stencil == (IWineD3DSurfaceImpl *)resource)
|
if (entry->depth_stencil == surface)
|
||||||
{
|
{
|
||||||
list_remove(&entry->entry);
|
callback(context, entry);
|
||||||
list_add_head(&context->fbo_destroy_list, &entry->entry);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < gl_info->limits.buffers; ++j)
|
for (j = 0; j < gl_info->limits.buffers; ++j)
|
||||||
{
|
{
|
||||||
if (entry->render_targets[j] == (IWineD3DSurfaceImpl *)resource)
|
if (entry->render_targets[j] == surface)
|
||||||
{
|
{
|
||||||
|
callback(context, entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void context_queue_fbo_entry_destruction(struct wined3d_context *context, struct fbo_entry *entry)
|
||||||
|
{
|
||||||
list_remove(&entry->entry);
|
list_remove(&entry->entry);
|
||||||
list_add_head(&context->fbo_destroy_list, &entry->entry);
|
list_add_head(&context->fbo_destroy_list, &entry->entry);
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -6546,7 +6546,7 @@ void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resour
|
||||||
|
|
||||||
TRACE("(%p) : resource %p\n", This, resource);
|
TRACE("(%p) : resource %p\n", This, resource);
|
||||||
|
|
||||||
context_resource_released((IWineD3DDevice *)This, resource, type);
|
context_resource_released(This, resource, type);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
/* TODO: check front and back buffers, rendertargets etc.. possibly swapchains? */
|
/* TODO: check front and back buffers, rendertargets etc.. possibly swapchains? */
|
||||||
|
|
|
@ -105,6 +105,12 @@ void resource_cleanup(IWineD3DResource *iface)
|
||||||
if (This->resource.device) device_resource_released(This->resource.device, 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)
|
static PrivateData* resource_find_private_data(IWineD3DResourceImpl *This, REFGUID tag)
|
||||||
{
|
{
|
||||||
PrivateData *data;
|
PrivateData *data;
|
||||||
|
|
|
@ -1230,6 +1230,8 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
|
||||||
}
|
}
|
||||||
|
|
||||||
context_release(context);
|
context_release(context);
|
||||||
|
|
||||||
|
resource_unload((IWineD3DResourceImpl *)This);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ******************************************************
|
/* ******************************************************
|
||||||
|
|
|
@ -166,11 +166,14 @@ static void WINAPI IWineD3DVolumeImpl_PreLoad(IWineD3DVolume *iface) {
|
||||||
FIXME("iface %p stub!\n", iface);
|
FIXME("iface %p stub!\n", iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WINAPI IWineD3DVolumeImpl_UnLoad(IWineD3DVolume *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("iface %p.\n", iface);
|
||||||
*/
|
|
||||||
TRACE("(%p): Nothing to do\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) {
|
static WINED3DRESOURCETYPE WINAPI IWineD3DVolumeImpl_GetType(IWineD3DVolume *iface) {
|
||||||
|
|
|
@ -1177,7 +1177,9 @@ void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPE
|
||||||
struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN;
|
struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN;
|
||||||
DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN;
|
DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN;
|
||||||
void context_release(struct wined3d_context *context) 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;
|
IWineD3DResource *resource, WINED3DRESOURCETYPE type) DECLSPEC_HIDDEN;
|
||||||
BOOL context_set_current(struct wined3d_context *ctx) 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_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;
|
DWORD resource_set_priority(IWineD3DResource *iface, DWORD new_priority) DECLSPEC_HIDDEN;
|
||||||
HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid,
|
HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid,
|
||||||
const void *data, DWORD data_size, DWORD flags) DECLSPEC_HIDDEN;
|
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 */
|
/* Tests show that the start address of resources is 32 byte aligned */
|
||||||
#define RESOURCE_ALIGNMENT 16
|
#define RESOURCE_ALIGNMENT 16
|
||||||
|
|
Loading…
Reference in New Issue