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