Jon Ashburn | 8c51936 | 2015-01-06 10:33:36 -0700 | [diff] [blame] | 1 | # Loader Description |
| 2 | |
| 3 | ## Overview |
Ian Elliott | eff61a0 | 2015-02-13 11:23:05 -0700 | [diff] [blame^] | 4 | The Loader implements the main XGL library (e.g. "XGL.dll" on Windows and |
| 5 | "libXGL.so" on Linux). It handles layer management and driver management. The |
| 6 | loader fully supports multi-gpu operation. As part of this, it dispatches API |
| 7 | calls to the correct driver, and to the correct layers, based on the GPU object |
| 8 | selected by the application. |
Jon Ashburn | 8c51936 | 2015-01-06 10:33:36 -0700 | [diff] [blame] | 9 | |
Ian Elliott | eff61a0 | 2015-02-13 11:23:05 -0700 | [diff] [blame^] | 10 | The loader's driver management includes finding driver libraries and loading |
| 11 | them. When a driver is initialized, the loader sets up its dispatch tables, |
| 12 | using a very light-weight "trampoline" mechanism. To do so, it reserves space |
| 13 | for a pointer in API objects (see below for more information about this). |
| 14 | |
| 15 | The loader's layer management includes finding layer libraries and activating |
| 16 | them as requested. The loader correctly sets up each activated layer, and its |
| 17 | own dispatch tables in order to support all activated layers. Each active |
| 18 | layer can intercept a subset of the full API entrypoints. A layer which |
| 19 | doesn't intercept a given entrypoint will be skipped for that entrypoint. The |
| 20 | loader supports layers that operate on multiple GPUs. |
Jon Ashburn | 8c51936 | 2015-01-06 10:33:36 -0700 | [diff] [blame] | 21 | |
| 22 | ## Environment Variables |
Ian Elliott | eff61a0 | 2015-02-13 11:23:05 -0700 | [diff] [blame^] | 23 | **LIBXGL\_DRIVERS\_PATH** directory for loader to search for ICD driver libraries to open |
Courtney Goeltzenleuchter | c507e3d | 2015-01-07 09:24:45 -0700 | [diff] [blame] | 24 | |
Ian Elliott | eff61a0 | 2015-02-13 11:23:05 -0700 | [diff] [blame^] | 25 | **LIBXGL\_LAYERS\_PATH** directory for loader to search for layer libraries that may get activated and used at xglCreateDevice() time. |
Courtney Goeltzenleuchter | c507e3d | 2015-01-07 09:24:45 -0700 | [diff] [blame] | 26 | |
Ian Elliott | eff61a0 | 2015-02-13 11:23:05 -0700 | [diff] [blame^] | 27 | **LIBXGL\_LAYER\_NAMES** colon-separated list of layer names to be activated (e.g., LIBXGL\_LAYER\_NAMES=MemTracker:DrawState). |
| 28 | |
| 29 | Note: Both of the LIBXGL\_*\_PATH variables may contain more than one directory. Each directory must be separated by one of the following characters, depending on your OS: |
| 30 | |
| 31 | - ";" on Windows |
| 32 | - ":" on Linux |
Jon Ashburn | 8c51936 | 2015-01-06 10:33:36 -0700 | [diff] [blame] | 33 | |
| 34 | ## Interface to driver (ICD) |
Jon Ashburn | 117a0d4 | 2015-02-11 12:40:00 -0700 | [diff] [blame] | 35 | - xglEnumerateGpus exported |
| 36 | - xglCreateInstance exported |
| 37 | - xglDestroyInstance exported |
Jon Ashburn | 8c51936 | 2015-01-06 10:33:36 -0700 | [diff] [blame] | 38 | - xglGetProcAddr exported and returns valid function pointers for all the XGL API entrypoints |
Courtney Goeltzenleuchter | ba7133b | 2015-02-10 18:40:14 -0700 | [diff] [blame] | 39 | - all objects created by ICD can be cast to (XGL\_LAYER\_DISPATCH\_TABLE \*\*) |
Jon Ashburn | 8c51936 | 2015-01-06 10:33:36 -0700 | [diff] [blame] | 40 | where the loader will replace the first entry with a pointer to the dispatch table which is |
Courtney Goeltzenleuchter | ba7133b | 2015-02-10 18:40:14 -0700 | [diff] [blame] | 41 | owned by the loader. This implies three things for ICD drivers: |
Ian Elliott | eff61a0 | 2015-02-13 11:23:05 -0700 | [diff] [blame^] | 42 | 1. The ICD must return a pointer for the opaque object handle |
| 43 | 2. This pointer points to a regular C structure with the first entry being a pointer. |
Jon Ashburn | 117a0d4 | 2015-02-11 12:40:00 -0700 | [diff] [blame] | 44 | Note: for any C++ ICD's that implement XGL objects directly as C++ classes. |
Ian Elliott | eff61a0 | 2015-02-13 11:23:05 -0700 | [diff] [blame^] | 45 | The C++ compiler may put a vtable at offset zero, if your class is virtual. |
| 46 | In this case use a regular C structure (see below). |
| 47 | 3. The reservedForLoader.loaderMagic member must be initialized with ICD\_LOADER\_MAGIC, as follows: |
| 48 | |
Jon Ashburn | 117a0d4 | 2015-02-11 12:40:00 -0700 | [diff] [blame] | 49 | ``` |
Courtney Goeltzenleuchter | ba7133b | 2015-02-10 18:40:14 -0700 | [diff] [blame] | 50 | #include "xglIcd.h" |
Ian Elliott | eff61a0 | 2015-02-13 11:23:05 -0700 | [diff] [blame^] | 51 | |
Jon Ashburn | 117a0d4 | 2015-02-11 12:40:00 -0700 | [diff] [blame] | 52 | struct { |
Ian Elliott | eff61a0 | 2015-02-13 11:23:05 -0700 | [diff] [blame^] | 53 | XGL_LOADER_DATA *reservedForLoader; // Reserve space for pointer to loader's dispatch table |
| 54 | myObjectClass myObj; // Your driver's C++ class |
Jon Ashburn | 117a0d4 | 2015-02-11 12:40:00 -0700 | [diff] [blame] | 55 | } xglObj; |
Ian Elliott | eff61a0 | 2015-02-13 11:23:05 -0700 | [diff] [blame^] | 56 | |
| 57 | xglObj alloc_icd_obj() |
| 58 | { |
| 59 | xglObj *newObj = alloc_obj(); |
| 60 | ... |
| 61 | // Initialize pointer to loader's dispatch table with ICD_LOADER_MAGIC |
| 62 | set_loader_magic_value(newObj); |
| 63 | ... |
| 64 | return newObj; |
| 65 | } |
Jon Ashburn | 117a0d4 | 2015-02-11 12:40:00 -0700 | [diff] [blame] | 66 | ``` |
Ian Elliott | eff61a0 | 2015-02-13 11:23:05 -0700 | [diff] [blame^] | 67 | |
| 68 | Additional Notes: |
| 69 | |
| 70 | - The ICD may or may not implement a dispatch table. |
| 71 | - ICD entrypoints can be named anything including the offcial xgl name such as xglCreateDevice(). However, beware of interposing by dynamic OS library loaders if the offical names are used. On Linux, if offical names are used, the ICD library must be linked with -Bsymbolic. |
Courtney Goeltzenleuchter | c507e3d | 2015-01-07 09:24:45 -0700 | [diff] [blame] | 72 | |