loader: Move lookup of icd entrypoints to CreateInstance and add more lookups
Move the icd Vulkan entrypoint address lookups to CreateInstance and icd list
rather than in the scanned_icd list. Also add more instance chain entrypoints
diff --git a/loader/loader.c b/loader/loader.c
index 6699410..f80ce61 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -69,7 +69,18 @@
VkBaseLayerObject *wrappedGpus[MAX_GPUS_FOR_LAYER];
uint32_t gpu_count;
VkBaseLayerObject *gpus;
-
+ VkInstance instance; // instance object from the icd
+ PFN_vkGetProcAddr GetProcAddr;
+ PFN_vkDestroyInstance DestroyInstance;
+ PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
+ PFN_vkGetPhysicalDeviceInfo GetPhysicalDeviceInfo;
+ PFN_vkCreateDevice CreateDevice;
+ PFN_vkGetPhysicalDeviceExtensionInfo GetPhysicalDeviceExtensionInfo;
+ PFN_vkEnumerateLayers EnumerateLayers;
+ PFN_vkGetMultiDeviceCompatibility GetMultiDeviceCompatibility;
+ PFN_vkDbgRegisterMsgCallback DbgRegisterMsgCallback;
+ PFN_vkDbgUnregisterMsgCallback DbgUnregisterMsgCallback;
+ PFN_vkDbgSetGlobalOption DbgSetGlobalOption;
struct loader_icd *next;
};
@@ -77,12 +88,8 @@
struct loader_scanned_icds {
loader_platform_dl_handle handle;
- PFN_vkGetProcAddr GetProcAddr;
PFN_vkCreateInstance CreateInstance;
- PFN_vkDestroyInstance DestroyInstance;
- PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
PFN_vkGetGlobalExtensionInfo GetGlobalExtensionInfo;
- VkInstance instance;
struct loader_scanned_icds *next;
uint32_t extension_count;
struct extension_property *extensions;
@@ -419,7 +426,7 @@
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;
+ void *fp_create_inst;
void *fp_get_global_ext_info;
struct loader_scanned_icds *new_node;
@@ -438,10 +445,7 @@
} \
} while (0)
- LOOKUP(fp_gpa, GetProcAddr);
LOOKUP(fp_create_inst, CreateInstance);
- LOOKUP(fp_destroy_inst, DestroyInstance);
- LOOKUP(fp_enumerate, EnumeratePhysicalDevices);
LOOKUP(fp_get_global_ext_info, GetGlobalExtensionInfo);
#undef LOOKUP
@@ -452,10 +456,7 @@
}
new_node->handle = handle;
- new_node->GetProcAddr = fp_gpa;
new_node->CreateInstance = fp_create_inst;
- new_node->DestroyInstance = fp_destroy_inst;
- new_node->EnumeratePhysicalDevices = fp_enumerate;
new_node->GetGlobalExtensionInfo = fp_get_global_ext_info;
new_node->extension_count = 0;
new_node->extensions = NULL;
@@ -472,6 +473,36 @@
}
}
+static void loader_icd_init_entrys(struct loader_icd *icd,
+ struct loader_scanned_icds *scanned_icds)
+{
+ /* initialize entrypoint function pointers */
+
+ #define LOOKUP(func) do { \
+ icd->func = (PFN_vk ##func) loader_platform_get_proc_address(scanned_icds->handle, "vk" #func); \
+ if (!icd->func) { \
+ loader_log(VK_DBG_MSG_WARNING, 0, loader_platform_get_proc_address_error("vk" #func)); \
+ return; \
+ } \
+ } while (0)
+
+ /* could change this to use GetInstanceProcAddr in driver once they support it */
+ LOOKUP(GetProcAddr);
+ LOOKUP(DestroyInstance);
+ LOOKUP(EnumeratePhysicalDevices);
+ LOOKUP(GetPhysicalDeviceInfo);
+ LOOKUP(CreateDevice);
+ LOOKUP(GetPhysicalDeviceExtensionInfo);
+ LOOKUP(EnumerateLayers);
+ LOOKUP(GetMultiDeviceCompatibility);
+ LOOKUP(DbgRegisterMsgCallback);
+ LOOKUP(DbgUnregisterMsgCallback);
+ LOOKUP(DbgSetGlobalOption);
+#undef LOOKUP
+
+ return;
+}
+
/**
* Try to \c loader_icd_scan VK driver(s).
*
@@ -1166,7 +1197,7 @@
gpu->pGPA = nextGPA;
gpuObj = icd->wrappedGpus[gpu_index] + icd->layer_count[gpu_index] - 1;
gpuObj->nextObject = (VkObject) baseObj;
- gpuObj->pGPA = icd->scanned_icds->GetProcAddr;
+ gpuObj->pGPA = icd->GetProcAddr;
}
}
@@ -1201,14 +1232,17 @@
icd = loader_icd_add(ptr_instance, scanned_icds);
if (icd) {
res = scanned_icds->CreateInstance(pCreateInfo,
- &(scanned_icds->instance));
+ &(icd->instance));
if (res != VK_SUCCESS)
{
ptr_instance->icds = ptr_instance->icds->next;
loader_icd_destroy(icd);
- scanned_icds->instance = VK_NULL_HANDLE;
+ icd->instance = VK_NULL_HANDLE;
loader_log(VK_DBG_MSG_WARNING, 0,
"ICD ignored: failed to CreateInstance on device");
+ } else
+ {
+ loader_icd_init_entrys(icd, scanned_icds);
}
}
scanned_icds = scanned_icds->next;
@@ -1225,7 +1259,7 @@
VkInstance instance)
{
struct loader_instance *ptr_instance = (struct loader_instance *) instance;
- struct loader_scanned_icds *scanned_icds;
+ struct loader_icd *icds = ptr_instance->icds;
VkResult res;
uint32_t i;
@@ -1254,16 +1288,15 @@
loader_deactivate_instance_layer(ptr_instance);
- scanned_icds = loader.scanned_icd_list;
- while (scanned_icds) {
- if (scanned_icds->instance) {
- res = scanned_icds->DestroyInstance(scanned_icds->instance);
+ while (icds) {
+ if (icds->instance) {
+ res = icds->DestroyInstance(icds->instance);
if (res != VK_SUCCESS)
loader_log(VK_DBG_MSG_WARNING, 0,
"ICD ignored: failed to DestroyInstance on device");
}
- scanned_icds->instance = VK_NULL_HANDLE;
- scanned_icds = scanned_icds->next;
+ icds->instance = VK_NULL_HANDLE;
+ icds = icds->next;
}
free(ptr_instance);
@@ -1285,8 +1318,8 @@
icd = ptr_instance->icds;
if (pPhysicalDevices == NULL) {
while (icd) {
- res = icd->scanned_icds->EnumeratePhysicalDevices(
- icd->scanned_icds->instance,
+ res = icd->EnumeratePhysicalDevices(
+ icd->instance,
&n, NULL);
if (res != VK_SUCCESS)
return res;
@@ -1307,11 +1340,11 @@
return VK_ERROR_OUT_OF_HOST_MEMORY;
while (icd) {
VkBaseLayerObject * wrapped_gpus;
- PFN_vkGetProcAddr get_proc_addr = icd->scanned_icds->GetProcAddr;
+ PFN_vkGetProcAddr get_proc_addr = icd->GetProcAddr;
n = *pPhysicalDeviceCount;
- res = icd->scanned_icds->EnumeratePhysicalDevices(
- icd->scanned_icds->instance,
+ res = icd->EnumeratePhysicalDevices(
+ icd->instance,
&n,
gpus);
if (res == VK_SUCCESS && n) {
@@ -1359,6 +1392,22 @@
return (count > 0) ? VK_SUCCESS : res;
}
+VkResult loader_GetPhysicalDeviceInfo(
+ VkPhysicalDevice gpu,
+ VkPhysicalDeviceInfoType infoType,
+ size_t* pDataSize,
+ void* pData)
+{
+ uint32_t gpu_index;
+ struct loader_icd *icd = loader_get_icd((const VkBaseLayerObject *) gpu, &gpu_index);
+ VkResult res = VK_ERROR_INITIALIZATION_FAILED;
+
+ if (icd->GetPhysicalDeviceInfo)
+ res = icd->GetPhysicalDeviceInfo(gpu, infoType, pDataSize, pData);
+
+ return res;
+}
+
LOADER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance instance, const char * pName)
{
if (instance != VK_NULL_HANDLE) {
@@ -1538,7 +1587,6 @@
const struct loader_icd *icd;
struct loader_instance *inst;
VkResult res;
- uint32_t gpu_idx;
if (instance == VK_NULL_HANDLE)
return VK_ERROR_INVALID_HANDLE;
@@ -1554,14 +1602,10 @@
return VK_ERROR_INVALID_HANDLE;
for (icd = inst->icds; icd; icd = icd->next) {
- for (uint32_t i = 0; i < icd->gpu_count; i++) {
- res = (icd->loader_dispatch + i)->DbgRegisterMsgCallback(icd->scanned_icds->instance,
+ if (!icd->DbgRegisterMsgCallback)
+ continue;
+ res = icd->DbgRegisterMsgCallback(icd->instance,
pfnMsgCallback, pUserData);
- if (res != VK_SUCCESS) {
- gpu_idx = i;
- break;
- }
- }
if (res != VK_SUCCESS)
break;
}
@@ -1571,12 +1615,11 @@
if (icd) {
for (const struct loader_icd *tmp = inst->icds; tmp != icd;
tmp = tmp->next) {
- for (uint32_t i = 0; i < icd->gpu_count; i++)
- (tmp->loader_dispatch + i)->DbgUnregisterMsgCallback(tmp->scanned_icds->instance, pfnMsgCallback);
+ if (!tmp->DbgUnregisterMsgCallback)
+ continue;
+ tmp->DbgUnregisterMsgCallback(tmp->instance,
+ pfnMsgCallback);
}
- /* and gpus on current icd */
- for (uint32_t i = 0; i < gpu_idx; i++)
- (icd->loader_dispatch + i)->DbgUnregisterMsgCallback(icd->scanned_icds->instance, pfnMsgCallback);
return res;
}
@@ -1602,12 +1645,12 @@
return VK_ERROR_INVALID_HANDLE;
for (const struct loader_icd * icd = inst->icds; icd; icd = icd->next) {
- for (uint32_t i = 0; i < icd->gpu_count; i++) {
- VkResult r;
- r = (icd->loader_dispatch + i)->DbgUnregisterMsgCallback(icd->scanned_icds->instance, pfnMsgCallback);
- if (r != VK_SUCCESS) {
- res = r;
- }
+ VkResult r;
+ if (!icd->DbgUnregisterMsgCallback)
+ continue;
+ r = icd->DbgUnregisterMsgCallback(icd->instance, pfnMsgCallback);
+ if (r != VK_SUCCESS) {
+ res = r;
}
}
return res;
@@ -1630,15 +1673,15 @@
if (inst == VK_NULL_HANDLE)
return VK_ERROR_INVALID_HANDLE;
for (const struct loader_icd * icd = inst->icds; icd; icd = icd->next) {
- for (uint32_t i = 0; i < icd->gpu_count; i++) {
VkResult r;
- r = (icd->loader_dispatch + i)->DbgSetGlobalOption(icd->scanned_icds->instance, dbgOption,
+ if (!icd->DbgSetGlobalOption)
+ continue;
+ r = icd->DbgSetGlobalOption(icd->instance, dbgOption,
dataSize, pData);
/* unfortunately we cannot roll back */
if (r != VK_SUCCESS) {
res = r;
}
- }
}
return res;
diff --git a/loader/loader.h b/loader/loader.h
index c2e15a5..4004692 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -153,5 +153,6 @@
void loader_icd_scan(void);
void layer_lib_scan(void);
void loader_coalesce_extensions(void);
+struct loader_icd * loader_get_icd(const VkBaseLayerObject *gpu, uint32_t *gpu_index);
uint32_t loader_activate_instance_layers(struct loader_instance *inst);
#endif /* LOADER_H */