Commit 6e09d7bd authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Cleanup device_resource_released().

In particular, releasing a resource that's in use by the device or the stateblock is always an internal error in either wined3d or the relevant wined3d client library.
parent 35b9d3db
...@@ -6538,100 +6538,102 @@ static void device_resource_remove(IWineD3DDeviceImpl *This, IWineD3DResource *r ...@@ -6538,100 +6538,102 @@ static void device_resource_remove(IWineD3DDeviceImpl *This, IWineD3DResource *r
list_remove(&((IWineD3DResourceImpl *) resource)->resource.resource_list_entry); list_remove(&((IWineD3DResourceImpl *) resource)->resource.resource_list_entry);
} }
void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resource) void device_resource_released(IWineD3DDeviceImpl *device, IWineD3DResource *resource)
{ {
WINED3DRESOURCETYPE type = IWineD3DResource_GetType(resource); WINED3DRESOURCETYPE type = IWineD3DResource_GetType(resource);
int counter; unsigned int i;
TRACE("(%p) : resource %p\n", This, resource); TRACE("device %p, resource %p, type %s.\n", device, resource, debug_d3dresourcetype(type));
context_resource_released(This, resource, type); context_resource_released(device, resource, type);
switch (type) { switch (type)
/* TODO: check front and back buffers, rendertargets etc.. possibly swapchains? */ {
case WINED3DRTYPE_SURFACE: { case WINED3DRTYPE_SURFACE:
unsigned int i; if (!device->d3d_initialized) break;
if (This->d3d_initialized) for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
{ {
for (i = 0; i < This->adapter->gl_info.limits.buffers; ++i) if (device->render_targets[i] == (IWineD3DSurfaceImpl *)resource)
{ {
if (This->render_targets[i] == (IWineD3DSurfaceImpl *)resource) ERR("Surface %p is still in use as render target %u.\n", resource, i);
This->render_targets[i] = NULL; device->render_targets[i] = NULL;
} }
if (This->depth_stencil == (IWineD3DSurfaceImpl *)resource)
This->depth_stencil = NULL;
} }
if (device->depth_stencil == (IWineD3DSurfaceImpl *)resource)
{
ERR("Surface %p is still in use as depth/stencil buffer.\n", resource);
device->depth_stencil = NULL;
}
break; break;
}
case WINED3DRTYPE_TEXTURE: case WINED3DRTYPE_TEXTURE:
case WINED3DRTYPE_CUBETEXTURE: case WINED3DRTYPE_CUBETEXTURE:
case WINED3DRTYPE_VOLUMETEXTURE: case WINED3DRTYPE_VOLUMETEXTURE:
for (counter = 0; counter < MAX_COMBINED_SAMPLERS; counter++) { for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
if (This->stateBlock != NULL && This->stateBlock->textures[counter] == (IWineD3DBaseTexture *)resource) { {
WARN("Texture being released is still by a stateblock, Stage = %u Texture = %p\n", counter, resource); if (device->stateBlock && device->stateBlock->textures[i] == (IWineD3DBaseTexture *)resource)
This->stateBlock->textures[counter] = NULL; {
} ERR("Texture %p is still in use by stateblock %p, stage %u.\n",
if (This->updateStateBlock != This->stateBlock ){ resource, device->stateBlock, i);
if (This->updateStateBlock->textures[counter] == (IWineD3DBaseTexture *)resource) { device->stateBlock->textures[i] = NULL;
WARN("Texture being released is still by a stateblock, Stage = %u Texture = %p\n", counter, resource);
This->updateStateBlock->textures[counter] = NULL;
}
}
} }
break;
case WINED3DRTYPE_VOLUME: if (device->updateStateBlock != device->stateBlock
/* TODO: nothing really? */ && device->updateStateBlock->textures[i] == (IWineD3DBaseTexture *)resource)
break; {
ERR("Texture %p is still in use by stateblock %p, stage %u.\n",
resource, device->updateStateBlock, i);
device->updateStateBlock->textures[i] = NULL;
}
}
break;
case WINED3DRTYPE_BUFFER: case WINED3DRTYPE_BUFFER:
{ for (i = 0; i < MAX_STREAMS; ++i)
int streamNumber; {
TRACE("Cleaning up stream pointers\n"); if (device->stateBlock && device->stateBlock->streamSource[i] == (IWineD3DBuffer *)resource)
{
for(streamNumber = 0; streamNumber < MAX_STREAMS; streamNumber ++){ ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
/* FINDOUT: should a warn be generated if were recording and updateStateBlock->streamSource is lost? resource, device->stateBlock, i);
FINDOUT: should changes.streamSource[StreamNumber] be set ? device->stateBlock->streamSource[i] = NULL;
*/
if (This->updateStateBlock != NULL ) { /* ==NULL when device is being destroyed */
if ((IWineD3DResource *)This->updateStateBlock->streamSource[streamNumber] == resource) {
FIXME("Vertex buffer released while bound to a state block, stream %d\n", streamNumber);
This->updateStateBlock->streamSource[streamNumber] = 0;
/* Set changed flag? */
}
} }
if (This->stateBlock != NULL ) { /* only happens if there is an error in the application, or on reset/release (because we don't manage internal tracking properly) */
if ((IWineD3DResource *)This->stateBlock->streamSource[streamNumber] == resource) { if (device->updateStateBlock != device->stateBlock
TRACE("Vertex buffer released while bound to a state block, stream %d\n", streamNumber); && device->updateStateBlock->streamSource[i] == (IWineD3DBuffer *)resource)
This->stateBlock->streamSource[streamNumber] = 0; {
} ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
resource, device->updateStateBlock, i);
device->updateStateBlock->streamSource[i] = NULL;
} }
} }
if (This->updateStateBlock != NULL ) { /* ==NULL when device is being destroyed */ if (device->stateBlock && device->stateBlock->pIndexData == (IWineD3DBuffer *)resource)
if (This->updateStateBlock->pIndexData == (IWineD3DBuffer *)resource) { {
This->updateStateBlock->pIndexData = NULL; ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
} resource, device->stateBlock);
device->stateBlock->pIndexData = NULL;
} }
if (This->stateBlock != NULL ) { /* ==NULL when device is being destroyed */
if (This->stateBlock->pIndexData == (IWineD3DBuffer *)resource) { if (device->updateStateBlock != device->stateBlock
This->stateBlock->pIndexData = NULL; && device->updateStateBlock->pIndexData == (IWineD3DBuffer *)resource)
} {
ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
resource, device->updateStateBlock);
device->updateStateBlock->pIndexData = NULL;
} }
} break;
break;
default: default:
FIXME("(%p) unknown resource type %p %u\n", This, resource, IWineD3DResource_GetType(resource)); break;
break;
} }
/* Remove the resource from the resourceStore */ /* Remove the resource from the resourceStore */
device_resource_remove(This, resource); device_resource_remove(device, resource);
TRACE("Resource released\n");
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 pCallback, void *pData) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment