blob: c08a92a1336113246e5642571f9ffd567eea0e17 [file] [log] [blame]
Mark Young0746fce2017-03-10 17:31:18 -07001/*
2 * Copyright (c) 2015-2017 The Khronos Group Inc.
3 * Copyright (c) 2015-2017 Valve Corporation
4 * Copyright (c) 2015-2017 LunarG, Inc.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Mark Young <marky@lunarg.com>
Lenny Komow99f647e2017-05-23 15:18:21 -060019 * Author: Lenny Komow <lenny@lunarg.com>
Mark Young0746fce2017-03-10 17:31:18 -070020 */
21
22#define _GNU_SOURCE
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include "vk_loader_platform.h"
27#include "loader.h"
28#include "vk_loader_extensions.h"
29#include <vulkan/vk_icd.h>
30#include "wsi.h"
31#include "debug_report.h"
32
33// ---- Manually added trampoline/terminator functions
34
35// These functions, for whatever reason, require more complex changes than
36// can easily be automatically generated.
37VkResult setupLoaderTrampPhysDevGroups(VkInstance instance);
38VkResult setupLoaderTermPhysDevGroups(struct loader_instance *inst);
39
40VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceGroupsKHX(
41 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount,
42 VkPhysicalDeviceGroupPropertiesKHX *pPhysicalDeviceGroupProperties) {
43 VkResult res = VK_SUCCESS;
44 uint32_t count;
45 uint32_t i;
46 struct loader_instance *inst = NULL;
47
48 loader_platform_thread_lock_mutex(&loader_lock);
49
50 inst = loader_get_instance(instance);
51 if (NULL == inst) {
52 res = VK_ERROR_INITIALIZATION_FAILED;
53 goto out;
54 }
55
56 if (NULL == pPhysicalDeviceGroupCount) {
57 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
58 "vkEnumeratePhysicalDeviceGroupsKHX: Received NULL pointer for physical "
59 "device group count return value.");
60 res = VK_ERROR_INITIALIZATION_FAILED;
61 goto out;
62 }
63
64 VkResult setup_res = setupLoaderTrampPhysDevGroups(instance);
65 if (VK_SUCCESS != setup_res) {
66 res = setup_res;
67 goto out;
68 }
69
70 count = inst->phys_dev_group_count_tramp;
71
72 // Wrap the PhysDev object for loader usage, return wrapped objects
73 if (NULL != pPhysicalDeviceGroupProperties) {
74 if (inst->phys_dev_group_count_tramp > *pPhysicalDeviceGroupCount) {
75 loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
76 "vkEnumeratePhysicalDeviceGroupsKHX: Trimming device group count down"
77 " by application request from %d to %d physical device groups",
78 inst->phys_dev_group_count_tramp, *pPhysicalDeviceGroupCount);
79 count = *pPhysicalDeviceGroupCount;
80 res = VK_INCOMPLETE;
81 }
82 for (i = 0; i < count; i++) {
83 memcpy(&pPhysicalDeviceGroupProperties[i], inst->phys_dev_groups_tramp[i],
84 sizeof(VkPhysicalDeviceGroupPropertiesKHX));
85 }
86 }
87
88 *pPhysicalDeviceGroupCount = count;
89
90out:
91
92 loader_platform_thread_unlock_mutex(&loader_lock);
93 return res;
94}
95
96VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroupsKHX(
97 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount,
98 VkPhysicalDeviceGroupPropertiesKHX *pPhysicalDeviceGroupProperties) {
99 struct loader_instance *inst = (struct loader_instance *)instance;
100 VkResult res = VK_SUCCESS;
101
102 // Always call the setup loader terminator physical device groups because they may
103 // have changed at any point.
104 res = setupLoaderTermPhysDevGroups(inst);
105 if (VK_SUCCESS != res) {
106 goto out;
107 }
108
109 uint32_t copy_count = inst->phys_dev_group_count_term;
110 if (NULL != pPhysicalDeviceGroupProperties) {
111 if (copy_count > *pPhysicalDeviceGroupCount) {
112 copy_count = *pPhysicalDeviceGroupCount;
113 res = VK_INCOMPLETE;
114 }
115
116 for (uint32_t i = 0; i < copy_count; i++) {
117 memcpy(&pPhysicalDeviceGroupProperties[i], inst->phys_dev_groups_term[i],
118 sizeof(VkPhysicalDeviceGroupPropertiesKHX));
119 }
120 }
121
122 *pPhysicalDeviceGroupCount = copy_count;
123
124out:
125
126 return res;
127}
128
129VKAPI_ATTR VkResult VKAPI_CALL
130GetPhysicalDeviceExternalImageFormatPropertiesNV(
131 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
132 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
133 VkExternalMemoryHandleTypeFlagsNV externalHandleType,
134 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
135 const VkLayerInstanceDispatchTable *disp;
136 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
137 disp = loader_get_instance_layer_dispatch(physicalDevice);
138
139 return disp->GetPhysicalDeviceExternalImageFormatPropertiesNV(
140 unwrapped_phys_dev, format, type, tiling, usage, flags,
141 externalHandleType, pExternalImageFormatProperties);
142}
143
144VKAPI_ATTR VkResult VKAPI_CALL
145terminator_GetPhysicalDeviceExternalImageFormatPropertiesNV(
146 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
147 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
148 VkExternalMemoryHandleTypeFlagsNV externalHandleType,
149 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
150 struct loader_physical_device_term *phys_dev_term =
151 (struct loader_physical_device_term *)physicalDevice;
152 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
153
154 if (!icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV) {
155 if (externalHandleType) {
156 return VK_ERROR_FORMAT_NOT_SUPPORTED;
157 }
158
159 if (!icd_term->dispatch.GetPhysicalDeviceImageFormatProperties) {
160 return VK_ERROR_INITIALIZATION_FAILED;
161 }
162
163 pExternalImageFormatProperties->externalMemoryFeatures = 0;
164 pExternalImageFormatProperties->exportFromImportedHandleTypes = 0;
165 pExternalImageFormatProperties->compatibleHandleTypes = 0;
166
167 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(
168 phys_dev_term->phys_dev, format, type, tiling, usage, flags,
169 &pExternalImageFormatProperties->imageFormatProperties);
170 }
171
172 return icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV(
173 phys_dev_term->phys_dev, format, type, tiling, usage, flags,
174 externalHandleType, pExternalImageFormatProperties);
175}
176
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600177// ---- VK_KHR_get_physical_device_properties2 extension trampoline/terminators
178
179VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR *pFeatures) {
180 const VkLayerInstanceDispatchTable *disp;
181 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
182 disp = loader_get_instance_layer_dispatch(physicalDevice);
183 disp->GetPhysicalDeviceFeatures2KHR(unwrapped_phys_dev, pFeatures);
184}
185
186VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
187 VkPhysicalDeviceFeatures2KHR *pFeatures) {
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
191 if (icd_term->dispatch.GetPhysicalDeviceFeatures2KHR != NULL) {
Lenny Komow99f647e2017-05-23 15:18:21 -0600192 // Pass the call to the driver
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600193 icd_term->dispatch.GetPhysicalDeviceFeatures2KHR(phys_dev_term->phys_dev, pFeatures);
194 } else {
Lenny Komow99f647e2017-05-23 15:18:21 -0600195 // Emulate the call
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600196 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
Lenny Komowcf30e582017-05-15 13:05:33 -0600197 "vkGetPhysicalDeviceFeatures2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFeatures",
198 icd_term->scanned_icd->lib_name);
Lenny Komow99f647e2017-05-23 15:18:21 -0600199
200 // Write to the VkPhysicalDeviceFeatures2KHR struct
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600201 icd_term->dispatch.GetPhysicalDeviceFeatures(phys_dev_term->phys_dev, &pFeatures->features);
Lenny Komow99f647e2017-05-23 15:18:21 -0600202
203 void *pNext = pFeatures->pNext;
204 while (pNext != NULL) {
205 switch (*(VkStructureType *)pNext) {
206 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHX: {
207 // Skip the check if VK_KHX_multiview is enabled because it's a device extension
208 // Write to the VkPhysicalDeviceMultiviewFeaturesKHX struct
209 VkPhysicalDeviceMultiviewFeaturesKHX *multiview_features = pNext;
210 multiview_features->multiview = VK_FALSE;
211 multiview_features->multiviewGeometryShader = VK_FALSE;
212 multiview_features->multiviewTessellationShader = VK_FALSE;
213
214 pNext = multiview_features->pNext;
215 break;
216 }
217 default: {
218 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
219 "vkGetPhysicalDeviceFeatures2KHR: Emulation found unrecognized structure type in pFeatures->pNext - "
220 "this struct will be ignored");
221
222 struct VkStructureHeader *header = pNext;
223 pNext = (void *)header->pNext;
224 break;
225 }
226 }
227 }
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600228 }
229}
230
231VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice,
232 VkPhysicalDeviceProperties2KHR *pProperties) {
233 const VkLayerInstanceDispatchTable *disp;
234 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
235 disp = loader_get_instance_layer_dispatch(physicalDevice);
236 disp->GetPhysicalDeviceProperties2KHR(unwrapped_phys_dev, pProperties);
237}
238
239VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice,
240 VkPhysicalDeviceProperties2KHR *pProperties) {
241 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
242 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
243
244 if (icd_term->dispatch.GetPhysicalDeviceProperties2KHR != NULL) {
Lenny Komow99f647e2017-05-23 15:18:21 -0600245 // Pass the call to the driver
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600246 icd_term->dispatch.GetPhysicalDeviceProperties2KHR(phys_dev_term->phys_dev, pProperties);
247 } else {
Lenny Komow99f647e2017-05-23 15:18:21 -0600248 // Emulate the call
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600249 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
Lenny Komowcf30e582017-05-15 13:05:33 -0600250 "vkGetPhysicalDeviceProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceProperties",
251 icd_term->scanned_icd->lib_name);
Lenny Komow99f647e2017-05-23 15:18:21 -0600252
253 // Write to the VkPhysicalDeviceProperties2KHR struct
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600254 icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &pProperties->properties);
Lenny Komow99f647e2017-05-23 15:18:21 -0600255
256 void *pNext = pProperties->pNext;
257 while (pNext != NULL) {
258 switch (*(VkStructureType *)pNext) {
259 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHX: {
260 VkPhysicalDeviceIDPropertiesKHX *id_properties = pNext;
261
262 // Verify that "VK_KHX_external_memory_capabilities" is enabled
263 if (icd_term->this_instance->enabled_known_extensions.khx_external_memory_capabilities) {
264 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
265 "vkGetPhysicalDeviceProperties2KHR: Emulation cannot generate unique IDs for struct "
266 "VkPhysicalDeviceIDPropertiesKHX - setting IDs to zero instead");
267
268 // Write to the VkPhysicalDeviceIDPropertiesKHX struct
269 memset(id_properties->deviceUUID, 0, VK_UUID_SIZE);
270 memset(id_properties->driverUUID, 0, VK_UUID_SIZE);
271 id_properties->deviceLUIDValid = VK_FALSE;
272 }
273
274 pNext = id_properties->pNext;
275 break;
276 }
277 default: {
278 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
279 "vkGetPhysicalDeviceProperties2KHR: Emulation found unrecognized structure type in "
280 "pProperties->pNext - this struct will be ignored");
281
282 struct VkStructureHeader *header = pNext;
283 pNext = (void *)header->pNext;
284 break;
285 }
286 }
287 }
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600288 }
289}
290
291VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format,
292 VkFormatProperties2KHR *pFormatProperties) {
293 const VkLayerInstanceDispatchTable *disp;
294 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
295 disp = loader_get_instance_layer_dispatch(physicalDevice);
296 disp->GetPhysicalDeviceFormatProperties2KHR(unwrapped_phys_dev, format, pFormatProperties);
297}
298
299VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format,
300 VkFormatProperties2KHR *pFormatProperties) {
301 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
302 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
303
304 if (icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR != NULL) {
Lenny Komow99f647e2017-05-23 15:18:21 -0600305 // Pass the call to the driver
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600306 icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR(phys_dev_term->phys_dev, format, pFormatProperties);
307 } else {
Lenny Komow99f647e2017-05-23 15:18:21 -0600308 // Emulate the call
Lenny Komowcf30e582017-05-15 13:05:33 -0600309 loader_log(
310 icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
311 "vkGetPhysicalDeviceFormatProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFormatProperties",
312 icd_term->scanned_icd->lib_name);
Lenny Komow99f647e2017-05-23 15:18:21 -0600313
314 // Write to the VkFormatProperties2KHR struct
315 icd_term->dispatch.GetPhysicalDeviceFormatProperties(phys_dev_term->phys_dev, format, &pFormatProperties->formatProperties);
316
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600317 if (pFormatProperties->pNext != NULL) {
318 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
Lenny Komow99f647e2017-05-23 15:18:21 -0600319 "vkGetPhysicalDeviceFormatProperties2KHR: Emulation found unrecognized structure type in "
320 "pFormatProperties->pNext - this struct will be ignored");
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600321 }
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600322 }
323}
324
325VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties2KHR(
326 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
327 VkImageFormatProperties2KHR *pImageFormatProperties) {
328 const VkLayerInstanceDispatchTable *disp;
329 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
330 disp = loader_get_instance_layer_dispatch(physicalDevice);
331 return disp->GetPhysicalDeviceImageFormatProperties2KHR(unwrapped_phys_dev, pImageFormatInfo, pImageFormatProperties);
332}
333
334VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties2KHR(
335 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
336 VkImageFormatProperties2KHR *pImageFormatProperties) {
337 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
338 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
339
340 if (icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR != NULL) {
Lenny Komow99f647e2017-05-23 15:18:21 -0600341 // Pass the call to the driver
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600342 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR(phys_dev_term->phys_dev, pImageFormatInfo,
343 pImageFormatProperties);
344 } else {
Lenny Komow99f647e2017-05-23 15:18:21 -0600345 // Emulate the call
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600346 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
Lenny Komowcf30e582017-05-15 13:05:33 -0600347 "vkGetPhysicalDeviceImageFormatProperties2KHR: Emulating call in ICD \"%s\" using "
348 "vkGetPhysicalDeviceImageFormatProperties",
349 icd_term->scanned_icd->lib_name);
Lenny Komow99f647e2017-05-23 15:18:21 -0600350
351 // If there is more info in either pNext, then this is unsupported
352 if (pImageFormatInfo->pNext != NULL || pImageFormatProperties->pNext != NULL) {
353 return VK_ERROR_FORMAT_NOT_SUPPORTED;
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600354 }
Lenny Komow99f647e2017-05-23 15:18:21 -0600355
356 // Write to the VkImageFormatProperties2KHR struct
357 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600358 phys_dev_term->phys_dev, pImageFormatInfo->format, pImageFormatInfo->type, pImageFormatInfo->tiling,
359 pImageFormatInfo->usage, pImageFormatInfo->flags, &pImageFormatProperties->imageFormatProperties);
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600360 }
361}
362
363VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
364 uint32_t *pQueueFamilyPropertyCount,
365 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
366 const VkLayerInstanceDispatchTable *disp;
367 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
368 disp = loader_get_instance_layer_dispatch(physicalDevice);
369 disp->GetPhysicalDeviceQueueFamilyProperties2KHR(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
370}
371
372VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties2KHR(
373 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
374 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
375 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
376
377 if (icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR != NULL) {
Lenny Komow99f647e2017-05-23 15:18:21 -0600378 // Pass the call to the driver
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600379 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR(phys_dev_term->phys_dev, pQueueFamilyPropertyCount,
380 pQueueFamilyProperties);
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600381 } else {
Lenny Komow99f647e2017-05-23 15:18:21 -0600382 // Emulate the call
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600383 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
Lenny Komowcf30e582017-05-15 13:05:33 -0600384 "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Emulating call in ICD \"%s\" using "
385 "vkGetPhysicalDeviceQueueFamilyProperties",
386 icd_term->scanned_icd->lib_name);
Lenny Komow99f647e2017-05-23 15:18:21 -0600387
388 if (pQueueFamilyProperties == NULL || *pQueueFamilyPropertyCount == 0) {
389 // Write to pQueueFamilyPropertyCount
390 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, NULL);
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600391 } else {
Lenny Komow99f647e2017-05-23 15:18:21 -0600392 // Allocate a temporary array for the output of the old function
393 VkQueueFamilyProperties *properties = loader_stack_alloc(*pQueueFamilyPropertyCount * sizeof(VkQueueFamilyProperties));
394 if (properties == NULL) {
395 *pQueueFamilyPropertyCount = 0;
396 loader_log(
397 icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
398 "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Out of memory - Failed to allocate array for loader emulation.");
399 return;
400 }
401
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600402 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount,
403 properties);
404 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) {
Lenny Komow99f647e2017-05-23 15:18:21 -0600405 // Write to the VkQueueFamilyProperties2KHR struct
406 memcpy(&pQueueFamilyProperties[i].queueFamilyProperties, &properties[i], sizeof(VkQueueFamilyProperties));
407
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600408 if (pQueueFamilyProperties[i].pNext != NULL) {
409 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
Lenny Komow99f647e2017-05-23 15:18:21 -0600410 "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Emulation found unrecognized structure type in "
Lenny Komow3d31f062017-05-30 13:04:46 -0600411 "pQueueFamilyProperties[%d].pNext - this struct will be ignored",
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600412 i);
413 }
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600414 }
415 }
416 }
417}
418
419VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties2KHR(VkPhysicalDevice physicalDevice,
420 VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties) {
421 const VkLayerInstanceDispatchTable *disp;
422 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
423 disp = loader_get_instance_layer_dispatch(physicalDevice);
424 disp->GetPhysicalDeviceMemoryProperties2KHR(unwrapped_phys_dev, pMemoryProperties);
425}
426
427VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties2KHR(
428 VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties) {
429 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
430 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
431
432 if (icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR != NULL) {
Lenny Komow99f647e2017-05-23 15:18:21 -0600433 // Pass the call to the driver
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600434 icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR(phys_dev_term->phys_dev, pMemoryProperties);
435 } else {
Lenny Komow99f647e2017-05-23 15:18:21 -0600436 // Emulate the call
Lenny Komowcf30e582017-05-15 13:05:33 -0600437 loader_log(
438 icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
439 "vkGetPhysicalDeviceMemoryProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceMemoryProperties",
440 icd_term->scanned_icd->lib_name);
Lenny Komow99f647e2017-05-23 15:18:21 -0600441
442 // Write to the VkPhysicalDeviceMemoryProperties2KHR struct
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600443 icd_term->dispatch.GetPhysicalDeviceMemoryProperties(phys_dev_term->phys_dev, &pMemoryProperties->memoryProperties);
Lenny Komow99f647e2017-05-23 15:18:21 -0600444
445 if (pMemoryProperties->pNext != NULL) {
446 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
447 "vkGetPhysicalDeviceMemoryProperties2KHR: Emulation found unrecognized structure type in "
448 "pMemoryProperties->pNext - this struct will be ignored");
449 }
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600450 }
451}
452
453VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties2KHR(
454 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount,
455 VkSparseImageFormatProperties2KHR *pProperties) {
456 const VkLayerInstanceDispatchTable *disp;
457 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
458 disp = loader_get_instance_layer_dispatch(physicalDevice);
459 disp->GetPhysicalDeviceSparseImageFormatProperties2KHR(unwrapped_phys_dev, pFormatInfo, pPropertyCount, pProperties);
460}
461
462VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties2KHR(
463 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount,
464 VkSparseImageFormatProperties2KHR *pProperties) {
465 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
466 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
467
468 if (icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR != NULL) {
Lenny Komow99f647e2017-05-23 15:18:21 -0600469 // Pass the call to the driver
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600470 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR(phys_dev_term->phys_dev, pFormatInfo, pPropertyCount,
471 pProperties);
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600472 } else {
Lenny Komow99f647e2017-05-23 15:18:21 -0600473 // Emulate the call
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600474 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
Lenny Komowcf30e582017-05-15 13:05:33 -0600475 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulating call in ICD \"%s\" using "
476 "vkGetPhysicalDeviceSparseImageFormatProperties",
477 icd_term->scanned_icd->lib_name);
Lenny Komow99f647e2017-05-23 15:18:21 -0600478
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600479 if (pFormatInfo->pNext != NULL) {
480 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
Lenny Komow99f647e2017-05-23 15:18:21 -0600481 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulation found unrecognized structure type in "
482 "pFormatInfo->pNext - this struct will be ignored");
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600483 }
Lenny Komow99f647e2017-05-23 15:18:21 -0600484
485 if (pProperties == NULL || *pPropertyCount == 0) {
486 // Write to pPropertyCount
487 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(
488 phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage,
489 pFormatInfo->tiling, pPropertyCount, NULL);
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600490 } else {
Lenny Komow99f647e2017-05-23 15:18:21 -0600491 // Allocate a temporary array for the output of the old function
492 VkSparseImageFormatProperties *properties =
493 loader_stack_alloc(*pPropertyCount * sizeof(VkSparseImageMemoryRequirements));
494 if (properties == NULL) {
495 *pPropertyCount = 0;
496 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
497 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Out of memory - Failed to allocate array for "
498 "loader emulation.");
499 return;
500 }
501
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600502 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(
503 phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage,
504 pFormatInfo->tiling, pPropertyCount, properties);
505 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Lenny Komow99f647e2017-05-23 15:18:21 -0600506 // Write to the VkSparseImageFormatProperties2KHR struct
507 memcpy(&pProperties[i].properties, &properties[i], sizeof(VkSparseImageFormatProperties));
508
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600509 if (pProperties[i].pNext != NULL) {
510 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
Lenny Komow99f647e2017-05-23 15:18:21 -0600511 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulation found unrecognized structure type in "
Lenny Komow3d31f062017-05-30 13:04:46 -0600512 "pProperties[%d].pNext - this struct will be ignored",
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600513 i);
514 }
Lenny Komow4b5cfec2017-05-10 10:06:13 -0600515 }
516 }
517 }
518}
Mark Young0746fce2017-03-10 17:31:18 -0700519
Lenny Komow3d31f062017-05-30 13:04:46 -0600520// ---- VK_KHR_get_surface_capabilities2 extension trampoline/terminators
521
522VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
523 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
524 VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
525 const VkLayerInstanceDispatchTable *disp;
526 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
527 disp = loader_get_instance_layer_dispatch(physicalDevice);
528 return disp->GetPhysicalDeviceSurfaceCapabilities2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceCapabilities);
529}
530
531VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2KHR(
532 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
533 VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
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
537 VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
538 uint8_t icd_index = phys_dev_term->icd_index;
539
540 if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) {
541 // Pass the call to the driver, possibly unwrapping the ICD surface
542 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
543 VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
544 info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
545 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy,
546 pSurfaceCapabilities);
547 } else {
548 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
549 pSurfaceCapabilities);
550 }
551 } else {
552 // Emulate the call
553 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
554 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulating call in ICD \"%s\" using "
555 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
556 icd_term->scanned_icd->lib_name);
557
558 if (pSurfaceInfo->pNext != NULL) {
559 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
560 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
561 "pSurfaceInfo->pNext - this struct will be ignored");
562 }
563
564 // Write to the VkSurfaceCapabilities2KHR struct
565 VkSurfaceKHR surface = pSurfaceInfo->surface;
566 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
567 surface = icd_surface->real_icd_surfaces[icd_index];
568 }
569 VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface,
570 &pSurfaceCapabilities->surfaceCapabilities);
571
572 if (pSurfaceCapabilities->pNext != NULL) {
573 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
574 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
575 "pSurfaceCapabilities->pNext - this struct will be ignored");
576 }
577 return res;
578 }
579}
580
581VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
582 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
583 uint32_t *pSurfaceFormatCount,
584 VkSurfaceFormat2KHR *pSurfaceFormats) {
585 const VkLayerInstanceDispatchTable *disp;
586 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
587 disp = loader_get_instance_layer_dispatch(physicalDevice);
588 return disp->GetPhysicalDeviceSurfaceFormats2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats);
589}
590
591VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
592 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
593 uint32_t *pSurfaceFormatCount,
594 VkSurfaceFormat2KHR *pSurfaceFormats) {
595 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
596 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
597
598 VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
599 uint8_t icd_index = phys_dev_term->icd_index;
600
601 if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) {
602 // Pass the call to the driver, possibly unwrapping the ICD surface
603 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
604 VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
605 info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
606 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount,
607 pSurfaceFormats);
608 } else {
609 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
610 pSurfaceFormatCount, pSurfaceFormats);
611 }
612 } else {
613 // Emulate the call
614 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
615 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceSurfaceFormatsKHR",
616 icd_term->scanned_icd->lib_name);
617
618 if (pSurfaceInfo->pNext != NULL) {
619 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
620 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in pSurfaceInfo->pNext "
621 "- this struct will be ignored");
622 }
623
624 VkSurfaceKHR surface = pSurfaceInfo->surface;
625 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
626 surface = icd_surface->real_icd_surfaces[icd_index];
627 }
628
629 if (*pSurfaceFormatCount == 0 || pSurfaceFormats == NULL) {
630 // Write to pSurfaceFormatCount
631 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
632 NULL);
633 } else {
634 // Allocate a temporary array for the output of the old function
635 VkSurfaceFormatKHR *formats = loader_stack_alloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
636 if (formats == NULL) {
637 return VK_ERROR_OUT_OF_HOST_MEMORY;
638 }
639
640 VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface,
641 pSurfaceFormatCount, formats);
642 for (uint32_t i = 0; i < *pSurfaceFormatCount; ++i) {
643 pSurfaceFormats[i].surfaceFormat = formats[i];
644 if (pSurfaceFormats[i].pNext != NULL) {
645 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
646 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in "
647 "pSurfaceFormats[%d].pNext - this struct will be ignored",
648 i);
649 }
650 }
651 return res;
652 }
653 }
654}
655
656// ---- Helper functions
657
Mark Young0746fce2017-03-10 17:31:18 -0700658VkResult setupLoaderTrampPhysDevGroups(VkInstance instance) {
659 VkResult res = VK_SUCCESS;
660 struct loader_instance *inst;
661 uint32_t total_count = 0;
662 VkPhysicalDeviceGroupPropertiesKHX **new_phys_dev_groups = NULL;
663 VkPhysicalDeviceGroupPropertiesKHX *local_phys_dev_groups = NULL;
664
665 inst = loader_get_instance(instance);
666 if (NULL == inst) {
667 res = VK_ERROR_INITIALIZATION_FAILED;
668 goto out;
669 }
670
671 // Setup the trampoline loader physical devices. This will actually
672 // call down and setup the terminator loader physical devices during the
673 // process.
674 VkResult setup_res = setupLoaderTrampPhysDevs(instance);
675 if (setup_res != VK_SUCCESS && setup_res != VK_INCOMPLETE) {
676 res = setup_res;
677 goto out;
678 }
679
680 // Query how many physical device groups there
681 res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroupsKHX(instance, &total_count, NULL);
682 if (res != VK_SUCCESS) {
683 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
684 "setupLoaderTrampPhysDevGroups: Failed during dispatch call of "
685 "\'EnumeratePhysicalDeviceGroupsKHX\' to lower layers or "
686 "loader to get count.");
687 goto out;
688 }
689
690 // Create an array for the new physical device groups, which will be stored
691 // in the instance for the trampoline code.
692 new_phys_dev_groups = (VkPhysicalDeviceGroupPropertiesKHX **)loader_instance_heap_alloc(
693 inst, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
694 if (NULL == new_phys_dev_groups) {
695 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
696 "setupLoaderTrampPhysDevGroups: Failed to allocate new physical device"
697 " group array of size %d",
698 total_count);
699 res = VK_ERROR_OUT_OF_HOST_MEMORY;
700 goto out;
701 }
702 memset(new_phys_dev_groups, 0, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *));
703
704 // Create a temporary array (on the stack) to keep track of the
705 // returned VkPhysicalDevice values.
706 local_phys_dev_groups = loader_stack_alloc(sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
707 if (NULL == local_phys_dev_groups) {
708 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
709 "setupLoaderTrampPhysDevGroups: Failed to allocate local "
710 "physical device group array of size %d",
711 total_count);
712 res = VK_ERROR_OUT_OF_HOST_MEMORY;
713 goto out;
714 }
715 // Initialize the memory to something valid
716 memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
717 for (uint32_t group = 0; group < total_count; group++) {
718 local_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
719 local_phys_dev_groups[group].pNext = NULL;
720 local_phys_dev_groups[group].subsetAllocation = false;
721 }
722
723 // Call down and get the content
724 res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroupsKHX(instance, &total_count, local_phys_dev_groups);
725 if (VK_SUCCESS != res) {
726 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
727 "setupLoaderTrampPhysDevGroups: Failed during dispatch call of "
728 "\'EnumeratePhysicalDeviceGroupsKHX\' to lower layers or "
729 "loader to get content.");
730 goto out;
731 }
732
733 // Replace all the physical device IDs with the proper loader values
734 for (uint32_t group = 0; group < total_count; group++) {
735 for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) {
736 bool found = false;
737 for (uint32_t tramp_gpu = 0; tramp_gpu < inst->phys_dev_count_tramp; tramp_gpu++) {
738 if (local_phys_dev_groups[group].physicalDevices[group_gpu] == inst->phys_devs_tramp[tramp_gpu]->phys_dev) {
739 local_phys_dev_groups[group].physicalDevices[group_gpu] = (VkPhysicalDevice)inst->phys_devs_tramp[tramp_gpu];
740 found = true;
741 break;
742 }
743 }
744 if (!found) {
745 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
746 "setupLoaderTrampPhysDevGroups: Failed to find GPU %d in group %d"
747 " returned by \'EnumeratePhysicalDeviceGroupsKHX\' in list returned"
748 " by \'EnumeratePhysicalDevices\'", group_gpu, group);
749 res = VK_ERROR_INITIALIZATION_FAILED;
750 goto out;
751 }
752 }
753 }
754
755 // Copy or create everything to fill the new array of physical device groups
756 for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) {
757 // Check if this physical device group with the same contents is already in the old buffer
758 for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_tramp; old_idx++) {
759 if (local_phys_dev_groups[new_idx].physicalDeviceCount == inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount) {
760 bool found_all_gpus = true;
761 for (uint32_t old_gpu = 0; old_gpu < inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount; old_gpu++) {
762 bool found_gpu = false;
763 for (uint32_t new_gpu = 0; new_gpu < local_phys_dev_groups[new_idx].physicalDeviceCount; new_gpu++) {
764 if (local_phys_dev_groups[new_idx].physicalDevices[new_gpu] == inst->phys_dev_groups_tramp[old_idx]->physicalDevices[old_gpu]) {
765 found_gpu = true;
766 break;
767 }
768 }
769
770 if (!found_gpu) {
771 found_all_gpus = false;
772 break;
773 }
774 }
775 if (!found_all_gpus) {
776 continue;
777 } else {
778 new_phys_dev_groups[new_idx] = inst->phys_dev_groups_tramp[old_idx];
779 break;
780 }
781 }
782 }
783
784 // If this physical device group isn't in the old buffer, create it
785 if (NULL == new_phys_dev_groups[new_idx]) {
786 new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHX *)loader_instance_heap_alloc(
787 inst, sizeof(VkPhysicalDeviceGroupPropertiesKHX), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
788 if (NULL == new_phys_dev_groups[new_idx]) {
789 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
790 "setupLoaderTrampPhysDevGroups: Failed to allocate "
791 "physical device group trampoline object %d",
792 new_idx);
793 total_count = new_idx;
794 res = VK_ERROR_OUT_OF_HOST_MEMORY;
795 goto out;
796 }
797 memcpy(new_phys_dev_groups[new_idx], &local_phys_dev_groups[new_idx],
798 sizeof(VkPhysicalDeviceGroupPropertiesKHX));
799 }
800 }
801
802out:
803
804 if (VK_SUCCESS != res) {
805 if (NULL != new_phys_dev_groups) {
806 for (uint32_t i = 0; i < total_count; i++) {
807 loader_instance_heap_free(inst, new_phys_dev_groups[i]);
808 }
809 loader_instance_heap_free(inst, new_phys_dev_groups);
810 }
811 total_count = 0;
812 } else {
813 // Free everything that didn't carry over to the new array of
814 // physical device groups
815 if (NULL != inst->phys_dev_groups_tramp) {
816 for (uint32_t i = 0; i < inst->phys_dev_group_count_tramp; i++) {
817 bool found = false;
818 for (uint32_t j = 0; j < total_count; j++) {
819 if (inst->phys_dev_groups_tramp[i] == new_phys_dev_groups[j]) {
820 found = true;
821 break;
822 }
823 }
824 if (!found) {
825 loader_instance_heap_free(inst, inst->phys_dev_groups_tramp[i]);
826 }
827 }
828 loader_instance_heap_free(inst, inst->phys_dev_groups_tramp);
829 }
830
831 // Swap in the new physical device group list
832 inst->phys_dev_group_count_tramp = total_count;
833 inst->phys_dev_groups_tramp = new_phys_dev_groups;
834 }
835
836 return res;
837}
838
839VkResult setupLoaderTermPhysDevGroups(struct loader_instance *inst) {
840 VkResult res = VK_SUCCESS;
841 struct loader_icd_term *icd_term;
842 uint32_t total_count = 0;
843 uint32_t cur_icd_group_count = 0;
844 VkPhysicalDeviceGroupPropertiesKHX **new_phys_dev_groups = NULL;
845 VkPhysicalDeviceGroupPropertiesKHX *local_phys_dev_groups = NULL;
846
847 if (0 == inst->phys_dev_count_term) {
848 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
849 "setupLoaderTermPhysDevGroups: Loader failed to setup physical "
850 "device terminator info before calling \'EnumeratePhysicalDeviceGroupsKHX\'.");
851 assert(false);
852 res = VK_ERROR_INITIALIZATION_FAILED;
853 goto out;
854 }
855
856 // For each ICD, query the number of physical device groups, and then get an
857 // internal value for those physical devices.
858 icd_term = inst->icd_terms;
859 for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
860 cur_icd_group_count = 0;
861 if (NULL == icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX) {
862 // Treat each ICD's GPU as it's own group if the extension isn't supported
863 res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &cur_icd_group_count, NULL);
864 if (res != VK_SUCCESS) {
865 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
866 "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
867 "\'EnumeratePhysicalDevices\' to ICD %d to get plain phys dev count.",
868 icd_idx);
869 goto out;
870 }
871 } else {
872 // Query the actual group info
873 res = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX(icd_term->instance, &cur_icd_group_count, NULL);
874 if (res != VK_SUCCESS) {
875 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
876 "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
877 "\'EnumeratePhysicalDeviceGroupsKHX\' to ICD %d to get count.",
878 icd_idx);
879 goto out;
880 }
881 }
882 total_count += cur_icd_group_count;
883 }
884
885 // Create an array for the new physical device groups, which will be stored
886 // in the instance for the Terminator code.
887 new_phys_dev_groups = (VkPhysicalDeviceGroupPropertiesKHX **)loader_instance_heap_alloc(
888 inst, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
889 if (NULL == new_phys_dev_groups) {
890 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
891 "setupLoaderTermPhysDevGroups: Failed to allocate new physical device"
892 " group array of size %d",
893 total_count);
894 res = VK_ERROR_OUT_OF_HOST_MEMORY;
895 goto out;
896 }
897 memset(new_phys_dev_groups, 0, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *));
898
899 // Create a temporary array (on the stack) to keep track of the
900 // returned VkPhysicalDevice values.
901 local_phys_dev_groups = loader_stack_alloc(sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
902 if (NULL == local_phys_dev_groups) {
903 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
904 "setupLoaderTermPhysDevGroups: Failed to allocate local "
905 "physical device group array of size %d",
906 total_count);
907 res = VK_ERROR_OUT_OF_HOST_MEMORY;
908 goto out;
909 }
910 // Initialize the memory to something valid
911 memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
912 for (uint32_t group = 0; group < total_count; group++) {
913 local_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
914 local_phys_dev_groups[group].pNext = NULL;
915 local_phys_dev_groups[group].subsetAllocation = false;
916 }
917
918 cur_icd_group_count = 0;
919 icd_term = inst->icd_terms;
920 for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
921 uint32_t count_this_time = total_count - cur_icd_group_count;
922
923 if (NULL == icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX) {
924 VkPhysicalDevice* phys_dev_array = loader_stack_alloc(sizeof(VkPhysicalDevice) * count_this_time);
925 if (NULL == phys_dev_array) {
926 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
927 "setupLoaderTermPhysDevGroups: Failed to allocate local "
928 "physical device array of size %d",
929 count_this_time);
930 res = VK_ERROR_OUT_OF_HOST_MEMORY;
931 goto out;
932 }
933
934 res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &count_this_time, phys_dev_array);
935 if (res != VK_SUCCESS) {
936 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
937 "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
938 "\'EnumeratePhysicalDevices\' to ICD %d to get plain phys dev count.",
939 icd_idx);
940 goto out;
941 }
942
943 // Add each GPU as it's own group
944 for (uint32_t indiv_gpu = 0; indiv_gpu < count_this_time; indiv_gpu++) {
945 local_phys_dev_groups[indiv_gpu + cur_icd_group_count].physicalDeviceCount = 1;
946 local_phys_dev_groups[indiv_gpu + cur_icd_group_count].physicalDevices[0] = phys_dev_array[indiv_gpu];
947 }
948
949 } else {
950 res = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX(icd_term->instance, &count_this_time, &local_phys_dev_groups[cur_icd_group_count]);
951 if (VK_SUCCESS != res) {
952 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
953 "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
954 "\'EnumeratePhysicalDeviceGroupsKHX\' to ICD %d to get content.",
955 icd_idx);
956 goto out;
957 }
958 }
959
960 cur_icd_group_count += count_this_time;
961 }
962
963 // Replace all the physical device IDs with the proper loader values
964 for (uint32_t group = 0; group < total_count; group++) {
965 for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) {
966 bool found = false;
967 for (uint32_t term_gpu = 0; term_gpu < inst->phys_dev_count_term; term_gpu++) {
968 if (local_phys_dev_groups[group].physicalDevices[group_gpu] == inst->phys_devs_term[term_gpu]->phys_dev) {
969 local_phys_dev_groups[group].physicalDevices[group_gpu] = (VkPhysicalDevice)inst->phys_devs_term[term_gpu];
970 found = true;
971 break;
972 }
973 }
974 if (!found) {
975 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
976 "setupLoaderTermPhysDevGroups: Failed to find GPU %d in group %d"
977 " returned by \'EnumeratePhysicalDeviceGroupsKHX\' in list returned"
978 " by \'EnumeratePhysicalDevices\'", group_gpu, group);
979 res = VK_ERROR_INITIALIZATION_FAILED;
980 goto out;
981 }
982 }
983 }
984
985 // Copy or create everything to fill the new array of physical device groups
986 for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) {
987 // Check if this physical device group with the same contents is already in the old buffer
988 for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_term; old_idx++) {
989 if (local_phys_dev_groups[new_idx].physicalDeviceCount == inst->phys_dev_groups_term[old_idx]->physicalDeviceCount) {
990 bool found_all_gpus = true;
991 for (uint32_t old_gpu = 0; old_gpu < inst->phys_dev_groups_term[old_idx]->physicalDeviceCount; old_gpu++) {
992 bool found_gpu = false;
993 for (uint32_t new_gpu = 0; new_gpu < local_phys_dev_groups[new_idx].physicalDeviceCount; new_gpu++) {
994 if (local_phys_dev_groups[new_idx].physicalDevices[new_gpu] == inst->phys_dev_groups_term[old_idx]->physicalDevices[old_gpu]) {
995 found_gpu = true;
996 break;
997 }
998 }
999
1000 if (!found_gpu) {
1001 found_all_gpus = false;
1002 break;
1003 }
1004 }
1005 if (!found_all_gpus) {
1006 continue;
1007 } else {
1008 new_phys_dev_groups[new_idx] = inst->phys_dev_groups_term[old_idx];
1009 break;
1010 }
1011 }
1012 }
1013
1014 // If this physical device group isn't in the old buffer, create it
1015 if (NULL == new_phys_dev_groups[new_idx]) {
1016 new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHX *)loader_instance_heap_alloc(
1017 inst, sizeof(VkPhysicalDeviceGroupPropertiesKHX), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
1018 if (NULL == new_phys_dev_groups[new_idx]) {
1019 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1020 "setupLoaderTermPhysDevGroups: Failed to allocate "
1021 "physical device group Terminator object %d",
1022 new_idx);
1023 total_count = new_idx;
1024 res = VK_ERROR_OUT_OF_HOST_MEMORY;
1025 goto out;
1026 }
1027 memcpy(new_phys_dev_groups[new_idx], &local_phys_dev_groups[new_idx],
1028 sizeof(VkPhysicalDeviceGroupPropertiesKHX));
1029 }
1030 }
1031
1032out:
1033
1034 if (VK_SUCCESS != res) {
1035 if (NULL != new_phys_dev_groups) {
1036 for (uint32_t i = 0; i < total_count; i++) {
1037 loader_instance_heap_free(inst, new_phys_dev_groups[i]);
1038 }
1039 loader_instance_heap_free(inst, new_phys_dev_groups);
1040 }
1041 total_count = 0;
1042 } else {
1043 // Free everything that didn't carry over to the new array of
1044 // physical device groups
1045 if (NULL != inst->phys_dev_groups_term) {
1046 for (uint32_t i = 0; i < inst->phys_dev_group_count_term; i++) {
1047 bool found = false;
1048 for (uint32_t j = 0; j < total_count; j++) {
1049 if (inst->phys_dev_groups_term[i] == new_phys_dev_groups[j]) {
1050 found = true;
1051 break;
1052 }
1053 }
1054 if (!found) {
1055 loader_instance_heap_free(inst, inst->phys_dev_groups_term[i]);
1056 }
1057 }
1058 loader_instance_heap_free(inst, inst->phys_dev_groups_term);
1059 }
1060
1061 // Swap in the new physical device group list
1062 inst->phys_dev_group_count_term = total_count;
1063 inst->phys_dev_groups_term = new_phys_dev_groups;
1064 }
1065
1066 return res;
1067}