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 | a75af3d | 2015-04-06 09:24:42 -0600 | [diff] [blame^] | 48 | layer/draw\_state.c (name=DrawState) - DrawState reports the Descriptor Set, Pipeline State, and dynamic state at each Draw call. DrawState layer performs a number of validation checks on this state. Of primary interest is making sure that the resources bound to Descriptor Sets correctly align with the layout specified for the Set. 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 | a75af3d | 2015-04-06 09:24:42 -0600 | [diff] [blame^] | 51 | layer/mem\_tracker.c (name=MemTracker) - MemTracker functions mostly as a validation layer, attempting to ensure that memory objects are managed correctly by the application. These memory objects are bound to pipelines, objects, and command buffers, and then submitted to the GPU for work. As an example, the layer validates that the correct memory objects have been bound, and that they are specified correctly when the command buffers are submitted. Also, that only existing memory objects are referenced, and that any destroyed memory objects are not referenced. Another type of validation done is that before any memory objects are reused or destroyed, the layer ensures that the application has confirmed that they are no longer in use, and that they have been properly unbound before destruction. 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 | - 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] | 111 | - 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] | 112 | - 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] | 113 | - Since Layers aren't activated until xglCreateDevice, any calls to xglGetExtension() will not report layer extensions unless implemented in the layer; |
| 114 | - layer extensions do NOT need to be enabled in xglCreateDevice to be available; |
| 115 | - no support for apps registering layers, must be discovered via initial scan |
Jon Ashburn | 183dfd0 | 2014-10-22 18:13:16 -0600 | [diff] [blame] | 116 | |