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