Coverage Report

Created: 2026-10-16 06:55

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