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