224 lines
9.4 KiB
Plaintext
224 lines
9.4 KiB
Plaintext
|
-------------------------------------------------------------------------------
|
||
|
Porting GLSREF to a new platform
|
||
|
-------------------------------------------------------------------------------
|
||
|
|
||
|
GLSREF is a reference implementation of the GLS API. The primary
|
||
|
goals of GLSREF are as follows:
|
||
|
|
||
|
- Correct runtime behavior
|
||
|
- Portability to many platforms
|
||
|
|
||
|
The following are NOT primary goals of GLSREF:
|
||
|
|
||
|
- Maximum execution speed
|
||
|
- Minimum resource usage
|
||
|
- Portability to all platforms
|
||
|
|
||
|
Although GLSREF is strictly a reference implementation of the GLS API,
|
||
|
and not a sample implementation or a product-quality implementation,
|
||
|
the task of creating a product-quality implementation of the GLS API
|
||
|
on a specific platform is likely to be significantly easier if GLSREF,
|
||
|
rather than a clean sheet of paper, is used as the starting point.
|
||
|
|
||
|
There are many possible product-quality implementations of the GLS
|
||
|
API. The only constraint on all such implementations is that their
|
||
|
runtime behavior (as observed via the GLS API) must be
|
||
|
indistinguishable (except for execution speed and resource usage) from
|
||
|
the runtime behavior of GLSREF.
|
||
|
|
||
|
As explained below, developing a product-quality implementation of the
|
||
|
GLS API requires the addition of hooks to the underlying GL
|
||
|
implementation.
|
||
|
|
||
|
-------------------------------------------------------------------------------
|
||
|
Assumptions
|
||
|
-------------------------------------------------------------------------------
|
||
|
|
||
|
GLSREF makes the following assumptions about the underlying platform.
|
||
|
Bringing up GLSREF on a platform that matches these assumptions should
|
||
|
involve relatively little effort. Bringing up GLSREF on a platform
|
||
|
that does not match these assumptions is likely to require significant
|
||
|
modifications to GLSREF.
|
||
|
|
||
|
- The implementation of the C language and standard library conforms to the
|
||
|
ISO C standard.
|
||
|
|
||
|
- Two's complement representation is used for all signed integers.
|
||
|
|
||
|
- The representation of all floating-point numbers conforms to the IEEE
|
||
|
754-1985 standard.
|
||
|
|
||
|
- The implementation of GL conforms to the OpenGL standard.
|
||
|
|
||
|
- The sizes of GL data types are as follows:
|
||
|
|
||
|
GLbitfield 32 bits
|
||
|
GLboolean 8 bits
|
||
|
GLbyte 8 bits
|
||
|
GLclampd 64 bits
|
||
|
GLclampf 32 bits
|
||
|
GLdouble 64 bits
|
||
|
GLenum 32 bits
|
||
|
GLfloat 32 bits
|
||
|
GLint 32 bits
|
||
|
GLlong 64 bits
|
||
|
GLshort 16 bits
|
||
|
GLsizei 32 bits
|
||
|
GLubyte 8 bits
|
||
|
GLuint 32 bits
|
||
|
GLulong 64 bits
|
||
|
GLushort 16 bits
|
||
|
|
||
|
- A runtime linking mechanism is available. To date, GLSREF has been brought
|
||
|
up on platforms that support one of the following runtime linking
|
||
|
mechanisms:
|
||
|
|
||
|
- AIX Shared Archives (.a)
|
||
|
- HP-UX Shared Libraries (.sl)
|
||
|
- SVR4 Dynamic Shared Objects (.so)
|
||
|
- Windows NT Dynamic Link Libraries (.dll)
|
||
|
|
||
|
SGI has no plans to change this set of assumptions.
|
||
|
|
||
|
The test programs supplied with GLSREF assume that the GL commands
|
||
|
glGetIntegerv() and glPixelStorei() are no-ops if there is no current
|
||
|
GL rendering context. This assumption obviates the need for the test
|
||
|
programs to create GL rendering contexts. This in turn makes the test
|
||
|
programs more portable.
|
||
|
|
||
|
-------------------------------------------------------------------------------
|
||
|
Bringing up GLSREF on a new platform
|
||
|
-------------------------------------------------------------------------------
|
||
|
|
||
|
Platform dependencies in GLSREF are encapsulated in the files
|
||
|
lib/platform.[ch]. These files contain platform specific code for a
|
||
|
number of platforms. The #if/#endif conditional compilation mechanism
|
||
|
is used to select code for a specific platform.
|
||
|
|
||
|
Conditional compilation can also be used to build different GLS
|
||
|
implementations for a single platform. For example, the files
|
||
|
lib/platform.[ch] contain platform specific code for both the portable
|
||
|
IRIX version of GLSREF (which will run on any system running IRIX
|
||
|
Release 5.3 or later) and the product-quality IRIX implementation of
|
||
|
the GLS API (which contains generated source code that is subject to
|
||
|
change with each IRIX release). Conditional compilation determines
|
||
|
which IRIX implementation is built.
|
||
|
|
||
|
Use the following steps as a guide to bringing up GLSREF on a new
|
||
|
platform.
|
||
|
|
||
|
- Create <platform>.mak files for your platform, using the supplied
|
||
|
makefiles as a guide.
|
||
|
|
||
|
- Add the following symbol definition to your C compilation command line:
|
||
|
|
||
|
-D__GLS_PLATFORM_<platform>=1
|
||
|
|
||
|
If your platform has "big-endian" byte order, also add to your C
|
||
|
compilation command line:
|
||
|
|
||
|
-D__GLS_MSB_FIRST=1
|
||
|
|
||
|
- For ease of initial bringup, add the following to lib/platform.h,
|
||
|
using the supplied platform specific sections as a guide:
|
||
|
|
||
|
#if __GLS_PLATFORM_<platform>
|
||
|
|
||
|
#define __GL_LIB_NAME "<GL_lib_name>"
|
||
|
#define __GLS_FAKE_FINITE_FUNC 1
|
||
|
#define __GLS_FAKE_MUTEX 1
|
||
|
#define __GLS_FAKE_THREAD_LOCAL_STORAGE 1
|
||
|
#define __GLS_FAKE_TRUNCATE_FUNC 1
|
||
|
#define __GLS_GL_DISPATCH 1
|
||
|
#define __GLS_PLATFORM "<platform>"
|
||
|
|
||
|
#endif /* __GLS_PLATFORM_<platform> */
|
||
|
|
||
|
If your platform supports SVR4 Dynamic Shared Objects, also add to
|
||
|
this section:
|
||
|
|
||
|
#define __GLS_GL_DISPATCH_DSO 1
|
||
|
|
||
|
- Add a platform specific section to lib/platform.c that contains code to
|
||
|
operate your platform's dynamic linking mechanism. Use the supplied
|
||
|
platform specific sections as a guide.
|
||
|
|
||
|
- Once you have successfully brought up an initial version of GLSREF on your
|
||
|
platform, use the supplied platform specific code as a guide to determine
|
||
|
if you can implement the following:
|
||
|
|
||
|
- use of alloca() for decode functions
|
||
|
- finite function for 64-bit floating point numbers
|
||
|
- mutual exclusion (critical sections)
|
||
|
- thread local storage
|
||
|
- file truncate function
|
||
|
- support for 64-bit integers
|
||
|
|
||
|
None of these things is required by the ISO C standard. If you can
|
||
|
implement some or all of them, make appropriate modifications to your
|
||
|
platform specific #defines in lib/platform.h.
|
||
|
|
||
|
- Once you have successfully brought up GLSREF on your platform, please send
|
||
|
SGI a set of diffs containing the changes you had to make. If your
|
||
|
platform matches the assumptions listed above, SGI will make a good-faith
|
||
|
effort to incorporate your changes into the master GLSREF sources. This
|
||
|
will simplify your integration task when SGI produces future GLSREF
|
||
|
releases.
|
||
|
|
||
|
If your platform does not match the assumptions listed above, SGI will
|
||
|
consider incorporating your changes into the master GLSREF sources, but
|
||
|
reserves the right to choose not to incorporate your changes, especially
|
||
|
if those changes do not enhance portability to any other platform.
|
||
|
|
||
|
-------------------------------------------------------------------------------
|
||
|
Developing a product-quality GLS implementation based on GLSREF
|
||
|
-------------------------------------------------------------------------------
|
||
|
|
||
|
The main difficulty in using GLSREF as the basis for a product-quality
|
||
|
implementation of the GLS API arises from the fact that every GL
|
||
|
command must be captured by GLS when the issuing thread has a current
|
||
|
GLS context and that GLS context is in capture mode.
|
||
|
|
||
|
As shipped, GLSREF achieves this effect by providing a wrapper
|
||
|
function for each GL command. Each wrapper function has the same name
|
||
|
as the function that implements the corresponding GL command.
|
||
|
|
||
|
If a thread has a current GLS context and that context is in capture
|
||
|
mode, the wrapper functions redirect to GLS all GL commands issued by
|
||
|
that thread. Otherwise, the wrapper functions pass directly to GL all
|
||
|
GL commands issued by that thread. GLSREF uses the underlying
|
||
|
platform's runtime linking mechanism to obtain the addresses of the
|
||
|
functions that implement GL commands.
|
||
|
|
||
|
The wrapper technique makes it possible to bring up GLSREF quickly on
|
||
|
a platform that matches the assumptions listed above. On the other
|
||
|
hand, the wrapper technique has the major disadvantage that linking an
|
||
|
application with the GLSREF library will degrade that application's
|
||
|
immediate-mode GL performance, even when the wrapper functions are
|
||
|
passing all GL commands directly to GL. As a result, GLSREF is not
|
||
|
suitable for shipping unmodified to customers as a product.
|
||
|
|
||
|
In order to make it possible for applications to link with the GLSREF
|
||
|
library without affecting immediate-mode GL performance, it is
|
||
|
necessary to modify GLSREF to not use the wrapper technique. This in
|
||
|
turn requires modifications to the underlying GL implementation.
|
||
|
|
||
|
Specifically, it is necessary to add hooks to the underlying GL
|
||
|
command-dispatch mechanism that cause a GL command to be redirected to
|
||
|
GLS if the issuing thread has a current GLS context and that GLS
|
||
|
context is in capture mode.
|
||
|
|
||
|
For an example of how this can be done, see the files lib/platform.c
|
||
|
and lib/g_irix.c. The command __glsUpdateDispatchTables() enables and
|
||
|
disables the underlying GL dispatch table override mechanism, and the
|
||
|
commands __glsBeginCaptureExec() and __glsEndCaptureExec() are used to
|
||
|
temporarily disable the underlying GL dispatch table override
|
||
|
mechanism for a single command. This is necessary when a GLS context
|
||
|
is in capture mode and either generates a glGet() command or captures
|
||
|
a GL command whose capture-flag variable has the bit
|
||
|
GLS_CAPTURE_EXECUTE_BIT set.
|
||
|
|
||
|
-------------------------------------------------------------------------------
|
||
|
End
|
||
|
-------------------------------------------------------------------------------
|