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