blob: ef62b52b1ec5dc39124f3923cc678bc14c657a85 [file] [log] [blame]
Mark Youngd66edd52017-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 Komow185b35a2017-05-23 15:18:21 -060019 * Author: Lenny Komow <lenny@lunarg.com>
Mark Youngd66edd52017-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
Lenny Komow728ff062017-06-01 13:32:28 -060040// ---- VK_KHX_device_group extension trampoline/terminators
41
Mark Youngd66edd52017-03-10 17:31:18 -070042VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceGroupsKHX(
43 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount,
44 VkPhysicalDeviceGroupPropertiesKHX *pPhysicalDeviceGroupProperties) {
45 VkResult res = VK_SUCCESS;
46 uint32_t count;
47 uint32_t i;
48 struct loader_instance *inst = NULL;
49
50 loader_platform_thread_lock_mutex(&loader_lock);
51
52 inst = loader_get_instance(instance);
53 if (NULL == inst) {
54 res = VK_ERROR_INITIALIZATION_FAILED;
55 goto out;
56 }
57
58 if (NULL == pPhysicalDeviceGroupCount) {
59 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
60 "vkEnumeratePhysicalDeviceGroupsKHX: Received NULL pointer for physical "
61 "device group count return value.");
62 res = VK_ERROR_INITIALIZATION_FAILED;
63 goto out;
64 }
65
66 VkResult setup_res = setupLoaderTrampPhysDevGroups(instance);
67 if (VK_SUCCESS != setup_res) {
68 res = setup_res;
69 goto out;
70 }
71
72 count = inst->phys_dev_group_count_tramp;
73
74 // Wrap the PhysDev object for loader usage, return wrapped objects
75 if (NULL != pPhysicalDeviceGroupProperties) {
76 if (inst->phys_dev_group_count_tramp > *pPhysicalDeviceGroupCount) {
77 loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
78 "vkEnumeratePhysicalDeviceGroupsKHX: Trimming device group count down"
79 " by application request from %d to %d physical device groups",
80 inst->phys_dev_group_count_tramp, *pPhysicalDeviceGroupCount);
81 count = *pPhysicalDeviceGroupCount;
82 res = VK_INCOMPLETE;
83 }
84 for (i = 0; i < count; i++) {
85 memcpy(&pPhysicalDeviceGroupProperties[i], inst->phys_dev_groups_tramp[i],
86 sizeof(VkPhysicalDeviceGroupPropertiesKHX));
87 }
88 }
89
90 *pPhysicalDeviceGroupCount = count;
91
92out:
93
94 loader_platform_thread_unlock_mutex(&loader_lock);
95 return res;
96}
97
98VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroupsKHX(
99 VkInstance instance, uint32_t *pPhysicalDeviceGroupCount,
100 VkPhysicalDeviceGroupPropertiesKHX *pPhysicalDeviceGroupProperties) {
101 struct loader_instance *inst = (struct loader_instance *)instance;
102 VkResult res = VK_SUCCESS;
103
104 // Always call the setup loader terminator physical device groups because they may
105 // have changed at any point.
106 res = setupLoaderTermPhysDevGroups(inst);
107 if (VK_SUCCESS != res) {
108 goto out;
109 }
110
111 uint32_t copy_count = inst->phys_dev_group_count_term;
112 if (NULL != pPhysicalDeviceGroupProperties) {
113 if (copy_count > *pPhysicalDeviceGroupCount) {
114 copy_count = *pPhysicalDeviceGroupCount;
115 res = VK_INCOMPLETE;
116 }
117
118 for (uint32_t i = 0; i < copy_count; i++) {
119 memcpy(&pPhysicalDeviceGroupProperties[i], inst->phys_dev_groups_term[i],
120 sizeof(VkPhysicalDeviceGroupPropertiesKHX));
121 }
122 }
123
124 *pPhysicalDeviceGroupCount = copy_count;
125
126out:
127
128 return res;
129}
130
Lenny Komow728ff062017-06-01 13:32:28 -0600131// ---- VK_NV_external_memory_capabilities extension trampoline/terminators
132
Mark Youngd66edd52017-03-10 17:31:18 -0700133VKAPI_ATTR VkResult VKAPI_CALL
134GetPhysicalDeviceExternalImageFormatPropertiesNV(
135 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
136 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
137 VkExternalMemoryHandleTypeFlagsNV externalHandleType,
138 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
139 const VkLayerInstanceDispatchTable *disp;
140 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
141 disp = loader_get_instance_layer_dispatch(physicalDevice);
142
143 return disp->GetPhysicalDeviceExternalImageFormatPropertiesNV(
144 unwrapped_phys_dev, format, type, tiling, usage, flags,
145 externalHandleType, pExternalImageFormatProperties);
146}
147
148VKAPI_ATTR VkResult VKAPI_CALL
149terminator_GetPhysicalDeviceExternalImageFormatPropertiesNV(
150 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
151 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
152 VkExternalMemoryHandleTypeFlagsNV externalHandleType,
153 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
154 struct loader_physical_device_term *phys_dev_term =
155 (struct loader_physical_device_term *)physicalDevice;
156 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
157
158 if (!icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV) {
159 if (externalHandleType) {
160 return VK_ERROR_FORMAT_NOT_SUPPORTED;
161 }
162
163 if (!icd_term->dispatch.GetPhysicalDeviceImageFormatProperties) {
164 return VK_ERROR_INITIALIZATION_FAILED;
165 }
166
167 pExternalImageFormatProperties->externalMemoryFeatures = 0;
168 pExternalImageFormatProperties->exportFromImportedHandleTypes = 0;
169 pExternalImageFormatProperties->compatibleHandleTypes = 0;
170
171 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(
172 phys_dev_term->phys_dev, format, type, tiling, usage, flags,
173 &pExternalImageFormatProperties->imageFormatProperties);
174 }
175
176 return icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV(
177 phys_dev_term->phys_dev, format, type, tiling, usage, flags,
178 externalHandleType, pExternalImageFormatProperties);
179}
180
Lenny Komow1d5b9152017-05-10 10:06:13 -0600181// ---- VK_KHR_get_physical_device_properties2 extension trampoline/terminators
182
183VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR *pFeatures) {
184 const VkLayerInstanceDispatchTable *disp;
185 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
186 disp = loader_get_instance_layer_dispatch(physicalDevice);
187 disp->GetPhysicalDeviceFeatures2KHR(unwrapped_phys_dev, pFeatures);
188}
189
190VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
191 VkPhysicalDeviceFeatures2KHR *pFeatures) {
192 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
193 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
194
195 if (icd_term->dispatch.GetPhysicalDeviceFeatures2KHR != NULL) {
Lenny Komow185b35a2017-05-23 15:18:21 -0600196 // Pass the call to the driver
Lenny Komow1d5b9152017-05-10 10:06:13 -0600197 icd_term->dispatch.GetPhysicalDeviceFeatures2KHR(phys_dev_term->phys_dev, pFeatures);
198 } else {
Lenny Komow185b35a2017-05-23 15:18:21 -0600199 // Emulate the call
Lenny Komow1d5b9152017-05-10 10:06:13 -0600200 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
Lenny Komow9c74c6a2017-05-15 13:05:33 -0600201 "vkGetPhysicalDeviceFeatures2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFeatures",
202 icd_term->scanned_icd->lib_name);
Lenny Komow185b35a2017-05-23 15:18:21 -0600203
204 // Write to the VkPhysicalDeviceFeatures2KHR struct
Lenny Komow1d5b9152017-05-10 10:06:13 -0600205 icd_term->dispatch.GetPhysicalDeviceFeatures(phys_dev_term->phys_dev, &pFeatures->features);
Lenny Komow185b35a2017-05-23 15:18:21 -0600206
207 void *pNext = pFeatures->pNext;
208 while (pNext != NULL) {
209 switch (*(VkStructureType *)pNext) {
210 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHX: {
211 // Skip the check if VK_KHX_multiview is enabled because it's a device extension
212 // Write to the VkPhysicalDeviceMultiviewFeaturesKHX struct
213 VkPhysicalDeviceMultiviewFeaturesKHX *multiview_features = pNext;
214 multiview_features->multiview = VK_FALSE;
215 multiview_features->multiviewGeometryShader = VK_FALSE;
216 multiview_features->multiviewTessellationShader = VK_FALSE;
217
218 pNext = multiview_features->pNext;
219 break;
220 }
221 default: {
222 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
223 "vkGetPhysicalDeviceFeatures2KHR: Emulation found unrecognized structure type in pFeatures->pNext - "
224 "this struct will be ignored");
225
226 struct VkStructureHeader *header = pNext;
227 pNext = (void *)header->pNext;
228 break;
229 }
230 }
231 }
Lenny Komow1d5b9152017-05-10 10:06:13 -0600232 }
233}
234
235VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice,
236 VkPhysicalDeviceProperties2KHR *pProperties) {
237 const VkLayerInstanceDispatchTable *disp;
238 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
239 disp = loader_get_instance_layer_dispatch(physicalDevice);
240 disp->GetPhysicalDeviceProperties2KHR(unwrapped_phys_dev, pProperties);
241}
242
243VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice,
244 VkPhysicalDeviceProperties2KHR *pProperties) {
245 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
246 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
247
248 if (icd_term->dispatch.GetPhysicalDeviceProperties2KHR != NULL) {
Lenny Komow185b35a2017-05-23 15:18:21 -0600249 // Pass the call to the driver
Lenny Komow1d5b9152017-05-10 10:06:13 -0600250 icd_term->dispatch.GetPhysicalDeviceProperties2KHR(phys_dev_term->phys_dev, pProperties);
251 } else {
Lenny Komow185b35a2017-05-23 15:18:21 -0600252 // Emulate the call
Lenny Komow1d5b9152017-05-10 10:06:13 -0600253 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
Lenny Komow9c74c6a2017-05-15 13:05:33 -0600254 "vkGetPhysicalDeviceProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceProperties",
255 icd_term->scanned_icd->lib_name);
Lenny Komow185b35a2017-05-23 15:18:21 -0600256
257 // Write to the VkPhysicalDeviceProperties2KHR struct
Lenny Komow1d5b9152017-05-10 10:06:13 -0600258 icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &pProperties->properties);
Lenny Komow185b35a2017-05-23 15:18:21 -0600259
260 void *pNext = pProperties->pNext;
261 while (pNext != NULL) {
262 switch (*(VkStructureType *)pNext) {
Mark Youngabc2d6e2017-07-07 07:59:56 -0600263 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR: {
264 VkPhysicalDeviceIDPropertiesKHR *id_properties = pNext;
Lenny Komow185b35a2017-05-23 15:18:21 -0600265
Mark Youngabc2d6e2017-07-07 07:59:56 -0600266 // Verify that "VK_KHR_external_memory_capabilities" is enabled
267 if (icd_term->this_instance->enabled_known_extensions.khr_external_memory_capabilities) {
Lenny Komow185b35a2017-05-23 15:18:21 -0600268 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
269 "vkGetPhysicalDeviceProperties2KHR: Emulation cannot generate unique IDs for struct "
Mark Youngabc2d6e2017-07-07 07:59:56 -0600270 "VkPhysicalDeviceIDPropertiesKHR - setting IDs to zero instead");
Lenny Komow185b35a2017-05-23 15:18:21 -0600271
Mark Youngabc2d6e2017-07-07 07:59:56 -0600272 // Write to the VkPhysicalDeviceIDPropertiesKHR struct
Lenny Komow185b35a2017-05-23 15:18:21 -0600273 memset(id_properties->deviceUUID, 0, VK_UUID_SIZE);
274 memset(id_properties->driverUUID, 0, VK_UUID_SIZE);
275 id_properties->deviceLUIDValid = VK_FALSE;
276 }
277
278 pNext = id_properties->pNext;
279 break;
280 }
281 default: {
282 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
283 "vkGetPhysicalDeviceProperties2KHR: Emulation found unrecognized structure type in "
284 "pProperties->pNext - this struct will be ignored");
285
286 struct VkStructureHeader *header = pNext;
287 pNext = (void *)header->pNext;
288 break;
289 }
290 }
291 }
Lenny Komow1d5b9152017-05-10 10:06:13 -0600292 }
293}
294
295VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format,
296 VkFormatProperties2KHR *pFormatProperties) {
297 const VkLayerInstanceDispatchTable *disp;
298 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
299 disp = loader_get_instance_layer_dispatch(physicalDevice);
300 disp->GetPhysicalDeviceFormatProperties2KHR(unwrapped_phys_dev, format, pFormatProperties);
301}
302
303VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties2KHR(VkPhysicalDevice physicalDevice, VkFormat format,
304 VkFormatProperties2KHR *pFormatProperties) {
305 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
306 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
307
308 if (icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR != NULL) {
Lenny Komow185b35a2017-05-23 15:18:21 -0600309 // Pass the call to the driver
Lenny Komow1d5b9152017-05-10 10:06:13 -0600310 icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR(phys_dev_term->phys_dev, format, pFormatProperties);
311 } else {
Lenny Komow185b35a2017-05-23 15:18:21 -0600312 // Emulate the call
Lenny Komow9c74c6a2017-05-15 13:05:33 -0600313 loader_log(
314 icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
315 "vkGetPhysicalDeviceFormatProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFormatProperties",
316 icd_term->scanned_icd->lib_name);
Lenny Komow185b35a2017-05-23 15:18:21 -0600317
318 // Write to the VkFormatProperties2KHR struct
319 icd_term->dispatch.GetPhysicalDeviceFormatProperties(phys_dev_term->phys_dev, format, &pFormatProperties->formatProperties);
320
Lenny Komow1d5b9152017-05-10 10:06:13 -0600321 if (pFormatProperties->pNext != NULL) {
322 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
Lenny Komow185b35a2017-05-23 15:18:21 -0600323 "vkGetPhysicalDeviceFormatProperties2KHR: Emulation found unrecognized structure type in "
324 "pFormatProperties->pNext - this struct will be ignored");
Lenny Komow1d5b9152017-05-10 10:06:13 -0600325 }
Lenny Komow1d5b9152017-05-10 10:06:13 -0600326 }
327}
328
329VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceImageFormatProperties2KHR(
330 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
331 VkImageFormatProperties2KHR *pImageFormatProperties) {
332 const VkLayerInstanceDispatchTable *disp;
333 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
334 disp = loader_get_instance_layer_dispatch(physicalDevice);
335 return disp->GetPhysicalDeviceImageFormatProperties2KHR(unwrapped_phys_dev, pImageFormatInfo, pImageFormatProperties);
336}
337
338VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties2KHR(
339 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
340 VkImageFormatProperties2KHR *pImageFormatProperties) {
341 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
342 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
343
344 if (icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR != NULL) {
Lenny Komow185b35a2017-05-23 15:18:21 -0600345 // Pass the call to the driver
Lenny Komow1d5b9152017-05-10 10:06:13 -0600346 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR(phys_dev_term->phys_dev, pImageFormatInfo,
347 pImageFormatProperties);
348 } else {
Lenny Komow185b35a2017-05-23 15:18:21 -0600349 // Emulate the call
Lenny Komow1d5b9152017-05-10 10:06:13 -0600350 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
Lenny Komow9c74c6a2017-05-15 13:05:33 -0600351 "vkGetPhysicalDeviceImageFormatProperties2KHR: Emulating call in ICD \"%s\" using "
352 "vkGetPhysicalDeviceImageFormatProperties",
353 icd_term->scanned_icd->lib_name);
Lenny Komow185b35a2017-05-23 15:18:21 -0600354
355 // If there is more info in either pNext, then this is unsupported
356 if (pImageFormatInfo->pNext != NULL || pImageFormatProperties->pNext != NULL) {
357 return VK_ERROR_FORMAT_NOT_SUPPORTED;
Lenny Komow1d5b9152017-05-10 10:06:13 -0600358 }
Lenny Komow185b35a2017-05-23 15:18:21 -0600359
360 // Write to the VkImageFormatProperties2KHR struct
361 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(
Lenny Komow1d5b9152017-05-10 10:06:13 -0600362 phys_dev_term->phys_dev, pImageFormatInfo->format, pImageFormatInfo->type, pImageFormatInfo->tiling,
363 pImageFormatInfo->usage, pImageFormatInfo->flags, &pImageFormatProperties->imageFormatProperties);
Lenny Komow1d5b9152017-05-10 10:06:13 -0600364 }
365}
366
367VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice,
368 uint32_t *pQueueFamilyPropertyCount,
369 VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
370 const VkLayerInstanceDispatchTable *disp;
371 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
372 disp = loader_get_instance_layer_dispatch(physicalDevice);
373 disp->GetPhysicalDeviceQueueFamilyProperties2KHR(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
374}
375
376VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties2KHR(
377 VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
378 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
379 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
380
381 if (icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR != NULL) {
Lenny Komow185b35a2017-05-23 15:18:21 -0600382 // Pass the call to the driver
Lenny Komow1d5b9152017-05-10 10:06:13 -0600383 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR(phys_dev_term->phys_dev, pQueueFamilyPropertyCount,
384 pQueueFamilyProperties);
Lenny Komow1d5b9152017-05-10 10:06:13 -0600385 } else {
Lenny Komow185b35a2017-05-23 15:18:21 -0600386 // Emulate the call
Lenny Komow1d5b9152017-05-10 10:06:13 -0600387 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
Lenny Komow9c74c6a2017-05-15 13:05:33 -0600388 "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Emulating call in ICD \"%s\" using "
389 "vkGetPhysicalDeviceQueueFamilyProperties",
390 icd_term->scanned_icd->lib_name);
Lenny Komow185b35a2017-05-23 15:18:21 -0600391
392 if (pQueueFamilyProperties == NULL || *pQueueFamilyPropertyCount == 0) {
393 // Write to pQueueFamilyPropertyCount
394 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, NULL);
Lenny Komow1d5b9152017-05-10 10:06:13 -0600395 } else {
Lenny Komow185b35a2017-05-23 15:18:21 -0600396 // Allocate a temporary array for the output of the old function
397 VkQueueFamilyProperties *properties = loader_stack_alloc(*pQueueFamilyPropertyCount * sizeof(VkQueueFamilyProperties));
398 if (properties == NULL) {
399 *pQueueFamilyPropertyCount = 0;
400 loader_log(
401 icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
402 "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Out of memory - Failed to allocate array for loader emulation.");
403 return;
404 }
405
Lenny Komow1d5b9152017-05-10 10:06:13 -0600406 icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount,
407 properties);
408 for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) {
Lenny Komow185b35a2017-05-23 15:18:21 -0600409 // Write to the VkQueueFamilyProperties2KHR struct
410 memcpy(&pQueueFamilyProperties[i].queueFamilyProperties, &properties[i], sizeof(VkQueueFamilyProperties));
411
Lenny Komow1d5b9152017-05-10 10:06:13 -0600412 if (pQueueFamilyProperties[i].pNext != NULL) {
413 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
Lenny Komow185b35a2017-05-23 15:18:21 -0600414 "vkGetPhysicalDeviceQueueFamilyProperties2KHR: Emulation found unrecognized structure type in "
Lenny Komow4687c7f2017-05-30 13:04:46 -0600415 "pQueueFamilyProperties[%d].pNext - this struct will be ignored",
Lenny Komow1d5b9152017-05-10 10:06:13 -0600416 i);
417 }
Lenny Komow1d5b9152017-05-10 10:06:13 -0600418 }
419 }
420 }
421}
422
423VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMemoryProperties2KHR(VkPhysicalDevice physicalDevice,
424 VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties) {
425 const VkLayerInstanceDispatchTable *disp;
426 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
427 disp = loader_get_instance_layer_dispatch(physicalDevice);
428 disp->GetPhysicalDeviceMemoryProperties2KHR(unwrapped_phys_dev, pMemoryProperties);
429}
430
431VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties2KHR(
432 VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2KHR *pMemoryProperties) {
433 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
434 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
435
436 if (icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR != NULL) {
Lenny Komow185b35a2017-05-23 15:18:21 -0600437 // Pass the call to the driver
Lenny Komow1d5b9152017-05-10 10:06:13 -0600438 icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR(phys_dev_term->phys_dev, pMemoryProperties);
439 } else {
Lenny Komow185b35a2017-05-23 15:18:21 -0600440 // Emulate the call
Lenny Komow9c74c6a2017-05-15 13:05:33 -0600441 loader_log(
442 icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
443 "vkGetPhysicalDeviceMemoryProperties2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceMemoryProperties",
444 icd_term->scanned_icd->lib_name);
Lenny Komow185b35a2017-05-23 15:18:21 -0600445
446 // Write to the VkPhysicalDeviceMemoryProperties2KHR struct
Lenny Komow1d5b9152017-05-10 10:06:13 -0600447 icd_term->dispatch.GetPhysicalDeviceMemoryProperties(phys_dev_term->phys_dev, &pMemoryProperties->memoryProperties);
Lenny Komow185b35a2017-05-23 15:18:21 -0600448
449 if (pMemoryProperties->pNext != NULL) {
450 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
451 "vkGetPhysicalDeviceMemoryProperties2KHR: Emulation found unrecognized structure type in "
452 "pMemoryProperties->pNext - this struct will be ignored");
453 }
Lenny Komow1d5b9152017-05-10 10:06:13 -0600454 }
455}
456
457VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSparseImageFormatProperties2KHR(
458 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount,
459 VkSparseImageFormatProperties2KHR *pProperties) {
460 const VkLayerInstanceDispatchTable *disp;
461 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
462 disp = loader_get_instance_layer_dispatch(physicalDevice);
463 disp->GetPhysicalDeviceSparseImageFormatProperties2KHR(unwrapped_phys_dev, pFormatInfo, pPropertyCount, pProperties);
464}
465
466VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties2KHR(
467 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount,
468 VkSparseImageFormatProperties2KHR *pProperties) {
469 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
470 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
471
472 if (icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR != NULL) {
Lenny Komow185b35a2017-05-23 15:18:21 -0600473 // Pass the call to the driver
Lenny Komow1d5b9152017-05-10 10:06:13 -0600474 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR(phys_dev_term->phys_dev, pFormatInfo, pPropertyCount,
475 pProperties);
Lenny Komow1d5b9152017-05-10 10:06:13 -0600476 } else {
Lenny Komow185b35a2017-05-23 15:18:21 -0600477 // Emulate the call
Lenny Komow1d5b9152017-05-10 10:06:13 -0600478 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
Lenny Komow9c74c6a2017-05-15 13:05:33 -0600479 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulating call in ICD \"%s\" using "
480 "vkGetPhysicalDeviceSparseImageFormatProperties",
481 icd_term->scanned_icd->lib_name);
Lenny Komow185b35a2017-05-23 15:18:21 -0600482
Lenny Komow1d5b9152017-05-10 10:06:13 -0600483 if (pFormatInfo->pNext != NULL) {
484 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
Lenny Komow185b35a2017-05-23 15:18:21 -0600485 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulation found unrecognized structure type in "
486 "pFormatInfo->pNext - this struct will be ignored");
Lenny Komow1d5b9152017-05-10 10:06:13 -0600487 }
Lenny Komow185b35a2017-05-23 15:18:21 -0600488
489 if (pProperties == NULL || *pPropertyCount == 0) {
490 // Write to pPropertyCount
491 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(
492 phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage,
493 pFormatInfo->tiling, pPropertyCount, NULL);
Lenny Komow1d5b9152017-05-10 10:06:13 -0600494 } else {
Lenny Komow185b35a2017-05-23 15:18:21 -0600495 // Allocate a temporary array for the output of the old function
496 VkSparseImageFormatProperties *properties =
497 loader_stack_alloc(*pPropertyCount * sizeof(VkSparseImageMemoryRequirements));
498 if (properties == NULL) {
499 *pPropertyCount = 0;
500 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
501 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Out of memory - Failed to allocate array for "
502 "loader emulation.");
503 return;
504 }
505
Lenny Komow1d5b9152017-05-10 10:06:13 -0600506 icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(
507 phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage,
508 pFormatInfo->tiling, pPropertyCount, properties);
509 for (uint32_t i = 0; i < *pPropertyCount; ++i) {
Lenny Komow185b35a2017-05-23 15:18:21 -0600510 // Write to the VkSparseImageFormatProperties2KHR struct
511 memcpy(&pProperties[i].properties, &properties[i], sizeof(VkSparseImageFormatProperties));
512
Lenny Komow1d5b9152017-05-10 10:06:13 -0600513 if (pProperties[i].pNext != NULL) {
514 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
Lenny Komow185b35a2017-05-23 15:18:21 -0600515 "vkGetPhysicalDeviceSparseImageFormatProperties2KHR: Emulation found unrecognized structure type in "
Lenny Komow4687c7f2017-05-30 13:04:46 -0600516 "pProperties[%d].pNext - this struct will be ignored",
Lenny Komow1d5b9152017-05-10 10:06:13 -0600517 i);
518 }
Lenny Komow1d5b9152017-05-10 10:06:13 -0600519 }
520 }
521 }
522}
Mark Youngd66edd52017-03-10 17:31:18 -0700523
Lenny Komow4687c7f2017-05-30 13:04:46 -0600524// ---- VK_KHR_get_surface_capabilities2 extension trampoline/terminators
525
526VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
527 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
528 VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
529 const VkLayerInstanceDispatchTable *disp;
530 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
531 disp = loader_get_instance_layer_dispatch(physicalDevice);
532 return disp->GetPhysicalDeviceSurfaceCapabilities2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceCapabilities);
533}
534
535VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2KHR(
536 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
537 VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
538 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
539 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
540
541 VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
542 uint8_t icd_index = phys_dev_term->icd_index;
543
544 if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) {
545 // Pass the call to the driver, possibly unwrapping the ICD surface
546 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
547 VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
548 info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
549 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy,
550 pSurfaceCapabilities);
551 } else {
552 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
553 pSurfaceCapabilities);
554 }
555 } else {
556 // Emulate the call
557 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
558 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulating call in ICD \"%s\" using "
559 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
560 icd_term->scanned_icd->lib_name);
561
562 if (pSurfaceInfo->pNext != NULL) {
563 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
564 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
565 "pSurfaceInfo->pNext - this struct will be ignored");
566 }
567
568 // Write to the VkSurfaceCapabilities2KHR struct
569 VkSurfaceKHR surface = pSurfaceInfo->surface;
570 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
571 surface = icd_surface->real_icd_surfaces[icd_index];
572 }
573 VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface,
574 &pSurfaceCapabilities->surfaceCapabilities);
575
576 if (pSurfaceCapabilities->pNext != NULL) {
577 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
578 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
579 "pSurfaceCapabilities->pNext - this struct will be ignored");
580 }
581 return res;
582 }
583}
584
585VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
586 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
587 uint32_t *pSurfaceFormatCount,
588 VkSurfaceFormat2KHR *pSurfaceFormats) {
589 const VkLayerInstanceDispatchTable *disp;
590 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
591 disp = loader_get_instance_layer_dispatch(physicalDevice);
592 return disp->GetPhysicalDeviceSurfaceFormats2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats);
593}
594
595VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
596 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
597 uint32_t *pSurfaceFormatCount,
598 VkSurfaceFormat2KHR *pSurfaceFormats) {
599 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
600 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
601
602 VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
603 uint8_t icd_index = phys_dev_term->icd_index;
604
605 if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) {
606 // Pass the call to the driver, possibly unwrapping the ICD surface
607 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
608 VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
609 info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
610 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount,
611 pSurfaceFormats);
612 } else {
613 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
614 pSurfaceFormatCount, pSurfaceFormats);
615 }
616 } else {
617 // Emulate the call
618 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
619 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceSurfaceFormatsKHR",
620 icd_term->scanned_icd->lib_name);
621
622 if (pSurfaceInfo->pNext != NULL) {
623 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
624 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in pSurfaceInfo->pNext "
625 "- this struct will be ignored");
626 }
627
628 VkSurfaceKHR surface = pSurfaceInfo->surface;
629 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
630 surface = icd_surface->real_icd_surfaces[icd_index];
631 }
632
633 if (*pSurfaceFormatCount == 0 || pSurfaceFormats == NULL) {
634 // Write to pSurfaceFormatCount
635 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
636 NULL);
637 } else {
638 // Allocate a temporary array for the output of the old function
639 VkSurfaceFormatKHR *formats = loader_stack_alloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
640 if (formats == NULL) {
641 return VK_ERROR_OUT_OF_HOST_MEMORY;
642 }
643
644 VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface,
645 pSurfaceFormatCount, formats);
646 for (uint32_t i = 0; i < *pSurfaceFormatCount; ++i) {
647 pSurfaceFormats[i].surfaceFormat = formats[i];
648 if (pSurfaceFormats[i].pNext != NULL) {
649 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
650 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in "
651 "pSurfaceFormats[%d].pNext - this struct will be ignored",
652 i);
653 }
654 }
655 return res;
656 }
657 }
658}
659
Lenny Komow728ff062017-06-01 13:32:28 -0600660// ---- VK_EXT_display_surface_counter extension trampoline/terminators
661
662VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
663 VkSurfaceCapabilities2EXT *pSurfaceCapabilities) {
664 const VkLayerInstanceDispatchTable *disp;
665 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
666 disp = loader_get_instance_layer_dispatch(physicalDevice);
667 return disp->GetPhysicalDeviceSurfaceCapabilities2EXT(unwrapped_phys_dev, surface, pSurfaceCapabilities);
668}
669
670VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2EXT(
671 VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT *pSurfaceCapabilities) {
672 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
673 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
674
675 VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
676 uint8_t icd_index = phys_dev_term->icd_index;
677
678 // Unwrap the surface if needed
679 VkSurfaceKHR unwrapped_surface = surface;
680 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
681 unwrapped_surface = icd_surface->real_icd_surfaces[icd_index];
682 }
683
684 if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT != NULL) {
685 // Pass the call to the driver
686 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT(phys_dev_term->phys_dev, unwrapped_surface,
687 pSurfaceCapabilities);
688 } else {
689 // Emulate the call
690 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
691 "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulating call in ICD \"%s\" using "
692 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
693 icd_term->scanned_icd->lib_name);
694
695 VkSurfaceCapabilitiesKHR surface_caps;
696 VkResult res =
697 icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, unwrapped_surface, &surface_caps);
698 pSurfaceCapabilities->minImageCount = surface_caps.minImageCount;
699 pSurfaceCapabilities->maxImageCount = surface_caps.maxImageCount;
700 pSurfaceCapabilities->currentExtent = surface_caps.currentExtent;
701 pSurfaceCapabilities->minImageExtent = surface_caps.minImageExtent;
702 pSurfaceCapabilities->maxImageExtent = surface_caps.maxImageExtent;
703 pSurfaceCapabilities->maxImageArrayLayers = surface_caps.maxImageArrayLayers;
704 pSurfaceCapabilities->supportedTransforms = surface_caps.supportedTransforms;
705 pSurfaceCapabilities->currentTransform = surface_caps.currentTransform;
706 pSurfaceCapabilities->supportedCompositeAlpha = surface_caps.supportedCompositeAlpha;
707 pSurfaceCapabilities->supportedUsageFlags = surface_caps.supportedUsageFlags;
708 pSurfaceCapabilities->supportedSurfaceCounters = 0;
709
710 if (pSurfaceCapabilities->pNext != NULL) {
711 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
712 "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulation found unrecognized structure type in "
713 "pSurfaceCapabilities->pNext - this struct will be ignored");
714 }
715
716 return res;
717 }
718}
719
720// ---- VK_EXT_direct_mode_display extension trampoline/terminators
721
722VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
723 const VkLayerInstanceDispatchTable *disp;
724 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
725 disp = loader_get_instance_layer_dispatch(physicalDevice);
726 return disp->ReleaseDisplayEXT(unwrapped_phys_dev, display);
727}
728
729VKAPI_ATTR VkResult VKAPI_CALL terminator_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
730 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
731 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
732
733 if (icd_term->dispatch.ReleaseDisplayEXT == NULL) {
734 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
735 "ICD \"%s\" associated with VkPhysicalDevice does not support vkReleaseDisplayEXT - Consequently, the call is "
736 "invalid because it should not be possible to acquire a display on this device",
737 icd_term->scanned_icd->lib_name);
738 }
739 return icd_term->dispatch.ReleaseDisplayEXT(phys_dev_term->phys_dev, display);
740}
741
742// ---- VK_EXT_acquire_xlib_display extension trampoline/terminators
743
744#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
745VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, VkDisplayKHR display) {
746 const VkLayerInstanceDispatchTable *disp;
747 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
748 disp = loader_get_instance_layer_dispatch(physicalDevice);
749 return disp->AcquireXlibDisplayEXT(unwrapped_phys_dev, dpy, display);
750}
751
752VKAPI_ATTR VkResult VKAPI_CALL terminator_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy,
753 VkDisplayKHR display) {
754 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
755 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
756
757 if (icd_term->dispatch.AcquireXlibDisplayEXT != NULL) {
758 // Pass the call to the driver
759 return icd_term->dispatch.AcquireXlibDisplayEXT(phys_dev_term->phys_dev, dpy, display);
760 } else {
761 // Emulate the call
762 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
763 "vkAcquireXLibDisplayEXT: Emulating call in ICD \"%s\" by returning error", icd_term->scanned_icd->lib_name);
764
765 // Fail for the unsupported command
766 return VK_ERROR_INITIALIZATION_FAILED;
767 }
768}
769
770VKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput,
771 VkDisplayKHR *pDisplay) {
772 const VkLayerInstanceDispatchTable *disp;
773 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
774 disp = loader_get_instance_layer_dispatch(physicalDevice);
775 return disp->GetRandROutputDisplayEXT(unwrapped_phys_dev, dpy, rrOutput, pDisplay);
776}
777
778VKAPI_ATTR VkResult VKAPI_CALL terminator_GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput,
779 VkDisplayKHR *pDisplay) {
780 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
781 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
782
783 if (icd_term->dispatch.GetRandROutputDisplayEXT != NULL) {
784 // Pass the call to the driver
785 return icd_term->dispatch.GetRandROutputDisplayEXT(phys_dev_term->phys_dev, dpy, rrOutput, pDisplay);
786 } else {
787 // Emulate the call
788 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
789 "vkGetRandROutputDisplayEXT: Emulating call in ICD \"%s\" by returning null display",
790 icd_term->scanned_icd->lib_name);
791
792 // Return a null handle to indicate this can't be done
793 *pDisplay = VK_NULL_HANDLE;
794 return VK_SUCCESS;
795 }
796}
797
798#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
799
Mark Youngabc2d6e2017-07-07 07:59:56 -0600800// ---- VK_KHR_external_memory_capabilities extension trampoline/terminators
801
802VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalBufferPropertiesKHR(
803 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo,
804 VkExternalBufferPropertiesKHR *pExternalBufferProperties) {
805 const VkLayerInstanceDispatchTable *disp;
806 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
807 disp = loader_get_instance_layer_dispatch(physicalDevice);
808 disp->GetPhysicalDeviceExternalBufferPropertiesKHR(unwrapped_phys_dev, pExternalBufferInfo, pExternalBufferProperties);
809}
810
811VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalBufferPropertiesKHR(
812 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo,
813 VkExternalBufferPropertiesKHR *pExternalBufferProperties) {
814 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
815 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
816
817 if (icd_term->dispatch.GetPhysicalDeviceExternalBufferPropertiesKHR) {
818 // Pass the call to the driver
819 icd_term->dispatch.GetPhysicalDeviceExternalBufferPropertiesKHR(phys_dev_term->phys_dev, pExternalBufferInfo,
820 pExternalBufferProperties);
821 } else {
822 // Emulate the call
823 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
824 "vkGetPhysicalDeviceExternalBufferPropertiesKHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
825
826 if (pExternalBufferInfo->pNext != NULL) {
827 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
828 "vkGetPhysicalDeviceExternalBufferPropertiesKHR: Emulation found unrecognized structure type in "
829 "pExternalBufferInfo->pNext - this struct will be ignored");
830 }
831
832 // Fill in everything being unsupported
833 memset(&pExternalBufferProperties->externalMemoryProperties, 0, sizeof(VkExternalMemoryPropertiesKHR));
834
835 if (pExternalBufferProperties->pNext != NULL) {
836 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
837 "vkGetPhysicalDeviceExternalBufferPropertiesKHR: Emulation found unrecognized structure type in "
838 "pExternalBufferProperties->pNext - this struct will be ignored");
839 }
840 }
841}
842
843// ---- VK_KHR_external_semaphore_capabilities extension trampoline/terminators
844
845VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalSemaphorePropertiesKHR(
846 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfoKHR *pExternalSemaphoreInfo,
847 VkExternalSemaphorePropertiesKHR *pExternalSemaphoreProperties) {
848 const VkLayerInstanceDispatchTable *disp;
849 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
850 disp = loader_get_instance_layer_dispatch(physicalDevice);
851 disp->GetPhysicalDeviceExternalSemaphorePropertiesKHR(unwrapped_phys_dev, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
852}
853
854VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalSemaphorePropertiesKHR(
855 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfoKHR *pExternalSemaphoreInfo,
856 VkExternalSemaphorePropertiesKHR *pExternalSemaphoreProperties) {
857 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
858 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
859
860 if (icd_term->dispatch.GetPhysicalDeviceExternalSemaphorePropertiesKHR != NULL) {
861 // Pass the call to the driver
862 icd_term->dispatch.GetPhysicalDeviceExternalSemaphorePropertiesKHR(phys_dev_term->phys_dev, pExternalSemaphoreInfo,
863 pExternalSemaphoreProperties);
864 } else {
865 // Emulate the call
866 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
867 "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR: Emulating call in ICD \"%s\"",
868 icd_term->scanned_icd->lib_name);
869
870 if (pExternalSemaphoreInfo->pNext != NULL) {
871 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
872 "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR: Emulation found unrecognized structure type in "
873 "pExternalSemaphoreInfo->pNext - this struct will be ignored");
874 }
875
876 // Fill in everything being unsupported
877 pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
878 pExternalSemaphoreProperties->compatibleHandleTypes = 0;
879 pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
880
881 if (pExternalSemaphoreProperties->pNext != NULL) {
882 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
883 "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR: Emulation found unrecognized structure type in "
884 "pExternalSemaphoreProperties->pNext - this struct will be ignored");
885 }
886 }
887}
888
889// ---- VK_KHR_external_fence_capabilities extension trampoline/terminators
890
891VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceExternalFencePropertiesKHR(
892 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfoKHR *pExternalFenceInfo,
893 VkExternalFencePropertiesKHR *pExternalFenceProperties) {
894 const VkLayerInstanceDispatchTable *disp;
895 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
896 disp = loader_get_instance_layer_dispatch(physicalDevice);
897 disp->GetPhysicalDeviceExternalFencePropertiesKHR(unwrapped_phys_dev, pExternalFenceInfo, pExternalFenceProperties);
898}
899
900VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalFencePropertiesKHR(
901 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfoKHR *pExternalFenceInfo,
902 VkExternalFencePropertiesKHR *pExternalFenceProperties) {
903 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
904 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
905
906 if (icd_term->dispatch.GetPhysicalDeviceExternalFencePropertiesKHR != NULL) {
907 // Pass the call to the driver
908 icd_term->dispatch.GetPhysicalDeviceExternalFencePropertiesKHR(phys_dev_term->phys_dev, pExternalFenceInfo,
909 pExternalFenceProperties);
910 } else {
911 // Emulate the call
912 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
913 "vkGetPhysicalDeviceExternalFencePropertiesKHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
914
915 if (pExternalFenceInfo->pNext != NULL) {
916 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
917 "vkGetPhysicalDeviceExternalFencePropertiesKHR: Emulation found unrecognized structure type in "
918 "pExternalFenceInfo->pNext - this struct will be ignored");
919 }
920
921 // Fill in everything being unsupported
922 pExternalFenceProperties->exportFromImportedHandleTypes = 0;
923 pExternalFenceProperties->compatibleHandleTypes = 0;
924 pExternalFenceProperties->externalFenceFeatures = 0;
925
926 if (pExternalFenceProperties->pNext != NULL) {
927 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
928 "vkGetPhysicalDeviceExternalFencePropertiesKHR: Emulation found unrecognized structure type in "
929 "pExternalFenceProperties->pNext - this struct will be ignored");
930 }
931 }
932}
933
Lenny Komow4687c7f2017-05-30 13:04:46 -0600934// ---- Helper functions
935
Mark Youngd66edd52017-03-10 17:31:18 -0700936VkResult setupLoaderTrampPhysDevGroups(VkInstance instance) {
937 VkResult res = VK_SUCCESS;
938 struct loader_instance *inst;
939 uint32_t total_count = 0;
940 VkPhysicalDeviceGroupPropertiesKHX **new_phys_dev_groups = NULL;
941 VkPhysicalDeviceGroupPropertiesKHX *local_phys_dev_groups = NULL;
942
943 inst = loader_get_instance(instance);
944 if (NULL == inst) {
945 res = VK_ERROR_INITIALIZATION_FAILED;
946 goto out;
947 }
948
949 // Setup the trampoline loader physical devices. This will actually
950 // call down and setup the terminator loader physical devices during the
951 // process.
952 VkResult setup_res = setupLoaderTrampPhysDevs(instance);
953 if (setup_res != VK_SUCCESS && setup_res != VK_INCOMPLETE) {
954 res = setup_res;
955 goto out;
956 }
957
958 // Query how many physical device groups there
959 res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroupsKHX(instance, &total_count, NULL);
960 if (res != VK_SUCCESS) {
961 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
962 "setupLoaderTrampPhysDevGroups: Failed during dispatch call of "
963 "\'EnumeratePhysicalDeviceGroupsKHX\' to lower layers or "
964 "loader to get count.");
965 goto out;
966 }
967
968 // Create an array for the new physical device groups, which will be stored
969 // in the instance for the trampoline code.
970 new_phys_dev_groups = (VkPhysicalDeviceGroupPropertiesKHX **)loader_instance_heap_alloc(
971 inst, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
972 if (NULL == new_phys_dev_groups) {
973 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
974 "setupLoaderTrampPhysDevGroups: Failed to allocate new physical device"
975 " group array of size %d",
976 total_count);
977 res = VK_ERROR_OUT_OF_HOST_MEMORY;
978 goto out;
979 }
980 memset(new_phys_dev_groups, 0, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *));
981
982 // Create a temporary array (on the stack) to keep track of the
983 // returned VkPhysicalDevice values.
984 local_phys_dev_groups = loader_stack_alloc(sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
985 if (NULL == local_phys_dev_groups) {
986 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
987 "setupLoaderTrampPhysDevGroups: Failed to allocate local "
988 "physical device group array of size %d",
989 total_count);
990 res = VK_ERROR_OUT_OF_HOST_MEMORY;
991 goto out;
992 }
993 // Initialize the memory to something valid
994 memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
995 for (uint32_t group = 0; group < total_count; group++) {
996 local_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
997 local_phys_dev_groups[group].pNext = NULL;
998 local_phys_dev_groups[group].subsetAllocation = false;
999 }
1000
1001 // Call down and get the content
1002 res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroupsKHX(instance, &total_count, local_phys_dev_groups);
1003 if (VK_SUCCESS != res) {
1004 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1005 "setupLoaderTrampPhysDevGroups: Failed during dispatch call of "
1006 "\'EnumeratePhysicalDeviceGroupsKHX\' to lower layers or "
1007 "loader to get content.");
1008 goto out;
1009 }
1010
1011 // Replace all the physical device IDs with the proper loader values
1012 for (uint32_t group = 0; group < total_count; group++) {
1013 for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) {
1014 bool found = false;
1015 for (uint32_t tramp_gpu = 0; tramp_gpu < inst->phys_dev_count_tramp; tramp_gpu++) {
1016 if (local_phys_dev_groups[group].physicalDevices[group_gpu] == inst->phys_devs_tramp[tramp_gpu]->phys_dev) {
1017 local_phys_dev_groups[group].physicalDevices[group_gpu] = (VkPhysicalDevice)inst->phys_devs_tramp[tramp_gpu];
1018 found = true;
1019 break;
1020 }
1021 }
1022 if (!found) {
1023 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1024 "setupLoaderTrampPhysDevGroups: Failed to find GPU %d in group %d"
1025 " returned by \'EnumeratePhysicalDeviceGroupsKHX\' in list returned"
1026 " by \'EnumeratePhysicalDevices\'", group_gpu, group);
1027 res = VK_ERROR_INITIALIZATION_FAILED;
1028 goto out;
1029 }
1030 }
1031 }
1032
1033 // Copy or create everything to fill the new array of physical device groups
1034 for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) {
1035 // Check if this physical device group with the same contents is already in the old buffer
1036 for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_tramp; old_idx++) {
1037 if (local_phys_dev_groups[new_idx].physicalDeviceCount == inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount) {
1038 bool found_all_gpus = true;
1039 for (uint32_t old_gpu = 0; old_gpu < inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount; old_gpu++) {
1040 bool found_gpu = false;
1041 for (uint32_t new_gpu = 0; new_gpu < local_phys_dev_groups[new_idx].physicalDeviceCount; new_gpu++) {
1042 if (local_phys_dev_groups[new_idx].physicalDevices[new_gpu] == inst->phys_dev_groups_tramp[old_idx]->physicalDevices[old_gpu]) {
1043 found_gpu = true;
1044 break;
1045 }
1046 }
1047
1048 if (!found_gpu) {
1049 found_all_gpus = false;
1050 break;
1051 }
1052 }
1053 if (!found_all_gpus) {
1054 continue;
1055 } else {
1056 new_phys_dev_groups[new_idx] = inst->phys_dev_groups_tramp[old_idx];
1057 break;
1058 }
1059 }
1060 }
1061
1062 // If this physical device group isn't in the old buffer, create it
1063 if (NULL == new_phys_dev_groups[new_idx]) {
1064 new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHX *)loader_instance_heap_alloc(
1065 inst, sizeof(VkPhysicalDeviceGroupPropertiesKHX), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
1066 if (NULL == new_phys_dev_groups[new_idx]) {
1067 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1068 "setupLoaderTrampPhysDevGroups: Failed to allocate "
1069 "physical device group trampoline object %d",
1070 new_idx);
1071 total_count = new_idx;
1072 res = VK_ERROR_OUT_OF_HOST_MEMORY;
1073 goto out;
1074 }
1075 memcpy(new_phys_dev_groups[new_idx], &local_phys_dev_groups[new_idx],
1076 sizeof(VkPhysicalDeviceGroupPropertiesKHX));
1077 }
1078 }
1079
1080out:
1081
1082 if (VK_SUCCESS != res) {
1083 if (NULL != new_phys_dev_groups) {
1084 for (uint32_t i = 0; i < total_count; i++) {
1085 loader_instance_heap_free(inst, new_phys_dev_groups[i]);
1086 }
1087 loader_instance_heap_free(inst, new_phys_dev_groups);
1088 }
1089 total_count = 0;
1090 } else {
1091 // Free everything that didn't carry over to the new array of
1092 // physical device groups
1093 if (NULL != inst->phys_dev_groups_tramp) {
1094 for (uint32_t i = 0; i < inst->phys_dev_group_count_tramp; i++) {
1095 bool found = false;
1096 for (uint32_t j = 0; j < total_count; j++) {
1097 if (inst->phys_dev_groups_tramp[i] == new_phys_dev_groups[j]) {
1098 found = true;
1099 break;
1100 }
1101 }
1102 if (!found) {
1103 loader_instance_heap_free(inst, inst->phys_dev_groups_tramp[i]);
1104 }
1105 }
1106 loader_instance_heap_free(inst, inst->phys_dev_groups_tramp);
1107 }
1108
1109 // Swap in the new physical device group list
1110 inst->phys_dev_group_count_tramp = total_count;
1111 inst->phys_dev_groups_tramp = new_phys_dev_groups;
1112 }
1113
1114 return res;
1115}
1116
1117VkResult setupLoaderTermPhysDevGroups(struct loader_instance *inst) {
1118 VkResult res = VK_SUCCESS;
1119 struct loader_icd_term *icd_term;
1120 uint32_t total_count = 0;
1121 uint32_t cur_icd_group_count = 0;
1122 VkPhysicalDeviceGroupPropertiesKHX **new_phys_dev_groups = NULL;
1123 VkPhysicalDeviceGroupPropertiesKHX *local_phys_dev_groups = NULL;
1124
1125 if (0 == inst->phys_dev_count_term) {
1126 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1127 "setupLoaderTermPhysDevGroups: Loader failed to setup physical "
1128 "device terminator info before calling \'EnumeratePhysicalDeviceGroupsKHX\'.");
1129 assert(false);
1130 res = VK_ERROR_INITIALIZATION_FAILED;
1131 goto out;
1132 }
1133
1134 // For each ICD, query the number of physical device groups, and then get an
1135 // internal value for those physical devices.
1136 icd_term = inst->icd_terms;
1137 for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
1138 cur_icd_group_count = 0;
1139 if (NULL == icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX) {
1140 // Treat each ICD's GPU as it's own group if the extension isn't supported
1141 res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &cur_icd_group_count, NULL);
1142 if (res != VK_SUCCESS) {
1143 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1144 "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
1145 "\'EnumeratePhysicalDevices\' to ICD %d to get plain phys dev count.",
1146 icd_idx);
1147 goto out;
1148 }
1149 } else {
1150 // Query the actual group info
1151 res = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX(icd_term->instance, &cur_icd_group_count, NULL);
1152 if (res != VK_SUCCESS) {
1153 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1154 "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
1155 "\'EnumeratePhysicalDeviceGroupsKHX\' to ICD %d to get count.",
1156 icd_idx);
1157 goto out;
1158 }
1159 }
1160 total_count += cur_icd_group_count;
1161 }
1162
1163 // Create an array for the new physical device groups, which will be stored
1164 // in the instance for the Terminator code.
1165 new_phys_dev_groups = (VkPhysicalDeviceGroupPropertiesKHX **)loader_instance_heap_alloc(
1166 inst, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
1167 if (NULL == new_phys_dev_groups) {
1168 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1169 "setupLoaderTermPhysDevGroups: Failed to allocate new physical device"
1170 " group array of size %d",
1171 total_count);
1172 res = VK_ERROR_OUT_OF_HOST_MEMORY;
1173 goto out;
1174 }
1175 memset(new_phys_dev_groups, 0, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHX *));
1176
1177 // Create a temporary array (on the stack) to keep track of the
1178 // returned VkPhysicalDevice values.
1179 local_phys_dev_groups = loader_stack_alloc(sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
1180 if (NULL == local_phys_dev_groups) {
1181 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1182 "setupLoaderTermPhysDevGroups: Failed to allocate local "
1183 "physical device group array of size %d",
1184 total_count);
1185 res = VK_ERROR_OUT_OF_HOST_MEMORY;
1186 goto out;
1187 }
1188 // Initialize the memory to something valid
1189 memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupPropertiesKHX) * total_count);
1190 for (uint32_t group = 0; group < total_count; group++) {
1191 local_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
1192 local_phys_dev_groups[group].pNext = NULL;
1193 local_phys_dev_groups[group].subsetAllocation = false;
1194 }
1195
1196 cur_icd_group_count = 0;
1197 icd_term = inst->icd_terms;
1198 for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
1199 uint32_t count_this_time = total_count - cur_icd_group_count;
1200
1201 if (NULL == icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX) {
1202 VkPhysicalDevice* phys_dev_array = loader_stack_alloc(sizeof(VkPhysicalDevice) * count_this_time);
1203 if (NULL == phys_dev_array) {
1204 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1205 "setupLoaderTermPhysDevGroups: Failed to allocate local "
1206 "physical device array of size %d",
1207 count_this_time);
1208 res = VK_ERROR_OUT_OF_HOST_MEMORY;
1209 goto out;
1210 }
1211
1212 res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &count_this_time, phys_dev_array);
1213 if (res != VK_SUCCESS) {
1214 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1215 "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
1216 "\'EnumeratePhysicalDevices\' to ICD %d to get plain phys dev count.",
1217 icd_idx);
1218 goto out;
1219 }
1220
1221 // Add each GPU as it's own group
1222 for (uint32_t indiv_gpu = 0; indiv_gpu < count_this_time; indiv_gpu++) {
1223 local_phys_dev_groups[indiv_gpu + cur_icd_group_count].physicalDeviceCount = 1;
1224 local_phys_dev_groups[indiv_gpu + cur_icd_group_count].physicalDevices[0] = phys_dev_array[indiv_gpu];
1225 }
1226
1227 } else {
1228 res = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHX(icd_term->instance, &count_this_time, &local_phys_dev_groups[cur_icd_group_count]);
1229 if (VK_SUCCESS != res) {
1230 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1231 "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
1232 "\'EnumeratePhysicalDeviceGroupsKHX\' to ICD %d to get content.",
1233 icd_idx);
1234 goto out;
1235 }
1236 }
1237
1238 cur_icd_group_count += count_this_time;
1239 }
1240
1241 // Replace all the physical device IDs with the proper loader values
1242 for (uint32_t group = 0; group < total_count; group++) {
1243 for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) {
1244 bool found = false;
1245 for (uint32_t term_gpu = 0; term_gpu < inst->phys_dev_count_term; term_gpu++) {
1246 if (local_phys_dev_groups[group].physicalDevices[group_gpu] == inst->phys_devs_term[term_gpu]->phys_dev) {
1247 local_phys_dev_groups[group].physicalDevices[group_gpu] = (VkPhysicalDevice)inst->phys_devs_term[term_gpu];
1248 found = true;
1249 break;
1250 }
1251 }
1252 if (!found) {
1253 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1254 "setupLoaderTermPhysDevGroups: Failed to find GPU %d in group %d"
1255 " returned by \'EnumeratePhysicalDeviceGroupsKHX\' in list returned"
1256 " by \'EnumeratePhysicalDevices\'", group_gpu, group);
1257 res = VK_ERROR_INITIALIZATION_FAILED;
1258 goto out;
1259 }
1260 }
1261 }
1262
1263 // Copy or create everything to fill the new array of physical device groups
1264 for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) {
1265 // Check if this physical device group with the same contents is already in the old buffer
1266 for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_term; old_idx++) {
1267 if (local_phys_dev_groups[new_idx].physicalDeviceCount == inst->phys_dev_groups_term[old_idx]->physicalDeviceCount) {
1268 bool found_all_gpus = true;
1269 for (uint32_t old_gpu = 0; old_gpu < inst->phys_dev_groups_term[old_idx]->physicalDeviceCount; old_gpu++) {
1270 bool found_gpu = false;
1271 for (uint32_t new_gpu = 0; new_gpu < local_phys_dev_groups[new_idx].physicalDeviceCount; new_gpu++) {
1272 if (local_phys_dev_groups[new_idx].physicalDevices[new_gpu] == inst->phys_dev_groups_term[old_idx]->physicalDevices[old_gpu]) {
1273 found_gpu = true;
1274 break;
1275 }
1276 }
1277
1278 if (!found_gpu) {
1279 found_all_gpus = false;
1280 break;
1281 }
1282 }
1283 if (!found_all_gpus) {
1284 continue;
1285 } else {
1286 new_phys_dev_groups[new_idx] = inst->phys_dev_groups_term[old_idx];
1287 break;
1288 }
1289 }
1290 }
1291
1292 // If this physical device group isn't in the old buffer, create it
1293 if (NULL == new_phys_dev_groups[new_idx]) {
1294 new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHX *)loader_instance_heap_alloc(
1295 inst, sizeof(VkPhysicalDeviceGroupPropertiesKHX), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
1296 if (NULL == new_phys_dev_groups[new_idx]) {
1297 loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
1298 "setupLoaderTermPhysDevGroups: Failed to allocate "
1299 "physical device group Terminator object %d",
1300 new_idx);
1301 total_count = new_idx;
1302 res = VK_ERROR_OUT_OF_HOST_MEMORY;
1303 goto out;
1304 }
1305 memcpy(new_phys_dev_groups[new_idx], &local_phys_dev_groups[new_idx],
1306 sizeof(VkPhysicalDeviceGroupPropertiesKHX));
1307 }
1308 }
1309
1310out:
1311
1312 if (VK_SUCCESS != res) {
1313 if (NULL != new_phys_dev_groups) {
1314 for (uint32_t i = 0; i < total_count; i++) {
1315 loader_instance_heap_free(inst, new_phys_dev_groups[i]);
1316 }
1317 loader_instance_heap_free(inst, new_phys_dev_groups);
1318 }
1319 total_count = 0;
1320 } else {
1321 // Free everything that didn't carry over to the new array of
1322 // physical device groups
1323 if (NULL != inst->phys_dev_groups_term) {
1324 for (uint32_t i = 0; i < inst->phys_dev_group_count_term; i++) {
1325 bool found = false;
1326 for (uint32_t j = 0; j < total_count; j++) {
1327 if (inst->phys_dev_groups_term[i] == new_phys_dev_groups[j]) {
1328 found = true;
1329 break;
1330 }
1331 }
1332 if (!found) {
1333 loader_instance_heap_free(inst, inst->phys_dev_groups_term[i]);
1334 }
1335 }
1336 loader_instance_heap_free(inst, inst->phys_dev_groups_term);
1337 }
1338
1339 // Swap in the new physical device group list
1340 inst->phys_dev_group_count_term = total_count;
1341 inst->phys_dev_groups_term = new_phys_dev_groups;
1342 }
1343
1344 return res;
Mark Youngabc2d6e2017-07-07 07:59:56 -06001345}