home | << prev | next >> | contents |
Shaders are written as C or C++ subroutines, stored in files with the extension " .c". To use these shaders in a scene, they must be dynamically linked into mental ray at runtime. mental ray accepts shaders in three forms:
To create a DSO, first compile the shader source to object format using cc as described above, then run the Unix command " ld -shared source.o", again assuming that the object file is called source.o. This ld command applies to Unix/Linux. Using DSOs is the fastest way to load shaders, there is very little overhead. DSOs, like object files, are loaded using link statements or -link options.
The commands to create a DSO depend on the operating system type. To create a DSO named example.so from a source file example.c, use the following commands. Insert the -g command line option after -c to insert debugging information, or insert -O to compile an optimized version. On Linux, -g and -O can be combined. Refer to the compiler documentation for details.
Linux x86, gcc
gcc -c -O3 -fPIC -Bsymbolic [14] shader.cLinux x86, icc
icc -c -O2 -KPIC -Bsymbolic -tpp7 shader.cLinux x86, 64 bits
gcc -c -O3 -fPIC -Bsymbolic -DBIT64 shader.cLinux IA 64
gcc -c -O3 -KPIC -Bsymbolic -DBIT64 shader.cLinux Alpha
gcc -c -O3 -ansi -fPIC -mieee -DBIT64 shader.cIRIX, 32 bits
cc -n32 -O3 -shared -o example.so example.cIRIX, 64 bits
cc -64 -O3 -DBIT64 -shared -o example.so example.cMacOS X
cc -c -O3 -fPIC -dynamic -fno-common example.cHP/UX HPPA
cc -c -Aa +z example.cHP/UX IA 64
cc -c +O3 +Onolimit +DD64 -Ae -Bprotected_defIBM AIX
cc -c -O3 example.cSun Solaris
cc -c -xO3 -KPIC -D_REENTRANT example.cTru64 Unix
cc -c -newc -O2 -ieee_with_no_inexact -DBIT64 -D_REENTRANTNT x86, VC
cl /c /O2 /G6 /MD /nologo /W3 -DWIN_NT example.cNT x86, icl
icl /c /Ox /G7 /MD /nologo /W3 -DWIN_NT example.cNT x86, 64 bits
cl /c /GR /Zp8 /W3 /GX /GR /GF /O2 /MD /nologo /W3NT IA 64
ecl -c /GR /Zp8 /W3 /GX /GR /GF /O2 /MD /nologo /W3Compiling and creating DSOs requires that a C development environment is installed on the system. If the cc, ld, etc. commands are not found, make sure that a development environment exists. On most platforms, it is a separate product that must be purchased separately. Dynamically loading a DSO does not require compilers or development options.
If a host supports multiple programming models, such as IRIX with 32 and 64 bits, the options must agree with the version of mental ray. Use the Unix file command on mental ray and the shader library and make sure that they agree. If there is a mismatch, the run-time linker will print error messages like:
/my/shader.so: 1234:ray: rld: Fatal Error: cannot successfully map soname '/my/shader.so' under any of the filenames /my/shader.so
The run-time linker always tries to match executables and libraries, which allows multiple ABIs to reside on the same system without conflicts. If the filename of the DSO given as an absolute pathname mental ray only tries to load that particular file. If it is given as a relative path, mental ray searches the DSO in a list of paths that can be supplied via the command line parameter ( -ld_path) or the environment variable ( MI_LIBRARY_PATH). There is also a default search path ( /usr/local/mi/lib;.). A search list is a colon-separated (Unix) or semicolon-separated (Unix or Windows NT) list of paths to be searched. (Windows NT uses colons for drive letters.)
Note that source code ( .c extension) is normally portable, unless nonportable system features (such as fsqrt on SGIs) are used. This means that the shader will run on all other vendors' systems unchanged. If the compilation fails and the shaders therefore are undefined, mental ray will - when calls of the undefined shaders are attempted - return miFALSE, which will generally leave the pixel sample black.
Neither object files ( .o extension) nor DSOs ( .so extension) are portable. They must be compiled separately for each platform and, usually, for each major operating system release. For example, a Hewlett-Packard object file will not run on an SGI system, and an SGI IRIX 4.x object file cannot be used on an IRIX 6.x system, and vice versa. Also note that pointers are 32-bit values on some systems and 64-bit values on others, and that most but not all (IBM) processors require that 64-bit values such as doubles are stored at memory addresses evenly divisible by 8.
On SGI systems, a shader can be debugged after it has been called for the first time, which attaches it to the program and makes its symbols available to the debugger. For this to work, the -g option must be given to the cc and ld commands in all stages - compilation, linking, and shared-library building. Also, only DSO shaders are debuggable, not shaders loaded in object ( .o) or source ( .c) form.
On non-SGI systems, debugging shaders is, unfortunately, difficult. The reason is that most debuggers cannot deal with parts of a program that have been dynamically linked. In general, the debugger will refuse to set breakpoints in dynamically linked shaders, and will step over calls to these shaders as if they were a single operating system call. Some vendors are working on fixing these problems, but at this time the only option on non-SGI systems is using mi_info or mi_debug statements in the shader sources. Avoid printf because it is lost on slave hosts and because it can cause problems at runtime.
Windows NT shader libraries must use at least one shader interface call (any true C function beginning with mi_), or an error message "DLL_SetModuleHandle not found" will occur.
When a shared library is loaded that contains a function module_init, that function is called just after the library was loaded, before the first shader in it is called. Conversely, if it contains a function module_exit, that function is called just before the library is unloaded, after the last call to a shader in this library. Note that in the case of irrecoverable errors at any time after the library was loaded module_exit is not guaranteed to be called. Neither module_init nor module_exit may rely on any shader interface services that assume that a rendering operation is in progress. Message functions such as mi_info are available. Note that this feature is not supported on IBM systems and should not be used for portable shaders.
Note that if a C++ compiler is used to compile a shader, all names (shader, init, exit, version) need to be declared with extern "C". This is necessary because C++ compilers "mangle" symbols by tacking on type information, so mental ray cannot find the shader in the library. This will result in a "declaring nonexisting function" warning, and the shader will not be called.
[14] The -Bsymbolic
option is supported by RedHat and SuSE Linux 8.0 and later. It
makes it possible to use a different standard C++ library in the
shaders than in mental ray, even though both are part of the same
executable. This is important because mental ray uses a
lowest-common-denominator library that is likely to differ from the
default version used when compiling shaders.
home | << prev | next >> | contents |
Copyright © 1986-2007 by mental images GmbH