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: Ian Elliott <ian@lunarg.com>
19 * Author: Jon Ashburn <jon@lunarg.com>
20 * Author: Ian Elliott <ianelliott@google.com>
21 * Author: Mark Lobodzinski <mark@lunarg.com>
22 * Author: Lenny Komow <lenny@lunarg.com>
23 * Author: Charles Giessen <charles@lunarg.com>
24 */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28
29 #include <vulkan/vk_icd.h>
30
31 #include "allocation.h"
32 #include "loader.h"
33 #include "log.h"
34 #include "vk_loader_platform.h"
35 #include "wsi.h"
36
37 // The first ICD/Loader interface that support querying the SurfaceKHR from
38 // the ICDs.
39 #define ICD_VER_SUPPORTS_ICD_SURFACE_KHR 3
40
wsi_create_instance(struct loader_instance *loader_inst, const VkInstanceCreateInfo *pCreateInfo)41 void wsi_create_instance(struct loader_instance *loader_inst, const VkInstanceCreateInfo *pCreateInfo) {
42 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
43 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
44 loader_inst->wsi_surface_enabled = true;
45 continue;
46 }
47 #if defined(VK_USE_PLATFORM_WIN32_KHR)
48 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
49 loader_inst->wsi_win32_surface_enabled = true;
50 continue;
51 }
52 #endif // VK_USE_PLATFORM_WIN32_KHR
53 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
54 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
55 loader_inst->wsi_wayland_surface_enabled = true;
56 continue;
57 }
58 #endif // VK_USE_PLATFORM_WAYLAND_KHR
59 #if defined(VK_USE_PLATFORM_XCB_KHR)
60 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
61 loader_inst->wsi_xcb_surface_enabled = true;
62 continue;
63 }
64 #endif // VK_USE_PLATFORM_XCB_KHR
65 #if defined(VK_USE_PLATFORM_XLIB_KHR)
66 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
67 loader_inst->wsi_xlib_surface_enabled = true;
68 continue;
69 }
70 #endif // VK_USE_PLATFORM_XLIB_KHR
71 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
72 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME) == 0) {
73 loader_inst->wsi_directfb_surface_enabled = true;
74 continue;
75 }
76 #endif // VK_USE_PLATFORM_DIRECTFB_EXT
77 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
78 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
79 loader_inst->wsi_android_surface_enabled = true;
80 continue;
81 }
82 #endif // VK_USE_PLATFORM_ANDROID_KHR
83 #if defined(VK_USE_PLATFORM_OHOS)
84 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_OHOS_SURFACE_EXTENSION_NAME) == 0) {
85 loader_inst->wsi_ohos_surface_enabled = true;
86 continue;
87 }
88 #endif // VK_USE_PLATFORM_OHOS
89 #if defined(VK_USE_PLATFORM_MACOS_MVK)
90 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_MVK_MACOS_SURFACE_EXTENSION_NAME) == 0) {
91 loader_inst->wsi_macos_surface_enabled = true;
92 continue;
93 }
94 #endif // VK_USE_PLATFORM_MACOS_MVK
95 #if defined(VK_USE_PLATFORM_IOS_MVK)
96 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_MVK_IOS_SURFACE_EXTENSION_NAME) == 0) {
97 loader_inst->wsi_ios_surface_enabled = true;
98 continue;
99 }
100 #endif // VK_USE_PLATFORM_IOS_MVK
101 #if defined(VK_USE_PLATFORM_GGP)
102 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME) == 0) {
103 loader_inst->wsi_ggp_surface_enabled = true;
104 continue;
105 }
106 #endif // VK_USE_PLATFORM_GGP
107 #if defined(VK_USE_PLATFORM_FUCHSIA)
108 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME) == 0) {
109 loader_inst->wsi_imagepipe_surface_enabled = true;
110 continue;
111 }
112 #endif // VK_USE_PLATFORM_FUCHSIA
113 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME) == 0) {
114 loader_inst->wsi_headless_surface_enabled = true;
115 continue;
116 }
117 #if defined(VK_USE_PLATFORM_METAL_EXT)
118 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME) == 0) {
119 loader_inst->wsi_metal_surface_enabled = true;
120 continue;
121 }
122 #endif
123 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
124 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_QNX_SCREEN_SURFACE_EXTENSION_NAME) == 0) {
125 loader_inst->wsi_screen_surface_enabled = true;
126 continue;
127 }
128 #endif // VK_USE_PLATFORM_SCREEN_QNX
129 #if defined(VK_USE_PLATFORM_VI_NN)
130 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NN_VI_SURFACE_EXTENSION_NAME) == 0) {
131 loader_inst->wsi_vi_surface_enabled = true;
132 continue;
133 }
134 #endif // VK_USE_PLATFORM_VI_NN
135 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
136 loader_inst->wsi_display_enabled = true;
137 continue;
138 }
139 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME) == 0) {
140 loader_inst->wsi_display_props2_enabled = true;
141 continue;
142 }
143 }
144 }
145
146 // Linux WSI surface extensions are not always compiled into the loader. (Assume
147 // for Windows the KHR_win32_surface is always compiled into loader). A given
148 // Linux build environment might not have the headers required for building one
149 // of the three extensions (Xlib, Xcb, Wayland). Thus, need to check if
150 // the built loader actually supports the particular Linux surface extension.
151 // If not supported by the built loader it will not be included in the list of
152 // enumerated instance extensions. This solves the issue where an ICD or layer
153 // advertises support for a given Linux surface extension but the loader was not
154 // built to support the extension.
wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop)155 bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop) {
156 #if !defined(VK_USE_PLATFORM_WAYLAND_KHR)
157 if (!strcmp(ext_prop->extensionName, "VK_KHR_wayland_surface")) return true;
158 #endif // VK_USE_PLATFORM_WAYLAND_KHR
159 #if !defined(VK_USE_PLATFORM_XCB_KHR)
160 if (!strcmp(ext_prop->extensionName, "VK_KHR_xcb_surface")) return true;
161 #endif // VK_USE_PLATFORM_XCB_KHR
162 #if !defined(VK_USE_PLATFORM_XLIB_KHR)
163 if (!strcmp(ext_prop->extensionName, "VK_KHR_xlib_surface")) return true;
164 #endif // VK_USE_PLATFORM_XLIB_KHR
165 #if !defined(VK_USE_PLATFORM_DIRECTFB_EXT)
166 if (!strcmp(ext_prop->extensionName, "VK_EXT_directfb_surface")) return true;
167 #endif // VK_USE_PLATFORM_DIRECTFB_EXT
168 #if !defined(VK_USE_PLATFORM_SCREEN_QNX)
169 if (!strcmp(ext_prop->extensionName, "VK_QNX_screen_surface")) return true;
170 #endif // VK_USE_PLATFORM_SCREEN_QNX
171
172 return false;
173 }
174
175 // Functions for the VK_KHR_surface extension:
176
177 // This is the trampoline entrypoint for DestroySurfaceKHR
vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator)178 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
179 const VkAllocationCallbacks *pAllocator) {
180 struct loader_instance *loader_inst = loader_get_instance(instance);
181 if (NULL == loader_inst) {
182 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
183 "vkDestroySurfaceKHR: Invalid instance [VUID-vkDestroySurfaceKHR-instance-parameter]");
184 abort(); /* Intentionally fail so user can correct issue. */
185 }
186 loader_inst->disp->layer_inst_disp.DestroySurfaceKHR(loader_inst->instance, surface, pAllocator);
187 }
188
189 // TODO probably need to lock around all the loader_get_instance() calls.
190
191 // This is the instance chain terminator function for DestroySurfaceKHR
terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator)192 VKAPI_ATTR void VKAPI_CALL terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
193 const VkAllocationCallbacks *pAllocator) {
194 struct loader_instance *loader_inst = loader_get_instance(instance);
195
196 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface);
197 if (NULL != icd_surface) {
198 if (NULL != icd_surface->real_icd_surfaces) {
199 uint32_t i = 0;
200 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
201 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
202 if (NULL != icd_term->dispatch.DestroySurfaceKHR &&
203 (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[i]) {
204 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator);
205 icd_surface->real_icd_surfaces[i] = (VkSurfaceKHR)(uintptr_t)NULL;
206 }
207 } else {
208 // The real_icd_surface for any ICD not supporting the
209 // proper interface version should be NULL. If not, then
210 // we have a problem.
211 assert((VkSurfaceKHR)(uintptr_t)NULL == icd_surface->real_icd_surfaces[i]);
212 }
213 }
214 loader_instance_heap_free(loader_inst, icd_surface->real_icd_surfaces);
215 }
216
217 loader_instance_heap_free(loader_inst, (void *)(uintptr_t)surface);
218 }
219 }
220
221 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceSupportKHR
vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 *pSupported)222 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
223 uint32_t queueFamilyIndex, VkSurfaceKHR surface,
224 VkBool32 *pSupported) {
225 const VkLayerInstanceDispatchTable *disp;
226 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
227 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
228 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
229 "vkGetPhysicalDeviceSurfaceSupportKHR: Invalid physicalDevice "
230 "[VUID-vkGetPhysicalDeviceSurfaceSupportKHR-physicalDevice-parameter]");
231 abort(); /* Intentionally fail so user can correct issue. */
232 }
233 disp = loader_get_instance_layer_dispatch(physicalDevice);
234 return disp->GetPhysicalDeviceSurfaceSupportKHR(unwrapped_phys_dev, queueFamilyIndex, surface, pSupported);
235 }
236
237 // This is the instance chain terminator function for
238 // GetPhysicalDeviceSurfaceSupportKHR
terminator_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 *pSupported)239 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
240 uint32_t queueFamilyIndex, VkSurfaceKHR surface,
241 VkBool32 *pSupported) {
242 // First, check to ensure the appropriate extension was enabled:
243 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
244 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
245 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
246 if (!loader_inst->wsi_surface_enabled) {
247 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
248 "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not executed!");
249 return VK_SUCCESS;
250 }
251
252 if (NULL == pSupported) {
253 loader_log(loader_inst, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
254 "NULL pointer passed into vkGetPhysicalDeviceSurfaceSupportKHR for pSupported!");
255 abort();
256 }
257 *pSupported = false;
258
259 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR) {
260 // set pSupported to false as this driver doesn't support WSI functionality
261 *pSupported = false;
262 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
263 "ICD for selected physical device does not export vkGetPhysicalDeviceSurfaceSupportKHR!");
264 return VK_SUCCESS;
265 }
266
267 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
268 if (NULL != icd_surface->real_icd_surfaces &&
269 (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
270 return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(
271 phys_dev_term->phys_dev, queueFamilyIndex, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSupported);
272 }
273
274 return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, surface, pSupported);
275 }
276
277 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceCapabilitiesKHR
vkGetPhysicalDeviceSurfaceCapabilitiesKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)278 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
279 VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
280 const VkLayerInstanceDispatchTable *disp;
281 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
282 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
283 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
284 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR: Invalid physicalDevice "
285 "[VUID-vkGetPhysicalDeviceSurfaceCapabilitiesKHR-physicalDevice-parameter]");
286 abort(); /* Intentionally fail so user can correct issue. */
287 }
288 disp = loader_get_instance_layer_dispatch(physicalDevice);
289 return disp->GetPhysicalDeviceSurfaceCapabilitiesKHR(unwrapped_phys_dev, surface, pSurfaceCapabilities);
290 }
291
292 // This is the instance chain terminator function for
293 // GetPhysicalDeviceSurfaceCapabilitiesKHR
terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)294 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,
295 VkSurfaceKHR surface,
296 VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
297 // First, check to ensure the appropriate extension was enabled:
298 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
299 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
300 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
301 if (!loader_inst->wsi_surface_enabled) {
302 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
303 "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceCapabilitiesKHR not executed!");
304 return VK_SUCCESS;
305 }
306
307 if (NULL == pSurfaceCapabilities) {
308 loader_log(loader_inst, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
309 "NULL pointer passed into vkGetPhysicalDeviceSurfaceCapabilitiesKHR for pSurfaceCapabilities!");
310 abort();
311 }
312
313 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR) {
314 // Zero out the capabilities as this driver doesn't support WSI functionality
315 memset(pSurfaceCapabilities, 0, sizeof(VkSurfaceCapabilitiesKHR));
316 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
317 "ICD for selected physical device does not export vkGetPhysicalDeviceSurfaceCapabilitiesKHR!");
318 return VK_SUCCESS;
319 }
320
321 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
322 if (NULL != icd_surface->real_icd_surfaces &&
323 (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
324 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(
325 phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSurfaceCapabilities);
326 }
327
328 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface, pSurfaceCapabilities);
329 }
330
331 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceFormatsKHR
vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats)332 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,
333 VkSurfaceKHR surface,
334 uint32_t *pSurfaceFormatCount,
335 VkSurfaceFormatKHR *pSurfaceFormats) {
336 const VkLayerInstanceDispatchTable *disp;
337 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
338 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
339 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
340 "vkGetPhysicalDeviceSurfaceFormatsKHR: Invalid physicalDevice "
341 "[VUID-vkGetPhysicalDeviceSurfaceFormatsKHR-physicalDevice-parameter]");
342 abort(); /* Intentionally fail so user can correct issue. */
343 }
344 disp = loader_get_instance_layer_dispatch(physicalDevice);
345 return disp->GetPhysicalDeviceSurfaceFormatsKHR(unwrapped_phys_dev, surface, pSurfaceFormatCount, pSurfaceFormats);
346 }
347
348 // This is the instance chain terminator function for
349 // GetPhysicalDeviceSurfaceFormatsKHR
terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats)350 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
351 uint32_t *pSurfaceFormatCount,
352 VkSurfaceFormatKHR *pSurfaceFormats) {
353 // First, check to ensure the appropriate extension was enabled:
354 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
355 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
356 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
357 if (!loader_inst->wsi_surface_enabled) {
358 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
359 "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not executed!");
360 return VK_SUCCESS;
361 }
362
363 if (NULL == pSurfaceFormatCount) {
364 loader_log(loader_inst, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
365 "NULL pointer passed into vkGetPhysicalDeviceSurfaceFormatsKHR for pSurfaceFormatCount!");
366 abort();
367 }
368
369 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR) {
370 // Zero out the format count as this driver doesn't support WSI functionality
371 *pSurfaceFormatCount = 0;
372 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
373 "ICD for selected physical device does not export vkGetPhysicalDeviceSurfaceCapabilitiesKHR!");
374 return VK_SUCCESS;
375 }
376
377 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
378 if (NULL != icd_surface->real_icd_surfaces &&
379 (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
380 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev,
381 icd_surface->real_icd_surfaces[phys_dev_term->icd_index],
382 pSurfaceFormatCount, pSurfaceFormats);
383 }
384
385 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
386 pSurfaceFormats);
387 }
388
389 // This is the trampoline entrypoint for GetPhysicalDeviceSurfacePresentModesKHR
vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes)390 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
391 VkSurfaceKHR surface,
392 uint32_t *pPresentModeCount,
393 VkPresentModeKHR *pPresentModes) {
394 const VkLayerInstanceDispatchTable *disp;
395 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
396 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
397 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
398 "vkGetPhysicalDeviceSurfacePresentModesKHR: Invalid physicalDevice "
399 "[VUID-vkGetPhysicalDeviceSurfacePresentModesKHR-physicalDevice-parameter]");
400 abort(); /* Intentionally fail so user can correct issue. */
401 }
402 disp = loader_get_instance_layer_dispatch(physicalDevice);
403 return disp->GetPhysicalDeviceSurfacePresentModesKHR(unwrapped_phys_dev, surface, pPresentModeCount, pPresentModes);
404 }
405
406 // This is the instance chain terminator function for
407 // GetPhysicalDeviceSurfacePresentModesKHR
terminator_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes)408 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
409 VkSurfaceKHR surface, uint32_t *pPresentModeCount,
410 VkPresentModeKHR *pPresentModes) {
411 // First, check to ensure the appropriate extension was enabled:
412 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
413 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
414 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
415 if (!loader_inst->wsi_surface_enabled) {
416 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
417 "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR not executed!");
418 return VK_SUCCESS;
419 }
420
421 if (NULL == pPresentModeCount) {
422 loader_log(loader_inst, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT, 0,
423 "NULL pointer passed into vkGetPhysicalDeviceSurfacePresentModesKHR for pPresentModeCount!");
424 abort();
425 }
426
427 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR) {
428 // Zero out the present mode count as this driver doesn't support WSI functionality
429 *pPresentModeCount = 0;
430 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
431 "ICD for selected physical device does not export vkGetPhysicalDeviceSurfacePresentModesKHR!");
432 return VK_SUCCESS;
433 }
434
435 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
436 if (NULL != icd_surface->real_icd_surfaces &&
437 (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
438 return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(
439 phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pPresentModeCount, pPresentModes);
440 }
441
442 return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(phys_dev_term->phys_dev, surface, pPresentModeCount,
443 pPresentModes);
444 }
445
446 // Functions for the VK_KHR_swapchain extension:
447
448 // This is the trampoline entrypoint for CreateSwapchainKHR
vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain)449 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
450 const VkAllocationCallbacks *pAllocator,
451 VkSwapchainKHR *pSwapchain) {
452 const VkLayerDispatchTable *disp = loader_get_dispatch(device);
453 if (NULL == disp) {
454 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
455 "vkCreateSwapchainKHR: Invalid device [VUID-vkCreateSwapchainKHR-device-parameter]");
456 abort(); /* Intentionally fail so user can correct issue. */
457 }
458 if (NULL == disp->CreateSwapchainKHR) {
459 struct loader_device *dev = *((struct loader_device **)device);
460 loader_log(NULL != dev ? dev->phys_dev_term->this_icd_term->this_instance : NULL,
461 VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
462 "vkCreateSwapchainKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the VK_KHR_swapchain "
463 "extension enabled?");
464 abort();
465 }
466 return disp->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
467 }
468
terminator_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain)469 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
470 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
471 uint32_t icd_index = 0;
472 struct loader_device *dev;
473 struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
474 if (NULL == icd_term || NULL == dev) {
475 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
476 "vkCreateSwapchainKHR Terminator: device handle. This is likely the result of a "
477 "layer wrapping device handles and failing to unwrap them in all functions. "
478 "[VUID-vkCreateSwapchainKHR-device-parameter]");
479 abort(); /* Intentionally fail so user can correct issue. */
480 }
481 if (NULL == pCreateInfo) {
482 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
483 "vkCreateSwapchainKHR: Invalid pCreateInfo pointer [VUID-vkCreateSwapchainKHR-pCreateInfo-parameter]");
484 abort(); /* Intentionally fail so user can correct issue. */
485 }
486 // Need to gracefully handle the function pointer not being found.
487 if (NULL == dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR) {
488 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
489 "vkCreateSwapchainKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the VK_KHR_swapchain "
490 "extension enabled?");
491 return VK_SUCCESS;
492 }
493 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfo->surface;
494 if (NULL != icd_surface->real_icd_surfaces) {
495 if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) {
496 // We found the ICD, and there is an ICD KHR surface
497 // associated with it, so copy the CreateInfo struct
498 // and point it at the ICD's surface.
499 VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR));
500 if (NULL == pCreateCopy) {
501 return VK_ERROR_OUT_OF_HOST_MEMORY;
502 }
503 memcpy(pCreateCopy, pCreateInfo, sizeof(VkSwapchainCreateInfoKHR));
504 pCreateCopy->surface = icd_surface->real_icd_surfaces[icd_index];
505 return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, pCreateCopy, pAllocator,
506 pSwapchain);
507 }
508 }
509 return dev->loader_dispatch.extension_terminator_dispatch.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
510 }
511
512 // This is the trampoline entrypoint for DestroySwapchainKHR
vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator)513 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
514 const VkAllocationCallbacks *pAllocator) {
515 const VkLayerDispatchTable *disp = loader_get_dispatch(device);
516 if (NULL == disp) {
517 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
518 "vkDestroySwapchainKHR: Invalid device [VUID-vkDestroySwapchainKHR-device-parameter]");
519 abort(); /* Intentionally fail so user can correct issue. */
520 }
521 disp->DestroySwapchainKHR(device, swapchain, pAllocator);
522 }
523
524 // This is the trampoline entrypoint for GetSwapchainImagesKHR
vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages)525 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
526 uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
527 const VkLayerDispatchTable *disp = loader_get_dispatch(device);
528 if (NULL == disp) {
529 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
530 "vkGetSwapchainImagesKHR: Invalid device [VUID-vkGetSwapchainImagesKHR-device-parameter]");
531 abort(); /* Intentionally fail so user can correct issue. */
532 }
533 return disp->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
534 }
535
536 // This is the trampoline entrypoint for AcquireNextImageKHR
vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex)537 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
538 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
539 const VkLayerDispatchTable *disp = loader_get_dispatch(device);
540 if (NULL == disp) {
541 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
542 "vkAcquireNextImageKHR: Invalid device [VUID-vkAcquireNextImageKHR-device-parameter]");
543 abort(); /* Intentionally fail so user can correct issue. */
544 }
545 return disp->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
546 }
547
548 // This is the trampoline entrypoint for QueuePresentKHR
vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo)549 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
550 const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
551 if (NULL == disp) {
552 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
553 "vkQueuePresentKHR: Invalid queue [VUID-vkQueuePresentKHR-queue-parameter]");
554 abort(); /* Intentionally fail so user can correct issue. */
555 }
556 return disp->QueuePresentKHR(queue, pPresentInfo);
557 }
558
AllocateIcdSurfaceStruct(struct loader_instance *instance, size_t base_size, size_t platform_size)559 VkIcdSurface *AllocateIcdSurfaceStruct(struct loader_instance *instance, size_t base_size, size_t platform_size) {
560 // Next, if so, proceed with the implementation of this function:
561 VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
562 if (pIcdSurface != NULL) {
563 // Setup the new sizes and offsets so we can grow the structures in the
564 // future without having problems
565 pIcdSurface->base_size = (uint32_t)base_size;
566 pIcdSurface->platform_size = (uint32_t)platform_size;
567 pIcdSurface->non_platform_offset = (uint32_t)((uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
568 pIcdSurface->entire_size = sizeof(VkIcdSurface);
569
570 pIcdSurface->real_icd_surfaces = loader_instance_heap_calloc(instance, sizeof(VkSurfaceKHR) * instance->total_icd_count,
571 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
572 if (pIcdSurface->real_icd_surfaces == NULL) {
573 loader_instance_heap_free(instance, pIcdSurface);
574 pIcdSurface = NULL;
575 }
576 }
577 return pIcdSurface;
578 }
579
580 #if defined(VK_USE_PLATFORM_WIN32_KHR)
581
582 // Functions for the VK_KHR_win32_surface extension:
583
584 // This is the trampoline entrypoint for CreateWin32SurfaceKHR
vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)585 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance instance,
586 const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
587 const VkAllocationCallbacks *pAllocator,
588 VkSurfaceKHR *pSurface) {
589 struct loader_instance *loader_inst = loader_get_instance(instance);
590 if (NULL == loader_inst) {
591 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
592 "vkCreateWin32SurfaceKHR: Invalid instance [VUID-vkCreateWin32SurfaceKHR-instance-parameter]");
593 abort(); /* Intentionally fail so user can correct issue. */
594 }
595 return loader_inst->disp->layer_inst_disp.CreateWin32SurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
596 }
597
598 // This is the instance chain terminator function for CreateWin32SurfaceKHR
terminator_CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)599 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
600 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
601 VkResult vkRes = VK_SUCCESS;
602 VkIcdSurface *pIcdSurface = NULL;
603 uint32_t i = 0;
604
605 // Initialize pSurface to NULL just to be safe.
606 *pSurface = VK_NULL_HANDLE;
607 // First, check to ensure the appropriate extension was enabled:
608 struct loader_instance *loader_inst = loader_get_instance(instance);
609 if (!loader_inst->wsi_win32_surface_enabled) {
610 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
611 "VK_KHR_win32_surface extension not enabled. vkCreateWin32SurfaceKHR not executed!");
612 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
613 goto out;
614 }
615
616 // Next, if so, proceed with the implementation of this function:
617 pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->win_surf.base), sizeof(pIcdSurface->win_surf));
618 if (pIcdSurface == NULL) {
619 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
620 goto out;
621 }
622
623 pIcdSurface->win_surf.base.platform = VK_ICD_WSI_PLATFORM_WIN32;
624 pIcdSurface->win_surf.hinstance = pCreateInfo->hinstance;
625 pIcdSurface->win_surf.hwnd = pCreateInfo->hwnd;
626
627 // Loop through each ICD and determine if they need to create a surface
628 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
629 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
630 if (NULL != icd_term->dispatch.CreateWin32SurfaceKHR) {
631 vkRes = icd_term->dispatch.CreateWin32SurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
632 &pIcdSurface->real_icd_surfaces[i]);
633 if (VK_SUCCESS != vkRes) {
634 goto out;
635 }
636 }
637 }
638 }
639
640 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
641
642 out:
643
644 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
645 if (NULL != pIcdSurface->real_icd_surfaces) {
646 i = 0;
647 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
648 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
649 NULL != icd_term->dispatch.DestroySurfaceKHR) {
650 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
651 }
652 }
653 loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
654 }
655 loader_instance_heap_free(loader_inst, pIcdSurface);
656 }
657
658 return vkRes;
659 }
660
661 // This is the trampoline entrypoint for
662 // GetPhysicalDeviceWin32PresentationSupportKHR
vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex)663 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
664 uint32_t queueFamilyIndex) {
665 const VkLayerInstanceDispatchTable *disp;
666 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
667 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
668 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
669 "vkGetPhysicalDeviceWin32PresentationSupportKHR: Invalid physicalDevice "
670 "[VUID-vkGetPhysicalDeviceWin32PresentationSupportKHR-physicalDevice-parameter]");
671 abort(); /* Intentionally fail so user can correct issue. */
672 }
673 disp = loader_get_instance_layer_dispatch(physicalDevice);
674 return disp->GetPhysicalDeviceWin32PresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex);
675 }
676
677 // This is the instance chain terminator function for
678 // GetPhysicalDeviceWin32PresentationSupportKHR
terminator_GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex)679 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
680 uint32_t queueFamilyIndex) {
681 // First, check to ensure the appropriate extension was enabled:
682 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
683 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
684 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
685 if (!loader_inst->wsi_win32_surface_enabled) {
686 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
687 "VK_KHR_win32_surface extension not enabled. vkGetPhysicalDeviceWin32PresentationSupportKHR not executed!");
688 return VK_FALSE;
689 }
690
691 if (NULL == icd_term->dispatch.GetPhysicalDeviceWin32PresentationSupportKHR) {
692 // return VK_FALSE as this driver doesn't support WSI functionality
693 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
694 "ICD for selected physical device does not export vkGetPhysicalDeviceWin32PresentationSupportKHR!");
695 return VK_FALSE;
696 }
697
698 return icd_term->dispatch.GetPhysicalDeviceWin32PresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex);
699 }
700 #endif // VK_USE_PLATFORM_WIN32_KHR
701
702 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
703
704 // This is the trampoline entrypoint for CreateWaylandSurfaceKHR
vkCreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)705 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(VkInstance instance,
706 const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
707 const VkAllocationCallbacks *pAllocator,
708 VkSurfaceKHR *pSurface) {
709 struct loader_instance *loader_inst = loader_get_instance(instance);
710 if (NULL == loader_inst) {
711 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
712 "vkCreateWaylandSurfaceKHR: Invalid instance [VUID-vkCreateWaylandSurfaceKHR-instance-parameter]");
713 abort(); /* Intentionally fail so user can correct issue. */
714 }
715 return loader_inst->disp->layer_inst_disp.CreateWaylandSurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
716 }
717
718 // This is the instance chain terminator function for CreateWaylandSurfaceKHR
terminator_CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)719 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance instance,
720 const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
721 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
722 VkResult vkRes = VK_SUCCESS;
723 VkIcdSurface *pIcdSurface = NULL;
724 uint32_t i = 0;
725
726 // First, check to ensure the appropriate extension was enabled:
727 struct loader_instance *loader_inst = loader_get_instance(instance);
728 if (!loader_inst->wsi_wayland_surface_enabled) {
729 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
730 "VK_KHR_wayland_surface extension not enabled. vkCreateWaylandSurfaceKHR not executed!");
731 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
732 goto out;
733 }
734
735 // Next, if so, proceed with the implementation of this function:
736 pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->wayland_surf.base), sizeof(pIcdSurface->wayland_surf));
737 if (pIcdSurface == NULL) {
738 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
739 goto out;
740 }
741
742 pIcdSurface->wayland_surf.base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
743 pIcdSurface->wayland_surf.display = pCreateInfo->display;
744 pIcdSurface->wayland_surf.surface = pCreateInfo->surface;
745
746 // Loop through each ICD and determine if they need to create a surface
747 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
748 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
749 if (NULL != icd_term->dispatch.CreateWaylandSurfaceKHR) {
750 vkRes = icd_term->dispatch.CreateWaylandSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
751 &pIcdSurface->real_icd_surfaces[i]);
752 if (VK_SUCCESS != vkRes) {
753 goto out;
754 }
755 }
756 }
757 }
758
759 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
760
761 out:
762
763 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
764 if (NULL != pIcdSurface->real_icd_surfaces) {
765 i = 0;
766 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
767 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
768 NULL != icd_term->dispatch.DestroySurfaceKHR) {
769 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
770 }
771 }
772 loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
773 }
774 loader_instance_heap_free(loader_inst, pIcdSurface);
775 }
776
777 return vkRes;
778 }
779
780 // This is the trampoline entrypoint for
781 // GetPhysicalDeviceWaylandPresentationSupportKHR
vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display *display)782 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
783 uint32_t queueFamilyIndex,
784 struct wl_display *display) {
785 const VkLayerInstanceDispatchTable *disp;
786 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
787 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
788 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
789 "vkGetPhysicalDeviceWaylandPresentationSupportKHR: Invalid physicalDevice "
790 "[VUID-vkGetPhysicalDeviceWaylandPresentationSupportKHR-physicalDevice-parameter]");
791 abort(); /* Intentionally fail so user can correct issue. */
792 }
793 disp = loader_get_instance_layer_dispatch(physicalDevice);
794 return disp->GetPhysicalDeviceWaylandPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, display);
795 }
796
797 // This is the instance chain terminator function for
798 // GetPhysicalDeviceWaylandPresentationSupportKHR
terminator_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display *display)799 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
800 uint32_t queueFamilyIndex,
801 struct wl_display *display) {
802 // First, check to ensure the appropriate extension was enabled:
803 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
804 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
805 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
806 if (!loader_inst->wsi_wayland_surface_enabled) {
807 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
808 "VK_KHR_wayland_surface extension not enabled. vkGetPhysicalDeviceWaylandPresentationSupportKHR not executed!");
809 return VK_FALSE;
810 }
811
812 if (NULL == icd_term->dispatch.GetPhysicalDeviceWaylandPresentationSupportKHR) {
813 // return VK_FALSE as this driver doesn't support WSI functionality
814 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
815 "ICD for selected physical device does not export vkGetPhysicalDeviceWaylandPresentationSupportKHR!");
816 return VK_FALSE;
817 }
818
819 return icd_term->dispatch.GetPhysicalDeviceWaylandPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, display);
820 }
821 #endif // VK_USE_PLATFORM_WAYLAND_KHR
822
823 #if defined(VK_USE_PLATFORM_XCB_KHR)
824
825 // Functions for the VK_KHR_xcb_surface extension:
826
827 // This is the trampoline entrypoint for CreateXcbSurfaceKHR
vkCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)828 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(VkInstance instance,
829 const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
830 const VkAllocationCallbacks *pAllocator,
831 VkSurfaceKHR *pSurface) {
832 struct loader_instance *loader_inst = loader_get_instance(instance);
833 if (NULL == loader_inst) {
834 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
835 "vkCreateXcbSurfaceKHR: Invalid instance [VUID-vkCreateXcbSurfaceKHR-instance-parameter]");
836 abort(); /* Intentionally fail so user can correct issue. */
837 }
838 return loader_inst->disp->layer_inst_disp.CreateXcbSurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
839 }
840
841 // This is the instance chain terminator function for CreateXcbSurfaceKHR
terminator_CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)842 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
843 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
844 VkResult vkRes = VK_SUCCESS;
845 VkIcdSurface *pIcdSurface = NULL;
846 uint32_t i = 0;
847
848 // First, check to ensure the appropriate extension was enabled:
849 struct loader_instance *loader_inst = loader_get_instance(instance);
850 if (!loader_inst->wsi_xcb_surface_enabled) {
851 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
852 "VK_KHR_xcb_surface extension not enabled. vkCreateXcbSurfaceKHR not executed!");
853 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
854 goto out;
855 }
856
857 // Next, if so, proceed with the implementation of this function:
858 pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->xcb_surf.base), sizeof(pIcdSurface->xcb_surf));
859 if (pIcdSurface == NULL) {
860 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
861 goto out;
862 }
863
864 pIcdSurface->xcb_surf.base.platform = VK_ICD_WSI_PLATFORM_XCB;
865 pIcdSurface->xcb_surf.connection = pCreateInfo->connection;
866 pIcdSurface->xcb_surf.window = pCreateInfo->window;
867
868 // Loop through each ICD and determine if they need to create a surface
869 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
870 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
871 if (NULL != icd_term->dispatch.CreateXcbSurfaceKHR) {
872 vkRes = icd_term->dispatch.CreateXcbSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
873 &pIcdSurface->real_icd_surfaces[i]);
874 if (VK_SUCCESS != vkRes) {
875 goto out;
876 }
877 }
878 }
879 }
880
881 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
882
883 out:
884
885 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
886 if (NULL != pIcdSurface->real_icd_surfaces) {
887 i = 0;
888 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
889 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
890 NULL != icd_term->dispatch.DestroySurfaceKHR) {
891 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
892 }
893 }
894 loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
895 }
896 loader_instance_heap_free(loader_inst, pIcdSurface);
897 }
898
899 return vkRes;
900 }
901
902 // This is the trampoline entrypoint for
903 // GetPhysicalDeviceXcbPresentationSupportKHR
vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t *connection, xcb_visualid_t visual_id)904 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
905 uint32_t queueFamilyIndex,
906 xcb_connection_t *connection,
907 xcb_visualid_t visual_id) {
908 const VkLayerInstanceDispatchTable *disp;
909 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
910 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
911 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
912 "vkGetPhysicalDeviceXcbPresentationSupportKHR: Invalid physicalDevice "
913 "[VUID-vkGetPhysicalDeviceXcbPresentationSupportKHR-physicalDevice-parameter]");
914 abort(); /* Intentionally fail so user can correct issue. */
915 }
916 disp = loader_get_instance_layer_dispatch(physicalDevice);
917 return disp->GetPhysicalDeviceXcbPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, connection, visual_id);
918 }
919
920 // This is the instance chain terminator function for
921 // GetPhysicalDeviceXcbPresentationSupportKHR
terminator_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t *connection, xcb_visualid_t visual_id)922 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
923 uint32_t queueFamilyIndex,
924 xcb_connection_t *connection,
925 xcb_visualid_t visual_id) {
926 // First, check to ensure the appropriate extension was enabled:
927 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
928 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
929 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
930 if (!loader_inst->wsi_xcb_surface_enabled) {
931 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
932 "VK_KHR_xcb_surface extension not enabled. vkGetPhysicalDeviceXcbPresentationSupportKHR not executed!");
933 return VK_FALSE;
934 }
935
936 if (NULL == icd_term->dispatch.GetPhysicalDeviceXcbPresentationSupportKHR) {
937 // return VK_FALSE as this driver doesn't support WSI functionality
938 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
939 "ICD for selected physical device does not export vkGetPhysicalDeviceXcbPresentationSupportKHR!");
940 return VK_FALSE;
941 }
942
943 return icd_term->dispatch.GetPhysicalDeviceXcbPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, connection,
944 visual_id);
945 }
946 #endif // VK_USE_PLATFORM_XCB_KHR
947
948 #if defined(VK_USE_PLATFORM_XLIB_KHR)
949
950 // Functions for the VK_KHR_xlib_surface extension:
951
952 // This is the trampoline entrypoint for CreateXlibSurfaceKHR
vkCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)953 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(VkInstance instance,
954 const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
955 const VkAllocationCallbacks *pAllocator,
956 VkSurfaceKHR *pSurface) {
957 struct loader_instance *loader_inst = loader_get_instance(instance);
958 if (NULL == loader_inst) {
959 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
960 "vkCreateXlibSurfaceKHR: Invalid instance [VUID-vkCreateXlibSurfaceKHR-instance-parameter]");
961 abort(); /* Intentionally fail so user can correct issue. */
962 }
963 return loader_inst->disp->layer_inst_disp.CreateXlibSurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
964 }
965
966 // This is the instance chain terminator function for CreateXlibSurfaceKHR
terminator_CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)967 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
968 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
969 VkResult vkRes = VK_SUCCESS;
970 VkIcdSurface *pIcdSurface = NULL;
971 uint32_t i = 0;
972
973 // First, check to ensure the appropriate extension was enabled:
974 struct loader_instance *loader_inst = loader_get_instance(instance);
975 if (!loader_inst->wsi_xlib_surface_enabled) {
976 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
977 "VK_KHR_xlib_surface extension not enabled. vkCreateXlibSurfaceKHR not executed!");
978 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
979 goto out;
980 }
981
982 // Next, if so, proceed with the implementation of this function:
983 pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->xlib_surf.base), sizeof(pIcdSurface->xlib_surf));
984 if (pIcdSurface == NULL) {
985 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
986 goto out;
987 }
988
989 pIcdSurface->xlib_surf.base.platform = VK_ICD_WSI_PLATFORM_XLIB;
990 pIcdSurface->xlib_surf.dpy = pCreateInfo->dpy;
991 pIcdSurface->xlib_surf.window = pCreateInfo->window;
992
993 // Loop through each ICD and determine if they need to create a surface
994 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
995 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
996 if (NULL != icd_term->dispatch.CreateXlibSurfaceKHR) {
997 vkRes = icd_term->dispatch.CreateXlibSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
998 &pIcdSurface->real_icd_surfaces[i]);
999 if (VK_SUCCESS != vkRes) {
1000 goto out;
1001 }
1002 }
1003 }
1004 }
1005
1006 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1007
1008 out:
1009
1010 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1011 if (NULL != pIcdSurface->real_icd_surfaces) {
1012 i = 0;
1013 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1014 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1015 NULL != icd_term->dispatch.DestroySurfaceKHR) {
1016 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1017 }
1018 }
1019 loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1020 }
1021 loader_instance_heap_free(loader_inst, pIcdSurface);
1022 }
1023
1024 return vkRes;
1025 }
1026
1027 // This is the trampoline entrypoint for
1028 // GetPhysicalDeviceXlibPresentationSupportKHR
vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display *dpy, VisualID visualID)1029 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
1030 uint32_t queueFamilyIndex, Display *dpy,
1031 VisualID visualID) {
1032 const VkLayerInstanceDispatchTable *disp;
1033 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1034 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1035 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1036 "vkGetPhysicalDeviceXlibPresentationSupportKHR: Invalid physicalDevice "
1037 "[VUID-vkGetPhysicalDeviceXlibPresentationSupportKHR-physicalDevice-parameter]");
1038 abort(); /* Intentionally fail so user can correct issue. */
1039 }
1040 disp = loader_get_instance_layer_dispatch(physicalDevice);
1041 return disp->GetPhysicalDeviceXlibPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, dpy, visualID);
1042 }
1043
1044 // This is the instance chain terminator function for
1045 // GetPhysicalDeviceXlibPresentationSupportKHR
terminator_GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display *dpy, VisualID visualID)1046 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
1047 uint32_t queueFamilyIndex, Display *dpy,
1048 VisualID visualID) {
1049 // First, check to ensure the appropriate extension was enabled:
1050 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1051 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1052 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1053 if (!loader_inst->wsi_xlib_surface_enabled) {
1054 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1055 "VK_KHR_xlib_surface extension not enabled. vkGetPhysicalDeviceXlibPresentationSupportKHR not executed!");
1056 return VK_FALSE;
1057 }
1058
1059 if (NULL == icd_term->dispatch.GetPhysicalDeviceXlibPresentationSupportKHR) {
1060 // return VK_FALSE as this driver doesn't support WSI functionality
1061 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1062 "ICD for selected physical device does not export vkGetPhysicalDeviceXlibPresentationSupportKHR!");
1063 return VK_FALSE;
1064 }
1065
1066 return icd_term->dispatch.GetPhysicalDeviceXlibPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, dpy, visualID);
1067 }
1068 #endif // VK_USE_PLATFORM_XLIB_KHR
1069
1070 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
1071
1072 // Functions for the VK_EXT_directfb_surface extension:
1073
1074 // This is the trampoline entrypoint for CreateDirectFBSurfaceEXT
vkCreateDirectFBSurfaceEXT(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1075 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT(VkInstance instance,
1076 const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo,
1077 const VkAllocationCallbacks *pAllocator,
1078 VkSurfaceKHR *pSurface) {
1079 struct loader_instance *loader_inst = loader_get_instance(instance);
1080 if (NULL == loader_inst) {
1081 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1082 "vkCreateDirectFBSurfaceEXT: Invalid instance [VUID-vkCreateDirectFBSurfaceEXT-instance-parameter]");
1083 abort(); /* Intentionally fail so user can correct issue. */
1084 }
1085 return loader_inst->disp->layer_inst_disp.CreateDirectFBSurfaceEXT(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1086 }
1087
1088 // This is the instance chain terminator function for CreateDirectFBSurfaceEXT
terminator_CreateDirectFBSurfaceEXT(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1089 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDirectFBSurfaceEXT(VkInstance instance,
1090 const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo,
1091 const VkAllocationCallbacks *pAllocator,
1092 VkSurfaceKHR *pSurface) {
1093 VkResult vkRes = VK_SUCCESS;
1094 VkIcdSurface *pIcdSurface = NULL;
1095 uint32_t i = 0;
1096
1097 // First, check to ensure the appropriate extension was enabled:
1098 struct loader_instance *loader_inst = loader_get_instance(instance);
1099 if (!loader_inst->wsi_directfb_surface_enabled) {
1100 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1101 "VK_EXT_directfb_surface extension not enabled. vkCreateDirectFBSurfaceEXT not executed!");
1102 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1103 goto out;
1104 }
1105
1106 // Next, if so, proceed with the implementation of this function:
1107 pIcdSurface =
1108 AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->directfb_surf.base), sizeof(pIcdSurface->directfb_surf));
1109 if (pIcdSurface == NULL) {
1110 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1111 goto out;
1112 }
1113
1114 pIcdSurface->directfb_surf.base.platform = VK_ICD_WSI_PLATFORM_DIRECTFB;
1115 pIcdSurface->directfb_surf.dfb = pCreateInfo->dfb;
1116 pIcdSurface->directfb_surf.surface = pCreateInfo->surface;
1117
1118 // Loop through each ICD and determine if they need to create a surface
1119 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1120 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1121 if (NULL != icd_term->dispatch.CreateDirectFBSurfaceEXT) {
1122 vkRes = icd_term->dispatch.CreateDirectFBSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
1123 &pIcdSurface->real_icd_surfaces[i]);
1124 if (VK_SUCCESS != vkRes) {
1125 goto out;
1126 }
1127 }
1128 }
1129 }
1130
1131 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1132
1133 out:
1134
1135 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1136 if (NULL != pIcdSurface->real_icd_surfaces) {
1137 i = 0;
1138 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1139 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1140 NULL != icd_term->dispatch.DestroySurfaceKHR) {
1141 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1142 }
1143 }
1144 loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1145 }
1146 loader_instance_heap_free(loader_inst, pIcdSurface);
1147 }
1148
1149 return vkRes;
1150 }
1151
1152 // This is the trampoline entrypoint for
1153 // GetPhysicalDeviceDirectFBPresentationSupportEXT
vkGetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB *dfb)1154 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice,
1155 uint32_t queueFamilyIndex,
1156 IDirectFB *dfb) {
1157 const VkLayerInstanceDispatchTable *disp;
1158 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1159 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1160 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1161 "vkGetPhysicalDeviceDirectFBPresentationSupportEXT: Invalid physicalDevice "
1162 "[VUID-vkGetPhysicalDeviceDirectFBPresentationSupportEXT-physicalDevice-parameter]");
1163 abort(); /* Intentionally fail so user can correct issue. */
1164 }
1165 disp = loader_get_instance_layer_dispatch(physicalDevice);
1166 return disp->GetPhysicalDeviceDirectFBPresentationSupportEXT(unwrapped_phys_dev, queueFamilyIndex, dfb);
1167 }
1168
1169 // This is the instance chain terminator function for
1170 // GetPhysicalDeviceDirectFBPresentationSupportEXT
terminator_GetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB *dfb)1171 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice,
1172 uint32_t queueFamilyIndex,
1173 IDirectFB *dfb) {
1174 // First, check to ensure the appropriate extension was enabled:
1175 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1176 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1177 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1178 if (!loader_inst->wsi_directfb_surface_enabled) {
1179 loader_log(
1180 loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1181 "VK_EXT_directfb_surface extension not enabled. vkGetPhysicalDeviceDirectFBPresentationSupportKHR not executed!");
1182 return VK_FALSE;
1183 }
1184
1185 if (NULL == icd_term->dispatch.GetPhysicalDeviceDirectFBPresentationSupportEXT) {
1186 // return VK_FALSE as this driver doesn't support WSI functionality
1187 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1188 "ICD for selected physical device does not export vkGetPhysicalDeviceDirectFBPresentationSupportEXT!");
1189 return VK_FALSE;
1190 }
1191
1192 return icd_term->dispatch.GetPhysicalDeviceDirectFBPresentationSupportEXT(phys_dev_term->phys_dev, queueFamilyIndex, dfb);
1193 }
1194
1195 #endif // VK_USE_PLATFORM_DIRECTFB_EXT
1196
1197 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
1198
1199 // Functions for the VK_KHR_android_surface extension:
1200
1201 // This is the trampoline entrypoint for CreateAndroidSurfaceKHR
vkCreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1202 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(VkInstance instance,
1203 const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
1204 const VkAllocationCallbacks *pAllocator,
1205 VkSurfaceKHR *pSurface) {
1206 struct loader_instance *loader_inst = loader_get_instance(instance);
1207 if (NULL == loader_inst) {
1208 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1209 "vkCreateAndroidSurfaceKHR: Invalid instance [VUID-vkCreateAndroidSurfaceKHR-instance-parameter]");
1210 abort(); /* Intentionally fail so user can correct issue. */
1211 }
1212 return loader_inst->disp->layer_inst_disp.CreateAndroidSurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1213 }
1214
1215 // This is the instance chain terminator function for CreateAndroidSurfaceKHR
terminator_CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1216 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateAndroidSurfaceKHR(VkInstance instance,
1217 const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
1218 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1219 // First, check to ensure the appropriate extension was enabled:
1220 struct loader_instance *loader_inst = loader_get_instance(instance);
1221 if (!loader_inst->wsi_display_enabled) {
1222 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1223 "VK_KHR_display extension not enabled. vkCreateAndroidSurfaceKHR not executed!");
1224 return VK_ERROR_EXTENSION_NOT_PRESENT;
1225 }
1226
1227 // Next, if so, proceed with the implementation of this function:
1228 VkIcdSurfaceAndroid *pIcdSurface =
1229 loader_instance_heap_alloc(loader_inst, sizeof(VkIcdSurfaceAndroid), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1230 if (pIcdSurface == NULL) {
1231 return VK_ERROR_OUT_OF_HOST_MEMORY;
1232 }
1233
1234 pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_ANDROID;
1235 pIcdSurface->window = pCreateInfo->window;
1236
1237 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1238
1239 return VK_SUCCESS;
1240 }
1241
1242 #endif // VK_USE_PLATFORM_ANDROID_KHR
1243
1244 #if defined(VK_USE_PLATFORM_OHOS)
1245
1246 // Functions for the VK_OHOS_surface extension:
1247
1248 // This is the trampoline entrypoint for CreateSurfaceOHOS
1249
vkCreateSurfaceOHOS(VkInstance instance, const VkSurfaceCreateInfoOHOS *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1250 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSurfaceOHOS(VkInstance instance,
1251 const VkSurfaceCreateInfoOHOS *pCreateInfo,
1252 const VkAllocationCallbacks *pAllocator,
1253 VkSurfaceKHR *pSurface) {
1254 struct loader_instance *loader_inst = loader_get_instance(instance);
1255 if (NULL == loader_inst) {
1256 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1257 "vkCreateSurfaceOHOS: Invalid instance [VUID-vkCreateSurfaceOHOS-instance-parameter]");
1258 abort(); /* Intentionally fail so user can correct issue. */
1259 }
1260 return loader_inst->disp->layer_inst_disp.CreateSurfaceOHOS(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1261 }
1262
1263 // This is the instance chain terminator function for CreateSurfaceOHOS
terminator_CreateSurfaceOHOS(VkInstance instance, const VkSurfaceCreateInfoOHOS *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1264 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSurfaceOHOS(VkInstance instance,
1265 const VkSurfaceCreateInfoOHOS *pCreateInfo,
1266 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1267 // First, check to ensure the appropriate extension was enabled:
1268 struct loader_instance *loader_inst = loader_get_instance(instance);
1269 if (!loader_inst->wsi_ohos_surface_enabled) {
1270 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1271 "VK_OHOS_surface extension not enabled. vkCreateSurfaceOHOS not executed!\n");
1272 return VK_ERROR_EXTENSION_NOT_PRESENT;
1273 }
1274
1275 // Next, if so, proceed with the implementation of this function:
1276 VkIcdSurfaceOHOS *pIcdSurface =
1277 loader_instance_heap_alloc(loader_inst, sizeof(VkIcdSurfaceOHOS), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1278 if (pIcdSurface == NULL) {
1279 return VK_ERROR_OUT_OF_HOST_MEMORY;
1280 }
1281
1282 pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_OHOS;
1283 pIcdSurface->window = pCreateInfo->window;
1284
1285 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1286
1287 return VK_SUCCESS;
1288 }
1289
1290 #endif // VK_USE_PLATFORM_OHOS
1291
1292
1293 // Functions for the VK_EXT_headless_surface extension:
1294
vkCreateHeadlessSurfaceEXT(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1295 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateHeadlessSurfaceEXT(VkInstance instance,
1296 const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
1297 const VkAllocationCallbacks *pAllocator,
1298 VkSurfaceKHR *pSurface) {
1299 struct loader_instance *loader_inst = loader_get_instance(instance);
1300 if (NULL == loader_inst) {
1301 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1302 "vkCreateHeadlessSurfaceEXT: Invalid instance [VUID-vkCreateHeadlessSurfaceEXT-instance-parameter]");
1303 abort(); /* Intentionally fail so user can correct issue. */
1304 }
1305 return loader_inst->disp->layer_inst_disp.CreateHeadlessSurfaceEXT(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1306 }
1307
terminator_CreateHeadlessSurfaceEXT(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1308 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance instance,
1309 const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
1310 const VkAllocationCallbacks *pAllocator,
1311 VkSurfaceKHR *pSurface) {
1312 struct loader_instance *inst = loader_get_instance(instance);
1313 VkIcdSurface *pIcdSurface = NULL;
1314 VkResult vkRes = VK_SUCCESS;
1315 uint32_t i = 0;
1316
1317 if (!inst->wsi_headless_surface_enabled) {
1318 loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
1319 "VK_EXT_headless_surface extension not enabled. "
1320 "vkCreateHeadlessSurfaceEXT not executed!");
1321 return VK_SUCCESS;
1322 }
1323
1324 // Next, if so, proceed with the implementation of this function:
1325 pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->headless_surf.base), sizeof(pIcdSurface->headless_surf));
1326 if (pIcdSurface == NULL) {
1327 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1328 goto out;
1329 }
1330
1331 pIcdSurface->headless_surf.base.platform = VK_ICD_WSI_PLATFORM_HEADLESS;
1332 // Loop through each ICD and determine if they need to create a surface
1333 for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1334 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1335 if (NULL != icd_term->dispatch.CreateHeadlessSurfaceEXT) {
1336 vkRes = icd_term->dispatch.CreateHeadlessSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
1337 &pIcdSurface->real_icd_surfaces[i]);
1338 if (VK_SUCCESS != vkRes) {
1339 goto out;
1340 }
1341 }
1342 }
1343 }
1344
1345 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1346
1347 out:
1348
1349 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1350 if (NULL != pIcdSurface->real_icd_surfaces) {
1351 i = 0;
1352 for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1353 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1354 NULL != icd_term->dispatch.DestroySurfaceKHR) {
1355 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1356 }
1357 }
1358 loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces);
1359 }
1360 loader_instance_heap_free(inst, pIcdSurface);
1361 }
1362
1363 return vkRes;
1364 }
1365
1366 // Ensure we are properly setting VK_USE_PLATFORM_METAL_EXT, VK_USE_PLATFORM_IOS_MVK, and VK_USE_PLATFORM_MACOS_MVK.
1367 #if __APPLE__
1368
1369 #ifndef VK_USE_PLATFORM_METAL_EXT
1370 #error "VK_USE_PLATFORM_METAL_EXT not defined!"
1371 #endif
1372
1373 #include <TargetConditionals.h>
1374
1375 #if TARGET_OS_IOS
1376
1377 #ifndef VK_USE_PLATFORM_IOS_MVK
1378 #error "VK_USE_PLATFORM_IOS_MVK not defined!"
1379 #endif
1380
1381 #endif // TARGET_OS_IOS
1382
1383 #if TARGET_OS_OSX
1384
1385 #ifndef VK_USE_PLATFORM_MACOS_MVK
1386 #error "VK_USE_PLATFORM_MACOS_MVK not defined!"
1387 #endif
1388
1389 #endif // TARGET_OS_OSX
1390
1391 #endif // __APPLE__
1392
1393 #if defined(VK_USE_PLATFORM_MACOS_MVK)
1394
1395 // Functions for the VK_MVK_macos_surface extension:
1396
1397 // This is the trampoline entrypoint for CreateMacOSSurfaceMVK
vkCreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1398 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(VkInstance instance,
1399 const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
1400 const VkAllocationCallbacks *pAllocator,
1401 VkSurfaceKHR *pSurface) {
1402 struct loader_instance *loader_inst = loader_get_instance(instance);
1403 if (NULL == loader_inst) {
1404 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1405 "vkCreateMacOSSurfaceMVK: Invalid instance [VUID-vkCreateMacOSSurfaceMVK-instance-parameter]");
1406 abort(); /* Intentionally fail so user can correct issue. */
1407 }
1408 return loader_inst->disp->layer_inst_disp.CreateMacOSSurfaceMVK(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1409 }
1410
1411 // This is the instance chain terminator function for CreateMacOSSurfaceKHR
terminator_CreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1412 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
1413 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1414 VkResult vkRes = VK_SUCCESS;
1415 VkIcdSurface *pIcdSurface = NULL;
1416 uint32_t i = 0;
1417
1418 // First, check to ensure the appropriate extension was enabled:
1419 struct loader_instance *loader_inst = loader_get_instance(instance);
1420 if (!loader_inst->wsi_macos_surface_enabled) {
1421 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1422 "VK_MVK_macos_surface extension not enabled. vkCreateMacOSSurfaceMVK not executed!");
1423 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1424 goto out;
1425 }
1426
1427 // Next, if so, proceed with the implementation of this function:
1428 pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->macos_surf.base), sizeof(pIcdSurface->macos_surf));
1429 if (pIcdSurface == NULL) {
1430 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1431 goto out;
1432 }
1433
1434 pIcdSurface->macos_surf.base.platform = VK_ICD_WSI_PLATFORM_MACOS;
1435 pIcdSurface->macos_surf.pView = pCreateInfo->pView;
1436
1437 // Loop through each ICD and determine if they need to create a surface
1438 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1439 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1440 if (NULL != icd_term->dispatch.CreateMacOSSurfaceMVK) {
1441 vkRes = icd_term->dispatch.CreateMacOSSurfaceMVK(icd_term->instance, pCreateInfo, pAllocator,
1442 &pIcdSurface->real_icd_surfaces[i]);
1443 if (VK_SUCCESS != vkRes) {
1444 goto out;
1445 }
1446 }
1447 }
1448 }
1449
1450 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1451
1452 out:
1453
1454 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1455 if (NULL != pIcdSurface->real_icd_surfaces) {
1456 i = 0;
1457 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1458 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1459 NULL != icd_term->dispatch.DestroySurfaceKHR) {
1460 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1461 }
1462 }
1463 loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1464 }
1465 loader_instance_heap_free(loader_inst, pIcdSurface);
1466 }
1467
1468 return vkRes;
1469 }
1470
1471 #endif // VK_USE_PLATFORM_MACOS_MVK
1472
1473 #if defined(VK_USE_PLATFORM_IOS_MVK)
1474
1475 // Functions for the VK_MVK_ios_surface extension:
1476
1477 // This is the trampoline entrypoint for CreateIOSSurfaceMVK
vkCreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1478 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK(VkInstance instance,
1479 const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
1480 const VkAllocationCallbacks *pAllocator,
1481 VkSurfaceKHR *pSurface) {
1482 struct loader_instance *loader_inst = loader_get_instance(instance);
1483 if (NULL == loader_inst) {
1484 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1485 "vkCreateIOSSurfaceMVK: Invalid instance [VUID-vkCreateIOSSurfaceMVK-instance-parameter]");
1486 abort(); /* Intentionally fail so user can correct issue. */
1487 }
1488 return loader_inst->disp->layer_inst_disp.CreateIOSSurfaceMVK(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1489 }
1490
1491 // This is the instance chain terminator function for CreateIOSSurfaceKHR
terminator_CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1492 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
1493 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1494 (void)pAllocator;
1495
1496 // First, check to ensure the appropriate extension was enabled:
1497 struct loader_instance *loader_inst = loader_get_instance(instance);
1498 if (!loader_inst->wsi_ios_surface_enabled) {
1499 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1500 "VK_MVK_ios_surface extension not enabled. vkCreateIOSSurfaceMVK not executed!");
1501 return VK_ERROR_EXTENSION_NOT_PRESENT;
1502 }
1503
1504 // Next, if so, proceed with the implementation of this function:
1505 VkIcdSurfaceIOS *pIcdSurface =
1506 loader_instance_heap_alloc(loader_inst, sizeof(VkIcdSurfaceIOS), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1507 if (pIcdSurface == NULL) {
1508 return VK_ERROR_OUT_OF_HOST_MEMORY;
1509 }
1510
1511 pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_IOS;
1512 pIcdSurface->pView = pCreateInfo->pView;
1513
1514 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1515
1516 return VK_SUCCESS;
1517 }
1518
1519 #endif // VK_USE_PLATFORM_IOS_MVK
1520
1521 #if defined(VK_USE_PLATFORM_GGP)
1522
1523 // Functions for the VK_GGP_stream_descriptor_surface extension:
1524
1525 // This is the trampoline entrypoint for CreateStreamDescriptorSurfaceGGP
1526 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkCreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1527 vkCreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo,
1528 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1529 struct loader_instance *loader_inst = loader_get_instance(instance);
1530 if (NULL == loader_inst) {
1531 loader_log(
1532 NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1533 "vkCreateStreamDescriptorSurfaceGGP: Invalid instance [VUID-vkCreateStreamDescriptorSurfaceGGP-instance-parameter]");
1534 abort(); /* Intentionally fail so user can correct issue. */
1535 }
1536 return loader_inst->disp->layer_inst_disp.CreateStreamDescriptorSurfaceGGP(loader_inst->instance, pCreateInfo, pAllocator,
1537 pSurface);
1538 }
1539
1540 // This is the instance chain terminator function for CreateStreamDescriptorSurfaceGGP
1541 VKAPI_ATTR VkResult VKAPI_CALL
terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1542 terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP *pCreateInfo,
1543 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1544 VkResult vkRes = VK_SUCCESS;
1545 VkIcdSurface *pIcdSurface = NULL;
1546 uint32_t i = 0;
1547
1548 // First, check to ensure the appropriate extension was enabled:
1549 struct loader_instance *loader_inst = loader_get_instance(instance);
1550 if (!loader_inst->wsi_ggp_surface_enabled) {
1551 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1552 "VK_GGP_stream_descriptor_surface extension not enabled. vkCreateStreamDescriptorSurfaceGGP not executed!");
1553 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1554 goto out;
1555 }
1556
1557 // Next, if so, proceed with the implementation of this function:
1558 pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->ggp_surf.base), sizeof(pIcdSurface->ggp_surf));
1559 if (pIcdSurface == NULL) {
1560 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1561 goto out;
1562 }
1563
1564 pIcdSurface->ggp_surf.base.platform = VK_ICD_WSI_PLATFORM_GGP;
1565 pIcdSurface->ggp_surf.streamDescriptor = pCreateInfo->streamDescriptor;
1566
1567 // Loop through each ICD and determine if they need to create a surface
1568 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1569 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1570 if (NULL != icd_term->dispatch.CreateStreamDescriptorSurfaceGGP) {
1571 vkRes = icd_term->dispatch.CreateStreamDescriptorSurfaceGGP(icd_term->instance, pCreateInfo, pAllocator,
1572 &pIcdSurface->real_icd_surfaces[i]);
1573 if (VK_SUCCESS != vkRes) {
1574 goto out;
1575 }
1576 }
1577 }
1578 }
1579
1580 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1581
1582 out:
1583
1584 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1585 if (NULL != pIcdSurface->real_icd_surfaces) {
1586 i = 0;
1587 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1588 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1589 NULL != icd_term->dispatch.DestroySurfaceKHR) {
1590 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1591 }
1592 }
1593 loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1594 }
1595 loader_instance_heap_free(loader_inst, pIcdSurface);
1596 }
1597 return vkRes;
1598 }
1599
1600 #endif // VK_USE_PLATFORM_GGP
1601
1602 #if defined(VK_USE_PLATFORM_METAL_EXT)
1603
vkCreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1604 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(VkInstance instance,
1605 const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
1606 const VkAllocationCallbacks *pAllocator,
1607 VkSurfaceKHR *pSurface) {
1608 struct loader_instance *loader_inst = loader_get_instance(instance);
1609 if (NULL == loader_inst) {
1610 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1611 "vkCreateMetalSurfaceEXT: Invalid instance [VUID-vkCreateMetalSurfaceEXT-instance-parameter]");
1612 abort(); /* Intentionally fail so user can correct issue. */
1613 }
1614 return loader_inst->disp->layer_inst_disp.CreateMetalSurfaceEXT(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1615 }
1616
terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1617 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
1618 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1619 VkResult result = VK_SUCCESS;
1620 VkIcdSurface *icd_surface = NULL;
1621 uint32_t i;
1622
1623 // First, check to ensure the appropriate extension was enabled:
1624 struct loader_instance *loader_inst = loader_get_instance(instance);
1625 if (!loader_inst->wsi_metal_surface_enabled) {
1626 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1627 "VK_EXT_metal_surface extension not enabled. vkCreateMetalSurfaceEXT will not be executed.");
1628 }
1629
1630 // Next, if so, proceed with the implementation of this function:
1631 icd_surface = AllocateIcdSurfaceStruct(loader_inst, sizeof(icd_surface->metal_surf.base), sizeof(icd_surface->metal_surf));
1632 if (icd_surface == NULL) {
1633 result = VK_ERROR_OUT_OF_HOST_MEMORY;
1634 goto out;
1635 }
1636
1637 icd_surface->metal_surf.base.platform = VK_ICD_WSI_PLATFORM_METAL;
1638 icd_surface->metal_surf.pLayer = pCreateInfo->pLayer;
1639
1640 // Loop through each ICD and determine if they need to create a surface
1641 i = 0;
1642 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
1643 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1644 if (icd_term->dispatch.CreateMetalSurfaceEXT != NULL) {
1645 result = icd_term->dispatch.CreateMetalSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
1646 &icd_surface->real_icd_surfaces[i]);
1647 if (result != VK_SUCCESS) {
1648 goto out;
1649 }
1650 }
1651 }
1652 }
1653 *pSurface = (VkSurfaceKHR)(uintptr_t)icd_surface;
1654
1655 out:
1656 if (result != VK_SUCCESS && icd_surface != NULL) {
1657 if (icd_surface->real_icd_surfaces != NULL) {
1658 i = 0;
1659 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
1660 if (icd_surface->real_icd_surfaces[i] == VK_NULL_HANDLE && icd_term->dispatch.DestroySurfaceKHR != NULL) {
1661 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator);
1662 }
1663 }
1664 loader_instance_heap_free(loader_inst, icd_surface->real_icd_surfaces);
1665 }
1666 loader_instance_heap_free(loader_inst, icd_surface);
1667 }
1668 return result;
1669 }
1670
1671 #endif // VK_USE_PLATFORM_METAL_EXT
1672
1673 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
1674
1675 // This is the trampoline entrypoint for CreateScreenSurfaceQNX
vkCreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1676 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX(VkInstance instance,
1677 const VkScreenSurfaceCreateInfoQNX *pCreateInfo,
1678 const VkAllocationCallbacks *pAllocator,
1679 VkSurfaceKHR *pSurface) {
1680 struct loader_instance *loader_inst = loader_get_instance(instance);
1681 if (NULL == loader_inst) {
1682 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1683 "vkCreateScreenSurfaceQNX: Invalid instance [VUID-vkCreateScreenSurfaceQNX-instance-parameter]");
1684 abort(); /* Intentionally fail so user can correct issue. */
1685 }
1686 return loader_inst->disp->layer_inst_disp.CreateScreenSurfaceQNX(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1687 }
1688
1689 // This is the instance chain terminator function for CreateScreenSurfaceQNX
terminator_CreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1690 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateScreenSurfaceQNX(VkInstance instance,
1691 const VkScreenSurfaceCreateInfoQNX *pCreateInfo,
1692 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1693 VkResult vkRes = VK_SUCCESS;
1694 VkIcdSurface *pIcdSurface = NULL;
1695 uint32_t i = 0;
1696
1697 // First, check to ensure the appropriate extension was enabled:
1698 struct loader_instance *loader_inst = loader_get_instance(instance);
1699 if (!loader_inst->wsi_screen_surface_enabled) {
1700 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1701 "VK_QNX_screen_surface extension not enabled. vkCreateScreenSurfaceQNX not executed!");
1702 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1703 goto out;
1704 }
1705
1706 // Next, if so, proceed with the implementation of this function:
1707 pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->screen_surf.base), sizeof(pIcdSurface->screen_surf));
1708 if (pIcdSurface == NULL) {
1709 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1710 goto out;
1711 }
1712
1713 pIcdSurface->screen_surf.base.platform = VK_ICD_WSI_PLATFORM_SCREEN;
1714 pIcdSurface->screen_surf.context = pCreateInfo->context;
1715 pIcdSurface->screen_surf.window = pCreateInfo->window;
1716
1717 // Loop through each ICD and determine if they need to create a surface
1718 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1719 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1720 if (NULL != icd_term->dispatch.CreateScreenSurfaceQNX) {
1721 vkRes = icd_term->dispatch.CreateScreenSurfaceQNX(icd_term->instance, pCreateInfo, pAllocator,
1722 &pIcdSurface->real_icd_surfaces[i]);
1723 if (VK_SUCCESS != vkRes) {
1724 goto out;
1725 }
1726 }
1727 }
1728 }
1729
1730 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1731
1732 out:
1733
1734 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1735 if (NULL != pIcdSurface->real_icd_surfaces) {
1736 i = 0;
1737 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1738 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1739 NULL != icd_term->dispatch.DestroySurfaceKHR) {
1740 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1741 }
1742 }
1743 loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1744 }
1745 loader_instance_heap_free(loader_inst, pIcdSurface);
1746 }
1747
1748 return vkRes;
1749 }
1750
1751 // This is the trampoline entrypoint for
1752 // GetPhysicalDeviceScreenPresentationSupportQNX
vkGetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window *window)1753 LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
1754 uint32_t queueFamilyIndex,
1755 struct _screen_window *window) {
1756 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1757 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1758 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1759 "vkGetPhysicalDeviceScreenPresentationSupportQNX: Invalid physicalDevice "
1760 "[VUID-vkGetPhysicalDeviceScreenPresentationSupportQNX-physicalDevice-parameter]");
1761 abort(); /* Intentionally fail so user can correct issue. */
1762 }
1763 const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
1764 VkBool32 res = disp->GetPhysicalDeviceScreenPresentationSupportQNX(unwrapped_phys_dev, queueFamilyIndex, window);
1765 return res;
1766 }
1767
1768 // This is the instance chain terminator function for
1769 // GetPhysicalDeviceScreenPresentationSupportQNX
terminator_GetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window *window)1770 VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
1771 uint32_t queueFamilyIndex,
1772 struct _screen_window *window) {
1773 // First, check to ensure the appropriate extension was enabled:
1774 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1775 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1776 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1777 if (!loader_inst->wsi_screen_surface_enabled) {
1778 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1779 "VK_QNX_screen_surface extension not enabled. vkGetPhysicalDeviceScreenPresentationSupportQNX not executed!");
1780 return VK_FALSE;
1781 }
1782
1783 if (NULL == icd_term->dispatch.GetPhysicalDeviceScreenPresentationSupportQNX) {
1784 // return VK_FALSE as this driver doesn't support WSI functionality
1785 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1786 "ICD for selected physical device does not export vkGetPhysicalDeviceScreenPresentationSupportQNX!");
1787 return VK_FALSE;
1788 }
1789
1790 return icd_term->dispatch.GetPhysicalDeviceScreenPresentationSupportQNX(phys_dev_term->phys_dev, queueFamilyIndex, window);
1791 }
1792 #endif // VK_USE_PLATFORM_SCREEN_QNX
1793
1794 #if defined(VK_USE_PLATFORM_VI_NN)
1795
1796 // Functions for the VK_NN_vi_surface extension:
1797
1798 // This is the trampoline entrypoint for CreateViSurfaceNN
vkCreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1799 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo,
1800 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1801 struct loader_instance *loader_inst = loader_get_instance(instance);
1802 if (NULL == loader_inst) {
1803 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1804 "vkCreateViSurfaceNN: Invalid instance [VUID-vkCreateViSurfaceNN-instance-parameter]");
1805 abort(); /* Intentionally fail so user can correct issue. */
1806 }
1807 return loader_inst->disp->layer_inst_disp.CreateViSurfaceNN(loader_inst->instance, pCreateInfo, pAllocator, pSurface);
1808 }
1809
1810 // This is the instance chain terminator function for CreateViSurfaceNN
terminator_CreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)1811 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateViSurfaceNN(VkInstance instance, const VkViSurfaceCreateInfoNN *pCreateInfo,
1812 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
1813 VkResult vkRes = VK_SUCCESS;
1814 VkIcdSurface *pIcdSurface = NULL;
1815 uint32_t i = 0;
1816
1817 // First, check to ensure the appropriate extension was enabled:
1818 struct loader_instance *loader_inst = loader_get_instance(instance);
1819 if (!loader_inst->wsi_vi_surface_enabled) {
1820 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1821 "VK_NN_vi_surface extension not enabled. vkCreateViSurfaceNN not executed!");
1822 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
1823 goto out;
1824 }
1825
1826 // Next, if so, proceed with the implementation of this function:
1827 pIcdSurface = AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->vi_surf.base), sizeof(pIcdSurface->vi_surf));
1828 if (pIcdSurface == NULL) {
1829 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
1830 goto out;
1831 }
1832
1833 pIcdSurface->vi_surf.base.platform = VK_ICD_WSI_PLATFORM_VI;
1834 pIcdSurface->vi_surf.window = pCreateInfo->window;
1835
1836 // Loop through each ICD and determine if they need to create a surface
1837 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1838 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
1839 if (NULL != icd_term->dispatch.CreateViSurfaceNN) {
1840 vkRes = icd_term->dispatch.CreateViSurfaceNN(icd_term->instance, pCreateInfo, pAllocator,
1841 &pIcdSurface->real_icd_surfaces[i]);
1842 if (VK_SUCCESS != vkRes) {
1843 goto out;
1844 }
1845 }
1846 }
1847 }
1848
1849 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
1850
1851 out:
1852
1853 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
1854 if (NULL != pIcdSurface->real_icd_surfaces) {
1855 i = 0;
1856 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
1857 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
1858 NULL != icd_term->dispatch.DestroySurfaceKHR) {
1859 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
1860 }
1861 }
1862 loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
1863 }
1864 loader_instance_heap_free(loader_inst, pIcdSurface);
1865 }
1866
1867 return vkRes;
1868 }
1869
1870 #endif // VK_USE_PLATFORM_VI_NN
1871
1872 // Functions for the VK_KHR_display instance extension:
vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties)1873 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
1874 uint32_t *pPropertyCount,
1875 VkDisplayPropertiesKHR *pProperties) {
1876 const VkLayerInstanceDispatchTable *disp;
1877 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1878 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1879 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1880 "vkGetPhysicalDeviceDisplayPropertiesKHR: Invalid physicalDevice "
1881 "[VUID-vkGetPhysicalDeviceDisplayPropertiesKHR-physicalDevice-parameter]");
1882 abort(); /* Intentionally fail so user can correct issue. */
1883 }
1884 disp = loader_get_instance_layer_dispatch(physicalDevice);
1885 VkResult res = disp->GetPhysicalDeviceDisplayPropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties);
1886 return res;
1887 }
1888
terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties)1889 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
1890 uint32_t *pPropertyCount,
1891 VkDisplayPropertiesKHR *pProperties) {
1892 // First, check to ensure the appropriate extension was enabled:
1893 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1894 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1895 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1896 if (!loader_inst->wsi_display_enabled) {
1897 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1898 "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPropertiesKHR not executed!");
1899 return VK_SUCCESS;
1900 }
1901
1902 if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR) {
1903 loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
1904 "ICD for selected physical device does not export vkGetPhysicalDeviceDisplayPropertiesKHR!");
1905 // return 0 for property count as this driver doesn't support WSI functionality
1906 if (pPropertyCount) {
1907 *pPropertyCount = 0;
1908 }
1909 return VK_SUCCESS;
1910 }
1911
1912 return icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
1913 }
1914
vkGetPhysicalDeviceDisplayPlanePropertiesKHR( VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties)1915 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR(
1916 VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties) {
1917 const VkLayerInstanceDispatchTable *disp;
1918 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1919 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1920 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1921 "vkGetPhysicalDeviceDisplayPlanePropertiesKHR: Invalid physicalDevice "
1922 "[VUID-vkGetPhysicalDeviceDisplayPlanePropertiesKHR-physicalDevice-parameter]");
1923 abort(); /* Intentionally fail so user can correct issue. */
1924 }
1925 disp = loader_get_instance_layer_dispatch(physicalDevice);
1926 VkResult res = disp->GetPhysicalDeviceDisplayPlanePropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties);
1927 return res;
1928 }
1929
terminator_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties)1930 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
1931 uint32_t *pPropertyCount,
1932 VkDisplayPlanePropertiesKHR *pProperties) {
1933 // First, check to ensure the appropriate extension was enabled:
1934 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1935 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1936 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1937 if (!loader_inst->wsi_display_enabled) {
1938 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1939 "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPlanePropertiesKHR not executed!");
1940 return VK_SUCCESS;
1941 }
1942
1943 if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR) {
1944 loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
1945 "ICD for selected physical device does not export vkGetPhysicalDeviceDisplayPlanePropertiesKHR!");
1946 // return 0 for property count as this driver doesn't support WSI functionality
1947 if (pPropertyCount) {
1948 *pPropertyCount = 0;
1949 }
1950 return VK_SUCCESS;
1951 }
1952
1953 return icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
1954 }
1955
vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t *pDisplayCount, VkDisplayKHR *pDisplays)1956 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
1957 uint32_t planeIndex, uint32_t *pDisplayCount,
1958 VkDisplayKHR *pDisplays) {
1959 const VkLayerInstanceDispatchTable *disp;
1960 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
1961 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
1962 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
1963 "vkGetDisplayPlaneSupportedDisplaysKHR: Invalid physicalDevice "
1964 "[VUID-vkGetDisplayPlaneSupportedDisplaysKHR-physicalDevice-parameter]");
1965 abort(); /* Intentionally fail so user can correct issue. */
1966 }
1967 disp = loader_get_instance_layer_dispatch(physicalDevice);
1968 VkResult res = disp->GetDisplayPlaneSupportedDisplaysKHR(unwrapped_phys_dev, planeIndex, pDisplayCount, pDisplays);
1969 return res;
1970 }
1971
terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t *pDisplayCount, VkDisplayKHR *pDisplays)1972 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
1973 uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
1974 // First, check to ensure the appropriate extension was enabled:
1975 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
1976 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
1977 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
1978 if (!loader_inst->wsi_display_enabled) {
1979 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
1980 "VK_KHR_display extension not enabled. vkGetDisplayPlaneSupportedDisplaysKHR not executed!");
1981 return VK_SUCCESS;
1982 }
1983
1984 if (NULL == icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR) {
1985 loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
1986 "ICD for selected physical device does not export vkGetDisplayPlaneSupportedDisplaysKHR!");
1987 // return 0 for property count as this driver doesn't support WSI functionality
1988 if (pDisplayCount) {
1989 *pDisplayCount = 0;
1990 }
1991 return VK_SUCCESS;
1992 }
1993
1994 return icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR(phys_dev_term->phys_dev, planeIndex, pDisplayCount, pDisplays);
1995 }
1996
vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties)1997 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
1998 uint32_t *pPropertyCount,
1999 VkDisplayModePropertiesKHR *pProperties) {
2000 const VkLayerInstanceDispatchTable *disp;
2001 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2002 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2003 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2004 "vkGetDisplayModePropertiesKHR: Invalid physicalDevice "
2005 "[VUID-vkGetDisplayModePropertiesKHR-physicalDevice-parameter]");
2006 abort(); /* Intentionally fail so user can correct issue. */
2007 }
2008 disp = loader_get_instance_layer_dispatch(physicalDevice);
2009 VkResult res = disp->GetDisplayModePropertiesKHR(unwrapped_phys_dev, display, pPropertyCount, pProperties);
2010 return res;
2011 }
2012
terminator_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties)2013 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2014 uint32_t *pPropertyCount,
2015 VkDisplayModePropertiesKHR *pProperties) {
2016 // First, check to ensure the appropriate extension was enabled:
2017 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2018 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2019 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2020 if (!loader_inst->wsi_display_enabled) {
2021 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2022 "VK_KHR_display extension not enabled. vkGetDisplayModePropertiesKHR not executed!");
2023 return VK_SUCCESS;
2024 }
2025
2026 if (NULL == icd_term->dispatch.GetDisplayModePropertiesKHR) {
2027 loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
2028 "ICD for selected physical device does not export vkGetDisplayModePropertiesKHR!");
2029 // return 0 for property count as this driver doesn't support WSI functionality
2030 if (pPropertyCount) {
2031 *pPropertyCount = 0;
2032 }
2033 return VK_SUCCESS;
2034 }
2035
2036 return icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, pProperties);
2037 }
2038
vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode)2039 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2040 const VkDisplayModeCreateInfoKHR *pCreateInfo,
2041 const VkAllocationCallbacks *pAllocator,
2042 VkDisplayModeKHR *pMode) {
2043 const VkLayerInstanceDispatchTable *disp;
2044 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2045 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2046 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2047 "vkCreateDisplayModeKHR: Invalid physicalDevice "
2048 "[VUID-vkCreateDisplayModeKHR-physicalDevice-parameter]");
2049 abort(); /* Intentionally fail so user can correct issue. */
2050 }
2051 disp = loader_get_instance_layer_dispatch(physicalDevice);
2052 VkResult res = disp->CreateDisplayModeKHR(unwrapped_phys_dev, display, pCreateInfo, pAllocator, pMode);
2053 return res;
2054 }
2055
terminator_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode)2056 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2057 const VkDisplayModeCreateInfoKHR *pCreateInfo,
2058 const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode) {
2059 // First, check to ensure the appropriate extension was enabled:
2060 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2061 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2062 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2063 if (!loader_inst->wsi_display_enabled) {
2064 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2065 "VK_KHR_display extension not enabled. vkCreateDisplayModeKHR not executed!");
2066 return VK_ERROR_EXTENSION_NOT_PRESENT;
2067 }
2068
2069 if (NULL == icd_term->dispatch.CreateDisplayModeKHR) {
2070 // Can't emulate, so return an appropriate error
2071 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2072 "ICD for selected physical device does not export vkCreateDisplayModeKHR!");
2073 return VK_ERROR_INITIALIZATION_FAILED;
2074 }
2075
2076 return icd_term->dispatch.CreateDisplayModeKHR(phys_dev_term->phys_dev, display, pCreateInfo, pAllocator, pMode);
2077 }
2078
vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR *pCapabilities)2079 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,
2080 VkDisplayModeKHR mode, uint32_t planeIndex,
2081 VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
2082 const VkLayerInstanceDispatchTable *disp;
2083 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2084 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2085 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2086 "vkGetDisplayPlaneCapabilitiesKHR: Invalid physicalDevice "
2087 "[VUID-vkGetDisplayPlaneCapabilitiesKHR-physicalDevice-parameter]");
2088 abort(); /* Intentionally fail so user can correct issue. */
2089 }
2090 disp = loader_get_instance_layer_dispatch(physicalDevice);
2091 VkResult res = disp->GetDisplayPlaneCapabilitiesKHR(unwrapped_phys_dev, mode, planeIndex, pCapabilities);
2092 return res;
2093 }
2094
terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR *pCapabilities)2095 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode,
2096 uint32_t planeIndex,
2097 VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
2098 // First, check to ensure the appropriate extension was enabled:
2099 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2100 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2101 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2102 if (!loader_inst->wsi_display_enabled) {
2103 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2104 "VK_KHR_display extension not enabled. vkGetDisplayPlaneCapabilitiesKHR not executed!");
2105 return VK_SUCCESS;
2106 }
2107
2108 if (NULL == icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR) {
2109 // Emulate support
2110 loader_log(loader_inst, VULKAN_LOADER_WARN_BIT, 0,
2111 "ICD for selected physical device does not export vkGetDisplayPlaneCapabilitiesKHR!");
2112 if (pCapabilities) {
2113 memset(pCapabilities, 0, sizeof(VkDisplayPlaneCapabilitiesKHR));
2114 }
2115 return VK_SUCCESS;
2116 }
2117
2118 return icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR(phys_dev_term->phys_dev, mode, planeIndex, pCapabilities);
2119 }
2120
vkCreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)2121 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR(VkInstance instance,
2122 const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
2123 const VkAllocationCallbacks *pAllocator,
2124 VkSurfaceKHR *pSurface) {
2125 struct loader_instance *loader_inst = loader_get_instance(instance);
2126 if (NULL == loader_inst) {
2127 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2128 "vkCreateDisplayPlaneSurfaceKHR: Invalid instance [VUID-vkCreateDisplayPlaneSurfaceKHR-instance-parameter]");
2129 abort(); /* Intentionally fail so user can correct issue. */
2130 }
2131 return loader_inst->disp->layer_inst_disp.CreateDisplayPlaneSurfaceKHR(loader_inst->instance, pCreateInfo, pAllocator,
2132 pSurface);
2133 }
2134
terminator_CreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)2135 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstance instance,
2136 const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
2137 const VkAllocationCallbacks *pAllocator,
2138 VkSurfaceKHR *pSurface) {
2139 struct loader_instance *inst = loader_get_instance(instance);
2140 VkIcdSurface *pIcdSurface = NULL;
2141 VkResult vkRes = VK_SUCCESS;
2142 uint32_t i = 0;
2143
2144 if (!inst->wsi_display_enabled) {
2145 loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
2146 "VK_KHR_surface extension not enabled. vkCreateDisplayPlaneSurfaceKHR not executed!");
2147 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
2148 goto out;
2149 }
2150
2151 // Next, if so, proceed with the implementation of this function:
2152 pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base), sizeof(pIcdSurface->display_surf));
2153 if (pIcdSurface == NULL) {
2154 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
2155 goto out;
2156 }
2157
2158 pIcdSurface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;
2159 pIcdSurface->display_surf.displayMode = pCreateInfo->displayMode;
2160 pIcdSurface->display_surf.planeIndex = pCreateInfo->planeIndex;
2161 pIcdSurface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex;
2162 pIcdSurface->display_surf.transform = pCreateInfo->transform;
2163 pIcdSurface->display_surf.globalAlpha = pCreateInfo->globalAlpha;
2164 pIcdSurface->display_surf.alphaMode = pCreateInfo->alphaMode;
2165 pIcdSurface->display_surf.imageExtent = pCreateInfo->imageExtent;
2166
2167 // Loop through each ICD and determine if they need to create a surface
2168 for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2169 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
2170 if (NULL != icd_term->dispatch.CreateDisplayPlaneSurfaceKHR) {
2171 vkRes = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
2172 &pIcdSurface->real_icd_surfaces[i]);
2173 if (VK_SUCCESS != vkRes) {
2174 goto out;
2175 }
2176 }
2177 }
2178 }
2179
2180 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
2181
2182 out:
2183
2184 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
2185 if (NULL != pIcdSurface->real_icd_surfaces) {
2186 i = 0;
2187 for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2188 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
2189 NULL != icd_term->dispatch.DestroySurfaceKHR) {
2190 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
2191 }
2192 }
2193 loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces);
2194 }
2195 loader_instance_heap_free(inst, pIcdSurface);
2196 }
2197
2198 return vkRes;
2199 }
2200
2201 // EXT_display_swapchain Extension command
2202
vkCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains)2203 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
2204 const VkSwapchainCreateInfoKHR *pCreateInfos,
2205 const VkAllocationCallbacks *pAllocator,
2206 VkSwapchainKHR *pSwapchains) {
2207 const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2208 if (NULL == disp) {
2209 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2210 "vkCreateSharedSwapchainsKHR: Invalid device [VUID-vkCreateSharedSwapchainsKHR-device-parameter]");
2211 abort(); /* Intentionally fail so user can correct issue. */
2212 }
2213 return disp->CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
2214 }
2215
terminator_CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains)2216 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
2217 const VkSwapchainCreateInfoKHR *pCreateInfos,
2218 const VkAllocationCallbacks *pAllocator,
2219 VkSwapchainKHR *pSwapchains) {
2220 uint32_t icd_index = 0;
2221 struct loader_device *dev;
2222 struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
2223 if (NULL == icd_term || NULL == dev) {
2224 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2225 "vkCreateSharedSwapchainsKHR Terminator: Invalid device handle. This is likely the result of a "
2226 "layer wrapping device handles and failing to unwrap them in all functions. "
2227 "[VUID-vkCreateSharedSwapchainsKHR-device-parameter]");
2228 abort(); /* Intentionally fail so user can correct issue. */
2229 }
2230 if (NULL == dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR) {
2231 loader_log(NULL, VULKAN_LOADER_ERROR_BIT, 0,
2232 "vkCreateSharedSwapchainsKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was the "
2233 "VK_KHR_display_swapchain extension enabled?");
2234 return VK_SUCCESS;
2235 }
2236 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfos->surface;
2237 if ((VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) {
2238 // We found the ICD, and there is an ICD KHR surface
2239 // associated with it, so copy the CreateInfo struct
2240 // and point it at the ICD's surface.
2241 VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR) * swapchainCount);
2242 if (NULL == pCreateCopy) {
2243 return VK_ERROR_OUT_OF_HOST_MEMORY;
2244 }
2245 memcpy(pCreateCopy, pCreateInfos, sizeof(VkSwapchainCreateInfoKHR) * swapchainCount);
2246 for (uint32_t sc = 0; sc < swapchainCount; sc++) {
2247 pCreateCopy[sc].surface = icd_surface->real_icd_surfaces[icd_index];
2248 }
2249 return dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateCopy,
2250 pAllocator, pSwapchains);
2251 }
2252 return dev->loader_dispatch.extension_terminator_dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos,
2253 pAllocator, pSwapchains);
2254 }
2255
2256 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkGetDeviceGroupPresentCapabilitiesKHR(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR *pDeviceGroupPresentCapabilities)2257 vkGetDeviceGroupPresentCapabilitiesKHR(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR *pDeviceGroupPresentCapabilities) {
2258 const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2259 if (NULL == disp) {
2260 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2261 "vkGetDeviceGroupPresentCapabilitiesKHR: Invalid device "
2262 "[VUID-vkGetDeviceGroupPresentCapabilitiesKHR-device-parameter]");
2263 abort(); /* Intentionally fail so user can correct issue. */
2264 }
2265 return disp->GetDeviceGroupPresentCapabilitiesKHR(device, pDeviceGroupPresentCapabilities);
2266 }
2267
vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR *pModes)2268 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface,
2269 VkDeviceGroupPresentModeFlagsKHR *pModes) {
2270 const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2271 if (NULL == disp) {
2272 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2273 "vkGetDeviceGroupSurfacePresentModesKHR: Invalid device "
2274 "[VUID-vkGetDeviceGroupSurfacePresentModesKHR-device-parameter]");
2275 abort(); /* Intentionally fail so user can correct issue. */
2276 }
2277 return disp->GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
2278 }
2279
terminator_GetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR *pModes)2280 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface,
2281 VkDeviceGroupPresentModeFlagsKHR *pModes) {
2282 uint32_t icd_index = 0;
2283 struct loader_device *dev;
2284 struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
2285 if (NULL == icd_term || NULL == dev) {
2286 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2287 "vkGetDeviceGroupSurfacePresentModesKHR: Invalid device "
2288 "[VUID-vkGetDeviceGroupSurfacePresentModesKHR-device-parameter]");
2289 abort(); /* Intentionally fail so user can correct issue. */
2290 }
2291 if (NULL == dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR) {
2292 loader_log(NULL, VULKAN_LOADER_ERROR_BIT, 0,
2293 "vkGetDeviceGroupSurfacePresentModesKHR: Driver's function pointer was NULL, returning VK_SUCCESS. Was either "
2294 "Vulkan 1.1 and VK_KHR_swapchain enabled or both the VK_KHR_device_group and VK_KHR_surface "
2295 "extensions enabled when using Vulkan 1.0?");
2296 return VK_SUCCESS;
2297 }
2298 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
2299 if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)(uintptr_t)NULL != icd_surface->real_icd_surfaces[icd_index]) {
2300 return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR(
2301 device, icd_surface->real_icd_surfaces[icd_index], pModes);
2302 }
2303 return dev->loader_dispatch.extension_terminator_dispatch.GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
2304 }
2305
vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pRectCount, VkRect2D *pRects)2306 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
2307 VkSurfaceKHR surface, uint32_t *pRectCount,
2308 VkRect2D *pRects) {
2309 const VkLayerInstanceDispatchTable *disp;
2310 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2311 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2312 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2313 "vkGetPhysicalDevicePresentRectanglesKHR: Invalid physicalDevice "
2314 "[VUID-vkGetPhysicalDevicePresentRectanglesKHR-physicalDevice-parameter]");
2315 abort(); /* Intentionally fail so user can correct issue. */
2316 }
2317 disp = loader_get_instance_layer_dispatch(physicalDevice);
2318 return disp->GetPhysicalDevicePresentRectanglesKHR(unwrapped_phys_dev, surface, pRectCount, pRects);
2319 }
2320
terminator_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pRectCount, VkRect2D *pRects)2321 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
2322 VkSurfaceKHR surface, uint32_t *pRectCount,
2323 VkRect2D *pRects) {
2324 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2325 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2326 if (NULL == icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR) {
2327 loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
2328 "ICD associated with VkPhysicalDevice does not support GetPhysicalDevicePresentRectanglesKHX");
2329 // return as this driver doesn't support WSI functionality
2330 if (pRectCount) {
2331 *pRectCount = 0;
2332 }
2333 return VK_SUCCESS;
2334 }
2335 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(surface);
2336 uint8_t icd_index = phys_dev_term->icd_index;
2337 if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2338 return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR(
2339 phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[icd_index], pRectCount, pRects);
2340 }
2341 return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR(phys_dev_term->phys_dev, surface, pRectCount, pRects);
2342 }
2343
vkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo, uint32_t *pImageIndex)2344 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo,
2345 uint32_t *pImageIndex) {
2346 const VkLayerDispatchTable *disp = loader_get_dispatch(device);
2347 if (NULL == disp) {
2348 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2349 "vkAcquireNextImage2KHR: Invalid device [VUID-vkAcquireNextImage2KHR-device-parameter]");
2350 abort(); /* Intentionally fail so user can correct issue. */
2351 }
2352 return disp->AcquireNextImage2KHR(device, pAcquireInfo, pImageIndex);
2353 }
2354
2355 // ---- VK_KHR_get_display_properties2 extension trampoline/terminators
2356
vkGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayProperties2KHR *pProperties)2357 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
2358 uint32_t *pPropertyCount,
2359 VkDisplayProperties2KHR *pProperties) {
2360 const VkLayerInstanceDispatchTable *disp;
2361 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2362 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2363 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2364 "vkGetPhysicalDeviceDisplayProperties2KHR: Invalid physicalDevice "
2365 "[VUID-vkGetPhysicalDeviceDisplayProperties2KHR-physicalDevice-parameter]");
2366 abort(); /* Intentionally fail so user can correct issue. */
2367 }
2368 disp = loader_get_instance_layer_dispatch(physicalDevice);
2369 return disp->GetPhysicalDeviceDisplayProperties2KHR(unwrapped_phys_dev, pPropertyCount, pProperties);
2370 }
2371
terminator_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayProperties2KHR *pProperties)2372 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
2373 uint32_t *pPropertyCount,
2374 VkDisplayProperties2KHR *pProperties) {
2375 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2376 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2377
2378 // If the function is available in the driver, just call into it
2379 if (icd_term->dispatch.GetPhysicalDeviceDisplayProperties2KHR != NULL) {
2380 return icd_term->dispatch.GetPhysicalDeviceDisplayProperties2KHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
2381 }
2382
2383 // We have to emulate the function.
2384 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2385 "vkGetPhysicalDeviceDisplayProperties2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
2386
2387 // If the icd doesn't support VK_KHR_display, then no properties are available
2388 if (icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR == NULL) {
2389 *pPropertyCount = 0;
2390 return VK_SUCCESS;
2391 }
2392
2393 // If we aren't writing to pProperties, then emulation is straightforward
2394 if (pProperties == NULL || *pPropertyCount == 0) {
2395 return icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, NULL);
2396 }
2397
2398 // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayPropertiesKHR and copy it
2399 VkDisplayPropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayPropertiesKHR));
2400 if (properties == NULL) {
2401 return VK_ERROR_OUT_OF_HOST_MEMORY;
2402 }
2403 VkResult res = icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, properties);
2404 if (res < 0) {
2405 return res;
2406 }
2407 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2408 memcpy(&pProperties[i].displayProperties, &properties[i], sizeof(VkDisplayPropertiesKHR));
2409 }
2410 return res;
2411 }
2412
vkGetPhysicalDeviceDisplayPlaneProperties2KHR( VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlaneProperties2KHR *pProperties)2413 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlaneProperties2KHR(
2414 VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlaneProperties2KHR *pProperties) {
2415 const VkLayerInstanceDispatchTable *disp;
2416 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2417 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2418 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2419 "vkGetPhysicalDeviceDisplayPlaneProperties2KHR: Invalid physicalDevice "
2420 "[VUID-vkGetPhysicalDeviceDisplayPlaneProperties2KHR-physicalDevice-parameter]");
2421 abort(); /* Intentionally fail so user can correct issue. */
2422 }
2423 disp = loader_get_instance_layer_dispatch(physicalDevice);
2424 return disp->GetPhysicalDeviceDisplayPlaneProperties2KHR(unwrapped_phys_dev, pPropertyCount, pProperties);
2425 }
2426
terminator_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlaneProperties2KHR *pProperties)2427 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
2428 uint32_t *pPropertyCount,
2429 VkDisplayPlaneProperties2KHR *pProperties) {
2430 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2431 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2432
2433 // If the function is available in the driver, just call into it
2434 if (icd_term->dispatch.GetPhysicalDeviceDisplayPlaneProperties2KHR != NULL) {
2435 return icd_term->dispatch.GetPhysicalDeviceDisplayPlaneProperties2KHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
2436 }
2437
2438 // We have to emulate the function.
2439 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2440 "vkGetPhysicalDeviceDisplayPlaneProperties2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
2441
2442 // If the icd doesn't support VK_KHR_display, then no properties are available
2443 if (icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR == NULL) {
2444 *pPropertyCount = 0;
2445 return VK_SUCCESS;
2446 }
2447
2448 // If we aren't writing to pProperties, then emulation is straightforward
2449 if (pProperties == NULL || *pPropertyCount == 0) {
2450 return icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, NULL);
2451 }
2452
2453 // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayPlanePropertiesKHR and copy it
2454 VkDisplayPlanePropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayPlanePropertiesKHR));
2455 if (properties == NULL) {
2456 return VK_ERROR_OUT_OF_HOST_MEMORY;
2457 }
2458 VkResult res =
2459 icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, properties);
2460 if (res < 0) {
2461 return res;
2462 }
2463 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2464 memcpy(&pProperties[i].displayPlaneProperties, &properties[i], sizeof(VkDisplayPlanePropertiesKHR));
2465 }
2466 return res;
2467 }
2468
vkGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount, VkDisplayModeProperties2KHR *pProperties)2469 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2470 uint32_t *pPropertyCount,
2471 VkDisplayModeProperties2KHR *pProperties) {
2472 const VkLayerInstanceDispatchTable *disp;
2473 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2474 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2475 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2476 "vkGetDisplayModeProperties2KHR: Invalid physicalDevice "
2477 "[VUID-vkGetDisplayModeProperties2KHR-physicalDevice-parameter]");
2478 abort(); /* Intentionally fail so user can correct issue. */
2479 }
2480 disp = loader_get_instance_layer_dispatch(physicalDevice);
2481 return disp->GetDisplayModeProperties2KHR(unwrapped_phys_dev, display, pPropertyCount, pProperties);
2482 }
2483
terminator_GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount, VkDisplayModeProperties2KHR *pProperties)2484 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
2485 uint32_t *pPropertyCount,
2486 VkDisplayModeProperties2KHR *pProperties) {
2487 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2488 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2489
2490 // If the function is available in the driver, just call into it
2491 if (icd_term->dispatch.GetDisplayModeProperties2KHR != NULL) {
2492 return icd_term->dispatch.GetDisplayModeProperties2KHR(phys_dev_term->phys_dev, display, pPropertyCount, pProperties);
2493 }
2494
2495 // We have to emulate the function.
2496 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0, "vkGetDisplayModeProperties2KHR: Emulating call in ICD \"%s\"",
2497 icd_term->scanned_icd->lib_name);
2498
2499 // If the icd doesn't support VK_KHR_display, then no properties are available
2500 if (icd_term->dispatch.GetDisplayModePropertiesKHR == NULL) {
2501 *pPropertyCount = 0;
2502 return VK_SUCCESS;
2503 }
2504
2505 // If we aren't writing to pProperties, then emulation is straightforward
2506 if (pProperties == NULL || *pPropertyCount == 0) {
2507 return icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, NULL);
2508 }
2509
2510 // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayModePropertiesKHR and copy it
2511 VkDisplayModePropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayModePropertiesKHR));
2512 if (properties == NULL) {
2513 return VK_ERROR_OUT_OF_HOST_MEMORY;
2514 }
2515 VkResult res = icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, properties);
2516 if (res < 0) {
2517 return res;
2518 }
2519 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
2520 memcpy(&pProperties[i].displayModeProperties, &properties[i], sizeof(VkDisplayModePropertiesKHR));
2521 }
2522 return res;
2523 }
2524
vkGetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR *pCapabilities)2525 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
2526 const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
2527 VkDisplayPlaneCapabilities2KHR *pCapabilities) {
2528 const VkLayerInstanceDispatchTable *disp;
2529 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2530 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2531 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2532 "vkGetDisplayPlaneCapabilities2KHR: Invalid physicalDevice "
2533 "[VUID-vkGetDisplayPlaneCapabilities2KHR-physicalDevice-parameter]");
2534 abort(); /* Intentionally fail so user can correct issue. */
2535 }
2536 disp = loader_get_instance_layer_dispatch(physicalDevice);
2537 return disp->GetDisplayPlaneCapabilities2KHR(unwrapped_phys_dev, pDisplayPlaneInfo, pCapabilities);
2538 }
2539
terminator_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR *pCapabilities)2540 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
2541 const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
2542 VkDisplayPlaneCapabilities2KHR *pCapabilities) {
2543 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2544 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2545
2546 // If the function is available in the driver, just call into it
2547 if (icd_term->dispatch.GetDisplayPlaneCapabilities2KHR != NULL) {
2548 return icd_term->dispatch.GetDisplayPlaneCapabilities2KHR(phys_dev_term->phys_dev, pDisplayPlaneInfo, pCapabilities);
2549 }
2550
2551 // We have to emulate the function.
2552 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2553 "vkGetDisplayPlaneCapabilities2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
2554
2555 // If the icd doesn't support VK_KHR_display, then there are no capabilities
2556 if (NULL == icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR) {
2557 if (pCapabilities) {
2558 memset(&pCapabilities->capabilities, 0, sizeof(VkDisplayPlaneCapabilitiesKHR));
2559 }
2560 return VK_SUCCESS;
2561 }
2562
2563 // Just call into the old version of the function.
2564 return icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR(phys_dev_term->phys_dev, pDisplayPlaneInfo->mode,
2565 pDisplayPlaneInfo->planeIndex, &pCapabilities->capabilities);
2566 }
2567
2568 #if defined(VK_USE_PLATFORM_FUCHSIA)
2569
2570 // This is the trampoline entrypoint for CreateImagePipeSurfaceFUCHSIA
vkCreateImagePipeSurfaceFUCHSIA(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)2571 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA(VkInstance instance,
2572 const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo,
2573 const VkAllocationCallbacks *pAllocator,
2574 VkSurfaceKHR *pSurface) {
2575 struct loader_instance *loader_inst = loader_get_instance(instance);
2576 if (NULL == loader_inst) {
2577 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2578 "vkCreateImagePipeSurfaceFUCHSIA: Invalid instance [VUID-vkCreateImagePipeSurfaceFUCHSIA-instance-parameter]");
2579 abort(); /* Intentionally fail so user can correct issue. */
2580 }
2581 return loader_inst->disp->layer_inst_disp.CreateImagePipeSurfaceFUCHSIA(loader_inst->instance, pCreateInfo, pAllocator,
2582 pSurface);
2583 }
2584
2585 // This is the instance chain terminator function for CreateImagePipeSurfaceFUCHSIA
terminator_CreateImagePipeSurfaceFUCHSIA(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface)2586 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(VkInstance instance,
2587 const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo,
2588 const VkAllocationCallbacks *pAllocator,
2589 VkSurfaceKHR *pSurface) {
2590 VkResult vkRes = VK_SUCCESS;
2591 VkIcdSurface *pIcdSurface = NULL;
2592 uint32_t i = 0;
2593
2594 // Initialize pSurface to NULL just to be safe.
2595 *pSurface = VK_NULL_HANDLE;
2596 // First, check to ensure the appropriate extension was enabled:
2597 struct loader_instance *loader_inst = loader_get_instance(instance);
2598 if (!loader_inst->wsi_imagepipe_surface_enabled) {
2599 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2600 "VK_FUCHSIA_imagepipe_surface extension not enabled. "
2601 "vkCreateImagePipeSurfaceFUCHSIA not executed!");
2602 vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
2603 goto out;
2604 }
2605
2606 // Next, if so, proceed with the implementation of this function:
2607 pIcdSurface =
2608 AllocateIcdSurfaceStruct(loader_inst, sizeof(pIcdSurface->imagepipe_surf.base), sizeof(pIcdSurface->imagepipe_surf));
2609 if (pIcdSurface == NULL) {
2610 vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
2611 goto out;
2612 }
2613
2614 pIcdSurface->imagepipe_surf.base.platform = VK_ICD_WSI_PLATFORM_FUCHSIA;
2615
2616 // Loop through each ICD and determine if they need to create a surface
2617 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2618 if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
2619 if (NULL != icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA) {
2620 vkRes = icd_term->dispatch.CreateImagePipeSurfaceFUCHSIA(icd_term->instance, pCreateInfo, pAllocator,
2621 &pIcdSurface->real_icd_surfaces[i]);
2622 if (VK_SUCCESS != vkRes) {
2623 goto out;
2624 }
2625 }
2626 }
2627 }
2628
2629 *pSurface = (VkSurfaceKHR)(uintptr_t)pIcdSurface;
2630
2631 out:
2632
2633 if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
2634 if (NULL != pIcdSurface->real_icd_surfaces) {
2635 i = 0;
2636 for (struct loader_icd_term *icd_term = loader_inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
2637 if ((VkSurfaceKHR)(uintptr_t)NULL != pIcdSurface->real_icd_surfaces[i] &&
2638 NULL != icd_term->dispatch.DestroySurfaceKHR) {
2639 icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
2640 }
2641 }
2642 loader_instance_heap_free(loader_inst, pIcdSurface->real_icd_surfaces);
2643 }
2644 loader_instance_heap_free(loader_inst, pIcdSurface);
2645 }
2646
2647 return vkRes;
2648 }
2649 #endif // VK_USE_PLATFORM_FUCHSIA
2650
2651 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities)2652 vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2653 VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
2654 const VkLayerInstanceDispatchTable *disp;
2655 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2656 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2657 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2658 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Invalid physicalDevice "
2659 "[VUID-vkGetPhysicalDeviceSurfaceCapabilities2KHR-physicalDevice-parameter]");
2660 abort(); /* Intentionally fail so user can correct issue. */
2661 }
2662 disp = loader_get_instance_layer_dispatch(physicalDevice);
2663 return disp->GetPhysicalDeviceSurfaceCapabilities2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceCapabilities);
2664 }
2665
terminator_GetPhysicalDeviceSurfaceCapabilities2KHR( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities)2666 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2KHR(
2667 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2668 VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
2669 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2670 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2671 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2672
2673 if (!loader_inst->wsi_surface_enabled) {
2674 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2675 "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceCapabilities2KHR not executed!");
2676 return VK_SUCCESS;
2677 }
2678
2679 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
2680 uint8_t icd_index = phys_dev_term->icd_index;
2681
2682 if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) {
2683 VkBaseOutStructure *pNext = (VkBaseOutStructure *)pSurfaceCapabilities->pNext;
2684 while (pNext != NULL) {
2685 if ((int)pNext->sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR) {
2686 // Not all ICDs may be supporting VK_KHR_surface_protected_capabilities
2687 // Initialize VkSurfaceProtectedCapabilitiesKHR.supportsProtected to false and
2688 // if an ICD supports protected surfaces, it will reset it to true accordingly.
2689 ((VkSurfaceProtectedCapabilitiesKHR *)pNext)->supportsProtected = VK_FALSE;
2690 }
2691 pNext = (VkBaseOutStructure *)pNext->pNext;
2692 }
2693
2694 // Pass the call to the driver, possibly unwrapping the ICD surface
2695 if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)icd_surface->real_icd_surfaces[icd_index]) {
2696 VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
2697 info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
2698 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy,
2699 pSurfaceCapabilities);
2700 } else {
2701 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
2702 pSurfaceCapabilities);
2703 }
2704 } else {
2705 // Emulate the call
2706 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2707 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulating call in ICD \"%s\" using "
2708 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
2709 icd_term->scanned_icd->lib_name);
2710
2711 if (pSurfaceInfo->pNext != NULL) {
2712 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2713 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
2714 "pSurfaceInfo->pNext - this struct will be ignored");
2715 }
2716
2717 // Write to the VkSurfaceCapabilities2KHR struct
2718 VkSurfaceKHR surface = pSurfaceInfo->surface;
2719 if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2720 surface = icd_surface->real_icd_surfaces[icd_index];
2721 }
2722
2723 // If the icd doesn't support VK_KHR_surface, then there are no capabilities
2724 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR) {
2725 if (pSurfaceCapabilities) {
2726 memset(&pSurfaceCapabilities->surfaceCapabilities, 0, sizeof(VkSurfaceCapabilitiesKHR));
2727 }
2728 return VK_SUCCESS;
2729 }
2730 VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface,
2731 &pSurfaceCapabilities->surfaceCapabilities);
2732
2733 if (pSurfaceCapabilities->pNext != NULL) {
2734 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2735 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
2736 "pSurfaceCapabilities->pNext - this struct will be ignored");
2737 }
2738 return res;
2739 }
2740 }
2741
2742 LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats)2743 vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2744 uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats) {
2745 const VkLayerInstanceDispatchTable *disp;
2746 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
2747 if (VK_NULL_HANDLE == unwrapped_phys_dev) {
2748 loader_log(NULL, VULKAN_LOADER_FATAL_ERROR_BIT | VULKAN_LOADER_ERROR_BIT | VULKAN_LOADER_VALIDATION_BIT, 0,
2749 "vkGetPhysicalDeviceSurfaceFormats2KHR: Invalid physicalDevice "
2750 "[VUID-vkGetPhysicalDeviceSurfaceFormats2KHR-physicalDevice-parameter]");
2751 abort(); /* Intentionally fail so user can correct issue. */
2752 }
2753 disp = loader_get_instance_layer_dispatch(physicalDevice);
2754 return disp->GetPhysicalDeviceSurfaceFormats2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats);
2755 }
2756
terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats)2757 VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
2758 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
2759 uint32_t *pSurfaceFormatCount,
2760 VkSurfaceFormat2KHR *pSurfaceFormats) {
2761 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
2762 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
2763 struct loader_instance *loader_inst = (struct loader_instance *)icd_term->this_instance;
2764
2765 if (!loader_inst->wsi_surface_enabled) {
2766 loader_log(loader_inst, VULKAN_LOADER_ERROR_BIT, 0,
2767 "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceFormats2KHR not executed!");
2768 return VK_SUCCESS;
2769 }
2770
2771 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)(pSurfaceInfo->surface);
2772 uint8_t icd_index = phys_dev_term->icd_index;
2773
2774 if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) {
2775 // Pass the call to the driver, possibly unwrapping the ICD surface
2776 if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2777 VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
2778 info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
2779 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount,
2780 pSurfaceFormats);
2781 } else {
2782 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
2783 pSurfaceFormatCount, pSurfaceFormats);
2784 }
2785 } else {
2786 // Emulate the call
2787 loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
2788 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceSurfaceFormatsKHR",
2789 icd_term->scanned_icd->lib_name);
2790
2791 if (pSurfaceInfo->pNext != NULL) {
2792 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2793 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in pSurfaceInfo->pNext "
2794 "- this struct will be ignored");
2795 }
2796
2797 VkSurfaceKHR surface = pSurfaceInfo->surface;
2798 if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)(uintptr_t)(icd_surface->real_icd_surfaces[icd_index])) {
2799 surface = icd_surface->real_icd_surfaces[icd_index];
2800 }
2801
2802 // If the icd doesn't support VK_KHR_surface, then there are no formats
2803 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR) {
2804 if (pSurfaceFormatCount) {
2805 *pSurfaceFormatCount = 0;
2806 }
2807 return VK_SUCCESS;
2808 }
2809
2810 if (*pSurfaceFormatCount == 0 || pSurfaceFormats == NULL) {
2811 // Write to pSurfaceFormatCount
2812 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
2813 NULL);
2814 } else {
2815 // Allocate a temporary array for the output of the old function
2816 VkSurfaceFormatKHR *formats = loader_stack_alloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
2817 if (formats == NULL) {
2818 return VK_ERROR_OUT_OF_HOST_MEMORY;
2819 }
2820
2821 VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface,
2822 pSurfaceFormatCount, formats);
2823 for (uint32_t i = 0; i < *pSurfaceFormatCount; ++i) {
2824 pSurfaceFormats[i].surfaceFormat = formats[i];
2825 if (pSurfaceFormats[i].pNext != NULL) {
2826 loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
2827 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in "
2828 "pSurfaceFormats[%d].pNext - this struct will be ignored",
2829 i);
2830 }
2831 }
2832 return res;
2833 }
2834 }
2835 }
2836
wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char *name, void **addr)2837 bool wsi_swapchain_instance_gpa(struct loader_instance *loader_inst, const char *name, void **addr) {
2838 *addr = NULL;
2839
2840 // Functions for the VK_KHR_surface extension:
2841 if (!strcmp("vkDestroySurfaceKHR", name)) {
2842 *addr = loader_inst->wsi_surface_enabled ? (void *)vkDestroySurfaceKHR : NULL;
2843 return true;
2844 }
2845 if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name)) {
2846 *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceSupportKHR : NULL;
2847 return true;
2848 }
2849 if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name)) {
2850 *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilitiesKHR : NULL;
2851 return true;
2852 }
2853 if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name)) {
2854 *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormatsKHR : NULL;
2855 return true;
2856 }
2857 if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name)) {
2858 *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfacePresentModesKHR : NULL;
2859 return true;
2860 }
2861
2862 if (!strcmp("vkGetDeviceGroupPresentCapabilitiesKHR", name)) {
2863 *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetDeviceGroupPresentCapabilitiesKHR : NULL;
2864 return true;
2865 }
2866
2867 if (!strcmp("vkGetDeviceGroupSurfacePresentModesKHR", name)) {
2868 *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetDeviceGroupSurfacePresentModesKHR : NULL;
2869 return true;
2870 }
2871
2872 if (!strcmp("vkGetPhysicalDevicePresentRectanglesKHR", name)) {
2873 *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDevicePresentRectanglesKHR : NULL;
2874 return true;
2875 }
2876
2877 // Functions for VK_KHR_get_surface_capabilities2 extension:
2878 if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilities2KHR", name)) {
2879 *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilities2KHR : NULL;
2880 return true;
2881 }
2882
2883 if (!strcmp("vkGetPhysicalDeviceSurfaceFormats2KHR", name)) {
2884 *addr = loader_inst->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormats2KHR : NULL;
2885 return true;
2886 }
2887
2888 // Functions for the VK_KHR_swapchain extension:
2889
2890 // Note: This is a device extension, and its functions are statically
2891 // exported from the loader. Per Khronos decisions, the loader's GIPA
2892 // function will return the trampoline function for such device-extension
2893 // functions, regardless of whether the extension has been enabled.
2894 if (!strcmp("vkCreateSwapchainKHR", name)) {
2895 *addr = (void *)vkCreateSwapchainKHR;
2896 return true;
2897 }
2898 if (!strcmp("vkDestroySwapchainKHR", name)) {
2899 *addr = (void *)vkDestroySwapchainKHR;
2900 return true;
2901 }
2902 if (!strcmp("vkGetSwapchainImagesKHR", name)) {
2903 *addr = (void *)vkGetSwapchainImagesKHR;
2904 return true;
2905 }
2906 if (!strcmp("vkAcquireNextImageKHR", name)) {
2907 *addr = (void *)vkAcquireNextImageKHR;
2908 return true;
2909 }
2910 if (!strcmp("vkQueuePresentKHR", name)) {
2911 *addr = (void *)vkQueuePresentKHR;
2912 return true;
2913 }
2914 if (!strcmp("vkAcquireNextImage2KHR", name)) {
2915 *addr = (void *)vkAcquireNextImage2KHR;
2916 return true;
2917 }
2918
2919 #if defined(VK_USE_PLATFORM_WIN32_KHR)
2920
2921 // Functions for the VK_KHR_win32_surface extension:
2922 if (!strcmp("vkCreateWin32SurfaceKHR", name)) {
2923 *addr = loader_inst->wsi_win32_surface_enabled ? (void *)vkCreateWin32SurfaceKHR : NULL;
2924 return true;
2925 }
2926 if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", name)) {
2927 *addr = loader_inst->wsi_win32_surface_enabled ? (void *)vkGetPhysicalDeviceWin32PresentationSupportKHR : NULL;
2928 return true;
2929 }
2930 #endif // VK_USE_PLATFORM_WIN32_KHR
2931 #if defined(VK_USE_PLATFORM_WAYLAND_KHR)
2932
2933 // Functions for the VK_KHR_wayland_surface extension:
2934 if (!strcmp("vkCreateWaylandSurfaceKHR", name)) {
2935 *addr = loader_inst->wsi_wayland_surface_enabled ? (void *)vkCreateWaylandSurfaceKHR : NULL;
2936 return true;
2937 }
2938 if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", name)) {
2939 *addr = loader_inst->wsi_wayland_surface_enabled ? (void *)vkGetPhysicalDeviceWaylandPresentationSupportKHR : NULL;
2940 return true;
2941 }
2942 #endif // VK_USE_PLATFORM_WAYLAND_KHR
2943 #if defined(VK_USE_PLATFORM_XCB_KHR)
2944
2945 // Functions for the VK_KHR_xcb_surface extension:
2946 if (!strcmp("vkCreateXcbSurfaceKHR", name)) {
2947 *addr = loader_inst->wsi_xcb_surface_enabled ? (void *)vkCreateXcbSurfaceKHR : NULL;
2948 return true;
2949 }
2950 if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", name)) {
2951 *addr = loader_inst->wsi_xcb_surface_enabled ? (void *)vkGetPhysicalDeviceXcbPresentationSupportKHR : NULL;
2952 return true;
2953 }
2954 #endif // VK_USE_PLATFORM_XCB_KHR
2955 #if defined(VK_USE_PLATFORM_XLIB_KHR)
2956
2957 // Functions for the VK_KHR_xlib_surface extension:
2958 if (!strcmp("vkCreateXlibSurfaceKHR", name)) {
2959 *addr = loader_inst->wsi_xlib_surface_enabled ? (void *)vkCreateXlibSurfaceKHR : NULL;
2960 return true;
2961 }
2962 if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", name)) {
2963 *addr = loader_inst->wsi_xlib_surface_enabled ? (void *)vkGetPhysicalDeviceXlibPresentationSupportKHR : NULL;
2964 return true;
2965 }
2966 #endif // VK_USE_PLATFORM_XLIB_KHR
2967 #if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
2968
2969 // Functions for the VK_EXT_directfb_surface extension:
2970 if (!strcmp("vkCreateDirectFBSurfaceEXT", name)) {
2971 *addr = loader_inst->wsi_directfb_surface_enabled ? (void *)vkCreateDirectFBSurfaceEXT : NULL;
2972 return true;
2973 }
2974 if (!strcmp("vkGetPhysicalDeviceDirectFBPresentationSupportEXT", name)) {
2975 *addr = loader_inst->wsi_directfb_surface_enabled ? (void *)vkGetPhysicalDeviceDirectFBPresentationSupportEXT : NULL;
2976 return true;
2977 }
2978 #endif // VK_USE_PLATFORM_DIRECTFB_EXT
2979 #if defined(VK_USE_PLATFORM_ANDROID_KHR)
2980
2981 // Functions for the VK_KHR_android_surface extension:
2982 if (!strcmp("vkCreateAndroidSurfaceKHR", name)) {
2983 *addr = loader_inst->wsi_android_surface_enabled ? (void *)vkCreateAndroidSurfaceKHR : NULL;
2984 return true;
2985 }
2986 #endif // VK_USE_PLATFORM_ANDROID_KHR
2987 #if defined(VK_USE_PLATFORM_OHOS)
2988
2989 // Functions for the VK_OHOS_surface extension:
2990 if (!strcmp("vkCreateSurfaceOHOS", name)) {
2991 *addr = loader_inst->wsi_ohos_surface_enabled ? (void *)vkCreateSurfaceOHOS : NULL;
2992 return true;
2993 }
2994 #endif // VK_USE_PLATFORM_OHOS
2995
2996 #if defined(VK_USE_PLATFORM_MACOS_MVK)
2997
2998 // Functions for the VK_MVK_macos_surface extension:
2999 if (!strcmp("vkCreateMacOSSurfaceMVK", name)) {
3000 *addr = loader_inst->wsi_macos_surface_enabled ? (void *)vkCreateMacOSSurfaceMVK : NULL;
3001 return true;
3002 }
3003 #endif // VK_USE_PLATFORM_MACOS_MVK
3004 #if defined(VK_USE_PLATFORM_IOS_MVK)
3005
3006 // Functions for the VK_MVK_ios_surface extension:
3007 if (!strcmp("vkCreateIOSSurfaceMVK", name)) {
3008 *addr = loader_inst->wsi_ios_surface_enabled ? (void *)vkCreateIOSSurfaceMVK : NULL;
3009 return true;
3010 }
3011 #endif // VK_USE_PLATFORM_IOS_MVK
3012 #if defined(VK_USE_PLATFORM_GGP)
3013
3014 // Functions for the VK_GGP_stream_descriptor_surface extension:
3015 if (!strcmp("vkCreateStreamDescriptorSurfaceGGP", name)) {
3016 *addr = loader_inst->wsi_ggp_surface_enabled ? (void *)vkCreateStreamDescriptorSurfaceGGP : NULL;
3017 return true;
3018 }
3019 #endif // VK_USE_PLATFORM_GGP
3020 #if defined(VK_USE_PLATFORM_FUCHSIA)
3021
3022 // Functions for the VK_FUCHSIA_imagepipe_surface extension:
3023 if (!strcmp("vkCreateImagePipeSurfaceFUCHSIA", name)) {
3024 *addr = loader_inst->wsi_imagepipe_surface_enabled ? (void *)vkCreateImagePipeSurfaceFUCHSIA : NULL;
3025 return true;
3026 }
3027
3028 #endif // VK_USE_PLATFORM_FUCHSIA
3029
3030 // Functions for the VK_EXT_headless_surface extension:
3031 if (!strcmp("vkCreateHeadlessSurfaceEXT", name)) {
3032 *addr = loader_inst->wsi_headless_surface_enabled ? (void *)vkCreateHeadlessSurfaceEXT : NULL;
3033 return true;
3034 }
3035
3036 #if defined(VK_USE_PLATFORM_METAL_EXT)
3037 // Functions for the VK_MVK_macos_surface extension:
3038 if (!strcmp("vkCreateMetalSurfaceEXT", name)) {
3039 *addr = loader_inst->wsi_metal_surface_enabled ? (void *)vkCreateMetalSurfaceEXT : NULL;
3040 return true;
3041 }
3042 #endif // VK_USE_PLATFORM_METAL_EXT
3043
3044 #if defined(VK_USE_PLATFORM_SCREEN_QNX)
3045
3046 // Functions for the VK_QNX_screen_surface extension:
3047 if (!strcmp("vkCreateScreenSurfaceQNX", name)) {
3048 *addr = loader_inst->wsi_screen_surface_enabled ? (void *)vkCreateScreenSurfaceQNX : NULL;
3049 return true;
3050 }
3051 if (!strcmp("vkGetPhysicalDeviceScreenPresentationSupportQNX", name)) {
3052 *addr = loader_inst->wsi_screen_surface_enabled ? (void *)vkGetPhysicalDeviceScreenPresentationSupportQNX : NULL;
3053 return true;
3054 }
3055 #endif // VK_USE_PLATFORM_SCREEN_QNX
3056
3057 #if defined(VK_USE_PLATFORM_VI_NN)
3058
3059 // Functions for the VK_NN_vi_surface extension:
3060 if (!strcmp("vkCreateViSurfaceNN", name)) {
3061 *addr = loader_inst->wsi_vi_surface_enabled ? (void *)vkCreateViSurfaceNN : NULL;
3062 return true;
3063 }
3064 #endif // VK_USE_PLATFORM_VI_NN
3065
3066 // Functions for VK_KHR_display extension:
3067 if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) {
3068 *addr = loader_inst->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL;
3069 return true;
3070 }
3071 if (!strcmp("vkGetPhysicalDeviceDisplayPlanePropertiesKHR", name)) {
3072 *addr = loader_inst->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPlanePropertiesKHR : NULL;
3073 return true;
3074 }
3075 if (!strcmp("vkGetDisplayPlaneSupportedDisplaysKHR", name)) {
3076 *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayPlaneSupportedDisplaysKHR : NULL;
3077 return true;
3078 }
3079 if (!strcmp("vkGetDisplayModePropertiesKHR", name)) {
3080 *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayModePropertiesKHR : NULL;
3081 return true;
3082 }
3083 if (!strcmp("vkCreateDisplayModeKHR", name)) {
3084 *addr = loader_inst->wsi_display_enabled ? (void *)vkCreateDisplayModeKHR : NULL;
3085 return true;
3086 }
3087 if (!strcmp("vkGetDisplayPlaneCapabilitiesKHR", name)) {
3088 *addr = loader_inst->wsi_display_enabled ? (void *)vkGetDisplayPlaneCapabilitiesKHR : NULL;
3089 return true;
3090 }
3091 if (!strcmp("vkCreateDisplayPlaneSurfaceKHR", name)) {
3092 *addr = loader_inst->wsi_display_enabled ? (void *)vkCreateDisplayPlaneSurfaceKHR : NULL;
3093 return true;
3094 }
3095
3096 // Functions for KHR_display_swapchain extension:
3097 if (!strcmp("vkCreateSharedSwapchainsKHR", name)) {
3098 *addr = (void *)vkCreateSharedSwapchainsKHR;
3099 return true;
3100 }
3101
3102 // Functions for KHR_get_display_properties2
3103 if (!strcmp("vkGetPhysicalDeviceDisplayProperties2KHR", name)) {
3104 *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayProperties2KHR : NULL;
3105 return true;
3106 }
3107 if (!strcmp("vkGetPhysicalDeviceDisplayPlaneProperties2KHR", name)) {
3108 *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayPlaneProperties2KHR : NULL;
3109 return true;
3110 }
3111 if (!strcmp("vkGetDisplayModeProperties2KHR", name)) {
3112 *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetDisplayModeProperties2KHR : NULL;
3113 return true;
3114 }
3115 if (!strcmp("vkGetDisplayPlaneCapabilities2KHR", name)) {
3116 *addr = loader_inst->wsi_display_props2_enabled ? (void *)vkGetDisplayPlaneCapabilities2KHR : NULL;
3117 return true;
3118 }
3119
3120 return false;
3121 }
3122