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