diff options
Diffstat (limited to 'loader')
| -rw-r--r-- | loader/loader.c | 299 | ||||
| -rw-r--r-- | loader/loader.h | 26 | ||||
| -rw-r--r-- | loader/table_ops.h | 6 | ||||
| -rw-r--r-- | loader/trampoline.c | 33 |
4 files changed, 264 insertions, 100 deletions
diff --git a/loader/loader.c b/loader/loader.c index fd234657..b55ddcf8 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -69,7 +69,7 @@ VkLayerInstanceDispatchTable instance_disp = { .GetPhysicalDeviceInfo = loader_GetPhysicalDeviceInfo, .CreateDevice = loader_CreateDevice, .GetGlobalExtensionInfo = vkGetGlobalExtensionInfo, - .GetPhysicalDeviceExtensionInfo = loader_GetPhysicalDeviceExtensionInfo, + .GetPhysicalDeviceExtensionInfo = vkGetPhysicalDeviceExtensionInfo, .GetMultiDeviceCompatibility = loader_GetMultiDeviceCompatibility, .GetDisplayInfoWSI = loader_GetDisplayInfoWSI, .DbgCreateMsgCallback = loader_DbgCreateMsgCallback, @@ -302,6 +302,52 @@ static void get_global_extensions( return; } +static void get_physical_device_layer_extensions( + struct loader_instance *ptr_instance, + VkPhysicalDevice physical_device, + const uint32_t layer_index, + struct loader_extension_list *ext_list) +{ + uint32_t i, count; + size_t siz = sizeof(count); + VkResult res; + loader_platform_dl_handle lib_handle; + PFN_vkGetPhysicalDeviceExtensionInfo fp_get; + struct loader_extension_property ext_props; + + if (!loader.scanned_layers[layer_index].physical_device_extensions_supported) { + return; + } + + ext_props.origin = VK_EXTENSION_ORIGIN_LAYER; + ext_props.lib_name = loader.scanned_layers[layer_index].lib_name; + char funcStr[256]; + snprintf(funcStr, 256, "%sGetPhysicalDeviceExtensionInfo", ext_props.info.name); + lib_handle = loader_add_layer_lib("device", &ext_props); + fp_get = (PFN_vkGetPhysicalDeviceExtensionInfo) loader_platform_get_proc_address(lib_handle, "vkGetPhysicalDeviceExtensionInfo"); + if (fp_get) { + res = fp_get(physical_device, VK_EXTENSION_INFO_TYPE_COUNT, 0, &siz, &count); + if (res == VK_SUCCESS) { + siz = sizeof(VkExtensionProperties); + for (i = 0; i < count; i++) { + memset(&ext_props, 0, sizeof(ext_props)); + res = fp_get(physical_device, VK_EXTENSION_INFO_TYPE_PROPERTIES, i, &siz, &ext_props.info); + if (res == VK_SUCCESS && (ext_props.info.sType == VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES)) { + ext_props.hosted = false; + ext_props.origin = VK_EXTENSION_ORIGIN_LAYER; + ext_props.lib_name = loader.scanned_layers[layer_index].lib_name; + loader_add_to_ext_list(ext_list, 1, &ext_props); + } + } + } else { + loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Error getting physical device extension info count from Layer %s", ext_props.lib_name); + } + } + + loader_remove_layer_lib(ptr_instance, &ext_props); + return; +} + static bool loader_init_ext_list(struct loader_extension_list *ext_info) { ext_info->capacity = 32 * sizeof(struct loader_extension_property); @@ -490,6 +536,7 @@ static void loader_scanned_icd_add(const char *filename) loader_platform_dl_handle handle; void *fp_create_inst; void *fp_get_global_ext_info; + void *fp_get_device_ext_info; struct loader_scanned_icds *new_node; // Used to call: dlopen(filename, RTLD_LAZY); @@ -509,6 +556,7 @@ static void loader_scanned_icd_add(const char *filename) LOOKUP(fp_create_inst, CreateInstance); LOOKUP(fp_get_global_ext_info, GetGlobalExtensionInfo); + LOOKUP(fp_get_device_ext_info, GetPhysicalDeviceExtensionInfo); #undef LOOKUP new_node = (struct loader_scanned_icds *) malloc(sizeof(struct loader_scanned_icds) @@ -522,6 +570,7 @@ static void loader_scanned_icd_add(const char *filename) new_node->CreateInstance = fp_create_inst; new_node->GetGlobalExtensionInfo = fp_get_global_ext_info; loader_init_ext_list(&new_node->global_extension_list); + loader_init_ext_list(&new_node->device_extension_list); new_node->next = loader.scanned_icd_list; new_node->lib_name = (char *) (new_node + 1); @@ -794,6 +843,12 @@ void layer_lib_scan(void) VK_EXTENSION_ORIGIN_LAYER, &loader.scanned_layers[count].global_extension_list); + fp_get_ext = loader_platform_get_proc_address(handle, + "vkGetPhysicalDeviceExtensionInfo"); + if (fp_get_ext) { + loader.scanned_layers[count].physical_device_extensions_supported = true; + } + count++; loader_platform_close_library(handle); } @@ -880,8 +935,8 @@ static loader_platform_dl_handle loader_add_layer_lib( /* Have already loaded this library, just increment ref count */ loader.loaded_layer_lib_list[i].ref_count++; loader_log(VK_DBG_REPORT_INFO_BIT, 0, - "Inserting %s layer %s from library %s", chain_type, - ext_prop->info.name, ext_prop->lib_name); + "%s Chain: Increment layer reference count for layer library %s", + chain_type, ext_prop->lib_name); return loader.loaded_layer_lib_list[i].lib_handle; } } @@ -896,7 +951,7 @@ static loader_platform_dl_handle loader_add_layer_lib( my_lib = &new_layer_lib_list[loader.loaded_layer_lib_count]; - /* NOTE: We require that the extension property to be immutable */ + /* NOTE: We require that the extension property be immutable */ my_lib->lib_name = ext_prop->lib_name; my_lib->ref_count = 0; my_lib->lib_handle = NULL; @@ -907,8 +962,8 @@ static loader_platform_dl_handle loader_add_layer_lib( return NULL; } else { loader_log(VK_DBG_REPORT_INFO_BIT, 0, - "Inserting %s layer %s from library %s", chain_type, - ext_prop->info.name, ext_prop->lib_name); + "Chain: %s: Loading layer library %s", + chain_type, ext_prop->lib_name); } loader.loaded_layer_lib_count++; loader.loaded_layer_lib_list = new_layer_lib_list; @@ -941,9 +996,15 @@ static void loader_remove_layer_lib( my_lib->ref_count--; inst->layer_count--; if (my_lib->ref_count > 0) { + loader_log(VK_DBG_REPORT_INFO_BIT, 0, + "Decrement reference count for layer library %s", ext_prop->lib_name); return; } + loader_platform_close_library(my_lib->lib_handle); + loader_log(VK_DBG_REPORT_INFO_BIT, 0, + "Unloading layer library %s", ext_prop->lib_name); + /* Need to remove unused library from list */ new_layer_lib_list = malloc((loader.loaded_layer_lib_count - 1) * sizeof(struct loader_lib_info)); if (!new_layer_lib_list) { @@ -961,6 +1022,7 @@ static void loader_remove_layer_lib( memcpy(&new_layer_lib_list[idx], &loader.loaded_layer_lib_list[idx+1], sizeof(struct loader_lib_info) * (loader.loaded_layer_lib_count - idx - 1)); } + free(loader.loaded_layer_lib_list); loader.loaded_layer_lib_count--; loader.loaded_layer_lib_list = new_layer_lib_list; @@ -1133,6 +1195,10 @@ uint32_t loader_activate_instance_layers(struct loader_instance *inst) continue; } + loader_log(VK_DBG_REPORT_INFO_BIT, 0, + "Insert instance layer library %s for extension: %s", + ext_prop->lib_name, ext_prop->info.name); + layer_idx--; } @@ -1141,6 +1207,14 @@ uint32_t loader_activate_instance_layers(struct loader_instance *inst) return inst->layer_count; } +void loader_activate_instance_layer_extensions(struct loader_instance *inst) +{ + + loader_init_instance_extension_dispatch_table(inst->disp, + inst->disp->GetInstanceProcAddr, + (VkInstance) inst->wrappedInstance); +} + void loader_enable_device_layers(struct loader_icd *icd, uint32_t gpu_index) { if (icd == NULL) @@ -1220,6 +1294,10 @@ extern uint32_t loader_activate_device_layers( continue; } + loader_log(VK_DBG_REPORT_INFO_BIT, 0, + "Insert device layer library %s for extension: %s", + ext_prop->lib_name, ext_prop->info.name); + layer_idx--; } @@ -1315,79 +1393,142 @@ VkResult loader_DestroyInstance( return VK_SUCCESS; } -VkResult loader_EnumeratePhysicalDevices( - VkInstance instance, - uint32_t* pPhysicalDeviceCount, - VkPhysicalDevice* pPhysicalDevices) +VkResult loader_init_physical_device_info( + struct loader_instance *ptr_instance) { - struct loader_instance *ptr_instance = (struct loader_instance *) instance; struct loader_icd *icd; uint32_t n, count = 0; VkResult res = VK_ERROR_UNKNOWN; - //in spirit of VK don't error check on the instance parameter icd = ptr_instance->icds; - if (pPhysicalDevices == NULL) { - while (icd) { - res = icd->EnumeratePhysicalDevices(icd->instance, &n, NULL); - if (res != VK_SUCCESS) - return res; - icd->gpu_count = n; - count += n; - icd = icd->next; - } + while (icd) { + res = icd->EnumeratePhysicalDevices(icd->instance, &n, NULL); + if (res != VK_SUCCESS) + return res; + icd->gpu_count = n; + count += n; + icd = icd->next; + } - ptr_instance->total_gpu_count = count; + ptr_instance->total_gpu_count = count; - } else - { - VkPhysicalDevice* gpus; - if (*pPhysicalDeviceCount < ptr_instance->total_gpu_count) - return VK_ERROR_INVALID_VALUE; - gpus = malloc( sizeof(VkPhysicalDevice) * *pPhysicalDeviceCount); - if (!gpus) - return VK_ERROR_OUT_OF_HOST_MEMORY; - while (icd) { - VkBaseLayerObject * wrapped_gpus; - PFN_vkGetDeviceProcAddr get_proc_addr = icd->GetDeviceProcAddr; - - n = *pPhysicalDeviceCount; - res = icd->EnumeratePhysicalDevices( - icd->instance, - &n, - gpus); - if (res == VK_SUCCESS && n) { - wrapped_gpus = (VkBaseLayerObject*) malloc(n * - sizeof(VkBaseLayerObject)); - icd->gpus = wrapped_gpus; - icd->gpu_count = n; - icd->loader_dispatch = (VkLayerDispatchTable *) malloc(n * - sizeof(VkLayerDispatchTable)); - for (unsigned int i = 0; i < n; i++) { - (wrapped_gpus + i)->baseObject = gpus[i]; - (wrapped_gpus + i)->pGPA = get_proc_addr; - (wrapped_gpus + i)->nextObject = gpus[i]; - memcpy(pPhysicalDevices + count, gpus, sizeof(*pPhysicalDevices)); - loader_init_device_dispatch_table(icd->loader_dispatch + i, - get_proc_addr, gpus[i], gpus[i]); - - loader_init_dispatch(gpus[i], ptr_instance->disp); - } + VkPhysicalDevice* gpus; + gpus = malloc( sizeof(VkPhysicalDevice) * count); + if (!gpus) { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + icd = ptr_instance->icds; + while (icd) { + VkBaseLayerObject * wrapped_gpus; + PFN_vkGetDeviceProcAddr get_proc_addr = icd->GetDeviceProcAddr; + + n = icd->gpu_count; + res = icd->EnumeratePhysicalDevices( + icd->instance, + &n, + gpus); + if (res == VK_SUCCESS && n) { + wrapped_gpus = (VkBaseLayerObject*) malloc(n * + sizeof(VkBaseLayerObject)); + if (!wrapped_gpus) { + /* TODO: Add cleanup code here */ + return VK_ERROR_OUT_OF_HOST_MEMORY; + } - count += n; + icd->gpus = wrapped_gpus; + icd->loader_dispatch = (VkLayerDispatchTable *) malloc(n * + sizeof(VkLayerDispatchTable)); + for (unsigned int i = 0; i < n; i++) { + (wrapped_gpus + i)->baseObject = gpus[i]; + (wrapped_gpus + i)->pGPA = get_proc_addr; + (wrapped_gpus + i)->nextObject = gpus[i]; - if (count >= *pPhysicalDeviceCount) { - break; + loader_init_device_dispatch_table(icd->loader_dispatch + i, + get_proc_addr, gpus[i], gpus[i]); + + loader_init_dispatch(gpus[i], ptr_instance->disp); + + if (!loader_init_ext_list(&icd->device_extension_cache[i])) { + /* TODO: Add cleanup code here */ + res = VK_ERROR_OUT_OF_HOST_MEMORY; + } + if (res == VK_SUCCESS && icd->GetPhysicalDeviceExtensionInfo) { + size_t data_size; + uint32_t extension_count; + + data_size = sizeof(extension_count); + res = icd->GetPhysicalDeviceExtensionInfo(gpus[i], VK_EXTENSION_INFO_TYPE_COUNT, 0, &data_size, &extension_count); + if (data_size == sizeof(extension_count) && res == VK_SUCCESS) { + struct loader_extension_property ext_props; + + /* Gather all the ICD extensions */ + for (uint32_t extension_id = 0; extension_id < extension_count; extension_id++) { + data_size = sizeof(VkExtensionProperties); + res = icd->GetPhysicalDeviceExtensionInfo(gpus[i], VK_EXTENSION_INFO_TYPE_PROPERTIES, + extension_id, &data_size, &ext_props.info); + if (data_size == sizeof(VkExtensionProperties) && res == VK_SUCCESS) { + ext_props.hosted = false; + ext_props.origin = VK_EXTENSION_ORIGIN_ICD; + ext_props.lib_name = icd->scanned_icds->lib_name; + loader_add_to_ext_list(&icd->device_extension_cache[i], 1, &ext_props); + } + } + + // Traverse layers list adding non-duplicate extensions to the list + for (uint32_t l = 0; l < loader.scanned_layer_count; l++) { + get_physical_device_layer_extensions(ptr_instance, gpus[i], l, &icd->device_extension_cache[i]); + } + } + } + + if (res != VK_SUCCESS) { + /* clean up any extension lists previously created before this request failed */ + for (uint32_t j = 0; j < i; j++) { + loader_destroy_ext_list(&icd->device_extension_cache[i]); + } + return res; } } - icd = icd->next; + count += n; } + + icd = icd->next; } - *pPhysicalDeviceCount = count; + return VK_SUCCESS; +} - return (count > 0) ? VK_SUCCESS : res; +VkResult loader_EnumeratePhysicalDevices( + VkInstance instance, + uint32_t* pPhysicalDeviceCount, + VkPhysicalDevice* pPhysicalDevices) +{ + uint32_t index = 0; + struct loader_instance *ptr_instance = (struct loader_instance *) instance; + struct loader_icd *icd = ptr_instance->icds; + + /* TODO: How do we only do this once? */ + if (ptr_instance->total_gpu_count == 0) { + loader_init_physical_device_info(ptr_instance); + } + + *pPhysicalDeviceCount = ptr_instance->total_gpu_count; + if (!pPhysicalDevices) { + return VK_SUCCESS; + } + + while (icd) { + assert((index + icd->gpu_count) <= *pPhysicalDeviceCount); + for (uint32_t i = 0; i < icd->gpu_count; i++) { + memcpy(&pPhysicalDevices[index], &icd->gpus[i].baseObject, sizeof(VkPhysicalDevice)); + } + index += icd->gpu_count; + icd = icd->next; + } + + return VK_SUCCESS; } VkResult loader_GetPhysicalDeviceInfo( @@ -1572,7 +1713,8 @@ LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( return VK_SUCCESS; } -VkResult loader_GetPhysicalDeviceExtensionInfo( + +LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionInfo( VkPhysicalDevice gpu, VkExtensionInfoType infoType, uint32_t extensionIndex, @@ -1580,14 +1722,35 @@ VkResult loader_GetPhysicalDeviceExtensionInfo( void* pData) { uint32_t gpu_index; + uint32_t *count; struct loader_icd *icd = loader_get_icd((const VkBaseLayerObject *) gpu, &gpu_index); - VkResult res = VK_ERROR_INITIALIZATION_FAILED; - if (icd->GetPhysicalDeviceExtensionInfo) - res = icd->GetPhysicalDeviceExtensionInfo(gpu, infoType, extensionIndex, - pDataSize, pData); + if (pDataSize == NULL) + return VK_ERROR_INVALID_POINTER; - return res; + switch (infoType) { + case VK_EXTENSION_INFO_TYPE_COUNT: + *pDataSize = sizeof(uint32_t); + if (pData == NULL) + return VK_SUCCESS; + count = (uint32_t *) pData; + *count = icd->device_extension_cache[gpu_index].count; + break; + case VK_EXTENSION_INFO_TYPE_PROPERTIES: + *pDataSize = sizeof(VkExtensionProperties); + if (pData == NULL) + return VK_SUCCESS; + if (extensionIndex >= icd->device_extension_cache[gpu_index].count) + return VK_ERROR_INVALID_VALUE; + memcpy((VkExtensionProperties *) pData, + &icd->device_extension_cache[gpu_index].list[extensionIndex], + sizeof(VkExtensionProperties)); + break; + default: + return VK_ERROR_INVALID_VALUE; + }; + + return VK_SUCCESS; } VkResult loader_GetMultiDeviceCompatibility( diff --git a/loader/loader.h b/loader/loader.h index 8b427b5f..2d3b067a 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -69,16 +69,14 @@ struct loader_scanned_layers { char *lib_name; /* cache of global extensions for a specific layer */ -// uint32_t global_extension_count; -// struct loader_extension_property *global_extensions; struct loader_extension_list global_extension_list; + bool physical_device_extensions_supported; /* * cache of device extensions for a specific layer, * filled in at CreateInstance time */ - uint32_t device_ext_count; - struct loader_extension_property *device_ext_list; + struct loader_extension_list physical_device_extension_list; }; struct loader_icd { @@ -105,6 +103,13 @@ struct loader_icd { uint32_t app_extension_count[MAX_GPUS_FOR_LAYER]; VkExtensionProperties *app_extension_props[MAX_GPUS_FOR_LAYER]; + /* + * Fill in the cache of available extensions from all layers that + * operate with this physical device. + * This cache will be used to satisfy calls to GetPhysicalDeviceExtensionInfo + */ + struct loader_extension_list device_extension_cache[MAX_GPUS_FOR_LAYER]; + struct loader_extension_list enabled_device_extensions[MAX_GPUS_FOR_LAYER]; }; @@ -238,8 +243,7 @@ struct loader_scanned_icds { * cache of device extensions for specific ICD, * filled in at CreateInstance time */ - uint32_t device_extension_count; - struct loader_extension_property *device_extensions; + struct loader_extension_list device_extension_list; }; static inline void loader_set_dispatch(VkObject obj, const void *data) @@ -312,7 +316,6 @@ VkResult VKAPI loader_GetGlobalExtensionInfo( uint32_t extensionIndex, size_t* pDataSize, void* pData); -#endif VkResult loader_GetPhysicalDeviceExtensionInfo( VkPhysicalDevice gpu, @@ -320,6 +323,7 @@ VkResult loader_GetPhysicalDeviceExtensionInfo( uint32_t extensionIndex, size_t* pDataSize, void* pData); +#endif VkResult loader_GetMultiDeviceCompatibility( VkPhysicalDevice gpu0, @@ -343,7 +347,15 @@ void loader_icd_scan(void); void layer_lib_scan(void); void loader_coalesce_extensions(void); +static loader_platform_dl_handle loader_add_layer_lib( + const char *chain_type, + struct loader_extension_property *ext_prop); +static void loader_remove_layer_lib( + struct loader_instance *inst, + struct loader_extension_property *ext_prop); + struct loader_icd * loader_get_icd(const VkBaseLayerObject *gpu, uint32_t *gpu_index); uint32_t loader_activate_instance_layers(struct loader_instance *inst); +void loader_activate_instance_layer_extensions(struct loader_instance *inst); #endif /* LOADER_H */ diff --git a/loader/table_ops.h b/loader/table_ops.h index 93131b18..e4c39f2e 100644 --- a/loader/table_ops.h +++ b/loader/table_ops.h @@ -387,7 +387,13 @@ static inline void loader_init_instance_core_dispatch_table(VkLayerInstanceDispa table->GetPhysicalDeviceExtensionInfo = (PFN_vkGetPhysicalDeviceExtensionInfo) gpa(inst, "vkGetPhysicalDeviceExtensionInfo"); table->GetMultiDeviceCompatibility = (PFN_vkGetMultiDeviceCompatibility) gpa(inst, "vkGetMultiDeviceCompatibility"); table->GetDisplayInfoWSI = (PFN_vkGetDisplayInfoWSI) gpa(inst, "vkGetDisplayInfoWSI"); +} +static inline void loader_init_instance_extension_dispatch_table( + VkLayerInstanceDispatchTable *table, + PFN_vkGetInstanceProcAddr gpa, + VkInstance inst) +{ table->DbgCreateMsgCallback = (PFN_vkDbgCreateMsgCallback) gpa(inst, "vkDbgCreateMsgCallback"); table->DbgDestroyMsgCallback = (PFN_vkDbgDestroyMsgCallback) gpa(inst, "vkDbgDestroyMsgCallback"); } diff --git a/loader/trampoline.c b/loader/trampoline.c index 85039713..d22df048 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -120,6 +120,14 @@ LOADER_EXPORT VkResult VKAPI vkCreateInstance( res = ptr_instance->disp->CreateInstance(pCreateInfo, pInstance); + /* + * Finally have the layers in place and everyone has seen + * the CreateInstance command go by. This allows the layer's + * GetInstanceProcAddr functions to return valid extension functions + * if enabled. + */ + loader_activate_instance_layer_extensions(ptr_instance); + return res; } @@ -199,31 +207,6 @@ LOADER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device) return res; } -#if 0 //TODO get working on layer instance chain -LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo( - VkExtensionInfoType infoType, - uint32_t extensionIndex, - size_t* pDataSize, - void* pData) -{ - return instance_disp.GetGlobalExtensionInfo(infoType, extensionIndex, pDataSize, pData); -} -#endif - -LOADER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionInfo( - VkPhysicalDevice gpu, - VkExtensionInfoType infoType, - uint32_t extensionIndex, - size_t* pDataSize, - void* pData) -{ - const VkLayerInstanceDispatchTable *disp; - - disp = loader_get_instance_dispatch(gpu); - - return disp->GetPhysicalDeviceExtensionInfo(gpu, infoType, extensionIndex, pDataSize, pData); -} - LOADER_EXPORT VkResult VKAPI vkGetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex, VkQueue* pQueue) { const VkLayerDispatchTable *disp; |
