Coverage Report

Created: 2025-07-18 06:34

/src/vulkan-loader/loader/terminator.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2014-2021 The Khronos Group Inc.
4
 * Copyright (c) 2014-2021 Valve Corporation
5
 * Copyright (c) 2014-2021 LunarG, Inc.
6
 * Copyright (C) 2015 Google Inc.
7
 * Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
8
 * Copyright (c) 2023-2023 RasterGrid Kft.
9
 *
10
 * Licensed under the Apache License, Version 2.0 (the "License");
11
 * you may not use this file except in compliance with the License.
12
 * You may obtain a copy of the License at
13
 *
14
 *     http://www.apache.org/licenses/LICENSE-2.0
15
 *
16
 * Unless required by applicable law or agreed to in writing, software
17
 * distributed under the License is distributed on an "AS IS" BASIS,
18
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
 * See the License for the specific language governing permissions and
20
 * limitations under the License.
21
22
 *
23
 * Author: Jon Ashburn <jon@lunarg.com>
24
 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
25
 * Author: Mark Young <marky@lunarg.com>
26
 * Author: Lenny Komow <lenny@lunarg.com>
27
 * Author: Charles Giessen <charles@lunarg.com>
28
 *
29
 */
30
31
// Terminators which have simple logic belong here, since they are mostly "pass through"
32
// Function declarations are in vk_loader_extensions.h, thus not needed here
33
34
#include "loader_common.h"
35
#include "loader.h"
36
#include "log.h"
37
#include "stack_allocation.h"
38
39
// Terminators for 1.0 functions
40
41
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
42
0
                                                                  VkPhysicalDeviceProperties *pProperties) {
43
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
44
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
45
0
    if (NULL != icd_term->dispatch.GetPhysicalDeviceProperties) {
46
0
        icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, pProperties);
47
0
    }
48
0
}
49
50
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
51
                                                                             uint32_t *pQueueFamilyPropertyCount,
52
0
                                                                             VkQueueFamilyProperties *pProperties) {
53
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
54
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
55
0
    if (NULL != icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties) {
56
0
        icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, pProperties);
57
0
    }
58
0
}
59
60
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
61
0
                                                                        VkPhysicalDeviceMemoryProperties *pProperties) {
62
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
63
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
64
0
    if (NULL != icd_term->dispatch.GetPhysicalDeviceMemoryProperties) {
65
0
        icd_term->dispatch.GetPhysicalDeviceMemoryProperties(phys_dev_term->phys_dev, pProperties);
66
0
    }
67
0
}
68
69
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
70
0
                                                                VkPhysicalDeviceFeatures *pFeatures) {
71
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
72
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
73
0
    if (NULL != icd_term->dispatch.GetPhysicalDeviceFeatures) {
74
0
        icd_term->dispatch.GetPhysicalDeviceFeatures(phys_dev_term->phys_dev, pFeatures);
75
0
    }
76
0
}
77
78
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
79
0
                                                                        VkFormatProperties *pFormatInfo) {
80
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
81
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
82
0
    if (NULL != icd_term->dispatch.GetPhysicalDeviceFormatProperties) {
83
0
        icd_term->dispatch.GetPhysicalDeviceFormatProperties(phys_dev_term->phys_dev, format, pFormatInfo);
84
0
    }
85
0
}
86
87
VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
88
                                                                                 VkImageType type, VkImageTiling tiling,
89
                                                                                 VkImageUsageFlags usage, VkImageCreateFlags flags,
90
0
                                                                                 VkImageFormatProperties *pImageFormatProperties) {
91
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
92
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
93
0
    if (NULL == icd_term->dispatch.GetPhysicalDeviceImageFormatProperties) {
94
0
        loader_log(
95
0
            icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
96
0
            "The icd's vkGetPhysicalDeviceImageFormatProperties was null, returning with VK_ERROR_INITIALIZATION_FAILED instead.");
97
0
        return VK_ERROR_INITIALIZATION_FAILED;
98
0
    }
99
0
    return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(phys_dev_term->phys_dev, format, type, tiling, usage, flags,
100
0
                                                                     pImageFormatProperties);
101
0
}
102
103
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
104
                                                                                   VkImageType type, VkSampleCountFlagBits samples,
105
                                                                                   VkImageUsageFlags usage, VkImageTiling tiling,
106
                                                                                   uint32_t *pNumProperties,
107
0
                                                                                   VkSparseImageFormatProperties *pProperties) {
108
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
109
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
110
0
    if (NULL != icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties) {
111
0
        icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(phys_dev_term->phys_dev, format, type, samples, usage,
112
0
                                                                        tiling, pNumProperties, pProperties);
113
0
    }
114
0
}
115
116
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
117
0
                                                                         VkLayerProperties *pProperties) {
118
0
    (void)pPropertyCount;
119
0
    (void)pProperties;
120
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
121
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
122
0
    loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
123
0
               "Encountered the vkEnumerateDeviceLayerProperties terminator.  This means a layer improperly continued.");
124
    // Should never get here this call isn't dispatched down the chain
125
0
    return VK_ERROR_INITIALIZATION_FAILED;
126
0
}
127
128
// Terminators for 1.1 functions
129
130
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
131
0
                                                                 VkPhysicalDeviceFeatures2 *pFeatures) {
132
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
133
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
134
0
    const struct loader_instance *inst = icd_term->this_instance;
135
136
0
    assert(inst != NULL);
137
138
    // Get the function pointer to use to call into the ICD. This could be the core or KHR version
139
0
    PFN_vkGetPhysicalDeviceFeatures2 fpGetPhysicalDeviceFeatures2 = NULL;
140
0
    if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
141
0
        fpGetPhysicalDeviceFeatures2 = icd_term->dispatch.GetPhysicalDeviceFeatures2;
142
0
    }
143
0
    if (fpGetPhysicalDeviceFeatures2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
144
0
        fpGetPhysicalDeviceFeatures2 = icd_term->dispatch.GetPhysicalDeviceFeatures2KHR;
145
0
    }
146
147
0
    if (fpGetPhysicalDeviceFeatures2 != NULL) {
148
        // Pass the call to the driver
149
0
        fpGetPhysicalDeviceFeatures2(phys_dev_term->phys_dev, pFeatures);
150
0
    } else {
151
        // Emulate the call
152
0
        loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
153
0
                   "vkGetPhysicalDeviceFeatures2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFeatures",
154
0
                   icd_term->scanned_icd->lib_name);
155
156
        // Write to the VkPhysicalDeviceFeatures2 struct
157
0
        icd_term->dispatch.GetPhysicalDeviceFeatures(phys_dev_term->phys_dev, &pFeatures->features);
158
159
0
        void *pNext = pFeatures->pNext;
160
0
        while (pNext != NULL) {
161
0
            VkBaseOutStructure pNext_in_structure = {0};
162
0
            memcpy(&pNext_in_structure, pNext, sizeof(VkBaseOutStructure));
163
0
            switch (pNext_in_structure.sType) {
164
0
                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {
165
                    // Skip the check if VK_KHR_multiview is enabled because it's a device extension
166
                    // Write to the VkPhysicalDeviceMultiviewFeaturesKHR struct
167
0
                    VkPhysicalDeviceMultiviewFeaturesKHR *multiview_features = (VkPhysicalDeviceMultiviewFeaturesKHR *)pNext;
168
0
                    multiview_features->multiview = VK_FALSE;
169
0
                    multiview_features->multiviewGeometryShader = VK_FALSE;
170
0
                    multiview_features->multiviewTessellationShader = VK_FALSE;
171
172
0
                    pNext = multiview_features->pNext;
173
0
                    break;
174
0
                }
175
0
                default: {
176
0
                    loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
177
0
                               "vkGetPhysicalDeviceFeatures2: Emulation found unrecognized structure type in pFeatures->pNext - "
178
0
                               "this struct will be ignored");
179
180
0
                    pNext = pNext_in_structure.pNext;
181
0
                    break;
182
0
                }
183
0
            }
184
0
        }
185
0
    }
186
0
}
187
188
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
189
0
                                                                   VkPhysicalDeviceProperties2 *pProperties) {
190
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
191
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
192
0
    const struct loader_instance *inst = icd_term->this_instance;
193
194
0
    assert(inst != NULL);
195
196
    // Get the function pointer to use to call into the ICD. This could be the core or KHR version
197
0
    PFN_vkGetPhysicalDeviceProperties2 fpGetPhysicalDeviceProperties2 = NULL;
198
0
    if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
199
0
        fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2;
200
0
    }
201
0
    if (fpGetPhysicalDeviceProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
202
0
        fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2KHR;
203
0
    }
204
205
0
    if (fpGetPhysicalDeviceProperties2 != NULL) {
206
        // Pass the call to the driver
207
0
        fpGetPhysicalDeviceProperties2(phys_dev_term->phys_dev, pProperties);
208
0
    } else {
209
        // Emulate the call
210
0
        loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
211
0
                   "vkGetPhysicalDeviceProperties2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceProperties",
212
0
                   icd_term->scanned_icd->lib_name);
213
214
        // Write to the VkPhysicalDeviceProperties2 struct
215
0
        icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &pProperties->properties);
216
217
0
        void *pNext = pProperties->pNext;
218
0
        while (pNext != NULL) {
219
0
            VkBaseOutStructure pNext_in_structure = {0};
220
0
            memcpy(&pNext_in_structure, pNext, sizeof(VkBaseOutStructure));
221
0
            switch (pNext_in_structure.sType) {
222
0
                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
223
0
                    VkPhysicalDeviceIDPropertiesKHR *id_properties = (VkPhysicalDeviceIDPropertiesKHR *)pNext;
224
225
                    // Verify that "VK_KHR_external_memory_capabilities" is enabled
226
0
                    if (icd_term->this_instance->enabled_extensions.khr_external_memory_capabilities) {
227
0
                        loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
228
0
                                   "vkGetPhysicalDeviceProperties2: Emulation cannot generate unique IDs for struct "
229
0
                                   "VkPhysicalDeviceIDProperties - setting IDs to zero instead");
230
231
                        // Write to the VkPhysicalDeviceIDPropertiesKHR struct
232
0
                        memset(id_properties->deviceUUID, 0, VK_UUID_SIZE);
233
0
                        memset(id_properties->driverUUID, 0, VK_UUID_SIZE);
234
0
                        id_properties->deviceLUIDValid = VK_FALSE;
235
0
                    }
236
237
0
                    pNext = id_properties->pNext;
238
0
                    break;
239
0
                }
240
0
                default: {
241
0
                    loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
242
0
                               "vkGetPhysicalDeviceProperties2KHR: Emulation found unrecognized structure type in "
243
0
                               "pProperties->pNext - this struct will be ignored");
244
245
0
                    pNext = pNext_in_structure.pNext;
246
0
                    break;
247
0
                }
248
0
            }
249
0
        }
250
0
    }
251
0
}
252
253
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
254
0
                                                                         VkFormatProperties2 *pFormatProperties) {
255
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
256
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
257
0
    const struct loader_instance *inst = icd_term->this_instance;
258
259
0
    assert(inst != NULL);
260
261
    // Get the function pointer to use to call into the ICD. This could be the core or KHR version
262
0
    PFN_vkGetPhysicalDeviceFormatProperties2 fpGetPhysicalDeviceFormatProperties2 = NULL;
263
0
    if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
264
0
        fpGetPhysicalDeviceFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceFormatProperties2;
265
0
    }
266
0
    if (fpGetPhysicalDeviceFormatProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
267
0
        fpGetPhysicalDeviceFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR;
268
0
    }
269
270
0
    if (fpGetPhysicalDeviceFormatProperties2 != NULL) {
271
        // Pass the call to the driver
272
0
        fpGetPhysicalDeviceFormatProperties2(phys_dev_term->phys_dev, format, pFormatProperties);
273
0
    } else {
274
        // Emulate the call
275
0
        loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
276
0
                   "vkGetPhysicalDeviceFormatProperties2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFormatProperties",
277
0
                   icd_term->scanned_icd->lib_name);
278
279
        // Write to the VkFormatProperties2 struct
280
0
        icd_term->dispatch.GetPhysicalDeviceFormatProperties(phys_dev_term->phys_dev, format, &pFormatProperties->formatProperties);
281
282
0
        if (pFormatProperties->pNext != NULL) {
283
0
            loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
284
0
                       "vkGetPhysicalDeviceFormatProperties2: Emulation found unrecognized structure type in "
285
0
                       "pFormatProperties->pNext - this struct will be ignored");
286
0
        }
287
0
    }
288
0
}
289
290
VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties2(
291
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
292
0
    VkImageFormatProperties2 *pImageFormatProperties) {
293
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
294
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
295
0
    const struct loader_instance *inst = icd_term->this_instance;
296
297
0
    assert(inst != NULL);
298
299
    // Get the function pointer to use to call into the ICD. This could be the core or KHR version
300
0
    PFN_vkGetPhysicalDeviceImageFormatProperties2 fpGetPhysicalDeviceImageFormatProperties2 = NULL;
301
0
    if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
302
0
        fpGetPhysicalDeviceImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2;
303
0
    }
304
0
    if (fpGetPhysicalDeviceImageFormatProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
305
0
        fpGetPhysicalDeviceImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR;
306
0
    }
307
308
0
    if (fpGetPhysicalDeviceImageFormatProperties2 != NULL) {
309
        // Pass the call to the driver
310
0
        return fpGetPhysicalDeviceImageFormatProperties2(phys_dev_term->phys_dev, pImageFormatInfo, pImageFormatProperties);
311
0
    } else {
312
        // Emulate the call
313
0
        loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
314
0
                   "vkGetPhysicalDeviceImageFormatProperties2: Emulating call in ICD \"%s\" using "
315
0
                   "vkGetPhysicalDeviceImageFormatProperties",
316
0
                   icd_term->scanned_icd->lib_name);
317
318
        // If there is more info in  either pNext, then this is unsupported
319
0
        if (pImageFormatInfo->pNext != NULL || pImageFormatProperties->pNext != NULL) {
320
0
            return VK_ERROR_FORMAT_NOT_SUPPORTED;
321
0
        }
322
323
        // Write to the VkImageFormatProperties2KHR struct
324
0
        return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(
325
0
            phys_dev_term->phys_dev, pImageFormatInfo->format, pImageFormatInfo->type, pImageFormatInfo->tiling,
326
0
            pImageFormatInfo->usage, pImageFormatInfo->flags, &pImageFormatProperties->imageFormatProperties);
327
0
    }
328
0
}
329
330
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
331
                                                                              uint32_t *pQueueFamilyPropertyCount,
332
0
                                                                              VkQueueFamilyProperties2 *pQueueFamilyProperties) {
333
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
334
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
335
0
    const struct loader_instance *inst = icd_term->this_instance;
336
337
0
    assert(inst != NULL);
338
339
    // Get the function pointer to use to call into the ICD. This could be the core or KHR version
340
0
    PFN_vkGetPhysicalDeviceQueueFamilyProperties2 fpGetPhysicalDeviceQueueFamilyProperties2 = NULL;
341
0
    if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
342
0
        fpGetPhysicalDeviceQueueFamilyProperties2 = icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2;
343
0
    }
344
0
    if (fpGetPhysicalDeviceQueueFamilyProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
345
0
        fpGetPhysicalDeviceQueueFamilyProperties2 = icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR;
346
0
    }
347
348
0
    if (fpGetPhysicalDeviceQueueFamilyProperties2 != NULL) {
349
        // Pass the call to the driver
350
0
        fpGetPhysicalDeviceQueueFamilyProperties2(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
351
0
    } else {
352
        // Emulate the call
353
0
        loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
354
0
                   "vkGetPhysicalDeviceQueueFamilyProperties2: Emulating call in ICD \"%s\" using "
355
0
                   "vkGetPhysicalDeviceQueueFamilyProperties",
356
0
                   icd_term->scanned_icd->lib_name);
357
358
0
        if (pQueueFamilyProperties == NULL || *pQueueFamilyPropertyCount == 0) {
359
            // Write to pQueueFamilyPropertyCount
360
0
            icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, NULL);
361
0
        } else {
362
            // Allocate a temporary array for the output of the old function
363
0
            VkQueueFamilyProperties *properties = loader_stack_alloc(*pQueueFamilyPropertyCount * sizeof(VkQueueFamilyProperties));
364
0
            if (properties == NULL) {
365
0
                *pQueueFamilyPropertyCount = 0;
366
0
                loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
367
0
                           "vkGetPhysicalDeviceQueueFamilyProperties2: Out of memory - Failed to allocate array for loader "
368
0
                           "emulation.");
369
0
                return;
370
0
            }
371
372
0
            icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount,
373
0
                                                                      properties);
374
0
            for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) {
375
                // Write to the VkQueueFamilyProperties2KHR struct
376
0
                memcpy(&pQueueFamilyProperties[i].queueFamilyProperties, &properties[i], sizeof(VkQueueFamilyProperties));
377
378
0
                if (pQueueFamilyProperties[i].pNext != NULL) {
379
0
                    loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
380
0
                               "vkGetPhysicalDeviceQueueFamilyProperties2: Emulation found unrecognized structure type in "
381
0
                               "pQueueFamilyProperties[%d].pNext - this struct will be ignored",
382
0
                               i);
383
0
                }
384
0
            }
385
0
        }
386
0
    }
387
0
}
388
389
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,
390
0
                                                                         VkPhysicalDeviceMemoryProperties2 *pMemoryProperties) {
391
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
392
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
393
0
    const struct loader_instance *inst = icd_term->this_instance;
394
395
0
    assert(inst != NULL);
396
397
    // Get the function pointer to use to call into the ICD. This could be the core or KHR version
398
0
    PFN_vkGetPhysicalDeviceMemoryProperties2 fpGetPhysicalDeviceMemoryProperties2 = NULL;
399
0
    if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
400
0
        fpGetPhysicalDeviceMemoryProperties2 = icd_term->dispatch.GetPhysicalDeviceMemoryProperties2;
401
0
    }
402
0
    if (fpGetPhysicalDeviceMemoryProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
403
0
        fpGetPhysicalDeviceMemoryProperties2 = icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR;
404
0
    }
405
406
0
    if (fpGetPhysicalDeviceMemoryProperties2 != NULL) {
407
        // Pass the call to the driver
408
0
        fpGetPhysicalDeviceMemoryProperties2(phys_dev_term->phys_dev, pMemoryProperties);
409
0
    } else {
410
        // Emulate the call
411
0
        loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
412
0
                   "vkGetPhysicalDeviceMemoryProperties2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceMemoryProperties",
413
0
                   icd_term->scanned_icd->lib_name);
414
415
        // Write to the VkPhysicalDeviceMemoryProperties2 struct
416
0
        icd_term->dispatch.GetPhysicalDeviceMemoryProperties(phys_dev_term->phys_dev, &pMemoryProperties->memoryProperties);
417
418
0
        if (pMemoryProperties->pNext != NULL) {
419
0
            loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
420
0
                       "vkGetPhysicalDeviceMemoryProperties2: Emulation found unrecognized structure type in "
421
0
                       "pMemoryProperties->pNext - this struct will be ignored");
422
0
        }
423
0
    }
424
0
}
425
426
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties2(
427
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount,
428
0
    VkSparseImageFormatProperties2KHR *pProperties) {
429
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
430
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
431
0
    const struct loader_instance *inst = icd_term->this_instance;
432
433
0
    assert(inst != NULL);
434
435
    // Get the function pointer to use to call into the ICD. This could be the core or KHR version
436
0
    PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 fpGetPhysicalDeviceSparseImageFormatProperties2 = NULL;
437
0
    if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
438
0
        fpGetPhysicalDeviceSparseImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2;
439
0
    }
440
0
    if (fpGetPhysicalDeviceSparseImageFormatProperties2 == NULL && inst->enabled_extensions.khr_get_physical_device_properties2) {
441
0
        fpGetPhysicalDeviceSparseImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR;
442
0
    }
443
444
0
    if (fpGetPhysicalDeviceSparseImageFormatProperties2 != NULL) {
445
        // Pass the call to the driver
446
0
        fpGetPhysicalDeviceSparseImageFormatProperties2(phys_dev_term->phys_dev, pFormatInfo, pPropertyCount, pProperties);
447
0
    } else {
448
        // Emulate the call
449
0
        loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
450
0
                   "vkGetPhysicalDeviceSparseImageFormatProperties2: Emulating call in ICD \"%s\" using "
451
0
                   "vkGetPhysicalDeviceSparseImageFormatProperties",
452
0
                   icd_term->scanned_icd->lib_name);
453
454
0
        if (pFormatInfo->pNext != NULL) {
455
0
            loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
456
0
                       "vkGetPhysicalDeviceSparseImageFormatProperties2: Emulation found unrecognized structure type in "
457
0
                       "pFormatInfo->pNext - this struct will be ignored");
458
0
        }
459
460
0
        if (pProperties == NULL || *pPropertyCount == 0) {
461
            // Write to pPropertyCount
462
0
            icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(
463
0
                phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage,
464
0
                pFormatInfo->tiling, pPropertyCount, NULL);
465
0
        } else {
466
            // Allocate a temporary array for the output of the old function
467
0
            VkSparseImageFormatProperties *properties =
468
0
                loader_stack_alloc(*pPropertyCount * sizeof(VkSparseImageMemoryRequirements));
469
0
            if (properties == NULL) {
470
0
                *pPropertyCount = 0;
471
0
                loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
472
0
                           "vkGetPhysicalDeviceSparseImageFormatProperties2: Out of memory - Failed to allocate array for "
473
0
                           "loader emulation.");
474
0
                return;
475
0
            }
476
477
0
            icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(
478
0
                phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage,
479
0
                pFormatInfo->tiling, pPropertyCount, properties);
480
0
            for (uint32_t i = 0; i < *pPropertyCount; ++i) {
481
                // Write to the VkSparseImageFormatProperties2KHR struct
482
0
                memcpy(&pProperties[i].properties, &properties[i], sizeof(VkSparseImageFormatProperties));
483
484
0
                if (pProperties[i].pNext != NULL) {
485
0
                    loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
486
0
                               "vkGetPhysicalDeviceSparseImageFormatProperties2: Emulation found unrecognized structure type in "
487
0
                               "pProperties[%d].pNext - this struct will be ignored",
488
0
                               i);
489
0
                }
490
0
            }
491
0
        }
492
0
    }
493
0
}
494
495
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalBufferProperties(
496
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
497
0
    VkExternalBufferProperties *pExternalBufferProperties) {
498
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
499
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
500
0
    const struct loader_instance *inst = icd_term->this_instance;
501
502
0
    assert(inst != NULL);
503
504
    // Get the function pointer to use to call into the ICD. This could be the core or KHR version
505
0
    PFN_vkGetPhysicalDeviceExternalBufferProperties fpGetPhysicalDeviceExternalBufferProperties = NULL;
506
0
    if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
507
0
        fpGetPhysicalDeviceExternalBufferProperties = icd_term->dispatch.GetPhysicalDeviceExternalBufferProperties;
508
0
    }
509
0
    if (fpGetPhysicalDeviceExternalBufferProperties == NULL && inst->enabled_extensions.khr_external_memory_capabilities) {
510
0
        fpGetPhysicalDeviceExternalBufferProperties = icd_term->dispatch.GetPhysicalDeviceExternalBufferPropertiesKHR;
511
0
    }
512
513
0
    if (fpGetPhysicalDeviceExternalBufferProperties != NULL) {
514
        // Pass the call to the driver
515
0
        fpGetPhysicalDeviceExternalBufferProperties(phys_dev_term->phys_dev, pExternalBufferInfo, pExternalBufferProperties);
516
0
    } else {
517
        // Emulate the call
518
0
        loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
519
0
                   "vkGetPhysicalDeviceExternalBufferProperties: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
520
521
0
        if (pExternalBufferInfo->pNext != NULL) {
522
0
            loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
523
0
                       "vkGetPhysicalDeviceExternalBufferProperties: Emulation found unrecognized structure type in "
524
0
                       "pExternalBufferInfo->pNext - this struct will be ignored");
525
0
        }
526
527
        // Fill in everything being unsupported
528
0
        memset(&pExternalBufferProperties->externalMemoryProperties, 0, sizeof(VkExternalMemoryPropertiesKHR));
529
530
0
        if (pExternalBufferProperties->pNext != NULL) {
531
0
            loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
532
0
                       "vkGetPhysicalDeviceExternalBufferProperties: Emulation found unrecognized structure type in "
533
0
                       "pExternalBufferProperties->pNext - this struct will be ignored");
534
0
        }
535
0
    }
536
0
}
537
538
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalSemaphoreProperties(
539
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,
540
0
    VkExternalSemaphoreProperties *pExternalSemaphoreProperties) {
541
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
542
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
543
0
    const struct loader_instance *inst = icd_term->this_instance;
544
545
0
    assert(inst != NULL);
546
547
    // Get the function pointer to use to call into the ICD. This could be the core or KHR version
548
0
    PFN_vkGetPhysicalDeviceExternalSemaphoreProperties fpGetPhysicalDeviceExternalSemaphoreProperties = NULL;
549
0
    if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
550
0
        fpGetPhysicalDeviceExternalSemaphoreProperties = icd_term->dispatch.GetPhysicalDeviceExternalSemaphoreProperties;
551
0
    }
552
0
    if (fpGetPhysicalDeviceExternalSemaphoreProperties == NULL && inst->enabled_extensions.khr_external_semaphore_capabilities) {
553
0
        fpGetPhysicalDeviceExternalSemaphoreProperties = icd_term->dispatch.GetPhysicalDeviceExternalSemaphorePropertiesKHR;
554
0
    }
555
556
0
    if (fpGetPhysicalDeviceExternalSemaphoreProperties != NULL) {
557
        // Pass the call to the driver
558
0
        fpGetPhysicalDeviceExternalSemaphoreProperties(phys_dev_term->phys_dev, pExternalSemaphoreInfo,
559
0
                                                       pExternalSemaphoreProperties);
560
0
    } else {
561
        // Emulate the call
562
0
        loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
563
0
                   "vkGetPhysicalDeviceExternalSemaphoreProperties: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
564
565
0
        if (pExternalSemaphoreInfo->pNext != NULL) {
566
0
            loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
567
0
                       "vkGetPhysicalDeviceExternalSemaphoreProperties: Emulation found unrecognized structure type in "
568
0
                       "pExternalSemaphoreInfo->pNext - this struct will be ignored");
569
0
        }
570
571
        // Fill in everything being unsupported
572
0
        pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
573
0
        pExternalSemaphoreProperties->compatibleHandleTypes = 0;
574
0
        pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
575
576
0
        if (pExternalSemaphoreProperties->pNext != NULL) {
577
0
            loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
578
0
                       "vkGetPhysicalDeviceExternalSemaphoreProperties: Emulation found unrecognized structure type in "
579
0
                       "pExternalSemaphoreProperties->pNext - this struct will be ignored");
580
0
        }
581
0
    }
582
0
}
583
584
VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalFenceProperties(
585
    VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
586
0
    VkExternalFenceProperties *pExternalFenceProperties) {
587
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
588
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
589
0
    const struct loader_instance *inst = icd_term->this_instance;
590
591
0
    assert(inst != NULL);
592
593
    // Get the function pointer to use to call into the ICD. This could be the core or KHR version
594
0
    PFN_vkGetPhysicalDeviceExternalFenceProperties fpGetPhysicalDeviceExternalFenceProperties = NULL;
595
0
    if (loader_check_version_meets_required(LOADER_VERSION_1_1_0, inst->app_api_version)) {
596
0
        fpGetPhysicalDeviceExternalFenceProperties = icd_term->dispatch.GetPhysicalDeviceExternalFenceProperties;
597
0
    }
598
0
    if (fpGetPhysicalDeviceExternalFenceProperties == NULL && inst->enabled_extensions.khr_external_fence_capabilities) {
599
0
        fpGetPhysicalDeviceExternalFenceProperties = icd_term->dispatch.GetPhysicalDeviceExternalFencePropertiesKHR;
600
0
    }
601
602
0
    if (fpGetPhysicalDeviceExternalFenceProperties != NULL) {
603
        // Pass the call to the driver
604
0
        fpGetPhysicalDeviceExternalFenceProperties(phys_dev_term->phys_dev, pExternalFenceInfo, pExternalFenceProperties);
605
0
    } else {
606
        // Emulate the call
607
0
        loader_log(icd_term->this_instance, VULKAN_LOADER_INFO_BIT, 0,
608
0
                   "vkGetPhysicalDeviceExternalFenceProperties: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
609
610
0
        if (pExternalFenceInfo->pNext != NULL) {
611
0
            loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
612
0
                       "vkGetPhysicalDeviceExternalFenceProperties: Emulation found unrecognized structure type in "
613
0
                       "pExternalFenceInfo->pNext - this struct will be ignored");
614
0
        }
615
616
        // Fill in everything being unsupported
617
0
        pExternalFenceProperties->exportFromImportedHandleTypes = 0;
618
0
        pExternalFenceProperties->compatibleHandleTypes = 0;
619
0
        pExternalFenceProperties->externalFenceFeatures = 0;
620
621
0
        if (pExternalFenceProperties->pNext != NULL) {
622
0
            loader_log(icd_term->this_instance, VULKAN_LOADER_WARN_BIT, 0,
623
0
                       "vkGetPhysicalDeviceExternalFenceProperties: Emulation found unrecognized structure type in "
624
0
                       "pExternalFenceProperties->pNext - this struct will be ignored");
625
0
        }
626
0
    }
627
0
}
628
629
// 1.3 Core terminators
630
631
VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceToolProperties(VkPhysicalDevice physicalDevice, uint32_t *pToolCount,
632
0
                                                                          VkPhysicalDeviceToolProperties *pToolProperties) {
633
0
    struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
634
0
    struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
635
636
0
    if (NULL == icd_term->dispatch.GetPhysicalDeviceToolProperties) {
637
0
        loader_log(icd_term->this_instance, VULKAN_LOADER_ERROR_BIT, 0,
638
0
                   "terminator_GetPhysicalDeviceToolProperties: The ICD's vkGetPhysicalDeviceToolProperties was NULL yet "
639
0
                   "the physical device supports Vulkan API Version 1.3.");
640
0
    } else {
641
0
        VkPhysicalDeviceProperties properties;
642
0
        if (icd_term->dispatch.GetPhysicalDeviceProperties) {
643
0
            icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &properties);
644
645
0
            if (VK_API_VERSION_MINOR(properties.apiVersion) >= 3) {
646
0
                return icd_term->dispatch.GetPhysicalDeviceToolProperties(phys_dev_term->phys_dev, pToolCount, pToolProperties);
647
0
            }
648
0
        }
649
0
    }
650
651
    // In the case the driver didn't support 1.3, make sure that the first layer doesn't find the count uninitialized
652
0
    *pToolCount = 0;
653
0
    return VK_SUCCESS;
654
0
}