From 451b58a51e9ffa0b2fbbe143ca47c3ee31ad2f58 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 7 Feb 2018 10:31:44 -0800 Subject: [PATCH] radv: Add KHR_display extension to radv [v5] This adds support for the KHR_display extension to the radv Vulkan driver. The driver now attempts to open the master DRM node when the KHR_display extension is requested so that the common winsys code can perform the necessary operations. v2: * Simplify addition of VK_USE_PLATFORM_DISPLAY_KHR to vulkan_wsi_args Suggested-by: Eric Engestrom v3: Adapt to new wsi_device_init API (added display_fd) v4: Adopt Jason Ekstrand's coding conventions Declare variables at first use, eliminate extra whitespace between types and names. Wrap lines to 80 columns. Suggested-by: Jason Ekstrand v5: Add vkCreateDisplayModeKHR. This doesn't actually create new modes, it only looks to see if the requested parameters matches an existing mode and returns that. Suggested-by: Jason Ekstrand Signed-off-by: Keith Packard Reviewed-by: Jason Ekstrand --- src/amd/vulkan/Makefile.am | 8 ++ src/amd/vulkan/Makefile.sources | 3 + src/amd/vulkan/meson.build | 5 + src/amd/vulkan/radv_device.c | 17 ++++ src/amd/vulkan/radv_extensions.py | 7 +- src/amd/vulkan/radv_private.h | 1 + src/amd/vulkan/radv_wsi_display.c | 155 ++++++++++++++++++++++++++++++ 7 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 src/amd/vulkan/radv_wsi_display.c diff --git a/src/amd/vulkan/Makefile.am b/src/amd/vulkan/Makefile.am index 18f263ab447..f4f99400275 100644 --- a/src/amd/vulkan/Makefile.am +++ b/src/amd/vulkan/Makefile.am @@ -80,6 +80,14 @@ VULKAN_LIB_DEPS = \ $(DLOPEN_LIBS) \ -lm +if HAVE_PLATFORM_DRM +AM_CPPFLAGS += \ + -DVK_USE_PLATFORM_DISPLAY_KHR + +VULKAN_SOURCES += $(VULKAN_WSI_DISPLAY_FILES) + +endif + if HAVE_PLATFORM_X11 AM_CPPFLAGS += \ $(XCB_DRI3_CFLAGS) \ diff --git a/src/amd/vulkan/Makefile.sources b/src/amd/vulkan/Makefile.sources index ccb956a2396..70d56e88cb3 100644 --- a/src/amd/vulkan/Makefile.sources +++ b/src/amd/vulkan/Makefile.sources @@ -80,6 +80,9 @@ VULKAN_WSI_WAYLAND_FILES := \ VULKAN_WSI_X11_FILES := \ radv_wsi_x11.c +VULKAN_WSI_DISPLAY_FILES := \ + radv_wsi_display.c + VULKAN_GENERATED_FILES := \ radv_entrypoints.c \ radv_entrypoints.h \ diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build index b5a99fe91e1..15e69d582dd 100644 --- a/src/amd/vulkan/meson.build +++ b/src/amd/vulkan/meson.build @@ -115,6 +115,11 @@ if with_platform_wayland libradv_files += files('radv_wsi_wayland.c') endif +if with_platform_drm + radv_flags += '-DVK_USE_PLATFORM_DISPLAY_KHR' + libradv_files += files('radv_wsi_display.c') +endif + libvulkan_radeon = shared_library( 'vulkan_radeon', [libradv_files, radv_entrypoints, radv_extensions_c, vk_format_table_c], diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 056043a9169..ffeb6450b33 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -274,6 +274,23 @@ radv_physical_device_init(struct radv_physical_device *device, goto fail; } + if (instance->enabled_extensions.KHR_display) { + master_fd = open(drm_device->nodes[DRM_NODE_PRIMARY], O_RDWR | O_CLOEXEC); + if (master_fd >= 0) { + uint32_t accel_working = 0; + struct drm_amdgpu_info request = { + .return_pointer = (uintptr_t)&accel_working, + .return_size = sizeof(accel_working), + .query = AMDGPU_INFO_ACCEL_WORKING + }; + + if (drmCommandWrite(master_fd, DRM_AMDGPU_INFO, &request, sizeof (struct drm_amdgpu_info)) < 0 || !accel_working) { + close(master_fd); + master_fd = -1; + } + } + } + device->master_fd = master_fd; device->local_fd = fd; device->ws->query_info(device->ws, &device->rad_info); diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py index a5b5a8dc34e..6f4fc71bfd8 100644 --- a/src/amd/vulkan/radv_extensions.py +++ b/src/amd/vulkan/radv_extensions.py @@ -86,6 +86,7 @@ EXTENSIONS = [ Extension('VK_KHR_xcb_surface', 6, 'VK_USE_PLATFORM_XCB_KHR'), Extension('VK_KHR_xlib_surface', 6, 'VK_USE_PLATFORM_XLIB_KHR'), Extension('VK_KHR_multiview', 1, True), + Extension('VK_KHR_display', 23, 'VK_USE_PLATFORM_DISPLAY_KHR'), Extension('VK_EXT_debug_report', 9, True), Extension('VK_EXT_depth_range_unrestricted', 1, True), Extension('VK_EXT_descriptor_indexing', 2, True), @@ -214,7 +215,7 @@ _TEMPLATE_C = Template(COPYRIGHT + """ #include "vk_util.h" /* Convert the VK_USE_PLATFORM_* defines to booleans */ -%for platform in ['ANDROID', 'WAYLAND', 'XCB', 'XLIB']: +%for platform in ['ANDROID', 'WAYLAND', 'XCB', 'XLIB', 'DISPLAY']: #ifdef VK_USE_PLATFORM_${platform}_KHR # undef VK_USE_PLATFORM_${platform}_KHR # define VK_USE_PLATFORM_${platform}_KHR true @@ -233,7 +234,9 @@ _TEMPLATE_C = Template(COPYRIGHT + """ #define RADV_HAS_SURFACE (VK_USE_PLATFORM_WAYLAND_KHR || \\ VK_USE_PLATFORM_XCB_KHR || \\ - VK_USE_PLATFORM_XLIB_KHR) + VK_USE_PLATFORM_XLIB_KHR || \\ + VK_USE_PLATFORM_DISPLAY_KHR) + const VkExtensionProperties radv_instance_extensions[RADV_INSTANCE_EXTENSION_COUNT] = { %for ext in instance_extensions: diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index a76d771e4a5..abaf2eb929a 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -79,6 +79,7 @@ typedef uint32_t xcb_window_t; #include "radv_entrypoints.h" #include "wsi_common.h" +#include "wsi_common_display.h" #define ATI_VENDOR_ID 0x1002 diff --git a/src/amd/vulkan/radv_wsi_display.c b/src/amd/vulkan/radv_wsi_display.c new file mode 100644 index 00000000000..048d992e1cf --- /dev/null +++ b/src/amd/vulkan/radv_wsi_display.c @@ -0,0 +1,155 @@ +/* + * Copyright © 2017 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include "radv_private.h" +#include "radv_cs.h" +#include "util/disk_cache.h" +#include "util/strtod.h" +#include "vk_util.h" +#include +#include +#include +#include +#include "winsys/amdgpu/radv_amdgpu_winsys_public.h" +#include "ac_llvm_util.h" +#include "vk_format.h" +#include "sid.h" +#include "util/debug.h" +#include "wsi_common_display.h" + +#define MM_PER_PIXEL (1.0/96.0 * 25.4) + +VkResult +radv_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physical_device, + uint32_t *property_count, + VkDisplayPropertiesKHR *properties) +{ + RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device); + + return wsi_display_get_physical_device_display_properties( + physical_device, + &pdevice->wsi_device, + property_count, + properties); +} + +VkResult +radv_GetPhysicalDeviceDisplayPlanePropertiesKHR( + VkPhysicalDevice physical_device, + uint32_t *property_count, + VkDisplayPlanePropertiesKHR *properties) +{ + RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device); + + return wsi_display_get_physical_device_display_plane_properties( + physical_device, + &pdevice->wsi_device, + property_count, + properties); +} + +VkResult +radv_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physical_device, + uint32_t plane_index, + uint32_t *display_count, + VkDisplayKHR *displays) +{ + RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device); + + return wsi_display_get_display_plane_supported_displays( + physical_device, + &pdevice->wsi_device, + plane_index, + display_count, + displays); +} + + +VkResult +radv_GetDisplayModePropertiesKHR(VkPhysicalDevice physical_device, + VkDisplayKHR display, + uint32_t *property_count, + VkDisplayModePropertiesKHR *properties) +{ + RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device); + + return wsi_display_get_display_mode_properties(physical_device, + &pdevice->wsi_device, + display, + property_count, + properties); +} + +VkResult +radv_CreateDisplayModeKHR(VkPhysicalDevice physical_device, + VkDisplayKHR display, + const VkDisplayModeCreateInfoKHR *create_info, + const VkAllocationCallbacks *allocator, + VkDisplayModeKHR *mode) +{ + RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device); + + return wsi_display_create_display_mode(physical_device, + &pdevice->wsi_device, + display, + create_info, + allocator, + mode); +} + +VkResult +radv_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physical_device, + VkDisplayModeKHR mode_khr, + uint32_t plane_index, + VkDisplayPlaneCapabilitiesKHR *capabilities) +{ + RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device); + + return wsi_get_display_plane_capabilities(physical_device, + &pdevice->wsi_device, + mode_khr, + plane_index, + capabilities); +} + +VkResult +radv_CreateDisplayPlaneSurfaceKHR( + VkInstance _instance, + const VkDisplaySurfaceCreateInfoKHR *create_info, + const VkAllocationCallbacks *allocator, + VkSurfaceKHR *surface) +{ + RADV_FROM_HANDLE(radv_instance, instance, _instance); + const VkAllocationCallbacks *alloc; + + if (allocator) + alloc = allocator; + else + alloc = &instance->alloc; + + return wsi_create_display_surface(_instance, alloc, + create_info, surface); +} -- 2.30.2