• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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