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 ([email protected])
|
---|
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
|
---|
36 | <name> is a driver such as "radeon", "i965", "nouveau", etc.
|
---|
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
|
---|
52 | requires two calls to pthread_get_specific() which can noticeably
|
---|
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 to `true`. 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 | The gl_x86_asm.py and assyntax.h files implement x86-optimized dispatch
|
---|
89 | of GL functions. They are not required; C-based dispatch can be used
|
---|
90 | instead, with a slight performance penalty.
|
---|
91 |
|
---|
92 |
|
---|
93 |
|
---|
94 | Driver loading and binding
|
---|
95 |
|
---|
96 | When libGL.so initializes itself (via the __glXInitialize function) a
|
---|
97 | call is made to driCreateDisplay(). This function uses DRI facilities
|
---|
98 | to determine the driver file appropriate for each screen on the local
|
---|
99 | display. Each screen's driver is then opened with dlopen() and asked
|
---|
100 | for its __driCreateScreen() function. The pointers to the __driCreateScreen()
|
---|
101 | functions are kept in an array, indexed by screen number, in the
|
---|
102 | __DRIdisplayRec struct.
|
---|
103 |
|
---|
104 | When a driver's __driCreateScreen() function is called, it must initialize
|
---|
105 | a __DRIscreenRec struct. This struct acts as the root of a tree of
|
---|
106 | function pointers which are called to create and destroy contexts and
|
---|
107 | drawables and perform all the operations needed by the GLX interface.
|
---|
108 | See the xc/lib/GL/glx/glxclient.h file for details.
|
---|
109 |
|
---|
110 |
|
---|
111 |
|
---|
112 | Dynamic Extension Function Registration
|
---|
113 |
|
---|
114 | In order to provide forward compatibility with future drivers, libGL.so
|
---|
115 | allows drivers to register new OpenGL extension functions which weren't
|
---|
116 | known when libGL.so was built.
|
---|
117 |
|
---|
118 | The register_extensions() function in xc/lib/GL/dri/dri_glx.c is called
|
---|
119 | as soon as libGL.so is loaded. This is done with gcc's constructor
|
---|
120 | attribute. This mechanism will likely have to be changed for other compilers.
|
---|
121 |
|
---|
122 | register_extensions() loops over all local displays and screens, determines
|
---|
123 | the DRI driver for each, and calls the driver's __driRegisterExtensions()
|
---|
124 | function, if present.
|
---|
125 |
|
---|
126 | The __driRegisterExtensions() function can add new entrypoints to libGL
|
---|
127 | by calling:
|
---|
128 |
|
---|
129 | GLboolean _glapi_add_entrypoint(const char *funcName, GLuint offset)
|
---|
130 |
|
---|
131 | The parameters are the name of the function (such as "glFoobarEXT") and the
|
---|
132 | offset of the dispatch slot in the API dispatch table. The return value
|
---|
133 | indicates success (GL_TRUE) or failure (GL_FALSE).
|
---|
134 |
|
---|
135 | _glapi_add_entrypoint() will synthesize entrypoint code in assembly
|
---|
136 | language. Assembly languages is required since parameter passing
|
---|
137 | can't be handled correctly using a C-based solution.
|
---|
138 |
|
---|
139 | The address of the new entrypoint is obtained by calling the
|
---|
140 | glXGetProcAddressARB() function.
|
---|
141 |
|
---|
142 | The dispatch offset number MUST be a number allocated by SGI in the same
|
---|
143 | manner in which new GL_* constants are allocated. Using an arbitrary
|
---|
144 | offset number will result in many problems.
|
---|
145 |
|
---|
146 |
|
---|
147 |
|
---|
148 | Dispatch Management
|
---|
149 |
|
---|
150 | When a GL context is made current, the driver must install its dispatch
|
---|
151 | table as the current dispatch table. This is done by calling
|
---|
152 |
|
---|
153 | void _glapi_set_dispatch(struct _glapi_table *dispatch);
|
---|
154 |
|
---|
155 | This will install the named dispatch table for the calling thread.
|
---|
156 | The current dispatch table for a thread can be obtained by calling
|
---|
157 |
|
---|
158 | struct _glapi_table *_glapi_get_dispatch(void);
|
---|
159 |
|
---|
160 | For higher performance in the common single-thread case, the global
|
---|
161 | variable _glapi_Dispatch will point to the current dispatch table.
|
---|
162 | This variable will be NULL when in multi-thread mode.
|
---|
163 |
|
---|
164 |
|
---|
165 |
|
---|
166 | Context Management
|
---|
167 |
|
---|
168 | libGL.so uses the XFree86 xthreads package to manage a thread-specific
|
---|
169 | current context pointer. See __glXGet/SetCurrentContext() in glext.c
|
---|
170 |
|
---|
171 | Drivers may use the _glapi_set/get_context() functions to maintain
|
---|
172 | a private thread-specific context pointer.
|
---|
173 |
|
---|