1/* 2 * Copyright (c) 2015-2022 The Khronos Group Inc. 3 * Copyright (c) 2015-2022 Valve Corporation 4 * Copyright (c) 2015-2022 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@lunarg.com> 19 * Author: Lenny Komow <lenny@lunarg.com> 20 * Author: Charles Giessen <charles@lunarg.com> 21 */ 22 23#include "extension_manual.h" 24 25#include <stdio.h> 26#include <stdlib.h> 27#include <string.h> 28 29#include "allocation.h" 30#include "debug_utils.h" 31#include "loader.h" 32#include "log.h" 33#include "wsi.h" 34 35// ---- Manually added trampoline/terminator functions 36 37// These functions, for whatever reason, require more complex changes than 38// can easily be automatically generated. 39 40// ---- VK_NV_external_memory_capabilities extension trampoline/terminators 41 42VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceExternalImageFormatPropertiesNV( 43 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, 44 VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType, 45 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) { 46 const VkLayerInstanceDispatchTable *disp; 47 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 48 if (VK_NULL_HANDLE == unwrapped_phys_dev) { 49 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, 50 "vkGetPhysicalDeviceExternalImageFormatPropertiesNV: Invalid physicalDevice " 51 "[VUID-vkGetPhysicalDeviceExternalImageFormatPropertiesNV-physicalDevice-parameter]"); 52 abort(); /* Intentionally fail so user can correct issue. */ 53 } 54 disp = loader_get_instance_layer_dispatch(physicalDevice); 55 56 return disp->GetPhysicalDeviceExternalImageFormatPropertiesNV(unwrapped_phys_dev, format, type, tiling, usage, flags, 57 externalHandleType, pExternalImageFormatProperties); 58} 59 60VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceExternalImageFormatPropertiesNV( 61 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, 62 VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType, 63 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) { 64 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 65 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 66 67 if (!icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV) { 68 if (externalHandleType) { 69 return VK_ERROR_FORMAT_NOT_SUPPORTED; 70 } 71 72 if (!icd_term->dispatch.GetPhysicalDeviceImageFormatProperties) { 73 return VK_ERROR_INITIALIZATION_FAILED; 74 } 75 76 pExternalImageFormatProperties->externalMemoryFeatures = 0; 77 pExternalImageFormatProperties->exportFromImportedHandleTypes = 0; 78 pExternalImageFormatProperties->compatibleHandleTypes = 0; 79 80 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties( 81 phys_dev_term->phys_dev, format, type, tiling, usage, flags, &pExternalImageFormatProperties->imageFormatProperties); 82 } 83 84 return icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV( 85 phys_dev_term->phys_dev, format, type, tiling, usage, flags, externalHandleType, pExternalImageFormatProperties); 86} 87 88// ---- VK_EXT_display_surface_counter extension trampoline/terminators 89 90VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 91 VkSurfaceCapabilities2EXT *pSurfaceCapabilities) { 92 const VkLayerInstanceDispatchTable *disp; 93 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 94 if (VK_NULL_HANDLE == unwrapped_phys_dev) { 95 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, 96 "vkGetPhysicalDeviceExternalImageFormatPropertiesNV: Invalid physicalDevice " 97 "[VUID-vkGetPhysicalDeviceSurfaceCapabilities2EXT-physicalDevice-parameter]"); 98 abort(); /* Intentionally fail so user can correct issue. */ 99 } 100 disp = loader_get_instance_layer_dispatch(physicalDevice); 101 return disp->GetPhysicalDeviceSurfaceCapabilities2EXT(unwrapped_phys_dev, surface, pSurfaceCapabilities); 102} 103 104VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2EXT( 105 VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT *pSurfaceCapabilities) { 106 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 107 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 108 109 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface); 110 uint8_t icd_index = phys_dev_term->icd_index; 111 112 // Unwrap the surface if needed 113 VkSurfaceKHR unwrapped_surface = surface; 114 if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) { 115 unwrapped_surface = icd_surface->real_icd_surfaces[icd_index]; 116 } 117 118 if (NULL != icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT) { 119 // Pass the call to the driver 120 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT(phys_dev_term->phys_dev, unwrapped_surface, 121 pSurfaceCapabilities); 122 } else { 123 // Emulate the call 124 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 125 "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulating call in ICD \"%s\" using " 126 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", 127 icd_term->scanned_icd->lib_name); 128 129 VkSurfaceCapabilitiesKHR surface_caps; 130 VkResult res = 131 icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, unwrapped_surface, &surface_caps); 132 pSurfaceCapabilities->minImageCount = surface_caps.minImageCount; 133 pSurfaceCapabilities->maxImageCount = surface_caps.maxImageCount; 134 pSurfaceCapabilities->currentExtent = surface_caps.currentExtent; 135 pSurfaceCapabilities->minImageExtent = surface_caps.minImageExtent; 136 pSurfaceCapabilities->maxImageExtent = surface_caps.maxImageExtent; 137 pSurfaceCapabilities->maxImageArrayLayers = surface_caps.maxImageArrayLayers; 138 pSurfaceCapabilities->supportedTransforms = surface_caps.supportedTransforms; 139 pSurfaceCapabilities->currentTransform = surface_caps.currentTransform; 140 pSurfaceCapabilities->supportedCompositeAlpha = surface_caps.supportedCompositeAlpha; 141 pSurfaceCapabilities->supportedUsageFlags = surface_caps.supportedUsageFlags; 142 pSurfaceCapabilities->supportedSurfaceCounters = 0; 143 144 if (pSurfaceCapabilities->pNext != NULL) { 145 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0, 146 "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulation found unrecognized structure type in " 147 "pSurfaceCapabilities->pNext - this struct will be ignored"); 148 } 149 150 return res; 151 } 152} 153 154// ---- VK_EXT_direct_mode_display extension trampoline/terminators 155 156VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) { 157 const VkLayerInstanceDispatchTable *disp; 158 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 159 if (VK_NULL_HANDLE == unwrapped_phys_dev) { 160 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, 161 "vkReleaseDisplayEXT: Invalid physicalDevice [VUID-vkReleaseDisplayEXT-physicalDevice-parameter]"); 162 abort(); /* Intentionally fail so user can correct issue. */ 163 } 164 disp = loader_get_instance_layer_dispatch(physicalDevice); 165 return disp->ReleaseDisplayEXT(unwrapped_phys_dev, display); 166} 167 168VKAPI_ATTR VkResult VKAPI_CALL terminator_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) { 169 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 170 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 171 172 if (icd_term->dispatch.ReleaseDisplayEXT == NULL) { 173 loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0, 174 "ICD \"%s\" associated with VkPhysicalDevice does not support vkReleaseDisplayEXT - Consequently, the call is " 175 "invalid because it should not be possible to acquire a display on this device", 176 icd_term->scanned_icd->lib_name); 177 abort(); 178 } 179 return icd_term->dispatch.ReleaseDisplayEXT(phys_dev_term->phys_dev, display); 180} 181 182// ---- VK_EXT_acquire_xlib_display extension trampoline/terminators 183 184#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) 185VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, VkDisplayKHR display) { 186 const VkLayerInstanceDispatchTable *disp; 187 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 188 if (VK_NULL_HANDLE == unwrapped_phys_dev) { 189 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, 190 "vkAcquireXlibDisplayEXT: Invalid physicalDevice [VUID-vkAcquireXlibDisplayEXT-physicalDevice-parameter]"); 191 abort(); /* Intentionally fail so user can correct issue. */ 192 } 193 disp = loader_get_instance_layer_dispatch(physicalDevice); 194 return disp->AcquireXlibDisplayEXT(unwrapped_phys_dev, dpy, display); 195} 196 197VKAPI_ATTR VkResult VKAPI_CALL terminator_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, 198 VkDisplayKHR display) { 199 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 200 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 201 202 if (icd_term->dispatch.AcquireXlibDisplayEXT != NULL) { 203 // Pass the call to the driver 204 return icd_term->dispatch.AcquireXlibDisplayEXT(phys_dev_term->phys_dev, dpy, display); 205 } else { 206 // Emulate the call 207 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 208 "vkAcquireXLibDisplayEXT: Emulating call in ICD \"%s\" by returning error", icd_term->scanned_icd->lib_name); 209 210 // Fail for the unsupported command 211 return VK_ERROR_INITIALIZATION_FAILED; 212 } 213} 214 215VKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput, 216 VkDisplayKHR *pDisplay) { 217 const VkLayerInstanceDispatchTable *disp; 218 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 219 if (VK_NULL_HANDLE == unwrapped_phys_dev) { 220 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, 221 "vkGetRandROutputDisplayEXT: Invalid physicalDevice [VUID-vkGetRandROutputDisplayEXT-physicalDevice-parameter]"); 222 abort(); /* Intentionally fail so user can correct issue. */ 223 } 224 disp = loader_get_instance_layer_dispatch(physicalDevice); 225 return disp->GetRandROutputDisplayEXT(unwrapped_phys_dev, dpy, rrOutput, pDisplay); 226} 227 228VKAPI_ATTR VkResult VKAPI_CALL terminator_GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput, 229 VkDisplayKHR *pDisplay) { 230 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 231 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 232 233 if (icd_term->dispatch.GetRandROutputDisplayEXT != NULL) { 234 // Pass the call to the driver 235 return icd_term->dispatch.GetRandROutputDisplayEXT(phys_dev_term->phys_dev, dpy, rrOutput, pDisplay); 236 } else { 237 // Emulate the call 238 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, 239 "vkGetRandROutputDisplayEXT: Emulating call in ICD \"%s\" by returning null display", 240 icd_term->scanned_icd->lib_name); 241 242 // Return a null handle to indicate this can't be done 243 *pDisplay = VK_NULL_HANDLE; 244 return VK_SUCCESS; 245 } 246} 247 248#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT 249 250#if defined(VK_USE_PLATFORM_WIN32_KHR) 251VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModes2EXT(VkPhysicalDevice physicalDevice, 252 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 253 uint32_t *pPresentModeCount, 254 VkPresentModeKHR *pPresentModes) { 255 const VkLayerInstanceDispatchTable *disp; 256 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 257 if (VK_NULL_HANDLE == unwrapped_phys_dev) { 258 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, 259 "vkGetPhysicalDeviceSurfacePresentModes2EXT: Invalid physicalDevice " 260 "[VUID-vkGetPhysicalDeviceSurfacePresentModes2EXT-physicalDevice-parameter]"); 261 abort(); /* Intentionally fail so user can correct issue. */ 262 } 263 disp = loader_get_instance_layer_dispatch(physicalDevice); 264 return disp->GetPhysicalDeviceSurfacePresentModes2EXT(unwrapped_phys_dev, pSurfaceInfo, pPresentModeCount, pPresentModes); 265} 266 267VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModes2EXT( 268 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, uint32_t *pPresentModeCount, 269 VkPresentModeKHR *pPresentModes) { 270 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 271 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 272 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT) { 273 loader_log(icd_term->this_instance, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0, 274 "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceSurfacePresentModes2EXT"); 275 abort(); 276 } 277 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface); 278 uint8_t icd_index = phys_dev_term->icd_index; 279 if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)icd_surface->real_icd_surfaces[icd_index]) { 280 VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy; 281 surface_info_copy.sType = pSurfaceInfo->sType; 282 surface_info_copy.pNext = pSurfaceInfo->pNext; 283 surface_info_copy.surface = icd_surface->real_icd_surfaces[icd_index]; 284 return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, &surface_info_copy, 285 pPresentModeCount, pPresentModes); 286 } 287 return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, pSurfaceInfo, pPresentModeCount, 288 pPresentModes); 289} 290 291VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupSurfacePresentModes2EXT(VkDevice device, 292 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 293 VkDeviceGroupPresentModeFlagsKHR *pModes) { 294 const VkLayerDispatchTable *disp = loader_get_dispatch(device); 295 if (NULL == disp) { 296 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, 297 "vkGetDeviceGroupSurfacePresentModes2EXT: Invalid device " 298 "[VUID-vkGetDeviceGroupSurfacePresentModes2EXT-device-parameter]"); 299 abort(); /* Intentionally fail so user can correct issue. */ 300 } 301 return disp->GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes); 302} 303 304VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModes2EXT(VkDevice device, 305 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 306 VkDeviceGroupPresentModeFlagsKHR *pModes) { 307 uint32_t icd_index = 0; 308 struct loader_device *dev; 309 struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); 310 if (NULL == icd_term || NULL == dev || 311 NULL == dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT) { 312 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, 313 "vkGetDeviceGroupSurfacePresentModes2EXT Terminator: Invalid device handle. This is likely the result of a " 314 "layer wrapping device handles and failing to unwrap them in all functions. " 315 "[VUID-vkGetDeviceGroupSurfacePresentModes2EXT-device-parameter]"); 316 abort(); /* Intentionally fail so user can correct issue. */ 317 } 318 if (NULL == pSurfaceInfo) { 319 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, 320 "vkGetDeviceGroupSurfacePresentModes2EXT: Invalid pSurfaceInfo pointer " 321 "[VUID-vkGetDeviceGroupSurfacePresentModes2EXT-pSurfaceInfo-parameter]"); 322 abort(); /* Intentionally fail so user can correct issue. */ 323 } 324 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface; 325 if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)icd_surface->real_icd_surfaces[icd_index]) { 326 VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy; 327 surface_info_copy.sType = pSurfaceInfo->sType; 328 surface_info_copy.pNext = pSurfaceInfo->pNext; 329 surface_info_copy.surface = icd_surface->real_icd_surfaces[icd_index]; 330 return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, &surface_info_copy, 331 pModes); 332 } 333 return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes); 334} 335 336#endif // VK_USE_PLATFORM_WIN32_KHR 337 338// ---- VK_EXT_tooling_info extension trampoline/terminators 339 340VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceToolPropertiesEXT(VkPhysicalDevice physicalDevice, uint32_t *pToolCount, 341 VkPhysicalDeviceToolPropertiesEXT *pToolProperties) { 342 const VkLayerInstanceDispatchTable *disp; 343 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 344 if (VK_NULL_HANDLE == unwrapped_phys_dev) { 345 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0, 346 "vkGetPhysicalDeviceToolPropertiesEXT: Invalid physicalDevice " 347 "[VUID-vkGetPhysicalDeviceToolPropertiesEXT-physicalDevice-parameter]"); 348 abort(); /* Intentionally fail so user can correct issue. */ 349 } 350 disp = loader_get_instance_layer_dispatch(physicalDevice); 351 return disp->GetPhysicalDeviceToolPropertiesEXT(unwrapped_phys_dev, pToolCount, pToolProperties); 352} 353 354VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceToolPropertiesEXT(VkPhysicalDevice physicalDevice, uint32_t *pToolCount, 355 VkPhysicalDeviceToolPropertiesEXT *pToolProperties) { 356 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 357 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 358 359 bool tooling_info_supported = false; 360 uint32_t ext_count = 0; 361 VkExtensionProperties *ext_props = NULL; 362 VkResult res = VK_SUCCESS; 363 VkResult enumerate_res = VK_SUCCESS; 364 365 enumerate_res = icd_term->dispatch.EnumerateDeviceExtensionProperties(phys_dev_term->phys_dev, NULL, &ext_count, NULL); 366 if (enumerate_res != VK_SUCCESS) { 367 goto out; 368 } 369 370 ext_props = loader_instance_heap_alloc(icd_term->this_instance, sizeof(VkExtensionProperties) * ext_count, 371 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 372 if (!ext_props) { 373 res = VK_ERROR_OUT_OF_HOST_MEMORY; 374 goto out; 375 } 376 377 enumerate_res = icd_term->dispatch.EnumerateDeviceExtensionProperties(phys_dev_term->phys_dev, NULL, &ext_count, ext_props); 378 if (enumerate_res != VK_SUCCESS) { 379 goto out; 380 } 381 382 for (uint32_t i = 0; i < ext_count; i++) { 383 if (strncmp(ext_props[i].extensionName, VK_EXT_TOOLING_INFO_EXTENSION_NAME, VK_MAX_EXTENSION_NAME_SIZE) == 0) { 384 tooling_info_supported = true; 385 break; 386 } 387 } 388 389 if (tooling_info_supported && icd_term->dispatch.GetPhysicalDeviceToolPropertiesEXT) { 390 res = icd_term->dispatch.GetPhysicalDeviceToolPropertiesEXT(phys_dev_term->phys_dev, pToolCount, pToolProperties); 391 } 392 393out: 394 // In the case the driver didn't support the extension, make sure that the first layer doesn't find the count uninitialized 395 if (!tooling_info_supported || !icd_term->dispatch.GetPhysicalDeviceToolPropertiesEXT) { 396 *pToolCount = 0; 397 } 398 399 loader_instance_heap_free(icd_term->this_instance, ext_props); 400 401 return res; 402} 403