blob: fab25813f53cbd5de12e19a137bef9faa7f48915 [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
Tom Andersona8358802018-07-25 17:10:16 -070022#ifndef _GNU_SOURCE
Mark Young0746fce2017-03-10 17:31:18 -070023#define _GNU_SOURCE
Tom Andersona8358802018-07-25 17:10:16 -070024#endif
Mark Young0746fce2017-03-10 17:31:18 -070025#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include "vk_loader_platform.h"
29#include "loader.h"
30#include "vk_loader_extensions.h"
31#include <vulkan/vk_icd.h>
32#include "wsi.h"
Mark Younge3e9b562017-11-09 10:37:04 -070033#include "debug_utils.h"
Mark Young0746fce2017-03-10 17:31:18 -070034
35// ---- Manually added trampoline/terminator functions
36
37// These functions, for whatever reason, require more complex changes than
38// can easily be automatically generated.
Mark Young0746fce2017-03-10 17:31:18 -070039
Lenny Komow31217432017-10-02 15:08:53 -060040// ---- VK_NV_external_memory_capabilities extension trampoline/terminators
41
42VKAPI_ATTR VkResult VKAPI_CALL
43GetPhysicalDeviceExternalImageFormatPropertiesNV(
44 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
45 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
46 VkExternalMemoryHandleTypeFlagsNV externalHandleType,
47 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
48 const VkLayerInstanceDispatchTable *disp;
49 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
50 disp = loader_get_instance_layer_dispatch(physicalDevice);
51
52 return disp->GetPhysicalDeviceExternalImageFormatPropertiesNV(
53 unwrapped_phys_dev, format, type, tiling, usage, flags,
54 externalHandleType, pExternalImageFormatProperties);
55}
56
57VKAPI_ATTR VkResult VKAPI_CALL
58terminator_GetPhysicalDeviceExternalImageFormatPropertiesNV(
59 VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
60 VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
61 VkExternalMemoryHandleTypeFlagsNV externalHandleType,
62 VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
63 struct loader_physical_device_term *phys_dev_term =
64 (struct loader_physical_device_term *)physicalDevice;
65 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
66
67 if (!icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV) {
68 if (externalHandleType) {
69 return VK_ERROR_FORMAT_NOT_SUPPORTED;
70 }
71
72 if (!icd_term->dispatch.GetPhysicalDeviceImageFormatProperties) {
73 return VK_ERROR_INITIALIZATION_FAILED;
74 }
75
76 pExternalImageFormatProperties->externalMemoryFeatures = 0;
77 pExternalImageFormatProperties->exportFromImportedHandleTypes = 0;
78 pExternalImageFormatProperties->compatibleHandleTypes = 0;
79
80 return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(
81 phys_dev_term->phys_dev, format, type, tiling, usage, flags,
82 &pExternalImageFormatProperties->imageFormatProperties);
83 }
84
85 return icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV(
86 phys_dev_term->phys_dev, format, type, tiling, usage, flags,
87 externalHandleType, pExternalImageFormatProperties);
88}
89
Lenny Komow0e5b07e2017-06-01 13:32:28 -060090// ---- VK_EXT_display_surface_counter extension trampoline/terminators
91
92VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
93 VkSurfaceCapabilities2EXT *pSurfaceCapabilities) {
94 const VkLayerInstanceDispatchTable *disp;
95 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
96 disp = loader_get_instance_layer_dispatch(physicalDevice);
97 return disp->GetPhysicalDeviceSurfaceCapabilities2EXT(unwrapped_phys_dev, surface, pSurfaceCapabilities);
98}
99
100VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2EXT(
101 VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT *pSurfaceCapabilities) {
102 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
103 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
104
105 VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
106 uint8_t icd_index = phys_dev_term->icd_index;
107
108 // Unwrap the surface if needed
109 VkSurfaceKHR unwrapped_surface = surface;
110 if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
111 unwrapped_surface = icd_surface->real_icd_surfaces[icd_index];
112 }
113
114 if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT != NULL) {
115 // Pass the call to the driver
116 return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT(phys_dev_term->phys_dev, unwrapped_surface,
117 pSurfaceCapabilities);
118 } else {
119 // Emulate the call
120 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
121 "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulating call in ICD \"%s\" using "
122 "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
123 icd_term->scanned_icd->lib_name);
124
125 VkSurfaceCapabilitiesKHR surface_caps;
126 VkResult res =
127 icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, unwrapped_surface, &surface_caps);
128 pSurfaceCapabilities->minImageCount = surface_caps.minImageCount;
129 pSurfaceCapabilities->maxImageCount = surface_caps.maxImageCount;
130 pSurfaceCapabilities->currentExtent = surface_caps.currentExtent;
131 pSurfaceCapabilities->minImageExtent = surface_caps.minImageExtent;
132 pSurfaceCapabilities->maxImageExtent = surface_caps.maxImageExtent;
133 pSurfaceCapabilities->maxImageArrayLayers = surface_caps.maxImageArrayLayers;
134 pSurfaceCapabilities->supportedTransforms = surface_caps.supportedTransforms;
135 pSurfaceCapabilities->currentTransform = surface_caps.currentTransform;
136 pSurfaceCapabilities->supportedCompositeAlpha = surface_caps.supportedCompositeAlpha;
137 pSurfaceCapabilities->supportedUsageFlags = surface_caps.supportedUsageFlags;
138 pSurfaceCapabilities->supportedSurfaceCounters = 0;
139
140 if (pSurfaceCapabilities->pNext != NULL) {
141 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
142 "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulation found unrecognized structure type in "
143 "pSurfaceCapabilities->pNext - this struct will be ignored");
144 }
145
146 return res;
147 }
148}
149
150// ---- VK_EXT_direct_mode_display extension trampoline/terminators
151
152VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
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->ReleaseDisplayEXT(unwrapped_phys_dev, display);
157}
158
159VKAPI_ATTR VkResult VKAPI_CALL terminator_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
160 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
161 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
162
163 if (icd_term->dispatch.ReleaseDisplayEXT == NULL) {
164 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
165 "ICD \"%s\" associated with VkPhysicalDevice does not support vkReleaseDisplayEXT - Consequently, the call is "
166 "invalid because it should not be possible to acquire a display on this device",
167 icd_term->scanned_icd->lib_name);
168 }
169 return icd_term->dispatch.ReleaseDisplayEXT(phys_dev_term->phys_dev, display);
170}
171
172// ---- VK_EXT_acquire_xlib_display extension trampoline/terminators
173
174#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
175VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, VkDisplayKHR display) {
176 const VkLayerInstanceDispatchTable *disp;
177 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
178 disp = loader_get_instance_layer_dispatch(physicalDevice);
179 return disp->AcquireXlibDisplayEXT(unwrapped_phys_dev, dpy, display);
180}
181
182VKAPI_ATTR VkResult VKAPI_CALL terminator_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy,
183 VkDisplayKHR display) {
184 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
185 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
186
187 if (icd_term->dispatch.AcquireXlibDisplayEXT != NULL) {
188 // Pass the call to the driver
189 return icd_term->dispatch.AcquireXlibDisplayEXT(phys_dev_term->phys_dev, dpy, display);
190 } else {
191 // Emulate the call
192 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
193 "vkAcquireXLibDisplayEXT: Emulating call in ICD \"%s\" by returning error", icd_term->scanned_icd->lib_name);
194
195 // Fail for the unsupported command
196 return VK_ERROR_INITIALIZATION_FAILED;
197 }
198}
199
200VKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput,
201 VkDisplayKHR *pDisplay) {
202 const VkLayerInstanceDispatchTable *disp;
203 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
204 disp = loader_get_instance_layer_dispatch(physicalDevice);
205 return disp->GetRandROutputDisplayEXT(unwrapped_phys_dev, dpy, rrOutput, pDisplay);
206}
207
208VKAPI_ATTR VkResult VKAPI_CALL terminator_GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput,
209 VkDisplayKHR *pDisplay) {
210 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
211 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
212
213 if (icd_term->dispatch.GetRandROutputDisplayEXT != NULL) {
214 // Pass the call to the driver
215 return icd_term->dispatch.GetRandROutputDisplayEXT(phys_dev_term->phys_dev, dpy, rrOutput, pDisplay);
216 } else {
217 // Emulate the call
218 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
219 "vkGetRandROutputDisplayEXT: Emulating call in ICD \"%s\" by returning null display",
220 icd_term->scanned_icd->lib_name);
221
222 // Return a null handle to indicate this can't be done
223 *pDisplay = VK_NULL_HANDLE;
224 return VK_SUCCESS;
225 }
226}
227
228#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
Lenny Komowc51f36f2019-04-15 14:49:58 -0600229
230#ifdef VK_USE_PLATFORM_WIN32_KHR
231VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModes2EXT(
232 VkPhysicalDevice physicalDevice,
233 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
234 uint32_t* pPresentModeCount,
235 VkPresentModeKHR* pPresentModes) {
236 const VkLayerInstanceDispatchTable *disp;
237 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
238 disp = loader_get_instance_layer_dispatch(physicalDevice);
239 return disp->GetPhysicalDeviceSurfacePresentModes2EXT(unwrapped_phys_dev, pSurfaceInfo, pPresentModeCount, pPresentModes);
240}
241
242VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModes2EXT(
243 VkPhysicalDevice physicalDevice,
244 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
245 uint32_t* pPresentModeCount,
246 VkPresentModeKHR* pPresentModes) {
247 struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
248 struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
249 if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT) {
250 loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
251 "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceSurfacePresentModes2EXT");
252 }
253 VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
254 uint8_t icd_index = phys_dev_term->icd_index;
255 if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {
256 const VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy = {
257 .sType = pSurfaceInfo->sType,
258 .pNext = pSurfaceInfo->pNext,
259 .surface = icd_surface->real_icd_surfaces[icd_index],
260 };
261 return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, &surface_info_copy, pPresentModeCount, pPresentModes);
262 }
263 return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, pSurfaceInfo, pPresentModeCount, pPresentModes);
264}
Lenny Komowc51f36f2019-04-15 14:49:58 -0600265
266VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupSurfacePresentModes2EXT(
267 VkDevice device,
268 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
269 VkDeviceGroupPresentModeFlagsKHR* pModes) {
270 const VkLayerDispatchTable *disp = loader_get_dispatch(device);
271 return disp->GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes);
272}
273
274VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModes2EXT(
275 VkDevice device,
276 const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
277 VkDeviceGroupPresentModeFlagsKHR* pModes) {
278 uint32_t icd_index = 0;
279 struct loader_device *dev;
280 struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
281 if (NULL != icd_term && NULL != icd_term->dispatch.GetDeviceGroupSurfacePresentModes2EXT) {
282 VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface;
283 if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) {
284 const VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy = {
285 .sType = pSurfaceInfo->sType,
286 .pNext = pSurfaceInfo->pNext,
287 .surface = icd_surface->real_icd_surfaces[icd_index],
288 };
289 return icd_term->dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, &surface_info_copy, pModes);
290 }
291 return icd_term->dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes);
292 }
293 return VK_SUCCESS;
294}
Shannon McPherson392a7eb2019-05-22 15:41:13 -0600295
296#endif // VK_USE_PLATFORM_WIN32_KHR
Lenny Komow20697982019-12-12 15:38:07 -0700297
298// ---- VK_EXT_tooling_info extension trampoline/terminators
299
300VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceToolPropertiesEXT(
301 VkPhysicalDevice physicalDevice,
302 uint32_t* pToolCount,
303 VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
304 const VkLayerInstanceDispatchTable *disp;
305 VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
306 disp = loader_get_instance_layer_dispatch(physicalDevice);
307 return disp->GetPhysicalDeviceToolPropertiesEXT(unwrapped_phys_dev, pToolCount, pToolProperties);
308}
309
310VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceToolPropertiesEXT(
311 VkPhysicalDevice physicalDevice,
312 uint32_t* pToolCount,
313 VkPhysicalDeviceToolPropertiesEXT* pToolProperties) {
314 return VK_SUCCESS;
315}