1 /*
2 * Copyright © 2017 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
23 #include <stdbool.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sys/ioctl.h>
28 #include "tu_private.h"
29 #include "tu_cs.h"
30 #include "util/disk_cache.h"
31 #include "util/strtod.h"
32 #include "vk_util.h"
33 #include "vk_format.h"
34 #include "util/debug.h"
35 #include "wsi_common_display.h"
36
37 VkResult
tu_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayPropertiesKHR * properties)38 tu_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physical_device,
39 uint32_t *property_count,
40 VkDisplayPropertiesKHR *properties)
41 {
42 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
43
44 return wsi_display_get_physical_device_display_properties(
45 physical_device,
46 &pdevice->wsi_device,
47 property_count,
48 properties);
49 }
50
51 VkResult
tu_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayProperties2KHR * properties)52 tu_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physical_device,
53 uint32_t *property_count,
54 VkDisplayProperties2KHR *properties)
55 {
56 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
57
58 return wsi_display_get_physical_device_display_properties2(
59 physical_device,
60 &pdevice->wsi_device,
61 property_count,
62 properties);
63 }
64
65 VkResult
tu_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayPlanePropertiesKHR * properties)66 tu_GetPhysicalDeviceDisplayPlanePropertiesKHR(
67 VkPhysicalDevice physical_device,
68 uint32_t *property_count,
69 VkDisplayPlanePropertiesKHR *properties)
70 {
71 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
72
73 return wsi_display_get_physical_device_display_plane_properties(
74 physical_device,
75 &pdevice->wsi_device,
76 property_count,
77 properties);
78 }
79
80 VkResult
tu_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayPlaneProperties2KHR * properties)81 tu_GetPhysicalDeviceDisplayPlaneProperties2KHR(
82 VkPhysicalDevice physical_device,
83 uint32_t *property_count,
84 VkDisplayPlaneProperties2KHR *properties)
85 {
86 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
87
88 return wsi_display_get_physical_device_display_plane_properties2(
89 physical_device,
90 &pdevice->wsi_device,
91 property_count,
92 properties);
93 }
94
95 VkResult
tu_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physical_device,uint32_t plane_index,uint32_t * display_count,VkDisplayKHR * displays)96 tu_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physical_device,
97 uint32_t plane_index,
98 uint32_t *display_count,
99 VkDisplayKHR *displays)
100 {
101 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
102
103 return wsi_display_get_display_plane_supported_displays(
104 physical_device,
105 &pdevice->wsi_device,
106 plane_index,
107 display_count,
108 displays);
109 }
110
111
112 VkResult
tu_GetDisplayModePropertiesKHR(VkPhysicalDevice physical_device,VkDisplayKHR display,uint32_t * property_count,VkDisplayModePropertiesKHR * properties)113 tu_GetDisplayModePropertiesKHR(VkPhysicalDevice physical_device,
114 VkDisplayKHR display,
115 uint32_t *property_count,
116 VkDisplayModePropertiesKHR *properties)
117 {
118 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
119
120 return wsi_display_get_display_mode_properties(physical_device,
121 &pdevice->wsi_device,
122 display,
123 property_count,
124 properties);
125 }
126
127 VkResult
tu_GetDisplayModeProperties2KHR(VkPhysicalDevice physical_device,VkDisplayKHR display,uint32_t * property_count,VkDisplayModeProperties2KHR * properties)128 tu_GetDisplayModeProperties2KHR(VkPhysicalDevice physical_device,
129 VkDisplayKHR display,
130 uint32_t *property_count,
131 VkDisplayModeProperties2KHR *properties)
132 {
133 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
134
135 return wsi_display_get_display_mode_properties2(physical_device,
136 &pdevice->wsi_device,
137 display,
138 property_count,
139 properties);
140 }
141
142 VkResult
tu_CreateDisplayModeKHR(VkPhysicalDevice physical_device,VkDisplayKHR display,const VkDisplayModeCreateInfoKHR * create_info,const VkAllocationCallbacks * allocator,VkDisplayModeKHR * mode)143 tu_CreateDisplayModeKHR(VkPhysicalDevice physical_device,
144 VkDisplayKHR display,
145 const VkDisplayModeCreateInfoKHR *create_info,
146 const VkAllocationCallbacks *allocator,
147 VkDisplayModeKHR *mode)
148 {
149 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
150
151 return wsi_display_create_display_mode(physical_device,
152 &pdevice->wsi_device,
153 display,
154 create_info,
155 allocator,
156 mode);
157 }
158
159 VkResult
tu_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physical_device,VkDisplayModeKHR mode_khr,uint32_t plane_index,VkDisplayPlaneCapabilitiesKHR * capabilities)160 tu_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physical_device,
161 VkDisplayModeKHR mode_khr,
162 uint32_t plane_index,
163 VkDisplayPlaneCapabilitiesKHR *capabilities)
164 {
165 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
166
167 return wsi_get_display_plane_capabilities(physical_device,
168 &pdevice->wsi_device,
169 mode_khr,
170 plane_index,
171 capabilities);
172 }
173
174 VkResult
tu_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physical_device,const VkDisplayPlaneInfo2KHR * pDisplayPlaneInfo,VkDisplayPlaneCapabilities2KHR * capabilities)175 tu_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physical_device,
176 const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
177 VkDisplayPlaneCapabilities2KHR *capabilities)
178 {
179 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
180
181 return wsi_get_display_plane_capabilities2(physical_device,
182 &pdevice->wsi_device,
183 pDisplayPlaneInfo,
184 capabilities);
185 }
186
187 VkResult
tu_CreateDisplayPlaneSurfaceKHR(VkInstance _instance,const VkDisplaySurfaceCreateInfoKHR * create_info,const VkAllocationCallbacks * allocator,VkSurfaceKHR * surface)188 tu_CreateDisplayPlaneSurfaceKHR(
189 VkInstance _instance,
190 const VkDisplaySurfaceCreateInfoKHR *create_info,
191 const VkAllocationCallbacks *allocator,
192 VkSurfaceKHR *surface)
193 {
194 TU_FROM_HANDLE(tu_instance, instance, _instance);
195 const VkAllocationCallbacks *alloc;
196
197 if (allocator)
198 alloc = allocator;
199 else
200 alloc = &instance->alloc;
201
202 return wsi_create_display_surface(_instance, alloc,
203 create_info, surface);
204 }
205
206 VkResult
tu_ReleaseDisplayEXT(VkPhysicalDevice physical_device,VkDisplayKHR display)207 tu_ReleaseDisplayEXT(VkPhysicalDevice physical_device,
208 VkDisplayKHR display)
209 {
210 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
211
212 return wsi_release_display(physical_device,
213 &pdevice->wsi_device,
214 display);
215 }
216
217 #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
218 VkResult
tu_AcquireXlibDisplayEXT(VkPhysicalDevice physical_device,Display * dpy,VkDisplayKHR display)219 tu_AcquireXlibDisplayEXT(VkPhysicalDevice physical_device,
220 Display *dpy,
221 VkDisplayKHR display)
222 {
223 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
224
225 return wsi_acquire_xlib_display(physical_device,
226 &pdevice->wsi_device,
227 dpy,
228 display);
229 }
230
231 VkResult
tu_GetRandROutputDisplayEXT(VkPhysicalDevice physical_device,Display * dpy,RROutput output,VkDisplayKHR * display)232 tu_GetRandROutputDisplayEXT(VkPhysicalDevice physical_device,
233 Display *dpy,
234 RROutput output,
235 VkDisplayKHR *display)
236 {
237 TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
238
239 return wsi_get_randr_output_display(physical_device,
240 &pdevice->wsi_device,
241 dpy,
242 output,
243 display);
244 }
245 #endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */
246
247 /* VK_EXT_display_control */
248
249 VkResult
tu_DisplayPowerControlEXT(VkDevice _device,VkDisplayKHR display,const VkDisplayPowerInfoEXT * display_power_info)250 tu_DisplayPowerControlEXT(VkDevice _device,
251 VkDisplayKHR display,
252 const VkDisplayPowerInfoEXT *display_power_info)
253 {
254 TU_FROM_HANDLE(tu_device, device, _device);
255
256 return wsi_display_power_control(_device,
257 &device->physical_device->wsi_device,
258 display,
259 display_power_info);
260 }
261
262 VkResult
tu_RegisterDeviceEventEXT(VkDevice _device,const VkDeviceEventInfoEXT * device_event_info,const VkAllocationCallbacks * allocator,VkFence * _fence)263 tu_RegisterDeviceEventEXT(VkDevice _device,
264 const VkDeviceEventInfoEXT *device_event_info,
265 const VkAllocationCallbacks *allocator,
266 VkFence *_fence)
267 {
268 TU_FROM_HANDLE(tu_device, device, _device);
269 VkResult ret;
270
271 ret = tu_CreateFence(_device, &(VkFenceCreateInfo) {}, allocator, _fence);
272 if (ret != VK_SUCCESS)
273 return ret;
274
275 TU_FROM_HANDLE(tu_syncobj, fence, *_fence);
276
277 int sync_fd = tu_syncobj_to_fd(device, fence);
278 if (sync_fd >= 0) {
279 ret = wsi_register_device_event(_device,
280 &device->physical_device->wsi_device,
281 device_event_info,
282 allocator,
283 NULL,
284 sync_fd);
285
286 close(sync_fd);
287 } else {
288 ret = VK_ERROR_OUT_OF_HOST_MEMORY;
289 }
290
291 if (ret != VK_SUCCESS)
292 tu_DestroyFence(_device, *_fence, allocator);
293
294 return ret;
295 }
296
297 VkResult
tu_RegisterDisplayEventEXT(VkDevice _device,VkDisplayKHR display,const VkDisplayEventInfoEXT * display_event_info,const VkAllocationCallbacks * allocator,VkFence * _fence)298 tu_RegisterDisplayEventEXT(VkDevice _device,
299 VkDisplayKHR display,
300 const VkDisplayEventInfoEXT *display_event_info,
301 const VkAllocationCallbacks *allocator,
302 VkFence *_fence)
303 {
304 TU_FROM_HANDLE(tu_device, device, _device);
305 VkResult ret;
306
307 ret = tu_CreateFence(_device, &(VkFenceCreateInfo) {}, allocator, _fence);
308 if (ret != VK_SUCCESS)
309 return ret;
310
311 TU_FROM_HANDLE(tu_syncobj, fence, *_fence);
312
313 int sync_fd = tu_syncobj_to_fd(device, fence);
314 if (sync_fd >= 0) {
315 ret = wsi_register_display_event(_device,
316 &device->physical_device->wsi_device,
317 display,
318 display_event_info,
319 allocator,
320 NULL,
321 sync_fd);
322
323 close(sync_fd);
324 } else {
325 ret = VK_ERROR_OUT_OF_HOST_MEMORY;
326 }
327
328 if (ret != VK_SUCCESS)
329 tu_DestroyFence(_device, *_fence, allocator);
330
331 return ret;
332 }
333
334 VkResult
tu_GetSwapchainCounterEXT(VkDevice _device,VkSwapchainKHR swapchain,VkSurfaceCounterFlagBitsEXT flag_bits,uint64_t * value)335 tu_GetSwapchainCounterEXT(VkDevice _device,
336 VkSwapchainKHR swapchain,
337 VkSurfaceCounterFlagBitsEXT flag_bits,
338 uint64_t *value)
339 {
340 TU_FROM_HANDLE(tu_device, device, _device);
341
342 return wsi_get_swapchain_counter(_device,
343 &device->physical_device->wsi_device,
344 swapchain,
345 flag_bits,
346 value);
347 }
348
349