From ecc82ad5fc151f8d08d6fde54e709940c6044606 Mon Sep 17 00:00:00 2001 From: Jon Ashburn Date: Tue, 14 Oct 2014 19:15:22 -0600 Subject: [PATCH] Layers initial prototype. Includes an auto generated layer (GenericLayer) that wraps all api calls. Includes a basic handwritten layer (basicLayer) that wraps a few apis. Adds xglGetProcAddr as a new api, which is used to chain layers together. All layers and loader implement a dispatch table. --- CMakeLists.txt | 1 + loader/CMakeLists.txt | 9 +- loader/loader.c | 646 +++++++++++++++++++++++++++++++++++++++++- loader/loader.h | 4 +- xgl-generate.py | 152 ++++++++-- xgl.py | 19 +- 6 files changed, 793 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cbeb2cf..2a0db8d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,3 +23,4 @@ endif() add_subdirectory(loader) add_subdirectory(icd) add_subdirectory(tests) +add_subdirectory(layers) diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index 8c01a604..f3486978 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -1,8 +1,13 @@ -add_custom_command(OUTPUT dispatch.c +add_custom_command(OUTPUT dispatch.c ${PROJECT_SOURCE_DIR}/icd/common/icd-dispatch-table.h COMMAND ${PROJECT_SOURCE_DIR}/xgl-generate.py loader > dispatch.c + COMMAND ${PROJECT_SOURCE_DIR}/xgl-generate.py icd-dispatch-table > ${PROJECT_SOURCE_DIR}/icd/common/icd-dispatch-table.h DEPENDS ${PROJECT_SOURCE_DIR}/xgl-generate.py ${PROJECT_SOURCE_DIR}/xgl.py) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) add_library(XGL SHARED loader.c dispatch.c) set_target_properties(XGL PROPERTIES SOVERSION 0) diff --git a/loader/loader.c b/loader/loader.c index fddbc24f..c86ada21 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -37,25 +37,27 @@ #include #include #include - +#include #include "loader.h" -typedef XGL_RESULT (XGLAPI *InitAndEnumerateGpusT)(const XGL_APPLICATION_INFO* pAppInfo, const XGL_ALLOC_CALLBACKS* pAllocCb, XGL_UINT maxGpus, XGL_UINT* pGpuCount, XGL_PHYSICAL_GPU* pGpus); -typedef XGL_RESULT (XGLAPI *DbgRegisterMsgCallbackT)(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, XGL_VOID* pUserData); -typedef XGL_RESULT (XGLAPI *DbgUnregisterMsgCallbackT)(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback); -typedef XGL_RESULT (XGLAPI *DbgSetGlobalOptionT)(XGL_INT dbgOption, XGL_SIZE dataSize, const XGL_VOID* pData); struct loader_icd { void *handle; - InitAndEnumerateGpusT InitAndEnumerateGpus; - DbgRegisterMsgCallbackT DbgRegisterMsgCallback; - DbgUnregisterMsgCallbackT DbgUnregisterMsgCallback; - DbgSetGlobalOptionT DbgSetGlobalOption; + GetProcAddrType GetProcAddr; + InitAndEnumerateGpusType InitAndEnumerateGpus; + DbgRegisterMsgCallbackType DbgRegisterMsgCallback; + DbgUnregisterMsgCallbackType DbgUnregisterMsgCallback; + DbgSetGlobalOptionType DbgSetGlobalOption; struct loader_icd *next; }; +struct loader_layers { + void *lib_handle; + char lib_name[1024]; +}; + struct loader_msg_callback { XGL_DBG_MSG_CALLBACK_FUNCTION func; XGL_VOID *data; @@ -63,10 +65,15 @@ struct loader_msg_callback { struct loader_msg_callback *next; }; + static struct { bool scanned; struct loader_icd *icds; - + XGL_LAYER_DISPATCH_TABLE *loader_dispatch; + XGL_UINT layer_count; + bool layer_scaned; + char layer_dirs[4096]; + struct loader_layers layer_libs[MAX_LAYER_LIBRARIES]; struct loader_msg_callback *msg_callbacks; bool debug_echo_enable; @@ -198,13 +205,14 @@ loader_icd_create(const char *filename) } #define LOOKUP(icd, func) do { \ - icd->func = (func## T) dlsym(icd->handle, "xgl" #func); \ + icd->func = (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); LOOKUP(icd, DbgRegisterMsgCallback); LOOKUP(icd, DbgUnregisterMsgCallback); @@ -351,6 +359,603 @@ static void loader_icd_scan(void) loader.scanned = true; } +#ifndef DEFAULT_XGL_LAYERS_PATH +// TODO: Is this a good default locations +#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) +{ + const char *p, *next; + char *libPaths = &loader.layer_dirs[0]; + DIR *curdir; + struct dirent *dent; + int len, i, n; + + if (libInPaths){ + strncpy(libPaths, libInPaths, sizeof(loader.layer_dirs)); + } + else { + *libPaths = '\0'; + } + + /* 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; + } + loader.layer_count = 0; + + if (useDefaultDirs) + strncat(libPaths, DEFAULT_XGL_LAYERS_PATH, sizeof(loader.layer_dirs) - sizeof(DEFAULT_XGL_LAYERS_PATH)); + + for (p = libPaths; *p; p = next) { + next = strchr(p, ':'); + if (next == NULL) { + len = strlen(p); + next = p + len; + } + else { + len = next - p; + *(char *) next = '\0'; + next++; + } + + curdir = opendir(p); + 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) + continue; + + loader.layer_count++; + if (!openLibs) + dlclose(loader.layer_libs[n].lib_handle); + } + + dent = readdir(curdir); + } + closedir(curdir); + } + } + + 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; +} + +static void init_dispatch_table(XGL_LAYER_DISPATCH_TABLE *tab, GetProcAddrType fpGPA, XGL_PHYSICAL_GPU gpu) +{ + tab->GetProcAddr = fpGPA; + tab->InitAndEnumerateGpus = fpGPA(gpu, (const XGL_CHAR *) "xglInitAndEnumerateGpus"); + tab->GetGpuInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetGpuInfo"); + tab->CreateDevice = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDevice"); + tab->DestroyDevice = fpGPA(gpu, (const XGL_CHAR *) "xglDestroyDevice"); + tab->GetExtensionSupport = fpGPA(gpu, (const XGL_CHAR *) "xglGetExtensionSupport"); + tab->GetDeviceQueue = fpGPA(gpu, (const XGL_CHAR *) "xglGetDeviceQueue"); + tab->QueueSubmit = fpGPA(gpu, (const XGL_CHAR *) "xglQueueSubmit"); + tab->QueueSetGlobalMemReferences = fpGPA(gpu, (const XGL_CHAR *) "xglQueueSetGlobalMemReferences"); + tab->QueueWaitIdle = fpGPA(gpu, (const XGL_CHAR *) "xglQueueWaitIdle"); + tab->DeviceWaitIdle = fpGPA(gpu, (const XGL_CHAR *) "xglDeviceWaitIdle"); + tab->GetMemoryHeapCount = fpGPA(gpu, (const XGL_CHAR *) "xglGetMemoryHeapCount"); + tab->GetMemoryHeapInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetMemoryHeapInfo"); + tab->AllocMemory = fpGPA(gpu, (const XGL_CHAR *) "xglAllocMemory"); + tab->FreeMemory = fpGPA(gpu, (const XGL_CHAR *) "xglFreeMemory"); + tab->SetMemoryPriority = fpGPA(gpu, (const XGL_CHAR *) "xglSetMemoryPriority"); + tab->MapMemory = fpGPA(gpu, (const XGL_CHAR *) "xglMapMemory"); + tab->UnmapMemory = fpGPA(gpu, (const XGL_CHAR *) "xglUnmapMemory"); + tab->PinSystemMemory = fpGPA(gpu, (const XGL_CHAR *) "xglPinSystemMemory"); + tab->RemapVirtualMemoryPages = fpGPA(gpu, (const XGL_CHAR *) "xglRemapVirtualMemoryPages"); + tab->GetMultiGpuCompatibility = fpGPA(gpu, (const XGL_CHAR *) "xglGetMultiGpuCompatibility"); + tab->OpenSharedMemory = fpGPA(gpu, (const XGL_CHAR *) "xglOpenSharedMemory"); + tab->OpenSharedQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglOpenSharedQueueSemaphore"); + tab->OpenPeerMemory = fpGPA(gpu, (const XGL_CHAR *) "xglOpenPeerMemory"); + tab->OpenPeerImage = fpGPA(gpu, (const XGL_CHAR *) "xglOpenPeerImage"); + tab->DestroyObject = fpGPA(gpu, (const XGL_CHAR *) "xglDestroyObject"); + tab->GetObjectInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetObjectInfo"); + tab->BindObjectMemory = fpGPA(gpu, (const XGL_CHAR *) "xglBindObjectMemory"); + tab->CreateFence = fpGPA(gpu, (const XGL_CHAR *) "xglCreateFence"); + tab->GetFenceStatus = fpGPA(gpu, (const XGL_CHAR *) "xglGetFenceStatus"); + tab->WaitForFences = fpGPA(gpu, (const XGL_CHAR *) "xglWaitForFences"); + tab->CreateQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglCreateQueueSemaphore"); + tab->SignalQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglSignalQueueSemaphore"); + tab->WaitQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglWaitQueueSemaphore"); + tab->CreateEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCreateEvent"); + tab->GetEventStatus = fpGPA(gpu, (const XGL_CHAR *) "xglGetEventStatus"); + tab->SetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglSetEvent"); + tab->ResetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglResetEvent"); + tab->CreateQueryPool = fpGPA(gpu, (const XGL_CHAR *) "xglCreateQueryPool"); + tab->GetQueryPoolResults = fpGPA(gpu, (const XGL_CHAR *) "xglGetQueryPoolResults"); + tab->GetFormatInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetFormatInfo"); + tab->CreateImage = fpGPA(gpu, (const XGL_CHAR *) "xglCreateImage"); + tab->GetImageSubresourceInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetImageSubresourceInfo"); + tab->CreateImageView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateImageView"); + tab->CreateColorAttachmentView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateColorAttachmentView"); + tab->CreateDepthStencilView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDepthStencilView"); + tab->CreateShader = fpGPA(gpu, (const XGL_CHAR *) "xglCreateShader"); + tab->CreateGraphicsPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCreateGraphicsPipeline"); + tab->CreateComputePipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCreateComputePipeline"); + tab->StorePipeline = fpGPA(gpu, (const XGL_CHAR *) "xglStorePipeline"); + tab->LoadPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglLoadPipeline"); + tab->CreatePipelineDelta = fpGPA(gpu, (const XGL_CHAR *) "xglCreatePipelineDelta"); + tab->CreateSampler = fpGPA(gpu, (const XGL_CHAR *) "xglCreateSampler"); + tab->CreateDescriptorSet = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDescriptorSet"); + tab->BeginDescriptorSetUpdate = fpGPA(gpu, (const XGL_CHAR *) "xglBeginDescriptorSetUpdate"); + tab->EndDescriptorSetUpdate = fpGPA(gpu, (const XGL_CHAR *) "xglEndDescriptorSetUpdate"); + tab->AttachSamplerDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachSamplerDescriptors"); + tab->AttachImageViewDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachImageViewDescriptors"); + tab->AttachMemoryViewDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachMemoryViewDescriptors"); + tab->AttachNestedDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachNestedDescriptors"); + tab->ClearDescriptorSetSlots = fpGPA(gpu, (const XGL_CHAR *) "xglClearDescriptorSetSlots"); + tab->CreateViewportState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateViewportState"); + tab->CreateRasterState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateRasterState"); + tab->CreateMsaaState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateMsaaState"); + tab->CreateColorBlendState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateColorBlendState"); + tab->CreateDepthStencilState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDepthStencilState"); + tab->CreateCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglCreateCommandBuffer"); + tab->BeginCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglBeginCommandBuffer"); + tab->EndCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglEndCommandBuffer"); + tab->ResetCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglResetCommandBuffer"); + tab->CmdBindPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindPipeline"); + tab->CmdBindPipelineDelta = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindPipelineDelta"); + tab->CmdBindStateObject = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindStateObject"); + tab->CmdBindDescriptorSet = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindDescriptorSet"); + tab->CmdBindDynamicMemoryView = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindDynamicMemoryView"); + tab->CmdBindIndexData = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindIndexData"); + tab->CmdBindAttachments = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindAttachments"); + tab->CmdPrepareMemoryRegions = fpGPA(gpu, (const XGL_CHAR *) "xglCmdPrepareMemoryRegions"); + tab->CmdPrepareImages = fpGPA(gpu, (const XGL_CHAR *) "xglCmdPrepareImages"); + tab->CmdDraw = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDraw"); + tab->CmdDrawIndexed = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndexed"); + tab->CmdDrawIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndirect"); + tab->CmdDrawIndexedIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndexedIndirect"); + tab->CmdDispatch = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDispatch"); + tab->CmdDispatchIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDispatchIndirect"); + tab->CmdCopyMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyMemory"); + tab->CmdCopyImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyImage"); + tab->CmdCopyMemoryToImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyMemoryToImage"); + tab->CmdCopyImageToMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyImageToMemory"); + tab->CmdCloneImageData = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCloneImageData"); + tab->CmdUpdateMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdUpdateMemory"); + tab->CmdFillMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdFillMemory"); + tab->CmdClearColorImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearColorImage"); + tab->CmdClearColorImageRaw = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearColorImageRaw"); + tab->CmdClearDepthStencil = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearDepthStencil"); + tab->CmdResolveImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResolveImage"); + tab->CmdSetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCmdSetEvent"); + tab->CmdResetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResetEvent"); + tab->CmdMemoryAtomic = fpGPA(gpu, (const XGL_CHAR *) "xglCmdMemoryAtomic"); + tab->CmdBeginQuery = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBeginQuery"); + tab->CmdEndQuery = fpGPA(gpu, (const XGL_CHAR *) "xglCmdEndQuery"); + tab->CmdResetQueryPool = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResetQueryPool"); + tab->CmdWriteTimestamp = fpGPA(gpu, (const XGL_CHAR *) "xglCmdWriteTimestamp"); + tab->CmdInitAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdInitAtomicCounters"); + tab->CmdLoadAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdLoadAtomicCounters"); + tab->CmdSaveAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdSaveAtomicCounters"); + tab->DbgSetValidationLevel = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetValidationLevel"); + tab->DbgRegisterMsgCallback = fpGPA(gpu, (const XGL_CHAR *) "xglDbgRegisterMsgCallback"); + tab->DbgUnregisterMsgCallback = fpGPA(gpu, (const XGL_CHAR *) "xglDbgUnregisterMsgCallback"); + tab->DbgSetMessageFilter = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetMessageFilter"); + tab->DbgSetObjectTag = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetObjectTag"); + tab->DbgSetGlobalOption = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetGlobalOption"); + tab->DbgSetDeviceOption = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetDeviceOption"); + tab->CmdDbgMarkerBegin = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDbgMarkerBegin"); + tab->CmdDbgMarkerEnd = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDbgMarkerEnd"); + tab->WsiX11AssociateConnection = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11AssociateConnection"); + tab->WsiX11GetMSC = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11GetMSC"); + tab->WsiX11CreatePresentableImage = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11CreatePresentableImage"); + tab->WsiX11QueuePresent = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11QueuePresent"); +} + +extern XGL_UINT ActivateLayers(XGL_PHYSICAL_GPU *gpu) +{ + static bool layer_installed = false; + //const struct loader_icd *icd; + /* activate any layer libraries */ + if (loader.layer_count > 0 && !layer_installed) { + + //todo get icd from gpu + //icd = loader.icds; // We are only going to configure the first driver + //SetDispatchType IcdSetDispatch = dlsym(icd->handle, "xglSetDispatch"); + + // 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 = gpuObj->pGPA; + 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()); + continue; + } else { + loader_log(XGL_DBG_MSG_UNKNOWN, 0, "Inserting layer lib %s",loader.layer_libs[i].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) { + //TODO handle multiple icd case + init_dispatch_table(loader.loader_dispatch, nextGPA, gpuObj); + //IcdSetDispatch(&new_table, true); + } + } + *gpu = ((XGL_PHYSICAL_GPU *) gpuObj); + layer_installed = true; + } + return loader.layer_count; +} + +#if 0 +LOADER_EXPORT XGL_RESULT xglSetLayers(const XGL_CHAR * pStr) +{ + char *p, *next, *str; + int len; + XGL_UINT count= 0; + + if (!pStr) + return XGL_ERROR_INVALID_POINTER; + + p= (char *) pStr; + str = malloc(strlen(p) + 1); + do { + next = strchr(p, ':'); + if (next == NULL) { + len = strlen(p); + next = p + len; + } + else { + len = next - p; + *(char *) next = '\0'; + next++; + } + + strncpy(str, p, len); + str[len] = '\0'; + if (layer_lib_sort(str, count)) + 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; +} + +#endif + +LOADER_EXPORT void * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const XGL_CHAR * pName) { + + if (gpu == NULL) + return NULL; + + XGL_LAYER_DISPATCH_TABLE * disp_table = * (XGL_LAYER_DISPATCH_TABLE **) gpu; + if (disp_table == NULL) + return NULL; + + if (!strncmp("xglGetProcAddr", (const char *) pName, sizeof("xglGetProcAddr"))) + return xglGetProcAddr; + else if (!strncmp("xglInitAndEnumerateGpus", (const char *) pName, sizeof("xglInitAndEnumerateGpus"))) + return disp_table->InitAndEnumerateGpus; + else if (!strncmp("xglGetGpuInfo", (const char *) pName, sizeof ("xglGetGpuInfo"))) + return disp_table->GetGpuInfo; + else if (!strncmp("xglCreateDevice", (const char *) pName, sizeof ("xglCreateDevice"))) + return disp_table->CreateDevice; + else if (!strncmp("xglDestroyDevice", (const char *) pName, sizeof ("xglDestroyDevice"))) + return disp_table->DestroyDevice; + else if (!strncmp("xglGetExtensionSupport", (const char *) pName, sizeof ("xglGetExtensionSupport"))) + return disp_table->GetExtensionSupport; + else if (!strncmp("xglGetDeviceQueue", (const char *) pName, sizeof ("xglGetDeviceQueue"))) + return disp_table->GetDeviceQueue; + else if (!strncmp("xglQueueSubmit", (const char *) pName, sizeof ("xglQueueSubmit"))) + return disp_table->QueueSubmit; + else if (!strncmp("xglQueueSetGlobalMemReferences", (const char *) pName, sizeof ("xglQueueSetGlobalMemReferences"))) + return disp_table->QueueSetGlobalMemReferences; + else if (!strncmp("xglQueueWaitIdle", (const char *) pName, sizeof ("xglQueueWaitIdle"))) + return disp_table->QueueWaitIdle; + else if (!strncmp("xglDeviceWaitIdle", (const char *) pName, sizeof ("xglDeviceWaitIdle"))) + return disp_table->DeviceWaitIdle; + else if (!strncmp("xglGetMemoryHeapCount", (const char *) pName, sizeof ("xglGetMemoryHeapCount"))) + return disp_table->GetMemoryHeapCount; + else if (!strncmp("xglGetMemoryHeapInfo", (const char *) pName, sizeof ("xglGetMemoryHeapInfo"))) + return disp_table->GetMemoryHeapInfo; + else if (!strncmp("xglAllocMemory", (const char *) pName, sizeof ("xglAllocMemory"))) + return disp_table->AllocMemory; + else if (!strncmp("xglFreeMemory", (const char *) pName, sizeof ("xglFreeMemory"))) + return disp_table->FreeMemory; + else if (!strncmp("xglSetMemoryPriority", (const char *) pName, sizeof ("xglSetMemoryPriority"))) + return disp_table->SetMemoryPriority; + else if (!strncmp("xglMapMemory", (const char *) pName, sizeof ("xglMapMemory"))) + return disp_table->MapMemory; + else if (!strncmp("xglUnmapMemory", (const char *) pName, sizeof ("xglUnmapMemory"))) + return disp_table->UnmapMemory; + else if (!strncmp("xglPinSystemMemory", (const char *) pName, sizeof ("xglPinSystemMemory"))) + return disp_table->PinSystemMemory; + else if (!strncmp("xglRemapVirtualMemoryPages", (const char *) pName, sizeof ("xglRemapVirtualMemoryPages"))) + return disp_table->RemapVirtualMemoryPages; + else if (!strncmp("xglGetMultiGpuCompatibility", (const char *) pName, sizeof ("xglGetMultiGpuCompatibility"))) + return disp_table->GetMultiGpuCompatibility; + else if (!strncmp("xglOpenSharedMemory", (const char *) pName, sizeof ("xglOpenSharedMemory"))) + return disp_table->OpenSharedMemory; + else if (!strncmp("xglOpenSharedQueueSemaphore", (const char *) pName, sizeof ("xglOpenSharedQueueSemaphore"))) + return disp_table->OpenSharedQueueSemaphore; + else if (!strncmp("xglOpenPeerMemory", (const char *) pName, sizeof ("xglOpenPeerMemory"))) + return disp_table->OpenPeerMemory; + else if (!strncmp("xglOpenPeerImage", (const char *) pName, sizeof ("xglOpenPeerImage"))) + return disp_table->OpenPeerImage; + else if (!strncmp("xglDestroyObject", (const char *) pName, sizeof ("xglDestroyObject"))) + return disp_table->DestroyObject; + else if (!strncmp("xglGetObjectInfo", (const char *) pName, sizeof ("xglGetObjectInfo"))) + return disp_table->GetObjectInfo; + else if (!strncmp("xglBindObjectMemory", (const char *) pName, sizeof ("xglBindObjectMemory"))) + return disp_table->BindObjectMemory; + else if (!strncmp("xglCreateFence", (const char *) pName, sizeof ("xgllCreateFence"))) + return disp_table->CreateFence; + else if (!strncmp("xglGetFenceStatus", (const char *) pName, sizeof ("xglGetFenceStatus"))) + return disp_table->GetFenceStatus; + else if (!strncmp("xglWaitForFences", (const char *) pName, sizeof ("xglWaitForFences"))) + return disp_table->WaitForFences; + else if (!strncmp("xglCreateQueueSemaphore", (const char *) pName, sizeof ("xgllCreateQueueSemaphore"))) + return disp_table->CreateQueueSemaphore; + else if (!strncmp("xglSignalQueueSemaphore", (const char *) pName, sizeof ("xglSignalQueueSemaphore"))) + return disp_table->SignalQueueSemaphore; + else if (!strncmp("xglWaitQueueSemaphore", (const char *) pName, sizeof ("xglWaitQueueSemaphore"))) + return disp_table->WaitQueueSemaphore; + else if (!strncmp("xglCreateEvent", (const char *) pName, sizeof ("xgllCreateEvent"))) + return disp_table->CreateEvent; + else if (!strncmp("xglGetEventStatus", (const char *) pName, sizeof ("xglGetEventStatus"))) + return disp_table->GetEventStatus; + else if (!strncmp("xglSetEvent", (const char *) pName, sizeof ("xglSetEvent"))) + return disp_table->SetEvent; + else if (!strncmp("xglResetEvent", (const char *) pName, sizeof ("xgllResetEvent"))) + return disp_table->ResetEvent; + else if (!strncmp("xglCreateQueryPool", (const char *) pName, sizeof ("xglCreateQueryPool"))) + return disp_table->CreateQueryPool; + else if (!strncmp("xglGetQueryPoolResults", (const char *) pName, sizeof ("xglGetQueryPoolResults"))) + return disp_table->GetQueryPoolResults; + else if (!strncmp("xglGetFormatInfo", (const char *) pName, sizeof ("xglGetFormatInfo"))) + return disp_table->GetFormatInfo; + else if (!strncmp("xglCreateImage", (const char *) pName, sizeof ("xglCreateImage"))) + return disp_table->CreateImage; + else if (!strncmp("xglGetImageSubresourceInfo", (const char *) pName, sizeof ("xglGetImageSubresourceInfo"))) + return disp_table->GetImageSubresourceInfo; + else if (!strncmp("xglCreateImageView", (const char *) pName, sizeof ("xglCreateImageView"))) + return disp_table->CreateImageView; + else if (!strncmp("xglCreateColorAttachmentView", (const char *) pName, sizeof ("xglCreateColorAttachmentView"))) + return disp_table->CreateColorAttachmentView; + else if (!strncmp("xglCreateDepthStencilView", (const char *) pName, sizeof ("xglCreateDepthStencilView"))) + return disp_table->CreateDepthStencilView; + else if (!strncmp("xglCreateShader", (const char *) pName, sizeof ("xglCreateShader"))) + return disp_table->CreateShader; + else if (!strncmp("xglCreateGraphicsPipeline", (const char *) pName, sizeof ("xglCreateGraphicsPipeline"))) + return disp_table->CreateGraphicsPipeline; + else if (!strncmp("xglCreateComputePipeline", (const char *) pName, sizeof ("xglCreateComputePipeline"))) + return disp_table->CreateComputePipeline; + else if (!strncmp("xglStorePipeline", (const char *) pName, sizeof ("xglStorePipeline"))) + return disp_table->StorePipeline; + else if (!strncmp("xglLoadPipeline", (const char *) pName, sizeof ("xglLoadPipeline"))) + return disp_table->LoadPipeline; + else if (!strncmp("xglCreatePipelineDelta", (const char *) pName, sizeof ("xglCreatePipelineDelta"))) + return disp_table->CreatePipelineDelta; + else if (!strncmp("xglCreateSampler", (const char *) pName, sizeof ("xglCreateSampler"))) + return disp_table->CreateSampler; + else if (!strncmp("xglCreateDescriptorSet", (const char *) pName, sizeof ("xglCreateDescriptorSet"))) + return disp_table->CreateDescriptorSet; + else if (!strncmp("xglBeginDescriptorSetUpdate", (const char *) pName, sizeof ("xglBeginDescriptorSetUpdate"))) + return disp_table->BeginDescriptorSetUpdate; + else if (!strncmp("xglEndDescriptorSetUpdate", (const char *) pName, sizeof ("xglEndDescriptorSetUpdate"))) + return disp_table->EndDescriptorSetUpdate; + else if (!strncmp("xglAttachSamplerDescriptors", (const char *) pName, sizeof ("xglAttachSamplerDescriptors"))) + return disp_table->AttachSamplerDescriptors; + else if (!strncmp("xglAttachImageViewDescriptors", (const char *) pName, sizeof ("xglAttachImageViewDescriptors"))) + return disp_table->AttachImageViewDescriptors; + else if (!strncmp("xglAttachMemoryViewDescriptors", (const char *) pName, sizeof ("xglAttachMemoryViewDescriptors"))) + return disp_table->AttachMemoryViewDescriptors; + else if (!strncmp("xglAttachNestedDescriptors", (const char *) pName, sizeof ("xglAttachNestedDescriptors"))) + return disp_table->AttachNestedDescriptors; + else if (!strncmp("xglClearDescriptorSetSlots", (const char *) pName, sizeof ("xglClearDescriptorSetSlots"))) + return disp_table->ClearDescriptorSetSlots; + else if (!strncmp("xglCreateViewportState", (const char *) pName, sizeof ("xglCreateViewportState"))) + return disp_table->CreateViewportState; + else if (!strncmp("xglCreateRasterState", (const char *) pName, sizeof ("xglCreateRasterState"))) + return disp_table->CreateRasterState; + else if (!strncmp("xglCreateMsaaState", (const char *) pName, sizeof ("xglCreateMsaaState"))) + return disp_table->CreateMsaaState; + else if (!strncmp("xglCreateColorBlendState", (const char *) pName, sizeof ("xglCreateColorBlendState"))) + return disp_table->CreateColorBlendState; + else if (!strncmp("xglCreateDepthStencilState", (const char *) pName, sizeof ("xglCreateDepthStencilState"))) + return disp_table->CreateDepthStencilState; + else if (!strncmp("xglCreateCommandBuffer", (const char *) pName, sizeof ("xglCreateCommandBuffer"))) + return disp_table->CreateCommandBuffer; + else if (!strncmp("xglBeginCommandBuffer", (const char *) pName, sizeof ("xglBeginCommandBuffer"))) + return disp_table->BeginCommandBuffer; + else if (!strncmp("xglEndCommandBuffer", (const char *) pName, sizeof ("xglEndCommandBuffer"))) + return disp_table->EndCommandBuffer; + else if (!strncmp("xglResetCommandBuffer", (const char *) pName, sizeof ("xglResetCommandBuffer"))) + return disp_table->ResetCommandBuffer; + else if (!strncmp("xglCmdBindPipeline", (const char *) pName, sizeof ("xglCmdBindPipeline"))) + return disp_table->CmdBindPipeline; + else if (!strncmp("xglCmdBindPipelineDelta", (const char *) pName, sizeof ("xglCmdBindPipelineDelta"))) + return disp_table->CmdBindPipelineDelta; + else if (!strncmp("xglCmdBindStateObject", (const char *) pName, sizeof ("xglCmdBindStateObject"))) + return disp_table->CmdBindStateObject; + else if (!strncmp("xglCmdBindDescriptorSet", (const char *) pName, sizeof ("xglCmdBindDescriptorSet"))) + return disp_table->CmdBindDescriptorSet; + else if (!strncmp("xglCmdBindDynamicMemoryView", (const char *) pName, sizeof ("xglCmdBindDynamicMemoryView"))) + return disp_table->CmdBindDynamicMemoryView; + else if (!strncmp("xglCmdBindIndexData", (const char *) pName, sizeof ("xglCmdBindIndexData"))) + return disp_table->CmdBindIndexData; + else if (!strncmp("xglCmdBindAttachments", (const char *) pName, sizeof ("xglCmdBindAttachments"))) + return disp_table->CmdBindAttachments; + else if (!strncmp("xglCmdPrepareMemoryRegions", (const char *) pName, sizeof ("xglCmdPrepareMemoryRegions"))) + return disp_table->CmdPrepareMemoryRegions; + else if (!strncmp("xglCmdPrepareImages", (const char *) pName, sizeof ("xglCmdPrepareImages"))) + return disp_table->CmdPrepareImages; + else if (!strncmp("xglCmdDraw", (const char *) pName, sizeof ("xglCmdDraw"))) + return disp_table->CmdDraw; + else if (!strncmp("xglCmdDrawIndexed", (const char *) pName, sizeof ("xglCmdDrawIndexed"))) + return disp_table->CmdDrawIndexed; + else if (!strncmp("xglCmdDrawIndirect", (const char *) pName, sizeof ("xglCmdDrawIndirect"))) + return disp_table->CmdDrawIndirect; + else if (!strncmp("xglCmdDrawIndexedIndirect", (const char *) pName, sizeof ("xglCmdDrawIndexedIndirect"))) + return disp_table->CmdDrawIndexedIndirect; + else if (!strncmp("xglCmdDispatch", (const char *) pName, sizeof ("xglCmdDispatch"))) + return disp_table->CmdDispatch; + else if (!strncmp("xglCmdDispatchIndirect", (const char *) pName, sizeof ("xglCmdDispatchIndirect"))) + return disp_table->CmdDispatchIndirect; + else if (!strncmp("xglCmdCopyMemory", (const char *) pName, sizeof ("xglCmdCopyMemory"))) + return disp_table->CmdCopyMemory; + else if (!strncmp("xglCmdCopyImage", (const char *) pName, sizeof ("xglCmdCopyImage"))) + return disp_table->CmdCopyImage; + else if (!strncmp("xglCmdCopyMemoryToImage", (const char *) pName, sizeof ("xglCmdCopyMemoryToImage"))) + return disp_table->CmdCopyMemoryToImage; + else if (!strncmp("xglCmdCopyImageToMemory", (const char *) pName, sizeof ("xglCmdCopyImageToMemory"))) + return disp_table->CmdCopyImageToMemory; + else if (!strncmp("xglCmdCloneImageData", (const char *) pName, sizeof ("xglCmdCloneImageData"))) + return disp_table->CmdCloneImageData; + else if (!strncmp("xglCmdUpdateMemory", (const char *) pName, sizeof ("xglCmdUpdateMemory"))) + return disp_table->CmdUpdateMemory; + else if (!strncmp("xglCmdFillMemory", (const char *) pName, sizeof ("xglCmdFillMemory"))) + return disp_table->CmdFillMemory; + else if (!strncmp("xglCmdClearColorImage", (const char *) pName, sizeof ("xglCmdClearColorImage"))) + return disp_table->CmdClearColorImage; + else if (!strncmp("xglCmdClearColorImageRaw", (const char *) pName, sizeof ("xglCmdClearColorImageRaw"))) + return disp_table->CmdClearColorImageRaw; + else if (!strncmp("xglCmdClearDepthStencil", (const char *) pName, sizeof ("xglCmdClearDepthStencil"))) + return disp_table->CmdClearDepthStencil; + else if (!strncmp("xglCmdResolveImage", (const char *) pName, sizeof ("xglCmdResolveImage"))) + return disp_table->CmdResolveImage; + else if (!strncmp("xglCmdSetEvent", (const char *) pName, sizeof ("xglCmdSetEvent"))) + return disp_table->CmdSetEvent; + else if (!strncmp("xglCmdResetEvent", (const char *) pName, sizeof ("xglCmdResetEvent"))) + return disp_table->CmdResetEvent; + else if (!strncmp("xglCmdMemoryAtomic", (const char *) pName, sizeof ("xglCmdMemoryAtomic"))) + return disp_table->CmdMemoryAtomic; + else if (!strncmp("xglCmdBeginQuery", (const char *) pName, sizeof ("xglCmdBeginQuery"))) + return disp_table->CmdBeginQuery; + else if (!strncmp("xglCmdEndQuery", (const char *) pName, sizeof ("xglCmdEndQuery"))) + return disp_table->CmdEndQuery; + else if (!strncmp("xglCmdResetQueryPool", (const char *) pName, sizeof ("xglCmdResetQueryPool"))) + return disp_table->CmdResetQueryPool; + else if (!strncmp("xglCmdWriteTimestamp", (const char *) pName, sizeof ("xglCmdWriteTimestamp"))) + return disp_table->CmdWriteTimestamp; + else if (!strncmp("xglCmdInitAtomicCounters", (const char *) pName, sizeof ("xglCmdInitAtomicCounters"))) + return disp_table->CmdInitAtomicCounters; + else if (!strncmp("xglCmdLoadAtomicCounters", (const char *) pName, sizeof ("xglCmdLoadAtomicCounters"))) + return disp_table->CmdLoadAtomicCounters; + else if (!strncmp("xglCmdSaveAtomicCounters", (const char *) pName, sizeof ("xglCmdSaveAtomicCounters"))) + return disp_table->CmdSaveAtomicCounters; + else if (!strncmp("xglDbgSetValidationLevel", (const char *) pName, sizeof ("xglDbgSetValidationLevel"))) + return disp_table->DbgSetValidationLevel; + else if (!strncmp("xglDbgRegisterMsgCallback", (const char *) pName, sizeof ("xglDbgRegisterMsgCallback"))) + return disp_table->DbgRegisterMsgCallback; + else if (!strncmp("xglDbgUnregisterMsgCallback", (const char *) pName, sizeof ("xglDbgUnregisterMsgCallback"))) + return disp_table->DbgUnregisterMsgCallback; + else if (!strncmp("xglDbgSetMessageFilter", (const char *) pName, sizeof ("xglDbgSetMessageFilter"))) + return disp_table->DbgSetMessageFilter; + else if (!strncmp("xglDbgSetObjectTag", (const char *) pName, sizeof ("xglDbgSetObjectTag"))) + return disp_table->DbgSetObjectTag; + else if (!strncmp("xglDbgSetGlobalOption", (const char *) pName, sizeof ("xglDbgSetGlobalOption"))) + return disp_table->DbgSetGlobalOption; + else if (!strncmp("xglDbgSetDeviceOption", (const char *) pName, sizeof ("xglDbgSetDeviceOption"))) + return disp_table->DbgSetDeviceOption; + else if (!strncmp("xglCmdDbgMarkerBegin", (const char *) pName, sizeof ("xglCmdDbgMarkerBegin"))) + return disp_table->CmdDbgMarkerBegin; + else if (!strncmp("xglCmdDbgMarkerEnd", (const char *) pName, sizeof ("xglCmdDbgMarkerEnd"))) + return disp_table->CmdDbgMarkerEnd; + else if (!strncmp("xglWsiX11AssociateConnection", (const char *) pName, sizeof("xglWsiX11AssociateConnection"))) + return disp_table->WsiX11AssociateConnection; + else if (!strncmp("xglWsiX11GetMSC", (const char *) pName, sizeof("xglWsiX11GetMSC"))) + return disp_table->WsiX11GetMSC; + else if (!strncmp("xglWsiX11CreatePresentableImage", (const char *) pName, sizeof("xglWsiX11CreatePresentableImage"))) + return disp_table->WsiX11CreatePresentableImage; + else if (!strncmp("xglWsiX11QueuePresent", (const char *) pName, sizeof("xglWsiX11QueuePresent"))) + return disp_table->WsiX11QueuePresent; + else { + XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu; + if (gpuw->pGPA == NULL) + return NULL; + return gpuw->pGPA(gpuw->nextObject, pName); + } +} + LOADER_EXPORT XGL_RESULT XGLAPI xglInitAndEnumerateGpus(const XGL_APPLICATION_INFO* pAppInfo, const XGL_ALLOC_CALLBACKS* pAllocCb, XGL_UINT maxGpus, XGL_UINT* pGpuCount, XGL_PHYSICAL_GPU* pGpus) { static pthread_once_t once = PTHREAD_ONCE_INIT; @@ -366,6 +971,8 @@ LOADER_EXPORT XGL_RESULT XGLAPI xglInitAndEnumerateGpus(const XGL_APPLICATION_IN icd = loader.icds; while (icd) { XGL_PHYSICAL_GPU gpus[XGL_MAX_PHYSICAL_GPUS]; + XGL_BASE_LAYER_OBJECT * wrappedGpus; + GetProcAddrType getProcAddr = icd->GetProcAddr; XGL_UINT n, max = maxGpus - count; if (max > XGL_MAX_PHYSICAL_GPUS) { @@ -374,7 +981,18 @@ LOADER_EXPORT XGL_RESULT XGLAPI xglInitAndEnumerateGpus(const XGL_APPLICATION_IN res = icd->InitAndEnumerateGpus(pAppInfo, pAllocCb, max, &n, gpus); if (res == XGL_SUCCESS && n) { - memcpy(pGpus + count, gpus, sizeof(*pGpus) * n); + wrappedGpus = (XGL_BASE_LAYER_OBJECT*) malloc(n * sizeof(XGL_BASE_LAYER_OBJECT)); + loader.loader_dispatch = (XGL_LAYER_DISPATCH_TABLE *) malloc(n * sizeof(XGL_LAYER_DISPATCH_TABLE)); + for (int i = 0; i < n; i++) { + (wrappedGpus + i)->baseObject = gpus[i]; + (wrappedGpus + i)->pGPA = getProcAddr; //loader.loader_dispatch + i; //getProcAddr; + (wrappedGpus + i)->nextObject = gpus[i]; + memcpy(pGpus + count, &wrappedGpus, sizeof(*pGpus)); + init_dispatch_table(loader.loader_dispatch + i, getProcAddr, wrappedGpus + i); + const XGL_LAYER_DISPATCH_TABLE * *disp = (const XGL_LAYER_DISPATCH_TABLE * *) gpus[i]; + *disp = loader.loader_dispatch + i; + } + count += n; if (count >= maxGpus) { @@ -385,6 +1003,10 @@ LOADER_EXPORT XGL_RESULT XGLAPI xglInitAndEnumerateGpus(const XGL_APPLICATION_IN icd = icd->next; } + /* get layer libraries */ + if (!loader.layer_scaned) + layer_lib_scan(NULL, true, false); + *pGpuCount = count; return (count > 0) ? XGL_SUCCESS : res; diff --git a/loader/loader.h b/loader/loader.h index b76f6344..d8191421 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -31,7 +31,7 @@ #include #include #include - +#include #if defined(__GNUC__) && __GNUC__ >= 4 # define LOADER_EXPORT __attribute__((visibility("default"))) #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590) @@ -40,4 +40,6 @@ # define LOADER_EXPORT #endif +extern XGL_UINT ActivateLayers(XGL_PHYSICAL_GPU *gpu); +#define MAX_LAYER_LIBRARIES 16 #endif /* LOADER_H */ diff --git a/xgl-generate.py b/xgl-generate.py index 900f50cd..6e790d8a 100755 --- a/xgl-generate.py +++ b/xgl-generate.py @@ -108,36 +108,149 @@ class Subcommand(object): %s; };""" % ";\n ".join(entries) - def _generate_icd_dispatch_entrypoints(self, qual=""): + def _generate_dispatch_entrypoints(self, qual="", unwrap=False, layer=False): if qual: qual += " " funcs = [] for proto in self.protos: - if not xgl.is_dispatchable(proto): - continue - - decl = proto.c_func(prefix="xgl", attr="XGLAPI") - stmt = "(*disp)->%s" % proto.c_call() - if proto.ret != "XGL_VOID": - stmt = "return " + stmt - - funcs.append("%s%s\n" - "{\n" - " const struct icd_dispatch_table * const *disp =\n" - " (const struct icd_dispatch_table * const *) %s;\n" - " %s;\n" - "}" % (qual, decl, proto.params[0].name, stmt)) + if not layer: + if not xgl.is_dispatchable(proto): + continue + decl = proto.c_func(prefix="xgl", attr="XGLAPI") + stmt = "(*disp)->%s" % proto.c_call() + if proto.ret != "XGL_VOID": + stmt = "return " + stmt + if proto.name == "CreateDevice" and qual == "LOADER_EXPORT ": + stmt_cd = "XGL_RESULT res = " + "(*disp)->%s" % proto.c_call() + funcs.append("%s%s\n" + "{\n" + " ActivateLayers(&%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" + " const XGL_LAYER_DISPATCH_TABLE * *disp_dev = (const XGL_LAYER_DISPATCH_TABLE * *) *%s;\n" + " *disp_dev = (const XGL_LAYER_DISPATCH_TABLE *) *disp;\n" + " return res;\n" + "}" % (qual, decl, proto.params[0].name, proto.params[0].name, proto.params[0].name, stmt_cd, proto.params[2].name)) + elif proto.params[0].ty != "XGL_PHYSICAL_GPU": + funcs.append("%s%s\n" + "{\n" + " const XGL_LAYER_DISPATCH_TABLE * const *disp =\n" + " (const XGL_LAYER_DISPATCH_TABLE * const *) %s;\n" + " %s;\n" + "}" % (qual, decl, proto.params[0].name, stmt)) + else: + funcs.append("%s%s\n" + "{\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, stmt)) + elif proto.name != "GetProcAddr": + decl = proto.c_func(prefix="xgl", attr="XGLAPI") + param0_name = proto.params[0].name + ret_val = '' + stmt = '' + if proto.ret != "XGL_VOID": + ret_val = "XGL_RESULT result = " + stmt = " return result;\n" + if proto.params[0].ty != "XGL_PHYSICAL_GPU": + funcs.append('%s%s\n' + '{\n' + ' %snextTable.%s;\n' + '%s' + '}' % (qual, decl, ret_val, proto.c_call(), stmt)) + else: + c_call = proto.c_call().replace("(" + proto.params[0].name, "((XGL_PHYSICAL_GPU)gpuw->nextObject", 1) + funcs.append('%s%s\n' + '{\n' + ' XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) %s;\n' + ' printf("At start of layered %s\\n");\n' + ' pCurObj = gpuw;\n' + ' pthread_once(&tabOnce, initLayerTable);\n' + ' %snextTable.%s;\n' + ' printf("Completed layered %s\\n");\n' + '%s' + '}' % (qual, decl, proto.params[0].name, proto.name, ret_val, c_call, proto.name, stmt)) return "\n\n".join(funcs) + def _generate_layer_gpa_function(self, prefix="xgl"): + func_body = [] + func_body.append("XGL_LAYER_EXPORT XGL_VOID* XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const XGL_CHAR* funcName)\n" + "{\n" + " XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;\n" + " if (gpu == NULL)\n" + " return NULL;\n" + " pCurObj = gpuw;\n" + " pthread_once(&tabOnce, initLayerTable);\n\n" + ' if (!strncmp("xglGetProcAddr", (const char *) funcName, sizeof("xglGetProcAddr")))\n' + ' return xglGetProcAddr;') + for name in xgl.icd_dispatch_table: + if name == "GetProcAddr": + continue + func_body.append(' else if (!strncmp("%s%s", (const char *) funcName, sizeof("%s%s")))\n' + ' return %s%s;' % (prefix, name, prefix, name, prefix, name)) + func_body.append(" else {\n" + " XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;\n" + " if (gpuw->pGPA == NULL)\n" + " return NULL;\n" + " return gpuw->pGPA(gpuw->nextObject, funcName);\n" + " }\n" + "}\n") + return "\n".join(func_body) + + def _generate_layer_dispatch_table(self, prefix='xgl'): + func_body = [] + func_body.append('static void initLayerTable()\n' + '{\n' + ' GetProcAddrType fpNextGPA;\n' + ' fpNextGPA = pCurObj->pGPA;\n' + ' assert(fpNextGPA);\n'); + + for name in xgl.icd_dispatch_table: + func_body.append(' %sType fp%s = fpNextGPA((XGL_PHYSICAL_GPU) pCurObj->nextObject, (XGL_CHAR *) "%s%s");\n' + ' nextTable.%s = fp%s;' % (name, name, prefix, name, name, name)) + + func_body.append("}\n") + return "\n".join(func_body) + class LoaderSubcommand(Subcommand): def generate_header(self): return "#include \"loader.h\"" def generate_body(self): - body = [self._generate_icd_dispatch_table(), - self._generate_icd_dispatch_entrypoints("LOADER_EXPORT")] + body = [self._generate_dispatch_entrypoints("LOADER_EXPORT")] + + return "\n\n".join(body) + +class LayerFuncsSubcommand(Subcommand): + def generate_header(self): + return '#include \n#include "loader.h"' + + def generate_body(self): + return self._generate_dispatch_entrypoints("static", True) + +class LayerDispatchSubcommand(Subcommand): + def generate_header(self): + return '#include "layer_wrappers.h"' + + def generate_body(self): + return self._generate_layer_dispatch_table() + +class GenericLayerSubcommand(Subcommand): + def generate_header(self): + return '#include \n#include \n#include \n#include \n#include \n#include "xglLayer.h"\n\nstatic XGL_LAYER_DISPATCH_TABLE nextTable;\nstatic XGL_BASE_LAYER_OBJECT *pCurObj;\nstatic pthread_once_t tabOnce = PTHREAD_ONCE_INIT;\n' + + def generate_body(self): + body = [self._generate_layer_dispatch_table(), + self._generate_dispatch_entrypoints("XGL_LAYER_EXPORT", True, True), + self._generate_layer_gpa_function()] return "\n\n".join(body) @@ -150,7 +263,7 @@ class IcdDispatchEntrypointsSubcommand(Subcommand): return "#include \"icd.h\"" def generate_body(self): - return self._generate_icd_dispatch_entrypoints("ICD_EXPORT") + return self._generate_dispatch_entrypoints("ICD_EXPORT") class IcdDispatchDummyImplSubcommand(Subcommand): def run(self): @@ -224,6 +337,9 @@ const struct icd_dispatch_table %s_debug_dispatch_table = { def main(): subcommands = { "loader": LoaderSubcommand, + "layer-funcs" : LayerFuncsSubcommand, + "layer-dispatch" : LayerDispatchSubcommand, + "generic-layer" : GenericLayerSubcommand, "icd-dispatch-table": IcdDispatchTableSubcommand, "icd-dispatch-entrypoints": IcdDispatchEntrypointsSubcommand, "icd-dispatch-dummy-impl": IcdDispatchDummyImplSubcommand, diff --git a/xgl.py b/xgl.py index 62ae0fb8..6f2b7387 100644 --- a/xgl.py +++ b/xgl.py @@ -87,6 +87,10 @@ class Proto(object): # XGL core API core = ( + Proto("void *", "GetProcAddr", + (Param("XGL_PHYSICAL_GPU", "gpu"), + Param("const XGL_CHAR*", "pName"))), + Proto("XGL_RESULT", "InitAndEnumerateGpus", (Param("const XGL_APPLICATION_INFO*", "pAppInfo"), Param("const XGL_ALLOC_CALLBACKS*", "pAllocCb"), @@ -726,6 +730,7 @@ ext_wsi_x11_headers = ("xglWsiX11Ext.h",) # XXX figure out the real order # XXX this is not extensible icd_dispatch_table = ( + "GetProcAddr", "InitAndEnumerateGpus", "GetGpuInfo", "CreateDevice", @@ -847,14 +852,18 @@ icd_dispatch_table = ( "WsiX11QueuePresent", ) +def is_name_dispatchable(name): + return name not in ( + "GetProcAddr", + "InitAndEnumerateGpus", + "DbgRegisterMsgCallback", + "DbgUnregisterMsgCallback", + "DbgSetGlobalOption") + def is_dispatchable(proto): """Return true if the prototype is dispatchable. That is, return true when the prototype takes a XGL_PHYSICAL_GPU or XGL_BASE_OBJECT. """ - return proto.name not in ( - "InitAndEnumerateGpus", - "DbgRegisterMsgCallback", - "DbgUnregisterMsgCallback", - "DbgSetGlobalOption") + return is_name_dispatchable(proto.name)