Coverage Report

Created: 2023-06-07 06:30

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