1 /* 2 * Copyright (c) 2015-2016 The Khronos Group Inc. 3 * Copyright (c) 2015-2016 Valve Corporation 4 * Copyright (c) 2015-2016 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: Ian Elliott <ian (at) lunarg.com> 19 * Author: Jon Ashburn <jon (at) lunarg.com> 20 * Author: Ian Elliott <ianelliott (at) google.com> 21 * Author: Mark Lobodzinski <mark (at) lunarg.com> 22 */ 23 24 #define _GNU_SOURCE 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include "vk_loader_platform.h" 29 #include "loader.h" 30 #include "wsi.h" 31 #include <vulkan/vk_icd.h> 32 33 // The first ICD/Loader interface that support querying the SurfaceKHR from 34 // the ICDs. 35 #define ICD_VER_SUPPORTS_ICD_SURFACE_KHR 3 36 37 void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) { 38 ptr_instance->wsi_surface_enabled = false; 39 40 #ifdef VK_USE_PLATFORM_WIN32_KHR 41 ptr_instance->wsi_win32_surface_enabled = false; 42 #endif // VK_USE_PLATFORM_WIN32_KHR 43 #ifdef VK_USE_PLATFORM_MIR_KHR 44 ptr_instance->wsi_mir_surface_enabled = false; 45 #endif // VK_USE_PLATFORM_MIR_KHR 46 #ifdef VK_USE_PLATFORM_WAYLAND_KHR 47 ptr_instance->wsi_wayland_surface_enabled = false; 48 #endif // VK_USE_PLATFORM_WAYLAND_KHR 49 #ifdef VK_USE_PLATFORM_XCB_KHR 50 ptr_instance->wsi_xcb_surface_enabled = false; 51 #endif // VK_USE_PLATFORM_XCB_KHR 52 #ifdef VK_USE_PLATFORM_XLIB_KHR 53 ptr_instance->wsi_xlib_surface_enabled = false; 54 #endif // VK_USE_PLATFORM_XLIB_KHR 55 #ifdef VK_USE_PLATFORM_ANDROID_KHR 56 ptr_instance->wsi_android_surface_enabled = false; 57 #endif // VK_USE_PLATFORM_ANDROID_KHR 58 59 ptr_instance->wsi_display_enabled = false; 60 61 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { 62 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) { 63 ptr_instance->wsi_surface_enabled = true; 64 continue; 65 } 66 #ifdef VK_USE_PLATFORM_WIN32_KHR 67 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) { 68 ptr_instance->wsi_win32_surface_enabled = true; 69 continue; 70 } 71 #endif // VK_USE_PLATFORM_WIN32_KHR 72 #ifdef VK_USE_PLATFORM_MIR_KHR 73 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) { 74 ptr_instance->wsi_mir_surface_enabled = true; 75 continue; 76 } 77 #endif // VK_USE_PLATFORM_MIR_KHR 78 #ifdef VK_USE_PLATFORM_WAYLAND_KHR 79 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) { 80 ptr_instance->wsi_wayland_surface_enabled = true; 81 continue; 82 } 83 #endif // VK_USE_PLATFORM_WAYLAND_KHR 84 #ifdef VK_USE_PLATFORM_XCB_KHR 85 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) { 86 ptr_instance->wsi_xcb_surface_enabled = true; 87 continue; 88 } 89 #endif // VK_USE_PLATFORM_XCB_KHR 90 #ifdef VK_USE_PLATFORM_XLIB_KHR 91 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) { 92 ptr_instance->wsi_xlib_surface_enabled = true; 93 continue; 94 } 95 #endif // VK_USE_PLATFORM_XLIB_KHR 96 #ifdef VK_USE_PLATFORM_ANDROID_KHR 97 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) { 98 ptr_instance->wsi_android_surface_enabled = true; 99 continue; 100 } 101 #endif // VK_USE_PLATFORM_ANDROID_KHR 102 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) { 103 ptr_instance->wsi_display_enabled = true; 104 continue; 105 } 106 } 107 } 108 109 // Linux WSI surface extensions are not always compiled into the loader. (Assume 110 // for Windows the KHR_win32_surface is always compiled into loader). A given 111 // Linux build environment might not have the headers required for building one 112 // of the four extensions (Xlib, Xcb, Mir, Wayland). Thus, need to check if 113 // the built loader actually supports the particular Linux surface extension. 114 // If not supported by the built loader it will not be included in the list of 115 // enumerated instance extensions. This solves the issue where an ICD or layer 116 // advertises support for a given Linux surface extension but the loader was not 117 // built to support the extension. 118 bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop) { 119 #ifndef VK_USE_PLATFORM_MIR_KHR 120 if (!strcmp(ext_prop->extensionName, "VK_KHR_mir_surface")) return true; 121 #endif // VK_USE_PLATFORM_MIR_KHR 122 #ifndef VK_USE_PLATFORM_WAYLAND_KHR 123 if (!strcmp(ext_prop->extensionName, "VK_KHR_wayland_surface")) return true; 124 #endif // VK_USE_PLATFORM_WAYLAND_KHR 125 #ifndef VK_USE_PLATFORM_XCB_KHR 126 if (!strcmp(ext_prop->extensionName, "VK_KHR_xcb_surface")) return true; 127 #endif // VK_USE_PLATFORM_XCB_KHR 128 #ifndef VK_USE_PLATFORM_XLIB_KHR 129 if (!strcmp(ext_prop->extensionName, "VK_KHR_xlib_surface")) return true; 130 #endif // VK_USE_PLATFORM_XLIB_KHR 131 132 return false; 133 } 134 135 // Functions for the VK_KHR_surface extension: 136 137 // This is the trampoline entrypoint for DestroySurfaceKHR 138 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, 139 const VkAllocationCallbacks *pAllocator) { 140 const VkLayerInstanceDispatchTable *disp; 141 disp = loader_get_instance_layer_dispatch(instance); 142 disp->DestroySurfaceKHR(instance, surface, pAllocator); 143 } 144 145 // TODO probably need to lock around all the loader_get_instance() calls. 146 147 // This is the instance chain terminator function for DestroySurfaceKHR 148 VKAPI_ATTR void VKAPI_CALL terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, 149 const VkAllocationCallbacks *pAllocator) { 150 struct loader_instance *ptr_instance = loader_get_instance(instance); 151 152 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; 153 if (NULL != icd_surface) { 154 if (NULL != icd_surface->real_icd_surfaces) { 155 uint32_t i = 0; 156 for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 157 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { 158 if (NULL != icd_term->dispatch.DestroySurfaceKHR && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[i]) { 159 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator); 160 icd_surface->real_icd_surfaces[i] = (VkSurfaceKHR)NULL; 161 } 162 } else { 163 // The real_icd_surface for any ICD not supporting the 164 // proper interface version should be NULL. If not, then 165 // we have a problem. 166 assert((VkSurfaceKHR)NULL == icd_surface->real_icd_surfaces[i]); 167 } 168 } 169 loader_instance_heap_free(ptr_instance, icd_surface->real_icd_surfaces); 170 } 171 172 loader_instance_heap_free(ptr_instance, (void *)(uintptr_t)surface); 173 } 174 } 175 176 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceSupportKHR 177 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, 178 uint32_t queueFamilyIndex, VkSurfaceKHR surface, 179 VkBool32 *pSupported) { 180 const VkLayerInstanceDispatchTable *disp; 181 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 182 disp = loader_get_instance_layer_dispatch(physicalDevice); 183 VkResult res = disp->GetPhysicalDeviceSurfaceSupportKHR(unwrapped_phys_dev, queueFamilyIndex, surface, pSupported); 184 return res; 185 } 186 187 // This is the instance chain terminator function for 188 // GetPhysicalDeviceSurfaceSupportKHR 189 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, 190 uint32_t queueFamilyIndex, VkSurfaceKHR surface, 191 VkBool32 *pSupported) { 192 // First, check to ensure the appropriate extension was enabled: 193 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 194 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 195 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 196 if (!ptr_instance->wsi_surface_enabled) { 197 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 198 "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not executed!\n"); 199 return VK_SUCCESS; 200 } 201 202 if (NULL == pSupported) { 203 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 204 "NULL pointer passed into vkGetPhysicalDeviceSurfaceSupportKHR for pSupported!\n"); 205 assert(false && "GetPhysicalDeviceSurfaceSupportKHR: Error, null pSupported"); 206 } 207 *pSupported = false; 208 209 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR) { 210 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 211 "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfaceSupportKHR!\n"); 212 assert(false && "loader: null GetPhysicalDeviceSurfaceSupportKHR ICD pointer"); 213 } 214 215 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; 216 if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) { 217 return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR( 218 phys_dev_term->phys_dev, queueFamilyIndex, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSupported); 219 } 220 221 return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, surface, pSupported); 222 } 223 224 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceCapabilitiesKHR 225 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR( 226 VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) { 227 const VkLayerInstanceDispatchTable *disp; 228 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 229 disp = loader_get_instance_layer_dispatch(physicalDevice); 230 VkResult res = disp->GetPhysicalDeviceSurfaceCapabilitiesKHR(unwrapped_phys_dev, surface, pSurfaceCapabilities); 231 return res; 232 } 233 234 // This is the instance chain terminator function for 235 // GetPhysicalDeviceSurfaceCapabilitiesKHR 236 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, 237 VkSurfaceKHR surface, 238 VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) { 239 // First, check to ensure the appropriate extension was enabled: 240 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 241 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 242 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 243 if (!ptr_instance->wsi_surface_enabled) { 244 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 245 "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceCapabilitiesKHR not executed!\n"); 246 return VK_SUCCESS; 247 } 248 249 if (NULL == pSurfaceCapabilities) { 250 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 251 "NULL pointer passed into vkGetPhysicalDeviceSurfaceCapabilitiesKHR for pSurfaceCapabilities!\n"); 252 assert(false && "GetPhysicalDeviceSurfaceCapabilitiesKHR: Error, null pSurfaceCapabilities"); 253 } 254 255 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR) { 256 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 257 "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfaceCapabilitiesKHR!\n"); 258 assert(false && "loader: null GetPhysicalDeviceSurfaceCapabilitiesKHR ICD pointer"); 259 } 260 261 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; 262 if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) { 263 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR( 264 phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSurfaceCapabilities); 265 } 266 267 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface, pSurfaceCapabilities); 268 } 269 270 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceFormatsKHR 271 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, 272 VkSurfaceKHR surface, 273 uint32_t *pSurfaceFormatCount, 274 VkSurfaceFormatKHR *pSurfaceFormats) { 275 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 276 const VkLayerInstanceDispatchTable *disp; 277 disp = loader_get_instance_layer_dispatch(physicalDevice); 278 VkResult res = disp->GetPhysicalDeviceSurfaceFormatsKHR(unwrapped_phys_dev, surface, pSurfaceFormatCount, pSurfaceFormats); 279 return res; 280 } 281 282 // This is the instance chain terminator function for 283 // GetPhysicalDeviceSurfaceFormatsKHR 284 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 285 uint32_t *pSurfaceFormatCount, 286 VkSurfaceFormatKHR *pSurfaceFormats) { 287 // First, check to ensure the appropriate extension was enabled: 288 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 289 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 290 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 291 if (!ptr_instance->wsi_surface_enabled) { 292 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 293 "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not executed!\n"); 294 return VK_SUCCESS; 295 } 296 297 if (NULL == pSurfaceFormatCount) { 298 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 299 "NULL pointer passed into vkGetPhysicalDeviceSurfaceFormatsKHR for pSurfaceFormatCount!\n"); 300 assert(false && "GetPhysicalDeviceSurfaceFormatsKHR(: Error, null pSurfaceFormatCount"); 301 } 302 303 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR) { 304 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 305 "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfaceCapabilitiesKHR!\n"); 306 assert(false && "loader: null GetPhysicalDeviceSurfaceFormatsKHR ICD pointer"); 307 } 308 309 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; 310 if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) { 311 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, 312 icd_surface->real_icd_surfaces[phys_dev_term->icd_index], 313 pSurfaceFormatCount, pSurfaceFormats); 314 } 315 316 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount, 317 pSurfaceFormats); 318 } 319 320 // This is the trampoline entrypoint for GetPhysicalDeviceSurfacePresentModesKHR 321 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, 322 VkSurfaceKHR surface, 323 uint32_t *pPresentModeCount, 324 VkPresentModeKHR *pPresentModes) { 325 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 326 const VkLayerInstanceDispatchTable *disp; 327 disp = loader_get_instance_layer_dispatch(physicalDevice); 328 VkResult res = disp->GetPhysicalDeviceSurfacePresentModesKHR(unwrapped_phys_dev, surface, pPresentModeCount, pPresentModes); 329 return res; 330 } 331 332 // This is the instance chain terminator function for 333 // GetPhysicalDeviceSurfacePresentModesKHR 334 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, 335 VkSurfaceKHR surface, uint32_t *pPresentModeCount, 336 VkPresentModeKHR *pPresentModes) { 337 // First, check to ensure the appropriate extension was enabled: 338 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 339 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 340 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 341 if (!ptr_instance->wsi_surface_enabled) { 342 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 343 "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR not executed!\n"); 344 return VK_SUCCESS; 345 } 346 347 if (NULL == pPresentModeCount) { 348 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 349 "NULL pointer passed into vkGetPhysicalDeviceSurfacePresentModesKHR for pPresentModeCount!\n"); 350 assert(false && "GetPhysicalDeviceSurfacePresentModesKHR(: Error, null pPresentModeCount"); 351 } 352 353 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR) { 354 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 355 "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfacePresentModesKHR!\n"); 356 assert(false && "loader: null GetPhysicalDeviceSurfacePresentModesKHR ICD pointer"); 357 } 358 359 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface; 360 if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) { 361 return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR( 362 phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pPresentModeCount, pPresentModes); 363 } 364 365 return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(phys_dev_term->phys_dev, surface, pPresentModeCount, 366 pPresentModes); 367 } 368 369 // Functions for the VK_KHR_swapchain extension: 370 371 // This is the trampoline entrypoint for CreateSwapchainKHR 372 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, 373 const VkAllocationCallbacks *pAllocator, 374 VkSwapchainKHR *pSwapchain) { 375 const VkLayerDispatchTable *disp; 376 disp = loader_get_dispatch(device); 377 return disp->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); 378 } 379 380 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, 381 const VkAllocationCallbacks *pAllocator, 382 VkSwapchainKHR *pSwapchain) { 383 uint32_t icd_index = 0; 384 struct loader_device *dev; 385 struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); 386 if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) { 387 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfo->surface; 388 if (NULL != icd_surface->real_icd_surfaces) { 389 if ((VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) { 390 // We found the ICD, and there is an ICD KHR surface 391 // associated with it, so copy the CreateInfo struct 392 // and point it at the ICD's surface. 393 VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR)); 394 if (NULL == pCreateCopy) { 395 return VK_ERROR_OUT_OF_HOST_MEMORY; 396 } 397 memcpy(pCreateCopy, pCreateInfo, sizeof(VkSwapchainCreateInfoKHR)); 398 pCreateCopy->surface = icd_surface->real_icd_surfaces[icd_index]; 399 return icd_term->dispatch.CreateSwapchainKHR(device, pCreateCopy, pAllocator, pSwapchain); 400 } 401 } 402 return icd_term->dispatch.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); 403 } 404 return VK_SUCCESS; 405 } 406 407 // This is the trampoline entrypoint for DestroySwapchainKHR 408 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, 409 const VkAllocationCallbacks *pAllocator) { 410 const VkLayerDispatchTable *disp; 411 disp = loader_get_dispatch(device); 412 disp->DestroySwapchainKHR(device, swapchain, pAllocator); 413 } 414 415 // This is the trampoline entrypoint for GetSwapchainImagesKHR 416 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, 417 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) { 418 const VkLayerDispatchTable *disp; 419 disp = loader_get_dispatch(device); 420 return disp->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages); 421 } 422 423 // This is the trampoline entrypoint for AcquireNextImageKHR 424 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, 425 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) { 426 const VkLayerDispatchTable *disp; 427 disp = loader_get_dispatch(device); 428 return disp->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex); 429 } 430 431 // This is the trampoline entrypoint for QueuePresentKHR 432 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) { 433 const VkLayerDispatchTable *disp; 434 disp = loader_get_dispatch(queue); 435 return disp->QueuePresentKHR(queue, pPresentInfo); 436 } 437 438 static VkIcdSurface *AllocateIcdSurfaceStruct(struct loader_instance *instance, size_t base_size, size_t platform_size) { 439 // Next, if so, proceed with the implementation of this function: 440 VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 441 if (pIcdSurface != NULL) { 442 // Setup the new sizes and offsets so we can grow the structures in the 443 // future without having problems 444 pIcdSurface->base_size = (uint32_t)base_size; 445 pIcdSurface->platform_size = (uint32_t)platform_size; 446 pIcdSurface->non_platform_offset = (uint32_t)((uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface); 447 pIcdSurface->entire_size = sizeof(VkIcdSurface); 448 449 pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(instance, sizeof(VkSurfaceKHR) * instance->total_icd_count, 450 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 451 if (pIcdSurface->real_icd_surfaces == NULL) { 452 loader_instance_heap_free(instance, pIcdSurface); 453 pIcdSurface = NULL; 454 } else { 455 memset(pIcdSurface->real_icd_surfaces, 0, sizeof(VkSurfaceKHR) * instance->total_icd_count); 456 } 457 } 458 return pIcdSurface; 459 } 460 461 #ifdef VK_USE_PLATFORM_WIN32_KHR 462 463 // Functions for the VK_KHR_win32_surface extension: 464 465 // This is the trampoline entrypoint for CreateWin32SurfaceKHR 466 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance instance, 467 const VkWin32SurfaceCreateInfoKHR *pCreateInfo, 468 const VkAllocationCallbacks *pAllocator, 469 VkSurfaceKHR *pSurface) { 470 const VkLayerInstanceDispatchTable *disp; 471 disp = loader_get_instance_layer_dispatch(instance); 472 VkResult res; 473 474 res = disp->CreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 475 return res; 476 } 477 478 // This is the instance chain terminator function for CreateWin32SurfaceKHR 479 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, 480 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 481 VkResult vkRes = VK_SUCCESS; 482 VkIcdSurface *pIcdSurface = NULL; 483 uint32_t i = 0; 484 485 // Initialize pSurface to NULL just to be safe. 486 *pSurface = VK_NULL_HANDLE; 487 // First, check to ensure the appropriate extension was enabled: 488 struct loader_instance *ptr_instance = loader_get_instance(instance); 489 if (!ptr_instance->wsi_win32_surface_enabled) { 490 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 491 "VK_KHR_win32_surface extension not enabled. vkCreateWin32SurfaceKHR not executed!\n"); 492 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; 493 goto out; 494 } 495 496 // Next, if so, proceed with the implementation of this function: 497 pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->win_surf.base), sizeof(pIcdSurface->win_surf)); 498 if (pIcdSurface == NULL) { 499 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; 500 goto out; 501 } 502 503 pIcdSurface->win_surf.base.platform = VK_ICD_WSI_PLATFORM_WIN32; 504 pIcdSurface->win_surf.hinstance = pCreateInfo->hinstance; 505 pIcdSurface->win_surf.hwnd = pCreateInfo->hwnd; 506 507 // Loop through each ICD and determine if they need to create a surface 508 for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 509 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { 510 if (NULL != icd_term->dispatch.CreateWin32SurfaceKHR) { 511 vkRes = icd_term->dispatch.CreateWin32SurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, 512 &pIcdSurface->real_icd_surfaces[i]); 513 if (VK_SUCCESS != vkRes) { 514 goto out; 515 } 516 } 517 } 518 } 519 520 *pSurface = (VkSurfaceKHR)(pIcdSurface); 521 522 out: 523 524 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { 525 if (NULL != pIcdSurface->real_icd_surfaces) { 526 i = 0; 527 for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 528 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) { 529 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); 530 } 531 } 532 loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces); 533 } 534 loader_instance_heap_free(ptr_instance, pIcdSurface); 535 } 536 537 return vkRes; 538 } 539 540 // This is the trampoline entrypoint for 541 // GetPhysicalDeviceWin32PresentationSupportKHR 542 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, 543 uint32_t queueFamilyIndex) { 544 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 545 const VkLayerInstanceDispatchTable *disp; 546 disp = loader_get_instance_layer_dispatch(physicalDevice); 547 VkBool32 res = disp->GetPhysicalDeviceWin32PresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex); 548 return res; 549 } 550 551 // This is the instance chain terminator function for 552 // GetPhysicalDeviceWin32PresentationSupportKHR 553 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, 554 uint32_t queueFamilyIndex) { 555 // First, check to ensure the appropriate extension was enabled: 556 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 557 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 558 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 559 if (!ptr_instance->wsi_win32_surface_enabled) { 560 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 561 "VK_KHR_win32_surface extension not enabled. vkGetPhysicalDeviceWin32PresentationSupportKHR not executed!\n"); 562 return VK_SUCCESS; 563 } 564 565 if (NULL == icd_term->dispatch.GetPhysicalDeviceWin32PresentationSupportKHR) { 566 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 567 "ICD for selected physical device is not exporting vkGetPhysicalDeviceWin32PresentationSupportKHR!\n"); 568 assert(false && "loader: null GetPhysicalDeviceWin32PresentationSupportKHR ICD pointer"); 569 } 570 571 return icd_term->dispatch.GetPhysicalDeviceWin32PresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex); 572 } 573 #endif // VK_USE_PLATFORM_WIN32_KHR 574 575 #ifdef VK_USE_PLATFORM_MIR_KHR 576 577 // Functions for the VK_KHR_mir_surface extension: 578 579 // This is the trampoline entrypoint for CreateMirSurfaceKHR 580 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(VkInstance instance, 581 const VkMirSurfaceCreateInfoKHR *pCreateInfo, 582 const VkAllocationCallbacks *pAllocator, 583 VkSurfaceKHR *pSurface) { 584 const VkLayerInstanceDispatchTable *disp; 585 disp = loader_get_instance_layer_dispatch(instance); 586 VkResult res; 587 588 res = disp->CreateMirSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 589 return res; 590 } 591 592 // This is the instance chain terminator function for CreateMirSurfaceKHR 593 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMirSurfaceKHR(VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo, 594 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 595 VkResult vkRes = VK_SUCCESS; 596 VkIcdSurface *pIcdSurface = NULL; 597 uint32_t i = 0; 598 599 // First, check to ensure the appropriate extension was enabled: 600 struct loader_instance *ptr_instance = loader_get_instance(instance); 601 if (!ptr_instance->wsi_mir_surface_enabled) { 602 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 603 "VK_KHR_mir_surface extension not enabled. vkCreateMirSurfaceKHR not executed!\n"); 604 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; 605 goto out; 606 } 607 608 // Next, if so, proceed with the implementation of this function: 609 pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->mir_surf.base), sizeof(pIcdSurface->mir_surf)); 610 if (pIcdSurface == NULL) { 611 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; 612 goto out; 613 } 614 615 pIcdSurface->mir_surf.base.platform = VK_ICD_WSI_PLATFORM_MIR; 616 pIcdSurface->mir_surf.connection = pCreateInfo->connection; 617 pIcdSurface->mir_surf.mirSurface = pCreateInfo->mirSurface; 618 619 // Loop through each ICD and determine if they need to create a surface 620 for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 621 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { 622 if (NULL != icd_term->dispatch.CreateMirSurfaceKHR) { 623 vkRes = icd_term->dispatch.CreateMirSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, 624 &pIcdSurface->real_icd_surfaces[i]); 625 if (VK_SUCCESS != vkRes) { 626 goto out; 627 } 628 } 629 } 630 } 631 632 *pSurface = (VkSurfaceKHR)pIcdSurface; 633 634 out: 635 636 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { 637 if (NULL != pIcdSurface->real_icd_surfaces) { 638 i = 0; 639 for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 640 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) { 641 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); 642 } 643 } 644 loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces); 645 } 646 loader_instance_heap_free(ptr_instance, pIcdSurface); 647 } 648 649 return vkRes; 650 } 651 652 // This is the trampoline entrypoint for 653 // GetPhysicalDeviceMirPresentationSupportKHR 654 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice, 655 uint32_t queueFamilyIndex, 656 MirConnection *connection) { 657 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 658 const VkLayerInstanceDispatchTable *disp; 659 disp = loader_get_instance_layer_dispatch(physicalDevice); 660 VkBool32 res = disp->GetPhysicalDeviceMirPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, connection); 661 return res; 662 } 663 664 // This is the instance chain terminator function for 665 // GetPhysicalDeviceMirPresentationSupportKHR 666 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice, 667 uint32_t queueFamilyIndex, 668 MirConnection *connection) { 669 // First, check to ensure the appropriate extension was enabled: 670 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 671 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 672 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 673 if (!ptr_instance->wsi_mir_surface_enabled) { 674 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 675 "VK_KHR_mir_surface extension not enabled. vkGetPhysicalDeviceMirPresentationSupportKHR not executed!\n"); 676 return VK_SUCCESS; 677 } 678 679 if (NULL == icd_term->dispatch.GetPhysicalDeviceMirPresentationSupportKHR) { 680 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 681 "ICD for selected physical device is not exporting vkGetPhysicalDeviceMirPresentationSupportKHR!\n"); 682 assert(false && "loader: null GetPhysicalDeviceMirPresentationSupportKHR ICD pointer"); 683 } 684 685 return icd_term->dispatch.GetPhysicalDeviceMirPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, connection); 686 } 687 #endif // VK_USE_PLATFORM_MIR_KHR 688 689 #ifdef VK_USE_PLATFORM_WAYLAND_KHR 690 691 // This is the trampoline entrypoint for CreateWaylandSurfaceKHR 692 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(VkInstance instance, 693 const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, 694 const VkAllocationCallbacks *pAllocator, 695 VkSurfaceKHR *pSurface) { 696 const VkLayerInstanceDispatchTable *disp; 697 disp = loader_get_instance_layer_dispatch(instance); 698 VkResult res; 699 700 res = disp->CreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 701 return res; 702 } 703 704 // This is the instance chain terminator function for CreateWaylandSurfaceKHR 705 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance instance, 706 const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, 707 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 708 VkResult vkRes = VK_SUCCESS; 709 VkIcdSurface *pIcdSurface = NULL; 710 uint32_t i = 0; 711 712 // First, check to ensure the appropriate extension was enabled: 713 struct loader_instance *ptr_instance = loader_get_instance(instance); 714 if (!ptr_instance->wsi_wayland_surface_enabled) { 715 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 716 "VK_KHR_wayland_surface extension not enabled. vkCreateWaylandSurfaceKHR not executed!\n"); 717 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; 718 goto out; 719 } 720 721 // Next, if so, proceed with the implementation of this function: 722 pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->wayland_surf.base), sizeof(pIcdSurface->wayland_surf)); 723 if (pIcdSurface == NULL) { 724 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; 725 goto out; 726 } 727 728 pIcdSurface->wayland_surf.base.platform = VK_ICD_WSI_PLATFORM_WAYLAND; 729 pIcdSurface->wayland_surf.display = pCreateInfo->display; 730 pIcdSurface->wayland_surf.surface = pCreateInfo->surface; 731 732 // Loop through each ICD and determine if they need to create a surface 733 for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 734 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { 735 if (NULL != icd_term->dispatch.CreateWaylandSurfaceKHR) { 736 vkRes = icd_term->dispatch.CreateWaylandSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, 737 &pIcdSurface->real_icd_surfaces[i]); 738 if (VK_SUCCESS != vkRes) { 739 goto out; 740 } 741 } 742 } 743 } 744 745 *pSurface = (VkSurfaceKHR)pIcdSurface; 746 747 out: 748 749 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { 750 if (NULL != pIcdSurface->real_icd_surfaces) { 751 i = 0; 752 for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 753 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) { 754 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); 755 } 756 } 757 loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces); 758 } 759 loader_instance_heap_free(ptr_instance, pIcdSurface); 760 } 761 762 return vkRes; 763 } 764 765 // This is the trampoline entrypoint for 766 // GetPhysicalDeviceWaylandPresentationSupportKHR 767 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, 768 uint32_t queueFamilyIndex, 769 struct wl_display *display) { 770 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 771 const VkLayerInstanceDispatchTable *disp; 772 disp = loader_get_instance_layer_dispatch(physicalDevice); 773 VkBool32 res = disp->GetPhysicalDeviceWaylandPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, display); 774 return res; 775 } 776 777 // This is the instance chain terminator function for 778 // GetPhysicalDeviceWaylandPresentationSupportKHR 779 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, 780 uint32_t queueFamilyIndex, 781 struct wl_display *display) { 782 // First, check to ensure the appropriate extension was enabled: 783 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 784 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 785 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 786 if (!ptr_instance->wsi_wayland_surface_enabled) { 787 loader_log( 788 ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 789 "VK_KHR_wayland_surface extension not enabled. vkGetPhysicalDeviceWaylandPresentationSupportKHR not executed!\n"); 790 return VK_SUCCESS; 791 } 792 793 if (NULL == icd_term->dispatch.GetPhysicalDeviceWaylandPresentationSupportKHR) { 794 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 795 "ICD for selected physical device is not exporting vkGetPhysicalDeviceWaylandPresentationSupportKHR!\n"); 796 assert(false && "loader: null GetPhysicalDeviceWaylandPresentationSupportKHR ICD pointer"); 797 } 798 799 return icd_term->dispatch.GetPhysicalDeviceWaylandPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, display); 800 } 801 #endif // VK_USE_PLATFORM_WAYLAND_KHR 802 803 #ifdef VK_USE_PLATFORM_XCB_KHR 804 805 // Functions for the VK_KHR_xcb_surface extension: 806 807 // This is the trampoline entrypoint for CreateXcbSurfaceKHR 808 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(VkInstance instance, 809 const VkXcbSurfaceCreateInfoKHR *pCreateInfo, 810 const VkAllocationCallbacks *pAllocator, 811 VkSurfaceKHR *pSurface) { 812 const VkLayerInstanceDispatchTable *disp; 813 disp = loader_get_instance_layer_dispatch(instance); 814 VkResult res; 815 816 res = disp->CreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 817 return res; 818 } 819 820 // This is the instance chain terminator function for CreateXcbSurfaceKHR 821 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, 822 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 823 VkResult vkRes = VK_SUCCESS; 824 VkIcdSurface *pIcdSurface = NULL; 825 uint32_t i = 0; 826 827 // First, check to ensure the appropriate extension was enabled: 828 struct loader_instance *ptr_instance = loader_get_instance(instance); 829 if (!ptr_instance->wsi_xcb_surface_enabled) { 830 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 831 "VK_KHR_xcb_surface extension not enabled. vkCreateXcbSurfaceKHR not executed!\n"); 832 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; 833 goto out; 834 } 835 836 // Next, if so, proceed with the implementation of this function: 837 pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->xcb_surf.base), sizeof(pIcdSurface->xcb_surf)); 838 if (pIcdSurface == NULL) { 839 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; 840 goto out; 841 } 842 843 pIcdSurface->xcb_surf.base.platform = VK_ICD_WSI_PLATFORM_XCB; 844 pIcdSurface->xcb_surf.connection = pCreateInfo->connection; 845 pIcdSurface->xcb_surf.window = pCreateInfo->window; 846 847 // Loop through each ICD and determine if they need to create a surface 848 for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 849 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { 850 if (NULL != icd_term->dispatch.CreateXcbSurfaceKHR) { 851 vkRes = icd_term->dispatch.CreateXcbSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, 852 &pIcdSurface->real_icd_surfaces[i]); 853 if (VK_SUCCESS != vkRes) { 854 goto out; 855 } 856 } 857 } 858 } 859 860 *pSurface = (VkSurfaceKHR)pIcdSurface; 861 862 out: 863 864 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { 865 if (NULL != pIcdSurface->real_icd_surfaces) { 866 i = 0; 867 for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 868 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) { 869 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); 870 } 871 } 872 loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces); 873 } 874 loader_instance_heap_free(ptr_instance, pIcdSurface); 875 } 876 877 return vkRes; 878 } 879 880 // This is the trampoline entrypoint for 881 // GetPhysicalDeviceXcbPresentationSupportKHR 882 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, 883 uint32_t queueFamilyIndex, 884 xcb_connection_t *connection, 885 xcb_visualid_t visual_id) { 886 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 887 const VkLayerInstanceDispatchTable *disp; 888 disp = loader_get_instance_layer_dispatch(physicalDevice); 889 VkBool32 res = disp->GetPhysicalDeviceXcbPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, connection, visual_id); 890 return res; 891 } 892 893 // This is the instance chain terminator function for 894 // GetPhysicalDeviceXcbPresentationSupportKHR 895 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, 896 uint32_t queueFamilyIndex, 897 xcb_connection_t *connection, 898 xcb_visualid_t visual_id) { 899 // First, check to ensure the appropriate extension was enabled: 900 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 901 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 902 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 903 if (!ptr_instance->wsi_xcb_surface_enabled) { 904 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 905 "VK_KHR_xcb_surface extension not enabled. vkGetPhysicalDeviceXcbPresentationSupportKHR not executed!\n"); 906 return VK_SUCCESS; 907 } 908 909 if (NULL == icd_term->dispatch.GetPhysicalDeviceXcbPresentationSupportKHR) { 910 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 911 "ICD for selected physical device is not exporting vkGetPhysicalDeviceXcbPresentationSupportKHR!\n"); 912 assert(false && "loader: null GetPhysicalDeviceXcbPresentationSupportKHR ICD pointer"); 913 } 914 915 return icd_term->dispatch.GetPhysicalDeviceXcbPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, connection, 916 visual_id); 917 } 918 #endif // VK_USE_PLATFORM_XCB_KHR 919 920 #ifdef VK_USE_PLATFORM_XLIB_KHR 921 922 // Functions for the VK_KHR_xlib_surface extension: 923 924 // This is the trampoline entrypoint for CreateXlibSurfaceKHR 925 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(VkInstance instance, 926 const VkXlibSurfaceCreateInfoKHR *pCreateInfo, 927 const VkAllocationCallbacks *pAllocator, 928 VkSurfaceKHR *pSurface) { 929 const VkLayerInstanceDispatchTable *disp; 930 disp = loader_get_instance_layer_dispatch(instance); 931 VkResult res; 932 933 res = disp->CreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 934 return res; 935 } 936 937 // This is the instance chain terminator function for CreateXlibSurfaceKHR 938 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, 939 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 940 VkResult vkRes = VK_SUCCESS; 941 VkIcdSurface *pIcdSurface = NULL; 942 uint32_t i = 0; 943 944 // First, check to ensure the appropriate extension was enabled: 945 struct loader_instance *ptr_instance = loader_get_instance(instance); 946 if (!ptr_instance->wsi_xlib_surface_enabled) { 947 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 948 "VK_KHR_xlib_surface extension not enabled. vkCreateXlibSurfaceKHR not executed!\n"); 949 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; 950 goto out; 951 } 952 953 // Next, if so, proceed with the implementation of this function: 954 pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->xlib_surf.base), sizeof(pIcdSurface->xlib_surf)); 955 if (pIcdSurface == NULL) { 956 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; 957 goto out; 958 } 959 960 pIcdSurface->xlib_surf.base.platform = VK_ICD_WSI_PLATFORM_XLIB; 961 pIcdSurface->xlib_surf.dpy = pCreateInfo->dpy; 962 pIcdSurface->xlib_surf.window = pCreateInfo->window; 963 964 // Loop through each ICD and determine if they need to create a surface 965 for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 966 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { 967 if (NULL != icd_term->dispatch.CreateXlibSurfaceKHR) { 968 vkRes = icd_term->dispatch.CreateXlibSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, 969 &pIcdSurface->real_icd_surfaces[i]); 970 if (VK_SUCCESS != vkRes) { 971 goto out; 972 } 973 } 974 } 975 } 976 977 *pSurface = (VkSurfaceKHR)pIcdSurface; 978 979 out: 980 981 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { 982 if (NULL != pIcdSurface->real_icd_surfaces) { 983 i = 0; 984 for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 985 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) { 986 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); 987 } 988 } 989 loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces); 990 } 991 loader_instance_heap_free(ptr_instance, pIcdSurface); 992 } 993 994 return vkRes; 995 } 996 997 // This is the trampoline entrypoint for 998 // GetPhysicalDeviceXlibPresentationSupportKHR 999 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, 1000 uint32_t queueFamilyIndex, Display *dpy, 1001 VisualID visualID) { 1002 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 1003 const VkLayerInstanceDispatchTable *disp; 1004 disp = loader_get_instance_layer_dispatch(physicalDevice); 1005 VkBool32 res = disp->GetPhysicalDeviceXlibPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, dpy, visualID); 1006 return res; 1007 } 1008 1009 // This is the instance chain terminator function for 1010 // GetPhysicalDeviceXlibPresentationSupportKHR 1011 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, 1012 uint32_t queueFamilyIndex, Display *dpy, 1013 VisualID visualID) { 1014 // First, check to ensure the appropriate extension was enabled: 1015 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 1016 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 1017 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 1018 if (!ptr_instance->wsi_xlib_surface_enabled) { 1019 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1020 "VK_KHR_xlib_surface extension not enabled. vkGetPhysicalDeviceXlibPresentationSupportKHR not executed!\n"); 1021 return VK_SUCCESS; 1022 } 1023 1024 if (NULL == icd_term->dispatch.GetPhysicalDeviceXlibPresentationSupportKHR) { 1025 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1026 "ICD for selected physical device is not exporting vkGetPhysicalDeviceXlibPresentationSupportKHR!\n"); 1027 assert(false && "loader: null GetPhysicalDeviceXlibPresentationSupportKHR ICD pointer"); 1028 } 1029 1030 return icd_term->dispatch.GetPhysicalDeviceXlibPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, dpy, visualID); 1031 } 1032 #endif // VK_USE_PLATFORM_XLIB_KHR 1033 1034 #ifdef VK_USE_PLATFORM_ANDROID_KHR 1035 1036 // Functions for the VK_KHR_android_surface extension: 1037 1038 // This is the trampoline entrypoint for CreateAndroidSurfaceKHR 1039 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(VkInstance instance, ANativeWindow *window, 1040 const VkAllocationCallbacks *pAllocator, 1041 VkSurfaceKHR *pSurface) { 1042 const VkLayerInstanceDispatchTable *disp; 1043 disp = loader_get_instance_layer_dispatch(instance); 1044 VkResult res; 1045 1046 res = disp->CreateAndroidSurfaceKHR(instance, window, pAllocator, pSurface); 1047 return res; 1048 } 1049 1050 // This is the instance chain terminator function for CreateAndroidSurfaceKHR 1051 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateAndroidSurfaceKHR(VkInstance instance, Window window, 1052 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 1053 // First, check to ensure the appropriate extension was enabled: 1054 struct loader_instance *ptr_instance = loader_get_instance(instance); 1055 if (!ptr_instance->wsi_display_enabled) { 1056 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1057 "VK_KHR_display extension not enabled. vkCreateAndroidSurfaceKHR not executed!\n"); 1058 return VK_ERROR_EXTENSION_NOT_PRESENT; 1059 } 1060 1061 // Next, if so, proceed with the implementation of this function: 1062 VkIcdSurfaceAndroid *pIcdSurface = 1063 loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceAndroid), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1064 if (pIcdSurface == NULL) { 1065 return VK_ERROR_OUT_OF_HOST_MEMORY; 1066 } 1067 1068 pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_ANDROID; 1069 pIcdSurface->dpy = dpy; 1070 pIcdSurface->window = window; 1071 1072 *pSurface = (VkSurfaceKHR)pIcdSurface; 1073 1074 return VK_SUCCESS; 1075 } 1076 1077 #endif // VK_USE_PLATFORM_ANDROID_KHR 1078 1079 // Functions for the VK_KHR_display instance extension: 1080 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, 1081 uint32_t *pPropertyCount, 1082 VkDisplayPropertiesKHR *pProperties) { 1083 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 1084 const VkLayerInstanceDispatchTable *disp; 1085 disp = loader_get_instance_layer_dispatch(physicalDevice); 1086 VkResult res = disp->GetPhysicalDeviceDisplayPropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties); 1087 return res; 1088 } 1089 1090 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, 1091 uint32_t *pPropertyCount, 1092 VkDisplayPropertiesKHR *pProperties) { 1093 // First, check to ensure the appropriate extension was enabled: 1094 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 1095 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 1096 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 1097 if (!ptr_instance->wsi_display_enabled) { 1098 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1099 "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPropertiesKHR not executed!\n"); 1100 return VK_SUCCESS; 1101 } 1102 1103 if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR) { 1104 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1105 "ICD for selected physical device is not exporting vkGetPhysicalDeviceDisplayPropertiesKHR!\n"); 1106 assert(false && "loader: null GetPhysicalDeviceDisplayPropertiesKHR ICD pointer"); 1107 } 1108 1109 return icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties); 1110 } 1111 1112 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR( 1113 VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties) { 1114 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 1115 const VkLayerInstanceDispatchTable *disp; 1116 disp = loader_get_instance_layer_dispatch(physicalDevice); 1117 VkResult res = disp->GetPhysicalDeviceDisplayPlanePropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties); 1118 return res; 1119 } 1120 1121 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, 1122 uint32_t *pPropertyCount, 1123 VkDisplayPlanePropertiesKHR *pProperties) { 1124 // First, check to ensure the appropriate extension was enabled: 1125 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 1126 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 1127 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 1128 if (!ptr_instance->wsi_display_enabled) { 1129 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1130 "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPlanePropertiesKHR not executed!\n"); 1131 return VK_SUCCESS; 1132 } 1133 1134 if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR) { 1135 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1136 "ICD for selected physical device is not exporting vkGetPhysicalDeviceDisplayPlanePropertiesKHR!\n"); 1137 assert(false && "loader: null GetPhysicalDeviceDisplayPlanePropertiesKHR ICD pointer"); 1138 } 1139 1140 return icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties); 1141 } 1142 1143 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, 1144 uint32_t planeIndex, uint32_t *pDisplayCount, 1145 VkDisplayKHR *pDisplays) { 1146 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 1147 const VkLayerInstanceDispatchTable *disp; 1148 disp = loader_get_instance_layer_dispatch(physicalDevice); 1149 VkResult res = disp->GetDisplayPlaneSupportedDisplaysKHR(unwrapped_phys_dev, planeIndex, pDisplayCount, pDisplays); 1150 return res; 1151 } 1152 1153 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, 1154 uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) { 1155 // First, check to ensure the appropriate extension was enabled: 1156 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 1157 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 1158 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 1159 if (!ptr_instance->wsi_display_enabled) { 1160 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1161 "VK_KHR_display extension not enabled. vkGetDisplayPlaneSupportedDisplaysKHR not executed!\n"); 1162 return VK_SUCCESS; 1163 } 1164 1165 if (NULL == icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR) { 1166 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1167 "ICD for selected physical device is not exporting vkGetDisplayPlaneSupportedDisplaysKHR!\n"); 1168 assert(false && "loader: null GetDisplayPlaneSupportedDisplaysKHR ICD pointer"); 1169 } 1170 1171 return icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR(phys_dev_term->phys_dev, planeIndex, pDisplayCount, pDisplays); 1172 } 1173 1174 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, 1175 uint32_t *pPropertyCount, 1176 VkDisplayModePropertiesKHR *pProperties) { 1177 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 1178 const VkLayerInstanceDispatchTable *disp; 1179 disp = loader_get_instance_layer_dispatch(physicalDevice); 1180 VkResult res = disp->GetDisplayModePropertiesKHR(unwrapped_phys_dev, display, pPropertyCount, pProperties); 1181 return res; 1182 } 1183 1184 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, 1185 uint32_t *pPropertyCount, 1186 VkDisplayModePropertiesKHR *pProperties) { 1187 // First, check to ensure the appropriate extension was enabled: 1188 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 1189 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 1190 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 1191 if (!ptr_instance->wsi_display_enabled) { 1192 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1193 "VK_KHR_display extension not enabled. vkGetDisplayModePropertiesKHR not executed!\n"); 1194 return VK_SUCCESS; 1195 } 1196 1197 if (NULL == icd_term->dispatch.GetDisplayModePropertiesKHR) { 1198 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1199 "ICD for selected physical device is not exporting vkGetDisplayModePropertiesKHR!\n"); 1200 assert(false && "loader: null GetDisplayModePropertiesKHR ICD pointer"); 1201 } 1202 1203 return icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, pProperties); 1204 } 1205 1206 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, 1207 const VkDisplayModeCreateInfoKHR *pCreateInfo, 1208 const VkAllocationCallbacks *pAllocator, 1209 VkDisplayModeKHR *pMode) { 1210 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 1211 const VkLayerInstanceDispatchTable *disp; 1212 disp = loader_get_instance_layer_dispatch(physicalDevice); 1213 VkResult res = disp->CreateDisplayModeKHR(unwrapped_phys_dev, display, pCreateInfo, pAllocator, pMode); 1214 return res; 1215 } 1216 1217 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, 1218 const VkDisplayModeCreateInfoKHR *pCreateInfo, 1219 const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode) { 1220 // First, check to ensure the appropriate extension was enabled: 1221 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 1222 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 1223 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 1224 if (!ptr_instance->wsi_display_enabled) { 1225 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1226 "VK_KHR_display extension not enabled. vkCreateDisplayModeKHR not executed!\n"); 1227 return VK_ERROR_EXTENSION_NOT_PRESENT; 1228 } 1229 1230 if (NULL == icd_term->dispatch.CreateDisplayModeKHR) { 1231 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1232 "ICD for selected physical device is not exporting vkCreateDisplayModeKHR!\n"); 1233 assert(false && "loader: null CreateDisplayModeKHR ICD pointer"); 1234 } 1235 1236 return icd_term->dispatch.CreateDisplayModeKHR(phys_dev_term->phys_dev, display, pCreateInfo, pAllocator, pMode); 1237 } 1238 1239 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, 1240 VkDisplayModeKHR mode, uint32_t planeIndex, 1241 VkDisplayPlaneCapabilitiesKHR *pCapabilities) { 1242 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); 1243 const VkLayerInstanceDispatchTable *disp; 1244 disp = loader_get_instance_layer_dispatch(physicalDevice); 1245 VkResult res = disp->GetDisplayPlaneCapabilitiesKHR(unwrapped_phys_dev, mode, planeIndex, pCapabilities); 1246 return res; 1247 } 1248 1249 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, 1250 uint32_t planeIndex, 1251 VkDisplayPlaneCapabilitiesKHR *pCapabilities) { 1252 // First, check to ensure the appropriate extension was enabled: 1253 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice; 1254 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; 1255 struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance; 1256 if (!ptr_instance->wsi_display_enabled) { 1257 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1258 "VK_KHR_display extension not enabled. vkGetDisplayPlaneCapabilitiesKHR not executed!\n"); 1259 return VK_SUCCESS; 1260 } 1261 1262 if (NULL == icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR) { 1263 loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1264 "ICD for selected physical device is not exporting vkGetDisplayPlaneCapabilitiesKHR!\n"); 1265 assert(false && "loader: null GetDisplayPlaneCapabilitiesKHR ICD pointer"); 1266 } 1267 1268 return icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR(phys_dev_term->phys_dev, mode, planeIndex, pCapabilities); 1269 } 1270 1271 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR(VkInstance instance, 1272 const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, 1273 const VkAllocationCallbacks *pAllocator, 1274 VkSurfaceKHR *pSurface) { 1275 const VkLayerInstanceDispatchTable *disp; 1276 disp = loader_get_instance_layer_dispatch(instance); 1277 VkResult res; 1278 1279 res = disp->CreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); 1280 return res; 1281 } 1282 1283 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstance instance, 1284 const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, 1285 const VkAllocationCallbacks *pAllocator, 1286 VkSurfaceKHR *pSurface) { 1287 struct loader_instance *inst = loader_get_instance(instance); 1288 VkIcdSurface *pIcdSurface = NULL; 1289 VkResult vkRes = VK_SUCCESS; 1290 uint32_t i = 0; 1291 1292 if (!inst->wsi_display_enabled) { 1293 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, 1294 "VK_KHR_surface extension not enabled. vkCreateDisplayPlaneSurfaceKHR not executed!\n"); 1295 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT; 1296 goto out; 1297 } 1298 1299 // Next, if so, proceed with the implementation of this function: 1300 pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base), sizeof(pIcdSurface->display_surf)); 1301 if (pIcdSurface == NULL) { 1302 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; 1303 goto out; 1304 } 1305 1306 pIcdSurface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY; 1307 pIcdSurface->display_surf.displayMode = pCreateInfo->displayMode; 1308 pIcdSurface->display_surf.planeIndex = pCreateInfo->planeIndex; 1309 pIcdSurface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex; 1310 pIcdSurface->display_surf.transform = pCreateInfo->transform; 1311 pIcdSurface->display_surf.globalAlpha = pCreateInfo->globalAlpha; 1312 pIcdSurface->display_surf.alphaMode = pCreateInfo->alphaMode; 1313 pIcdSurface->display_surf.imageExtent = pCreateInfo->imageExtent; 1314 1315 // Loop through each ICD and determine if they need to create a surface 1316 for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 1317 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) { 1318 if (NULL != icd_term->dispatch.CreateDisplayPlaneSurfaceKHR) { 1319 vkRes = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator, 1320 &pIcdSurface->real_icd_surfaces[i]); 1321 if (VK_SUCCESS != vkRes) { 1322 goto out; 1323 } 1324 } 1325 } 1326 } 1327 1328 *pSurface = (VkSurfaceKHR)pIcdSurface; 1329 1330 out: 1331 1332 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) { 1333 if (NULL != pIcdSurface->real_icd_surfaces) { 1334 i = 0; 1335 for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) { 1336 if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) { 1337 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator); 1338 } 1339 } 1340 loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces); 1341 } 1342 loader_instance_heap_free(inst, pIcdSurface); 1343 } 1344 1345 return vkRes; 1346 } 1347 1348 // EXT_display_swapchain Extension command 1349 1350 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount, 1351 const VkSwapchainCreateInfoKHR *pCreateInfos, 1352 const VkAllocationCallbacks *pAllocator, 1353 VkSwapchainKHR *pSwapchains) { 1354 const VkLayerDispatchTable *disp; 1355 disp = loader_get_dispatch(device); 1356 return disp->CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains); 1357 } 1358 1359 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount, 1360 const VkSwapchainCreateInfoKHR *pCreateInfos, 1361 const VkAllocationCallbacks *pAllocator, 1362 VkSwapchainKHR *pSwapchains) { 1363 uint32_t icd_index = 0; 1364 struct loader_device *dev; 1365 struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index); 1366 if (NULL != icd_term && NULL != icd_term->dispatch.CreateSharedSwapchainsKHR) { 1367 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfos->surface; 1368 if (NULL != icd_surface->real_icd_surfaces) { 1369 if ((VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) { 1370 // We found the ICD, and there is an ICD KHR surface 1371 // associated with it, so copy the CreateInfo struct 1372 // and point it at the ICD's surface. 1373 VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR) * swapchainCount); 1374 if (NULL == pCreateCopy) { 1375 return VK_ERROR_OUT_OF_HOST_MEMORY; 1376 } 1377 memcpy(pCreateCopy, pCreateInfos, sizeof(VkSwapchainCreateInfoKHR) * swapchainCount); 1378 for (uint32_t sc = 0; sc < swapchainCount; sc++) { 1379 pCreateCopy[sc].surface = icd_surface->real_icd_surfaces[icd_index]; 1380 } 1381 return icd_term->dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateCopy, pAllocator, pSwapchains); 1382 } 1383 } 1384 return icd_term->dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains); 1385 } 1386 return VK_SUCCESS; 1387 } 1388 1389 bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr) { 1390 *addr = NULL; 1391 1392 // Functions for the VK_KHR_surface extension: 1393 if (!strcmp("vkDestroySurfaceKHR", name)) { 1394 *addr = ptr_instance->wsi_surface_enabled ? (void *)vkDestroySurfaceKHR : NULL; 1395 return true; 1396 } 1397 if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name)) { 1398 *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceSupportKHR : NULL; 1399 return true; 1400 } 1401 if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name)) { 1402 *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilitiesKHR : NULL; 1403 return true; 1404 } 1405 if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name)) { 1406 *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormatsKHR : NULL; 1407 return true; 1408 } 1409 if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name)) { 1410 *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfacePresentModesKHR : NULL; 1411 return true; 1412 } 1413 1414 // Functions for the VK_KHR_swapchain extension: 1415 1416 // Note: This is a device extension, and its functions are statically 1417 // exported from the loader. Per Khronos decisions, the loader's GIPA 1418 // function will return the trampoline function for such device-extension 1419 // functions, regardless of whether the extension has been enabled. 1420 if (!strcmp("vkCreateSwapchainKHR", name)) { 1421 *addr = (void *)vkCreateSwapchainKHR; 1422 return true; 1423 } 1424 if (!strcmp("vkDestroySwapchainKHR", name)) { 1425 *addr = (void *)vkDestroySwapchainKHR; 1426 return true; 1427 } 1428 if (!strcmp("vkGetSwapchainImagesKHR", name)) { 1429 *addr = (void *)vkGetSwapchainImagesKHR; 1430 return true; 1431 } 1432 if (!strcmp("vkAcquireNextImageKHR", name)) { 1433 *addr = (void *)vkAcquireNextImageKHR; 1434 return true; 1435 } 1436 if (!strcmp("vkQueuePresentKHR", name)) { 1437 *addr = (void *)vkQueuePresentKHR; 1438 return true; 1439 } 1440 1441 #ifdef VK_USE_PLATFORM_WIN32_KHR 1442 1443 // Functions for the VK_KHR_win32_surface extension: 1444 if (!strcmp("vkCreateWin32SurfaceKHR", name)) { 1445 *addr = ptr_instance->wsi_win32_surface_enabled ? (void *)vkCreateWin32SurfaceKHR : NULL; 1446 return true; 1447 } 1448 if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", name)) { 1449 *addr = ptr_instance->wsi_win32_surface_enabled ? (void *)vkGetPhysicalDeviceWin32PresentationSupportKHR : NULL; 1450 return true; 1451 } 1452 #endif // VK_USE_PLATFORM_WIN32_KHR 1453 #ifdef VK_USE_PLATFORM_MIR_KHR 1454 1455 // Functions for the VK_KHR_mir_surface extension: 1456 if (!strcmp("vkCreateMirSurfaceKHR", name)) { 1457 *addr = ptr_instance->wsi_mir_surface_enabled ? (void *)vkCreateMirSurfaceKHR : NULL; 1458 return true; 1459 } 1460 if (!strcmp("vkGetPhysicalDeviceMirPresentationSupportKHR", name)) { 1461 *addr = ptr_instance->wsi_mir_surface_enabled ? (void *)vkGetPhysicalDeviceMirPresentationSupportKHR : NULL; 1462 return true; 1463 } 1464 #endif // VK_USE_PLATFORM_MIR_KHR 1465 #ifdef VK_USE_PLATFORM_WAYLAND_KHR 1466 1467 // Functions for the VK_KHR_wayland_surface extension: 1468 if (!strcmp("vkCreateWaylandSurfaceKHR", name)) { 1469 *addr = ptr_instance->wsi_wayland_surface_enabled ? (void *)vkCreateWaylandSurfaceKHR : NULL; 1470 return true; 1471 } 1472 if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", name)) { 1473 *addr = ptr_instance->wsi_wayland_surface_enabled ? (void *)vkGetPhysicalDeviceWaylandPresentationSupportKHR : NULL; 1474 return true; 1475 } 1476 #endif // VK_USE_PLATFORM_WAYLAND_KHR 1477 #ifdef VK_USE_PLATFORM_XCB_KHR 1478 1479 // Functions for the VK_KHR_xcb_surface extension: 1480 if (!strcmp("vkCreateXcbSurfaceKHR", name)) { 1481 *addr = ptr_instance->wsi_xcb_surface_enabled ? (void *)vkCreateXcbSurfaceKHR : NULL; 1482 return true; 1483 } 1484 if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", name)) { 1485 *addr = ptr_instance->wsi_xcb_surface_enabled ? (void *)vkGetPhysicalDeviceXcbPresentationSupportKHR : NULL; 1486 return true; 1487 } 1488 #endif // VK_USE_PLATFORM_XCB_KHR 1489 #ifdef VK_USE_PLATFORM_XLIB_KHR 1490 1491 // Functions for the VK_KHR_xlib_surface extension: 1492 if (!strcmp("vkCreateXlibSurfaceKHR", name)) { 1493 *addr = ptr_instance->wsi_xlib_surface_enabled ? (void *)vkCreateXlibSurfaceKHR : NULL; 1494 return true; 1495 } 1496 if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", name)) { 1497 *addr = ptr_instance->wsi_xlib_surface_enabled ? (void *)vkGetPhysicalDeviceXlibPresentationSupportKHR : NULL; 1498 return true; 1499 } 1500 #endif // VK_USE_PLATFORM_XLIB_KHR 1501 #ifdef VK_USE_PLATFORM_ANDROID_KHR 1502 1503 // Functions for the VK_KHR_android_surface extension: 1504 if (!strcmp("vkCreateAndroidSurfaceKHR", name)) { 1505 *addr = ptr_instance->wsi_xlib_surface_enabled ? (void *)vkCreateAndroidSurfaceKHR : NULL; 1506 return true; 1507 } 1508 #endif // VK_USE_PLATFORM_ANDROID_KHR 1509 1510 // Functions for VK_KHR_display extension: 1511 if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) { 1512 *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL; 1513 return true; 1514 } 1515 if (!strcmp("vkGetPhysicalDeviceDisplayPlanePropertiesKHR", name)) { 1516 *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPlanePropertiesKHR : NULL; 1517 return true; 1518 } 1519 if (!strcmp("vkGetDisplayPlaneSupportedDisplaysKHR", name)) { 1520 *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetDisplayPlaneSupportedDisplaysKHR : NULL; 1521 return true; 1522 } 1523 if (!strcmp("vkGetDisplayModePropertiesKHR", name)) { 1524 *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetDisplayModePropertiesKHR : NULL; 1525 return true; 1526 } 1527 if (!strcmp("vkCreateDisplayModeKHR", name)) { 1528 *addr = ptr_instance->wsi_display_enabled ? (void *)vkCreateDisplayModeKHR : NULL; 1529 return true; 1530 } 1531 if (!strcmp("vkGetDisplayPlaneCapabilitiesKHR", name)) { 1532 *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetDisplayPlaneCapabilitiesKHR : NULL; 1533 return true; 1534 } 1535 if (!strcmp("vkCreateDisplayPlaneSurfaceKHR", name)) { 1536 *addr = ptr_instance->wsi_display_enabled ? (void *)vkCreateDisplayPlaneSurfaceKHR : NULL; 1537 return true; 1538 } 1539 1540 // Functions for KHR_display_swapchain extension: 1541 if (!strcmp("vkCreateSharedSwapchainsKHR", name)) { 1542 *addr = (void *)vkCreateSharedSwapchainsKHR; 1543 return true; 1544 } 1545 1546 return false; 1547 } 1548