Re: Direct3D Z order question

2006-02-12 Thread Stefan Dösinger
Hi,

 Err reading your e-mail again, pardon my directx ignorance, but aren't
 all d3d z values supposed to be in the [0.0, 1.0] range? I thought that
 was the range for the z buffer. I recall reading that one of the main
 annoyance differences between OpenGL and D3D was OpenGL used [-1.0, 1.0]
 for depth and D3D used [0.0, 1.0].

You could be right, I have to do some more checks. But the Half-Life problem 
could be caused by a bug in my ProcessVertices implementation. I interpreted 
the results I got from windows and blindy implemented the viewport 
conversation, and it seems that there are conflicts between my conversation 
and the GL viewport setup.

However, the triangle problem remains. I have changed the code to use z=0.1 
for the red triangle and z=0.9 for the blue one, and the blue triangle still 
overlaps the red one on Windows. If I change the Z values, the result is 
unchanged.


pgpoC2FTK2d0X.pgp
Description: PGP signature



Re: Direct3D Z order question

2006-02-12 Thread Stefan Dösinger

 Err reading your e-mail again, pardon my directx ignorance, but aren't
 all d3d z values supposed to be in the [0.0, 1.0] range? I thought that
 was the range for the z buffer. I recall reading that one of the main
 annoyance differences between OpenGL and D3D was OpenGL used [-1.0, 1.0]
 for depth and D3D used [0.0, 1.0].

I've found the reason for the problems in half-life: HL draws with 2 different 
viewports, one with z...[0.0, 1.0], and another one with z...
[0.0.5.3...]. WineD3D calls glOrtho with the current viewport on the 
first draw with processed vertices, then it stores that the viewport is set  
and avoids the glOrtho call. ProcessVertices always uses the current 
viewport. So the Vertices processed with the [0.0, 0.5...] viewport were 
drawn into the [0.0, 1.0] viewport. Setting the glOrtho after a viewport 
change fixed the problem.

The HL Direct3D engine is now working fine :). I'll get a few more games 
running, then I can start sending patches :) :)
(Well, two bugs remain: Decals are flickering, and hl changes the screen 
resolution back to 640x480 for some reason. And it's quite slow)


pgpIed0FFn2Ea.pgp
Description: PGP signature



Re: WINED3D: Fix a couple of FIXMEs

2006-02-12 Thread H. Verbeet
On 10/02/06, Alexandre Julliard [EMAIL PROTECTED] wrote:
  The output of glGetString(GL_PROGRAM_ERROR_STRING_ARB) can get too
  large for a normal FIXME. Use fprintf to stderr instead.

 You should use debugstr_a. fprintf will mess up the output.

The output of glGetString(GL_PROGRAM_ERROR_STRING_ARB) contains
newlines, debugstr_a would convert those to \n, which would make the
output quite a bit less readable.




bugzilla account

2006-02-12 Thread Michael Jung
Hi,

I would like to change the status of bug 4322 to FIXED, but I'm not 
'empowered' to do it. Whom do I have to talk to?

Bye,
-- 
Michael Jung
[EMAIL PROTECTED]




Re: Small CVS-Update-Script

2006-02-12 Thread Christian Lachner
one more update. 0.12 is the current version and is mainly a
minor-fixes-release which also fixes a really stupid bug (or so).
Functionality is the same, have fun. hmmm, time to release this thing
with a readme...


getwinegit.sh
Description: Bourne shell script



Refcounting fun

2006-02-12 Thread H. Verbeet
I've run into a somewhat annoying problem with d3d9/wined3d recently.
It appears that on d3d9 on Windows a surface either forwards its
AddRef / Release calls to its container if it has one, or just shares
the refcount directly. Either way, it comes down to the same thing.
Calling  AddRef on the surface increases the texture's refcount and
calling AddRef on the texture increases the surface's refcount. Same
thing for Release.

As a consequence, on Windows, it's perfectly legal to do something like this:

/* Create a texture */
IDirect3DDevice9_CreateTexture()
/* Get a surface. Adds a reference to the surface/texture combination */
IDirect3DTexture9_GetSurfaceLevel()
/* Release the texture. Note that the texture isn't freed yet, because
we still hold a reference to the surface */
IDirect3DTexture9_Release()
Do some stuff with the surface, perhaps call GetContainer, etc
/* Release the surface. The texture and all of it's surfaces will now
be released. */
IDirect3DSurface9_Release()

In wine, the call to IDirect3DTexture9_Release() frees the texture.
(It also calls Release on it's surfaces, but since the surface had an
extra reference from the call to GetSurfaceLevel the surface is still
ok). Calling any function on the surface that needs access to the
container will now have undefines results, most likely a crash.

Naively, I tried to fix this by having the surface keep a reference to
it's container. That keeps the code above from crashing, but only
because it creates a circular reference between the surface and the
container. Oops.

Fixing the problem for wined3d is probably not even that hard. Just
separate the Release code from the Cleanup code, then have
WineD3DSurface forward its AddRef / Release calls to the container, if
it has one. The container can then call the Cleanup code for its
surfaces when it gets deleted.

However, there is another problem, related to the way d3d9 (and
ddraw/d3d7/d3d8, when their respective rewrites are finished) wraps
wined3d. After fixing the problem for wined3d as above, the relation
between IDirect3DSurface9 and IDirect3DTexture9 in wine would look
roughly like this:


|---|   |---|
| IDirect3DSurface9 |   | IDirect3DTexture9 |
|---|   |---|
^   ^
|   |
||   ||
| WineD3DSurface |-| WineD3DTexture |
||   ||

WineD3DSurface and WineD3DTexture share reference counts,
IDirect3DSurface9 keeps a reference to WineD3DSurface, and
IDirect3DTexture keeps a reference to WineD3DTexture. WineD3DSurface
and WineD3DTexture don't keep references to their parents (and can't,
without creating circular references).

So releasing the texture before the surface would still not work,
since the d3d9 texture still has only 1 reference, the one it got when
it was created. That means that in the call to
IDirect3DTexture9_Release the d3d9 texture gets freed, while the
wined3d texture doesn't. When we do something with the d3d9 surface
that needs the container, the wined3d surface correctly returns its
container, but when d3d9 then tries to get the parent of that
container it still dies.

One way to solve this would be to have wined3d handle the reference
counting for d3d7/8/9 as well, so that their AddRef/Release calls just
call AddRef/Release on the wined3d object they wrap. That would also
mean we need to pass a pointer to the d3d7/8/9 object's cleanup
function. (Releasing a d3d9 surface to 0 should cause a d3d9 texture
to be freed). Note that for creating a texture, currently a similair
construction is used, in that IWineD3DDeviceImpl_CreateTexture gets
passed a pointer to a d3d9 surface create function, in order to create
the texture's surfaces.

Obviously doing all that would be quite a change in the way d3d is
setup in wine, and would also have some implications for the d3d7 and
d3d8 rewrites. I'm wondering if this solution would be acceptable, and
whether perhaps there are other, better solutions. Anyone care to
comment?




Re: Refcounting fun

2006-02-12 Thread Stefan Dösinger
 One way to solve this would be to have wined3d handle the reference
 counting for d3d7/8/9 as well, so that their AddRef/Release calls just
 call AddRef/Release on the wined3d object they wrap. That would also
 mean we need to pass a pointer to the d3d7/8/9 object's cleanup
 function. (Releasing a d3d9 surface to 0 should cause a d3d9 texture
 to be freed). Note that for creating a texture, currently a similair
 construction is used, in that IWineD3DDeviceImpl_CreateTexture gets
 passed a pointer to a d3d9 surface create function, in order to create
 the texture's surfaces.
I have had some reference counting problems with ddraw too, but they were more 
simple(Mainly, that needed WineD3D objects had no ddraw counterpart, or that 
WineD3D destroys the ddraw parents, although they were still needed).

DDraw doesn't use containers, instead it has surface attachments and complex 
surfaces, with some reference counting difficulties. My solution was to 
handle that things in ddraw.

Could it be that d3d9 surfaces and textures are the same objects on windows? 
What happens if you QueryInterface the surface for the texture GUID?

 Obviously doing all that would be quite a change in the way d3d is
 setup in wine, and would also have some implications for the d3d7 and
 d3d8 rewrites. I'm wondering if this solution would be acceptable, and
 whether perhaps there are other, better solutions. Anyone care to
 comment?
It might be interesting if there are more such refcount connections. For 
textures, my parent/child connections are:

DDraw surface 1 - WineD3DTexture
IParent - WineD3DSurface 1
DDraw surface 2 - WineD3DSurface 2
etc

Directdraw textures are the same objects as directdraw surfaces, so they share 
the refcount.

First, I create a ddraw surface, and create a WineD3DTexture for it. The 
surface is the child for texture. WineD3D calls my surface creation callback, 
which creates a WineD3DSurface for the ddraw surface on the first call, and a 
Parent object for the WineD3Dsurface. The IParent objects only purpose is to 
release it's child when it's destroyed. For other levels, I create a new 
ddraw surface, which is the parent of the new WineD3D surface, and attach it 
to the first ddraw surface. The attachment list is managed in ddraw.

When the app releases the compound, it (hopefully) calls the release method of 
the first surface. This releases the WineD3D texture, which causes a release 
to the IParent object and the further ddraw surfaces. The parent and the 
ddraw surfaces release the Wined3d surfaces.
(That code works for 1 level textures, I haven't yet tried an app which uses 
multiple levels, or I silently broke that functionality)

My suggestion is to keep d3dX specific refcounting in ddraw / d3d8 / d3d9, and 
use the WineD3D refcounts for wined3d internal things.  A quick guessis to 
seperate the D3D9 release code from the cleanup code, instead of doing this 
in WineD3D.

What happens if a texture has 2 surface levels? A GetSurfaceLevel for the 
first level AddRefs both the texture and the surface. A GetSurfaceLevel for 
the secound addrefs the texture and the 2nd surface, but what happens to the 
first one? A Release() of the first surface Releases() the texture, what 
happens to the secound surface?

Stefan




Re: Refcounting fun

2006-02-12 Thread H. Verbeet
On 12/02/06, Stefan Dösinger [EMAIL PROTECTED] wrote:
 Could it be that d3d9 surfaces and textures are the same objects on windows?
 What happens if you QueryInterface the surface for the texture GUID?
It returns 0x80004002 (E_NOINTERFACE). Same thing for the reverse.

 When the app releases the compound, it (hopefully) calls the release method of
 the first surface.
At least for d3d9, it's not guaranteed which surface / texture gets
released last. Could be the texture, could be the first surface, could
be any of the other surfaces.

 My suggestion is to keep d3dX specific refcounting in ddraw / d3d8 / d3d9, and
 use the WineD3D refcounts for wined3d internal things.  A quick guessis to
 seperate the D3D9 release code from the cleanup code, instead of doing this
 in WineD3D.
With the solution mentioned in my previous post, d3d7/8/9 objects
would essentially not be real COM objects on their own, they would
just wrap the relevant wined3d AddRef/Release functions, and not have
refcounts of their own. Wined3d would be responsible for it's own
refcounting, and cleaning up the d3d7/8/9 object as part of it's own
cleanup. Separating the d3d9 cleanup and release code would obviously
be part of that. Note that if we separate the cleanup and release code
we can't just call the cleanup code from wined3d, because we don't
know the type of the parent, all we have is an IUnknown pointer. Which
is why we would have to pass a pointer to that function to wined3d
during object creation.

 What happens if a texture has 2 surface levels? A GetSurfaceLevel for the
 first level AddRefs both the texture and the surface. A GetSurfaceLevel for
 the secound addrefs the texture and the 2nd surface, but what happens to the
 first one? A Release() of the first surface Releases() the texture, what
 happens to the secound surface?
The reference count appears to be shared between the texture and all
of its surfaces. This is the output of a small test program I wrote:

texture_refs.c:67:Calling CreateTexture
texture_refs.c:69:texture @ 001DB220
texture_refs.c:71:texture refs: 1
texture_refs.c:73:Calling GetSurfaceLevel (0)
texture_refs.c:75:surface 0 @ 001DB420
texture_refs.c:78:texture refs: 2
texture_refs.c:79:surface 0 refs: 2
texture_refs.c:82:QueryInterface for surface on texture returned
0x80004002, ptr 
texture_refs.c:84:QueryInterface for texture on surface 0 returned
0x80004002, ptr 
texture_refs.c:86:Calling GetSurfaceLevel (1)
texture_refs.c:88:surface 1 @ 001DB540
texture_refs.c:92:texture refs: 3
texture_refs.c:93:surface 0 refs: 3
texture_refs.c:94:surface 1 refs: 3
texture_refs.c:96:Calling Release on texture
texture_refs.c:101:texture refs: 2
texture_refs.c:102:surface 0 refs: 2
texture_refs.c:103:surface 1 refs: 2
texture_refs.c:105:Calling Release on surface 1
texture_refs.c:110:texture refs: 1
texture_refs.c:111:surface 0 refs: 1
texture_refs.c:112:surface 1 refs: 1
texture_refs.c:114:Calling AddRef on surface 0
texture_refs.c:119:texture refs: 2
texture_refs.c:120:surface 0 refs: 2
texture_refs.c:121:surface 1 refs: 2

The refcounts in that program are retrieved like this:
static int get_refcount(IUnknown *object)
{
IUnknown_AddRef(object);
return IUnknown_Release(object);
}




Re: bugzilla account

2006-02-12 Thread Tony Lambregts

Michael Jung wrote:

Hi,

I would like to change the status of bug 4322 to FIXED, but I'm not 
'empowered' to do it. Whom do I have to talk to?


Bye,

One of them is me.

You are now empowered.

--

Tony Lambregts




Re: Refcounting fun

2006-02-12 Thread Stefan Dösinger
 With the solution mentioned in my previous post, d3d7/8/9 objects
 would essentially not be real COM objects on their own, they would
 just wrap the relevant wined3d AddRef/Release functions, and not have
 refcounts of their own. Wined3d would be responsible for it's own
 refcounting, and cleaning up the d3d7/8/9 object as part of it's own
 cleanup. Separating the d3d9 cleanup and release code would obviously
 be part of that. Note that if we separate the cleanup and release code
 we can't just call the cleanup code from wined3d, because we don't
 know the type of the parent, all we have is an IUnknown pointer. Which
 is why we would have to pass a pointer to that function to wined3d
 during object creation.
I don't think that this will work for ddraw. The ddraw object connections are 
a little different from D3D9 / WineD3D. For example, in ddraw, the app 
creates a DirectDraw interface. This interface doesn't have any surfaces on 
it's own, the primary surfaces are created by the app. When a Direct3DDevice 
is created, the surfaces already exist. In D3D9, creating the Direct3DDevice 
automatically creates the surfaces. There's no Texture object in ddraw too. I 
don't think that a direct DDraw - WineD3D refcount mapping can work.


  What happens if a texture has 2 surface levels? A GetSurfaceLevel for the
  first level AddRefs both the texture and the surface. A GetSurfaceLevel
  for the secound addrefs the texture and the 2nd surface, but what happens
  to the first one? A Release() of the first surface Releases() the
  texture, what happens to the secound surface?

 The reference count appears to be shared between the texture and all
 of its surfaces. This is the output of a small test program I wrote:

 texture_refs.c:67:Calling CreateTexture
 texture_refs.c:69:texture @ 001DB220
 texture_refs.c:71:texture refs: 1
 texture_refs.c:73:Calling GetSurfaceLevel (0)
 texture_refs.c:75:surface 0 @ 001DB420
 texture_refs.c:78:texture refs: 2
 texture_refs.c:79:surface 0 refs: 2
 texture_refs.c:82:QueryInterface for surface on texture returned
 0x80004002, ptr 
 texture_refs.c:84:QueryInterface for texture on surface 0 returned
 0x80004002, ptr 
 texture_refs.c:86:Calling GetSurfaceLevel (1)
 texture_refs.c:88:surface 1 @ 001DB540
 texture_refs.c:92:texture refs: 3
 texture_refs.c:93:surface 0 refs: 3
 texture_refs.c:94:surface 1 refs: 3
 texture_refs.c:96:Calling Release on texture
 texture_refs.c:101:texture refs: 2
 texture_refs.c:102:surface 0 refs: 2
 texture_refs.c:103:surface 1 refs: 2
 texture_refs.c:105:Calling Release on surface 1
 texture_refs.c:110:texture refs: 1
 texture_refs.c:111:surface 0 refs: 1
 texture_refs.c:112:surface 1 refs: 1
 texture_refs.c:114:Calling AddRef on surface 0
 texture_refs.c:119:texture refs: 2
 texture_refs.c:120:surface 0 refs: 2
 texture_refs.c:121:surface 1 refs: 2
Seems to be really one refcount. I'd suggest to create a addref_override and 
release_ovveride member for Direct3D9 Surfaces (and Direct3D8), and set them 
when a texture is created, and unset them when the texture is destroyed and 
before the surfaces are released the last time(so destroying the surface 
works normally with IDirect3DSurface9::Release).

As a sidenote, such overrides bring some problems. The current ddraw 
implementation is full of them. The callbacks and the existance of 3 
different IDirectDraw(Main, user, hal) implementations and 5 different 
IDirectDrawSurface(Main, user, hal, dib, zbuffer) implementations made it 
quite difficult to understand the code. I don't think that I've fully 
understood it by now.

I'll have a look about the consequences of a WineD3DTexture - WineD3DSurface 
refcount connection for ddraw. I think it's not hard to cope with that case, 
but I can't promise right now. Can you check if there are more refcount 
connections?

I think that I should line out the changes to WineD3D I am planning: I'm going 
to add some methods, like IWineD3DSurface::Blt, 
IWineD3DSurface::BltFast, ..., this doesn't make any difference for D3D9. I 
split up the WineD3DDevice initalisation code into the CreateDevice part, 
which doesn't initialize OpenGL, and a IWineD3DDevice::Init3D to create a 
swapchain and the render targets. As a counterpart, there's a 
IWineD3DDevice::Uninit3D, which destroys the swapchain, but not the 
rendertargets, and the IWineD3DDevice::Release method, which frees the rest.
The necessary changes to D3D9 are a call to IWineD3DDevice::Init3D during 
creation, and IWineD3DDevice::Uninit3D when the d3d9 device is destroyed. The 
d3d9 device has to release it's rendertarget surfaces on it's own too.

For 2D operation without OpenGL, I've created a secound surface 
implementation, IWineX11Surface(well, bad name). It replaces a few 
methods(Blt, Lock, Unlock, Flip, ...), but uses the same management code. 
CreateSurface takes another parameter which determines the surface type. To 
avoid a too complex code, there's no way to change a X11 surface into 

Representation of virtual hardware in desktop managers [Was Bug 4551]

2006-02-12 Thread Tom Spear (Dustin Booker, Dustin Navea)

Forwarded from Bugzilla bug 4551.

Nowadays on Linux you do not see your virtual wine hardware drives in KDE or
GNOME because they are not recognized. You have to open invisible folder
$HOME/.wine. Many users will not be able to do this.

Maybe one could work out some standard with freedesktop.org so that users can
easily access their virtual drive C:\ ? Who's work would that be? I am not sure
about that, so sorry if this is not the right inbox. I would liek to suggest
to extend this standard to other virtual machines like Xen or Vmware.


Thilo Pfennig





Re: bugzilla account

2006-02-12 Thread Tom Spear (Dustin Booker, Dustin Navea)
Tony, can you empower me to empower other people, since I have already 
been empowered to fix bugs, and I got his request email last night?


Tom

Tony Lambregts wrote:

Michael Jung wrote:

Hi,

I would like to change the status of bug 4322 to FIXED, but I'm not 
'empowered' to do it. Whom do I have to talk to?


Bye,

One of them is me.

You are now empowered.

--

Tony Lambregts









Re: Direct3D Z order question

2006-02-12 Thread Joseph Garvin

Stefan Dösinger wrote:


Err reading your e-mail again, pardon my directx ignorance, but aren't
all d3d z values supposed to be in the [0.0, 1.0] range? I thought that
was the range for the z buffer. I recall reading that one of the main
annoyance differences between OpenGL and D3D was OpenGL used [-1.0, 1.0]
for depth and D3D used [0.0, 1.0].
   



I've found the reason for the problems in half-life: HL draws with 2 different 
viewports, one with z...[0.0, 1.0], and another one with z...
[0.0.5.3...]. 

2 different viewports or just two different projection matrix settings? 
The way 2D overlays are handled in OpenGL from my (very limited) 
experience is that you setup your normal glPerspective, and then once 
you've drawn everything in the world, you switch to a glOrtho2D and do 
whatever 2D drawing you want on top. GL viewports just specify what what 
pixels in the window OpenGL has control over... if they use two whole 
different viewports instead of just changing projection settings that 
either strikes me as really dumb or that they're doing some black magic 
I don't know about ;)


Unless the viewport and the projection matrix are tied together in 
DirectX? If so there's a possible optimization in having the DirectX 
viewport function call check if everything that would be passed to 
glViewport is the same and if so only make the appropriate 
glOrtho/glPerspective call. I'm not sure how expensive a glViewport call is.





Re: Refcounting fun

2006-02-12 Thread Stefan Dösinger
Hi,
I've thought over this: If you want to connect the IWineD3DTexture and 
IWineD3DSurface refcounts only, then there's no problem for me. If you want 
to connect the Texture's and Surface's Parents refcount, then you have do the 
same for the rendertargets and the swapchain(I guess that Windows does that 
too), and I can use that connection to manage complex ddraw surfaces.

Stefan


pgpwAKmwOyez0.pgp
Description: PGP signature



Re: Direct3D Z order question

2006-02-12 Thread Stefan Dösinger
Hi,
 2 different viewports or just two different projection matrix settings?
 The way 2D overlays are handled in OpenGL from my (very limited)
 experience is that you setup your normal glPerspective, and then once
 you've drawn everything in the world, you switch to a glOrtho2D and do
 whatever 2D drawing you want on top. GL viewports just specify what what
 pixels in the window OpenGL has control over... if they use two whole
 different viewports instead of just changing projection settings that
 either strikes me as really dumb or that they're doing some black magic
 I don't know about
It's 2 different viewports, and constantly changing world and view matrices. 
The projection matrix is the idendity matrix every time.

The view, projection and world matrix for GL drawing are idendity matrices in 
this case, because processed vertices are drawn(they are in viewport 
coordinates). WineD3D does a check if a glOrtho call is necessary.

I don't know much about GL drawing, but I noticed that GL clips primitive 
parts that are outside the Z range. So if vertices that were processed into a 
[0,5.] Z range are drawn into a [0,1.0] viewport leads to missing 
vertices. I guess I have to attend a few more courses at univertiy to really 
understand what exactly is going on.

The relevant code is at dlls/wined3d/drawprim.c, line 186, vtx_transformed is 
true, useVS and vtx_lit are false.



pgpvVLb9T28em.pgp
Description: PGP signature



Re: Refcounting fun

2006-02-12 Thread H. Verbeet
On 12/02/06, Stefan Dösinger [EMAIL PROTECTED] wrote:
 Hi,
 I've thought over this: If you want to connect the IWineD3DTexture and
 IWineD3DSurface refcounts only, then there's no problem for me. If you want
 to connect the Texture's and Surface's Parents refcount,
Are you talking about IDirect3DSurface9 = IDirect3DTexture9 or do
you mean IDirect3DSurface9 = IWineD3DSurface?

 then you have do the
 same for the rendertargets and the swapchain(I guess that Windows does that
 too), and I can use that connection to manage complex ddraw surfaces.
I haven't verified it, but the MSDN documentation for GetContainer
appears to imply that it does.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/IDirect3DSurface9__GetContainer.asp
Unfortunately my knowledge of ddraw and d3d7 is somewhat limited, so
it's a bit hard for me to oversee all the implications those changes
would have for ddraw / d3d7. The choice for Surface and Texture as an
example is somewhat arbitrary I guess, but probably the one for which
it matters the most. (As in, is most likely to break stuff if it isn't
implemented correctly). In principle it would change for any object
that has a container or uses similar construction. Perhaps it would
even make sense to forward AddRef and Release calls for all d3d7/8/9
objects that directly wrap a wined3d object.

For reference, the code for Release  CleanUp would look something
like this for the different objects:

/* WineD3D Surface */
ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
if (This-container) {
return IWineD3DBase_Release(This-container);
} else {
/* Handle our own refcounting */
}
}

void WINAPI IWineD3DSurfaceImpl_CleanUp(IWineD3DSurface *iface) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

/* Do some cleaning for ourselves */

This-parentCleanUp(This-parent);
}

/* WineD3D Texture */
ULONG WINAPI IWineD3DTextureImpl_Release(IWineD3DTexture *iface) {
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
ULONG ref = InterlockedDecrement(This-resource.ref);
if (!ref) {
IWineD3DTexture_CleanUp(iface);
}

return ref;
}

void WINAPI IWineD3DTextureImpl_CleanUp(IWineD3DTexture *iface) {
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
int i;
for (i = 0; i  This-baseTexture.levels; ++i) {
IWineD3DSurface_Cleanup(This-surfaces[i]);
}

/* Do some cleaning for ourselves */

This-parentCleanUp(This-parent);
}

/* IDirect3DSurface9 */
ULONG WINAPI IDirect3DSurface9Impl_Release(IDirect3DSurface9 *iface) {
IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
return IWineD3DSurface_Release(This-wineD3DSurface);
}

void WINAPI IDirect3DSurface9Impl_CleanUp(IDirect3DSurface9 *iface) {
IDirect3DSurface9Impl *This = (IDirect3DSurface9Impl *)iface;
/* Cleanup Some stuff */
}

/* IDirect3DTexture9 */
ULONG WINAPI IDirect3DTexture9Impl_Release(IDirect3DTexture9 *iface) {
IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface;
return IWineD3DTexture_Release(This-wineD3DTexture);
}

void WINAPI IDirect3DTexture9Impl_CleanUp(IDirect3DTexture9 *iface) {
IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface;
/* Cleanup Some stuff */
}


AddRef would follow a similar pattern, although somewhat simpler since
it doesn't have to handle cleaning up the object.




Re: Refcounting fun

2006-02-12 Thread Stefan Dösinger
Hi,
 Are you talking about IDirect3DSurface9 = IDirect3DTexture9 or do
 you mean IDirect3DSurface9 = IWineD3DSurface?
I meant IWineD3DSurface = IWineD3DTexture and Parent(IWineD3DSurface) = 
Parent(IWineD3DTexture). The first case has no consequences for ddraw, if the 
secound one is forced by WineD3D this would cause a connection between 
IDirect3DSurface9 = IDirect3DTexture9 and between {Direct Draw texture root 
surface} = {Other ddraw texture surfaces}

 Unfortunately my knowledge of ddraw and
 d3d7 is somewhat limited, so it's a bit hard for me to oversee all the
 implications those changes would have for ddraw / d3d7. The choice for
 Surface and Texture as an example is somewhat arbitrary I guess, but
 probably the one for which it matters the most. (As in, is most likely to
 break stuff if it isn't implemented correctly). In principle it would
 change for any object that has a container or uses similar construction.
 Perhaps it would even make sense to forward AddRef and Release calls for
 all d3d7/8/9 objects that directly wrap a wined3d object.

 For reference, the code for Release  CleanUp would look something
 like this for the different objects:
I could deal with such a Release / cleanup difference in ddraw, but I don't 
like the idea. I think it creates a too complex connection between WineD3D 
and the d3d libs. My d3d9 knowledge is limited too, but what if you do 
something like this: (sort of pseude-code only)

IDirect3DSurface9::AddRef
{
  if(This-container /* Or get the container from WineD3D */)
  {
 return IUnknown_AddRef(This-container);
  }
  else
  {
ULONG ref = This-ref++;
etc
  }
}

IDirect3DSurface9::Releae
{
  if(This-container /* Or get the container from WineD3D */)
  {
 return IUnknown_Release(This-container);
  }
  else
  {
ULONG ref = This-ref--;

if(ref == 0)
{
   /*Destroy code*/
   IWineD3DSurface_Release(This-wineD3DSurface);
}
return ref;
  }
}

IDirect3DTexure9::AddRef
{
/* normal addref, nothing special */
}

IDirect3DTexure9::Release
{
  ULONG ref = This-ref--;

  if(ref == 0)
  {
for(all surfaces in this container)
{
  surfaceImpl-container = NULL;
  /* Or place this call in WineD3DTexture::Releaase*/

  IWineD3DTexture_Release(This-wineD3DTexture);
  /* IWineD3DTexture_Release will call the release method
   * of the IDirect3D9Surface(because it releases the parent),
   * run the surface's release code(not the container, because
   * it's set to NULL and destroy the surface, because it's own
   * refcount is 1 from creation, and we never changed it.
   * The D3D9 surface release code releases the wineD3DSurface,
   * and everthing is cleaned.
   */

   HeapFree(GetProcessHeap, 0, This);
}
  }
}

The important part is to set the surface's container when they are created, 
before the first AddRef() or Release() is called, and to set the container to 
NULL when the container is destroyed and before the surfaces are released. 
You can eighter track the containers in d3d9, or use wineD3D to get the 
container.

Could this work?

Stefan


pgpgDc14pzzRd.pgp
Description: PGP signature



Re: Refcounting fun

2006-02-12 Thread Stefan Dösinger
Hi
 IDirect3DTexure9::Release
 {
   ULONG ref = This-ref--;

   if(ref == 0)
   {
     for(all surfaces in this container)
     {
       surfaceImpl-container = NULL;
       /* Or place this call in WineD3DTexture::Releaase*/

       IWineD3DTexture_Release(This-wineD3DTexture);
       /* IWineD3DTexture_Release will call the release method
        * of the IDirect3D9Surface(because it releases the parent),
        * run the surface's release code(not the container, because
        * it's set to NULL and destroy the surface, because it's own
        * refcount is 1 from creation, and we never changed it.
        * The D3D9 surface release code releases the wineD3DSurface,
        * and everthing is cleaned.
        */

        HeapFree(GetProcessHeap, 0, This);
     }
   }
 }
Oops, little problem here: That should be

IDirect3DTexure9::Release
{
  ULONG ref = This-ref--;
  if(ref == 0)
  {
for(all surfaces in this container)
{
  surfaceImpl-container = NULL;
  /* Don't free the objects in this loop of course ;) */
}

/* Or place this call in WineD3DTexture::Releaase*/
IWineD3DTexture_Release(This-wineD3DTexture);

/* IWineD3DTexture_Release will call the release method
 * of the IDirect3D9Surface(because it releases the parent),
 * run the surface's release code(not the container, because
 * it's set to NULL and destroy the surface, because it's own
 * refcount is 1 from creation, and we never changed it.
 * The D3D9 surface release code releases the wineD3DSurface,
 * and everthing is cleaned.
 */
 HeapFree(GetProcessHeap, 0, This);
  }
}


pgpHYJNFmRtkY.pgp
Description: PGP signature



Re: Refcounting fun

2006-02-12 Thread H. Verbeet
On 12/02/06, Stefan Dösinger [EMAIL PROTECTED] wrote:
 I meant IWineD3DSurface = IWineD3DTexture and Parent(IWineD3DSurface) =
 Parent(IWineD3DTexture). The first case has no consequences for ddraw, if the
 secound one is forced by WineD3D this would cause a connection between
 IDirect3DSurface9 = IDirect3DTexture9 and between {Direct Draw texture root
 surface} = {Other ddraw texture surfaces}
Connecting the parents' refcounts wasn't really the idea, at least not
directly. I think it's probably a good idea to have as little logic in
the wrappers as possible. However, they are of course indirectly
connected through wined3d; The connection between IDirect3DSurface9
and IDirect3DTexture9 is the reason for doing it in the first place.

  For reference, the code for Release  CleanUp would look something
  like this for the different objects:
 I could deal with such a Release / cleanup difference in ddraw, but I don't
 like the idea. I think it creates a too complex connection between WineD3D
 and the d3d libs.
I'm not sure that connection is much more complex than the way it
currently is. Right now the d3d7/8/9 wrapper objects are responsible
for cleaning up their wined3d object, while with that change the
wined3d object would become responsible for deleting the d3d7/8/9
objects.

 The important part is to set the surface's container when they are created,
 before the first AddRef() or Release() is called, and to set the container to
 NULL when the container is destroyed and before the surfaces are released.
 You can eighter track the containers in d3d9, or use wineD3D to get the
 container.

 Could this work?
It probably would. However, it's not all that different from the other
option. The main difference seems to be that you don't separate the
CleanUp and Release code, but use the parent in combination with a
reference count that's guaranteed to be one as some sort of flag to
decide whether to do the entire release code or just the cleanup part.
That, and in order the use the container in that way you either have
to store it somewhere in d3d7/8/9 or retrieve it on every call to
Release. I'm not sure if that reduces the complexity all that much.
Regardless of whether separating the Release and CleanUp code would
make things a lot more complex, I do think it's somewhat cleaner.
Also, note that most (all?) wined3d objects already have a CleanUp
function.




Mozilla ActiveX download busted?

2006-02-12 Thread Dan Kegel
Trying to install Oregon Trail from cnet download,
http://www.download.com/Oregon-Trail-5th-Edition/3000-7502_4-10301783.html
Cnet has you download a tiny .exe that invokes
IE via ActiveX to do the real download.
This pops up Wine's Mozilla ActiveX downloader dialog (great)
which then downloads the ActiveX wrapper (great)
but stores it in c:\windows\temp\mozactivex (note the lack of a .exe, uh-oh),
and shortly thereafter prints
wine: could not load LC:\\windows\\temp\\mozactivex as Win32 binary
Wine's Mozilla ActiveX downloader dialog just sits there forever,
it doesn't seem to notice the problem.

Renaming mozactivex to mozactivex.exe and then running it manually
got me past that little problem -- I'm no longer prompted to download
wine's mozilla activex wrapper.

This worked better a month or two ago - what changed?
(I'd do a regression test myself, but can't afford to type too much...)
- Dan

--
Wine for Windows ISVs: http://kegel.com/wine/isv




Re: Refcounting fun

2006-02-12 Thread Stefan Dösinger
 Connecting the parents' refcounts wasn't really the idea, at least not
 directly. I think it's probably a good idea to have as little logic in
 the wrappers as possible. However, they are of course indirectly
 connected through wined3d; The connection between IDirect3DSurface9
 and IDirect3DTexture9 is the reason for doing it in the first place.
Right, I can't imagine how a IWineD3DTexture = IWineD3DSurface connection 
can help you, except if you use that connection to build the Direct3D9Texture 
= Direct3D9Surface connection.

 I'm not sure that connection is much more complex than the way it
 currently is. Right now the d3d7/8/9 wrapper objects are responsible
 for cleaning up their wined3d object, while with that change the
 wined3d object would become responsible for deleting the d3d7/8/9
 objects.
Err, the WineD3D objects clean themselves, it's the duty of the d3d7/8/9 
objects the release them if they are not needed any more. If the WineD3D 
refcount falls to 0 then(the general case), the WineD3D object will clean 
itself. If the object is in use somewhere internally in WineD3D, it's 
destroyed as soon WineD3D releases that refcount.

The exception is when WineD3D asked d3d7/8/9 to create objects via 
callbacks(e.g. the callback during texture creation), then wineD3D releases 
the parents of the objects it created. The parents take care for cleaning up, 
and they release their WineD3D child.



 It probably would. However, it's not all that different from the other
 option. The main difference seems to be that you don't separate the
 CleanUp and Release code, but use the parent in combination with a
 reference count that's guaranteed to be one as some sort of flag to
 decide whether to do the entire release code or just the cleanup part.
I personally think that we should stay withhin the possibilities that COM 
gives us, instead of adding cross-library destroy callbacks. Why? Read the 
current ddraw surface creation code and the surface release code, and follow 
the callbacks between the different ddraw / surface types.

 That, and in order the use the container in that way you either have
 to store it somewhere in d3d7/8/9 or retrieve it on every call to
 Release. I'm not sure if that reduces the complexity all that much.
 Regardless of whether separating the Release and CleanUp code would
 make things a lot more complex, I do think it's somewhat cleaner.
 Also, note that most (all?) wined3d objects already have a CleanUp
 function.
Well, at last it's up to Alexandre to decide which way to take.

I also think that seperated release / cleanup code makes it easy to do sloopy 
and incorrect refcounting. The ddraw code is full of bad surface reference 
counting, which is cascaded by a bad reference counting in ddraw, which works 
for most games, but breaks e.g. Empire Earth.


pgp6kYgx6pwvm.pgp
Description: PGP signature