Make layer activation via CreateDevice struct or env variable

Also finish making all activated layers per icd and per gpu.
diff --git a/include/xgl.h b/include/xgl.h
index 64734e1..25812c9 100644
--- a/include/xgl.h
+++ b/include/xgl.h
@@ -871,6 +871,7 @@
 // IMG CHANGE BEGIN - support for vertex input description
     XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO    = 34,
 // IMG CHANGE END
+    XGL_STRUCTURE_TYPE_LAYER_CREATE_INFO                   = 35,
     XGL_MAX_ENUM(_XGL_STRUCTURE_TYPE)
 } XGL_STRUCTURE_TYPE;
 
@@ -1118,6 +1119,14 @@
     XGL_FLAGS                               flags;                      // XGL_DEVICE_CREATE_FLAGS
 } XGL_DEVICE_CREATE_INFO;
 
+typedef struct _XGL_LAYER_CREATE_INFO
+{
+    XGL_STRUCTURE_TYPE                      sType;                      // Should be XGL_STRUCTURE_TYPE_LAYER_CREATE_INFO
+    XGL_VOID*                               pNext;                      // Pointer to next structure
+    XGL_UINT                                layerCount;
+    const XGL_CHAR *const*                  ppActiveLayerNames;         // layer library name of form libXGLLayer<Name>.so
+} XGL_LAYER_CREATE_INFO;
+
 typedef struct _XGL_PHYSICAL_GPU_QUEUE_PROPERTIES
 {
     XGL_SIZE                                structSize;                 // Size of structure in bytes
diff --git a/layers/README.md b/layers/README.md
new file mode 100644
index 0000000..135c69e
--- /dev/null
+++ b/layers/README.md
@@ -0,0 +1,51 @@
+Layer Description and Status
+10/22/2014
+
+Overview:
+Layer libraries can be written to intercept or hook XGL entrypoints for various
+debug and validation purpose.  One or more XGL entrypoints can be defined in your Layer
+library.  Undefined entrypoints in the Layer library will be passed to the next Layer which
+may be the driver.  Multiple layer libraries can be chained (actually a hierarchy) together.
+xglEnumerateLayer can be called to list the available layer libraries.  xglGetProcAddr i
+used internally by the Layers and ICD Loader to initialize dispatch tables. Layers are
+activated at xglCreateDevice time. xglCreateDevice createInfo struct is extended to allow
+a list of layers to be activated.  Layer libraries can alternatively be LD_PRELOADed.
+
+Layer library example code:
+layer/basic_plugin.c  - simple example
+<build dir>/layer/generic_layer.c  - auto generated example wrapping all XGL entrypoints
+
+Using Layers::
+Build XGL loader  and i965 icd driver using normal steps (cmake and make)
+Place libXGLLayer<name>.so in the same directory as your XGL test or app:
+  cp build/layer/libXGLLayerBasic.so build/tests
+
+Specify which Layers to activate by using xglCreateDevice XGL_LAYER_CREATE_INFO struct or
+environment variable LIBXGL_LAYERS_LIB
+   export LIBXGL_LAYERS_LIB=libXGLLayerBasic.so
+   cd build/tests; ./xglinfo
+
+
+Status:
+Current Features:
+-scanning of available Layers during xglInitAndEnumerateGpus
+-xglEnumerateLayers and xglGetProcAddr supported APIs in xgl.h, ICD loader and i965 driver
+-multiple layers in a hierarchy supported
+-layer enumeration works
+-layers  activated per gpu and per icd driver: separate  dispatch table and layer library
+   list in loader for each gpu or icd driver
+-activation via xglCreateDevice extension struct in CreateInfo or via env var
+   (LIBXGL_LAYER_LIBS)
+-layer libraries can be LD_PRELOADed
+
+Current known issues:
+-memory leak of gpu wrapped objects
+-layer libraries don't support multiple dispatch tables for multi-gpus
+-layers  with extension APIs  not yet tested or supported
+-layer libraries not yet include loader init functionality for full  LD_PRELOAD of
+    entire API including xglInitAndEnumerate
+-no support for apps registering layers, must be discovered via initial scan
+-no support for Loader discovering from layer and driver which layers support which
+  gpus/drivers: any layer can be use any gpu right now
+-xglEnumerateLayers doesn't qualify Layers based on gpu, but enumerates all that were scanned
+
diff --git a/loader/loader.c b/loader/loader.c
index b7c8dfd..01205f1 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -25,7 +25,7 @@
  *   Chia-I Wu <olv@lunarg.com>
  *   Courtney Goeltzenleuchter <courtney@lunarg.com>
  */
-
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -42,13 +42,19 @@
 
 typedef XGL_VOID (* SetDispatchType)(XGL_LAYER_DISPATCH_TABLE * disp, XGL_BOOL debug);
 
+struct loader_layers {
+    void *lib_handle;
+    char lib_name[1024];
+};
+
 struct loader_icd {
     void *handle;
 
     XGL_LAYER_DISPATCH_TABLE *loader_dispatch;
-    bool layers_activated;
+    XGL_UINT layer_count[XGL_MAX_PHYSICAL_GPUS];
+    struct loader_layers layer_libs[XGL_MAX_PHYSICAL_GPUS][MAX_LAYER_LIBRARIES];
     XGL_UINT gpu_count;
-    XGL_BASE_LAYER_OBJECT *gpu;
+    XGL_BASE_LAYER_OBJECT *gpus;
 
     GetProcAddrType GetProcAddr;
     InitAndEnumerateGpusType InitAndEnumerateGpus;
@@ -60,10 +66,6 @@
     struct loader_icd *next;
 };
 
-struct loader_layers {
-    void *lib_handle;
-    char lib_name[1024];
-};
 
 struct loader_msg_callback {
     XGL_DBG_MSG_CALLBACK_FUNCTION func;
@@ -76,10 +78,10 @@
 static struct {
     bool scanned;
     struct loader_icd *icds;
-    XGL_UINT layer_count;
-    bool layer_scaned;
+    bool layer_scanned;
     char layer_dirs[4096];
-    struct loader_layers layer_libs[MAX_LAYER_LIBRARIES];
+    unsigned int scanned_layer_count;
+    char *scanned_layer_names[MAX_LAYER_LIBRARIES];
     struct loader_msg_callback *msg_callbacks;
 
     bool debug_echo_enable;
@@ -371,13 +373,14 @@
 #define DEFAULT_XGL_LAYERS_PATH ".:/usr/lib/i386-linux-gnu/xgl:/usr/lib/x86_64-linux-gnu/xgl"
 #endif
 
-static void layer_lib_scan(const char * libInPaths, const bool useDefaultDirs, const bool openLibs)
+static void layer_lib_scan(const char * libInPaths, const bool useDefaultDirs)
 {
     const char *p, *next;
     char *libPaths = &loader.layer_dirs[0];
     DIR *curdir;
     struct dirent *dent;
-    int len, i, n;
+    int len, i;
+    char temp_str[1024];
 
     if (libInPaths){
         strncpy(libPaths, libInPaths, sizeof(loader.layer_dirs));
@@ -387,12 +390,12 @@
     }
 
     /* cleanup any previously scanned libraries */
-    for (i = 0; i < loader.layer_count; i++) {
-        if (loader.layer_libs[i].lib_handle != NULL)
-            dlclose(loader.layer_libs[i].lib_handle);
-        loader.layer_libs[i].lib_handle = NULL;
+    for (i = 0; i < loader.scanned_layer_count; i++) {
+        if (loader.scanned_layer_names[i] != NULL)
+            free(loader.scanned_layer_names[i]);
+        loader.scanned_layer_names[i] = NULL;
     }
-    loader.layer_count = 0;
+    loader.scanned_layer_count = 0;
 
     if (useDefaultDirs)
        strncat(libPaths, DEFAULT_XGL_LAYERS_PATH, sizeof(loader.layer_dirs) - sizeof(DEFAULT_XGL_LAYERS_PATH));
@@ -413,16 +416,23 @@
        if (curdir) {
           dent = readdir(curdir);
           while (dent) {
-              n = loader.layer_count;
              /* look for wrappers starting with "libXGLlayer" */
              if (!strncmp(dent->d_name, "libXGLLayer", strlen("libXGLLayer"))) {
-                snprintf((char *) &(loader.layer_libs[n].lib_name), sizeof(loader.layer_libs[0].lib_name), "%s/%s",p,dent->d_name);
-                if ((loader.layer_libs[n].lib_handle = dlopen((const char *) &(loader.layer_libs[n].lib_name), RTLD_LAZY)) == NULL)
+                void * handle;
+                snprintf(temp_str, sizeof(temp_str), "%s/%s",p,dent->d_name);
+                if ((handle = dlopen((const char *) temp_str, RTLD_LAZY)) == NULL)
                     continue;
-
-                loader.layer_count++;
-                if (!openLibs)
-                    dlclose(loader.layer_libs[n].lib_handle);
+                if (loader.scanned_layer_count == MAX_LAYER_LIBRARIES) {
+                    loader_log(XGL_DBG_MSG_ERROR, 0, "%s ignored: max layer libraries exceed", temp_str);
+                    break;
+                }
+                if ((loader.scanned_layer_names[loader.scanned_layer_count] = malloc(strlen(temp_str) + 1)) == NULL) {
+                     loader_log(XGL_DBG_MSG_ERROR, 0, "%s ignored: out of memory", temp_str);
+                     break;
+                }
+                strcpy(loader.scanned_layer_names[loader.scanned_layer_count], temp_str);
+                loader.scanned_layer_count++;
+                dlclose(handle);
              }
 
              dent = readdir(curdir);
@@ -431,63 +441,7 @@
        }
     }
 
-    loader.layer_scaned = true;
-}
-
-#if 0
-static bool layer_lib_sort(char * str, const XGL_UINT count)
-{
-    XGL_UINT i;
-    struct loader_layers temp, *cur, *start;
-
-    start = &loader.layer_libs[count];
-    for (i = count; i < loader.layer_count; i++) {
-        cur = &loader.layer_libs[i];
-
-        if (!strcmp(str, cur->lib_name) && cur->lib_handle != NULL) {
-            if (count == i)
-                return true;
-            strcpy(temp.lib_name, cur->lib_name);
-            temp.lib_handle = cur->lib_handle;
-            strcpy(cur->lib_name, start->lib_name);
-            cur->lib_handle = start->lib_handle;
-            strcpy(start->lib_name, temp.lib_name);
-            start->lib_handle = temp.lib_handle;
-            return true;
-        }
-    }
-    return false;
-}
-#endif
-LOADER_EXPORT XGL_RESULT XGLAPI ScanForLayers(const XGL_CHAR* pLibraryDirectories, XGL_CHAR * pStr)
-{
-    size_t size = 0;
-    XGL_UINT i;
-    static XGL_CHAR *lib_str=NULL;
-
-    if (!pLibraryDirectories)
-        return XGL_ERROR_INVALID_POINTER;
-
-    if (strlen((const char *) pLibraryDirectories) > sizeof(loader.layer_dirs))
-        return XGL_ERROR_INVALID_POINTER;
-
-    layer_lib_scan((const char *) pLibraryDirectories, true, false);
-
-    for (i = 0; i < loader.layer_count; i++) {
-        size += strlen(loader.layer_libs[i].lib_name) + 1;
-    }
-
-    free(lib_str);
-    lib_str = malloc(size);
-    if (!lib_str)
-        return XGL_ERROR_OUT_OF_MEMORY;
-
-   pStr = lib_str;
-   for (i = 0; i < loader.layer_count; i++) {
-        strncat((char *) pStr, loader.layer_libs[i].lib_name, strlen(loader.layer_libs[i].lib_name));
-        strcat((char *) pStr, ":");
-    }
-    return XGL_SUCCESS;
+    loader.layer_scanned = true;
 }
 
 static void loader_init_dispatch_table(XGL_LAYER_DISPATCH_TABLE *tab, GetProcAddrType fpGPA, XGL_PHYSICAL_GPU gpu)
@@ -620,7 +574,7 @@
 {
     for (struct loader_icd * icd = loader.icds; icd; icd = icd->next) {
         for (XGL_UINT i = 0; i < icd->gpu_count; i++)
-            if ((icd->gpu + i) == gpu) {
+            if ((icd->gpus + i) == gpu || (icd->gpus +i)->baseObject == gpu->baseObject) {
                 *gpu_index = i;
                 return icd;
             }
@@ -628,84 +582,60 @@
     return NULL;
 }
 
-static void loader_deactivate_layer()
+static bool loader_layers_activated(const struct loader_icd *icd, const XGL_UINT gpu_index)
 {
-    struct loader_icd *icd;
-
-    for (icd = loader.icds; icd; icd = icd->next) {
-        //TODO clean up the wrapped gpu structs malloced during layer activation
-        if (icd->gpu)
-            free(icd->gpu);
-        icd->gpu = NULL;
-        icd->gpu_count = 0;
-        if (icd->loader_dispatch)
-            free(icd->loader_dispatch);
-        icd->loader_dispatch = NULL;
-        icd->SetDispatch(NULL, true);
-        icd->layers_activated = false;
-    }
+    if (icd->layer_count[gpu_index])
+        return true;
+    else
+        return false;
 }
 
-extern XGL_UINT ActivateLayers(XGL_PHYSICAL_GPU *gpu)
+static void loader_init_layer_libs(struct loader_icd *icd, XGL_UINT gpu_index, XGL_CHAR ** ppLayerNames, XGL_UINT count)
 {
-    XGL_UINT gpu_index;
-    struct loader_icd *icd = loader_get_icd((const XGL_BASE_LAYER_OBJECT *) *gpu, &gpu_index);
+    if (!icd)
+        return;
 
-    /* activate any layer libraries */
-    // TODO layer active list should be per icd/gpu rather than global
-    if (loader.layer_count > 0 && !icd->layers_activated) {
-
-        // TODO For now just assume  all layers scanned will be  activated in the order they were scanned
-        XGL_BASE_LAYER_OBJECT *gpuObj = (XGL_BASE_LAYER_OBJECT *) *gpu;
-        XGL_BASE_LAYER_OBJECT *nextGpuObj;
-        GetProcAddrType nextGPA = xglGetProcAddr;
-        for (XGL_INT i = loader.layer_count - 1; i >= 0; i--) {
-
-            if ((loader.layer_libs[i].lib_handle = dlopen((const char *) &(loader.layer_libs[i].lib_name), RTLD_LAZY | RTLD_DEEPBIND)) == NULL) {
-                loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to open layer library %s got error %d", loader.layer_libs[i].lib_name, dlerror());
+    struct loader_layers *obj;
+    bool foundLib;
+    for (XGL_UINT i = 0; i < count; i++) {
+        foundLib = false;
+        for (XGL_UINT j = 0; j < icd->layer_count[gpu_index]; j++) {
+            if (icd->layer_libs[gpu_index][j].lib_handle && !strcmp(icd->layer_libs[gpu_index][j].lib_name, (char *) ppLayerNames[i])) {
+                foundLib = true;
+                break;
+            }
+        }
+        if (!foundLib) {
+            obj = &(icd->layer_libs[gpu_index][i]);
+            strncpy(obj->lib_name, (char *) ppLayerNames[i], sizeof(obj->lib_name) - 1);
+            obj->lib_name[sizeof(obj->lib_name) - 1] = '\0';
+            if ((obj->lib_handle = dlopen(obj->lib_name, RTLD_LAZY | RTLD_DEEPBIND)) == NULL) {
+                loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to open layer library %s got error %d", obj->lib_name, dlerror());
                 continue;
             } else {
-                loader_log(XGL_DBG_MSG_UNKNOWN, 0, "Inserting layer lib %s",loader.layer_libs[i].lib_name);
+                loader_log(XGL_DBG_MSG_UNKNOWN, 0, "Inserting layer lib %s", obj->lib_name);
             }
 
-            //create newly wrapped gpu object
-            nextGpuObj = malloc(sizeof(XGL_BASE_LAYER_OBJECT));
-            if (! nextGpuObj)
-                loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to malloc Gpu object for layer");
-            nextGpuObj->pGPA = nextGPA;
-            nextGpuObj->baseObject = gpuObj->baseObject;
-            nextGpuObj->nextObject = gpuObj;
-            gpuObj = nextGpuObj;
-
-            nextGPA = dlsym(loader.layer_libs[i].lib_handle, "xglGetProcAddr");
-            if (!nextGPA) {
-                loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to find xglGetProcAddr in layer %s", loader.layer_libs[i].lib_name);
-                continue;
-            }
-
-            if (i == 0)
-                loader_init_dispatch_table(icd->loader_dispatch + gpu_index, nextGPA, gpuObj);
-
+            icd->layer_count[gpu_index]++;
         }
-        *gpu = ((XGL_PHYSICAL_GPU *) gpuObj);
-        icd->layers_activated = true;
     }
-    return loader.layer_count;
 }
 
-#if 0
-LOADER_EXPORT XGL_RESULT xglSetLayers(const XGL_CHAR * pStr)
+static XGL_UINT loader_get_layer_env(XGL_CHAR * *ppLayerNames)
 {
-    char *p, *next, *str;
-    int len;
-    XGL_UINT count= 0;
+    const char *layerEnv;
+    XGL_UINT len, count = 0;
+    char *p, *next, *name;
 
-    if (!pStr)
-        return XGL_ERROR_INVALID_POINTER;
+    layerEnv = getenv("LIBXGL_LAYER_LIBS");
+    p = malloc(strlen(layerEnv) + 1);
+    if (!p)
+        return 0;
+    strcpy(p, layerEnv);
 
-    p= (char *) pStr;
-    str = malloc(strlen(p) + 1);
-    do {
+    while (p && *p && count < MAX_LAYER_LIBRARIES) {
+        bool foundScanned = false;
+        unsigned int j;
         next = strchr(p, ':');
         if (next == NULL) {
             len = strlen(p);
@@ -716,26 +646,163 @@
             *(char *) next = '\0';
             next++;
         }
+        name = basename(p);
+        for (j = 0; j < loader.scanned_layer_count; j++) {
+            if (!strcmp(basename(loader.scanned_layer_names[j]), name)) {
+                foundScanned = true;
+                break;
+            }
+        }
+        if (!foundScanned) {
+            p = next;
+            continue;
+        }
 
-        strncpy(str, p, len);
-        str[len] = '\0';
-        if (layer_lib_sort(str, count))
-           count++;
+        //copy to convert any dir path differences between scanned and base names
+        len = strlen(loader.scanned_layer_names[j]);
+        ppLayerNames[count] = malloc(len + 1);
+        if (!ppLayerNames[count])
+            return count;
+        strncpy((char *) ppLayerNames[count], loader.scanned_layer_names[j], len);
+        ppLayerNames[count][len] = '\0';
+        count++;
         p = next;
 
-    } while (*p  && count < MAX_LAYER_LIBRARIES-1);
+    };
 
-    for (int i = count; i < loader.layer_count; i++) {
-        loader.layer_libs[i].lib_handle = NULL;
-    }
-
-    loader.layer_count = count;
-    free(str);
-
-    return XGL_SUCCESS;
+    return count;
 }
 
-#endif
+static XGL_UINT loader_get_layer_libs(const XGL_DEVICE_CREATE_INFO* pCreateInfo, XGL_CHAR *** ppLayerNames)
+{
+    static XGL_CHAR *layerNames[MAX_LAYER_LIBRARIES];
+
+    *ppLayerNames =  &layerNames[0];
+    if (!pCreateInfo) {
+        return loader_get_layer_env(layerNames);
+    }
+
+    XGL_LAYER_CREATE_INFO *pCi = (XGL_LAYER_CREATE_INFO *) pCreateInfo->pNext;
+
+    while (pCi) {
+        if (pCi->sType == XGL_STRUCTURE_TYPE_LAYER_CREATE_INFO) {
+            const char *name;
+            XGL_UINT len;
+            unsigned int j;
+            for (XGL_UINT i = 0; i < pCi->layerCount; i++) {
+                bool foundScanned = false;
+                name = (const char *) *(pCi->ppActiveLayerNames + i);
+                for (j = 0; j < loader.scanned_layer_count; j++) {
+                    if (!strcmp(basename(loader.scanned_layer_names[j]), basename(name))) {
+                        foundScanned = true;
+                        break;
+                    }
+                }
+                if (!foundScanned)
+                    return loader_get_layer_env(layerNames);
+                //copy to convert any dir path differences between scanned and base names
+                len = strlen(loader.scanned_layer_names[j]);
+                layerNames[i] = malloc(len + 1);
+                if (!layerNames[i])
+                    return i;
+                strncpy((char *) layerNames[i], loader.scanned_layer_names[j], len);
+                layerNames[i][len] = '\0';
+            }
+            return pCi->layerCount;
+        }
+        pCi = pCi->pNext;
+    }
+    return loader_get_layer_env(layerNames);
+}
+
+static void loader_deactivate_layer()
+{
+    struct loader_icd *icd;
+    struct loader_layers *libs;
+
+    for (icd = loader.icds; icd; icd = icd->next) {
+        //TODO clean up the wrapped gpu structs malloced during layer activation
+        if (icd->gpus)
+            free(icd->gpus);
+        icd->gpus = NULL;
+        if (icd->loader_dispatch)
+            free(icd->loader_dispatch);
+        icd->loader_dispatch = NULL;
+        icd->SetDispatch(NULL, true);
+        for (XGL_UINT j = 0; j < icd->gpu_count; j++) {
+            if (icd->layer_count[j] > 0) {
+                for (XGL_UINT i = 0; i < icd->layer_count[j]; i++) {
+                    libs = &(icd->layer_libs[j][i]);
+                    if (libs->lib_handle)
+                        dlclose(libs->lib_handle);
+                    libs->lib_handle = NULL;
+                }
+            }
+            icd->layer_count[j] = 0;
+        }
+        icd->gpu_count = 0;
+    }
+}
+
+extern XGL_UINT ActivateLayers(XGL_PHYSICAL_GPU *gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo)
+{
+    XGL_UINT gpu_index;
+    XGL_UINT count;
+    XGL_CHAR ** ppLayerNames;
+    struct loader_icd *icd = loader_get_icd((const XGL_BASE_LAYER_OBJECT *) *gpu, &gpu_index);
+
+    if (!icd)
+        return 0;
+    assert(gpu_index < XGL_MAX_PHYSICAL_GPUS);
+
+    /* activate any layer libraries */
+    if (!loader_layers_activated(icd, gpu_index)) {
+        XGL_BASE_LAYER_OBJECT *gpuObj = (XGL_BASE_LAYER_OBJECT *) *gpu;
+        XGL_BASE_LAYER_OBJECT *nextGpuObj;
+        GetProcAddrType nextGPA = xglGetProcAddr;
+
+        count = loader_get_layer_libs(pCreateInfo, &ppLayerNames);
+        if (!count)
+            return 0;
+        loader_init_layer_libs(icd, gpu_index, ppLayerNames, count);
+
+        for (XGL_INT i = icd->layer_count[gpu_index] - 1; i >= 0; i--) {
+            //create newly wrapped gpu object
+            nextGpuObj = malloc(sizeof(XGL_BASE_LAYER_OBJECT));
+            if (! nextGpuObj)
+                loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to malloc Gpu object for layer");
+            nextGpuObj->pGPA = nextGPA;
+            nextGpuObj->baseObject = gpuObj->baseObject;
+            nextGpuObj->nextObject = gpuObj;
+            gpuObj = nextGpuObj;
+
+            nextGPA = dlsym(icd->layer_libs[gpu_index][i].lib_handle, "xglGetProcAddr");
+            if (!nextGPA) {
+                loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to find xglGetProcAddr in layer %s", icd->layer_libs[gpu_index][i].lib_name);
+                continue;
+            }
+
+            if (i == 0)
+                loader_init_dispatch_table(icd->loader_dispatch + gpu_index, nextGPA, gpuObj);
+
+        }
+        *gpu = ((XGL_PHYSICAL_GPU *) gpuObj);
+    }
+    else {
+        //make sure requested Layers matches currently activated Layers
+        count = loader_get_layer_libs(pCreateInfo, &ppLayerNames);
+        for (XGL_UINT i = 0; i < count; i++) {
+            if (strcmp(icd->layer_libs[gpu_index][i].lib_name, (char *) *(ppLayerNames + i))) {
+                loader_log(XGL_DBG_MSG_ERROR, 0, "Layers activated != Layers requested");
+                break;
+            }
+        }
+        if (count != icd->layer_count[gpu_index]) {
+            loader_log(XGL_DBG_MSG_ERROR, 0, "Number of Layers activated!= number requested");
+        }
+    }
+    return icd->layer_count[gpu_index];
+}
 
 LOADER_EXPORT XGL_VOID * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const XGL_CHAR * pName) {
 
@@ -1024,7 +1091,7 @@
         res = icd->InitAndEnumerateGpus(pAppInfo, pAllocCb, max, &n, gpus);
         if (res == XGL_SUCCESS && n) {
             wrappedGpus = (XGL_BASE_LAYER_OBJECT*) malloc(n * sizeof(XGL_BASE_LAYER_OBJECT));
-            icd->gpu = wrappedGpus;
+            icd->gpus = wrappedGpus;
             icd->gpu_count = n;
             icd->loader_dispatch = (XGL_LAYER_DISPATCH_TABLE *) malloc(n * sizeof(XGL_LAYER_DISPATCH_TABLE));
             for (int i = 0; i < n; i++) {
@@ -1049,8 +1116,8 @@
     }
 
     /* get layer libraries */
-    if (!loader.layer_scaned)
-        layer_lib_scan(NULL, true, false);
+    if (!loader.layer_scanned)
+        layer_lib_scan(NULL, true);
 
     *pGpuCount = count;
 
@@ -1059,20 +1126,20 @@
 
 LOADER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, XGL_SIZE maxLayerCount, XGL_SIZE maxStringSize, XGL_CHAR* const* pOutLayers, XGL_SIZE* pOutLayerCount)
 {
-    XGL_SIZE count = loader.layer_count;
+    XGL_SIZE count = loader.scanned_layer_count;
     // TODO handle layers per GPU, multiple icds
 
     if (pOutLayerCount == NULL)
         return XGL_ERROR_INVALID_POINTER;
 
-    if (maxLayerCount < loader.layer_count)
+    if (maxLayerCount < loader.scanned_layer_count)
         count = maxLayerCount;
     *pOutLayerCount = count;
 
     if (pOutLayers == NULL)
         return XGL_SUCCESS;
     for (XGL_SIZE i = 0; i < count; i++) {
-        strncpy((char *) (pOutLayers[i]), loader.layer_libs[i].lib_name, maxStringSize);
+        strncpy((char *) (pOutLayers[i]), loader.scanned_layer_names[i], maxStringSize);
         if (maxStringSize > 0)
             pOutLayers[i][maxStringSize - 1] = '\0';
     }
diff --git a/loader/loader.h b/loader/loader.h
index d819142..47802d4 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -40,6 +40,6 @@
 #  define LOADER_EXPORT
 #endif
 
-extern XGL_UINT ActivateLayers(XGL_PHYSICAL_GPU *gpu);
-#define MAX_LAYER_LIBRARIES 16
+extern XGL_UINT ActivateLayers(XGL_PHYSICAL_GPU *gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo);
+#define MAX_LAYER_LIBRARIES 64
 #endif /* LOADER_H */
diff --git a/xgl-generate.py b/xgl-generate.py
index 2f155d8..2551bbf 100755
--- a/xgl-generate.py
+++ b/xgl-generate.py
@@ -124,13 +124,13 @@
                 if proto.name == "CreateDevice" and qual == "LOADER_EXPORT ":
                     funcs.append("%s%s\n"
                              "{\n"
-                             "    ActivateLayers(&%s);\n"
+                             "    ActivateLayers(&%s, %s);\n"
                              "    XGL_BASE_LAYER_OBJECT* wrapped_obj = (XGL_BASE_LAYER_OBJECT*)%s;\n"
                              "    const XGL_LAYER_DISPATCH_TABLE * const *disp =\n"
                              "            (const XGL_LAYER_DISPATCH_TABLE * const *) wrapped_obj->baseObject;\n"
                              "    %s = wrapped_obj->nextObject;\n"
                              "    %s;\n"
-                             "}" % (qual, decl, proto.params[0].name, proto.params[0].name, proto.params[0].name, stmt))
+                             "}" % (qual, decl, proto.params[0].name, proto.params[1].name, proto.params[0].name, proto.params[0].name, stmt))
                 elif proto.params[0].ty != "XGL_PHYSICAL_GPU":
                     funcs.append("%s%s\n"
                              "{\n"