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