| 185 | } |
| 186 | |
| 187 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, |
| 188 | VkInstance *pInstance) { |
| 189 | #if defined(_WIN32) && defined(_CRTDBG_MODE_FILE) |
| 190 | #if !defined(NDEBUG) |
| 191 | _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); |
| 192 | _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); |
| 193 | #endif |
| 194 | // Avoid "Abort, Retry, Ignore" dialog boxes |
| 195 | _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); |
| 196 | SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); |
| 197 | _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); |
| 198 | _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); |
| 199 | #endif |
| 200 | |
| 201 | VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); |
| 202 | |
| 203 | assert(chain_info->u.pLayerInfo); |
| 204 | PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; |
| 205 | PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); |
| 206 | if (fpCreateInstance == NULL) { |
| 207 | return VK_ERROR_INITIALIZATION_FAILED; |
| 208 | } |
| 209 | |
| 210 | // Advance the link info for the next element on the chain |
| 211 | chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; |
| 212 | |
| 213 | VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); |
| 214 | if (result != VK_SUCCESS) return result; |
| 215 | |
| 216 | monitor_layer_data *my_data = GetLayerDataPtr(get_dispatch_key(*pInstance), layer_data_map); |
| 217 | my_data->instance_dispatch_table = new VkuInstanceDispatchTable; |
| 218 | vkuInitInstanceDispatchTable(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); |
| 219 | |
| 220 | #if defined(VK_USE_PLATFORM_XCB_KHR) |
| 221 | // Initialize connection to null in case vkCreateXcbSurfaceKHR is never called |
| 222 | my_data->connection = nullptr; |
| 223 | // Load the xcb library and initialize xcb function pointers |
| 224 | if (!xcb.xcbLib) { |
| 225 | xcb.xcbLib = dlopen("libxcb.so", RTLD_NOW | RTLD_LOCAL); |
| 226 | if (xcb.xcbLib) { |
| 227 | xcb.change_property = reinterpret_cast<decltype(xcb_change_property) *>(dlsym(xcb.xcbLib, "xcb_change_property")); |
| 228 | xcb.flush = reinterpret_cast<decltype(xcb_flush) *>(dlsym(xcb.xcbLib, "xcb_flush")); |
| 229 | xcb.get_property = reinterpret_cast<decltype(xcb_get_property) *>(dlsym(xcb.xcbLib, "xcb_get_property")); |
| 230 | xcb.get_property_reply = |
| 231 | reinterpret_cast<decltype(xcb_get_property_reply) *>(dlsym(xcb.xcbLib, "xcb_get_property_reply")); |
| 232 | xcb.get_property_value_length = |
| 233 | reinterpret_cast<decltype(xcb_get_property_value_length) *>(dlsym(xcb.xcbLib, "xcb_get_property_value_length")); |
| 234 | xcb.get_property_value = |
| 235 | reinterpret_cast<decltype(xcb_get_property_value) *>(dlsym(xcb.xcbLib, "xcb_get_property_value")); |
| 236 | if (!xcb.change_property || !xcb.flush || !xcb.get_property || !xcb.get_property_reply || |
| 237 | !xcb.get_property_value_length || !xcb.get_property_value) { |
| 238 | // Something went wrong querying the entry points - set xcb.xdbLib to NULL |
| 239 | // to indicate we didn't successufly load libxcb.so |
| 240 | xcb.xcbLib = NULL; |
| 241 | } |
| 242 | } |
| 243 | } |
| 244 | #endif |