@@ -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) \
@@ -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 \
@@ -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],
@@ -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) {
@@ -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)
@@ -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);
new file mode 100644
@@ -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);
+}
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