if (inst == VK_NULL_HANDLE) {
return NULL;
}
+
VkLayerInstanceDispatchTable *disp_table = *(VkLayerInstanceDispatchTable **)inst;
- void *addr;
if (disp_table == NULL) return NULL;
+ struct loader_instance *loader_inst = loader_get_instance(inst);
+
+ if (loader_inst->instance_finished_creation) {
+ disp_table = &loader_inst->terminator_dispatch;
+ }
+
bool found_name;
- addr = loader_lookup_instance_dispatch_table(disp_table, pName, &found_name);
+ void *addr = loader_lookup_instance_dispatch_table(disp_table, pName, &found_name);
if (found_name) {
return addr;
}
if (inst == VK_NULL_HANDLE) {
return NULL;
}
- struct loader_instance *loader_inst = loader_get_instance(inst);
-
VkLayerInstanceDispatchTable *disp_table = *(VkLayerInstanceDispatchTable **)inst;
- void *addr;
if (disp_table == NULL) return NULL;
+ struct loader_instance *loader_inst = loader_get_instance(inst);
+
// The VK_EXT_debug_utils functions need a special case here so the terminators can still be found from
// vkGetInstanceProcAddr This is because VK_EXT_debug_utils is an instance level extension with device level functions, and
// is 'supported' by the loader.
: NULL;
}
+ if (loader_inst->instance_finished_creation) {
+ disp_table = &loader_inst->terminator_dispatch;
+ }
+
bool found_name;
- addr = loader_lookup_instance_dispatch_table(disp_table, pName, &found_name);
+ void *addr = loader_lookup_instance_dispatch_table(disp_table, pName, &found_name);
if (found_name) {
return addr;
}
}
if (res == VK_SUCCESS) {
+ // Copy the current disp table into the terminator_dispatch table so we can use it in loader_gpa_instance_terminator()
+ memcpy(&inst->terminator_dispatch, &inst->disp->layer_inst_disp, sizeof(VkLayerInstanceDispatchTable));
+
loader_init_instance_core_dispatch_table(&inst->disp->layer_inst_disp, next_gipa, *created_instance);
inst->instance = *created_instance;
}
struct loader_instance_dispatch_table *disp; // must be first entry in structure
uint64_t magic; // Should be LOADER_MAGIC_NUMBER
+ // Store all the terminators for instance functions in case a layer queries one *after* vkCreateInstance
+ VkLayerInstanceDispatchTable terminator_dispatch;
+
// Vulkan API version the app is intending to use.
loader_api_version app_api_version;
VkAllocationCallbacks alloc_callbacks;
+ // Set to true after vkCreateInstance has returned - necessary for loader_gpa_instance_terminator()
+ bool instance_finished_creation;
+
bool portability_enumeration_enabled;
bool wsi_surface_enabled;
// GetInstanceProcAddr functions to return valid extension functions
// if enabled.
loader_activate_instance_layer_extensions(ptr_instance, created_instance);
+ ptr_instance->instance_finished_creation = true;
} else if (VK_ERROR_EXTENSION_NOT_PRESENT == res && !ptr_instance->create_terminator_invalid_extension) {
loader_log(ptr_instance, VULKAN_LOADER_WARN_BIT, 0,
"vkCreateInstance: Layer returning invalid extension error not triggered by ICD/Loader (Policy #LLP_LAYER_17).");
inst->pfn_inst_init = NULL;
inst->loader_disp = *(reinterpret_cast<VkLayerInstanceDispatchTable **>(inst->obj));
}
- layer_init_instance_dispatch_table(*pInstance, &inst->layer_disp, fpGetInstanceProcAddr);
+ layer_init_instance_dispatch_table(inst->obj, &inst->layer_disp, fpGetInstanceProcAddr);
bool found = false;
for (uint32_t layer = 0; layer < pCreateInfo->enabledLayerCount; ++layer) {
std::string layer_name = pCreateInfo->ppEnabledLayerNames[layer];