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