1848b8605Smrg 2848b8605Smrg 3848b8605Smrg 4848b8605SmrgIntroduction 5848b8605Smrg------------ 6848b8605Smrg 7848b8605SmrgThis document describes the implementation of the XFree86 4.0 libGL.so 8848b8605Smrglibrary defined by the Linux/OpenGL Base specification found at 9848b8605Smrghttp://reality.sgi.com/opengl/linux/linuxbase.html. 10848b8605Smrg 11848b8605SmrgThe documentation is divided into two sections: 12848b8605Smrg User's Guide 13848b8605Smrg Driver Developer's Guide 14848b8605Smrg 15848b8605SmrgAuthor: Brian Paul (brian@precisioninsight.com) 16848b8605SmrgDate: February 2000 17848b8605Smrg 18848b8605Smrg 19848b8605Smrg 20848b8605SmrgUser's Guide 21848b8605Smrg------------ 22848b8605Smrg 23848b8605SmrgUsing libGL.so 24848b8605Smrg 25848b8605SmrgThe libGL.so library defines the gl- and glX-prefixed functions needed to 26848b8605Smrgrun OpenGL programs. OpenGL client applications should link with the 27848b8605Smrg-lGL option to use it. 28848b8605Smrg 29848b8605SmrglibGL.so serves two primary functions: GLX protocol generation for indirect 30848b8605Smrgrendering and loading/management of hardware drivers for direct rendering. 31848b8605Smrg 32848b8605SmrgWhen libGL.so initializes itself it uses the DRI to determine the 33848b8605Smrgappropriate hardware driver for each screen on the local X display. 34848b8605SmrgThe hardware drivers are expected to be in the /usr/X11R6/lib/modules/dri/ 35848b8605Smrgdirectory. Drivers are named with the convention <name>_dri.so where 36848b8605Smrg<name> is a driver such as "radeon", "i965", "nouveau", etc. 37848b8605Smrg 38848b8605SmrgThe LIBGL_DRIVERS_DIR environment variable may be used to specify a 39848b8605Smrgdifferent DRI modules directory, overriding /usr/X11R6/lib/modules/dri/. 40848b8605SmrgThis environment variable is ignored in setuid programs for security 41848b8605Smrgreasons. 42848b8605Smrg 43848b8605SmrgWhen libGL.so is unable to locate appropriate hardware drivers it will 44848b8605Smrgfall back to using indirect GLX rendering. 45848b8605Smrg 46848b8605SmrgTo aid in solving problems, libGL.so will print diagnostic messages to 47848b8605Smrgstderr if the LIBGL_DEBUG environment variable is defined. 48848b8605Smrg 49848b8605SmrglibGL.so is thread safe. The overhead of thread safety for common, 50848b8605Smrgsingle-thread clients is negligible. However, the overhead of thread 51848b8605Smrgsafety for multi-threaded clients is significant. Each GL API call 52b8e80941Smrgrequires two calls to pthread_get_specific() which can noticeably 53848b8605Smrgimpact performance. Warning: libGL.so is thread safe but individual 54848b8605SmrgDRI drivers may not be. Please consult the documentation for a driver 55848b8605Smrgto learn if it is thread safe. 56848b8605Smrg 57848b8605Smrg 58848b8605Smrg 59848b8605SmrgIndirect Rendering 60848b8605Smrg 61848b8605SmrgYou can force indirect rendering mode by setting the LIBGL_ALWAYS_INDIRECT 62b8e80941Smrgenvironment variable to `true`. Hardware acceleration will not be used. 63848b8605Smrg 64848b8605Smrg 65848b8605Smrg 66848b8605SmrglibGL.so Extensibility 67848b8605Smrg 68848b8605SmrglibGL.so is designed to be extended without upgrading. That is, 69848b8605Smrgdrivers may install new OpenGL extension functions into libGL.so 70848b8605Smrgwithout requiring libGL.so to be replaced. Clients of libGL.so should 71848b8605Smrguse the glXGetProcAddressEXT() function to obtain the address of 72848b8605Smrgfunctions by name. For more details of GLX_ARB_get_proc_address see 73848b8605Smrghttp://oss.sgi.com/projects/ogl-sample/registry/ARB/get_proc_address.spec 74848b8605Smrg 75848b8605SmrglibGL.so is also designed with flexibility such that it may be used 76848b8605Smrgwith many generations of hardware drivers to come. 77848b8605Smrg 78848b8605Smrg 79848b8605Smrg 80848b8605Smrg 81848b8605SmrgDriver Developer's Guide 82848b8605Smrg------------------------ 83848b8605Smrg 84848b8605SmrgThis section describes the requirements to make an XFree86 4.0 85848b8605SmrglibGL.so-compatible hardware driver. It is not intended for end 86848b8605Smrgusers of libGL.so. 87848b8605Smrg 88848b8605Smrg 89848b8605SmrgXFree86 source files 90848b8605Smrg 91848b8605SmrglibGL.so is built inside XFree86 with sources found in xc/lib/GL/. 92848b8605SmrgSpecifically, libGL.so is built from: 93848b8605Smrg 94848b8605Smrg xc/lib/GL/glx/*.c 95848b8605Smrg xc/lib/dri/XF86dri.c 96848b8605Smrg xc/lib/dri/dri_glx.c 97848b8605Smrg xc/lib/GL/mesa/src/glapi.c 98848b8605Smrg xc/lib/GL/mesa/src/glapitemp.h 99848b8605Smrg xc/lib/GL/mesa/src/glapitable.h 100848b8605Smrg xc/lib/GL/mesa/src/glapioffsets.h 101848b8605Smrg xc/lib/GL/mesa/src/glapinoop.c 102848b8605Smrg xc/lib/GL/mesa/src/glheader.h 103848b8605Smrg xc/lib/GL/mesa/src/glthread.c 104848b8605Smrg xc/lib/GL/mesa/src/glthread.h 105848b8605Smrg xc/lib/GL/mesa/src/X86/glapi_x86.S 106848b8605Smrg xc/lib/GL/mesa/src/X86/assyntax.h 107848b8605Smrg 108848b8605SmrgUnderstand that the mesa/src/gl*.[ch] files are not tied to Mesa. They 109848b8605Smrghave no dependencies on the rest of Mesa and are designed to be reusable 110848b8605Smrgin a number of projects. 111848b8605Smrg 112848b8605SmrgThe glapi_x86.X and assyntax.h files implement x86-optimized dispatch 113848b8605Smrgof GL functions. They are not required; C-based dispatch can be used 114848b8605Smrginstead, with a slight performance penalty. 115848b8605Smrg 116848b8605Smrg 117848b8605Smrg 118848b8605SmrgDriver loading and binding 119848b8605Smrg 120848b8605SmrgWhen libGL.so initializes itself (via the __glXInitialize function) a 121848b8605Smrgcall is made to driCreateDisplay(). This function uses DRI facilities 122848b8605Smrgto determine the driver file appropriate for each screen on the local 123848b8605Smrgdisplay. Each screen's driver is then opened with dlopen() and asked 124848b8605Smrgfor its __driCreateScreen() function. The pointers to the __driCreateScreen() 125848b8605Smrgfunctions are kept in an array, indexed by screen number, in the 126848b8605Smrg__DRIdisplayRec struct. 127848b8605Smrg 128848b8605SmrgWhen a driver's __driCreateScreen() function is called, it must initialize 129848b8605Smrga __DRIscreenRec struct. This struct acts as the root of a tree of 130848b8605Smrgfunction pointers which are called to create and destroy contexts and 131848b8605Smrgdrawables and perform all the operations needed by the GLX interface. 132848b8605SmrgSee the xc/lib/GL/glx/glxclient.h file for details. 133848b8605Smrg 134848b8605Smrg 135848b8605Smrg 136848b8605SmrgDynamic Extension Function Registration 137848b8605Smrg 138848b8605SmrgIn order to provide forward compatibility with future drivers, libGL.so 139848b8605Smrgallows drivers to register new OpenGL extension functions which weren't 140848b8605Smrgknown when libGL.so was built. 141848b8605Smrg 142848b8605SmrgThe register_extensions() function in xc/lib/GL/dri/dri_glx.c is called 143848b8605Smrgas soon as libGL.so is loaded. This is done with gcc's constructor 144848b8605Smrgattribute. This mechanism will likely have to be changed for other compilers. 145848b8605Smrg 146848b8605Smrgregister_extensions() loops over all local displays and screens, determines 147848b8605Smrgthe DRI driver for each, and calls the driver's __driRegisterExtensions() 148848b8605Smrgfunction, if present. 149848b8605Smrg 150848b8605SmrgThe __driRegisterExtensions() function can add new entrypoints to libGL 151848b8605Smrgby calling: 152848b8605Smrg 153848b8605Smrg GLboolean _glapi_add_entrypoint(const char *funcName, GLuint offset) 154848b8605Smrg 155848b8605SmrgThe parameters are the name of the function (such as "glFoobarEXT") and the 156848b8605Smrgoffset of the dispatch slot in the API dispatch table. The return value 157848b8605Smrgindicates success (GL_TRUE) or failure (GL_FALSE). 158848b8605Smrg 159848b8605Smrg_glapi_add_entrypoint() will synthesize entrypoint code in assembly 160848b8605Smrglanguage. Assembly languages is required since parameter passing 161848b8605Smrgcan't be handled correctly using a C-based solution. 162848b8605Smrg 163848b8605SmrgThe address of the new entrypoint is obtained by calling the 164848b8605SmrgglXGetProcAddressARB() function. 165848b8605Smrg 166848b8605SmrgThe dispatch offset number MUST be a number allocated by SGI in the same 167848b8605Smrgmanner in which new GL_* constants are allocated. Using an arbitrary 168848b8605Smrgoffset number will result in many problems. 169848b8605Smrg 170848b8605Smrg 171848b8605Smrg 172848b8605SmrgDispatch Management 173848b8605Smrg 174848b8605SmrgWhen a GL context is made current, the driver must install its dispatch 175848b8605Smrgtable as the current dispatch table. This is done by calling 176848b8605Smrg 177848b8605Smrg void _glapi_set_dispatch(struct _glapi_table *dispatch); 178848b8605Smrg 179848b8605SmrgThis will install the named dispatch table for the calling thread. 180848b8605SmrgThe current dispatch table for a thread can be obtained by calling 181848b8605Smrg 182848b8605Smrg struct _glapi_table *_glapi_get_dispatch(void); 183848b8605Smrg 184848b8605SmrgFor higher performance in the common single-thread case, the global 185848b8605Smrgvariable _glapi_Dispatch will point to the current dispatch table. 186848b8605SmrgThis variable will be NULL when in multi-thread mode. 187848b8605Smrg 188848b8605Smrg 189848b8605Smrg 190848b8605SmrgContext Management 191848b8605Smrg 192848b8605SmrglibGL.so uses the XFree86 xthreads package to manage a thread-specific 193848b8605Smrgcurrent context pointer. See __glXGet/SetCurrentContext() in glext.c 194848b8605Smrg 195848b8605SmrgDrivers may use the _glapi_set/get_context() functions to maintain 196848b8605Smrga private thread-specific context pointer. 197848b8605Smrg 198