DirectX under Wine

Stefan Dösinger stefan at
Thu Apr 26 10:36:14 CDT 2007

Am Donnerstag 26 April 2007 12:28 schrieb Robert Fairlie:
> Hello,
> I am a contractor for a company in the UK. I have developed a 3D module for
> an oil reservoir visualisation program on Windows that is now required to
> run on Linux. The Wine port has been very successful (it started a month or
> so ago), but I'm having a couple of DirectX-related problems. We're using
> DirectX 9, the LinuxOS is Fedora Core 6, the Wine version is 0.9.32, and
> we're only using the binary loader, i.e. we're simply running our Windows
> executable under Wine.
> The problems I'm having relate to calling IDirect3DSurface9::GetDC() on an
> offscreen surface,
Do not use GetDC. This is a bad idea, especially in wine. This call is 
implemented only very rudimentarily. If you do what you are doing here, the 
the following happens: Then LockRect is called to download the opengl render 
target to the DIB secion. On the BitBlt, the DIB section is converted to the 
X server's color depth, then sent to the X server via shared memory which 
handles the Blit. The very first call creates a DIB section for the surface, 
which is destroyed when the surface is destroyed. However, I have never 
tested it for offscreen surfaces.

The whole issue is a huge PITA though. I think a more efficient way(but still 
very slow) would be to render to an offscreen surface or the back buffer, 
then use StretchRect to copy it to a texture and Lock the texture. If 
possible, do some other work between the stretchrect and the lock, because 
lock forces a gpu-cpu synchronisation. If you're rendering to the back buffer 
you should, if possible, render upside down and do an upside down stretch, if 
you render to an offscreen surface wined3d does the upside down thing for 
you. Thats because glCopyTexSubImage, which we use for the framebuffer -> 
texture copy, copies upside down, and unless the app orders an upside down 
copy we have to copy line by line. Also avoid StretchRect parameters that 
require the surface to be Stretched(just do a 1:1 copy). The blit the 
downloaded memory to the window. The mail gain of this is that wined3d knows 
you're locking the surface read only. If you use GetDC we don't know that and 
on ReleaseDC we upload the surface from the DIB section back to opengl 
because it may have been modified.

To answer your question about the general implementation of d3d: Yes, we do 
use hardware accelerated OpenGL, in fact we just call the opengl 
implementation that is present on the Linux system. Certain operations can't 
be mapped directly to opengl, like GetDC. I'm having plans to implement 
various GDI functions on top of opengl, but those are just plans.

Another *ugly* way may be to render to the back buffer and call glCopyPixels 
from your program. If you're using d3d in wine you have an opengl context 
active, so technically you can just do opengl calls. This avoids copying the 
frame buffer to system memory, but I don't know if glCopyPixels leaves the 
rest of the window intact. Furthermore you'd have to calculate the correct 
offset based on wine's bug.

As for the stateblock I have no idea what could go wrong. It would be 
interesting to follow the call into the wine code and find the line that 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url :

More information about the wine-devel mailing list