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