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