Hello, I have a a question regarding some code that might be rejected by Alexandre when I submit it. The problem is that I have to do an refcount hack in my new ddraw code to destroy textures properly. I CC this mail to AJ because it's him who has the last word ;)
WineD3D and Direct3D7 have different ideas about handling mipmap textures. In d3d7 they are complex surfaces - a bunch of surfaces with a root and sublevels. All surfaces in the compound have their own refcount, but they are all destroyed when the root is destroyed. In WineD3D there's the texture as a container, and the surfaces in the container have their refcount linked to the container(See the patch H. Verbeet sent a few days ago).
In d3d7 the application destroys the first surface to release the whole texture. My first idea was to Release the WineD3DTexture. It would then call the Release method of all the sublevel ddraw surfaces, which would destroy them. This works for a correctly written application, but applications call GetAttachedSurface for the sublevels, which addrefs, and many do not Release the sublevels after GetAttachedSurface(). This leaves the sublevel surfaces with a refcount of 2 or more when the root is destroyed. To make sure that they are destroyed, I set their refcount to 1 when the root is destroyed. When the last reference to the WineD3D Texture is released, wineD3D will destroy the sublevel surfaces.
Is such a thing acceptable for Wine? Does anyone have a better solution? If you need some code to look at, I'll upload an updated patch to my homepage later.
Thanks, Stefan
On 09/03/06, Stefan Dösinger stefandoesinger@gmx.at wrote:
Is such a thing acceptable for Wine? Does anyone have a better solution? If you need some code to look at, I'll upload an updated patch to my homepage later.
You could have a function to explicitly destroy the object, regardless of reference count. However, I think that one already got mentioned last time :-)
You could have a function to explicitly destroy the object, regardless of reference count. However, I think that one already got mentioned last time :-)
:-) Yes, that was mentioned, and indeed I have one internal function, mainly for code readability. The problem is that I can't destroy the sublevel surfaces when the root surface is destroyed, I have to wait until the WineD3DTexture is destroyed. In most cases, this is equal, and the root surface holds the only reference to the WineD3DTexture, but in some cases WineD3D holds an internal reference. If I just destroy the sublevels with the root, then WineD3D will get angry(aka crash) because I take away the Textures surfaces. The first wineD3D surface survives because it's parent is an IParent object, and destroying the root surface does only Release the WineD3DTexture, not the WineD3DSurface.