blob: 65c625ea2437697100fc8e61d0dc2dd719996574 [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.
Mark Young0746fce2017-03-10 17:31:18 -070037
Mark Lobodzinski7bc29f42017-09-18 16:28:27 -060038// ---- VK_KHR_device_group extension trampoline/terminators
Lenny Komow0e5b07e2017-06-01 13:32:28 -060039
Lenny Komow3d31f062017-05-30 13:04:46 -060040VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
41 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
42 VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
43 const VkLayerInstanceDispatchTable *disp;
44 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
45 disp = loader_get_instance_layer_dispatch(physicalDevice);
46 return disp->GetPhysicalDeviceSurfaceCapabilities2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceCapabilities);
47}
48
49VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2KHR(
50 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
51 VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
52 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
53 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
54
55 VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
56 uint8_t icd_index = phys_dev_term->icd_index;
57
58 if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) {
59 // Pass the call to the driver, possibly unwrapping the ICD surface
60 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
61 VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
62 info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
63 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy,
64 pSurfaceCapabilities);
65 } else {
66 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
67 pSurfaceCapabilities);
68 }
69 } else {
70 // Emulate the call
71 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
72 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulating call in ICD \"%s\" using "
73 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
74 icd_term->scanned_icd->lib_name);
75
76 if (pSurfaceInfo->pNext != NULL) {
77 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
78 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
79 "pSurfaceInfo->pNext - this struct will be ignored");
80 }
81
82 // Write to the VkSurfaceCapabilities2KHR struct
83 VkSurfaceKHR surface = pSurfaceInfo->surface;
84 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
85 surface = icd_surface->real_icd_surfaces[icd_index];
86 }
87 VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface,
88 &pSurfaceCapabilities->surfaceCapabilities);
89
90 if (pSurfaceCapabilities->pNext != NULL) {
91 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
92 "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
93 "pSurfaceCapabilities->pNext - this struct will be ignored");
94 }
95 return res;
96 }
97}
98
Lenny Komow31217432017-10-02 15:08:53 -060099// ---- VK_NV_external_memory_capabilities extension trampoline/terminators
100
101VKAPI_ATTR VkResult VKAPI_CALL
102GetPhysicalDeviceExternalImageFormatPropertiesNV(
103 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
104 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
105 VkExternalMemoryHandleTypeFlagsNV externalHandleType,
106 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
107 const VkLayerInstanceDispatchTable *disp;
108 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
109 disp = loader_get_instance_layer_dispatch(physicalDevice);
110
111 return disp->GetPhysicalDeviceExternalImageFormatPropertiesNV(
112 unwrapped_phys_dev, format, type, tiling, usage, flags,
113 externalHandleType, pExternalImageFormatProperties);
114}
115
116VKAPI_ATTR VkResult VKAPI_CALL
117terminator_GetPhysicalDeviceExternalImageFormatPropertiesNV(
118 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
119 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
120 VkExternalMemoryHandleTypeFlagsNV externalHandleType,
121 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
122 struct loader_physical_device_term *phys_dev_term =
123 (struct loader_physical_device_term *)physicalDevice;
124 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
125
126 if (!icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV) {
127 if (externalHandleType) {
128 return VK_ERROR_FORMAT_NOT_SUPPORTED;
129 }
130
131 if (!icd_term->dispatch.GetPhysicalDeviceImageFormatProperties) {
132 return VK_ERROR_INITIALIZATION_FAILED;
133 }
134
135 pExternalImageFormatProperties->externalMemoryFeatures = 0;
136 pExternalImageFormatProperties->exportFromImportedHandleTypes = 0;
137 pExternalImageFormatProperties->compatibleHandleTypes = 0;
138
139 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(
140 phys_dev_term->phys_dev, format, type, tiling, usage, flags,
141 &pExternalImageFormatProperties->imageFormatProperties);
142 }
143
144 return icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV(
145 phys_dev_term->phys_dev, format, type, tiling, usage, flags,
146 externalHandleType, pExternalImageFormatProperties);
147}
148
Lenny Komow3d31f062017-05-30 13:04:46 -0600149VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
150 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
151 uint32_t *pSurfaceFormatCount,
152 VkSurfaceFormat2KHR *pSurfaceFormats) {
153 const VkLayerInstanceDispatchTable *disp;
154 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
155 disp = loader_get_instance_layer_dispatch(physicalDevice);
156 return disp->GetPhysicalDeviceSurfaceFormats2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats);
157}
158
159VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
160 const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
161 uint32_t *pSurfaceFormatCount,
162 VkSurfaceFormat2KHR *pSurfaceFormats) {
163 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
164 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
165
166 VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
167 uint8_t icd_index = phys_dev_term->icd_index;
168
169 if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) {
170 // Pass the call to the driver, possibly unwrapping the ICD surface
171 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
172 VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
173 info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
174 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount,
175 pSurfaceFormats);
176 } else {
177 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
178 pSurfaceFormatCount, pSurfaceFormats);
179 }
180 } else {
181 // Emulate the call
182 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
183 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceSurfaceFormatsKHR",
184 icd_term->scanned_icd->lib_name);
185
186 if (pSurfaceInfo->pNext != NULL) {
187 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
188 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in pSurfaceInfo->pNext "
189 "- this struct will be ignored");
190 }
191
192 VkSurfaceKHR surface = pSurfaceInfo->surface;
193 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
194 surface = icd_surface->real_icd_surfaces[icd_index];
195 }
196
197 if (*pSurfaceFormatCount == 0 || pSurfaceFormats == NULL) {
198 // Write to pSurfaceFormatCount
199 return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
200 NULL);
201 } else {
202 // Allocate a temporary array for the output of the old function
203 VkSurfaceFormatKHR *formats = loader_stack_alloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
204 if (formats == NULL) {
205 return VK_ERROR_OUT_OF_HOST_MEMORY;
206 }
207
208 VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface,
209 pSurfaceFormatCount, formats);
210 for (uint32_t i = 0; i < *pSurfaceFormatCount; ++i) {
211 pSurfaceFormats[i].surfaceFormat = formats[i];
212 if (pSurfaceFormats[i].pNext != NULL) {
213 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
214 "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in "
215 "pSurfaceFormats[%d].pNext - this struct will be ignored",
216 i);
217 }
218 }
219 return res;
220 }
221 }
222}
223
Lenny Komow0e5b07e2017-06-01 13:32:28 -0600224// ---- VK_EXT_display_surface_counter extension trampoline/terminators
225
226VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
227 VkSurfaceCapabilities2EXT *pSurfaceCapabilities) {
228 const VkLayerInstanceDispatchTable *disp;
229 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
230 disp = loader_get_instance_layer_dispatch(physicalDevice);
231 return disp->GetPhysicalDeviceSurfaceCapabilities2EXT(unwrapped_phys_dev, surface, pSurfaceCapabilities);
232}
233
234VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2EXT(
235 VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT *pSurfaceCapabilities) {
236 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
237 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
238
239 VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
240 uint8_t icd_index = phys_dev_term->icd_index;
241
242 // Unwrap the surface if needed
243 VkSurfaceKHR unwrapped_surface = surface;
244 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
245 unwrapped_surface = icd_surface->real_icd_surfaces[icd_index];
246 }
247
248 if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT != NULL) {
249 // Pass the call to the driver
250 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT(phys_dev_term->phys_dev, unwrapped_surface,
251 pSurfaceCapabilities);
252 } else {
253 // Emulate the call
254 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
255 "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulating call in ICD \"%s\" using "
256 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
257 icd_term->scanned_icd->lib_name);
258
259 VkSurfaceCapabilitiesKHR surface_caps;
260 VkResult res =
261 icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, unwrapped_surface, &surface_caps);
262 pSurfaceCapabilities->minImageCount = surface_caps.minImageCount;
263 pSurfaceCapabilities->maxImageCount = surface_caps.maxImageCount;
264 pSurfaceCapabilities->currentExtent = surface_caps.currentExtent;
265 pSurfaceCapabilities->minImageExtent = surface_caps.minImageExtent;
266 pSurfaceCapabilities->maxImageExtent = surface_caps.maxImageExtent;
267 pSurfaceCapabilities->maxImageArrayLayers = surface_caps.maxImageArrayLayers;
268 pSurfaceCapabilities->supportedTransforms = surface_caps.supportedTransforms;
269 pSurfaceCapabilities->currentTransform = surface_caps.currentTransform;
270 pSurfaceCapabilities->supportedCompositeAlpha = surface_caps.supportedCompositeAlpha;
271 pSurfaceCapabilities->supportedUsageFlags = surface_caps.supportedUsageFlags;
272 pSurfaceCapabilities->supportedSurfaceCounters = 0;
273
274 if (pSurfaceCapabilities->pNext != NULL) {
275 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
276 "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulation found unrecognized structure type in "
277 "pSurfaceCapabilities->pNext - this struct will be ignored");
278 }
279
280 return res;
281 }
282}
283
284// ---- VK_EXT_direct_mode_display extension trampoline/terminators
285
286VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
287 const VkLayerInstanceDispatchTable *disp;
288 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
289 disp = loader_get_instance_layer_dispatch(physicalDevice);
290 return disp->ReleaseDisplayEXT(unwrapped_phys_dev, display);
291}
292
293VKAPI_ATTR VkResult VKAPI_CALL terminator_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
294 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
295 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
296
297 if (icd_term->dispatch.ReleaseDisplayEXT == NULL) {
298 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
299 "ICD \"%s\" associated with VkPhysicalDevice does not support vkReleaseDisplayEXT - Consequently, the call is "
300 "invalid because it should not be possible to acquire a display on this device",
301 icd_term->scanned_icd->lib_name);
302 }
303 return icd_term->dispatch.ReleaseDisplayEXT(phys_dev_term->phys_dev, display);
304}
305
306// ---- VK_EXT_acquire_xlib_display extension trampoline/terminators
307
308#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
309VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, VkDisplayKHR display) {
310 const VkLayerInstanceDispatchTable *disp;
311 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
312 disp = loader_get_instance_layer_dispatch(physicalDevice);
313 return disp->AcquireXlibDisplayEXT(unwrapped_phys_dev, dpy, display);
314}
315
316VKAPI_ATTR VkResult VKAPI_CALL terminator_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy,
317 VkDisplayKHR display) {
318 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
319 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
320
321 if (icd_term->dispatch.AcquireXlibDisplayEXT != NULL) {
322 // Pass the call to the driver
323 return icd_term->dispatch.AcquireXlibDisplayEXT(phys_dev_term->phys_dev, dpy, display);
324 } else {
325 // Emulate the call
326 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
327 "vkAcquireXLibDisplayEXT: Emulating call in ICD \"%s\" by returning error", icd_term->scanned_icd->lib_name);
328
329 // Fail for the unsupported command
330 return VK_ERROR_INITIALIZATION_FAILED;
331 }
332}
333
334VKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput,
335 VkDisplayKHR *pDisplay) {
336 const VkLayerInstanceDispatchTable *disp;
337 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
338 disp = loader_get_instance_layer_dispatch(physicalDevice);
339 return disp->GetRandROutputDisplayEXT(unwrapped_phys_dev, dpy, rrOutput, pDisplay);
340}
341
342VKAPI_ATTR VkResult VKAPI_CALL terminator_GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput,
343 VkDisplayKHR *pDisplay) {
344 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
345 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
346
347 if (icd_term->dispatch.GetRandROutputDisplayEXT != NULL) {
348 // Pass the call to the driver
349 return icd_term->dispatch.GetRandROutputDisplayEXT(phys_dev_term->phys_dev, dpy, rrOutput, pDisplay);
350 } else {
351 // Emulate the call
352 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
353 "vkGetRandROutputDisplayEXT: Emulating call in ICD \"%s\" by returning null display",
354 icd_term->scanned_icd->lib_name);
355
356 // Return a null handle to indicate this can't be done
357 *pDisplay = VK_NULL_HANDLE;
358 return VK_SUCCESS;
359 }
360}
361
362#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT