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 "drm-uapi/amdgpu_drm.h"
36 #include "winsys/amdgpu/radv_amdgpu_winsys_public.h"
37 #include "vk_format.h"
38 #include "sid.h"
39 #include "util/debug.h"
40 #include "wsi_common_display.h"
41
42 #define MM_PER_PIXEL (1.0/96.0 * 25.4)
43
44 VkResult
radv_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayPropertiesKHR * properties)45 radv_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physical_device,
46 uint32_t *property_count,
47 VkDisplayPropertiesKHR *properties)
48 {
49 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
50
51 return wsi_display_get_physical_device_display_properties(
52 physical_device,
53 &pdevice->wsi_device,
54 property_count,
55 properties);
56 }
57
58 VkResult
radv_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayProperties2KHR * properties)59 radv_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physical_device,
60 uint32_t *property_count,
61 VkDisplayProperties2KHR *properties)
62 {
63 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
64
65 return wsi_display_get_physical_device_display_properties2(
66 physical_device,
67 &pdevice->wsi_device,
68 property_count,
69 properties);
70 }
71
72 VkResult
radv_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayPlanePropertiesKHR * properties)73 radv_GetPhysicalDeviceDisplayPlanePropertiesKHR(
74 VkPhysicalDevice physical_device,
75 uint32_t *property_count,
76 VkDisplayPlanePropertiesKHR *properties)
77 {
78 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
79
80 return wsi_display_get_physical_device_display_plane_properties(
81 physical_device,
82 &pdevice->wsi_device,
83 property_count,
84 properties);
85 }
86
87 VkResult
radv_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physical_device,uint32_t * property_count,VkDisplayPlaneProperties2KHR * properties)88 radv_GetPhysicalDeviceDisplayPlaneProperties2KHR(
89 VkPhysicalDevice physical_device,
90 uint32_t *property_count,
91 VkDisplayPlaneProperties2KHR *properties)
92 {
93 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
94
95 return wsi_display_get_physical_device_display_plane_properties2(
96 physical_device,
97 &pdevice->wsi_device,
98 property_count,
99 properties);
100 }
101
102 VkResult
radv_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physical_device,uint32_t plane_index,uint32_t * display_count,VkDisplayKHR * displays)103 radv_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physical_device,
104 uint32_t plane_index,
105 uint32_t *display_count,
106 VkDisplayKHR *displays)
107 {
108 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
109
110 return wsi_display_get_display_plane_supported_displays(
111 physical_device,
112 &pdevice->wsi_device,
113 plane_index,
114 display_count,
115 displays);
116 }
117
118
119 VkResult
radv_GetDisplayModePropertiesKHR(VkPhysicalDevice physical_device,VkDisplayKHR display,uint32_t * property_count,VkDisplayModePropertiesKHR * properties)120 radv_GetDisplayModePropertiesKHR(VkPhysicalDevice physical_device,
121 VkDisplayKHR display,
122 uint32_t *property_count,
123 VkDisplayModePropertiesKHR *properties)
124 {
125 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
126
127 return wsi_display_get_display_mode_properties(physical_device,
128 &pdevice->wsi_device,
129 display,
130 property_count,
131 properties);
132 }
133
134 VkResult
radv_GetDisplayModeProperties2KHR(VkPhysicalDevice physical_device,VkDisplayKHR display,uint32_t * property_count,VkDisplayModeProperties2KHR * properties)135 radv_GetDisplayModeProperties2KHR(VkPhysicalDevice physical_device,
136 VkDisplayKHR display,
137 uint32_t *property_count,
138 VkDisplayModeProperties2KHR *properties)
139 {
140 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
141
142 return wsi_display_get_display_mode_properties2(physical_device,
143 &pdevice->wsi_device,
144 display,
145 property_count,
146 properties);
147 }
148
149 VkResult
radv_CreateDisplayModeKHR(VkPhysicalDevice physical_device,VkDisplayKHR display,const VkDisplayModeCreateInfoKHR * create_info,const VkAllocationCallbacks * allocator,VkDisplayModeKHR * mode)150 radv_CreateDisplayModeKHR(VkPhysicalDevice physical_device,
151 VkDisplayKHR display,
152 const VkDisplayModeCreateInfoKHR *create_info,
153 const VkAllocationCallbacks *allocator,
154 VkDisplayModeKHR *mode)
155 {
156 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
157
158 return wsi_display_create_display_mode(physical_device,
159 &pdevice->wsi_device,
160 display,
161 create_info,
162 allocator,
163 mode);
164 }
165
166 VkResult
radv_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physical_device,VkDisplayModeKHR mode_khr,uint32_t plane_index,VkDisplayPlaneCapabilitiesKHR * capabilities)167 radv_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physical_device,
168 VkDisplayModeKHR mode_khr,
169 uint32_t plane_index,
170 VkDisplayPlaneCapabilitiesKHR *capabilities)
171 {
172 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
173
174 return wsi_get_display_plane_capabilities(physical_device,
175 &pdevice->wsi_device,
176 mode_khr,
177 plane_index,
178 capabilities);
179 }
180
181 VkResult
radv_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physical_device,const VkDisplayPlaneInfo2KHR * pDisplayPlaneInfo,VkDisplayPlaneCapabilities2KHR * capabilities)182 radv_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physical_device,
183 const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
184 VkDisplayPlaneCapabilities2KHR *capabilities)
185 {
186 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
187
188 return wsi_get_display_plane_capabilities2(physical_device,
189 &pdevice->wsi_device,
190 pDisplayPlaneInfo,
191 capabilities);
192 }
193
194 VkResult
radv_CreateDisplayPlaneSurfaceKHR(VkInstance _instance,const VkDisplaySurfaceCreateInfoKHR * create_info,const VkAllocationCallbacks * allocator,VkSurfaceKHR * surface)195 radv_CreateDisplayPlaneSurfaceKHR(
196 VkInstance _instance,
197 const VkDisplaySurfaceCreateInfoKHR *create_info,
198 const VkAllocationCallbacks *allocator,
199 VkSurfaceKHR *surface)
200 {
201 RADV_FROM_HANDLE(radv_instance, instance, _instance);
202 const VkAllocationCallbacks *alloc;
203
204 if (allocator)
205 alloc = allocator;
206 else
207 alloc = &instance->alloc;
208
209 return wsi_create_display_surface(_instance, alloc,
210 create_info, surface);
211 }
212
213 VkResult
radv_ReleaseDisplayEXT(VkPhysicalDevice physical_device,VkDisplayKHR display)214 radv_ReleaseDisplayEXT(VkPhysicalDevice physical_device,
215 VkDisplayKHR display)
216 {
217 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
218
219 return wsi_release_display(physical_device,
220 &pdevice->wsi_device,
221 display);
222 }
223
224 #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
225 VkResult
radv_AcquireXlibDisplayEXT(VkPhysicalDevice physical_device,Display * dpy,VkDisplayKHR display)226 radv_AcquireXlibDisplayEXT(VkPhysicalDevice physical_device,
227 Display *dpy,
228 VkDisplayKHR display)
229 {
230 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
231
232 return wsi_acquire_xlib_display(physical_device,
233 &pdevice->wsi_device,
234 dpy,
235 display);
236 }
237
238 VkResult
radv_GetRandROutputDisplayEXT(VkPhysicalDevice physical_device,Display * dpy,RROutput output,VkDisplayKHR * display)239 radv_GetRandROutputDisplayEXT(VkPhysicalDevice physical_device,
240 Display *dpy,
241 RROutput output,
242 VkDisplayKHR *display)
243 {
244 RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
245
246 return wsi_get_randr_output_display(physical_device,
247 &pdevice->wsi_device,
248 dpy,
249 output,
250 display);
251 }
252 #endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */
253
254 /* VK_EXT_display_control */
255
256 VkResult
radv_DisplayPowerControlEXT(VkDevice _device,VkDisplayKHR display,const VkDisplayPowerInfoEXT * display_power_info)257 radv_DisplayPowerControlEXT(VkDevice _device,
258 VkDisplayKHR display,
259 const VkDisplayPowerInfoEXT *display_power_info)
260 {
261 RADV_FROM_HANDLE(radv_device, device, _device);
262
263 return wsi_display_power_control(_device,
264 &device->physical_device->wsi_device,
265 display,
266 display_power_info);
267 }
268
269 VkResult
radv_RegisterDeviceEventEXT(VkDevice _device,const VkDeviceEventInfoEXT * device_event_info,const VkAllocationCallbacks * allocator,VkFence * _fence)270 radv_RegisterDeviceEventEXT(VkDevice _device,
271 const VkDeviceEventInfoEXT *device_event_info,
272 const VkAllocationCallbacks *allocator,
273 VkFence *_fence)
274 {
275 RADV_FROM_HANDLE(radv_device, device, _device);
276 VkResult ret;
277 int fd;
278
279 ret = radv_CreateFence(_device, &(VkFenceCreateInfo) {
280 .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
281 .pNext = &(VkExportFenceCreateInfo) {
282 .sType = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
283 .handleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT,
284 },
285 }, allocator, _fence);
286 if (ret != VK_SUCCESS)
287 return ret;
288
289 RADV_FROM_HANDLE(radv_fence, fence, *_fence);
290
291 assert(fence->permanent.kind == RADV_FENCE_SYNCOBJ);
292
293 if (device->ws->export_syncobj(device->ws, fence->permanent.syncobj, &fd)) {
294 ret = VK_ERROR_OUT_OF_HOST_MEMORY;
295 } else {
296 ret = wsi_register_device_event(_device,
297 &device->physical_device->wsi_device,
298 device_event_info,
299 allocator,
300 NULL,
301 fd);
302 close(fd);
303 }
304
305 if (ret != VK_SUCCESS)
306 radv_DestroyFence(_device, *_fence, allocator);
307
308 return ret;
309 }
310
311 VkResult
radv_RegisterDisplayEventEXT(VkDevice _device,VkDisplayKHR display,const VkDisplayEventInfoEXT * display_event_info,const VkAllocationCallbacks * allocator,VkFence * _fence)312 radv_RegisterDisplayEventEXT(VkDevice _device,
313 VkDisplayKHR display,
314 const VkDisplayEventInfoEXT *display_event_info,
315 const VkAllocationCallbacks *allocator,
316 VkFence *_fence)
317 {
318 RADV_FROM_HANDLE(radv_device, device, _device);
319 VkResult ret;
320 int fd;
321
322 ret = radv_CreateFence(_device, &(VkFenceCreateInfo) {
323 .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
324 .pNext = &(VkExportFenceCreateInfo) {
325 .sType = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
326 .handleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT,
327 },
328 }, allocator, _fence);
329 if (ret != VK_SUCCESS)
330 return ret;
331
332 RADV_FROM_HANDLE(radv_fence, fence, *_fence);
333
334 assert(fence->permanent.kind == RADV_FENCE_SYNCOBJ);
335
336 if (device->ws->export_syncobj(device->ws, fence->permanent.syncobj, &fd)) {
337 ret = VK_ERROR_OUT_OF_HOST_MEMORY;
338 } else {
339 ret = wsi_register_display_event(_device,
340 &device->physical_device->wsi_device,
341 display,
342 display_event_info,
343 allocator,
344 NULL,
345 fd);
346 close(fd);
347 }
348
349 if (ret != VK_SUCCESS)
350 radv_DestroyFence(_device, *_fence, allocator);
351
352 return ret;
353 }
354
355 VkResult
radv_GetSwapchainCounterEXT(VkDevice _device,VkSwapchainKHR swapchain,VkSurfaceCounterFlagBitsEXT flag_bits,uint64_t * value)356 radv_GetSwapchainCounterEXT(VkDevice _device,
357 VkSwapchainKHR swapchain,
358 VkSurfaceCounterFlagBitsEXT flag_bits,
359 uint64_t *value)
360 {
361 RADV_FROM_HANDLE(radv_device, device, _device);
362
363 return wsi_get_swapchain_counter(_device,
364 &device->physical_device->wsi_device,
365 swapchain,
366 flag_bits,
367 value);
368 }
369
370