Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 1 | # Layer Description and Status |
Jon Ashburn | 183dfd0 | 2014-10-22 18:13:16 -0600 | [diff] [blame] | 2 | |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 3 | ## Overview |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 4 | |
Jon Ashburn | 183dfd0 | 2014-10-22 18:13:16 -0600 | [diff] [blame] | 5 | Layer libraries can be written to intercept or hook XGL entrypoints for various |
Courtney Goeltzenleuchter | 6be96bb | 2014-11-02 18:50:52 -0700 | [diff] [blame] | 6 | debug and validation purposes. One or more XGL entrypoints can be defined in your Layer |
Jon Ashburn | 183dfd0 | 2014-10-22 18:13:16 -0600 | [diff] [blame] | 7 | library. Undefined entrypoints in the Layer library will be passed to the next Layer which |
| 8 | may be the driver. Multiple layer libraries can be chained (actually a hierarchy) together. |
Tobin Ehlis | 475bebe | 2014-10-23 08:44:44 -0600 | [diff] [blame] | 9 | xglEnumerateLayer can be called to list the available layer libraries. xglGetProcAddr is |
Jon Ashburn | 183dfd0 | 2014-10-22 18:13:16 -0600 | [diff] [blame] | 10 | used internally by the Layers and ICD Loader to initialize dispatch tables. Layers are |
| 11 | activated at xglCreateDevice time. xglCreateDevice createInfo struct is extended to allow |
Jon Ashburn | de3630c | 2014-12-18 17:26:52 -0700 | [diff] [blame] | 12 | a list of layers to be activated. Layer libraries can alternatively be LD\_PRELOADed depending |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 13 | upon how they are implemented. |
Jon Ashburn | 183dfd0 | 2014-10-22 18:13:16 -0600 | [diff] [blame] | 14 | |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 15 | ##Layer library example code |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 16 | |
Jon Ashburn | de3630c | 2014-12-18 17:26:52 -0700 | [diff] [blame] | 17 | Note that some layers are code-generated and will therefore exist in the directory (build_dir)/layers |
| 18 | |
| 19 | -include/xglLayer.h - header file for layer code. |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 20 | |
| 21 | ### Templates |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 22 | layer/Basic.cpp (name=Basic) simple example wrapping a few entrypoints. Shows layer features: |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 23 | - Multiple dispatch tables for supporting multiple GPUs. |
| 24 | - Example layer extension function shown. |
| 25 | - Layer extension advertised by xglGetExtension(). |
| 26 | - xglEnumerateLayers() supports loader layer name queries and call interception |
Jon Ashburn | de3630c | 2014-12-18 17:26:52 -0700 | [diff] [blame] | 27 | - Can be LD\_PRELOADed individually |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 28 | |
| 29 | layer/Multi.cpp (name=multi1:multi2) simple example showing multiple layers per library |
| 30 | |
Jon Ashburn | de3630c | 2014-12-18 17:26:52 -0700 | [diff] [blame] | 31 | (build dir)/layer/generic_layer.c (name=Generic) - auto generated example wrapping all XGL entrypoints. Single global dispatch table. Can be LD\_PRELOADed. |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 32 | |
| 33 | ### Print API Calls and Parameter Values |
Tobin Ehlis | 7302c35 | 2015-02-05 11:51:35 -0700 | [diff] [blame^] | 34 | (build dir)/layer/api_dump.c (name=APIDump) - print out API calls along with parameter values |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 35 | |
Tobin Ehlis | 7302c35 | 2015-02-05 11:51:35 -0700 | [diff] [blame^] | 36 | (build dir)/layer/api_dump.cpp (name=APIDumpCpp) - same as above but uses c++ strings and i/o streams |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 37 | |
Tobin Ehlis | 7302c35 | 2015-02-05 11:51:35 -0700 | [diff] [blame^] | 38 | (build dir)/layer/api\_dump\_file.c (name=APIDumpFile) - Write API calls along with parameter values to xgl\_apidump.txt file. |
| 39 | |
| 40 | (build dir)/layer/api\_dump\_no\_addr.c (name=APIDumpNoAddr) - print out API calls along with parameter values but replace any variable addresses with the static string "addr". |
| 41 | |
| 42 | (build dir)/layer/api\_dump\_no\_addr.cpp (name=APIDumpNoAddrCpp) - same as above but uses c++ strings and i/o streams |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 43 | |
| 44 | ### Print Object Stats |
Tobin Ehlis | 7302c35 | 2015-02-05 11:51:35 -0700 | [diff] [blame^] | 45 | (build dir>/layer/object_track.c (name=ObjectTracker) - Print object CREATE/USE/DESTROY stats. Individually track objects by category. XGL\_OBJECT\_TYPE enum defined in object_track.h. If a Dbg callback function is registered, this layer will use callback function(s) for reporting, otherwise uses stdout. Provides custom interface to query number of live objects of given type "XGL\_UINT64 objTrackGetObjectCount(XGL\_OBJECT\_TYPE type)" and a secondary call to return an array of those objects "XGL\_RESULT objTrackGetObjects(XGL\_OBJECT\_TYPE type, XGL\_UINT64 objCount, OBJTRACK\_NODE* pObjNodeArray)". |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 46 | |
| 47 | ### Report Draw State |
Tobin Ehlis | 7302c35 | 2015-02-05 11:51:35 -0700 | [diff] [blame^] | 48 | layer/draw\_state.c (name=DrawState) - NOTE: This layer is currently non-functional due to a number of changes in xgl.h. When updated, it will report the Descriptor Set, Pipeline State, and dynamic state at each Draw call. If a Dbg callback function is registered, this layer will use callback function(s) for reporting, otherwise uses stdout. |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 49 | |
| 50 | ### Track GPU Memory |
Tobin Ehlis | 7302c35 | 2015-02-05 11:51:35 -0700 | [diff] [blame^] | 51 | layer/mem\_tracker.c (name=MemTracker) - NOTE: This layer is currently non-functional due to a number of changes in xgl.h. When updated, it will track GPU Memory and any binding it has to objects and/or Cmd Buffers. Report issues with freeing memory, memory dependencies on Cmd Buffers, and any memory leaks at DestroyDevice time. If a Dbg callback function is registered, this layer will use callback function(s) for reporting, otherwise uses stdout. |
Jon Ashburn | 183dfd0 | 2014-10-22 18:13:16 -0600 | [diff] [blame] | 52 | |
Tobin Ehlis | 27c2d82 | 2014-12-18 10:32:57 -0700 | [diff] [blame] | 53 | ### Check parameters |
| 54 | <build dir>/layer/param_checker.c (name=ParamChecker) - Check the input parameters to API calls for validity. Currently this only checks ENUM params directly passed to API calls and ENUMs embedded in struct params. If a Dbg callback function is registered, this layer will use callback function(s) for reporting, otherwise uses stdout. |
| 55 | |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 56 | ## Using Layers |
| 57 | |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 58 | 1. Build XGL loader and i965 icd driver using normal steps (cmake and make) |
| 59 | 2. Place libXGLLayer<name>.so in the same directory as your XGL test or app: |
| 60 | |
| 61 | cp build/layer/libXGLLayerBasic.so build/layer/libXGLLayerGeneric.so build/tests |
Jon Ashburn | de3630c | 2014-12-18 17:26:52 -0700 | [diff] [blame] | 62 | |
| 63 | This is required for the Icd loader to be able to scan and enumerate your library. Alternatively, use the LIBXGL\_LAYERS\_PATH environment variable to specify where the layer libraries reside. |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 64 | |
| 65 | 3. Specify which Layers to activate by using |
Jon Ashburn | de3630c | 2014-12-18 17:26:52 -0700 | [diff] [blame] | 66 | xglCreateDevice XGL\_LAYER\_CREATE\_INFO struct or environment variable LIBXGL\_LAYER\_NAMES |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 67 | |
Tobin Ehlis | 7302c35 | 2015-02-05 11:51:35 -0700 | [diff] [blame^] | 68 | export LIBXGL\_LAYER\_NAMES=Basic:Generic |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 69 | cd build/tests; ./xglinfo |
Jon Ashburn | 183dfd0 | 2014-10-22 18:13:16 -0600 | [diff] [blame] | 70 | |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 71 | ## Tips for writing new layers |
Jon Ashburn | 183dfd0 | 2014-10-22 18:13:16 -0600 | [diff] [blame] | 72 | |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 73 | 1. Must implement xglGetProcAddr() (aka GPA); |
| 74 | 2. Must have a local dispatch table to call next layer (see xglLayer.h); |
| 75 | 3. Should implement xglEnumerateLayers() returning layer name when gpu == NULL; otherwise layer name is extracted from library filename by the Loader; |
| 76 | 4. gpu objects must be unwrapped (gpu->nextObject) when passed to next layer; |
| 77 | 5. next layers GPA can be found in the wrapped gpu object; |
| 78 | 6. Loader calls a layer's GPA first so initialization should occur here; |
| 79 | 7. all entrypoints can be wrapped but only will be called after layer is activated |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 80 | via the first xglCreatDevice; |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 81 | 8. entrypoint names can be any name as specified by the layers xglGetProcAddr |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 82 | implementation; exceptions are xglGetProcAddr and xglEnumerateLayers, |
| 83 | which must have the correct name since the Loader calls these entrypoints; |
Jon Ashburn | de3630c | 2014-12-18 17:26:52 -0700 | [diff] [blame] | 84 | 9. entrypoint names must be exported to the dynamic loader with XGL\_LAYER\_EXPORT; |
| 85 | 10. For LD\_PRELOAD support: a)entrypoint names should be offical xgl names and |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 86 | b) initialization should occur on any call with a gpu object (Loader type |
| 87 | initialization must be done if implementing xglInitAndEnumerateGpus). |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 88 | 11. Implement xglGetExtension() if you want to advertise a layer extension |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 89 | (only available after the layer is activated); |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 90 | 12. Layer naming convention is camel case same name as in library: libXGLLayer<name>.so |
| 91 | 13. For multiple layers in one library should implement a separate GetProcAddr for each |
Jon Ashburn | 8d8dad0 | 2014-12-01 14:22:40 -0700 | [diff] [blame] | 92 | layer and export them to dynamic loader; function name is <layerName>GetProcAddr(). |
| 93 | Main xglGetProcAddr() should also be implemented. |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 94 | |
| 95 | ## Status |
| 96 | |
| 97 | ### Current Features |
| 98 | |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 99 | - scanning of available Layers during xglInitAndEnumerateGpus; |
| 100 | - layer names retrieved via xglEnumerateLayers(); |
| 101 | - xglEnumerateLayers and xglGetProcAddr supported APIs in xgl.h, ICD loader and i965 driver; |
| 102 | - multiple layers in a hierarchy supported; |
| 103 | - layer enumeration supported per GPU; |
| 104 | - layers activated per gpu and per icd driver: separate dispatch table and layer library list in loader for each gpu or icd driver; |
Jon Ashburn | de3630c | 2014-12-18 17:26:52 -0700 | [diff] [blame] | 105 | - activation via xglCreateDevice extension struct in CreateInfo or via env var (LIBXGL\_LAYER\_NAMES); |
| 106 | - layer libraries can be LD\_PRELOADed if implemented correctly; |
Jon Ashburn | 183dfd0 | 2014-10-22 18:13:16 -0600 | [diff] [blame] | 107 | |
Jon Ashburn | 9d290e4 | 2014-11-26 13:27:04 -0700 | [diff] [blame] | 108 | ### Current known issues |
| 109 | |
Tobin Ehlis | 7302c35 | 2015-02-05 11:51:35 -0700 | [diff] [blame^] | 110 | - DrawState and MemTracker layers are both non-functional due to updates to xgl.h. Work is ongoing to bring these layers up to latest header. |
| 111 | - Layers with multiple threads are not well tested and some layers likely to have issues. APIDump family of layers should be thread-safe. |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 112 | - layer libraries (except Basic) don't support multiple dispatch tables for multi-gpus; |
Jon Ashburn | de3630c | 2014-12-18 17:26:52 -0700 | [diff] [blame] | 113 | - layer libraries not yet include loader init functionality for full LD\_PRELOAD of entire API including xglInitAndEnumerateGpus; |
Jens Owen | 8b5ed54 | 2014-12-18 14:36:31 -0700 | [diff] [blame] | 114 | - Since Layers aren't activated until xglCreateDevice, any calls to xglGetExtension() will not report layer extensions unless implemented in the layer; |
| 115 | - layer extensions do NOT need to be enabled in xglCreateDevice to be available; |
| 116 | - no support for apps registering layers, must be discovered via initial scan |
Jon Ashburn | 183dfd0 | 2014-10-22 18:13:16 -0600 | [diff] [blame] | 117 | |