Compat (i386) GL apps can't work with hardware DRI on amd64

Hello!

I found a strange behavior of GL apps in compat mode. I have FreeBSD 9.0-CURRENT amd64 and I need to use i386 GL apps (WINE with Direct3D Windows apps). Xorg works on i965GM chipset (i915) with tuned up DRM. And native (amd64) GL applications work fine. But i386 apps won't work with hardware DRI. Just two examples:

The output of native (amd64) glxinfo:

Code:
%setenv LIBGL_DEBUG verbose
%glxinfo | grep render
libGL: XF86DRIGetClientDriverName: 1.9.0 i965 (screen 0)
libGL: OpenDriver: trying /usr/local/lib/dri/i965_dri.so
drmOpenDevice: node name is /dev/dri/card0
drmOpenDevice: open result is 4, (OK)
drmOpenByBusid: Searching for BusID pci:0000:00:02.0
drmOpenDevice: node name is /dev/dri/card0
drmOpenDevice: open result is 4, (OK)
drmOpenByBusid: drmOpenMinor returns 4
drmOpenByBusid: drmGetBusid reports pci:0000:00:02.0
Failed to initialize GEM.  Falling back to classic.
libGL error: 
Can't open configuration file /etc/drirc: No such file or directory.
direct rendering: Yes
OpenGL renderer string: Mesa DRI Intel(R) 965GM 20090418 2009Q1

And another one, i386 glxinfo:
Code:
%setenv LD_32_LIBRARY_PATH /usr/local/lib32
%setenv LIBGL_DRIVERS_PATH /usr/local/lib32/dri
%setenv LIBGL_DEBUG verbose
%cd mesa-demos-i386/bin ; glxinfo | grep render
libGL: XF86DRIGetClientDriverName: 1.9.0 i965 (screen 0)
libGL: OpenDriver: trying /usr/local/lib32/dri/i965_dri.so
drmOpenDevice: node name is /dev/dri/card0
drmOpenDevice: open result is 4, (OK)
drmOpenByBusid: Searching for BusID pci:0000:00:02.0
drmOpenDevice: node name is /dev/dri/card0
drmOpenDevice: open result is 4, (OK)
drmOpenByBusid: drmOpenMinor returns 4
drmOpenByBusid: drmGetBusid reports (null)
drmOpenDevice: node name is /dev/dri/card1
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card2
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card3
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card4
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card5
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card6
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card7
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card8
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card9
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card10
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card11
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card12
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card13
drmOpenByBusid: drmOpenMinor returns -1003
drmOpenDevice: node name is /dev/dri/card14
drmOpenByBusid: drmOpenMinor returns -1003
libGL error: drmOpenOnce failed (Operation not permitted)
libGL error: reverting to software direct rendering
libGL: OpenDriver: trying /usr/local/lib32/dri/swrast_dri.so
direct rendering: Yes
OpenGL renderer string: Software Rasterizer

(It was created i386 "workplace" - with i386 libs)

As you can see on libGL debug, it can't open device by BusId in compat mode. I played a little with the source code oflibdrm with debug insertions and found this function:

Code:
/**
 * Call ioctl, restarting if it is interupted
 */
int
drmIoctl(int fd, unsigned long request, void *arg)
{
    int	ret;

    do {
	ret = ioctl(fd, request, arg);
    } while (ret == -1 && (errno == EINTR || errno == EAGAIN));

    return ret;
}

which invoked as
Code:
drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)

Before
Code:
drmOpenByBusid: drmGetBusid reports (null)
in compat mode ioctl() returns -1 and errno described as
Code:
Bad address
But there is a device id (pci:0000:00:02.0) as return value in native mode.

So, the next step needs to be exploration of ioctl(), but I don't feel like jumping into that without guidance from a kernel Jedi.

Can anybody help me with my problem? Or did I complicate the problem and is there a simple solution?

By the way, there is the same problem with Linux applications - it can't use hardware dri too - only software emulation.
 
There is no simple solution. I talked with rnoland@ about this back when he was maintaining the DRM and he was aware of the problem. I believe there is even a pr open on the subject.

You can get hardware acceleration going via AIGLX (if you enable AIGLX in your xorg.conf) by setting LIBGL_ALWAYS_INDIRECT=1 before running the 32-bit app. It will pass all OpenGL commands through the X server (and, therefore, through the 64-bit r600_dri.so driver that the X server loads). As a result, it's faster than software rendering, but slower than direct rendering.

Adam
 
Thank you for the answer!

adamk said:
There is no simple solution. I talked with rnoland@ about this back when he was maintaining the DRM and he was aware of the problem. I believe there is even a pr open on the subject.
Could you explain me in two words why the problems is so complicated? Just to make the main picture of the problem. Can I help in making solution? I have a little knowledge of C and a short time, as well as logic and abstraction skills :).

adamk said:
You can get hardware acceleration going via AIGLX (if you enable AIGLX in your xorg.conf) by setting LIBGL_ALWAYS_INDIRECT=1 before running the 32-bit app. It will pass all OpenGL commands through the X server (and, therefore, through the 64-bit r600_dri.so driver that the X server loads). As a result, it's faster than software rendering, but slower than direct rendering.

Unfortunately, the required application does not work with AIXGL: when I turn this mode on it just crashes, and in the DRI software rendering mode a special application cursor on a black background is only visible; so the application is unusable at all.
 
heathen said:
Thank you for the answer!


Could you explain me in two words why the problems is so complicated? Just to make the main picture of the problem. Can I help in making solution? I have a little knowledge of C and a short time, as well as logic and abstraction skills :).

Sorry, I can't. It's been a coupe of years since I had that discussion with rnoland@.
 
Back
Top