diff options
| author | Jon Ashburn <jon@lunarg.com> | 2015-04-10 14:33:07 -0600 |
|---|---|---|
| committer | Chia-I Wu <olv@lunarg.com> | 2015-04-16 17:48:19 +0800 |
| commit | c1f104a68debb061464d7cac76aadfbfd05067f4 (patch) | |
| tree | b276c92baf2ccd170c86dd80d7e14f72cd097403 | |
| parent | 23e038d6ddc4b30ea889ea5ffa3fb068783f8540 (diff) | |
| download | usermoji-c1f104a68debb061464d7cac76aadfbfd05067f4.tar.xz | |
vulkan: Add vkGetGlobalExtensionInfo entrypoint
have loader use it to enumerate all extensions from layers and drivers.
Non-gode_gen layers also updated to include vkGetGlobalExtensionInfo
Includes verion info as part of GetExtensionSupport return data.
TODO: vk-layer-generate needs work
v2: do not check for non-existing ENABLE_WSI_X11 (olv)
| -rw-r--r-- | icd/nulldrv/VK_nulldrv.def | 1 | ||||
| -rw-r--r-- | icd/nulldrv/nulldrv.c | 35 | ||||
| -rw-r--r-- | include/vkLayer.h | 1 | ||||
| -rw-r--r-- | include/vulkan.h | 22 | ||||
| -rw-r--r-- | layers/basic.cpp | 53 | ||||
| -rw-r--r-- | layers/draw_state.cpp | 52 | ||||
| -rw-r--r-- | layers/mem_tracker.cpp | 52 | ||||
| -rw-r--r-- | layers/multi.cpp | 54 | ||||
| -rw-r--r-- | layers/param_checker.cpp | 53 | ||||
| -rw-r--r-- | loader/loader.c | 392 | ||||
| -rwxr-xr-x | vk-generate.py | 27 | ||||
| -rwxr-xr-x | vk-layer-generate.py | 124 | ||||
| -rwxr-xr-x | vulkan.py | 7 |
13 files changed, 725 insertions, 148 deletions
diff --git a/icd/nulldrv/VK_nulldrv.def b/icd/nulldrv/VK_nulldrv.def index 792fe6dd..a2d0167d 100644 --- a/icd/nulldrv/VK_nulldrv.def +++ b/icd/nulldrv/VK_nulldrv.def @@ -30,6 +30,7 @@ EXPORTS vkCreateInstance vkEnumerateGpus vkDestroyInstance + vkGetGlobalExtensionInfo xcbCreateWindow xcbDestroyWindow xcbGetMessage diff --git a/icd/nulldrv/nulldrv.c b/icd/nulldrv/nulldrv.c index 4d72b511..5dc99de6 100644 --- a/icd/nulldrv/nulldrv.c +++ b/icd/nulldrv/nulldrv.c @@ -1353,8 +1353,41 @@ ICD_EXPORT VkResult VKAPI vkGetGpuInfo( return VK_SUCCESS; } +ICD_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( + VkExtensionInfoType infoType, + uint32_t extensionIndex, + size_t* pDataSize, + void* pData) +{ + uint32_t *count; + + if (pDataSize == NULL) + return VK_ERROR_INVALID_POINTER; + + switch (infoType) { + case VK_EXTENSION_INFO_TYPE_COUNT: + *pDataSize = sizeof(uint32_t); + if (pData == NULL) + return VK_SUCCESS; + count = (uint32_t *) pData; + *count = 0; + break; + case VK_EXTENSION_INFO_TYPE_PROPERTIES: + *pDataSize = 0; + if (pData == NULL) + return VK_SUCCESS; + else + return VK_ERROR_INVALID_EXTENSION; + break; + default: + return VK_ERROR_INVALID_VALUE; + }; + + return VK_SUCCESS; +} + ICD_EXPORT VkResult VKAPI vkGetExtensionSupport( - VkPhysicalGpu gpu_, + VkPhysicalGpu gpu_, const char* pExtName) { NULLDRV_LOG_FUNC; diff --git a/include/vkLayer.h b/include/vkLayer.h index 97c9b375..e58ccdcd 100644 --- a/include/vkLayer.h +++ b/include/vkLayer.h @@ -34,6 +34,7 @@ typedef struct VkLayerDispatchTable_ PFN_vkGetGpuInfo GetGpuInfo; PFN_vkCreateDevice CreateDevice; PFN_vkDestroyDevice DestroyDevice; + PFN_vkGetGlobalExtensionInfo GetGlobalExtensionInfo; PFN_vkGetExtensionSupport GetExtensionSupport; PFN_vkEnumerateLayers EnumerateLayers; PFN_vkGetDeviceQueue GetDeviceQueue; diff --git a/include/vulkan.h b/include/vulkan.h index bf581f25..0c85cb18 100644 --- a/include/vulkan.h +++ b/include/vulkan.h @@ -89,6 +89,7 @@ VK_DEFINE_SUBCLASS_HANDLE(VkRenderPass, VkObject) #define VK_MAX_PHYSICAL_GPUS 16 #define VK_MAX_PHYSICAL_GPU_NAME 256 +#define VK_MAX_EXTENSION_NAME 256 #define VK_LOD_CLAMP_NONE MAX_FLOAT #define VK_LAST_MIP_OR_SLICE 0xffffffff @@ -670,6 +671,15 @@ typedef enum VkPhysicalGpuInfoType_ VK_MAX_ENUM(VkPhysicalGpuInfoType) } VkPhysicalGpuInfoType; +typedef enum VkExtensionInfoType_ +{ + // Info type for vkGetGlobalExtensionInfo() and vkGetPhysicalDeviceExtensionInfo() + VK_EXTENSION_INFO_TYPE_COUNT = 0x00000000, + VK_EXTENSION_INFO_TYPE_PROPERTIES = 0x00000001, + + //VK_ENUM_RANGE(EXTENSION_INFO_TYPE, COUNT, PROPERTIES) +} VkExtensionInfoType; + typedef enum VkFormatInfoType_ { // Info type for vkGetFormatInfo() @@ -1369,6 +1379,12 @@ typedef struct VkGpuCompatibilityInfo_ VkFlags compatibilityFlags; // VkGpuCompatibilityFlags } VkGpuCompatibilityInfo; +typedef struct VkExtensionProperties_ +{ + char extName[VK_MAX_EXTENSION_NAME]; // extension name + uint32_t version; // version of the extension specification +} VkExtensionProperties; + typedef struct VkApplicationInfo_ { VkStructureType sType; // Type of structure. Should be VK_STRUCTURE_TYPE_APPLICATION_INFO @@ -2274,6 +2290,7 @@ typedef VkResult (VKAPI *PFN_vkGetGpuInfo)(VkPhysicalGpu gpu, VkPhysicalGpuInfoT typedef void * (VKAPI *PFN_vkGetProcAddr)(VkPhysicalGpu gpu, const char * pName); typedef VkResult (VKAPI *PFN_vkCreateDevice)(VkPhysicalGpu gpu, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice); typedef VkResult (VKAPI *PFN_vkDestroyDevice)(VkDevice device); +typedef VkResult (VKAPI *PFN_vkGetGlobalExtensionInfo)(VkExtensionInfoType infoType, uint32_t extensionIndex, size_t* pDataSize, void* pData); typedef VkResult (VKAPI *PFN_vkGetExtensionSupport)(VkPhysicalGpu gpu, const char* pExtName); typedef VkResult (VKAPI *PFN_vkEnumerateLayers)(VkPhysicalGpu gpu, size_t maxLayerCount, size_t maxStringSize, size_t* pOutLayerCount, char* const* pOutLayers, void* pReserved); typedef VkResult (VKAPI *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue* pQueue); @@ -2420,6 +2437,11 @@ VkResult VKAPI vkDestroyDevice( VkDevice device); // Extension discovery functions +VkResult VKAPI vkGetGlobalExtensionInfo( + VkExtensionInfoType infoType, + uint32_t extensionIndex, + size_t* pDataSize, + void* pData); VkResult VKAPI vkGetExtensionSupport( VkPhysicalGpu gpu, diff --git a/layers/basic.cpp b/layers/basic.cpp index 524bd40f..d82c6c5e 100644 --- a/layers/basic.cpp +++ b/layers/basic.cpp @@ -61,6 +61,59 @@ VK_LAYER_EXPORT VkResult VKAPI vkLayerExtension1(VkDevice device) return VK_SUCCESS; } +struct extProps { + uint32_t version; + const char * const name; +}; +#define BASIC_LAYER_EXT_ARRAY_SIZE 2 +static const struct extProps basicExts[BASIC_LAYER_EXT_ARRAY_SIZE] = { + // TODO what is the version? + 0x10, "Basic", + 0x10, "vkLayerExtension1" +}; + +VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( + VkExtensionInfoType infoType, + uint32_t extensionIndex, + size_t* pDataSize, + void* pData) +{ + VkResult result; + + /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */ + VkExtensionProperties *ext_props; + uint32_t *count; + + if (pDataSize == NULL) + return VK_ERROR_INVALID_POINTER; + + switch (infoType) { + case VK_EXTENSION_INFO_TYPE_COUNT: + *pDataSize = sizeof(uint32_t); + if (pData == NULL) + return VK_SUCCESS; + count = (uint32_t *) pData; + *count = BASIC_LAYER_EXT_ARRAY_SIZE; + break; + case VK_EXTENSION_INFO_TYPE_PROPERTIES: + *pDataSize = sizeof(VkExtensionProperties); + if (pData == NULL) + return VK_SUCCESS; + if (extensionIndex >= BASIC_LAYER_EXT_ARRAY_SIZE) + return VK_ERROR_INVALID_VALUE; + ext_props = (VkExtensionProperties *) pData; + ext_props->version = basicExts[extensionIndex].version; + strncpy(ext_props->extName, basicExts[extensionIndex].name, + VK_MAX_EXTENSION_NAME); + ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0'; + break; + default: + return VK_ERROR_INVALID_VALUE; + }; + + return VK_SUCCESS; +} + VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName) { VkResult result; diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp index 58db6327..e74fa18e 100644 --- a/layers/draw_state.cpp +++ b/layers/draw_state.cpp @@ -1466,6 +1466,58 @@ VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device) return result; } +struct extProps { + uint32_t version; + const char * const name; +}; +#define DRAW_STATE_LAYER_EXT_ARRAY_SIZE 1 +static const struct extProps dsExts[DRAW_STATE_LAYER_EXT_ARRAY_SIZE] = { + // TODO what is the version? + 0x10, "DrawState" +}; + +VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( + VkExtensionInfoType infoType, + uint32_t extensionIndex, + size_t* pDataSize, + void* pData) +{ + VkResult result; + + /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */ + VkExtensionProperties *ext_props; + uint32_t *count; + + if (pDataSize == NULL) + return VK_ERROR_INVALID_POINTER; + + switch (infoType) { + case VK_EXTENSION_INFO_TYPE_COUNT: + *pDataSize = sizeof(uint32_t); + if (pData == NULL) + return VK_SUCCESS; + count = (uint32_t *) pData; + *count = DRAW_STATE_LAYER_EXT_ARRAY_SIZE; + break; + case VK_EXTENSION_INFO_TYPE_PROPERTIES: + *pDataSize = sizeof(VkExtensionProperties); + if (pData == NULL) + return VK_SUCCESS; + if (extensionIndex >= DRAW_STATE_LAYER_EXT_ARRAY_SIZE) + return VK_ERROR_INVALID_VALUE; + ext_props = (VkExtensionProperties *) pData; + ext_props->version = dsExts[extensionIndex].version; + strncpy(ext_props->extName, dsExts[extensionIndex].name, + VK_MAX_EXTENSION_NAME); + ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0'; + break; + default: + return VK_ERROR_INVALID_VALUE; + }; + + return VK_SUCCESS; +} + VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName) { VkResult result; diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp index 86fd02dc..e7f1f7eb 100644 --- a/layers/mem_tracker.cpp +++ b/layers/mem_tracker.cpp @@ -864,6 +864,58 @@ VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device) return result; } +struct extProps { + uint32_t version; + const char * const name; +}; +#define MEM_TRACKER_LAYER_EXT_ARRAY_SIZE 1 +static const struct extProps mtExts[MEM_TRACKER_LAYER_EXT_ARRAY_SIZE] = { + // TODO what is the version? + 0x10, "MemTracker" +}; + +VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( + VkExtensionInfoType infoType, + uint32_t extensionIndex, + size_t* pDataSize, + void* pData) +{ + VkResult result; + + /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */ + VkExtensionProperties *ext_props; + uint32_t *count; + + if (pDataSize == NULL) + return VK_ERROR_INVALID_POINTER; + + switch (infoType) { + case VK_EXTENSION_INFO_TYPE_COUNT: + *pDataSize = sizeof(uint32_t); + if (pData == NULL) + return VK_SUCCESS; + count = (uint32_t *) pData; + *count = MEM_TRACKER_LAYER_EXT_ARRAY_SIZE; + break; + case VK_EXTENSION_INFO_TYPE_PROPERTIES: + *pDataSize = sizeof(VkExtensionProperties); + if (pData == NULL) + return VK_SUCCESS; + if (extensionIndex >= MEM_TRACKER_LAYER_EXT_ARRAY_SIZE) + return VK_ERROR_INVALID_VALUE; + ext_props = (VkExtensionProperties *) pData; + ext_props->version = mtExts[extensionIndex].version; + strncpy(ext_props->extName, mtExts[extensionIndex].name, + VK_MAX_EXTENSION_NAME); + ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0'; + break; + default: + return VK_ERROR_INVALID_VALUE; + }; + + return VK_SUCCESS; +} + VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName) { VkResult result; diff --git a/layers/multi.cpp b/layers/multi.cpp index 910bc5bb..c5906203 100644 --- a/layers/multi.cpp +++ b/layers/multi.cpp @@ -283,6 +283,60 @@ VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalGpu gpu, size_t maxLa return VK_SUCCESS; } +struct extProps { + uint32_t version; + const char * const name; +}; + +#define MULTI_LAYER_EXT_ARRAY_SIZE 2 +static const struct extProps multiExts[MULTI_LAYER_EXT_ARRAY_SIZE] = { + // TODO what is the version? + 0x10, "multi1", + 0x10, "multi2", +}; + +VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( + VkExtensionInfoType infoType, + uint32_t extensionIndex, + size_t* pDataSize, + void* pData) +{ + VkResult result; + + /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */ + VkExtensionProperties *ext_props; + uint32_t *count; + + if (pDataSize == NULL) + return VK_ERROR_INVALID_POINTER; + + switch (infoType) { + case VK_EXTENSION_INFO_TYPE_COUNT: + *pDataSize = sizeof(uint32_t); + if (pData == NULL) + return VK_SUCCESS; + count = (uint32_t *) pData; + *count = MULTI_LAYER_EXT_ARRAY_SIZE; + break; + case VK_EXTENSION_INFO_TYPE_PROPERTIES: + *pDataSize = sizeof(VkExtensionProperties); + if (pData == NULL) + return VK_SUCCESS; + if (extensionIndex >= MULTI_LAYER_EXT_ARRAY_SIZE) + return VK_ERROR_INVALID_VALUE; + ext_props = (VkExtensionProperties *) pData; + ext_props->version = multiExts[extensionIndex].version; + strncpy(ext_props->extName, multiExts[extensionIndex].name, + VK_MAX_EXTENSION_NAME); + ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0'; + break; + default: + return VK_ERROR_INVALID_VALUE; + }; + + return VK_SUCCESS; +} + VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName) { VkResult result; diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp index 5687a543..e7c7e63b 100644 --- a/layers/param_checker.cpp +++ b/layers/param_checker.cpp @@ -257,6 +257,59 @@ VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device) return result; } +struct extProps { + uint32_t version; + const char * const name; +}; + +#define PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE 1 +static const struct extProps pcExts[PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE] = { + // TODO what is the version? + 0x10, "ParamChecker", +}; + +VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( + VkExtensionInfoType infoType, + uint32_t extensionIndex, + size_t* pDataSize, + void* pData) +{ + VkResult result; + + /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */ + VkExtensionProperties *ext_props; + uint32_t *count; + + if (pDataSize == NULL) + return VK_ERROR_INVALID_POINTER; + + switch (infoType) { + case VK_EXTENSION_INFO_TYPE_COUNT: + *pDataSize = sizeof(uint32_t); + if (pData == NULL) + return VK_SUCCESS; + count = (uint32_t *) pData; + *count = PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE; + break; + case VK_EXTENSION_INFO_TYPE_PROPERTIES: + *pDataSize = sizeof(VkExtensionProperties); + if (pData == NULL) + return VK_SUCCESS; + if (extensionIndex >= PARAM_CHECKER_LAYER_EXT_ARRAY_SIZE) + return VK_ERROR_INVALID_VALUE; + ext_props = (VkExtensionProperties *) pData; + ext_props->version = pcExts[extensionIndex].version; + strncpy(ext_props->extName, pcExts[extensionIndex].name, + VK_MAX_EXTENSION_NAME); + ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0'; + break; + default: + return VK_ERROR_INVALID_VALUE; + }; + + return VK_SUCCESS; +} + VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName) { pCurObj = (VkBaseLayerObject *) gpu; diff --git a/loader/loader.c b/loader/loader.c index dc053761..3ce99f01 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -58,6 +58,12 @@ struct layer_name_pair { const char *lib_name; }; +struct extension_property { + char extName[VK_MAX_EXTENSION_NAME]; + uint32_t version; + bool hosted; // does the extension reside in one driver/layer +}; + struct loader_icd { const struct loader_scanned_icds *scanned_icds; @@ -74,15 +80,23 @@ struct loader_icd { struct loader_scanned_icds { loader_platform_dl_handle handle; + PFN_vkGetProcAddr GetProcAddr; PFN_vkCreateInstance CreateInstance; PFN_vkDestroyInstance DestroyInstance; PFN_vkEnumerateGpus EnumerateGpus; - PFN_vkGetExtensionSupport GetExtensionSupport; + PFN_vkGetGlobalExtensionInfo GetGlobalExtensionInfo; VkInstance instance; struct loader_scanned_icds *next; + uint32_t extension_count; + struct extension_property *extensions; }; +struct loader_scanned_layers { + char *name; + uint32_t extension_count; + struct extension_property *extensions; +}; // Note: Since the following is a static structure, all members are initialized // to zero. static struct { @@ -92,9 +106,15 @@ static struct { bool layer_scanned; char *layer_dirs; unsigned int scanned_layer_count; - char *scanned_layer_names[MAX_LAYER_LIBRARIES]; + struct loader_scanned_layers scanned_layers[MAX_LAYER_LIBRARIES]; + size_t scanned_ext_list_capacity; + uint32_t scanned_ext_list_count; // coalesced from all layers/drivers + struct extension_property **scanned_ext_list; } loader; +static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_icd); +static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_layer); +static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_exts); #if defined(WIN32) char *loader_get_registry_string(const HKEY hive, @@ -216,15 +236,145 @@ static void loader_log(VK_DBG_MSG_TYPE msg_type, int32_t msg_code, fputc('\n', stderr); } -static void -loader_icd_destroy(struct loader_icd *icd) +static bool has_extension(struct extension_property *exts, uint32_t count, + const char *name, bool must_be_hosted) +{ + uint32_t i; + for (i = 0; i < count; i++) { + if (!strcmp(name, exts[i].extName) && (!must_be_hosted || exts[i].hosted)) + return true; + } + return false; +} + +static void get_global_extensions(PFN_vkGetGlobalExtensionInfo fp_get, + uint32_t *count_out, + struct extension_property **props_out) +{ + uint32_t i, count, cur; + size_t siz = sizeof(count); + struct extension_property *ext_props; + VkExtensionProperties vk_prop; + VkResult res; + + *count_out = 0; + *props_out = NULL; + res = fp_get(VK_EXTENSION_INFO_TYPE_COUNT, 0, &siz, &count); + if (res != VK_SUCCESS) { + loader_log(VK_DBG_MSG_WARNING, 0, "Error getting global extension count from ICD"); + return; + } + ext_props = (struct extension_property *) malloc(sizeof(struct extension_property) * count); + if (ext_props == NULL) { + loader_log(VK_DBG_MSG_WARNING, 0, "Out of memory didn't get global extensions from ICD"); + return; + } + siz = sizeof(VkExtensionProperties); + cur = 0; + for (i = 0; i < count; i++) { + res = fp_get(VK_EXTENSION_INFO_TYPE_PROPERTIES, i, &siz, &vk_prop); + if (res == VK_SUCCESS) { + (ext_props + cur)->hosted = false; + (ext_props + cur)->version = vk_prop.version; + strncpy((ext_props + cur)->extName, vk_prop.extName, VK_MAX_EXTENSION_NAME); + (ext_props + cur)->extName[VK_MAX_EXTENSION_NAME - 1] = '\0'; + cur++; + } + *count_out = cur; + *props_out = ext_props; + } + return; +} + +static void loader_init_ext_list() +{ + loader.scanned_ext_list_capacity = 256 * sizeof(struct extension_property *); + loader.scanned_ext_list = malloc(loader.scanned_ext_list_capacity); + memset(loader.scanned_ext_list, 0, loader.scanned_ext_list_capacity); + loader.scanned_ext_list_count = 0; +} + +#if 0 // currently no place to call this +static void loader_destroy_ext_list() +{ + free(loader.scanned_ext_list); + loader.scanned_ext_list_capacity = 0; + loader.scanned_ext_list_count = 0; +} +#endif + +static void loader_add_to_ext_list(uint32_t count, + struct extension_property *prop_list) +{ + uint32_t i, j; + bool duplicate; + struct extension_property *cur_ext; + + if (loader.scanned_ext_list == NULL || loader.scanned_ext_list_capacity == 0) + loader_init_ext_list(); + + if (loader.scanned_ext_list == NULL) + return; + + struct extension_property *ext_list, **ext_list_addr; + + for (i = 0; i < count; i++) { + cur_ext = prop_list + i; + + // look for duplicates or not + duplicate = false; + for (j = 0; j < loader.scanned_ext_list_count; j++) { + ext_list = loader.scanned_ext_list[j]; + if (!strcmp(cur_ext->extName, ext_list->extName)) { + duplicate = true; + ext_list->hosted = false; + break; + } + } + + // add to list at end + if (!duplicate) { + // check for enough capacity + if (loader.scanned_ext_list_count * sizeof(struct extension_property *) + >= loader.scanned_ext_list_capacity) { + // double capacity + loader.scanned_ext_list_capacity *= 2; + loader.scanned_ext_list = realloc(loader.scanned_ext_list, + loader.scanned_ext_list_capacity); + } + ext_list_addr = &(loader.scanned_ext_list[loader.scanned_ext_list_count++]); + *ext_list_addr = cur_ext; + cur_ext->hosted = true; + } + + } +} + +static void loader_coalesce_extensions() +{ + uint32_t i; + struct loader_scanned_icds *icd_list = loader.scanned_icd_list; + + // traverse scanned icd list adding non-duplicate extensions to the list + while (icd_list != NULL) { + loader_add_to_ext_list(icd_list->extension_count, icd_list->extensions); + icd_list = icd_list->next; + }; + + //Traverse layers list adding non-duplicate extensions to the list + for (i = 0; i < loader.scanned_layer_count; i++) { + loader_add_to_ext_list(loader.scanned_layers[i].extension_count, + loader.scanned_layers[i].extensions); + } +} + +static void loader_icd_destroy(struct loader_icd *icd) { loader_platform_close_library(icd->scanned_icds->handle); free(icd); } -static struct loader_icd * -loader_icd_create(const struct loader_scanned_icds *scanned) +static struct loader_icd * loader_icd_create(const struct loader_scanned_icds *scanned) { struct loader_icd *icd; @@ -258,7 +408,8 @@ static struct loader_icd *loader_icd_add(struct loader_instance *ptr_inst, static void loader_scanned_icd_add(const char *filename) { loader_platform_dl_handle handle; - void *fp_gpa, *fp_enumerate, *fp_create_inst, *fp_destroy_inst, *fp_get_extension_support; + void *fp_gpa, *fp_enumerate, *fp_create_inst, *fp_destroy_inst; + void *fp_get_global_ext_info; struct loader_scanned_icds *new_node; // Used to call: dlopen(filename, RTLD_LAZY); @@ -280,7 +431,7 @@ static void loader_scanned_icd_add(const char *filename) LOOKUP(fp_create_inst, CreateInstance); LOOKUP(fp_destroy_inst, DestroyInstance); LOOKUP(fp_enumerate, EnumerateGpus); - LOOKUP(fp_get_extension_support, GetExtensionSupport); + LOOKUP(fp_get_global_ext_info, GetGlobalExtensionInfo); #undef LOOKUP new_node = (struct loader_scanned_icds *) malloc(sizeof(struct loader_scanned_icds)); @@ -294,11 +445,21 @@ static void loader_scanned_icd_add(const char *filename) new_node->CreateInstance = fp_create_inst; new_node->DestroyInstance = fp_destroy_inst; new_node->EnumerateGpus = fp_enumerate; - new_node->GetExtensionSupport = fp_get_extension_support; + new_node->GetGlobalExtensionInfo = fp_get_global_ext_info; + new_node->extension_count = 0; + new_node->extensions = NULL; new_node->next = loader.scanned_icd_list; + loader.scanned_icd_list = new_node; -} + if (fp_get_global_ext_info) { + get_global_extensions((PFN_vkGetGlobalExtensionInfo) fp_get_global_ext_info, + &new_node->extension_count, + &new_node->extensions); + } else { + loader_log(VK_DBG_MSG_WARNING, 0, "Couldn't get global extensions from ICD"); + } +} /** * Try to \c loader_icd_scan VK driver(s). @@ -401,6 +562,8 @@ static void layer_lib_scan(void) struct dirent *dent; size_t len, i; char temp_str[1024]; + uint32_t count; + PFN_vkGetGlobalExtensionInfo fp_get_ext; #if defined(WIN32) bool must_free_libPaths; @@ -446,23 +609,27 @@ static void layer_lib_scan(void) /* cleanup any previously scanned libraries */ 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; + if (loader.scanned_layers[i].name != NULL) + free(loader.scanned_layers[i].name); + if (loader.scanned_layers[i].extensions != NULL) + free(loader.scanned_layers[i].extensions); + loader.scanned_layers[i].name = NULL; + loader.scanned_layers[i].extensions = NULL; } loader.scanned_layer_count = 0; + count = 0; for (p = libPaths; *p; p = next) { - next = strchr(p, PATH_SEPERATOR); - if (next == NULL) { - len = (uint32_t) strlen(p); - next = p + len; - } - else { - len = (uint32_t) (next - p); - *(char *) next = '\0'; - next++; - } + next = strchr(p, PATH_SEPERATOR); + if (next == NULL) { + len = (uint32_t) strlen(p); + next = p + len; + } + else { + len = (uint32_t) (next - p); + *(char *) next = '\0'; + next++; + } curdir = opendir(p); if (curdir) { @@ -481,32 +648,58 @@ static void layer_lib_scan(void) VK_LIBRARY_SUFFIX, VK_LIBRARY_SUFFIX_LEN)) { loader_platform_dl_handle handle; - snprintf(temp_str, sizeof(temp_str), "%s" DIRECTORY_SYMBOL "%s",p,dent->d_name); + snprintf(temp_str, sizeof(temp_str), + "%s" DIRECTORY_SYMBOL "%s",p,dent->d_name); // Used to call: dlopen(temp_str, RTLD_LAZY) if ((handle = loader_platform_open_library(temp_str)) == NULL) { dent = readdir(curdir); continue; } - if (loader.scanned_layer_count == MAX_LAYER_LIBRARIES) { - loader_log(VK_DBG_MSG_ERROR, 0, "%s ignored: max layer libraries exceed", temp_str); + if (count == MAX_LAYER_LIBRARIES) { + loader_log(VK_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) { + fp_get_ext = loader_platform_get_proc_address(handle, + "vkGetGlobalExtensionInfo"); + + if (!fp_get_ext) { + loader_log(VK_DBG_MSG_WARNING, 0, + "Couldn't dlsym vkGetGlobalExtensionInfo from library %s", + temp_str); + dent = readdir(curdir); + loader_platform_close_library(handle); + continue; + } + + loader.scanned_layers[count].name = + malloc(strlen(temp_str) + 1); + if (loader.scanned_layers[count].name == NULL) { loader_log(VK_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++; - loader_platform_close_library(handle); + + get_global_extensions(fp_get_ext, + &loader.scanned_layers[count].extension_count, + &loader.scanned_layers[count].extensions); + + + strcpy(loader.scanned_layers[count].name, temp_str); + count++; + loader_platform_close_library(handle); } } dent = readdir(curdir); - } + } // while (dir_entry) + if (count == MAX_LAYER_LIBRARIES) + break; closedir(curdir); - } - } + } // if (curdir)) + } // for (libpaths) + loader.scanned_layer_count = count; loader.layer_scanned = true; } @@ -578,62 +771,38 @@ static void loader_init_layer_libs(struct loader_icd *icd, uint32_t gpu_index, s } } -static VkResult find_layer_extension(struct loader_icd *icd, uint32_t gpu_index, const char *pExtName, const char **lib_name) +static bool find_layer_extension(struct loader_icd *icd, uint32_t gpu_index, const char *pExtName, const char **lib_name) { - VkResult err; char *search_name; - loader_platform_dl_handle handle; - PFN_vkGetExtensionSupport fpGetExtensionSupport; + uint32_t j; /* * The loader provides the abstraction that make layers and extensions work via * the currently defined extension mechanism. That is, when app queries for an extension - * via vkGetExtensionSupport, the loader will call both the driver as well as any layers + * via vkGetGlobalExtensionInfo, the loader will call both the driver as well as any layers * to see who implements that extension. Then, if the app enables the extension during - * vkCreateDevice the loader will find and load any layers that implement that extension. + * vkCreateInstance the loader will find and load any layers that implement that extension. */ - // TODO: What if extension is in multiple places? + // TODO: what about GetPhysicalDeviceExtension for device specific layers/extensions - // TODO: Who should we ask first? Driver or layers? Do driver for now. - err = icd->scanned_icds[gpu_index].GetExtensionSupport((VkPhysicalGpu) (icd->gpus[gpu_index].nextObject), pExtName); - if (err == VK_SUCCESS) { + for (j = 0; j < loader.scanned_layer_count; j++) { if (lib_name) { - *lib_name = NULL; + *lib_name = loader.scanned_layers[j].name; } - return VK_SUCCESS; - } + if (has_extension(loader.scanned_layers[j].extensions, + loader.scanned_layers[j].extension_count, pExtName, + true)) - for (unsigned int j = 0; j < loader.scanned_layer_count; j++) { - search_name = loader.scanned_layer_names[j]; + return true; - if ((handle = loader_platform_open_library(search_name)) == NULL) - continue; - - fpGetExtensionSupport = loader_platform_get_proc_address(handle, "vkGetExtensionSupport"); - - if (fpGetExtensionSupport != NULL) { - // Found layer's GetExtensionSupport call - err = fpGetExtensionSupport((VkPhysicalGpu) (icd->gpus + gpu_index), pExtName); - - loader_platform_close_library(handle); - - if (err == VK_SUCCESS) { - if (lib_name) { - *lib_name = loader.scanned_layer_names[j]; - } - return VK_SUCCESS; - } - } else { - loader_platform_close_library(handle); - } - - // No GetExtensionSupport or GetExtensionSupport returned invalid extension - // for the layer, so test the layer name as if it is an extension name - // use default layer name based on library name VK_LAYER_LIBRARY_PREFIX<name>.VK_LIBRARY_SUFFIX + // Extension not found in list for the layer, so test the layer name + // as if it is an extension name. Use default layer name based on + // library name VK_LAYER_LIBRARY_PREFIX<name>.VK_LIBRARY_SUFFIX char *pEnd; size_t siz; + search_name = loader.scanned_layers[j].name; search_name = basename(search_name); search_name += strlen(VK_LAYER_LIBRARY_PREFIX); pEnd = strrchr(search_name, '.'); @@ -642,13 +811,13 @@ static VkResult find_layer_extension(struct loader_icd *icd, uint32_t gpu_index, continue; if (strncmp(search_name, pExtName, siz) == 0) { - if (lib_name) { - *lib_name = loader.scanned_layer_names[j]; - } - return VK_SUCCESS; + return true; } } - return VK_ERROR_INVALID_EXTENSION; + if (lib_name) { + *lib_name = NULL; + } + return false; } static uint32_t loader_get_layer_env(struct loader_icd *icd, uint32_t gpu_index, struct layer_name_pair *pLayerNames) @@ -691,7 +860,7 @@ static uint32_t loader_get_layer_env(struct loader_icd *icd, uint32_t gpu_index, next++; } name = basename(p); - if (find_layer_extension(icd, gpu_index, name, &lib_name) != VK_SUCCESS) { + if (!find_layer_extension(icd, gpu_index, name, &lib_name)) { p = next; continue; } @@ -727,7 +896,7 @@ static uint32_t loader_get_layer_libs(struct loader_icd *icd, uint32_t gpu_index for (uint32_t i = 0; i < ext_count; i++) { const char *pExtName = ext_names[i]; - if (find_layer_extension(icd, gpu_index, pExtName, &lib_name) == VK_SUCCESS) { + if (find_layer_extension(icd, gpu_index, pExtName, &lib_name)) { uint32_t len; /* @@ -860,8 +1029,6 @@ LOADER_EXPORT VkResult VKAPI vkCreateInstance( const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance) { - static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_icd); - static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_layer); struct loader_instance *ptr_instance = NULL; struct loader_scanned_icds *scanned_icds; struct loader_icd *icd; @@ -874,6 +1041,9 @@ LOADER_EXPORT VkResult VKAPI vkCreateInstance( /* get layer libraries in a single-threaded manner */ loader_platform_thread_once(&once_layer, layer_lib_scan); + /* merge any duplicate extensions */ + loader_platform_thread_once(&once_exts, loader_coalesce_extensions); + ptr_instance = (struct loader_instance*) malloc(sizeof(struct loader_instance)); if (ptr_instance == NULL) { return VK_ERROR_OUT_OF_MEMORY; @@ -1060,18 +1230,60 @@ LOADER_EXPORT void * VKAPI vkGetProcAddr(VkPhysicalGpu gpu, const char * pName) } } -#if 0 -LOADER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char *pExtName) +//TODO make sure createInstance enables extensions that are valid (loader does) +//TODO make sure CreateDevice enables extensions that are valid (left for layers/drivers to do) + +//TODO how is layer extension going to be enabled? +//Need to call createInstance on the layer or something + +LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( + VkExtensionInfoType infoType, + uint32_t extensionIndex, + size_t* pDataSize, + void* pData) { - uint32_t gpu_index; - struct loader_icd *icd = loader_get_icd((const VkBaseLayerObject *) gpu, &gpu_index); + VkExtensionProperties *ext_props; + uint32_t *count; + /* Scan/discover all ICD libraries in a single-threaded manner */ + loader_platform_thread_once(&once_icd, loader_icd_scan); - if (!icd) - return VK_ERROR_UNAVAILABLE; + /* get layer libraries in a single-threaded manner */ + loader_platform_thread_once(&once_layer, layer_lib_scan); + + /* merge any duplicate extensions */ + loader_platform_thread_once(&once_exts, loader_coalesce_extensions); + + + if (pDataSize == NULL) + return VK_ERROR_INVALID_POINTER; - return find_layer_extension(icd, gpu_index, pExtName, NULL); + switch (infoType) { + case VK_EXTENSION_INFO_TYPE_COUNT: + *pDataSize = sizeof(uint32_t); + if (pData == NULL) + return VK_SUCCESS; + count = (uint32_t *) pData; + *count = loader.scanned_ext_list_count; + break; + case VK_EXTENSION_INFO_TYPE_PROPERTIES: + *pDataSize = sizeof(VkExtensionProperties); + if (pData == NULL) + return VK_SUCCESS; + if (extensionIndex >= loader.scanned_ext_list_count) + return VK_ERROR_INVALID_VALUE; + ext_props = (VkExtensionProperties *) pData; + ext_props->version = loader.scanned_ext_list[extensionIndex]->version; + strncpy(ext_props->extName, loader.scanned_ext_list[extensionIndex]->extName + , VK_MAX_EXTENSION_NAME); + ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0'; + break; + default: + loader_log(VK_DBG_MSG_WARNING, 0, "Invalid infoType in vkGetGlobalExtensionInfo"); + return VK_ERROR_INVALID_VALUE; + }; + + return VK_SUCCESS; } -#endif LOADER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalGpu gpu, size_t maxLayerCount, size_t maxStringSize, size_t* pOutLayerCount, char* const* pOutLayers, void* pReserved) { @@ -1094,7 +1306,7 @@ LOADER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalGpu gpu, size_t maxLaye layers[i] = &layer_buf[i][0]; for (unsigned int j = 0; j < loader.scanned_layer_count && count < maxLayerCount; j++) { - lib_name = loader.scanned_layer_names[j]; + lib_name = loader.scanned_layers[j].name; // Used to call: dlopen(*lib_name, RTLD_LAZY) if ((handle = loader_platform_open_library(lib_name)) == NULL) continue; diff --git a/vk-generate.py b/vk-generate.py index af807097..41ead485 100755 --- a/vk-generate.py +++ b/vk-generate.py @@ -33,6 +33,7 @@ def generate_get_proc_addr_check(name): return " if (!%s || %s[0] != 'v' || %s[1] != 'k')\n" \ " return NULL;" % ((name,) * 3) + class Subcommand(object): def __init__(self, argv): self.argv = argv @@ -42,6 +43,12 @@ class Subcommand(object): def run(self): print(self.generate()) + def is_dispatchable_object_first_param(self, proto): + in_objs = proto.object_in_params() + non_dispatch_objs = ["VkInstance"] + param0 = proto.params[0] + return (len(in_objs) > 0) and (in_objs[0].ty == param0.ty) and (param0.ty not in non_dispatch_objs) + def generate(self): copyright = self.generate_copyright() header = self.generate_header() @@ -100,14 +107,11 @@ class LoaderEntrypointsSubcommand(Subcommand): def generate_header(self): return "#include \"loader.h\"" - def _is_dispatchable(self, proto): - if proto.name in ["GetProcAddr", "DestroyInstance", "EnumerateGpus", - "EnumerateLayers", "DbgRegisterMsgCallback", - "DbgUnregisterMsgCallback", "DbgSetGlobalOption"]: - return False + def _is_loader_special_case(self, proto): + if proto.name in ["GetProcAddr", "EnumerateGpus", "EnumerateLayers"]: + return True - in_objs = proto.object_in_params() - return in_objs and in_objs[0] == proto.params[0] + return not self.is_dispatchable_object_first_param(proto) def _generate_object_setup(self, proto): method = "loader_init_data" @@ -144,7 +148,7 @@ class LoaderEntrypointsSubcommand(Subcommand): funcs = [] for proto in self.protos: - if not self._is_dispatchable(proto): + if self._is_loader_special_case(proto): continue func = [] @@ -214,7 +218,7 @@ class DispatchTableOpsSubcommand(Subcommand): if proto.name == "GetProcAddr": stmts.append("table->%s = gpa; /* direct assignment */" % proto.name) - else: + elif self.is_dispatchable_object_first_param(proto): stmts.append("table->%s = (PFN_vk%s) gpa(gpu, \"vk%s\");" % (proto.name, proto.name, proto.name)) stmts.append("#endif") @@ -237,8 +241,9 @@ class DispatchTableOpsSubcommand(Subcommand): for proto in self.protos: if 'WsiX11AssociateConnection' == proto.name: lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)") - lookups.append("if (!strcmp(name, \"%s\"))" % (proto.name)) - lookups.append(" return (void *) table->%s;" + if self.is_dispatchable_object_first_param(proto): + lookups.append("if (!strcmp(name, \"%s\"))" % (proto.name)) + lookups.append(" return (void *) table->%s;" % (proto.name)) lookups.append("#endif") diff --git a/vk-layer-generate.py b/vk-layer-generate.py index e95729f1..1b7ebd94 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -194,48 +194,52 @@ class Subcommand(object): ur_body.append('}') return "\n".join(ur_body) - def _gen_layer_get_extension_support(self, layer="Generic"): - ges_body = [] - ges_body.append('VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName)') - ges_body.append('{') - ges_body.append(' VkResult result;') - ges_body.append('') - ges_body.append(' /* This entrypoint is NOT going to init its own dispatch table since loader calls here early */') - ges_body.append(' if (!strncmp(pExtName, "%s", strlen("%s")))' % (layer, layer)) - ges_body.append(' {') - ges_body.append(' result = VK_SUCCESS;') - ges_body.append(' } else if (nextTable.GetExtensionSupport != NULL)') - ges_body.append(' {') - ges_body.append(' result = nextTable.GetExtensionSupport(gpu, pExtName);') - ges_body.append(' } else') - ges_body.append(' {') - ges_body.append(' result = VK_ERROR_INVALID_EXTENSION;') - ges_body.append(' }') - ges_body.append(' return result;') - ges_body.append('}') - return "\n".join(ges_body) - - def _gen_layer_get_extension_support(self, layer="Generic"): - ges_body = [] - ges_body.append('VK_LAYER_EXPORT VkResult VKAPI vkGetExtensionSupport(VkPhysicalGpu gpu, const char* pExtName)') - ges_body.append('{') - ges_body.append(' VkResult result;') - ges_body.append(' VK_BASE_LAYER_OBJECT* gpuw = (VK_BASE_LAYER_OBJECT *) gpu;') - ges_body.append('') - ges_body.append(' /* This entrypoint is NOT going to init its own dispatch table since loader calls here early */') - ges_body.append(' if (!strncmp(pExtName, "%s", strlen("%s")))' % (layer, layer)) - ges_body.append(' {') - ges_body.append(' result = VK_SUCCESS;') - ges_body.append(' } else if (nextTable.GetExtensionSupport != NULL)') - ges_body.append(' {') - ges_body.append(' result = nextTable.GetExtensionSupport((VkPhysicalGpu)gpuw->nextObject, pExtName);') - ges_body.append(' } else') - ges_body.append(' {') - ges_body.append(' result = VK_ERROR_INVALID_EXTENSION;') - ges_body.append(' }') - ges_body.append(' return result;') - ges_body.append('}') - return "\n".join(ges_body) + def _gen_layer_get_global_extension_info(self, layer="Generic"): + ggei_body = [] + ggei_body.append('struct extProps {') + ggei_body.append(' uint32_t version;') + ggei_body.append(' const char * const name;') + ggei_body.append('};') + ggei_body.append('#define LAYER_EXT_ARRAY_SIZE 1') + ggei_body.append('static const struct extProps layerExts[LAYER_EXT_ARRAY_SIZE] = {') + ggei_body.append(' // TODO what is the version?') + ggei_body.append(' {0x10, "%s"}' % layer) + ggei_body.append('};') + ggei_body.append('') + ggei_body.append('VK_LAYER_EXPORT VK_RESULT VKAPI vkGetGlobalExtensionInfo(VkExtensionInfoType infoType, uint32_t extensionIndex, size_t* pDataSize, void* pData)') + ggei_body.append('{') + ggei_body.append(' VkExtensionProperties *ext_props;') + ggei_body.append(' uint32_t *count;') + ggei_body.append('') + ggei_body.append(' if (pDataSize == NULL)') + ggei_body.append(' return VK_ERROR_INVALID_POINTER;') + ggei_body.append('') + ggei_body.append(' switch (infoType) {') + ggei_body.append(' case VK_EXTENSION_INFO_TYPE_COUNT:') + ggei_body.append(' *pDataSize = sizeof(uint32_t);') + ggei_body.append(' if (pData == NULL)') + ggei_body.append(' return VK_SUCCESS;') + ggei_body.append(' count = (uint32_t *) pData;') + ggei_body.append(' *count = LAYER_EXT_ARRAY_SIZE;') + ggei_body.append(' break;') + ggei_body.append(' case VK_EXTENSION_INFO_TYPE_PROPERTIES:') + ggei_body.append(' *pDataSize = sizeof(VkExtensionProperties);') + ggei_body.append(' if (pData == NULL)') + ggei_body.append(' return VK_SUCCESS;') + ggei_body.append(' if (extensionIndex >= LAYER_EXT_ARRAY_SIZE)') + ggei_body.append(' return VK_ERROR_INVALID_VALUE;') + ggei_body.append(' ext_props = (VkExtensionProperties *) pData;') + ggei_body.append(' ext_props->version = layerExts[extensionIndex].version;') + ggei_body.append(' strncpy(ext_props->extName, layerExts[extensionIndex].name,') + ggei_body.append(' VK_MAX_EXTENSION_NAME);') + ggei_body.append(" ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\\0';") + ggei_body.append(' break;') + ggei_body.append(' default:') + ggei_body.append(' return VK_ERROR_INVALID_VALUE;') + ggei_body.append(' };') + ggei_body.append(' return VK_SUCCESS;') + ggei_body.append('}') + return "\n".join(ggei_body) def _generate_dispatch_entrypoints(self, qual=""): if qual: @@ -254,6 +258,8 @@ class Subcommand(object): intercept = self._gen_layer_dbg_callback_unregister() elif 'GetExtensionSupport' == proto.name: funcs.append(self._gen_layer_get_extension_support(self.layer_name)) + elif 'GetGlobalExtensionInfo' == proto.name: + funcs.append(self._gen_layer_get_global_extension_info(self.layer_name)) if intercept is not None: funcs.append(intercept) intercepted.append(proto) @@ -269,6 +275,17 @@ class Subcommand(object): if 'WsiX11' in proto.name: lookups.append("#endif") + prefix="vk" + lookups = [] + for proto in intercepted: + if 'WsiX11' in proto.name: + lookups.append("#if defined(__linux__) || defined(XCB_NVIDIA)") + lookups.append("if (!strcmp(name, \"%s\"))" % proto.name) + lookups.append(" return (void*) %s%s;" % + (prefix, proto.name)) + if 'WsiX11' in proto.name: + lookups.append("#endif") + # add customized layer_intercept_proc body = [] body.append("static inline void* layer_intercept_proc(const char *name)") @@ -432,7 +449,7 @@ class GenericLayerSubcommand(Subcommand): return '#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include "loader_platform.h"\n#include "vkLayer.h"\n//The following is #included again to catch certain OS-specific functions being used:\n#include "loader_platform.h"\n\n#include "layers_config.h"\n#include "layers_msg.h"\n\nstatic VkLayerDispatchTable nextTable;\nstatic VkBaseLayerObject *pCurObj;\n\nstatic LOADER_PLATFORM_THREAD_ONCE_DECLARATION(tabOnce);' def generate_intercept(self, proto, qual): - if proto.name in [ 'DbgRegisterMsgCallback', 'DbgUnregisterMsgCallback' , 'GetExtensionSupport']: + if proto.name in [ 'DbgRegisterMsgCallback', 'DbgUnregisterMsgCallback' , 'GetExtensionSupport', 'GetGlobalExtensionInfo']: # use default version return None decl = proto.c_func(prefix="vk", attr="VKAPI") @@ -619,8 +636,9 @@ class APIDumpSubcommand(Subcommand): return "\n".join(func_body) def generate_intercept(self, proto, qual): + if proto.name in [ 'GetGlobalExtensionInfo']: + return None decl = proto.c_func(prefix="vk", attr="VKAPI") - param0_name = proto.params[0].name ret_val = '' stmt = '' funcs = [] @@ -666,6 +684,20 @@ class APIDumpSubcommand(Subcommand): else: prev_count_name = p.name else: + log_func_no_addr += '%s = " << %s << ", ' % (p.name, pfi) + if prev_count_name != '' and (prev_count_name.replace('Count', '')[1:] in p.name or 'slotCount' == prev_count_name): + sp_param_dict[pindex] = prev_count_name + elif 'pDescriptorSets' == p.name and proto.params[-1].name == 'pCount': + sp_param_dict[pindex] = '*pCount' + elif 'Wsi' not in proto.name and vk_helper.is_type(p.ty.strip('*').replace('const ', ''), 'struct'): + sp_param_dict[pindex] = 'index' + pindex += 1 + if p.name.endswith('Count'): + if '*' in p.ty: + prev_count_name = "*%s" % p.name + else: + prev_count_name = p.name + else: prev_count_name = '' log_func = log_func.strip(', ') log_func_no_addr = log_func_no_addr.strip(', ') @@ -1268,7 +1300,7 @@ class ObjectTrackerSubcommand(Subcommand): return "\n".join(header_txt) def generate_intercept(self, proto, qual): - if proto.name in [ 'DbgRegisterMsgCallback', 'DbgUnregisterMsgCallback' ]: + if proto.name in [ 'DbgRegisterMsgCallback', 'DbgUnregisterMsgCallback', 'GetGlobalExtensionInfo' ]: # use default version return None obj_type_mapping = {base_t : base_t.replace("VK_", "VK_OBJECT_TYPE_") for base_t in vulkan.object_type_list} @@ -1283,7 +1315,7 @@ class ObjectTrackerSubcommand(Subcommand): destroy_line = '' funcs = [] # Special cases for API funcs that don't use an object as first arg - if True in [no_use_proto in proto.name for no_use_proto in ['GlobalOption', 'CreateInstance', 'QueueSubmit', 'QueueAddMemReference', 'QueueRemoveMemReference', 'QueueWaitIdle', 'CreateDevice', 'GetGpuInfo', 'QueueSignalSemaphore', 'QueueWaitSemaphore', 'WsiX11QueuePresent']]: + if True in [no_use_proto in proto.name for no_use_proto in ['GlobalOption', 'CreateInstance', 'QueueSubmit', 'QueueAddMemReference', 'QueueRemoveMemReference', 'QueueWaitIdle', 'GetGlobalExtensionInfo', 'CreateDevice', 'GetGpuInfo', 'QueueSignalSemaphore', 'QueueWaitSemaphore', 'WsiX11QueuePresent']]: using_line = '' else: using_line = ' loader_platform_thread_lock_mutex(&objLock);\n' @@ -182,6 +182,7 @@ class Extension(object): core = Extension( name="VK_CORE", headers=["vulkan.h", "vkDbg.h"], + objects=[ "VkInstance", "VkPhysicalGpu", @@ -248,6 +249,12 @@ core = Extension( Proto("VkResult", "DestroyDevice", [Param("VkDevice", "device")]), + Proto("VkResult", "GetGlobalExtensionInfo", + [Param("VkExtensionInfoType", "infoType"), + Param("uint32_t", "extensionIndex"), + Param("size_t*", "pDataSize"), + Param("void*", "pData")]), + Proto("VkResult", "GetExtensionSupport", [Param("VkPhysicalGpu", "gpu"), Param("const char*", "pExtName")]), |
