diff mbox

[03/21] radv: Add KHR_display extension to radv

Message ID 20180214003134.1552-4-keithp@keithp.com (mailing list archive)
State New, archived
Headers show

Commit Message

Keith Packard Feb. 14, 2018, 12:31 a.m. UTC
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.

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 src/amd/vulkan/Makefile.am        |   8 +++
 src/amd/vulkan/Makefile.sources   |   3 +
 src/amd/vulkan/meson.build        |   7 ++
 src/amd/vulkan/radv_device.c      |  25 ++++++-
 src/amd/vulkan/radv_extensions.py |   7 +-
 src/amd/vulkan/radv_private.h     |   2 +
 src/amd/vulkan/radv_wsi_display.c | 143 ++++++++++++++++++++++++++++++++++++++
 7 files changed, 191 insertions(+), 4 deletions(-)
 create mode 100644 src/amd/vulkan/radv_wsi_display.c
diff mbox

Patch

diff --git a/src/amd/vulkan/Makefile.am b/src/amd/vulkan/Makefile.am
index 61025968942..061b8144b88 100644
--- a/src/amd/vulkan/Makefile.am
+++ b/src/amd/vulkan/Makefile.am
@@ -76,6 +76,14 @@  VULKAN_LIB_DEPS = \
 	$(DLOPEN_LIBS) \
 	-lm
 
+if HAVE_PLATFORM_DISPLAY
+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 a510d88d965..618a6cdaed0 100644
--- a/src/amd/vulkan/Makefile.sources
+++ b/src/amd/vulkan/Makefile.sources
@@ -78,6 +78,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 0a7b7c0bf3c..b7bb1075e7d 100644
--- a/src/amd/vulkan/meson.build
+++ b/src/amd/vulkan/meson.build
@@ -112,6 +112,13 @@  if with_platform_wayland
   libradv_files += files('radv_wsi_wayland.c')
 endif
 
+if with_platform_display
+  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 09bb382eeb8..8ae7391c891 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -191,9 +191,26 @@  radv_physical_device_init(struct radv_physical_device *device,
 	const char *path = drm_device->nodes[DRM_NODE_RENDER];
 	VkResult result;
 	drmVersionPtr version;
-	int fd;
+	int fd = -1;
+
+	if (instance->khr_display_requested) {
+		fd = open(drm_device->nodes[DRM_NODE_PRIMARY], O_RDWR | O_CLOEXEC);
+		if (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
+			};
 
-	fd = open(path, O_RDWR | O_CLOEXEC);
+			if (drmCommandWrite(fd, DRM_AMDGPU_INFO, &request, sizeof (struct drm_amdgpu_info)) < 0 || !accel_working) {
+				close(fd);
+				fd = -1;
+			}
+		}
+	}
+	if (fd < 0)
+		fd = open(path, O_RDWR | O_CLOEXEC);
 	if (fd < 0)
 		return vk_error(VK_ERROR_INCOMPATIBLE_DRIVER);
 
@@ -387,6 +404,7 @@  VkResult radv_CreateInstance(
 {
 	struct radv_instance *instance;
 	VkResult result;
+	bool khr_display_requested = false;
 
 	assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
 
@@ -411,6 +429,8 @@  VkResult radv_CreateInstance(
 	        const char *ext_name = pCreateInfo->ppEnabledExtensionNames[i];
 		if (!radv_instance_extension_supported(ext_name))
 			return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);
+		if (strcmp(ext_name, VK_KHR_DISPLAY_EXTENSION_NAME) == 0)
+			khr_display_requested = true;
 	}
 
 	instance = vk_zalloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
@@ -427,6 +447,7 @@  VkResult radv_CreateInstance(
 
 	instance->apiVersion = client_version;
 	instance->physicalDeviceCount = -1;
+	instance->khr_display_requested = khr_display_requested;
 
 	result = vk_debug_report_instance_init(&instance->debug_report_callbacks);
 	if (result != VK_SUCCESS) {
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index d761895d3a0..8a079595d40 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -81,6 +81,7 @@  EXTENSIONS = [
     Extension('VK_KHR_wayland_surface',                   6, 'VK_USE_PLATFORM_WAYLAND_KHR'),
     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_display',                          23, 'VK_USE_PLATFORM_DISPLAY_KHR'),
     Extension('VK_KHX_multiview',                         1, '!ANDROID'),
     Extension('VK_EXT_debug_report',                      9, True),
     Extension('VK_EXT_discard_rectangles',                1, True),
@@ -168,7 +169,7 @@  _TEMPLATE = 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
@@ -187,7 +188,9 @@  _TEMPLATE = 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)
+
 
 bool
 radv_instance_extension_supported(const char *name)
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index be9e8f43964..1e3719bcc4f 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -75,6 +75,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
 
@@ -300,6 +301,7 @@  struct radv_instance {
 	uint64_t perftest_flags;
 
 	struct vk_debug_report_instance             debug_report_callbacks;
+        bool                                        khr_display_requested;
 };
 
 VkResult radv_init_wsi(struct radv_physical_device *physical_device);
diff --git a/src/amd/vulkan/radv_wsi_display.c b/src/amd/vulkan/radv_wsi_display.c
new file mode 100644
index 00000000000..f98a071513d
--- /dev/null
+++ b/src/amd/vulkan/radv_wsi_display.c
@@ -0,0 +1,143 @@ 
+/*
+ * 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 <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "radv_private.h"
+#include "radv_cs.h"
+#include "util/disk_cache.h"
+#include "util/strtod.h"
+#include "vk_util.h"
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <amdgpu.h>
+#include <amdgpu_drm.h>
+#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)
+{
+	return VK_ERROR_INITIALIZATION_FAILED;
+}
+
+
+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);
+}