mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-12-05 08:14:57 +08:00
fe08c22bee
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Acked-by: Brian Paul brianp@vmware.com Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19472>
174 lines
6.1 KiB
Plaintext
174 lines
6.1 KiB
Plaintext
|
|
|
|
|
|
Introduction
|
|
------------
|
|
|
|
This document describes the implementation of the XFree86 4.0 libGL.so
|
|
library defined by the Linux/OpenGL Base specification found at
|
|
http://reality.sgi.com/opengl/linux/linuxbase.html.
|
|
|
|
The documentation is divided into two sections:
|
|
User's Guide
|
|
Driver Developer's Guide
|
|
|
|
Author: Brian Paul (brian@precisioninsight.com)
|
|
Date: February 2000
|
|
|
|
|
|
|
|
User's Guide
|
|
------------
|
|
|
|
Using libGL.so
|
|
|
|
The libGL.so library defines the gl- and glX-prefixed functions needed to
|
|
run OpenGL programs. OpenGL client applications should link with the
|
|
-lGL option to use it.
|
|
|
|
libGL.so serves two primary functions: GLX protocol generation for indirect
|
|
rendering and loading/management of hardware drivers for direct rendering.
|
|
|
|
When libGL.so initializes itself it uses the DRI to determine the
|
|
appropriate hardware driver for each screen on the local X display.
|
|
The hardware drivers are expected to be in the /usr/X11R6/lib/modules/dri/
|
|
directory. Drivers are named with the convention <name>_dri.so where
|
|
<name> is a driver such as "radeon", "i965", "nouveau", etc.
|
|
|
|
The LIBGL_DRIVERS_DIR environment variable may be used to specify a
|
|
different DRI modules directory, overriding /usr/X11R6/lib/modules/dri/.
|
|
This environment variable is ignored in setuid programs for security
|
|
reasons.
|
|
|
|
When libGL.so is unable to locate appropriate hardware drivers it will
|
|
fall back to using indirect GLX rendering.
|
|
|
|
To aid in solving problems, libGL.so will print diagnostic messages to
|
|
stderr if the LIBGL_DEBUG environment variable is defined.
|
|
|
|
libGL.so is thread safe. The overhead of thread safety for common,
|
|
single-thread clients is negligible. However, the overhead of thread
|
|
safety for multi-threaded clients is significant. Each GL API call
|
|
requires two calls to pthread_get_specific() which can noticeably
|
|
impact performance. Warning: libGL.so is thread safe but individual
|
|
DRI drivers may not be. Please consult the documentation for a driver
|
|
to learn if it is thread safe.
|
|
|
|
|
|
|
|
Indirect Rendering
|
|
|
|
You can force indirect rendering mode by setting the LIBGL_ALWAYS_INDIRECT
|
|
environment variable to `true`. Hardware acceleration will not be used.
|
|
|
|
|
|
|
|
libGL.so Extensibility
|
|
|
|
libGL.so is designed to be extended without upgrading. That is,
|
|
drivers may install new OpenGL extension functions into libGL.so
|
|
without requiring libGL.so to be replaced. Clients of libGL.so should
|
|
use the glXGetProcAddressEXT() function to obtain the address of
|
|
functions by name. For more details of GLX_ARB_get_proc_address see
|
|
http://oss.sgi.com/projects/ogl-sample/registry/ARB/get_proc_address.spec
|
|
|
|
libGL.so is also designed with flexibility such that it may be used
|
|
with many generations of hardware drivers to come.
|
|
|
|
|
|
|
|
|
|
Driver Developer's Guide
|
|
------------------------
|
|
|
|
This section describes the requirements to make an XFree86 4.0
|
|
libGL.so-compatible hardware driver. It is not intended for end
|
|
users of libGL.so.
|
|
|
|
The gl_x86_asm.py and assyntax.h files implement x86-optimized dispatch
|
|
of GL functions. They are not required; C-based dispatch can be used
|
|
instead, with a slight performance penalty.
|
|
|
|
|
|
|
|
Driver loading and binding
|
|
|
|
When libGL.so initializes itself (via the __glXInitialize function) a
|
|
call is made to driCreateDisplay(). This function uses DRI facilities
|
|
to determine the driver file appropriate for each screen on the local
|
|
display. Each screen's driver is then opened with dlopen() and asked
|
|
for its __driCreateScreen() function. The pointers to the __driCreateScreen()
|
|
functions are kept in an array, indexed by screen number, in the
|
|
__DRIdisplayRec struct.
|
|
|
|
When a driver's __driCreateScreen() function is called, it must initialize
|
|
a __DRIscreenRec struct. This struct acts as the root of a tree of
|
|
function pointers which are called to create and destroy contexts and
|
|
drawables and perform all the operations needed by the GLX interface.
|
|
See the xc/lib/GL/glx/glxclient.h file for details.
|
|
|
|
|
|
|
|
Dynamic Extension Function Registration
|
|
|
|
In order to provide forward compatibility with future drivers, libGL.so
|
|
allows drivers to register new OpenGL extension functions which weren't
|
|
known when libGL.so was built.
|
|
|
|
The register_extensions() function in xc/lib/GL/dri/dri_glx.c is called
|
|
as soon as libGL.so is loaded. This is done with gcc's constructor
|
|
attribute. This mechanism will likely have to be changed for other compilers.
|
|
|
|
register_extensions() loops over all local displays and screens, determines
|
|
the DRI driver for each, and calls the driver's __driRegisterExtensions()
|
|
function, if present.
|
|
|
|
The __driRegisterExtensions() function can add new entrypoints to libGL
|
|
by calling:
|
|
|
|
GLboolean _glapi_add_entrypoint(const char *funcName, GLuint offset)
|
|
|
|
The parameters are the name of the function (such as "glFoobarEXT") and the
|
|
offset of the dispatch slot in the API dispatch table. The return value
|
|
indicates success (GL_TRUE) or failure (GL_FALSE).
|
|
|
|
_glapi_add_entrypoint() will synthesize entrypoint code in assembly
|
|
language. Assembly languages is required since parameter passing
|
|
can't be handled correctly using a C-based solution.
|
|
|
|
The address of the new entrypoint is obtained by calling the
|
|
glXGetProcAddressARB() function.
|
|
|
|
The dispatch offset number MUST be a number allocated by SGI in the same
|
|
manner in which new GL_* constants are allocated. Using an arbitrary
|
|
offset number will result in many problems.
|
|
|
|
|
|
|
|
Dispatch Management
|
|
|
|
When a GL context is made current, the driver must install its dispatch
|
|
table as the current dispatch table. This is done by calling
|
|
|
|
void _glapi_set_dispatch(struct _glapi_table *dispatch);
|
|
|
|
This will install the named dispatch table for the calling thread.
|
|
The current dispatch table for a thread can be obtained by calling
|
|
|
|
struct _glapi_table *_glapi_get_dispatch(void);
|
|
|
|
For higher performance in the common single-thread case, the global
|
|
variable _glapi_Dispatch will point to the current dispatch table.
|
|
This variable will be NULL when in multi-thread mode.
|
|
|
|
|
|
|
|
Context Management
|
|
|
|
libGL.so uses the XFree86 xthreads package to manage a thread-specific
|
|
current context pointer. See __glXGet/SetCurrentContext() in glext.c
|
|
|
|
Drivers may use the _glapi_set/get_context() functions to maintain
|
|
a private thread-specific context pointer.
|
|
|