};
struct loader_icd {
- void *handle;
+ const struct loader_scanned_icds *scanned_icds;
XGL_LAYER_DISPATCH_TABLE *loader_dispatch;
uint32_t layer_count[XGL_MAX_PHYSICAL_GPUS];
uint32_t gpu_count;
XGL_BASE_LAYER_OBJECT *gpus;
- xglGetProcAddrType GetProcAddr;
- xglInitAndEnumerateGpusType InitAndEnumerateGpus;
-
struct loader_icd *next;
};
struct loader_msg_callback *next;
};
+struct loader_scanned_icds {
+ void *handle;
+ xglGetProcAddrType GetProcAddr;
+ xglInitAndEnumerateGpusType InitAndEnumerateGpus;
+
+ struct loader_scanned_icds *next;
+};
// Note: Since the following is a static structure, all members are initialized
// to zero.
static struct {
struct loader_instance *instances;
-
- bool scanned;
+ bool icds_scanned;
+ struct loader_scanned_icds *scanned_icd_list;
bool layer_scanned;
char *layer_dirs;
unsigned int scanned_layer_count;
static void
loader_icd_destroy(struct loader_icd *icd)
{
- dlclose(icd->handle);
+ dlclose(icd->scanned_icds->handle);
free(icd);
}
static struct loader_icd *
-loader_icd_create(const char *filename)
+loader_icd_create(const struct loader_scanned_icds *scanned)
{
struct loader_icd *icd;
memset(icd, 0, sizeof(*icd));
- icd->handle = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
- if (!icd->handle) {
- loader_log(XGL_DBG_MSG_WARNING, 0, dlerror());
- free(icd);
- return NULL;
- }
-
-#define LOOKUP(icd, func) do { \
- icd->func = (xgl ##func## Type) dlsym(icd->handle, "xgl" #func); \
- if (!icd->func) { \
- loader_log(XGL_DBG_MSG_WARNING, 0, dlerror()); \
- loader_icd_destroy(icd); \
- return NULL; \
- } \
-} while (0)
- LOOKUP(icd, GetProcAddr);
- LOOKUP(icd, InitAndEnumerateGpus);
-#undef LOOKUP
+ icd->scanned_icds = scanned;
return icd;
}
return XGL_SUCCESS;
}
-static struct loader_icd *loader_icd_add(const char *filename)
+static struct loader_icd *loader_icd_add(const struct loader_scanned_icds *scanned)
{
struct loader_icd *icd;
- icd = loader_icd_create(filename);
+ icd = loader_icd_create(scanned);
if (!icd)
return NULL;
return icd;
}
+static void loader_scanned_icd_add(const char *filename)
+{
+ void *handle;
+ void *fp_gpa, *fp_init;
+ struct loader_scanned_icds *new_node;
+
+ handle = dlopen(filename, RTLD_LAZY);
+ if (!handle) {
+ loader_log(XGL_DBG_MSG_WARNING, 0, dlerror());
+ return;
+ }
+
+#define LOOKUP(func_ptr, func) do { \
+ func_ptr = (xgl ##func## Type) dlsym(handle, "xgl" #func); \
+ if (!func_ptr) { \
+ loader_log(XGL_DBG_MSG_WARNING, 0, dlerror()); \
+ return; \
+ } \
+} while (0)
+
+ LOOKUP(fp_gpa, GetProcAddr);
+ LOOKUP(fp_init, InitAndEnumerateGpus);
+#undef LOOKUP
+
+ new_node = (struct loader_scanned_icds *) malloc(sizeof(struct loader_scanned_icds));
+ if (!new_node) {
+ loader_log(XGL_DBG_MSG_WARNING, 0, "Out of memory can't add icd");
+ return;
+ }
+
+ new_node->handle = handle;
+ new_node->GetProcAddr = fp_gpa;
+ new_node->InitAndEnumerateGpus = fp_init;
+ new_node->next = loader.scanned_icd_list;
+ loader.scanned_icd_list = new_node;
+}
+
#ifndef DEFAULT_XGL_DRIVERS_PATH
// TODO: Is this a good default location?
// Need to search for both 32bit and 64bit ICDs
/* look for ICDs starting with "libXGL_" */
if (!strncmp(dent->d_name, "libXGL_", 7)) {
snprintf(icd_library, 1024, "%s/%s",p,dent->d_name);
- loader_icd_add(icd_library);
+
+ loader_scanned_icd_add(icd_library);
}
dent = readdir(sysdir);
}
- loader.scanned = true;
+ loader.icds_scanned = true;
}
#ifndef DEFAULT_XGL_LAYERS_PATH
static struct loader_icd * loader_get_icd(const XGL_BASE_LAYER_OBJECT *gpu, uint32_t *gpu_index)
{
+ if (!loader.instances)
+ return NULL;
+
+ //TODO go through all instances
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) {
return loader_get_layer_env(icd, gpu_index, layerNames);
}
-static void loader_deactivate_layer()
+static void loader_deactivate_layer(const struct loader_instance *instance)
{
struct loader_icd *icd;
struct loader_layers *libs;
- for (icd = loader.instances->icds; icd; icd = icd->next) {
+ for (icd = instance->icds; icd; icd = icd->next) {
if (icd->gpus)
free(icd->gpus);
icd->gpus = NULL;
((XGL_BASE_LAYER_OBJECT *) gpu)->pGPA = nextGPA;
gpuObj = icd->wrappedGpus[gpu_index] + icd->layer_count[gpu_index] - 1;
gpuObj->nextObject = baseObj;
- gpuObj->pGPA = icd->GetProcAddr;
+ gpuObj->pGPA = icd->scanned_icds->GetProcAddr;
}
}
struct loader_icd *icd;
uint32_t count = 0;
XGL_RESULT res;
+ struct loader_scanned_icds *scanned_icds;
+
+ pthread_once(&once, loader_icd_scan);
// for now only one instance
if (loader.instances == NULL) {
if (loader.instances == NULL)
return XGL_ERROR_UNAVAILABLE;
memset(loader.instances, 0, sizeof(struct loader_instance));
+
+ scanned_icds = loader.scanned_icd_list;
+ while (scanned_icds) {
+ loader_icd_add(scanned_icds);
+ scanned_icds = scanned_icds->next;
+ }
+
+ if (loader.instances->icds == NULL)
+ return XGL_ERROR_UNAVAILABLE;
}
-
-
- // cleanup any prior layer initializations
- loader_deactivate_layer();
- pthread_once(&once, loader_icd_scan);
+ // cleanup any prior layer initializations
+ loader_deactivate_layer(loader.instances);
- if (!loader.instances->icds)
- return XGL_ERROR_UNAVAILABLE;
icd = loader.instances->icds;
while (icd) {
XGL_PHYSICAL_GPU gpus[XGL_MAX_PHYSICAL_GPUS];
XGL_BASE_LAYER_OBJECT * wrappedGpus;
- xglGetProcAddrType getProcAddr = icd->GetProcAddr;
+ xglGetProcAddrType getProcAddr = icd->scanned_icds->GetProcAddr;
uint32_t n, max = maxGpus - count;
if (max > XGL_MAX_PHYSICAL_GPUS) {
max = XGL_MAX_PHYSICAL_GPUS;
}
- res = icd->InitAndEnumerateGpus(pAppInfo, pAllocCb, max, &n, gpus);
+ res = icd->scanned_icds->InitAndEnumerateGpus(pAppInfo, pAllocCb, max, &n, gpus);
if (res == XGL_SUCCESS && n) {
wrappedGpus = (XGL_BASE_LAYER_OBJECT*) malloc(n * sizeof(XGL_BASE_LAYER_OBJECT));
icd->gpus = wrappedGpus;
if (pOutLayerCount == NULL || pOutLayers == NULL)
return XGL_ERROR_INVALID_POINTER;
+ if (!icd)
+ return XGL_ERROR_UNAVAILABLE;
+
for (int i = 0; i < 16; i++)
layers[i] = &layer_buf[i][0];
XGL_RESULT res;
uint32_t gpu_idx;
- if (!loader.scanned) {
+ //TODO fix for uncreated instances
+ if (!loader.icds_scanned) {
return loader_msg_callback_add(pfnMsgCallback, pUserData);
}
+ //TODO go through all instances
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);
LOADER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
{
- XGL_RESULT res = XGL_SUCCESS;
+ XGL_RESULT res = XGL_SUCCESS;\
- if (!loader.scanned) {
+ //TODO fix for uncreated instances
+ if (!loader.icds_scanned) {
return loader_msg_callback_remove(pfnMsgCallback);
}
+ //TODO loop through all instances
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);
{
XGL_RESULT res = XGL_SUCCESS;
- if (!loader.scanned) {
+ if (!loader.icds_scanned) {
if (dataSize == 0)
return XGL_ERROR_INVALID_VALUE;
return res;
}
+ //TODO loop through all instances
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);