AIGLX Update

Kristian Høgsberg krh at bitplanet.net
Thu Feb 23 22:07:27 PST 2006


Hi,

Here's an updated accelerated indirect glx patch.  At this point I'd say 
it's ready to merge to head, but it's a pretty big patch, so I'll give a 
overview of what changed and why.  The patch is just under 200k (6300 
lines), so I've put it it on freedesktop.org instead of attaching it:

     http://freedesktop.org/~krh/accel-indirect-glx/aiglx-take-2.patch

plus it's on the accel_indirect_branch branch.

As I mentioned at the xdevconf, the previous patch would access the DRI 
driver directly which doesn't work well with platforms or DDXes without 
DRI.  Also, to accomodate the software rasterizer and the Xgl glx 
implementation, we need an abstraction layer between the GLX protocol 
code and the GL implementation.

This abstraction layer used to be the __GLinterface and 
__GLdrawablePrivate structs, but they didn't quite fit the bill--more 
than half the function pointers in these struct were unused by the GLX 
protocol code and yet it was necessary to add function pointers outside 
these structs (e.g. to the __GLXdrawablePrivate struct) to provide the 
necessary hooks.

The patch does away with __GLinterface and __GLdrawablePrivate and moves 
the function pointers that GLX actually used from these structs into the 
GLX objects.  The new design is heavily inspired by the DRI driver 
interface: There are three primary objects: __GLXscreen (was 
__GLXscreenInfo), __GLXcontext and __GLXdrawable (was 
__GLXdrawablePrivate).  To initialize things we have a stack of GL 
"providers" (GLcore, DRI or Xgl) and at extension init time, the GLX 
module loops through the stack and asks each provider to create a 
__GLXscreen for each screen.  The first provider that returns a non-NULL 
__GLXscreen gets to drive that screen.

The GLX layer will use the screen object to create contexts and 
drawables as needed using the createContext and createDrawable function 
pointers in the screen object:

     __GLXcontext *(*createContext)(__GLXscreenInfo *screen,
                                    __GLcontextModes *modes,
                                    __GLXcontext *shareContext);

     __GLXdrawablePrivate *(*createDrawablePrivate)(__GLXcontext *context,
                                                    DrawablePtr pDraw,
                                                    XID drawId);

GL implementations extend these three objects by embedding the base 
object in an implementation specific struct. For example, this is what 
the DRI implementation does:

     struct __GLXDRIscreen {
         __GLXscreen              base;

         __DRIscreen              driScreen;
         void                    *driver;
     };

The DRI screen constructor allocates a __GLXDRIscreen struct, but 
returns a __GLXscreen pointer.  Likewise, the context and drawable 
constructors in the screen object will allocate DRI specific context and 
drawable objects, but to the GLX core they will look like __GLXcontext 
and __GLXdrawable objects.

The DRI implementation is entirely contained in glxdri.c and is only 768 
lines.  It's a pretty good example of how to implement a __GLXprovider, 
and I think it should be pretty easy to port Xgl's glx implementation 
over to uses this design.  Xgl occasionally chains to the software 
implementation to implement off-screen rendering.  To achieve this, the 
Xgl implementation of __GLXscreen should probably create a mesa 
__GLXscreen and delegate to that to create software rendering contexts.

There's a --enable-glx-dri ./configure option to enable compilation of 
the GLX DRI loader and a --with-dri-driver-path option to specify the 
path to the DRI driver directory.  I've added an "AIGLX" server option 
to control wether the server should use the DRI driver or fall back to 
software for indirect rendering.  It defaults to off, and to enable it,  add

     Option "AIGLX"

to the ServerLayout section.

I've added a new sub module load function:

     pointer LoadSubModuleLocal(pointer, const char *, const char **,
                               const char **, pointer, const 
XF86ModReqInfo *,
                               int *, int *);

which loads a module without adding all symbols to the global namespace 
(i.e. it doesn't pass RTLD_GLOBAL to dlopen()).  This is to prevent MESA 
symbols in the DRI driver from resolving against identical symbols in 
GLcore as the DRI driver is loaded.  I now use this function for loading 
GLcore.  This accounts for all the changes in hw/xfree86/loader but is 
only implemented for the dlloader.  As we're heading towards a 
dlopen()-only loader, this shouldn't be a problem, though.

Also, the patch drops glxbuf.c, glxbuf.h, glxfb.c, glxfb.h, glxmem.c, 
glxmem.h, glxpix.c, glxpix.h, which weren't actually used before, and 
glximports.c and glximports.h which are now no longer used.

As I said, I think this work is now committable; it plays well with all 
DDXes and can be disabled at ./configure-time.  The remaining work is to 
see how this merges with Xgl, but I think this is a step in the right 
direction.

Kristian




More information about the xorg mailing list