aboutsummaryrefslogtreecommitdiff
path: root/loader/loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'loader/loader.c')
-rw-r--r--loader/loader.c481
1 files changed, 296 insertions, 185 deletions
diff --git a/loader/loader.c b/loader/loader.c
index 9a3aa3f4..82aaafa0 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -1140,21 +1140,19 @@ static void loader_destroy_logical_device(const struct loader_instance *inst,
static struct loader_device *loader_add_logical_device(
const struct loader_instance *inst,
- const VkDevice dev,
struct loader_device **device_list)
{
struct loader_device *new_dev;
new_dev = loader_heap_alloc(inst, sizeof(struct loader_device), VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
if (!new_dev) {
- loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc struct laoder-device");
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc struct loader-device");
return NULL;
}
memset(new_dev, 0, sizeof(struct loader_device));
new_dev->next = *device_list;
- new_dev->device = dev;
*device_list = new_dev;
return new_dev;
}
@@ -2295,6 +2293,13 @@ void loader_layer_scan(
static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_instance_internal(VkInstance inst, const char * pName)
{
+ if (!strcmp(pName, "vkGetInstanceProcAddr"))
+ return (void *) loader_gpa_instance_internal;
+ if (!strcmp(pName, "vkCreateInstance"))
+ return (void *) loader_CreateInstance;
+ if (!strcmp(pName, "vkCreateDevice"))
+ return (void *) loader_create_device_terminator;
+
// inst is not wrapped
if (inst == VK_NULL_HANDLE) {
return NULL;
@@ -2302,9 +2307,6 @@ static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_instance_internal(VkI
VkLayerInstanceDispatchTable* disp_table = * (VkLayerInstanceDispatchTable **) inst;
void *addr;
- if (!strcmp(pName, "vkGetInstanceProcAddr"))
- return (void *) loader_gpa_instance_internal;
-
if (disp_table == NULL)
return NULL;
@@ -2785,19 +2787,17 @@ VkResult loader_enable_instance_layers(
}
/* Add any implicit layers first */
- loader_add_layer_implicit(
- inst,
- VK_LAYER_TYPE_INSTANCE_IMPLICIT,
- &inst->activated_layer_list,
- instance_layers);
+ loader_add_layer_implicit(inst,
+ VK_LAYER_TYPE_INSTANCE_IMPLICIT,
+ &inst->activated_layer_list,
+ instance_layers);
/* Add any layers specified via environment variable next */
- loader_add_layer_env(
- inst,
- VK_LAYER_TYPE_INSTANCE_EXPLICIT,
- "VK_INSTANCE_LAYERS",
- &inst->activated_layer_list,
- instance_layers);
+ loader_add_layer_env(inst,
+ VK_LAYER_TYPE_INSTANCE_EXPLICIT,
+ "VK_INSTANCE_LAYERS",
+ &inst->activated_layer_list,
+ instance_layers);
/* Add layers specified by the application */
err = loader_add_layer_names_to_list(
@@ -2810,87 +2810,116 @@ VkResult loader_enable_instance_layers(
return err;
}
-uint32_t loader_activate_instance_layers(struct loader_instance *inst)
-{
- uint32_t layer_idx;
- VkBaseLayerObject *wrappedInstance;
+/*
+ * Given the list of layers to activate in the loader_instance
+ * structure. This function will add a VkLayerInstanceCreateInfo
+ * structure to the VkInstanceCreateInfo.pNext pointer.
+ * Each activated layer will have it's own VkLayerInstanceLink
+ * structure that tells the layer what Get*ProcAddr to call to
+ * get function pointers to the next layer down.
+ * Once the chain info has been created this function will
+ * execute the CreateInstance call chain. Each layer will
+ * then have an opportunity in it's CreateInstance function
+ * to setup it's dispatch table when the lower layer returns
+ * successfully.
+ * Each layer can wrap or not-wrap the returned VkInstance object
+ * as it sees fit.
+ * The instance chain is terminated by a loader function
+ * that will call CreateInstance on all available ICD's and
+ * cache those VkInstance objects for future use.
+ */
+VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ struct loader_instance *inst)
+{
+ uint32_t activated_layers = 0;
+ VkLayerInstanceCreateInfo chain_info;
+ VkLayerInstanceLink *layer_instance_link_info = NULL;
+ VkInstanceCreateInfo loader_create_info;
+ VkResult res;
- if (inst == NULL) {
- return 0;
- }
+ PFN_vkGetInstanceProcAddr nextGIPA = loader_gpa_instance_internal;
+ PFN_vkGetInstanceProcAddr fpGIPA = loader_gpa_instance_internal;
- // NOTE inst is unwrapped at this point in time
- void* baseObj = (void*) inst;
- void* nextObj = (void*) inst;
- VkBaseLayerObject *nextInstObj;
- PFN_vkGetInstanceProcAddr nextGPA = loader_gpa_instance_internal;
+ memcpy(&loader_create_info, pCreateInfo, sizeof(VkInstanceCreateInfo));
- if (!inst->activated_layer_list.count) {
- loader_init_instance_core_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj, (VkInstance) baseObj);
- return 0;
- }
+ if (inst->activated_layer_list.count > 0) {
- wrappedInstance = loader_stack_alloc(sizeof(VkBaseLayerObject)
- * inst->activated_layer_list.count);
- if (!wrappedInstance) {
- loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Instance objects for layer");
- return 0;
- }
+ chain_info.u.pLayerInfo = NULL;
+ chain_info.pNext = pCreateInfo->pNext;
+ chain_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
+ chain_info.function = VK_LAYER_LINK_INFO;
+ loader_create_info.pNext = &chain_info;
- /* Create instance chain of enabled layers */
- layer_idx = inst->activated_layer_list.count - 1;
- for (int32_t i = inst->activated_layer_list.count - 1; i >= 0; i--) {
- struct loader_layer_properties *layer_prop = &inst->activated_layer_list.list[i];
- loader_platform_dl_handle lib_handle;
-
- /*
- * Note: An extension's Get*ProcAddr should not return a function pointer for
- * any extension entry points until the extension has been enabled.
- * To do this requires a different behavior from Get*ProcAddr functions implemented
- * in layers.
- * The very first call to a layer will be it's Get*ProcAddr function requesting
- * the layer's vkGet*ProcAddr. The layer should initialize its internal dispatch table
- * with the wrapped object given (either Instance or Device) and return the layer's
- * Get*ProcAddr function. The layer should also use this opportunity to record the
- * baseObject so that it can find the correct local dispatch table on future calls.
- * Subsequent calls to Get*ProcAddr, CreateInstance, CreateDevice
- * will not use a wrapped object and must look up their local dispatch table from
- * the given baseObject.
- */
- nextInstObj = (wrappedInstance + layer_idx);
- nextInstObj->pGPA = (PFN_vkGPA) nextGPA;
- nextInstObj->baseObject = baseObj;
- nextInstObj->nextObject = nextObj;
- nextObj = (void*) nextInstObj;
-
- lib_handle = loader_add_layer_lib(inst, "instance", layer_prop);
- if (!lib_handle)
- continue; // TODO what should we do in this case
- if ((nextGPA = layer_prop->functions.get_instance_proc_addr) == NULL) {
- if (layer_prop->functions.str_gipa == NULL || strlen(layer_prop->functions.str_gipa) == 0) {
- nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr");
- layer_prop->functions.get_instance_proc_addr = nextGPA;
- } else
- nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gipa);
- if (!nextGPA) {
- loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", layer_prop->lib_name);
-
- /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/
- continue;
+ layer_instance_link_info = loader_stack_alloc(sizeof(VkLayerInstanceLink)
+ * inst->activated_layer_list.count);
+ if (!layer_instance_link_info) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Instance objects for layer");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ /* Create instance chain of enabled layers */
+ for (int32_t i = inst->activated_layer_list.count - 1; i >= 0; i--) {
+ struct loader_layer_properties *layer_prop = &inst->activated_layer_list.list[i];
+ loader_platform_dl_handle lib_handle;
+
+ lib_handle = loader_add_layer_lib(inst, "instance", layer_prop);
+ if (!lib_handle)
+ continue; // TODO what should we do in this case
+ if ((fpGIPA = layer_prop->functions.get_instance_proc_addr) == NULL) {
+ if (layer_prop->functions.str_gipa == NULL || strlen(layer_prop->functions.str_gipa) == 0) {
+ fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr");
+ layer_prop->functions.get_instance_proc_addr = fpGIPA;
+ } else
+ fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gipa);
+ if (!fpGIPA) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", layer_prop->lib_name);
+
+ /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/
+ continue;
+ }
}
+
+ layer_instance_link_info[activated_layers].pNext = chain_info.u.pLayerInfo;
+ layer_instance_link_info[activated_layers].pfnNextGetInstanceProcAddr = nextGIPA;
+ chain_info.u.pLayerInfo = &layer_instance_link_info[activated_layers];
+ nextGIPA = fpGIPA;
+
+ loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0,
+ "Insert instance layer %s (%s)",
+ layer_prop->info.layerName,
+ layer_prop->lib_name);
+
+ activated_layers++;
}
+ }
+
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance) nextGIPA(VK_NULL_HANDLE, "vkCreateInstance");
+ if (fpCreateInstance) {
+ VkLayerInstanceCreateInfo instance_create_info;
+
+ instance_create_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
+ instance_create_info.function = VK_LAYER_INSTANCE_INFO;
+
+ instance_create_info.u.instanceInfo.instance_info = inst;
+ instance_create_info.u.instanceInfo.pfnNextGetInstanceProcAddr= nextGIPA;
- loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0,
- "Insert instance layer %s (%s)",
- layer_prop->info.layerName,
- layer_prop->lib_name);
+ instance_create_info.pNext = loader_create_info.pNext;
+ loader_create_info.pNext = &instance_create_info;
- layer_idx--;
+ res = fpCreateInstance(&loader_create_info, pAllocator, &inst->instance);
+ } else {
+ // Couldn't find CreateInstance function!
+ res = VK_ERROR_INITIALIZATION_FAILED;
}
- loader_init_instance_core_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj, (VkInstance) baseObj);
+ if (res != VK_SUCCESS) {
+ // TODO: Need to clean up here
+ } else {
+ loader_init_instance_core_dispatch_table(inst->disp, nextGIPA, inst->instance);
+ }
- return inst->activated_layer_list.count;
+ return res;
}
void loader_activate_instance_layer_extensions(struct loader_instance *inst, VkInstance created_inst)
@@ -2948,100 +2977,164 @@ static VkResult loader_enable_device_layers(
return err;
}
-/*
- * This function terminates the device chain for CreateDevice.
- * CreateDevice is a special case and so the loader call's
- * the ICD's CreateDevice before creating the chain. Since
- * we can't call CreateDevice twice we must terminate the
- * device chain with something else.
- */
-static VKAPI_ATTR VkResult VKAPI_CALL scratch_vkCreateDevice(
- VkPhysicalDevice physicalDevice,
- const VkDeviceCreateInfo *pCreateInfo,
- const VkAllocationCallbacks* pAllocator,
- VkDevice *pDevice)
+VkResult loader_create_device_terminator(
+ VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDevice* pDevice)
{
- return VK_SUCCESS;
+ struct loader_physical_device *phys_dev;
+ phys_dev = loader_get_physical_device(physicalDevice);
+
+ VkLayerDeviceCreateInfo *chain_info = (VkLayerDeviceCreateInfo *) pCreateInfo->pNext;
+ while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
+ && chain_info->function == VK_LAYER_DEVICE_INFO)) {
+ chain_info = (VkLayerDeviceCreateInfo *) chain_info->pNext;
+ }
+ assert(chain_info != NULL);
+
+ struct loader_device *dev = (struct loader_device *) chain_info->u.deviceInfo.device_info;
+ PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.deviceInfo.pfnNextGetInstanceProcAddr;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) fpGetInstanceProcAddr(phys_dev->this_icd->instance, "vkCreateDevice");
+ if (fpCreateDevice == NULL) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ VkDeviceCreateInfo localCreateInfo;
+ memcpy(&localCreateInfo, pCreateInfo, sizeof(localCreateInfo));
+ localCreateInfo.pNext = NULL;
+ // ICDs do not support layers
+ localCreateInfo.enabledLayerCount = 0;
+ localCreateInfo.ppEnabledLayerNames = NULL;
+
+ VkDevice localDevice;
+ VkResult res = fpCreateDevice(phys_dev->phys_dev, &localCreateInfo, pAllocator, &localDevice);
+
+ if (res != VK_SUCCESS) {
+ return res;
+ }
+
+ *pDevice = localDevice;
+
+ /* Init dispatch pointer in new device object */
+ loader_init_dispatch(*pDevice, &dev->loader_dispatch);
+
+ return res;
}
-static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_GetDeviceChainProcAddr(VkDevice device, const char * name)
+VkResult loader_create_device_chain(
+ VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ struct loader_instance *inst,
+ struct loader_icd *icd,
+ struct loader_device *dev)
{
- if (!strcmp(name, "vkGetDeviceProcAddr"))
- return (PFN_vkVoidFunction) loader_GetDeviceChainProcAddr;
- if (!strcmp(name, "vkCreateDevice"))
- return (PFN_vkVoidFunction) scratch_vkCreateDevice;
+ uint32_t activated_layers = 0;
+ VkLayerDeviceLink *layer_device_link_info;
+ VkLayerDeviceCreateInfo chain_info;
+ VkLayerDeviceCreateInfo device_info;
+ VkDeviceCreateInfo loader_create_info;
+ VkResult res;
- struct loader_device *found_dev;
- struct loader_icd *icd = loader_get_icd_and_device(device, &found_dev);
- return icd->GetDeviceProcAddr(device, name);
-}
+ PFN_vkGetDeviceProcAddr fpGDPA, nextGDPA = icd->GetDeviceProcAddr;
+ PFN_vkGetInstanceProcAddr fpGIPA, nextGIPA = loader_gpa_instance_internal;
-static uint32_t loader_activate_device_layers(
- const struct loader_instance *inst,
- struct loader_device *dev,
- VkDevice device)
-{
- if (!dev) {
- return 0;
- }
-
- /* activate any layer libraries */
- void* nextObj = (void*) device;
- void* baseObj = nextObj;
- VkBaseLayerObject *nextGpuObj;
- PFN_vkGetDeviceProcAddr nextGPA = loader_GetDeviceChainProcAddr;
- VkBaseLayerObject *wrappedGpus;
-
- if (!dev->activated_layer_list.count) {
- loader_init_device_dispatch_table(&dev->loader_dispatch, nextGPA,
- (VkDevice) nextObj, (VkDevice) baseObj);
- return 0;
- }
-
- wrappedGpus = loader_heap_alloc(inst,
- sizeof (VkBaseLayerObject) * dev->activated_layer_list.count,
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
- if (!wrappedGpus) {
- loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Gpu objects for layer");
- return 0;
- }
-
- for (int32_t i = dev->activated_layer_list.count - 1; i >= 0; i--) {
-
- struct loader_layer_properties *layer_prop = &dev->activated_layer_list.list[i];
- loader_platform_dl_handle lib_handle;
-
- nextGpuObj = (wrappedGpus + i);
- nextGpuObj->pGPA = (PFN_vkGPA)nextGPA;
- nextGpuObj->baseObject = baseObj;
- nextGpuObj->nextObject = nextObj;
- nextObj = (void*) nextGpuObj;
-
- lib_handle = loader_add_layer_lib(inst, "device", layer_prop);
- if ((nextGPA = layer_prop->functions.get_device_proc_addr) == NULL) {
- if (layer_prop->functions.str_gdpa == NULL || strlen(layer_prop->functions.str_gdpa) == 0) {
- nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetDeviceProcAddr");
- layer_prop->functions.get_device_proc_addr = nextGPA;
- } else
- nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gdpa);
- if (!nextGPA) {
- loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetDeviceProcAddr in layer %s", layer_prop->lib_name);
- continue;
+ memcpy(&loader_create_info, pCreateInfo, sizeof(VkDeviceCreateInfo));
+
+ chain_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
+ chain_info.function = VK_LAYER_LINK_INFO;
+ chain_info.u.pLayerInfo = NULL;
+ chain_info.pNext = pCreateInfo->pNext;
+
+ layer_device_link_info = loader_stack_alloc(sizeof(VkLayerDeviceLink)
+ * dev->activated_layer_list.count);
+ if (!layer_device_link_info) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to alloc Device objects for layer");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ /*
+ * This structure is used by loader_create_device_terminator
+ * so that it can intialize the device dispatch table pointer
+ * in the device object returned by the ICD. Without this
+ * structure the code wouldn't know where the loader's device_info
+ * structure is located.
+ */
+ device_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
+ device_info.function = VK_LAYER_DEVICE_INFO;
+ device_info.pNext = &chain_info;
+ device_info.u.deviceInfo.device_info = dev;
+ device_info.u.deviceInfo.pfnNextGetInstanceProcAddr = icd->this_icd_lib->GetInstanceProcAddr;
+
+ loader_create_info.pNext = &device_info;
+
+ if (dev->activated_layer_list.count > 0) {
+ /* Create instance chain of enabled layers */
+ for (int32_t i = dev->activated_layer_list.count - 1; i >= 0; i--) {
+ struct loader_layer_properties *layer_prop = &dev->activated_layer_list.list[i];
+ loader_platform_dl_handle lib_handle;
+
+ lib_handle = loader_add_layer_lib(inst, "device", layer_prop);
+ if (!lib_handle)
+ continue; // TODO what should we do in this case
+ if ((fpGIPA = layer_prop->functions.get_instance_proc_addr) == NULL) {
+ if (layer_prop->functions.str_gipa == NULL || strlen(layer_prop->functions.str_gipa) == 0) {
+ fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr");
+ layer_prop->functions.get_instance_proc_addr = fpGIPA;
+ } else
+ fpGIPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gipa);
+ if (!fpGIPA) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", layer_prop->lib_name);
+
+ /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/
+ continue;
+ }
}
- }
+ if ((fpGDPA = layer_prop->functions.get_device_proc_addr) == NULL) {
+ if (layer_prop->functions.str_gdpa == NULL || strlen(layer_prop->functions.str_gdpa) == 0) {
+ fpGDPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetDeviceProcAddr");
+ layer_prop->functions.get_device_proc_addr = fpGDPA;
+ } else
+ fpGDPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gdpa);
+ if (!fpGDPA) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Failed to find vkGetDeviceProcAddr in layer %s", layer_prop->lib_name);
+
+ /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/
+ continue;
+ }
+ }
+
+ layer_device_link_info[activated_layers].pNext = chain_info.u.pLayerInfo;
+ layer_device_link_info[activated_layers].pfnNextGetInstanceProcAddr = nextGIPA;
+ layer_device_link_info[activated_layers].pfnNextGetDeviceProcAddr = nextGDPA;
+ chain_info.u.pLayerInfo = &layer_device_link_info[activated_layers];
+ nextGIPA = fpGIPA;
+ nextGDPA = fpGDPA;
- loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0,
- "Insert device layer library %s (%s)",
- layer_prop->info.layerName,
- layer_prop->lib_name);
+ loader_log(inst, VK_DEBUG_REPORT_INFO_BIT_EXT, 0,
+ "Insert device layer %s (%s)",
+ layer_prop->info.layerName,
+ layer_prop->lib_name);
+ activated_layers++;
+ }
}
- loader_init_device_dispatch_table(&dev->loader_dispatch, nextGPA,
- (VkDevice) nextObj, (VkDevice) baseObj);
- loader_heap_free(inst, wrappedGpus);
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice) nextGIPA(VK_NULL_HANDLE, "vkCreateDevice");
+ if (fpCreateDevice) {
+ res = fpCreateDevice(physicalDevice, &loader_create_info, pAllocator, &dev->device);
+ } else {
+ // Couldn't find CreateDevice function!
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ /* Initialize device dispatch table */
+ loader_init_device_dispatch_table(&dev->loader_dispatch,
+ nextGDPA,
+ dev->device);
- return dev->activated_layer_list.count;
+ return res;
}
VkResult loader_validate_layers(
@@ -3149,7 +3242,6 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateInstance(
const VkAllocationCallbacks* pAllocator,
VkInstance* pInstance)
{
- struct loader_instance *ptr_instance = *(struct loader_instance **) pInstance;
struct loader_icd *icd;
VkExtensionProperties *prop;
char **filtered_extension_names = NULL;
@@ -3157,11 +3249,22 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateInstance(
VkResult res = VK_SUCCESS;
bool success = false;
+ VkLayerInstanceCreateInfo *chain_info = (VkLayerInstanceCreateInfo *) pCreateInfo->pNext;
+ while (chain_info && !(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
+ && chain_info->function == VK_LAYER_INSTANCE_INFO)) {
+ chain_info = (VkLayerInstanceCreateInfo *) chain_info->pNext;
+ }
+ assert(chain_info != NULL);
+
+ struct loader_instance *ptr_instance = (struct loader_instance *) chain_info->u.instanceInfo.instance_info;
memcpy(&icd_create_info, pCreateInfo, sizeof(icd_create_info));
icd_create_info.enabledLayerCount = 0;
icd_create_info.ppEnabledLayerNames = NULL;
+ // TODO: Should really strip off the VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO entries
+ icd_create_info.pNext = NULL;
+
/*
* NOTE: Need to filter the extensions to only those
* supported by the ICD.
@@ -3233,6 +3336,8 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateInstance(
}
}
+ *pInstance = (VkInstance) ptr_instance;
+
return VK_SUCCESS;
}
@@ -3362,6 +3467,7 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_EnumeratePhysicalDevices(
VkPhysicalDevice* pPhysicalDevices)
{
uint32_t i;
+ uint32_t copy_count = 0;
struct loader_instance *ptr_instance = (struct loader_instance *) instance;
VkResult res = VK_SUCCESS;
@@ -3374,9 +3480,15 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_EnumeratePhysicalDevices(
return res;
}
- for (i = 0; i < ptr_instance->total_gpu_count; i++) {
+ copy_count = (ptr_instance->total_gpu_count < *pPhysicalDeviceCount) ? ptr_instance->total_gpu_count : *pPhysicalDeviceCount;
+ for (i = 0; i < copy_count; i++) {
pPhysicalDevices[i] = (VkPhysicalDevice) &ptr_instance->phys_devs[i];
}
+ *pPhysicalDeviceCount = copy_count;
+
+ if (copy_count < ptr_instance->total_gpu_count) {
+ return VK_INCOMPLETE;
+ }
return res;
}
@@ -3578,21 +3690,12 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateDevice(
}
}
- // since physicalDevice object maybe wrapped by a layer need to get unwrapped version
- // we haven't yet called down the chain for the layer to unwrap the object
- res = icd->CreateDevice(phys_dev->phys_dev, &device_create_info, pAllocator, pDevice);
- if (res != VK_SUCCESS) {
- loader_destroy_generic_list(inst, (struct loader_generic_list *) &activated_layer_list);
- return res;
- }
-
- dev = loader_add_logical_device(inst, *pDevice, &icd->logical_device_list);
+ dev = loader_add_logical_device(inst, &icd->logical_device_list);
if (dev == NULL) {
loader_destroy_generic_list(inst, (struct loader_generic_list *) &activated_layer_list);
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
- loader_init_dispatch(*pDevice, &dev->loader_dispatch);
/* move the locally filled layer list into the device, and pass ownership of the memory */
dev->activated_layer_list.capacity = activated_layer_list.capacity;
@@ -3600,11 +3703,20 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateDevice(
dev->activated_layer_list.list = activated_layer_list.list;
memset(&activated_layer_list, 0, sizeof(activated_layer_list));
- /* activate any layers on device chain which terminates with device*/
- loader_activate_device_layers(inst, dev, *pDevice);
+ /* activate any layers on device chain which terminates with device*/
+ res = loader_enable_device_layers(inst, icd, &dev->activated_layer_list, pCreateInfo, &inst->device_layer_list);
+ if (res != VK_SUCCESS) {
+ loader_destroy_logical_device(inst, dev);
+ return res;
+ }
+
+ res = loader_create_device_chain(physicalDevice, pCreateInfo, pAllocator, inst, icd, dev);
+ if (res != VK_SUCCESS) {
+ loader_destroy_logical_device(inst, dev);
+ return res;
+ }
- /* finally can call down the chain */
- res = dev->loader_dispatch.core_dispatch.CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
+ *pDevice = dev->device;
/* initialize any device extension dispatch entry's from the instance list*/
loader_init_dispatch_dev_ext(inst, dev);
@@ -3614,7 +3726,6 @@ VKAPI_ATTR VkResult VKAPI_CALL loader_CreateDevice(
loader_init_device_extension_dispatch_table(&dev->loader_dispatch,
dev->loader_dispatch.core_dispatch.GetDeviceProcAddr,
*pDevice);
- dev->loader_dispatch.core_dispatch.CreateDevice = icd->CreateDevice;
return res;
}