1/* 2 * 3 * Copyright (c) 2014-2021 The Khronos Group Inc. 4 * Copyright (c) 2014-2021 Valve Corporation 5 * Copyright (c) 2014-2021 LunarG, Inc. 6 * Copyright (C) 2015 Google Inc. 7 * Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 8 * Copyright (c) 2023-2023 RasterGrid Kft. 9 * 10 * Licensed under the Apache License, Version 2.0 (the "License"); 11 * you may not use this file except in compliance with the License. 12 * You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, software 17 * distributed under the License is distributed on an "AS IS" BASIS, 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 * See the License for the specific language governing permissions and 20 * limitations under the License. 21 22 * 23 * Author: Jon Ashburn <jon@lunarg.com> 24 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> 25 * Author: Mark Young <marky@lunarg.com> 26 * Author: Lenny Komow <lenny@lunarg.com> 27 * Author: Charles Giessen <charles@lunarg.com> 28 * 29 */ 30 31// Terminators which have simple logic belong here, since they are mostly "pass through" 32// Function declarations are in vk_loader_extensions.h, thus not needed here 33 34#include "allocation.h" 35#include "loader_common.h" 36#include "loader.h" 37#include "log.h" 38 39// Terminators for 1.0 functions 40 41VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, 42 VkPhysicalDeviceProperties *pProperties) { 43 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 44 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 45 if (NULL != icd_term->dispatch.GetPhysicalDeviceProperties) { 46 icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, pProperties); 47 } 48} 49 50VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, 51 uint32_t *pQueueFamilyPropertyCount, 52 VkQueueFamilyProperties *pProperties) { 53 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 54 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 55 if (NULL != icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties) { 56 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, pProperties); 57 } 58} 59 60VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, 61 VkPhysicalDeviceMemoryProperties *pProperties) { 62 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 63 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 64 if (NULL != icd_term->dispatch.GetPhysicalDeviceMemoryProperties) { 65 icd_term->dispatch.GetPhysicalDeviceMemoryProperties(phys_dev_term->phys_dev, pProperties); 66 } 67} 68 69VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, 70 VkPhysicalDeviceFeatures *pFeatures) { 71 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 72 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 73 if (NULL != icd_term->dispatch.GetPhysicalDeviceFeatures) { 74 icd_term->dispatch.GetPhysicalDeviceFeatures(phys_dev_term->phys_dev, pFeatures); 75 } 76} 77 78VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, 79 VkFormatProperties *pFormatInfo) { 80 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 81 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 82 if (NULL != icd_term->dispatch.GetPhysicalDeviceFormatProperties) { 83 icd_term->dispatch.GetPhysicalDeviceFormatProperties(phys_dev_term->phys_dev, format, pFormatInfo); 84 } 85} 86 87VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, 88 VkImageType type, VkImageTiling tiling, 89 VkImageUsageFlags usage, VkImageCreateFlags flags, 90 VkImageFormatProperties *pImageFormatProperties) { 91 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 92 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 93 if (NULL == icd_term->dispatch.GetPhysicalDeviceImageFormatProperties) { 94 loader_log( 95 icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0, 96 "The icd's vkGetPhysicalDeviceImageFormatProperties was null, returning with VK_ERROR_INITIALIZATION_FAILED instead."); 97 return VK_ERROR_INITIALIZATION_FAILED; 98 } 99 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(phys_dev_term->phys_dev, format, type, tiling, usage, flags, 100 pImageFormatProperties); 101} 102 103VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, 104 VkImageType type, VkSampleCountFlagBits samples, 105 VkImageUsageFlags usage, VkImageTiling tiling, 106 uint32_t *pNumProperties, 107 VkSparseImageFormatProperties *pProperties) { 108 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 109 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 110 if (NULL != icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties) { 111 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(phys_dev_term->phys_dev, format, type, samples, usage, 112 tiling, pNumProperties, pProperties); 113 } 114} 115 116VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, 117 VkLayerProperties *pProperties) { 118 (void)pPropertyCount; 119 (void)pProperties; 120 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 121 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 122 loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0, 123 "Encountered the vkEnumerateDeviceLayerProperties terminator. This means a layer improperly continued."); 124 // Should never get here this call isn't dispatched down the chain 125 return VK_ERROR_INITIALIZATION_FAILED; 126} 127 128// Terminators for 1.1 functions 129 130VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, 131 VkPhysicalDeviceFeatures2 *pFeatures) { 132 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 133 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 134 const struct loader_instance *inst = icd_term->this_instance; 135 136 assert(inst != NULL); 137 138 // Get the function pointer to use to call into the ICD. This could be the core or KHR version 139 PFN_vkGetPhysicalDeviceFeatures2 fpGetPhysicalDeviceFeatures2 = NULL; 140 if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) { 141 fpGetPhysicalDeviceFeatures2 = icd_term->dispatch.GetPhysicalDeviceFeatures2; 142 } 143 if (fpGetPhysicalDeviceFeatures2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) { 144 fpGetPhysicalDeviceFeatures2 = icd_term->dispatch.GetPhysicalDeviceFeatures2KHR; 145 } 146 147 if (fpGetPhysicalDeviceFeatures2 != NULL) { 148 // Pass the call to the driver 149 fpGetPhysicalDeviceFeatures2(phys_dev_term->phys_dev, pFeatures); 150 } else { 151 // Emulate the call 152 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 153 "vkGetPhysicalDeviceFeatures2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFeatures", 154 icd_term->scanned_icd->lib_name); 155 156 // Write to the VkPhysicalDeviceFeatures2 struct 157 icd_term->dispatch.GetPhysicalDeviceFeatures(phys_dev_term->phys_dev, &pFeatures->features); 158 159 const VkBaseInStructure *pNext = pFeatures->pNext; 160 while (pNext != NULL) { 161 switch (pNext->sType) { 162 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: { 163 // Skip the check if VK_KHR_multiview is enabled because it's a device extension 164 // Write to the VkPhysicalDeviceMultiviewFeaturesKHR struct 165 VkPhysicalDeviceMultiviewFeaturesKHR *multiview_features = (VkPhysicalDeviceMultiviewFeaturesKHR *)pNext; 166 multiview_features->multiview = VK_FALSE; 167 multiview_features->multiviewGeometryShader = VK_FALSE; 168 multiview_features->multiviewTessellationShader = VK_FALSE; 169 170 pNext = multiview_features->pNext; 171 break; 172 } 173 default: { 174 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 175 "vkGetPhysicalDeviceFeatures2: Emulation found unrecognized structure type in pFeatures->pNext - " 176 "this struct will be ignored"); 177 178 pNext = pNext->pNext; 179 break; 180 } 181 } 182 } 183 } 184} 185 186VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, 187 VkPhysicalDeviceProperties2 *pProperties) { 188 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 189 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 190 const struct loader_instance *inst = icd_term->this_instance; 191 192 assert(inst != NULL); 193 194 // Get the function pointer to use to call into the ICD. This could be the core or KHR version 195 PFN_vkGetPhysicalDeviceProperties2 fpGetPhysicalDeviceProperties2 = NULL; 196 if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) { 197 fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2; 198 } 199 if (fpGetPhysicalDeviceProperties2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) { 200 fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2KHR; 201 } 202 203 if (fpGetPhysicalDeviceProperties2 != NULL) { 204 // Pass the call to the driver 205 fpGetPhysicalDeviceProperties2(phys_dev_term->phys_dev, pProperties); 206 } else { 207 // Emulate the call 208 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 209 "vkGetPhysicalDeviceProperties2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceProperties", 210 icd_term->scanned_icd->lib_name); 211 212 // Write to the VkPhysicalDeviceProperties2 struct 213 icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &pProperties->properties); 214 215 const VkBaseInStructure *pNext = pProperties->pNext; 216 while (pNext != NULL) { 217 switch (pNext->sType) { 218 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: { 219 VkPhysicalDeviceIDPropertiesKHR *id_properties = (VkPhysicalDeviceIDPropertiesKHR *)pNext; 220 221 // Verify that "VK_KHR_external_memory_capabilities" is enabled 222 if (icd_term->this_instance->enabled_known_extensions.khr_external_memory_capabilities) { 223 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 224 "vkGetPhysicalDeviceProperties2: Emulation cannot generate unique IDs for struct " 225 "VkPhysicalDeviceIDProperties - setting IDs to zero instead"); 226 227 // Write to the VkPhysicalDeviceIDPropertiesKHR struct 228 memset(id_properties->deviceUUID, 0, VK_UUID_SIZE); 229 memset(id_properties->driverUUID, 0, VK_UUID_SIZE); 230 id_properties->deviceLUIDValid = VK_FALSE; 231 } 232 233 pNext = id_properties->pNext; 234 break; 235 } 236 default: { 237 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 238 "vkGetPhysicalDeviceProperties2KHR: Emulation found unrecognized structure type in " 239 "pProperties->pNext - this struct will be ignored"); 240 241 pNext = pNext->pNext; 242 break; 243 } 244 } 245 } 246 } 247} 248 249VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format, 250 VkFormatProperties2 *pFormatProperties) { 251 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 252 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 253 const struct loader_instance *inst = icd_term->this_instance; 254 255 assert(inst != NULL); 256 257 // Get the function pointer to use to call into the ICD. This could be the core or KHR version 258 PFN_vkGetPhysicalDeviceFormatProperties2 fpGetPhysicalDeviceFormatProperties2 = NULL; 259 if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) { 260 fpGetPhysicalDeviceFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceFormatProperties2; 261 } 262 if (fpGetPhysicalDeviceFormatProperties2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) { 263 fpGetPhysicalDeviceFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR; 264 } 265 266 if (fpGetPhysicalDeviceFormatProperties2 != NULL) { 267 // Pass the call to the driver 268 fpGetPhysicalDeviceFormatProperties2(phys_dev_term->phys_dev, format, pFormatProperties); 269 } else { 270 // Emulate the call 271 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 272 "vkGetPhysicalDeviceFormatProperties2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFormatProperties", 273 icd_term->scanned_icd->lib_name); 274 275 // Write to the VkFormatProperties2 struct 276 icd_term->dispatch.GetPhysicalDeviceFormatProperties(phys_dev_term->phys_dev, format, &pFormatProperties->formatProperties); 277 278 if (pFormatProperties->pNext != NULL) { 279 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 280 "vkGetPhysicalDeviceFormatProperties2: Emulation found unrecognized structure type in " 281 "pFormatProperties->pNext - this struct will be ignored"); 282 } 283 } 284} 285 286VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties2( 287 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, 288 VkImageFormatProperties2 *pImageFormatProperties) { 289 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 290 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 291 const struct loader_instance *inst = icd_term->this_instance; 292 293 assert(inst != NULL); 294 295 // Get the function pointer to use to call into the ICD. This could be the core or KHR version 296 PFN_vkGetPhysicalDeviceImageFormatProperties2 fpGetPhysicalDeviceImageFormatProperties2 = NULL; 297 if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) { 298 fpGetPhysicalDeviceImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2; 299 } 300 if (fpGetPhysicalDeviceImageFormatProperties2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) { 301 fpGetPhysicalDeviceImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR; 302 } 303 304 if (fpGetPhysicalDeviceImageFormatProperties2 != NULL) { 305 // Pass the call to the driver 306 return fpGetPhysicalDeviceImageFormatProperties2(phys_dev_term->phys_dev, pImageFormatInfo, pImageFormatProperties); 307 } else { 308 // Emulate the call 309 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 310 "vkGetPhysicalDeviceImageFormatProperties2: Emulating call in ICD \"%s\" using " 311 "vkGetPhysicalDeviceImageFormatProperties", 312 icd_term->scanned_icd->lib_name); 313 314 // If there is more info in either pNext, then this is unsupported 315 if (pImageFormatInfo->pNext != NULL || pImageFormatProperties->pNext != NULL) { 316 return VK_ERROR_FORMAT_NOT_SUPPORTED; 317 } 318 319 // Write to the VkImageFormatProperties2KHR struct 320 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties( 321 phys_dev_term->phys_dev, pImageFormatInfo->format, pImageFormatInfo->type, pImageFormatInfo->tiling, 322 pImageFormatInfo->usage, pImageFormatInfo->flags, &pImageFormatProperties->imageFormatProperties); 323 } 324} 325 326VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, 327 uint32_t *pQueueFamilyPropertyCount, 328 VkQueueFamilyProperties2 *pQueueFamilyProperties) { 329 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 330 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 331 const struct loader_instance *inst = icd_term->this_instance; 332 333 assert(inst != NULL); 334 335 // Get the function pointer to use to call into the ICD. This could be the core or KHR version 336 PFN_vkGetPhysicalDeviceQueueFamilyProperties2 fpGetPhysicalDeviceQueueFamilyProperties2 = NULL; 337 if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) { 338 fpGetPhysicalDeviceQueueFamilyProperties2 = icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2; 339 } 340 if (fpGetPhysicalDeviceQueueFamilyProperties2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) { 341 fpGetPhysicalDeviceQueueFamilyProperties2 = icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR; 342 } 343 344 if (fpGetPhysicalDeviceQueueFamilyProperties2 != NULL) { 345 // Pass the call to the driver 346 fpGetPhysicalDeviceQueueFamilyProperties2(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties); 347 } else { 348 // Emulate the call 349 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 350 "vkGetPhysicalDeviceQueueFamilyProperties2: Emulating call in ICD \"%s\" using " 351 "vkGetPhysicalDeviceQueueFamilyProperties", 352 icd_term->scanned_icd->lib_name); 353 354 if (pQueueFamilyProperties == NULL || *pQueueFamilyPropertyCount == 0) { 355 // Write to pQueueFamilyPropertyCount 356 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, NULL); 357 } else { 358 // Allocate a temporary array for the output of the old function 359 VkQueueFamilyProperties *properties = loader_stack_alloc(*pQueueFamilyPropertyCount * sizeof(VkQueueFamilyProperties)); 360 if (properties == NULL) { 361 *pQueueFamilyPropertyCount = 0; 362 loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0, 363 "vkGetPhysicalDeviceQueueFamilyProperties2: Out of memory - Failed to allocate array for loader " 364 "emulation."); 365 return; 366 } 367 368 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, 369 properties); 370 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) { 371 // Write to the VkQueueFamilyProperties2KHR struct 372 memcpy(&pQueueFamilyProperties[i].queueFamilyProperties, &properties[i], sizeof(VkQueueFamilyProperties)); 373 374 if (pQueueFamilyProperties[i].pNext != NULL) { 375 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 376 "vkGetPhysicalDeviceQueueFamilyProperties2: Emulation found unrecognized structure type in " 377 "pQueueFamilyProperties[%d].pNext - this struct will be ignored", 378 i); 379 } 380 } 381 } 382 } 383} 384 385VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice, 386 VkPhysicalDeviceMemoryProperties2 *pMemoryProperties) { 387 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 388 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 389 const struct loader_instance *inst = icd_term->this_instance; 390 391 assert(inst != NULL); 392 393 // Get the function pointer to use to call into the ICD. This could be the core or KHR version 394 PFN_vkGetPhysicalDeviceMemoryProperties2 fpGetPhysicalDeviceMemoryProperties2 = NULL; 395 if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) { 396 fpGetPhysicalDeviceMemoryProperties2 = icd_term->dispatch.GetPhysicalDeviceMemoryProperties2; 397 } 398 if (fpGetPhysicalDeviceMemoryProperties2 == NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) { 399 fpGetPhysicalDeviceMemoryProperties2 = icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR; 400 } 401 402 if (fpGetPhysicalDeviceMemoryProperties2 != NULL) { 403 // Pass the call to the driver 404 fpGetPhysicalDeviceMemoryProperties2(phys_dev_term->phys_dev, pMemoryProperties); 405 } else { 406 // Emulate the call 407 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 408 "vkGetPhysicalDeviceMemoryProperties2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceMemoryProperties", 409 icd_term->scanned_icd->lib_name); 410 411 // Write to the VkPhysicalDeviceMemoryProperties2 struct 412 icd_term->dispatch.GetPhysicalDeviceMemoryProperties(phys_dev_term->phys_dev, &pMemoryProperties->memoryProperties); 413 414 if (pMemoryProperties->pNext != NULL) { 415 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 416 "vkGetPhysicalDeviceMemoryProperties2: Emulation found unrecognized structure type in " 417 "pMemoryProperties->pNext - this struct will be ignored"); 418 } 419 } 420} 421 422VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties2( 423 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount, 424 VkSparseImageFormatProperties2KHR *pProperties) { 425 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 426 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 427 const struct loader_instance *inst = icd_term->this_instance; 428 429 assert(inst != NULL); 430 431 // Get the function pointer to use to call into the ICD. This could be the core or KHR version 432 PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 fpGetPhysicalDeviceSparseImageFormatProperties2 = NULL; 433 if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) { 434 fpGetPhysicalDeviceSparseImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2; 435 } 436 if (fpGetPhysicalDeviceSparseImageFormatProperties2 == NULL && 437 inst->enabled_known_extensions.khr_get_physical_device_properties2) { 438 fpGetPhysicalDeviceSparseImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR; 439 } 440 441 if (fpGetPhysicalDeviceSparseImageFormatProperties2 != NULL) { 442 // Pass the call to the driver 443 fpGetPhysicalDeviceSparseImageFormatProperties2(phys_dev_term->phys_dev, pFormatInfo, pPropertyCount, pProperties); 444 } else { 445 // Emulate the call 446 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 447 "vkGetPhysicalDeviceSparseImageFormatProperties2: Emulating call in ICD \"%s\" using " 448 "vkGetPhysicalDeviceSparseImageFormatProperties", 449 icd_term->scanned_icd->lib_name); 450 451 if (pFormatInfo->pNext != NULL) { 452 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 453 "vkGetPhysicalDeviceSparseImageFormatProperties2: Emulation found unrecognized structure type in " 454 "pFormatInfo->pNext - this struct will be ignored"); 455 } 456 457 if (pProperties == NULL || *pPropertyCount == 0) { 458 // Write to pPropertyCount 459 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties( 460 phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage, 461 pFormatInfo->tiling, pPropertyCount, NULL); 462 } else { 463 // Allocate a temporary array for the output of the old function 464 VkSparseImageFormatProperties *properties = 465 loader_stack_alloc(*pPropertyCount * sizeof(VkSparseImageMemoryRequirements)); 466 if (properties == NULL) { 467 *pPropertyCount = 0; 468 loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0, 469 "vkGetPhysicalDeviceSparseImageFormatProperties2: Out of memory - Failed to allocate array for " 470 "loader emulation."); 471 return; 472 } 473 474 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties( 475 phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage, 476 pFormatInfo->tiling, pPropertyCount, properties); 477 for (uint32_t i = 0; i < *pPropertyCount; ++i) { 478 // Write to the VkSparseImageFormatProperties2KHR struct 479 memcpy(&pProperties[i].properties, &properties[i], sizeof(VkSparseImageFormatProperties)); 480 481 if (pProperties[i].pNext != NULL) { 482 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 483 "vkGetPhysicalDeviceSparseImageFormatProperties2: Emulation found unrecognized structure type in " 484 "pProperties[%d].pNext - this struct will be ignored", 485 i); 486 } 487 } 488 } 489 } 490} 491 492VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalBufferProperties( 493 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, 494 VkExternalBufferProperties *pExternalBufferProperties) { 495 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 496 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 497 const struct loader_instance *inst = icd_term->this_instance; 498 499 assert(inst != NULL); 500 501 // Get the function pointer to use to call into the ICD. This could be the core or KHR version 502 PFN_vkGetPhysicalDeviceExternalBufferProperties fpGetPhysicalDeviceExternalBufferProperties = NULL; 503 if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) { 504 fpGetPhysicalDeviceExternalBufferProperties = icd_term->dispatch.GetPhysicalDeviceExternalBufferProperties; 505 } 506 if (fpGetPhysicalDeviceExternalBufferProperties == NULL && inst->enabled_known_extensions.khr_external_memory_capabilities) { 507 fpGetPhysicalDeviceExternalBufferProperties = icd_term->dispatch.GetPhysicalDeviceExternalBufferPropertiesKHR; 508 } 509 510 if (fpGetPhysicalDeviceExternalBufferProperties != NULL) { 511 // Pass the call to the driver 512 fpGetPhysicalDeviceExternalBufferProperties(phys_dev_term->phys_dev, pExternalBufferInfo, pExternalBufferProperties); 513 } else { 514 // Emulate the call 515 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 516 "vkGetPhysicalDeviceExternalBufferProperties: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name); 517 518 if (pExternalBufferInfo->pNext != NULL) { 519 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 520 "vkGetPhysicalDeviceExternalBufferProperties: Emulation found unrecognized structure type in " 521 "pExternalBufferInfo->pNext - this struct will be ignored"); 522 } 523 524 // Fill in everything being unsupported 525 memset(&pExternalBufferProperties->externalMemoryProperties, 0, sizeof(VkExternalMemoryPropertiesKHR)); 526 527 if (pExternalBufferProperties->pNext != NULL) { 528 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 529 "vkGetPhysicalDeviceExternalBufferProperties: Emulation found unrecognized structure type in " 530 "pExternalBufferProperties->pNext - this struct will be ignored"); 531 } 532 } 533} 534 535VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalSemaphoreProperties( 536 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, 537 VkExternalSemaphoreProperties *pExternalSemaphoreProperties) { 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 const struct loader_instance *inst = icd_term->this_instance; 541 542 assert(inst != NULL); 543 544 // Get the function pointer to use to call into the ICD. This could be the core or KHR version 545 PFN_vkGetPhysicalDeviceExternalSemaphoreProperties fpGetPhysicalDeviceExternalSemaphoreProperties = NULL; 546 if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) { 547 fpGetPhysicalDeviceExternalSemaphoreProperties = icd_term->dispatch.GetPhysicalDeviceExternalSemaphoreProperties; 548 } 549 if (fpGetPhysicalDeviceExternalSemaphoreProperties == NULL && 550 inst->enabled_known_extensions.khr_external_semaphore_capabilities) { 551 fpGetPhysicalDeviceExternalSemaphoreProperties = icd_term->dispatch.GetPhysicalDeviceExternalSemaphorePropertiesKHR; 552 } 553 554 if (fpGetPhysicalDeviceExternalSemaphoreProperties != NULL) { 555 // Pass the call to the driver 556 fpGetPhysicalDeviceExternalSemaphoreProperties(phys_dev_term->phys_dev, pExternalSemaphoreInfo, 557 pExternalSemaphoreProperties); 558 } else { 559 // Emulate the call 560 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 561 "vkGetPhysicalDeviceExternalSemaphoreProperties: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name); 562 563 if (pExternalSemaphoreInfo->pNext != NULL) { 564 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 565 "vkGetPhysicalDeviceExternalSemaphoreProperties: Emulation found unrecognized structure type in " 566 "pExternalSemaphoreInfo->pNext - this struct will be ignored"); 567 } 568 569 // Fill in everything being unsupported 570 pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0; 571 pExternalSemaphoreProperties->compatibleHandleTypes = 0; 572 pExternalSemaphoreProperties->externalSemaphoreFeatures = 0; 573 574 if (pExternalSemaphoreProperties->pNext != NULL) { 575 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 576 "vkGetPhysicalDeviceExternalSemaphoreProperties: Emulation found unrecognized structure type in " 577 "pExternalSemaphoreProperties->pNext - this struct will be ignored"); 578 } 579 } 580} 581 582VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalFenceProperties( 583 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo, 584 VkExternalFenceProperties *pExternalFenceProperties) { 585 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 586 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 587 const struct loader_instance *inst = icd_term->this_instance; 588 589 assert(inst != NULL); 590 591 // Get the function pointer to use to call into the ICD. This could be the core or KHR version 592 PFN_vkGetPhysicalDeviceExternalFenceProperties fpGetPhysicalDeviceExternalFenceProperties = NULL; 593 if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) { 594 fpGetPhysicalDeviceExternalFenceProperties = icd_term->dispatch.GetPhysicalDeviceExternalFenceProperties; 595 } 596 if (fpGetPhysicalDeviceExternalFenceProperties == NULL && inst->enabled_known_extensions.khr_external_fence_capabilities) { 597 fpGetPhysicalDeviceExternalFenceProperties = icd_term->dispatch.GetPhysicalDeviceExternalFencePropertiesKHR; 598 } 599 600 if (fpGetPhysicalDeviceExternalFenceProperties != NULL) { 601 // Pass the call to the driver 602 fpGetPhysicalDeviceExternalFenceProperties(phys_dev_term->phys_dev, pExternalFenceInfo, pExternalFenceProperties); 603 } else { 604 // Emulate the call 605 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 606 "vkGetPhysicalDeviceExternalFenceProperties: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name); 607 608 if (pExternalFenceInfo->pNext != NULL) { 609 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 610 "vkGetPhysicalDeviceExternalFenceProperties: Emulation found unrecognized structure type in " 611 "pExternalFenceInfo->pNext - this struct will be ignored"); 612 } 613 614 // Fill in everything being unsupported 615 pExternalFenceProperties->exportFromImportedHandleTypes = 0; 616 pExternalFenceProperties->compatibleHandleTypes = 0; 617 pExternalFenceProperties->externalFenceFeatures = 0; 618 619 if (pExternalFenceProperties->pNext != NULL) { 620 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 621 "vkGetPhysicalDeviceExternalFenceProperties: Emulation found unrecognized structure type in " 622 "pExternalFenceProperties->pNext - this struct will be ignored"); 623 } 624 } 625} 626 627// 1.3 Core terminators 628 629VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceToolProperties(VkPhysicalDevice physicalDevice, uint32_t *pToolCount, 630 VkPhysicalDeviceToolProperties *pToolProperties) { 631 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 632 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 633 634 if (NULL == icd_term->dispatch.GetPhysicalDeviceToolProperties) { 635 loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0, 636 "terminator_GetPhysicalDeviceToolProperties: The ICD's vkGetPhysicalDeviceToolProperties was NULL yet " 637 "the physical device supports Vulkan API Version 1.3."); 638 } else { 639 VkPhysicalDeviceProperties properties; 640 if (icd_term->dispatch.GetPhysicalDeviceProperties) { 641 icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &properties); 642 643 if (VK_API_VERSION_MINOR(properties.apiVersion) >= 3) { 644 return icd_term->dispatch.GetPhysicalDeviceToolProperties(phys_dev_term->phys_dev, pToolCount, pToolProperties); 645 } 646 } 647 } 648 649 // In the case the driver didn't support 1.3, make sure that the first layer doesn't find the count uninitialized 650 *pToolCount = 0; 651 return VK_SUCCESS; 652} 653