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 "tu_private.h"
28 #include "tu_cs.h"
29 #include "util/disk_cache.h"
30 #include "util/strtod.h"
31 #include "vk_util.h"
32 #include <xf86drm.h>
33 #include <xf86drmMode.h>
34 #include "vk_format.h"
35 #include "util/debug.h"
36 #include "wsi_common_display.h"
37 
38 VkResult
tu_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayPropertiesKHR * properties)39 tu_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physical_device,
40                                          uint32_t *property_count,
41                                          VkDisplayPropertiesKHR *properties)
42 {
43    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
44 
45    return wsi_display_get_physical_device_display_properties(
46              physical_device,
47              &pdevice->wsi_device,
48              property_count,
49              properties);
50 }
51 
52 VkResult
tu_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayProperties2KHR * properties)53 tu_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physical_device,
54                                           uint32_t *property_count,
55                                           VkDisplayProperties2KHR *properties)
56 {
57    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
58 
59    return wsi_display_get_physical_device_display_properties2(
60              physical_device,
61              &pdevice->wsi_device,
62              property_count,
63              properties);
64 }
65 
66 VkResult
tu_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayPlanePropertiesKHR * properties)67 tu_GetPhysicalDeviceDisplayPlanePropertiesKHR(
68    VkPhysicalDevice physical_device,
69    uint32_t *property_count,
70    VkDisplayPlanePropertiesKHR *properties)
71 {
72    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
73 
74    return wsi_display_get_physical_device_display_plane_properties(
75              physical_device,
76              &pdevice->wsi_device,
77              property_count,
78              properties);
79 }
80 
81 VkResult
tu_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayPlaneProperties2KHR * properties)82 tu_GetPhysicalDeviceDisplayPlaneProperties2KHR(
83    VkPhysicalDevice physical_device,
84    uint32_t *property_count,
85    VkDisplayPlaneProperties2KHR *properties)
86 {
87    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
88 
89    return wsi_display_get_physical_device_display_plane_properties2(
90              physical_device,
91              &pdevice->wsi_device,
92              property_count,
93              properties);
94 }
95 
96 VkResult
tu_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physical_device,uint32_t plane_index,uint32_t * display_count,VkDisplayKHR * displays)97 tu_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physical_device,
98                                        uint32_t plane_index,
99                                        uint32_t *display_count,
100                                        VkDisplayKHR *displays)
101 {
102    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
103 
104    return wsi_display_get_display_plane_supported_displays(
105              physical_device,
106              &pdevice->wsi_device,
107              plane_index,
108              display_count,
109              displays);
110 }
111 
112 
113 VkResult
tu_GetDisplayModePropertiesKHR(VkPhysicalDevice physical_device,VkDisplayKHR display,uint32_t * property_count,VkDisplayModePropertiesKHR * properties)114 tu_GetDisplayModePropertiesKHR(VkPhysicalDevice physical_device,
115                                VkDisplayKHR display,
116                                uint32_t *property_count,
117                                VkDisplayModePropertiesKHR *properties)
118 {
119    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
120 
121    return wsi_display_get_display_mode_properties(physical_device,
122                                                   &pdevice->wsi_device,
123                                                   display,
124                                                   property_count,
125                                                   properties);
126 }
127 
128 VkResult
tu_GetDisplayModeProperties2KHR(VkPhysicalDevice physical_device,VkDisplayKHR display,uint32_t * property_count,VkDisplayModeProperties2KHR * properties)129 tu_GetDisplayModeProperties2KHR(VkPhysicalDevice physical_device,
130                                 VkDisplayKHR display,
131                                 uint32_t *property_count,
132                                 VkDisplayModeProperties2KHR *properties)
133 {
134    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
135 
136    return wsi_display_get_display_mode_properties2(physical_device,
137                                                    &pdevice->wsi_device,
138                                                    display,
139                                                    property_count,
140                                                    properties);
141 }
142 
143 VkResult
tu_CreateDisplayModeKHR(VkPhysicalDevice physical_device,VkDisplayKHR display,const VkDisplayModeCreateInfoKHR * create_info,const VkAllocationCallbacks * allocator,VkDisplayModeKHR * mode)144 tu_CreateDisplayModeKHR(VkPhysicalDevice physical_device,
145                         VkDisplayKHR display,
146                         const VkDisplayModeCreateInfoKHR *create_info,
147                         const VkAllocationCallbacks *allocator,
148                         VkDisplayModeKHR *mode)
149 {
150    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
151 
152    return wsi_display_create_display_mode(physical_device,
153                                           &pdevice->wsi_device,
154                                           display,
155                                           create_info,
156                                           allocator,
157                                           mode);
158 }
159 
160 VkResult
tu_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physical_device,VkDisplayModeKHR mode_khr,uint32_t plane_index,VkDisplayPlaneCapabilitiesKHR * capabilities)161 tu_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physical_device,
162                                   VkDisplayModeKHR mode_khr,
163                                   uint32_t plane_index,
164                                   VkDisplayPlaneCapabilitiesKHR *capabilities)
165 {
166    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
167 
168    return wsi_get_display_plane_capabilities(physical_device,
169                                              &pdevice->wsi_device,
170                                              mode_khr,
171                                              plane_index,
172                                              capabilities);
173 }
174 
175 VkResult
tu_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physical_device,const VkDisplayPlaneInfo2KHR * pDisplayPlaneInfo,VkDisplayPlaneCapabilities2KHR * capabilities)176 tu_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physical_device,
177                                    const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
178                                    VkDisplayPlaneCapabilities2KHR *capabilities)
179 {
180    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
181 
182    return wsi_get_display_plane_capabilities2(physical_device,
183                                               &pdevice->wsi_device,
184                                               pDisplayPlaneInfo,
185                                               capabilities);
186 }
187 
188 VkResult
tu_CreateDisplayPlaneSurfaceKHR(VkInstance _instance,const VkDisplaySurfaceCreateInfoKHR * create_info,const VkAllocationCallbacks * allocator,VkSurfaceKHR * surface)189 tu_CreateDisplayPlaneSurfaceKHR(
190    VkInstance _instance,
191    const VkDisplaySurfaceCreateInfoKHR *create_info,
192    const VkAllocationCallbacks *allocator,
193    VkSurfaceKHR *surface)
194 {
195    TU_FROM_HANDLE(tu_instance, instance, _instance);
196    const VkAllocationCallbacks *alloc;
197 
198    if (allocator)
199       alloc = allocator;
200    else
201       alloc = &instance->alloc;
202 
203    return wsi_create_display_surface(_instance, alloc,
204                                      create_info, surface);
205 }
206 
207 VkResult
tu_ReleaseDisplayEXT(VkPhysicalDevice physical_device,VkDisplayKHR display)208 tu_ReleaseDisplayEXT(VkPhysicalDevice physical_device,
209                      VkDisplayKHR     display)
210 {
211    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
212 
213    return wsi_release_display(physical_device,
214                               &pdevice->wsi_device,
215                               display);
216 }
217 
218 #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
219 VkResult
tu_AcquireXlibDisplayEXT(VkPhysicalDevice physical_device,Display * dpy,VkDisplayKHR display)220 tu_AcquireXlibDisplayEXT(VkPhysicalDevice     physical_device,
221                          Display              *dpy,
222                          VkDisplayKHR         display)
223 {
224    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
225 
226    return wsi_acquire_xlib_display(physical_device,
227                                    &pdevice->wsi_device,
228                                    dpy,
229                                    display);
230 }
231 
232 VkResult
tu_GetRandROutputDisplayEXT(VkPhysicalDevice physical_device,Display * dpy,RROutput output,VkDisplayKHR * display)233 tu_GetRandROutputDisplayEXT(VkPhysicalDevice  physical_device,
234                             Display           *dpy,
235                             RROutput          output,
236                             VkDisplayKHR      *display)
237 {
238    TU_FROM_HANDLE(tu_physical_device, pdevice, physical_device);
239 
240    return wsi_get_randr_output_display(physical_device,
241                                        &pdevice->wsi_device,
242                                        dpy,
243                                        output,
244                                        display);
245 }
246 #endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */
247 
248 /* VK_EXT_display_control */
249 
250 VkResult
tu_DisplayPowerControlEXT(VkDevice _device,VkDisplayKHR display,const VkDisplayPowerInfoEXT * display_power_info)251 tu_DisplayPowerControlEXT(VkDevice                    _device,
252                           VkDisplayKHR                display,
253                           const VkDisplayPowerInfoEXT *display_power_info)
254 {
255    TU_FROM_HANDLE(tu_device, device, _device);
256 
257    return wsi_display_power_control(_device,
258                                     &device->physical_device->wsi_device,
259                                     display,
260                                     display_power_info);
261 }
262 
263 VkResult
tu_RegisterDeviceEventEXT(VkDevice _device,const VkDeviceEventInfoEXT * device_event_info,const VkAllocationCallbacks * allocator,VkFence * _fence)264 tu_RegisterDeviceEventEXT(VkDevice                    _device,
265                           const VkDeviceEventInfoEXT  *device_event_info,
266                           const VkAllocationCallbacks *allocator,
267                           VkFence                     *_fence)
268 {
269    TU_FROM_HANDLE(tu_device, device, _device);
270    struct tu_fence            *fence;
271    VkResult                     ret;
272 
273    fence = vk_alloc2(&device->instance->alloc, allocator, sizeof (*fence),
274                      8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
275    if (!fence)
276       return VK_ERROR_OUT_OF_HOST_MEMORY;
277 
278    tu_fence_init(fence, false);
279 
280    ret = wsi_register_device_event(_device,
281                                    &device->physical_device->wsi_device,
282                                    device_event_info,
283                                    allocator,
284                                    &fence->fence_wsi);
285    if (ret == VK_SUCCESS)
286       *_fence = tu_fence_to_handle(fence);
287    else
288       vk_free2(&device->instance->alloc, allocator, fence);
289    return ret;
290 }
291 
292 VkResult
tu_RegisterDisplayEventEXT(VkDevice _device,VkDisplayKHR display,const VkDisplayEventInfoEXT * display_event_info,const VkAllocationCallbacks * allocator,VkFence * _fence)293 tu_RegisterDisplayEventEXT(VkDevice                           _device,
294                            VkDisplayKHR                       display,
295                            const VkDisplayEventInfoEXT        *display_event_info,
296                            const VkAllocationCallbacks        *allocator,
297                            VkFence                            *_fence)
298 {
299    TU_FROM_HANDLE(tu_device, device, _device);
300 
301    struct tu_fence            *fence;
302    VkResult                     ret;
303 
304    fence = vk_alloc2(&device->instance->alloc, allocator, sizeof (*fence),
305                      8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
306    if (!fence)
307       return VK_ERROR_OUT_OF_HOST_MEMORY;
308 
309    tu_fence_init(fence, false);
310 
311    ret = wsi_register_display_event(_device,
312                                     &device->physical_device->wsi_device,
313                                     display,
314                                     display_event_info,
315                                     allocator,
316                                     &fence->fence_wsi);
317 
318    if (ret == VK_SUCCESS)
319       *_fence = tu_fence_to_handle(fence);
320    else
321       vk_free2(&device->instance->alloc, allocator, fence);
322    return ret;
323 }
324 
325 VkResult
tu_GetSwapchainCounterEXT(VkDevice _device,VkSwapchainKHR swapchain,VkSurfaceCounterFlagBitsEXT flag_bits,uint64_t * value)326 tu_GetSwapchainCounterEXT(VkDevice                    _device,
327                           VkSwapchainKHR              swapchain,
328                           VkSurfaceCounterFlagBitsEXT flag_bits,
329                           uint64_t                    *value)
330 {
331    TU_FROM_HANDLE(tu_device, device, _device);
332 
333    return wsi_get_swapchain_counter(_device,
334                                     &device->physical_device->wsi_device,
335                                     swapchain,
336                                     flag_bits,
337                                     value);
338 }
339 
340