radv: add VK_EXT_display_control to radv driver [v5]
[mesa.git] / src / amd / vulkan / radv_wsi_display.c
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 "radv_private.h"
28 #include "radv_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 <amdgpu.h>
35 #include <amdgpu_drm.h>
36 #include "winsys/amdgpu/radv_amdgpu_winsys_public.h"
37 #include "ac_llvm_util.h"
38 #include "vk_format.h"
39 #include "sid.h"
40 #include "util/debug.h"
41 #include "wsi_common_display.h"
42
43 #define MM_PER_PIXEL (1.0/96.0 * 25.4)
44
45 VkResult
46 radv_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physical_device,
47 uint32_t *property_count,
48 VkDisplayPropertiesKHR *properties)
49 {
50 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
51
52 return wsi_display_get_physical_device_display_properties(
53 physical_device,
54 &pdevice->wsi_device,
55 property_count,
56 properties);
57 }
58
59 VkResult
60 radv_GetPhysicalDeviceDisplayPlanePropertiesKHR(
61 VkPhysicalDevice physical_device,
62 uint32_t *property_count,
63 VkDisplayPlanePropertiesKHR *properties)
64 {
65 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
66
67 return wsi_display_get_physical_device_display_plane_properties(
68 physical_device,
69 &pdevice->wsi_device,
70 property_count,
71 properties);
72 }
73
74 VkResult
75 radv_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physical_device,
76 uint32_t plane_index,
77 uint32_t *display_count,
78 VkDisplayKHR *displays)
79 {
80 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
81
82 return wsi_display_get_display_plane_supported_displays(
83 physical_device,
84 &pdevice->wsi_device,
85 plane_index,
86 display_count,
87 displays);
88 }
89
90
91 VkResult
92 radv_GetDisplayModePropertiesKHR(VkPhysicalDevice physical_device,
93 VkDisplayKHR display,
94 uint32_t *property_count,
95 VkDisplayModePropertiesKHR *properties)
96 {
97 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
98
99 return wsi_display_get_display_mode_properties(physical_device,
100 &pdevice->wsi_device,
101 display,
102 property_count,
103 properties);
104 }
105
106 VkResult
107 radv_CreateDisplayModeKHR(VkPhysicalDevice physical_device,
108 VkDisplayKHR display,
109 const VkDisplayModeCreateInfoKHR *create_info,
110 const VkAllocationCallbacks *allocator,
111 VkDisplayModeKHR *mode)
112 {
113 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
114
115 return wsi_display_create_display_mode(physical_device,
116 &pdevice->wsi_device,
117 display,
118 create_info,
119 allocator,
120 mode);
121 }
122
123 VkResult
124 radv_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physical_device,
125 VkDisplayModeKHR mode_khr,
126 uint32_t plane_index,
127 VkDisplayPlaneCapabilitiesKHR *capabilities)
128 {
129 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
130
131 return wsi_get_display_plane_capabilities(physical_device,
132 &pdevice->wsi_device,
133 mode_khr,
134 plane_index,
135 capabilities);
136 }
137
138 VkResult
139 radv_CreateDisplayPlaneSurfaceKHR(
140 VkInstance _instance,
141 const VkDisplaySurfaceCreateInfoKHR *create_info,
142 const VkAllocationCallbacks *allocator,
143 VkSurfaceKHR *surface)
144 {
145 RADV_FROM_HANDLE(radv_instance, instance, _instance);
146 const VkAllocationCallbacks *alloc;
147
148 if (allocator)
149 alloc = allocator;
150 else
151 alloc = &instance->alloc;
152
153 return wsi_create_display_surface(_instance, alloc,
154 create_info, surface);
155 }
156
157 VkResult
158 radv_ReleaseDisplayEXT(VkPhysicalDevice physical_device,
159 VkDisplayKHR display)
160 {
161 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
162
163 return wsi_release_display(physical_device,
164 &pdevice->wsi_device,
165 display);
166 }
167
168 #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
169 VkResult
170 radv_AcquireXlibDisplayEXT(VkPhysicalDevice physical_device,
171 Display *dpy,
172 VkDisplayKHR display)
173 {
174 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
175
176 return wsi_acquire_xlib_display(physical_device,
177 &pdevice->wsi_device,
178 dpy,
179 display);
180 }
181
182 VkResult
183 radv_GetRandROutputDisplayEXT(VkPhysicalDevice physical_device,
184 Display *dpy,
185 RROutput output,
186 VkDisplayKHR *display)
187 {
188 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
189
190 return wsi_get_randr_output_display(physical_device,
191 &pdevice->wsi_device,
192 dpy,
193 output,
194 display);
195 }
196 #endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */
197
198 /* VK_EXT_display_control */
199
200 VkResult
201 radv_DisplayPowerControlEXT(VkDevice _device,
202 VkDisplayKHR display,
203 const VkDisplayPowerInfoEXT *display_power_info)
204 {
205 RADV_FROM_HANDLE(radv_device, device, _device);
206
207 return wsi_display_power_control(_device,
208 &device->physical_device->wsi_device,
209 display,
210 display_power_info);
211 }
212
213 VkResult
214 radv_RegisterDeviceEventEXT(VkDevice _device,
215 const VkDeviceEventInfoEXT *device_event_info,
216 const VkAllocationCallbacks *allocator,
217 VkFence *_fence)
218 {
219 RADV_FROM_HANDLE(radv_device, device, _device);
220 struct radv_fence *fence;
221 VkResult ret;
222
223 fence = vk_alloc2(&device->instance->alloc, allocator, sizeof (*fence),
224 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
225 if (!fence)
226 return VK_ERROR_OUT_OF_HOST_MEMORY;
227
228 fence->fence = NULL;
229 fence->submitted = true;
230 fence->signalled = false;
231 fence->syncobj = 0;
232 fence->temp_syncobj = 0;
233
234 ret = wsi_register_device_event(_device,
235 &device->physical_device->wsi_device,
236 device_event_info,
237 allocator,
238 &fence->fence_wsi);
239 if (ret == VK_SUCCESS)
240 *_fence = radv_fence_to_handle(fence);
241 else
242 vk_free2(&device->instance->alloc, allocator, fence);
243 return ret;
244 }
245
246 VkResult
247 radv_RegisterDisplayEventEXT(VkDevice _device,
248 VkDisplayKHR display,
249 const VkDisplayEventInfoEXT *display_event_info,
250 const VkAllocationCallbacks *allocator,
251 VkFence *_fence)
252 {
253 RADV_FROM_HANDLE(radv_device, device, _device);
254
255 struct radv_fence *fence;
256 VkResult ret;
257
258 fence = vk_alloc2(&device->instance->alloc, allocator, sizeof (*fence),
259 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
260 if (!fence)
261 return VK_ERROR_OUT_OF_HOST_MEMORY;
262
263 fence->fence = NULL;
264 fence->submitted = true;
265 fence->signalled = false;
266 fence->syncobj = 0;
267 fence->temp_syncobj = 0;
268
269 ret = wsi_register_display_event(_device,
270 &device->physical_device->wsi_device,
271 display,
272 display_event_info,
273 allocator,
274 &(fence->fence_wsi));
275
276 if (ret == VK_SUCCESS)
277 *_fence = radv_fence_to_handle(fence);
278 else
279 vk_free2(&device->instance->alloc, allocator, fence);
280 return ret;
281 }
282
283 VkResult
284 radv_GetSwapchainCounterEXT(VkDevice _device,
285 VkSwapchainKHR swapchain,
286 VkSurfaceCounterFlagBitsEXT flag_bits,
287 uint64_t *value)
288 {
289 RADV_FROM_HANDLE(radv_device, device, _device);
290
291 return wsi_get_swapchain_counter(_device,
292 &device->physical_device->wsi_device,
293 swapchain,
294 flag_bits,
295 value);
296 }
297