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