1 /* 2 * Copyright (c) 2015-2017 The Khronos Group Inc. 3 * Copyright (c) 2015-2017 Valve Corporation 4 * Copyright (c) 2015-2017 LunarG, Inc. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * Author: Mark Young <marky (at) lunarg.com> 19 * Author: Lenny Komow <lenny (at) lunarg.com> 20 */ 21 22 #define _GNU_SOURCE 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include "vk_loader_platform.h" 27 #include "loader.h" 28 #include "vk_loader_extensions.h" 29 #include <vulkan/vk_icd.h> 30 #include "wsi.h" 31 #include "debug_report.h" 32 33 // ---- Manually added trampoline/terminator functions 34 35 // These functions, for whatever reason, require more complex changes than 36 // can easily be automatically generated. 37 VkResult setupLoaderTrampPhysDevGroups(VkInstance instance); 38 VkResult setupLoaderTermPhysDevGroups(struct loader_instance *inst); 39 40 // ---- VK_KHX_device_group extension trampoline/terminators 41 42 VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceGroupsKHX( 43 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, 44 VkPhysicalDeviceGroupPropertiesKHX *pPhysicalDeviceGroupProperties) { 45 VkResult res = VK_SUCCESS; 46 uint32_t count; 47 uint32_t i; 48 struct loader_instance *inst = NULL; 49 50 loader_platform_thread_lock_mutex(&loader_lock); 51 52 inst = loader_get_instance(instance); 53 if (NULL == inst) { 54 res = VK_ERROR_INITIALIZATION_FAILED; 55 goto out; 56 } 57 58 if (NULL == pPhysicalDeviceGroupCount) { 59 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 60 "vkEnumeratePhysicalDeviceGroupsKHX: Received NULL pointer for physical " 61 "device group count return value."); 62 res = VK_ERROR_INITIALIZATION_FAILED; 63 goto out; 64 } 65 66 VkResult setup_res = setupLoaderTrampPhysDevGroups(instance); 67 if (VK_SUCCESS != setup_res) { 68 res = setup_res; 69 goto out; 70 } 71 72 count = inst->phys_dev_group_count_tramp; 73 74 // Wrap the PhysDev object for loader usage, return wrapped objects 75 if (NULL != pPhysicalDeviceGroupProperties) { 76 if (inst->phys_dev_group_count_tramp > *pPhysicalDeviceGroupCount) { 77 loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 78 "vkEnumeratePhysicalDeviceGroupsKHX: Trimming device group count down" 79 " by application request from %d to %d physical device groups", 80 inst->phys_dev_group_count_tramp, *pPhysicalDeviceGroupCount); 81 count = *pPhysicalDeviceGroupCount; 82 res = VK_INCOMPLETE; 83 } 84 for (i = 0; i < count; i++) { 85 memcpy(&pPhysicalDeviceGroupProperties[i], inst->phys_dev_groups_tramp[i], 86 sizeof(VkPhysicalDeviceGroupPropertiesKHX)); 87 } 88 } 89 90 *pPhysicalDeviceGroupCount = count; 91 92 out: 93 94 loader_platform_thread_unlock_mutex(&loader_lock); 95 return res; 96 } 97 98 VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroupsKHX( 99 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, 100 VkPhysicalDeviceGroupPropertiesKHX *pPhysicalDeviceGroupProperties) { 101 struct loader_instance *inst = (struct loader_instance *)instance; 102 VkResult res = VK_SUCCESS; 103 104 // Always call the setup loader terminator physical device groups because they may 105 // have changed at any point. 106 res = setupLoaderTermPhysDevGroups(inst); 107 if (VK_SUCCESS != res) { 108 goto out; 109 } 110 111 uint32_t copy_count = inst->phys_dev_group_count_term; 112 if (NULL != pPhysicalDeviceGroupProperties) { 113 if (copy_count > *pPhysicalDeviceGroupCount) { 114 copy_count = *pPhysicalDeviceGroupCount; 115 res = VK_INCOMPLETE; 116 } 117 118 for (uint32_t i = 0; i < copy_count; i++) { 119 memcpy(&pPhysicalDeviceGroupProperties[i], inst->phys_dev_groups_term[i], 120 sizeof(VkPhysicalDeviceGroupPropertiesKHX)); 121 } 122 } 123 124 *pPhysicalDeviceGroupCount = copy_count; 125 126 out: 127 128 return res; 129 } 130 131 // ---- VK_NV_external_memory_capabilities extension trampoline/terminators 132 133 VKAPI_ATTR VkResult VKAPI_CALL 134 GetPhysicalDeviceExternalImageFormatPropertiesNV( 135 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, 136 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, 137 VkExternalMemoryHandleTypeFlagsNV externalHandleType, 138 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) { 139 const VkLayerInstanceDispatchTable *disp; 140 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 141 disp = loader_get_instance_layer_dispatch(physicalDevice); 142 143 return disp->GetPhysicalDeviceExternalImageFormatPropertiesNV( 144 unwrapped_phys_dev, format, type, tiling, usage, flags, 145 externalHandleType, pExternalImageFormatProperties); 146 } 147 148 VKAPI_ATTR VkResult VKAPI_CALL 149 terminator_GetPhysicalDeviceExternalImageFormatPropertiesNV( 150 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, 151 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, 152 VkExternalMemoryHandleTypeFlagsNV externalHandleType, 153 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) { 154 struct loader_physical_device_term *phys_dev_term = 155 (struct loader_physical_device_term *)physicalDevice; 156 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 157 158 if (!icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV) { 159 if (externalHandleType) { 160 return VK_ERROR_FORMAT_NOT_SUPPORTED; 161 } 162 163 if (!icd_term->dispatch.GetPhysicalDeviceImageFormatProperties) { 164 return VK_ERROR_INITIALIZATION_FAILED; 165 } 166 167 pExternalImageFormatProperties->externalMemoryFeatures = 0; 168 pExternalImageFormatProperties->exportFromImportedHandleTypes = 0; 169 pExternalImageFormatProperties->compatibleHandleTypes = 0; 170 171 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties( 172 phys_dev_term->phys_dev, format, type, tiling, usage, flags, 173 &pExternalImageFormatProperties->imageFormatProperties); 174 } 175 176 return icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV( 177 phys_dev_term->phys_dev, format, type, tiling, usage, flags, 178 externalHandleType, pExternalImageFormatProperties); 179 } 180 181 // ---- VK_KHR_get_physical_device_properties2 extension trampoline/terminators 182 183 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR *pFeatures) { 184 const VkLayerInstanceDispatchTable *disp; 185 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 186 disp = loader_get_instance_layer_dispatch(physicalDevice); 187 disp->GetPhysicalDeviceFeatures2KHR(unwrapped_phys_dev, pFeatures); 188 } 189 190 VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, 191 VkPhysicalDeviceFeatures2KHR *pFeatures) { 192 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 193 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 194 195 if (icd_term->dispatch.GetPhysicalDeviceFeatures2KHR != NULL) { 196 // Pass the call to the driver 197 icd_term->dispatch.GetPhysicalDeviceFeatures2KHR(phys_dev_term->phys_dev, pFeatures); 198 } else { 199 // Emulate the call 200 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 201 "vkGetPhysicalDeviceFeatures2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFeatures", 202 icd_term->scanned_icd->lib_name); 203 204 // Write to the VkPhysicalDeviceFeatures2KHR struct 205 icd_term->dispatch.GetPhysicalDeviceFeatures(phys_dev_term->phys_dev, &pFeatures->features); 206 207 void *pNext = pFeatures->pNext; 208 while (pNext != NULL) { 209 switch (*(VkStructureType *)pNext) { 210 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHX: { 211 // Skip the check if VK_KHX_multiview is enabled because it's a device extension 212 // Write to the VkPhysicalDeviceMultiviewFeaturesKHX struct 213 VkPhysicalDeviceMultiviewFeaturesKHX *multiview_features = pNext; 214 multiview_features->multiview = VK_FALSE; 215 multiview_features->multiviewGeometryShader = VK_FALSE; 216 multiview_features->multiviewTessellationShader = VK_FALSE; 217 218 pNext = multiview_features->pNext; 219 break; 220 } 221 default: { 222 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 223 "vkGetPhysicalDeviceFeatures2KHR: Emulation found unrecognized structure type in pFeatures->pNext - " 224 "this struct will be ignored"); 225 226 struct VkStructureHeader *header = pNext; 227 pNext = (void *)header->pNext; 228 break; 229 } 230 } 231 } 232 } 233 } 234 235 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, 236 VkPhysicalDeviceProperties2KHR *pProperties) { 237 const VkLayerInstanceDispatchTable *disp; 238 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 239 disp = loader_get_instance_layer_dispatch(physicalDevice); 240 disp->GetPhysicalDeviceProperties2KHR(unwrapped_phys_dev, pProperties); 241 } 242 243 VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, 244 VkPhysicalDeviceProperties2KHR *pProperties) { 245 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 246 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 247 248 if (icd_term->dispatch.GetPhysicalDeviceProperties2KHR != NULL) { 249 // Pass the call to the driver 250 icd_term->dispatch.GetPhysicalDeviceProperties2KHR(phys_dev_term->phys_dev, pProperties); 251 } else { 252 // Emulate the call 253 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 254 "vkGetPhysicalDeviceProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceProperties", 255 icd_term->scanned_icd->lib_name); 256 257 // Write to the VkPhysicalDeviceProperties2KHR struct 258 icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &pProperties->properties); 259 260 void *pNext = pProperties->pNext; 261 while (pNext != NULL) { 262 switch (*(VkStructureType *)pNext) { 263 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR: { 264 VkPhysicalDeviceIDPropertiesKHR *id_properties = pNext; 265 266 // Verify that "VK_KHR_external_memory_capabilities" is enabled 267 if (icd_term->this_instance->enabled_known_extensions.khr_external_memory_capabilities) { 268 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 269 "vkGetPhysicalDeviceProperties2KHR: Emulation cannot generate unique IDs for struct " 270 "VkPhysicalDeviceIDPropertiesKHR - setting IDs to zero instead"); 271 272 // Write to the VkPhysicalDeviceIDPropertiesKHR struct 273 memset(id_properties->deviceUUID, 0, VK_UUID_SIZE); 274 memset(id_properties->driverUUID, 0, VK_UUID_SIZE); 275 id_properties->deviceLUIDValid = VK_FALSE; 276 } 277 278 pNext = id_properties->pNext; 279 break; 280 } 281 default: { 282 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 283 "vkGetPhysicalDeviceProperties2KHR: Emulation found unrecognized structure type in " 284 "pProperties->pNext - this struct will be ignored"); 285 286 struct VkStructureHeader *header = pNext; 287 pNext = (void *)header->pNext; 288 break; 289 } 290 } 291 } 292 } 293 } 294 295 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format, 296 VkFormatProperties2KHR *pFormatProperties) { 297 const VkLayerInstanceDispatchTable *disp; 298 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 299 disp = loader_get_instance_layer_dispatch(physicalDevice); 300 disp->GetPhysicalDeviceFormatProperties2KHR(unwrapped_phys_dev, format, pFormatProperties); 301 } 302 303 VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format, 304 VkFormatProperties2KHR *pFormatProperties) { 305 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 306 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 307 308 if (icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR != NULL) { 309 // Pass the call to the driver 310 icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR(phys_dev_term->phys_dev, format, pFormatProperties); 311 } else { 312 // Emulate the call 313 loader_log( 314 icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 315 "vkGetPhysicalDeviceFormatProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFormatProperties", 316 icd_term->scanned_icd->lib_name); 317 318 // Write to the VkFormatProperties2KHR struct 319 icd_term->dispatch.GetPhysicalDeviceFormatProperties(phys_dev_term->phys_dev, format, &pFormatProperties->formatProperties); 320 321 if (pFormatProperties->pNext != NULL) { 322 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 323 "vkGetPhysicalDeviceFormatProperties2KHR: Emulation found unrecognized structure type in " 324 "pFormatProperties->pNext - this struct will be ignored"); 325 } 326 } 327 } 328 329 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties2KHR( 330 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo, 331 VkImageFormatProperties2KHR *pImageFormatProperties) { 332 const VkLayerInstanceDispatchTable *disp; 333 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 334 disp = loader_get_instance_layer_dispatch(physicalDevice); 335 return disp->GetPhysicalDeviceImageFormatProperties2KHR(unwrapped_phys_dev, pImageFormatInfo, pImageFormatProperties); 336 } 337 338 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties2KHR( 339 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo, 340 VkImageFormatProperties2KHR *pImageFormatProperties) { 341 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 342 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 343 344 if (icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR != NULL) { 345 // Pass the call to the driver 346 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR(phys_dev_term->phys_dev, pImageFormatInfo, 347 pImageFormatProperties); 348 } else { 349 // Emulate the call 350 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 351 "vkGetPhysicalDeviceImageFormatProperties2KHR: Emulating call in ICD \"%s\" using " 352 "vkGetPhysicalDeviceImageFormatProperties", 353 icd_term->scanned_icd->lib_name); 354 355 // If there is more info in either pNext, then this is unsupported 356 if (pImageFormatInfo->pNext != NULL || pImageFormatProperties->pNext != NULL) { 357 return VK_ERROR_FORMAT_NOT_SUPPORTED; 358 } 359 360 // Write to the VkImageFormatProperties2KHR struct 361 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties( 362 phys_dev_term->phys_dev, pImageFormatInfo->format, pImageFormatInfo->type, pImageFormatInfo->tiling, 363 pImageFormatInfo->usage, pImageFormatInfo->flags, &pImageFormatProperties->imageFormatProperties); 364 } 365 } 366 367 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice, 368 uint32_t *pQueueFamilyPropertyCount, 369 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { 370 const VkLayerInstanceDispatchTable *disp; 371 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 372 disp = loader_get_instance_layer_dispatch(physicalDevice); 373 disp->GetPhysicalDeviceQueueFamilyProperties2KHR(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties); 374 } 375 376 VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties2KHR( 377 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { 378 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 379 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 380 381 if (icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR != NULL) { 382 // Pass the call to the driver 383 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, 384 pQueueFamilyProperties); 385 } else { 386 // Emulate the call 387 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 388 "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Emulating call in ICD \"%s\" using " 389 "vkGetPhysicalDeviceQueueFamilyProperties", 390 icd_term->scanned_icd->lib_name); 391 392 if (pQueueFamilyProperties == NULL || *pQueueFamilyPropertyCount == 0) { 393 // Write to pQueueFamilyPropertyCount 394 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, NULL); 395 } else { 396 // Allocate a temporary array for the output of the old function 397 VkQueueFamilyProperties *properties = loader_stack_alloc(*pQueueFamilyPropertyCount * sizeof(VkQueueFamilyProperties)); 398 if (properties == NULL) { 399 *pQueueFamilyPropertyCount = 0; 400 loader_log( 401 icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 402 "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Out of memory - Failed to allocate array for loader emulation."); 403 return; 404 } 405 406 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, 407 properties); 408 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) { 409 // Write to the VkQueueFamilyProperties2KHR struct 410 memcpy(&pQueueFamilyProperties[i].queueFamilyProperties, &properties[i], sizeof(VkQueueFamilyProperties)); 411 412 if (pQueueFamilyProperties[i].pNext != NULL) { 413 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 414 "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Emulation found unrecognized structure type in " 415 "pQueueFamilyProperties[%d].pNext - this struct will be ignored", 416 i); 417 } 418 } 419 } 420 } 421 } 422 423 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties2KHR(VkPhysicalDevice physicalDevice, 424 VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties) { 425 const VkLayerInstanceDispatchTable *disp; 426 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 427 disp = loader_get_instance_layer_dispatch(physicalDevice); 428 disp->GetPhysicalDeviceMemoryProperties2KHR(unwrapped_phys_dev, pMemoryProperties); 429 } 430 431 VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties2KHR( 432 VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties) { 433 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 434 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 435 436 if (icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR != NULL) { 437 // Pass the call to the driver 438 icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR(phys_dev_term->phys_dev, pMemoryProperties); 439 } else { 440 // Emulate the call 441 loader_log( 442 icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 443 "vkGetPhysicalDeviceMemoryProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceMemoryProperties", 444 icd_term->scanned_icd->lib_name); 445 446 // Write to the VkPhysicalDeviceMemoryProperties2KHR struct 447 icd_term->dispatch.GetPhysicalDeviceMemoryProperties(phys_dev_term->phys_dev, &pMemoryProperties->memoryProperties); 448 449 if (pMemoryProperties->pNext != NULL) { 450 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 451 "vkGetPhysicalDeviceMemoryProperties2KHR: Emulation found unrecognized structure type in " 452 "pMemoryProperties->pNext - this struct will be ignored"); 453 } 454 } 455 } 456 457 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties2KHR( 458 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount, 459 VkSparseImageFormatProperties2KHR *pProperties) { 460 const VkLayerInstanceDispatchTable *disp; 461 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 462 disp = loader_get_instance_layer_dispatch(physicalDevice); 463 disp->GetPhysicalDeviceSparseImageFormatProperties2KHR(unwrapped_phys_dev, pFormatInfo, pPropertyCount, pProperties); 464 } 465 466 VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties2KHR( 467 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount, 468 VkSparseImageFormatProperties2KHR *pProperties) { 469 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 470 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 471 472 if (icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR != NULL) { 473 // Pass the call to the driver 474 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR(phys_dev_term->phys_dev, pFormatInfo, pPropertyCount, 475 pProperties); 476 } else { 477 // Emulate the call 478 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 479 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulating call in ICD \"%s\" using " 480 "vkGetPhysicalDeviceSparseImageFormatProperties", 481 icd_term->scanned_icd->lib_name); 482 483 if (pFormatInfo->pNext != NULL) { 484 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 485 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulation found unrecognized structure type in " 486 "pFormatInfo->pNext - this struct will be ignored"); 487 } 488 489 if (pProperties == NULL || *pPropertyCount == 0) { 490 // Write to pPropertyCount 491 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties( 492 phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage, 493 pFormatInfo->tiling, pPropertyCount, NULL); 494 } else { 495 // Allocate a temporary array for the output of the old function 496 VkSparseImageFormatProperties *properties = 497 loader_stack_alloc(*pPropertyCount * sizeof(VkSparseImageMemoryRequirements)); 498 if (properties == NULL) { 499 *pPropertyCount = 0; 500 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 501 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Out of memory - Failed to allocate array for " 502 "loader emulation."); 503 return; 504 } 505 506 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties( 507 phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage, 508 pFormatInfo->tiling, pPropertyCount, properties); 509 for (uint32_t i = 0; i < *pPropertyCount; ++i) { 510 // Write to the VkSparseImageFormatProperties2KHR struct 511 memcpy(&pProperties[i].properties, &properties[i], sizeof(VkSparseImageFormatProperties)); 512 513 if (pProperties[i].pNext != NULL) { 514 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 515 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulation found unrecognized structure type in " 516 "pProperties[%d].pNext - this struct will be ignored", 517 i); 518 } 519 } 520 } 521 } 522 } 523 524 // ---- VK_KHR_get_surface_capabilities2 extension trampoline/terminators 525 526 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, 527 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 528 VkSurfaceCapabilities2KHR *pSurfaceCapabilities) { 529 const VkLayerInstanceDispatchTable *disp; 530 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 531 disp = loader_get_instance_layer_dispatch(physicalDevice); 532 return disp->GetPhysicalDeviceSurfaceCapabilities2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceCapabilities); 533 } 534 535 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2KHR( 536 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 537 VkSurfaceCapabilities2KHR *pSurfaceCapabilities) { 538 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 539 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 540 541 VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface); 542 uint8_t icd_index = phys_dev_term->icd_index; 543 544 if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) { 545 // Pass the call to the driver, possibly unwrapping the ICD surface 546 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) { 547 VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo; 548 info_copy.surface = icd_surface->real_icd_surfaces[icd_index]; 549 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy, 550 pSurfaceCapabilities); 551 } else { 552 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, pSurfaceInfo, 553 pSurfaceCapabilities); 554 } 555 } else { 556 // Emulate the call 557 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 558 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulating call in ICD \"%s\" using " 559 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", 560 icd_term->scanned_icd->lib_name); 561 562 if (pSurfaceInfo->pNext != NULL) { 563 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 564 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in " 565 "pSurfaceInfo->pNext - this struct will be ignored"); 566 } 567 568 // Write to the VkSurfaceCapabilities2KHR struct 569 VkSurfaceKHR surface = pSurfaceInfo->surface; 570 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) { 571 surface = icd_surface->real_icd_surfaces[icd_index]; 572 } 573 VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface, 574 &pSurfaceCapabilities->surfaceCapabilities); 575 576 if (pSurfaceCapabilities->pNext != NULL) { 577 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 578 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in " 579 "pSurfaceCapabilities->pNext - this struct will be ignored"); 580 } 581 return res; 582 } 583 } 584 585 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, 586 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 587 uint32_t *pSurfaceFormatCount, 588 VkSurfaceFormat2KHR *pSurfaceFormats) { 589 const VkLayerInstanceDispatchTable *disp; 590 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 591 disp = loader_get_instance_layer_dispatch(physicalDevice); 592 return disp->GetPhysicalDeviceSurfaceFormats2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats); 593 } 594 595 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, 596 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 597 uint32_t *pSurfaceFormatCount, 598 VkSurfaceFormat2KHR *pSurfaceFormats) { 599 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 600 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 601 602 VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface); 603 uint8_t icd_index = phys_dev_term->icd_index; 604 605 if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) { 606 // Pass the call to the driver, possibly unwrapping the ICD surface 607 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) { 608 VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo; 609 info_copy.surface = icd_surface->real_icd_surfaces[icd_index]; 610 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount, 611 pSurfaceFormats); 612 } else { 613 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, pSurfaceInfo, 614 pSurfaceFormatCount, pSurfaceFormats); 615 } 616 } else { 617 // Emulate the call 618 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 619 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceSurfaceFormatsKHR", 620 icd_term->scanned_icd->lib_name); 621 622 if (pSurfaceInfo->pNext != NULL) { 623 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 624 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in pSurfaceInfo->pNext " 625 "- this struct will be ignored"); 626 } 627 628 VkSurfaceKHR surface = pSurfaceInfo->surface; 629 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) { 630 surface = icd_surface->real_icd_surfaces[icd_index]; 631 } 632 633 if (*pSurfaceFormatCount == 0 || pSurfaceFormats == NULL) { 634 // Write to pSurfaceFormatCount 635 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount, 636 NULL); 637 } else { 638 // Allocate a temporary array for the output of the old function 639 VkSurfaceFormatKHR *formats = loader_stack_alloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR)); 640 if (formats == NULL) { 641 return VK_ERROR_OUT_OF_HOST_MEMORY; 642 } 643 644 VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, 645 pSurfaceFormatCount, formats); 646 for (uint32_t i = 0; i < *pSurfaceFormatCount; ++i) { 647 pSurfaceFormats[i].surfaceFormat = formats[i]; 648 if (pSurfaceFormats[i].pNext != NULL) { 649 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 650 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in " 651 "pSurfaceFormats[%d].pNext - this struct will be ignored", 652 i); 653 } 654 } 655 return res; 656 } 657 } 658 } 659 660 // ---- VK_EXT_display_surface_counter extension trampoline/terminators 661 662 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 663 VkSurfaceCapabilities2EXT *pSurfaceCapabilities) { 664 const VkLayerInstanceDispatchTable *disp; 665 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 666 disp = loader_get_instance_layer_dispatch(physicalDevice); 667 return disp->GetPhysicalDeviceSurfaceCapabilities2EXT(unwrapped_phys_dev, surface, pSurfaceCapabilities); 668 } 669 670 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2EXT( 671 VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT *pSurfaceCapabilities) { 672 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 673 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 674 675 VkIcdSurface *icd_surface = (VkIcdSurface *)(surface); 676 uint8_t icd_index = phys_dev_term->icd_index; 677 678 // Unwrap the surface if needed 679 VkSurfaceKHR unwrapped_surface = surface; 680 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) { 681 unwrapped_surface = icd_surface->real_icd_surfaces[icd_index]; 682 } 683 684 if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT != NULL) { 685 // Pass the call to the driver 686 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT(phys_dev_term->phys_dev, unwrapped_surface, 687 pSurfaceCapabilities); 688 } else { 689 // Emulate the call 690 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 691 "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulating call in ICD \"%s\" using " 692 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", 693 icd_term->scanned_icd->lib_name); 694 695 VkSurfaceCapabilitiesKHR surface_caps; 696 VkResult res = 697 icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, unwrapped_surface, &surface_caps); 698 pSurfaceCapabilities->minImageCount = surface_caps.minImageCount; 699 pSurfaceCapabilities->maxImageCount = surface_caps.maxImageCount; 700 pSurfaceCapabilities->currentExtent = surface_caps.currentExtent; 701 pSurfaceCapabilities->minImageExtent = surface_caps.minImageExtent; 702 pSurfaceCapabilities->maxImageExtent = surface_caps.maxImageExtent; 703 pSurfaceCapabilities->maxImageArrayLayers = surface_caps.maxImageArrayLayers; 704 pSurfaceCapabilities->supportedTransforms = surface_caps.supportedTransforms; 705 pSurfaceCapabilities->currentTransform = surface_caps.currentTransform; 706 pSurfaceCapabilities->supportedCompositeAlpha = surface_caps.supportedCompositeAlpha; 707 pSurfaceCapabilities->supportedUsageFlags = surface_caps.supportedUsageFlags; 708 pSurfaceCapabilities->supportedSurfaceCounters = 0; 709 710 if (pSurfaceCapabilities->pNext != NULL) { 711 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 712 "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulation found unrecognized structure type in " 713 "pSurfaceCapabilities->pNext - this struct will be ignored"); 714 } 715 716 return res; 717 } 718 } 719 720 // ---- VK_EXT_direct_mode_display extension trampoline/terminators 721 722 VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) { 723 const VkLayerInstanceDispatchTable *disp; 724 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 725 disp = loader_get_instance_layer_dispatch(physicalDevice); 726 return disp->ReleaseDisplayEXT(unwrapped_phys_dev, display); 727 } 728 729 VKAPI_ATTR VkResult VKAPI_CALL terminator_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) { 730 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 731 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 732 733 if (icd_term->dispatch.ReleaseDisplayEXT == NULL) { 734 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 735 "ICD \"%s\" associated with VkPhysicalDevice does not support vkReleaseDisplayEXT - Consequently, the call is " 736 "invalid because it should not be possible to acquire a display on this device", 737 icd_term->scanned_icd->lib_name); 738 } 739 return icd_term->dispatch.ReleaseDisplayEXT(phys_dev_term->phys_dev, display); 740 } 741 742 // ---- VK_EXT_acquire_xlib_display extension trampoline/terminators 743 744 #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 745 VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, VkDisplayKHR display) { 746 const VkLayerInstanceDispatchTable *disp; 747 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 748 disp = loader_get_instance_layer_dispatch(physicalDevice); 749 return disp->AcquireXlibDisplayEXT(unwrapped_phys_dev, dpy, display); 750 } 751 752 VKAPI_ATTR VkResult VKAPI_CALL terminator_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, 753 VkDisplayKHR display) { 754 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 755 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 756 757 if (icd_term->dispatch.AcquireXlibDisplayEXT != NULL) { 758 // Pass the call to the driver 759 return icd_term->dispatch.AcquireXlibDisplayEXT(phys_dev_term->phys_dev, dpy, display); 760 } else { 761 // Emulate the call 762 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 763 "vkAcquireXLibDisplayEXT: Emulating call in ICD \"%s\" by returning error", icd_term->scanned_icd->lib_name); 764 765 // Fail for the unsupported command 766 return VK_ERROR_INITIALIZATION_FAILED; 767 } 768 } 769 770 VKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput, 771 VkDisplayKHR *pDisplay) { 772 const VkLayerInstanceDispatchTable *disp; 773 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 774 disp = loader_get_instance_layer_dispatch(physicalDevice); 775 return disp->GetRandROutputDisplayEXT(unwrapped_phys_dev, dpy, rrOutput, pDisplay); 776 } 777 778 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput, 779 VkDisplayKHR *pDisplay) { 780 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 781 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 782 783 if (icd_term->dispatch.GetRandROutputDisplayEXT != NULL) { 784 // Pass the call to the driver 785 return icd_term->dispatch.GetRandROutputDisplayEXT(phys_dev_term->phys_dev, dpy, rrOutput, pDisplay); 786 } else { 787 // Emulate the call 788 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 789 "vkGetRandROutputDisplayEXT: Emulating call in ICD \"%s\" by returning null display", 790 icd_term->scanned_icd->lib_name); 791 792 // Return a null handle to indicate this can't be done 793 *pDisplay = VK_NULL_HANDLE; 794 return VK_SUCCESS; 795 } 796 } 797 798 #endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT 799 800 // ---- VK_KHR_external_memory_capabilities extension trampoline/terminators 801 802 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalBufferPropertiesKHR( 803 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo, 804 VkExternalBufferPropertiesKHR *pExternalBufferProperties) { 805 const VkLayerInstanceDispatchTable *disp; 806 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 807 disp = loader_get_instance_layer_dispatch(physicalDevice); 808 disp->GetPhysicalDeviceExternalBufferPropertiesKHR(unwrapped_phys_dev, pExternalBufferInfo, pExternalBufferProperties); 809 } 810 811 VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalBufferPropertiesKHR( 812 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo, 813 VkExternalBufferPropertiesKHR *pExternalBufferProperties) { 814 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 815 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 816 817 if (icd_term->dispatch.GetPhysicalDeviceExternalBufferPropertiesKHR) { 818 // Pass the call to the driver 819 icd_term->dispatch.GetPhysicalDeviceExternalBufferPropertiesKHR(phys_dev_term->phys_dev, pExternalBufferInfo, 820 pExternalBufferProperties); 821 } else { 822 // Emulate the call 823 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 824 "vkGetPhysicalDeviceExternalBufferPropertiesKHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name); 825 826 if (pExternalBufferInfo->pNext != NULL) { 827 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 828 "vkGetPhysicalDeviceExternalBufferPropertiesKHR: Emulation found unrecognized structure type in " 829 "pExternalBufferInfo->pNext - this struct will be ignored"); 830 } 831 832 // Fill in everything being unsupported 833 memset(&pExternalBufferProperties->externalMemoryProperties, 0, sizeof(VkExternalMemoryPropertiesKHR)); 834 835 if (pExternalBufferProperties->pNext != NULL) { 836 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 837 "vkGetPhysicalDeviceExternalBufferPropertiesKHR: Emulation found unrecognized structure type in " 838 "pExternalBufferProperties->pNext - this struct will be ignored"); 839 } 840 } 841 } 842 843 // ---- VK_KHR_external_semaphore_capabilities extension trampoline/terminators 844 845 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalSemaphorePropertiesKHR( 846 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfoKHR *pExternalSemaphoreInfo, 847 VkExternalSemaphorePropertiesKHR *pExternalSemaphoreProperties) { 848 const VkLayerInstanceDispatchTable *disp; 849 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 850 disp = loader_get_instance_layer_dispatch(physicalDevice); 851 disp->GetPhysicalDeviceExternalSemaphorePropertiesKHR(unwrapped_phys_dev, pExternalSemaphoreInfo, pExternalSemaphoreProperties); 852 } 853 854 VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalSemaphorePropertiesKHR( 855 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfoKHR *pExternalSemaphoreInfo, 856 VkExternalSemaphorePropertiesKHR *pExternalSemaphoreProperties) { 857 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 858 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 859 860 if (icd_term->dispatch.GetPhysicalDeviceExternalSemaphorePropertiesKHR != NULL) { 861 // Pass the call to the driver 862 icd_term->dispatch.GetPhysicalDeviceExternalSemaphorePropertiesKHR(phys_dev_term->phys_dev, pExternalSemaphoreInfo, 863 pExternalSemaphoreProperties); 864 } else { 865 // Emulate the call 866 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 867 "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR: Emulating call in ICD \"%s\"", 868 icd_term->scanned_icd->lib_name); 869 870 if (pExternalSemaphoreInfo->pNext != NULL) { 871 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 872 "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR: Emulation found unrecognized structure type in " 873 "pExternalSemaphoreInfo->pNext - this struct will be ignored"); 874 } 875 876 // Fill in everything being unsupported 877 pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0; 878 pExternalSemaphoreProperties->compatibleHandleTypes = 0; 879 pExternalSemaphoreProperties->externalSemaphoreFeatures = 0; 880 881 if (pExternalSemaphoreProperties->pNext != NULL) { 882 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 883 "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR: Emulation found unrecognized structure type in " 884 "pExternalSemaphoreProperties->pNext - this struct will be ignored"); 885 } 886 } 887 } 888 889 // ---- VK_KHR_external_fence_capabilities extension trampoline/terminators 890 891 VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalFencePropertiesKHR( 892 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfoKHR *pExternalFenceInfo, 893 VkExternalFencePropertiesKHR *pExternalFenceProperties) { 894 const VkLayerInstanceDispatchTable *disp; 895 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 896 disp = loader_get_instance_layer_dispatch(physicalDevice); 897 disp->GetPhysicalDeviceExternalFencePropertiesKHR(unwrapped_phys_dev, pExternalFenceInfo, pExternalFenceProperties); 898 } 899 900 VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalFencePropertiesKHR( 901 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfoKHR *pExternalFenceInfo, 902 VkExternalFencePropertiesKHR *pExternalFenceProperties) { 903 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 904 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 905 906 if (icd_term->dispatch.GetPhysicalDeviceExternalFencePropertiesKHR != NULL) { 907 // Pass the call to the driver 908 icd_term->dispatch.GetPhysicalDeviceExternalFencePropertiesKHR(phys_dev_term->phys_dev, pExternalFenceInfo, 909 pExternalFenceProperties); 910 } else { 911 // Emulate the call 912 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, 913 "vkGetPhysicalDeviceExternalFencePropertiesKHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name); 914 915 if (pExternalFenceInfo->pNext != NULL) { 916 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 917 "vkGetPhysicalDeviceExternalFencePropertiesKHR: Emulation found unrecognized structure type in " 918 "pExternalFenceInfo->pNext - this struct will be ignored"); 919 } 920 921 // Fill in everything being unsupported 922 pExternalFenceProperties->exportFromImportedHandleTypes = 0; 923 pExternalFenceProperties->compatibleHandleTypes = 0; 924 pExternalFenceProperties->externalFenceFeatures = 0; 925 926 if (pExternalFenceProperties->pNext != NULL) { 927 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, 928 "vkGetPhysicalDeviceExternalFencePropertiesKHR: Emulation found unrecognized structure type in " 929 "pExternalFenceProperties->pNext - this struct will be ignored"); 930 } 931 } 932 } 933 934 // ---- Helper functions 935 936 VkResult setupLoaderTrampPhysDevGroups(VkInstance instance) { 937 VkResult res = VK_SUCCESS; 938 struct loader_instance *inst; 939 uint32_t total_count = 0; 940 VkPhysicalDeviceGroupPropertiesKHX **new_phys_dev_groups = NULL; 941 VkPhysicalDeviceGroupPropertiesKHX *local_phys_dev_groups = NULL; 942 943 inst = loader_get_instance(instance); 944 if (NULL == inst) { 945 res = VK_ERROR_INITIALIZATION_FAILED; 946 goto out; 947 } 948 949 // Setup the trampoline loader physical devices. This will actually 950 // call down and setup the terminator loader physical devices during the 951 // process. 952 VkResult setup_res = setupLoaderTrampPhysDevs(instance); 953 if (setup_res != VK_SUCCESS && setup_res != VK_INCOMPLETE) { 954 res = setup_res; 955 goto out; 956 } 957 958 // Query how many physical device groups there 959 res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroupsKHX(instance, &total_count, NULL); 960 if (res != VK_SUCCESS) { 961 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 962 "setupLoaderTrampPhysDevGroups: Failed during dispatch call of " 963 "\'EnumeratePhysicalDeviceGroupsKHX\' to lower layers or " 964 "loader to get count."); 965 goto out; 966 } 967 968 // Create an array for the new physical device groups, which will be stored 969 // in the instance for the trampoline code. 970 new_phys_dev_groups = (VkPhysicalDeviceGroupPropertiesKHX **)loader_instance_heap_alloc( 971 inst, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 972 if (NULL == new_phys_dev_groups) { 973 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 974 "setupLoaderTrampPhysDevGroups: Failed to allocate new physical device" 975 " group array of size %d", 976 total_count); 977 res = VK_ERROR_OUT_OF_HOST_MEMORY; 978 goto out; 979 } 980 memset(new_phys_dev_groups, 0, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *)); 981 982 // Create a temporary array (on the stack) to keep track of the 983 // returned VkPhysicalDevice values. 984 local_phys_dev_groups = loader_stack_alloc(sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count); 985 if (NULL == local_phys_dev_groups) { 986 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 987 "setupLoaderTrampPhysDevGroups: Failed to allocate local " 988 "physical device group array of size %d", 989 total_count); 990 res = VK_ERROR_OUT_OF_HOST_MEMORY; 991 goto out; 992 } 993 // Initialize the memory to something valid 994 memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count); 995 for (uint32_t group = 0; group < total_count; group++) { 996 local_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX; 997 local_phys_dev_groups[group].pNext = NULL; 998 local_phys_dev_groups[group].subsetAllocation = false; 999 } 1000 1001 // Call down and get the content 1002 res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroupsKHX(instance, &total_count, local_phys_dev_groups); 1003 if (VK_SUCCESS != res) { 1004 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1005 "setupLoaderTrampPhysDevGroups: Failed during dispatch call of " 1006 "\'EnumeratePhysicalDeviceGroupsKHX\' to lower layers or " 1007 "loader to get content."); 1008 goto out; 1009 } 1010 1011 // Replace all the physical device IDs with the proper loader values 1012 for (uint32_t group = 0; group < total_count; group++) { 1013 for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) { 1014 bool found = false; 1015 for (uint32_t tramp_gpu = 0; tramp_gpu < inst->phys_dev_count_tramp; tramp_gpu++) { 1016 if (local_phys_dev_groups[group].physicalDevices[group_gpu] == inst->phys_devs_tramp[tramp_gpu]->phys_dev) { 1017 local_phys_dev_groups[group].physicalDevices[group_gpu] = (VkPhysicalDevice)inst->phys_devs_tramp[tramp_gpu]; 1018 found = true; 1019 break; 1020 } 1021 } 1022 if (!found) { 1023 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1024 "setupLoaderTrampPhysDevGroups: Failed to find GPU %d in group %d" 1025 " returned by \'EnumeratePhysicalDeviceGroupsKHX\' in list returned" 1026 " by \'EnumeratePhysicalDevices\'", group_gpu, group); 1027 res = VK_ERROR_INITIALIZATION_FAILED; 1028 goto out; 1029 } 1030 } 1031 } 1032 1033 // Copy or create everything to fill the new array of physical device groups 1034 for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) { 1035 // Check if this physical device group with the same contents is already in the old buffer 1036 for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_tramp; old_idx++) { 1037 if (local_phys_dev_groups[new_idx].physicalDeviceCount == inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount) { 1038 bool found_all_gpus = true; 1039 for (uint32_t old_gpu = 0; old_gpu < inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount; old_gpu++) { 1040 bool found_gpu = false; 1041 for (uint32_t new_gpu = 0; new_gpu < local_phys_dev_groups[new_idx].physicalDeviceCount; new_gpu++) { 1042 if (local_phys_dev_groups[new_idx].physicalDevices[new_gpu] == inst->phys_dev_groups_tramp[old_idx]->physicalDevices[old_gpu]) { 1043 found_gpu = true; 1044 break; 1045 } 1046 } 1047 1048 if (!found_gpu) { 1049 found_all_gpus = false; 1050 break; 1051 } 1052 } 1053 if (!found_all_gpus) { 1054 continue; 1055 } else { 1056 new_phys_dev_groups[new_idx] = inst->phys_dev_groups_tramp[old_idx]; 1057 break; 1058 } 1059 } 1060 } 1061 1062 // If this physical device group isn't in the old buffer, create it 1063 if (NULL == new_phys_dev_groups[new_idx]) { 1064 new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHX *)loader_instance_heap_alloc( 1065 inst, sizeof(VkPhysicalDeviceGroupPropertiesKHX), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 1066 if (NULL == new_phys_dev_groups[new_idx]) { 1067 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1068 "setupLoaderTrampPhysDevGroups: Failed to allocate " 1069 "physical device group trampoline object %d", 1070 new_idx); 1071 total_count = new_idx; 1072 res = VK_ERROR_OUT_OF_HOST_MEMORY; 1073 goto out; 1074 } 1075 memcpy(new_phys_dev_groups[new_idx], &local_phys_dev_groups[new_idx], 1076 sizeof(VkPhysicalDeviceGroupPropertiesKHX)); 1077 } 1078 } 1079 1080 out: 1081 1082 if (VK_SUCCESS != res) { 1083 if (NULL != new_phys_dev_groups) { 1084 for (uint32_t i = 0; i < total_count; i++) { 1085 loader_instance_heap_free(inst, new_phys_dev_groups[i]); 1086 } 1087 loader_instance_heap_free(inst, new_phys_dev_groups); 1088 } 1089 total_count = 0; 1090 } else { 1091 // Free everything that didn't carry over to the new array of 1092 // physical device groups 1093 if (NULL != inst->phys_dev_groups_tramp) { 1094 for (uint32_t i = 0; i < inst->phys_dev_group_count_tramp; i++) { 1095 bool found = false; 1096 for (uint32_t j = 0; j < total_count; j++) { 1097 if (inst->phys_dev_groups_tramp[i] == new_phys_dev_groups[j]) { 1098 found = true; 1099 break; 1100 } 1101 } 1102 if (!found) { 1103 loader_instance_heap_free(inst, inst->phys_dev_groups_tramp[i]); 1104 } 1105 } 1106 loader_instance_heap_free(inst, inst->phys_dev_groups_tramp); 1107 } 1108 1109 // Swap in the new physical device group list 1110 inst->phys_dev_group_count_tramp = total_count; 1111 inst->phys_dev_groups_tramp = new_phys_dev_groups; 1112 } 1113 1114 return res; 1115 } 1116 1117 VkResult setupLoaderTermPhysDevGroups(struct loader_instance *inst) { 1118 VkResult res = VK_SUCCESS; 1119 struct loader_icd_term *icd_term; 1120 uint32_t total_count = 0; 1121 uint32_t cur_icd_group_count = 0; 1122 VkPhysicalDeviceGroupPropertiesKHX **new_phys_dev_groups = NULL; 1123 VkPhysicalDeviceGroupPropertiesKHX *local_phys_dev_groups = NULL; 1124 1125 if (0 == inst->phys_dev_count_term) { 1126 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1127 "setupLoaderTermPhysDevGroups: Loader failed to setup physical " 1128 "device terminator info before calling \'EnumeratePhysicalDeviceGroupsKHX\'."); 1129 assert(false); 1130 res = VK_ERROR_INITIALIZATION_FAILED; 1131 goto out; 1132 } 1133 1134 // For each ICD, query the number of physical device groups, and then get an 1135 // internal value for those physical devices. 1136 icd_term = inst->icd_terms; 1137 for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) { 1138 cur_icd_group_count = 0; 1139 if (NULL == icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX) { 1140 // Treat each ICD's GPU as it's own group if the extension isn't supported 1141 res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &cur_icd_group_count, NULL); 1142 if (res != VK_SUCCESS) { 1143 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1144 "setupLoaderTermPhysDevGroups: Failed during dispatch call of " 1145 "\'EnumeratePhysicalDevices\' to ICD %d to get plain phys dev count.", 1146 icd_idx); 1147 goto out; 1148 } 1149 } else { 1150 // Query the actual group info 1151 res = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX(icd_term->instance, &cur_icd_group_count, NULL); 1152 if (res != VK_SUCCESS) { 1153 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1154 "setupLoaderTermPhysDevGroups: Failed during dispatch call of " 1155 "\'EnumeratePhysicalDeviceGroupsKHX\' to ICD %d to get count.", 1156 icd_idx); 1157 goto out; 1158 } 1159 } 1160 total_count += cur_icd_group_count; 1161 } 1162 1163 // Create an array for the new physical device groups, which will be stored 1164 // in the instance for the Terminator code. 1165 new_phys_dev_groups = (VkPhysicalDeviceGroupPropertiesKHX **)loader_instance_heap_alloc( 1166 inst, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 1167 if (NULL == new_phys_dev_groups) { 1168 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1169 "setupLoaderTermPhysDevGroups: Failed to allocate new physical device" 1170 " group array of size %d", 1171 total_count); 1172 res = VK_ERROR_OUT_OF_HOST_MEMORY; 1173 goto out; 1174 } 1175 memset(new_phys_dev_groups, 0, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *)); 1176 1177 // Create a temporary array (on the stack) to keep track of the 1178 // returned VkPhysicalDevice values. 1179 local_phys_dev_groups = loader_stack_alloc(sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count); 1180 if (NULL == local_phys_dev_groups) { 1181 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1182 "setupLoaderTermPhysDevGroups: Failed to allocate local " 1183 "physical device group array of size %d", 1184 total_count); 1185 res = VK_ERROR_OUT_OF_HOST_MEMORY; 1186 goto out; 1187 } 1188 // Initialize the memory to something valid 1189 memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count); 1190 for (uint32_t group = 0; group < total_count; group++) { 1191 local_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX; 1192 local_phys_dev_groups[group].pNext = NULL; 1193 local_phys_dev_groups[group].subsetAllocation = false; 1194 } 1195 1196 cur_icd_group_count = 0; 1197 icd_term = inst->icd_terms; 1198 for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) { 1199 uint32_t count_this_time = total_count - cur_icd_group_count; 1200 1201 if (NULL == icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX) { 1202 VkPhysicalDevice* phys_dev_array = loader_stack_alloc(sizeof(VkPhysicalDevice) * count_this_time); 1203 if (NULL == phys_dev_array) { 1204 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1205 "setupLoaderTermPhysDevGroups: Failed to allocate local " 1206 "physical device array of size %d", 1207 count_this_time); 1208 res = VK_ERROR_OUT_OF_HOST_MEMORY; 1209 goto out; 1210 } 1211 1212 res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &count_this_time, phys_dev_array); 1213 if (res != VK_SUCCESS) { 1214 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1215 "setupLoaderTermPhysDevGroups: Failed during dispatch call of " 1216 "\'EnumeratePhysicalDevices\' to ICD %d to get plain phys dev count.", 1217 icd_idx); 1218 goto out; 1219 } 1220 1221 // Add each GPU as it's own group 1222 for (uint32_t indiv_gpu = 0; indiv_gpu < count_this_time; indiv_gpu++) { 1223 local_phys_dev_groups[indiv_gpu + cur_icd_group_count].physicalDeviceCount = 1; 1224 local_phys_dev_groups[indiv_gpu + cur_icd_group_count].physicalDevices[0] = phys_dev_array[indiv_gpu]; 1225 } 1226 1227 } else { 1228 res = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX(icd_term->instance, &count_this_time, &local_phys_dev_groups[cur_icd_group_count]); 1229 if (VK_SUCCESS != res) { 1230 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1231 "setupLoaderTermPhysDevGroups: Failed during dispatch call of " 1232 "\'EnumeratePhysicalDeviceGroupsKHX\' to ICD %d to get content.", 1233 icd_idx); 1234 goto out; 1235 } 1236 } 1237 1238 cur_icd_group_count += count_this_time; 1239 } 1240 1241 // Replace all the physical device IDs with the proper loader values 1242 for (uint32_t group = 0; group < total_count; group++) { 1243 for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) { 1244 bool found = false; 1245 for (uint32_t term_gpu = 0; term_gpu < inst->phys_dev_count_term; term_gpu++) { 1246 if (local_phys_dev_groups[group].physicalDevices[group_gpu] == inst->phys_devs_term[term_gpu]->phys_dev) { 1247 local_phys_dev_groups[group].physicalDevices[group_gpu] = (VkPhysicalDevice)inst->phys_devs_term[term_gpu]; 1248 found = true; 1249 break; 1250 } 1251 } 1252 if (!found) { 1253 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1254 "setupLoaderTermPhysDevGroups: Failed to find GPU %d in group %d" 1255 " returned by \'EnumeratePhysicalDeviceGroupsKHX\' in list returned" 1256 " by \'EnumeratePhysicalDevices\'", group_gpu, group); 1257 res = VK_ERROR_INITIALIZATION_FAILED; 1258 goto out; 1259 } 1260 } 1261 } 1262 1263 // Copy or create everything to fill the new array of physical device groups 1264 for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) { 1265 // Check if this physical device group with the same contents is already in the old buffer 1266 for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_term; old_idx++) { 1267 if (local_phys_dev_groups[new_idx].physicalDeviceCount == inst->phys_dev_groups_term[old_idx]->physicalDeviceCount) { 1268 bool found_all_gpus = true; 1269 for (uint32_t old_gpu = 0; old_gpu < inst->phys_dev_groups_term[old_idx]->physicalDeviceCount; old_gpu++) { 1270 bool found_gpu = false; 1271 for (uint32_t new_gpu = 0; new_gpu < local_phys_dev_groups[new_idx].physicalDeviceCount; new_gpu++) { 1272 if (local_phys_dev_groups[new_idx].physicalDevices[new_gpu] == inst->phys_dev_groups_term[old_idx]->physicalDevices[old_gpu]) { 1273 found_gpu = true; 1274 break; 1275 } 1276 } 1277 1278 if (!found_gpu) { 1279 found_all_gpus = false; 1280 break; 1281 } 1282 } 1283 if (!found_all_gpus) { 1284 continue; 1285 } else { 1286 new_phys_dev_groups[new_idx] = inst->phys_dev_groups_term[old_idx]; 1287 break; 1288 } 1289 } 1290 } 1291 1292 // If this physical device group isn't in the old buffer, create it 1293 if (NULL == new_phys_dev_groups[new_idx]) { 1294 new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHX *)loader_instance_heap_alloc( 1295 inst, sizeof(VkPhysicalDeviceGroupPropertiesKHX), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 1296 if (NULL == new_phys_dev_groups[new_idx]) { 1297 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1298 "setupLoaderTermPhysDevGroups: Failed to allocate " 1299 "physical device group Terminator object %d", 1300 new_idx); 1301 total_count = new_idx; 1302 res = VK_ERROR_OUT_OF_HOST_MEMORY; 1303 goto out; 1304 } 1305 memcpy(new_phys_dev_groups[new_idx], &local_phys_dev_groups[new_idx], 1306 sizeof(VkPhysicalDeviceGroupPropertiesKHX)); 1307 } 1308 } 1309 1310 out: 1311 1312 if (VK_SUCCESS != res) { 1313 if (NULL != new_phys_dev_groups) { 1314 for (uint32_t i = 0; i < total_count; i++) { 1315 loader_instance_heap_free(inst, new_phys_dev_groups[i]); 1316 } 1317 loader_instance_heap_free(inst, new_phys_dev_groups); 1318 } 1319 total_count = 0; 1320 } else { 1321 // Free everything that didn't carry over to the new array of 1322 // physical device groups 1323 if (NULL != inst->phys_dev_groups_term) { 1324 for (uint32_t i = 0; i < inst->phys_dev_group_count_term; i++) { 1325 bool found = false; 1326 for (uint32_t j = 0; j < total_count; j++) { 1327 if (inst->phys_dev_groups_term[i] == new_phys_dev_groups[j]) { 1328 found = true; 1329 break; 1330 } 1331 } 1332 if (!found) { 1333 loader_instance_heap_free(inst, inst->phys_dev_groups_term[i]); 1334 } 1335 } 1336 loader_instance_heap_free(inst, inst->phys_dev_groups_term); 1337 } 1338 1339 // Swap in the new physical device group list 1340 inst->phys_dev_group_count_term = total_count; 1341 inst->phys_dev_groups_term = new_phys_dev_groups; 1342 } 1343 1344 return res; 1345 } 1346