Hello, I am trying again to Implement Direct3D 7 using WineD3D, and I've made some progress. The D3D7 Device implementation seems to initialize correctly, with the correct surfaces.
My solution looks like this:
* DirectDraw is unmodified, and it remains in ddraw.dll. * Direct3D7 uses generally the Direct3D9 interface of WineD3D. The only changes made to WineD3D are in WineD3DDeviceImpl_Release and a little change in WineD3DSurface. * WineD3D Surfaces can be attached to DDraw Surfaces, and they receive the properties of their parents, including the memory reserved for the surface * The D3D7 implementation creates a SwapChain and a RenderTarget from the DirectDrawSurface it's attached to, as well as a DepthStencil WineD3D surface to make WineD3D happy
I've made the following changes to WineD3D so far: * Make WineD3D handle dxVersion 7, generally with the same code as with dxVersion 7 * A new parameter to WineD3DDevice_Create: a pointer, which specifies an existing surface memory. If != NULL is passed, no memory is reserved by WineD3D, and it's not Released on WineD3DSurface_Release * When releasing the WineD3DDevice, don't release the parents of the RenderTarget, the DepthStencilBuffer, BackBuffer and FrontBuffer, because ddraw.dll needs it's surfaces. Instead, release the WineD3DSurfaces only.
The whole thing is far from beeing useable, if anyone is interested in the code, I can send it, but be warned, it's quite a mess at the moment. My plan is to get some games running, and then I'll send small and clean patches for CVS commit and upload a big patch somewhere for prior testing.
Stefan
On Mon, Oct 10, 2005 at 12:17:47AM +0200, Stefan Dösinger wrote:
- WineD3D Surfaces can be attached to DDraw Surfaces, and they receive the
properties of their parents, including the memory reserved for the surface
How do you handle the 'special' case Blits (between surface and texture, between surfaces, ...) ?
The whole thing is far from beeing useable, if anyone is interested in the code, I can send it, but be warned, it's quite a mess at the moment. My plan is to get some games running, and then I'll send small and clean patches for CVS commit and upload a big patch somewhere for prior testing.
Well, for one, I would like to see first the big patch (or at least enough code to be able to see where this is going) before you start sending small self-contained patch to be able to have a big picture of where we are going and if it will work at the end (with all special cases a 2D / 3D mix entails).
Anyway, keep up the work :-)
Lionel
Hello,
How do you handle the 'special' case Blits (between surface and texture, between surfaces, ...) ?
Well, I must admit that I don't have an totally detailed plan, but the DDraw surface and the WineD3D surface share the same memory area. So those Blits will be handled by the original DirectDraw surface implementation in any case, and if a WineD3D surface is attached, the DDraw surface implemenation updates the WineD3D surface whereever it might be necessary. I hope that I can avoid extra memcpy()s
I don't know if there might occur any problems if DGA is used, and I can't test it because DDraw DGA fails on my system for some reason.
Well, for one, I would like to see first the big patch (or at least enough code to be able to see where this is going) before you start sending small self-contained patch to be able to have a big picture of where we are going and if it will work at the end (with all special cases a 2D / 3D mix entails).
Sure, that's my intention. This way, developers can test games and fix bugs.
I have the initialisation and Release working right now, and Empire Earth starts up to a point where it tries to do some actual rendering and crashes after a few stub calls. I am now working on getting the d3d light test working.
Thanks for your feedback, Stefan
Hello, I've got the light test running successfully, but I have a problem and need your advice:
WineD3D can't create a device without a Window. For DirectDraw and D3D7 running without a Window is valid, at least to a certain extent. The D3D light test does so, and some games use this for some purposes. So I need to do something for the case HWND == 0 or the d3d surface is not a primary surface.
* Modifiy WineD3D to work without a window. I don't really like this solution.
* Create a hidden window to pass to WineD3D. Such a thing seems to be in DirectDraw allready, at least there's a WNDCLASS member in IDirectDrawImpl, but it's always 0.
Does DirectDraw create a internal window somewhere? Is this a useable way to go, or should I try to modify WineD3D for this purpose?
Stefan
(I CCed this mail to Olivier because WineD3D is heavily involved here.)
On Tue, Oct 11, 2005 at 10:24:58PM +0200, Stefan Dösinger wrote:
WineD3D can't create a device without a Window. For DirectDraw and D3D7 running without a Window is valid, at least to a certain extent. The D3D light test does so, and some games use this for some purposes. So I need to do something for the case HWND == 0 or the d3d surface is not a primary surface.
Why not use the 'desktop' window to do it ? No idea what window will be used to display when not in Desktop mode (maybe the X root window ?).
Lionel
WineD3D can't create a device without a Window. For DirectDraw and D3D7 running without a Window is valid, at least to a certain extent. The D3D light test does so, and some games use this for some purposes. So I need to do something for the case HWND == 0 or the d3d surface is not a primary surface.
Why not use the 'desktop' window to do it ? No idea what window will be used to display when not in Desktop mode (maybe the X root window ?).
This seems to be a good idea. Is this WND_DESKTOP or can I get it with GetDesktopWindow?
Stefan
--- Lionel Ulmer lionel.ulmer@free.fr wrote:
On Tue, Oct 11, 2005 at 10:24:58PM +0200, Stefan Dösinger wrote:
WineD3D can't create a device without a Window. For DirectDraw and D3D7 running without a Window is valid, at least to a certain extent. The D3D light test does so, and some games use this for some purposes. So I need to do something for the case HWND == 0 or the d3d surface is not a primary surface.
Why not use the 'desktop' window to do it ? No idea what window will be used to display when not in Desktop mode (maybe the X root window ?).
Some of the code currently falls back to the desktop windows, and it looks like the X root windows is the desktop window when wine isn't running in desktop mode. We should only be using the desktop window if that's what Windows does, otherwise it could cause problems with other areas of code that are expecting the desktop window to behave like the same as it does on Windows.
Lionel
-- Lionel Ulmer - http://www.bbrox.org/
___________________________________________________________ Get My Web - a better way to save web pages http://uk.search.yahoo.com/myresults/default
On Wed, Oct 12, 2005 at 02:23:09PM +0100, Oliver Stieber wrote:
Some of the code currently falls back to the desktop windows, and it looks like the X root windows is the desktop window when wine isn't running in desktop mode. We should only be using the desktop window if that's what Windows does, otherwise it could cause problems with other areas of code that are expecting the desktop window to behave like the same as it does on Windows.
From what I know, it does. Case in point is QuickTime which (AFAICR) locks /
unlocks a 'NULL' window which in Wine does a lot of ugly stuff.
Will need to check this though.
Lionel
--- Stefan Dösinger stefandoesinger@gmx.at wrote:
Hello,
I am trying again to Implement Direct3D 7 using WineD3D, and I've made some progress. The D3D7 Device implementation seems to initialize correctly, with the correct surfaces.
My solution looks like this:
- DirectDraw is unmodified, and it remains in ddraw.dll.
- Direct3D7 uses generally the Direct3D9 interface of WineD3D. The only
changes made to WineD3D are in WineD3DDeviceImpl_Release and a little change in WineD3DSurface.
Good
- WineD3D Surfaces can be attached to DDraw Surfaces, and they receive the
properties of their parents, including the memory reserved for the surface
- The D3D7 implementation creates a SwapChain and a RenderTarget from the
DirectDrawSurface it's attached to, as well as a DepthStencil WineD3D surface to make WineD3D happy
I've made the following changes to WineD3D so far:
- Make WineD3D handle dxVersion 7, generally with the same code as with
dxVersion 7
- A new parameter to WineD3DDevice_Create: a pointer, which specifies an
existing surface memory. If != NULL is passed, no memory is reserved by WineD3D, and it's not Released on WineD3DSurface_Release
Wined3d need to be able to interact with the HAL a bit better, so that things like fullscreen mode in x11drv work for wined3d as well as ddraw.
- When releasing the WineD3DDevice, don't release the parents of the
RenderTarget, the DepthStencilBuffer, BackBuffer and FrontBuffer, because ddraw.dll needs it's surfaces. Instead, release the WineD3DSurfaces only.
This should be managed by reference counting wherever possible, if ddraw holds a reference to the surface then it won't be released when the device is released.
I've got the light test running successfully, but I have a problem and need your advice:
WineD3D can't create a device without a Window. For DirectDraw and D3D7 running without a Window is valid, at least to a certain extent. The D3D light test does so, and some games use this for some purposes. So I need to do something for the case HWND == 0 or the d3d surface is not a primary surface.
Modifiy WineD3D to work without a window. I don't really like this solution.
Create a hidden window to pass to WineD3D. Such a thing seems to be in
DirectDraw allready, at least there's a WNDCLASS member in IDirectDrawImpl, but it's always 0.
Some work needs to be done to get child and MDI windows working with wined3d, one of the possibilities would be to render to offscreen surfaces and then do a clipped blit of the results to the MDI/Child windows. Something similar could be setup so that a device can be created without a window.
Does DirectDraw create a internal window somewhere? Is this a useable way to go, or should I try to modify WineD3D for this purpose?
It doesn't look like it, the only CreateWindow in ddraw is in surface_user.c when OWN_WINDOW is set, the comments note that OWN_WINDOW no longer works because of threading issues.
Stefan
(I CCed this mail to Olivier because WineD3D is heavily involved here.)
Thanks, Oliver.
___________________________________________________________ Get My Web - a better way to save web pages http://uk.search.yahoo.com/myresults/default
Hello,
This should be managed by reference counting wherever possible, if ddraw holds a reference to the surface then it won't be released when the device is released.
I tried to do this, but I ran into problems: I have a DirectDrawSurface, a Direct3D7Device, WineD3DDevice and a WineD3DSurface. The DirectDrawSurface is the Parent of the WineD3DSurface, and the WineD3DSurface is used as the Front Buffer for the WineD3DDevice. The Direct3D7Device is the parent of the WineD3DDevice.
Now I want to Destroy the Direct3D7Device because the application tols me to do so. While doing so I have to Destroy the WineD3DDevice for cleanup. The WineD3DSurface has to be destroyed too, otherwise it would be without it's WineD3DDevice. But I must keep the DirectDrawSurface.
Making the DirectDrawSurface survive the WineD3DDevice->Release() is easy - A AddRef does this job. But in this case the WineD3DSurface isn't destroyed. So my options are
*Destroy the WineD3DSurface manually before the WineD3DDevice->Release call. Problems: The WineD3DSurface is needed in WineD3DDevice->Release. Doing so causes a crash
*Do some RefCount magic and destroy the WineD3DSurface when the DirectDrawSurface's refcount reaches 1. Ugly in my opinion.
*Release only the WineD3DSurface in WineD3DDevice->Release, and not it's parent. This was the simplest approach, it was a modification of a few lines for the case dxVersion == 7.
*Any other possibilities that I didn't think of?
It doesn't look like it, the only CreateWindow in ddraw is in surface_user.c when OWN_WINDOW is set, the comments note that OWN_WINDOW no longer works because of threading issues.
I decided to create my own window when constructing the Direct3DDevice if necessary. Using the X11 root window caused a crash due to an invalid X11 call.
--- Stefan Dösinger stefandoesinger@gmx.at wrote:
Hello,
This should be managed by reference counting wherever possible, if ddraw holds a reference to the surface then it won't be released when the device is released.
I tried to do this, but I ran into problems: I have a DirectDrawSurface, a Direct3D7Device, WineD3DDevice and a WineD3DSurface. The DirectDrawSurface is the Parent of the WineD3DSurface, and the WineD3DSurface is used as the Front Buffer for the WineD3DDevice. The Direct3D7Device is the parent of the WineD3DDevice.
Now I want to Destroy the Direct3D7Device because the application tols me to do so. While doing so I have to Destroy the WineD3DDevice for cleanup. The WineD3DSurface has to be destroyed too, otherwise it would be without it's WineD3DDevice. But I must keep the DirectDrawSurface.
Making the DirectDrawSurface survive the WineD3DDevice->Release() is easy - A AddRef does this job. But in this case the WineD3DSurface isn't destroyed. So my options are
*Destroy the WineD3DSurface manually before the WineD3DDevice->Release call. Problems: The WineD3DSurface is needed in WineD3DDevice->Release. Doing so causes a crash
*Do some RefCount magic and destroy the WineD3DSurface when the DirectDrawSurface's refcount reaches 1. Ugly in my opinion.
*Release only the WineD3DSurface in WineD3DDevice->Release, and not it's parent. This was the simplest approach, it was a modification of a few lines for the case dxVersion == 7.
*Any other possibilities that I didn't think of?
* Work out a way to keep hold of the WineD3DDevice without causing circular references.
* Allow wined3dSurface to exist without it's device (Memory based surfaces should be device independent)
* Possibly a method that creates the ddraw or wined3d surfaces as required (Though that would be messy)
* Keep an 'internal' reference count, but I expect that would cause too much mutual dependency.
It doesn't look like it, the only CreateWindow in ddraw is in surface_user.c when OWN_WINDOW is set, the comments note that OWN_WINDOW no longer works because of threading issues.
I decided to create my own window when constructing the Direct3DDevice if necessary. Using the X11 root window caused a crash due to an invalid X11 call.
You should be able to use GetDesktopWindow() in wine to get the root window.
Oliver.
___________________________________________________________ To help you stay safe and secure online, we've developed the all new Yahoo! Security Centre. http://uk.security.yahoo.com