Hello,
looking at the web page: http://www.nabble.com/d3d:-Bug-in-handling-of-depth-stencil-surfaces,-and-po...
I read that there are problems with the ref count in d3d wine implementation.
Does there exist any plan to fix it? Or can we try to implement the Jim's idea about it?
David
Am Sonntag, 5. April 2009 11:32:38 schrieb paulo lesgaz:
Hello,
looking at the web page: http://www.nabble.com/d3d:-Bug-in-handling-of-depth-stencil-surfaces,-and-p otential-patch-td19907752.html
I read that there are problems with the ref count in d3d wine implementation.
Does there exist any plan to fix it? Or can we try to implement the Jim's idea about it?
I looked at this some time ago but got distracted and dropped it again.
The problem doesn't just apply to depth stencil surfaces but to all other objects as well(buffers, textures, shaders, ...). We already keep an internal refcount, sort of - The refcount of the wined3d object. This refcount is already addrefed in Set*. So when the d3d9 object is released, the wined3d one stays intact and can be used for rendering. However, things currently fail if the app tries to retrieve the original object with a getter.
My idea was to add a callback to d3d9(and other) objects to allow wined3d trigger the final release.
It's also affecting one of my bugs: http://bugs.winehq.org/show_bug.cgi?id=15858
It's sort of random when a real crash occurs but the debugging revealed that the object that is used was already freed by wined3d.
I can increase the probability of a crash by running a bunch of memory-hungry apps besides wine. Loading a level mostly works when there isn't much memory-load on the system. Possibly other apps overwrite the memory that was previously freed. Of course this doesn't happen so often when there are only a few apps actually using mem.
I strongly encourage a proper fix, since the current situation is... well, sorta ugly (it works, but having random crashes on level load isn't exactly smooth gameplay...)
Greets, Tobias
After a discussion on #winehackers I want to add something for the archives:
This is a situation that cannot be solved in d3d9 alone, a fix has to involve wined3d. This is because there is a hidden reference kept on every object that is referenced in any stateblock, even the non-primary ones. d3d9 does not know which objects are in which stateblock, so it cannot adjust the hidden references properly in the setters(if a stateblock is recorded) or in stateblock::capture.
2009/4/5 Stefan Dösinger stefan@codeweavers.com:
After a discussion on #winehackers I want to add something for the archives:
This is a situation that cannot be solved in d3d9 alone, a fix has to involve wined3d. This is because there is a hidden reference kept on every object that is referenced in any stateblock, even the non-primary ones. d3d9 does not know which objects are in which stateblock, so it cannot adjust the hidden references properly in the setters(if a stateblock is recorded) or in stateblock::capture.
I don't know what was discussed on IRC, but essentially we need to keep track of which resources (in a broad way, not just objects derived from IWineD3DResource) are in use by a stateblock in wined3d, and delay destroying the d3d9 object as long as the wined3d object is in use.
The most reasonable way I can think of to do this at the moment is to have the d3d9 Release() methods not do the cleanup themselves, but instead have a destroy/cleanup function which the wined3d object calls once its refcount reaches zero. That also means the stateblock needs to keep a reference to these objects, of course. I think Stefan wrote something along those lines once for vertex buffers.
Am Sonntag, 5. April 2009 23:59:01 schrieb Henri Verbeet:
I don't know what was discussed on IRC, but essentially we need to keep track of which resources (in a broad way, not just objects derived from IWineD3DResource) are in use by a stateblock in wined3d, and delay destroying the d3d9 object as long as the wined3d object is in use.
Yep
The most reasonable way I can think of to do this at the moment is to have the d3d9 Release() methods not do the cleanup themselves, but instead have a destroy/cleanup function which the wined3d object calls once its refcount reaches zero. That also means the stateblock needs to keep a reference to these objects, of course. I think Stefan wrote something along those lines once for vertex buffers.
That was my suggestion. We already keep a wined3d-internal refcount for all these objects(shaders, textures, ...), and my plan was a callback function(maybe provided via a COM interface, similar to the WineD3DDeviceParent one). Some time ago I thought you weren't too fond of that idea, but maybe that was a missunderstanding.
2009/4/6 Stefan Dösinger stefan@codeweavers.com:
That was my suggestion. We already keep a wined3d-internal refcount for all these objects(shaders, textures, ...), and my plan was a callback function(maybe provided via a COM interface, similar to the WineD3DDeviceParent one). Some time ago I thought you weren't too fond of that idea, but maybe that was a missunderstanding.
Well, it isn't very nice of course, but it's probably our best option.