1 2 3 4Introduction 5------------ 6 7This document describes the implementation of the XFree86 4.0 libGL.so 8library defined by the Linux/OpenGL Base specification found at 9http://reality.sgi.com/opengl/linux/linuxbase.html. 10 11The documentation is divided into two sections: 12 User's Guide 13 Driver Developer's Guide 14 15Author: Brian Paul (brian@precisioninsight.com) 16Date: February 2000 17 18 19 20User's Guide 21------------ 22 23Using libGL.so 24 25The libGL.so library defines the gl- and glX-prefixed functions needed to 26run OpenGL programs. OpenGL client applications should link with the 27-lGL option to use it. 28 29libGL.so serves two primary functions: GLX protocol generation for indirect 30rendering and loading/management of hardware drivers for direct rendering. 31 32When libGL.so initializes itself it uses the DRI to determine the 33appropriate hardware driver for each screen on the local X display. 34The hardware drivers are expected to be in the /usr/X11R6/lib/modules/dri/ 35directory. Drivers are named with the convention <name>_dri.so where 36<name> is a driver such as "radeon", "i965", "nouveau", etc. 37 38The LIBGL_DRIVERS_DIR environment variable may be used to specify a 39different DRI modules directory, overriding /usr/X11R6/lib/modules/dri/. 40This environment variable is ignored in setuid programs for security 41reasons. 42 43When libGL.so is unable to locate appropriate hardware drivers it will 44fall back to using indirect GLX rendering. 45 46To aid in solving problems, libGL.so will print diagnostic messages to 47stderr if the LIBGL_DEBUG environment variable is defined. 48 49libGL.so is thread safe. The overhead of thread safety for common, 50single-thread clients is negligible. However, the overhead of thread 51safety for multi-threaded clients is significant. Each GL API call 52requires two calls to pthread_get_specific() which can noticeably 53impact performance. Warning: libGL.so is thread safe but individual 54DRI drivers may not be. Please consult the documentation for a driver 55to learn if it is thread safe. 56 57 58 59Indirect Rendering 60 61You can force indirect rendering mode by setting the LIBGL_ALWAYS_INDIRECT 62environment variable to `true`. Hardware acceleration will not be used. 63 64 65 66libGL.so Extensibility 67 68libGL.so is designed to be extended without upgrading. That is, 69drivers may install new OpenGL extension functions into libGL.so 70without requiring libGL.so to be replaced. Clients of libGL.so should 71use the glXGetProcAddressEXT() function to obtain the address of 72functions by name. For more details of GLX_ARB_get_proc_address see 73http://oss.sgi.com/projects/ogl-sample/registry/ARB/get_proc_address.spec 74 75libGL.so is also designed with flexibility such that it may be used 76with many generations of hardware drivers to come. 77 78 79 80 81Driver Developer's Guide 82------------------------ 83 84This section describes the requirements to make an XFree86 4.0 85libGL.so-compatible hardware driver. It is not intended for end 86users of libGL.so. 87 88 89XFree86 source files 90 91libGL.so is built inside XFree86 with sources found in xc/lib/GL/. 92Specifically, libGL.so is built from: 93 94 xc/lib/GL/glx/*.c 95 xc/lib/dri/XF86dri.c 96 xc/lib/dri/dri_glx.c 97 xc/lib/GL/mesa/src/glapi.c 98 xc/lib/GL/mesa/src/glapitemp.h 99 xc/lib/GL/mesa/src/glapitable.h 100 xc/lib/GL/mesa/src/glapioffsets.h 101 xc/lib/GL/mesa/src/glapinoop.c 102 xc/lib/GL/mesa/src/glheader.h 103 xc/lib/GL/mesa/src/glthread.c 104 xc/lib/GL/mesa/src/glthread.h 105 xc/lib/GL/mesa/src/X86/glapi_x86.S 106 xc/lib/GL/mesa/src/X86/assyntax.h 107 108Understand that the mesa/src/gl*.[ch] files are not tied to Mesa. They 109have no dependencies on the rest of Mesa and are designed to be reusable 110in a number of projects. 111 112The glapi_x86.X and assyntax.h files implement x86-optimized dispatch 113of GL functions. They are not required; C-based dispatch can be used 114instead, with a slight performance penalty. 115 116 117 118Driver loading and binding 119 120When libGL.so initializes itself (via the __glXInitialize function) a 121call is made to driCreateDisplay(). This function uses DRI facilities 122to determine the driver file appropriate for each screen on the local 123display. Each screen's driver is then opened with dlopen() and asked 124for its __driCreateScreen() function. The pointers to the __driCreateScreen() 125functions are kept in an array, indexed by screen number, in the 126__DRIdisplayRec struct. 127 128When a driver's __driCreateScreen() function is called, it must initialize 129a __DRIscreenRec struct. This struct acts as the root of a tree of 130function pointers which are called to create and destroy contexts and 131drawables and perform all the operations needed by the GLX interface. 132See the xc/lib/GL/glx/glxclient.h file for details. 133 134 135 136Dynamic Extension Function Registration 137 138In order to provide forward compatibility with future drivers, libGL.so 139allows drivers to register new OpenGL extension functions which weren't 140known when libGL.so was built. 141 142The register_extensions() function in xc/lib/GL/dri/dri_glx.c is called 143as soon as libGL.so is loaded. This is done with gcc's constructor 144attribute. This mechanism will likely have to be changed for other compilers. 145 146register_extensions() loops over all local displays and screens, determines 147the DRI driver for each, and calls the driver's __driRegisterExtensions() 148function, if present. 149 150The __driRegisterExtensions() function can add new entrypoints to libGL 151by calling: 152 153 GLboolean _glapi_add_entrypoint(const char *funcName, GLuint offset) 154 155The parameters are the name of the function (such as "glFoobarEXT") and the 156offset of the dispatch slot in the API dispatch table. The return value 157indicates success (GL_TRUE) or failure (GL_FALSE). 158 159_glapi_add_entrypoint() will synthesize entrypoint code in assembly 160language. Assembly languages is required since parameter passing 161can't be handled correctly using a C-based solution. 162 163The address of the new entrypoint is obtained by calling the 164glXGetProcAddressARB() function. 165 166The dispatch offset number MUST be a number allocated by SGI in the same 167manner in which new GL_* constants are allocated. Using an arbitrary 168offset number will result in many problems. 169 170 171 172Dispatch Management 173 174When a GL context is made current, the driver must install its dispatch 175table as the current dispatch table. This is done by calling 176 177 void _glapi_set_dispatch(struct _glapi_table *dispatch); 178 179This will install the named dispatch table for the calling thread. 180The current dispatch table for a thread can be obtained by calling 181 182 struct _glapi_table *_glapi_get_dispatch(void); 183 184For higher performance in the common single-thread case, the global 185variable _glapi_Dispatch will point to the current dispatch table. 186This variable will be NULL when in multi-thread mode. 187 188 189 190Context Management 191 192libGL.so uses the XFree86 xthreads package to manage a thread-specific 193current context pointer. See __glXGet/SetCurrentContext() in glext.c 194 195Drivers may use the _glapi_set/get_context() functions to maintain 196a private thread-specific context pointer. 197 198