instance: Added initial {Create|Destroy}Instance() and xglEnumerateGpus().

For now, retain the existing InitAndEnumerateGpus and have it create one
instance. New APIs aren't fully implemented yet in driver or loader.
diff --git a/include/xgl.h b/include/xgl.h
index 1c1bf31..4d4a8c5 100644
--- a/include/xgl.h
+++ b/include/xgl.h
@@ -54,6 +54,7 @@
     #define XGL_DEFINE_SUBCLASS_HANDLE(_obj, _base) typedef void* _obj;
 #endif // __cplusplus
 
+XGL_DEFINE_HANDLE(XGL_INSTANCE)
 XGL_DEFINE_HANDLE(XGL_PHYSICAL_GPU)
 XGL_DEFINE_HANDLE(XGL_BASE_OBJECT)
 XGL_DEFINE_SUBCLASS_HANDLE(XGL_DEVICE, XGL_BASE_OBJECT)
@@ -2241,6 +2242,9 @@
 // ------------------------------------------------------------------------------------------------
 // API functions
 typedef XGL_RESULT (XGLAPI *xglInitAndEnumerateGpusType)(const XGL_APPLICATION_INFO* pAppInfo, const XGL_ALLOC_CALLBACKS* pAllocCb, uint32_t maxGpus, uint32_t* pGpuCount, XGL_PHYSICAL_GPU* pGpus);
+typedef XGL_RESULT (XGLAPI *xglCreateInstanceType)(const XGL_APPLICATION_INFO* pAppInfo, const XGL_ALLOC_CALLBACKS* pAllocCb, XGL_INSTANCE* pInstance);
+typedef XGL_RESULT (XGLAPI *xglDestroyInstanceType)(XGL_INSTANCE instance);
+typedef XGL_RESULT (XGLAPI *xglEnumerateGpusType)(XGL_INSTANCE instance, uint32_t maxGpus, uint32_t* pGpuCount, XGL_PHYSICAL_GPU* pGpus);
 typedef XGL_RESULT (XGLAPI *xglGetGpuInfoType)(XGL_PHYSICAL_GPU gpu, XGL_PHYSICAL_GPU_INFO_TYPE infoType, size_t* pDataSize, void* pData);
 typedef void * (XGLAPI *xglGetProcAddrType)(XGL_PHYSICAL_GPU gpu, const char * pName);
 typedef XGL_RESULT (XGLAPI *xglCreateDeviceType)(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo, XGL_DEVICE* pDevice);
@@ -2361,6 +2365,20 @@
     uint32_t*                                   pGpuCount,
     XGL_PHYSICAL_GPU*                           pGpus);
 
+XGL_RESULT XGLAPI xglCreateInstance(
+    const XGL_APPLICATION_INFO*                 pAppInfo,
+    const XGL_ALLOC_CALLBACKS*                  pAllocCb,
+    XGL_INSTANCE*                               pInstance);
+
+XGL_RESULT XGLAPI xglDestroyInstance(
+    XGL_INSTANCE                                instance);
+
+XGL_RESULT XGLAPI xglEnumerateGpus(
+    XGL_INSTANCE                                instance,
+    uint32_t                                    maxGpus,
+    uint32_t*                                   pGpuCount,
+    XGL_PHYSICAL_GPU*                           pGpus);
+
 XGL_RESULT XGLAPI xglGetGpuInfo(
     XGL_PHYSICAL_GPU                            gpu,
     XGL_PHYSICAL_GPU_INFO_TYPE                  infoType,
diff --git a/include/xglLayer.h b/include/xglLayer.h
index 5654da0..5fb8e8c 100644
--- a/include/xglLayer.h
+++ b/include/xglLayer.h
@@ -27,6 +27,9 @@
 {
     xglGetProcAddrType GetProcAddr;
     xglInitAndEnumerateGpusType InitAndEnumerateGpus;
+    xglCreateInstanceType CreateInstance;
+    xglDestroyInstanceType DestroyInstance;
+    xglEnumerateGpusType EnumerateGpus;
     xglGetGpuInfoType GetGpuInfo;
     xglCreateDeviceType CreateDevice;
     xglDestroyDeviceType DestroyDevice;
diff --git a/loader/loader.c b/loader/loader.c
index d2b0dcf..7f5309f 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -42,6 +42,14 @@
 #include "table_ops.h"
 #include "loader.h"
 
+struct loader_instance {
+    const XGL_APPLICATION_INFO *app_info;
+    const XGL_ALLOC_CALLBACKS *alloc_cb;
+
+    struct loader_icd *icds;
+    struct loader_instance *next;
+};
+
 struct loader_layers {
     void *lib_handle;
     char name[256];
@@ -77,9 +85,12 @@
 };
 
 
+// Note: Since the following is a static structure, all members are initialized
+// to zero.
 static struct {
+    struct loader_instance *instances;
+
     bool scanned;
-    struct loader_icd *icds;
     bool layer_scanned;
     char *layer_dirs;
     unsigned int scanned_layer_count;
@@ -290,8 +301,8 @@
         return NULL;
 
     /* prepend to the list */
-    icd->next = loader.icds;
-    loader.icds = icd;
+    icd->next = loader.instances->icds;
+    loader.instances->icds = icd;
 
     return icd;
 }
@@ -471,7 +482,7 @@
 
 static struct loader_icd * loader_get_icd(const XGL_BASE_LAYER_OBJECT *gpu, uint32_t *gpu_index)
 {
-    for (struct loader_icd * icd = loader.icds; icd; icd = icd->next) {
+    for (struct loader_icd * icd = loader.instances->icds; icd; icd = icd->next) {
         for (uint32_t i = 0; i < icd->gpu_count; i++)
             if ((icd->gpus + i) == gpu || (icd->gpus +i)->baseObject == gpu->baseObject) {
                 *gpu_index = i;
@@ -657,7 +668,7 @@
     struct loader_icd *icd;
     struct loader_layers *libs;
 
-    for (icd = loader.icds; icd; icd = icd->next) {
+    for (icd = loader.instances->icds; icd; icd = icd->next) {
         if (icd->gpus)
             free(icd->gpus);
         icd->gpus = NULL;
@@ -750,8 +761,75 @@
     return icd->layer_count[gpu_index];
 }
 
-LOADER_EXPORT void * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char * pName) {
+LOADER_EXPORT XGL_RESULT XGLAPI xglCreateInstance(
+        const XGL_APPLICATION_INFO*                 pAppInfo,
+        const XGL_ALLOC_CALLBACKS*                  pAllocCb,
+        XGL_INSTANCE*                               pInstance)
+{
+    struct loader_instance *ptr_instance = NULL;
 
+    //TODO does this XGL_INSTANCE really have to be a dispatchable object??
+    ptr_instance = (struct loader_instance*) malloc(sizeof(struct loader_instance));
+    if (ptr_instance == NULL) {
+        return XGL_ERROR_OUT_OF_MEMORY;
+    }
+    memset(ptr_instance, 0, sizeof(struct loader_instance));
+
+    ptr_instance->app_info = pAppInfo;
+    ptr_instance->alloc_cb = pAllocCb;
+    ptr_instance->next = loader.instances;
+    loader.instances = ptr_instance;
+
+    *pInstance = (XGL_INSTANCE) ptr_instance;
+    // FIXME/TODO/TBD: WHAT ELSE NEEDS TO BE DONE?
+
+    return XGL_SUCCESS;
+}
+
+LOADER_EXPORT XGL_RESULT XGLAPI xglDestroyInstance(
+        XGL_INSTANCE                                instance)
+{
+    struct loader_instance *ptr_instance = (struct loader_instance *) instance;
+
+    // Remove this instance from the list of instances:
+    struct loader_instance *prev = NULL;
+    struct loader_instance *next = loader.instances;
+    while (next != NULL) {
+        if (next == ptr_instance) {
+            // Remove this instance from the list:
+            if (prev)
+                prev->next = next->next;
+            break;
+        }
+        prev = next;
+        next = next->next;
+    }
+    if (next  == NULL) {
+        // This must be an invalid instance handle or empty list
+        return XGL_ERROR_INVALID_HANDLE;
+    }
+
+    // FIXME/TODO/TBD: WHAT ELSE NEEDS TO BE DONE HERE???
+
+    // Now, remove the instance:
+    free(ptr_instance);
+
+    return XGL_SUCCESS;
+}
+
+LOADER_EXPORT XGL_RESULT XGLAPI xglEnumerateGpus(
+
+        XGL_INSTANCE                                instance,
+        uint32_t                                    maxGpus,
+        uint32_t*                                   pGpuCount,
+        XGL_PHYSICAL_GPU*                           pGpus)
+{
+    // FIXME/TODO/TBD: WHAT ELSE NEEDS TO BE DONE HERE???
+    return XGL_SUCCESS;
+}
+
+LOADER_EXPORT void * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const char * pName)
+{
     if (gpu == NULL)
         return NULL;
     XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
@@ -778,15 +856,24 @@
     uint32_t count = 0;
     XGL_RESULT res;
 
+    // for now only one instance
+    if (loader.instances == NULL) {
+        loader.instances = malloc(sizeof(struct loader_instance));
+        if (loader.instances == NULL)
+            return XGL_ERROR_UNAVAILABLE;
+        memset(loader.instances, 0, sizeof(struct loader_instance));
+    }
+    
+    
     // cleanup any prior layer initializations
     loader_deactivate_layer();
 
     pthread_once(&once, loader_icd_scan);
 
-    if (!loader.icds)
+    if (!loader.instances->icds)
         return XGL_ERROR_UNAVAILABLE;
 
-    icd = loader.icds;
+    icd = loader.instances->icds;
     while (icd) {
         XGL_PHYSICAL_GPU gpus[XGL_MAX_PHYSICAL_GPUS];
         XGL_BASE_LAYER_OBJECT * wrappedGpus;
@@ -921,7 +1008,7 @@
         return loader_msg_callback_add(pfnMsgCallback, pUserData);
     }
 
-    for (icd = loader.icds; icd; icd = icd->next) {
+    for (icd = loader.instances->icds; icd; icd = icd->next) {
         for (uint32_t i = 0; i < icd->gpu_count; i++) {
             res = (icd->loader_dispatch + i)->DbgRegisterMsgCallback(pfnMsgCallback, pUserData);
             if (res != XGL_SUCCESS) {
@@ -935,7 +1022,7 @@
 
     /* roll back on errors */
     if (icd) {
-        for (const struct loader_icd * tmp = loader.icds; tmp != icd; tmp = tmp->next) {
+        for (const struct loader_icd * tmp = loader.instances->icds; tmp != icd; tmp = tmp->next) {
             for (uint32_t i = 0; i < icd->gpu_count; i++)
                 (tmp->loader_dispatch + i)->DbgUnregisterMsgCallback(pfnMsgCallback);
         }
@@ -957,7 +1044,7 @@
         return loader_msg_callback_remove(pfnMsgCallback);
     }
 
-    for (const struct loader_icd * icd = loader.icds; icd; icd = icd->next) {
+    for (const struct loader_icd * icd = loader.instances->icds; icd; icd = icd->next) {
         for (uint32_t i = 0; i < icd->gpu_count; i++) {
             XGL_RESULT r = (icd->loader_dispatch + i)->DbgUnregisterMsgCallback(pfnMsgCallback);
             if (r != XGL_SUCCESS) {
@@ -994,7 +1081,7 @@
         return res;
     }
 
-    for (const struct loader_icd * icd = loader.icds; icd; icd = icd->next) {
+    for (const struct loader_icd * icd = loader.instances->icds; icd; icd = icd->next) {
         for (uint32_t i = 0; i < icd->gpu_count; i++) {
             XGL_RESULT r = (icd->loader_dispatch + i)->DbgSetGlobalOption(dbgOption, dataSize, pData);
             /* unfortunately we cannot roll back */
diff --git a/xgl-generate.py b/xgl-generate.py
index e107d0f..813d850 100755
--- a/xgl-generate.py
+++ b/xgl-generate.py
@@ -105,7 +105,7 @@
         return out_objs and out_objs[-1] == proto.params[-1]
 
     def _is_dispatchable(self, proto):
-        if proto.name in ["GetProcAddr", "EnumerateLayers"]:
+        if proto.name in ["GetProcAddr", "DestroyInstance", "EnumerateGpus", "EnumerateLayers"]:
             return False
 
         in_objs = proto.object_in_params()
diff --git a/xgl.py b/xgl.py
index 22baba5..fa5216b 100644
--- a/xgl.py
+++ b/xgl.py
@@ -183,6 +183,7 @@
     name="XGL_CORE",
     headers=["xgl.h", "xglDbg.h"],
     objects=[
+        "XGL_INSTANCE",
         "XGL_PHYSICAL_GPU",
         "XGL_BASE_OBJECT",
         "XGL_DEVICE",
@@ -223,6 +224,20 @@
              Param("uint32_t*", "pGpuCount"),
              Param("XGL_PHYSICAL_GPU*", "pGpus")]),
 
+        Proto("XGL_RESULT", "CreateInstance",
+            [Param("const XGL_APPLICATION_INFO*", "pAppInfo"),
+             Param("const XGL_ALLOC_CALLBACKS*", "pAllocCb"),
+             Param("XGL_INSTANCE*", "pInstance")]),
+
+        Proto("XGL_RESULT", "DestroyInstance",
+             [Param("XGL_INSTANCE", "pInstance")]),
+
+        Proto("XGL_RESULT", "EnumerateGpus",
+            [Param("XGL_INSTANCE", "instance"),
+             Param("uint32_t", "maxGpus"),
+             Param("uint32_t*", "pGpuCount"),
+             Param("XGL_PHYSICAL_GPU*", "pGpus")]),
+
         Proto("XGL_RESULT", "GetGpuInfo",
             [Param("XGL_PHYSICAL_GPU", "gpu"),
              Param("XGL_PHYSICAL_GPU_INFO_TYPE", "infoType"),