Adding VK_KHR_display to mesa based on KMS
PATCH 1/1 Adding VK_KHR_display to mesa based on KMS
As part of my adventures to implement 'DRM leases', it turns out to be easiest to just implement 'real' VK_KHR_display in mesa now, rather than a pile of ugly kludges. Because DRM leases just provide a DRM master fd with limited resource access, mesa doesn't have to care whether you provide a 'real' master or a lease.
That means all of the mesa code is separate from DRM leases, and can also be used to run applications directly on bare hardware.
The implementation of the KHR_display extension lives pretty much entirely within the common vulkan code in src/vulkan/wsi/wsi_common_display.c
The driver functions in radv simply call those functions, which means this should be 'trivial' to enable in the anv driver, but I haven't done that work.
To get the master FD into the driver, I've created a new extension, VK_KEITHP_kms_display which provides a DRM master file descriptor that the driver uses in place of creating it's own render node file descriptor. There's a bit of a dance involved in making sure we use the right driver; that could probably be improved.
There are a few bits of unimplemented functionality within the KHR_display implementation:
1) I don't dig the monitor name out of EDID. I'm thinking this should be done by the kernel and exposed as a property. It already has the code for this...
2) plane and surface capabilities are 'faked'. These expose the range of source surface sizes and positions which can be used; obviously the hardware can do a lot more than display an image at full size.
3) Planes in general. I'm exposing only a single plane per connector at this point. Obviously we'd want more.
4) bpp/depth. For now, I'm assuming depth 24, 32bpp. I think I just need a driver hook to get this out of the image; I sure don't want to try and parse the format.
I haven't rebased this in a while; it's a few revs back on master. I'm looking for general feedback and comments about the plan at this point; this is the second implementation of the code, I'm entirely willing to do at least one more to make it 'right'.
git://people.freedesktop.org/~keithp/mesa.git khr_display
There are also some simple changes in the vulkan looader (replicated in the relevant files in mesa) needed to gain access to the VK_KEITHP_kms_display extension (thanks, Vulkan, for not exposing vendor instance extensions by default)
git://people.freedesktop.org/~keithp/Vulkan-LoaderAndValidationLayers.git drm-leases
From 06088071af2a396ce58b0490ceb228e3aa079a09 Mon Sep 17 00:00:00 2001
From: Keith Packard <[email protected]>
Date: Wed, 17 May 2017 23:02:33 -0700
Subject: [PATCH] Add VK_KHR_display and VK_KEITHP_kms_display to radv vulkan
driver [v2]
Implements VK_KHR_display using DRM/KMS.
Expose ability to get to that using VK_KEITHP_kms_display, which allows the application to provide a master fd to the library which it uses instead of opening its own.
--- configure.ac | 1 + include/vulkan/vulkan.h | 3 +- include/vulkan/vulkan_keithp.h | 40 + src/Makefile.am | 7 + src/amd/vulkan/Makefile.am | 9 + src/amd/vulkan/Makefile.sources | 3 + src/amd/vulkan/radv_device.c | 71 +- src/amd/vulkan/radv_entrypoints_gen.py | 2 + src/amd/vulkan/radv_private.h | 7 + src/amd/vulkan/radv_radeon_winsys.h | 4 + src/amd/vulkan/radv_wsi.c | 37 +- src/amd/vulkan/radv_wsi_display.c | 144 ++++ src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c | 18 + src/intel/vulkan/anv_wsi.c | 2 +- src/vulkan/Makefile.am | 9 + src/vulkan/Makefile.sources | 4 + src/vulkan/registry/vk.xml | 18 + src/vulkan/wsi/wsi_common.h | 12 +- src/vulkan/wsi/wsi_common_display.c | 1063 +++++++++++++++++++++++++ src/vulkan/wsi/wsi_common_display.h | 80 ++ src/vulkan/wsi/wsi_common_wayland.c | 2 +- src/vulkan/wsi/wsi_common_x11.c | 4 +- 22 files changed, 1526 insertions(+), 14 deletions(-) create mode 100644 include/vulkan/vulkan_keithp.h create mode 100644 src/amd/vulkan/radv_wsi_display.c create mode 100644 src/vulkan/wsi/wsi_common_display.c create mode 100644 src/vulkan/wsi/wsi_common_display.h
configure.ac +1 -0
@@ -2238,6 +2238,7 @@ fi AM_CONDITIONAL(HAVE_PLATFORM_X11, echo "$egl_platforms" | grep -q 'x11') AM_CONDITIONAL(HAVE_PLATFORM_WAYLAND, echo "$egl_platforms" | grep -q 'wayland') +AM_CONDITIONAL(HAVE_PLATFORM_DISPLAY, echo "$egl_platforms" | grep -q 'drm') AM_CONDITIONAL(HAVE_EGL_PLATFORM_DRM, echo "$egl_platforms" | grep -q 'drm') AM_CONDITIONAL(HAVE_EGL_PLATFORM_SURFACELESS, echo "$egl_platforms" | grep -q 'surfaceless') AM_CONDITIONAL(HAVE_EGL_PLATFORM_ANDROID, echo "$egl_platforms" | grep -q 'android')
include/vulkan/vulkan.h +2 -1
@@ -43,7 +43,7 @@ extern "C" {#define VK_VERSION_MINOR (version) (((uint32_t)(version) >> 12) & 0x3ff)#define VK_VERSION_PATCH (version) ((uint32_t)(version) & 0xfff)// Version of this file -#define VK_HEADER_VERSION 46 +#define VK_HEADER_VERSION 48#define VK_NULL_HANDLE 0
@@ -214,6 +214,7 @@ typedef enum VkStructureType {VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR =1000007000 ,VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR =1000008000 ,VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR =1000009000 , +VK_STRUCTURE_TYPE_KMS_DISPLAY_INFO_KEITHP =1000010000 ,VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT =1000011000 ,VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD =1000018000 , VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000,
include/vulkan/vulkan_keithp.h new file +40 -0
@@ -0,0 +1,40 @@ +/* +* Copyright © 2017 Keith Packard <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +*/ + +#ifndef _VULKAN_KEITHP_H_ +#define _VULKAN_KEITHP_H_ + +#include "vulkan.h" +#include <xf86drmMode.h> +#include <xf86drm.h> + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +typedef struct VkKmsDisplayInfoKEITHP { +VkStructureType sType;/* VK_STRUCTURE_TYPE_KMS_DISPLAY_INFO_KEITHP */ +const void * pNext; +int fd; +}VkKmsDisplayInfoKEITHP ; + +#define VK_KEITHP_KMS_DISPLAY_SPEC_VERSION 1 +#define VK_KEITHP_KMS_DISPLAY_EXTENSION_NAME "VK_KEITHP_kms_display" + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _VULKAN_KEITHP_H_ */
src/Makefile.am +7 -0
@@ -85,6 +85,13 @@ SUBDIRS += vulkan endif EXTRA_DIST += vulkan/registry/vk.xml +EXTRA_DIST += include/vulkan/vulkan_keithp.h + +vulkan_includedir = $(includedir)/vulkan + +vulkan_include_HEADERS = \ + $(top_srcdir)/include/vulkan/vulkan_keithp.h + if HAVE_AMD_DRIVERS SUBDIRS += amd endif
src/amd/vulkan/Makefile.am +9 -0
@@ -61,6 +61,15 @@ VULKAN_SOURCES = \ VULKAN_LIB_DEPS = +if HAVE_PLATFORM_DISPLAY +AM_CPPFLAGS += \ + -DVK_USE_PLATFORM_DISPLAY_KHR \ + -DVK_USE_PLATFORM_KMS_KEITHP + +VULKAN_SOURCES += $(VULKAN_WSI_DISPLAY_FILES) + +VULKAN_LIB_DEPS += $(LIBDRM_LIBS) +endif if HAVE_PLATFORM_X11 AM_CPPFLAGS += \
src/amd/vulkan/Makefile.sources +3 -0
@@ -72,6 +72,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
src/amd/vulkan/radv_device.c +68 -3
101 lines not on this page · raw message
src/amd/vulkan/radv_entrypoints_gen.py +2 -0
@@ -42,6 +42,8 @@ supported_extensions = [ 'VK_KHR_wayland_surface', 'VK_KHR_xcb_surface', 'VK_KHR_xlib_surface', + 'VK_KEITHP_kms_display', + 'VK_KHR_display' ] # We generate a static hash table for entry point lookup
src/amd/vulkan/radv_private.h +7 -0
@@ -67,11 +67,13 @@ typedef uint32_t xcb_window_t;#include <vulkan/vulkan.h> #include <vulkan/vulkan_intel.h> +#include <vulkan/vulkan_keithp.h> #include <vulkan/vk_icd.h> #include "radv_entrypoints.h" #include "wsi_common.h" +#include "wsi_common_display.h" #define MAX_VBS 32#define MAX_VERTEX_ATTRIBS 32
@@ -281,6 +283,8 @@ struct radv_instance {int physicalDeviceCount;struct radv_physical_device physicalDevices[RADV_MAX_DRM_DEVICES ]; +int master_fd; +uint64_t debug_flags; };
@@ -894,6 +898,9 @@ void radv_cmd_buffer_trace_emit(struct radv_cmd_buffer *cmd_buffer);bool radv_get_memory_fd (struct radv_device *device,struct radv_device_memory *memory,int *pFD); +bool radv_get_memory_handle (struct radv_device *device, +struct radv_device_memory *memory, +uint32_t *pHandle);/* * Takes x,y,z as exact numbers of invocations, instead of blocks. *
src/amd/vulkan/radv_radeon_winsys.h +4 -0
@@ -283,6 +283,10 @@ struct radeon_winsys {struct radeon_winsys_bo *bo, int *fd); +bool (*buffer_get_handle)(struct radeon_winsys *ws, +struct radeon_winsys_bo *bo, +uint32_t *handle); +void (*buffer_unmap)(struct radeon_winsys_bo *bo);uint64_t (*buffer_get_va)(struct radeon_winsys_bo *bo);
src/amd/vulkan/radv_wsi.c +33 -4
@@ -57,6 +57,23 @@ radv_init_wsi(struct radv_physical_device *physical_device) }#endif +#ifdef VK_USE_PLATFORM_DISPLAY_KHR + result =wsi_display_init_wsi (&physical_device->wsi_device, + &physical_device->instance->alloc, +radv_physical_device_to_handle (physical_device), + physical_device->instance->master_fd >=0 ? physical_device->local_fd :-1 , + &wsi_cbs); +if (result !=VK_SUCCESS ) { +#ifdef VK_USE_PLATFORM_XCB_KHR +wsi_x11_finish_wsi (&physical_device->wsi_device, &physical_device->instance->alloc); +#endif +#ifdef VK_USE_PLATFORM_WAYLAND_KHR +wsi_wayland_finish_wsi (&physical_device->wsi_device, &physical_device->instance->alloc); +#endif +return result; + } +#endif +return VK_SUCCESS ; }
@@ -69,6 +86,9 @@ radv_finish_wsi(struct radv_physical_device *physical_device)#ifdef VK_USE_PLATFORM_XCB_KHR wsi_x11_finish_wsi (&physical_device->wsi_device, &physical_device->instance->alloc);#endif +#ifdef VK_USE_PLATFORM_DISPLAY_KHR +wsi_display_finish_wsi (&physical_device->wsi_device, &physical_device->instance->alloc); +#endif } void radv_DestroySurfaceKHR(
@@ -147,7 +167,7 @@ radv_wsi_image_create(VkDevice device_h, VkDeviceMemory *memory_p, uint32_t *size, uint32_t *offset, - uint32_t *row_pitch, int *fd_p) + uint32_t *row_pitch, int *fd_p, uint32_t *handle_p) {VkResult result =VK_SUCCESS ;struct radeon_surf *surface;
@@ -213,9 +233,18 @@ radv_wsi_image_create(VkDevice device_h,if (!needs_linear_copy || (needs_linear_copy && linear)) {RADV_FROM_HANDLE (radv_device, device, device_h);RADV_FROM_HANDLE (radv_device_memory, memory, memory_h); -if (!radv_get_memory_fd (device, memory, &fd)) - goto fail_alloc_memory; - *fd_p = fd; + +if (fd_p) { +if (!radv_get_memory_fd (device, memory, &fd)) + goto fail_alloc_memory; + *fd_p = fd; + } +if (handle_p) { +uint32_t handle; +if (!radv_get_memory_handle (device, memory, &handle)) + goto fail_alloc_memory; + *handle_p = handle; + } } surface = &image->surface;
src/amd/vulkan/radv_wsi_display.c new file +144 -0
144 lines not on this page · raw message
src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c +18 -0
@@ -445,6 +445,23 @@ radv_amdgpu_winsys_get_fd(struct radeon_winsys *_ws,return true; } +static bool +radv_amdgpu_winsys_get_handle (struct radeon_winsys *_ws, +struct radeon_winsys_bo *_bo, +uint32_t *handle) +{ +struct radv_amdgpu_winsys_bo *bo =radv_amdgpu_winsys_bo (_bo); +enum amdgpu_bo_handle_type type = amdgpu_bo_handle_type_kms; +int r; + + r =amdgpu_bo_export (bo->bo, type, handle); +if (r) +return false; + + bo->is_shared = true; +return true; +} +static unsigned radv_eg_tile_split_rev (unsigned eg_tile_split) {switch (eg_tile_split) {
@@ -503,6 +520,7 @@ void radv_amdgpu_bo_init_functions(struct radv_amdgpu_winsys *ws) ws->base.buffer_unmap = radv_amdgpu_winsys_bo_unmap; ws->base.buffer_from_fd = radv_amdgpu_winsys_bo_from_fd; ws->base.buffer_get_fd = radv_amdgpu_winsys_get_fd; + ws->base.buffer_get_handle = radv_amdgpu_winsys_get_handle; ws->base.buffer_set_metadata = radv_amdgpu_winsys_bo_set_metadata; ws->base.buffer_virtual_bind = radv_amdgpu_winsys_bo_virtual_bind; }
src/intel/vulkan/anv_wsi.c +1 -1
@@ -151,7 +151,7 @@ anv_wsi_image_create(VkDevice device_h, VkDeviceMemory *memory_p, uint32_t *size, uint32_t *offset, - uint32_t *row_pitch, int *fd_p) + uint32_t *row_pitch, int *fd_p, uint32_t *handle_p) {struct anv_device *device =anv_device_from_handle (device_h);VkImage image_h;
src/vulkan/Makefile.am +9 -0
@@ -48,6 +48,15 @@ VULKAN_WSI_SOURCES += $(VULKAN_WSI_X11_FILES) VULKAN_LIB_DEPS += $(XCB_DRI3_LIBS) -lX11-xcb endif +if HAVE_PLATFORM_DISPLAY +AM_CPPFLAGS += \ + -DVK_USE_PLATFORM_DISPLAY + +VULKAN_WSI_SOURCES += $(VULKAN_WSI_DISPLAY_FILES) + +VULKAN_LIB_DEPS += $(LIBDRM_LIBS) +endif + BUILT_SOURCES += $(VULKAN_WSI_WAYLAND_GENERATED_FILES) CLEANFILES = $(BUILT_SOURCES)
src/vulkan/Makefile.sources +4 -0
@@ -15,6 +15,10 @@ VULKAN_WSI_X11_FILES := \ wsi/wsi_common_x11.c \ wsi/wsi_common_x11.h +VULKAN_WSI_DISPLAY_FILES := \ + wsi/wsi_common_display.c \ + wsi/wsi_common_display.h + VULKAN_UTIL_GENERATED_FILES := \ util/vk_enum_to_str.c \ util/vk_enum_to_str.h
src/vulkan/registry/vk.xml +18 -0
@@ -67,6 +67,7 @@ maintained in the master branch of the Khronos Vulkan GitHub project. <tag name="KHR" author="Khronos" contact="Tom Olson @tom.olson"/> <tag name="EXT" author="Multivendor" contact="Jon Leech @oddhack"/> <tag name="MESA" author="Mesa open source project" contact="Chad Versace @chadversary, Daniel Stone @fooishbar, David Airlie @airlied, Jason Ekstrand @jekstrand"/> + <tag name="KEITHP" author="keithp.com" contact="keithp @keithp.com"/> </tags> <!-- SECTION: Vulkan type definitions -->
@@ -1538,6 +1539,16 @@ maintained in the master branch of the Khronos Vulkan GitHub project. <member noautovalidity="true"><type>xcb_connection_t</type>* <name>connection</name></member> <member><type>xcb_window_t</type> <name>window</name></member> </type> + <type catagory="struct" name="VkKmsDisplayInfoKEITHP"> + <member values="VK_STRUCTURE_TYPE_KMS_DISPLAY_INFO_KEITHP"><type>VkStructureType</type> <name>sType</name></member> + <member><type>VkStructureType</type> <name>sType</name></member> + <member>const<type>void</type>* <name>pNext</name></member> + <member><type>int</type> <name>fd</name></member> + <member><type>uint32_t</type> <name>crtc_id</name></member> + <member><type>uint32_t</type>* <name>connector_ids</name></member> + <member><type>int</type> <name>connector_count</name></member> + <member><type>drmModeModeInfoPtr</type> <name>mode</name></member> + </type> <type category="struct" name="VkSurfaceFormatKHR" returnedonly="true"> <member><type>VkFormat</type> <name>format</name></member> <!-- Supported pair of rendering format --> <member><type>VkColorSpaceKHR</type> <name>colorSpace</name></member> <!-- and color space for the surface -->
@@ -5117,6 +5128,13 @@ maintained in the master branch of the Khronos Vulkan GitHub project. <command name="vkGetPhysicalDeviceXcbPresentationSupportKHR"/> </require> </extension> + <extension name="VK_KEITHP_kms_display" number="1" type="instance" requires="VK_KHR_surface" protect="VK_USE_PLATFORM_KMS_KEITHP" supported="vulkan"> + <require> + <enum value="1" name="VK_KEITHP_KMS_DISPLAY_SPEC_VERSION"/> + <enum value=""VK_KEITHP_kms_display"" name="VK_KEITHP_KMS_DISPLAY_EXTENSION_NAME"/> + <enum offset="0" extends="VkStructureType" name="VK_STRUCTURE_TYPE_KMS_DISPLAY_INFO_KEITHP"/> + </require> + </extension> <extension name="VK_KHR_wayland_surface" number="7" type="instance" requires="VK_KHR_surface" protect="VK_USE_PLATFORM_WAYLAND_KHR" supported="vulkan"> <require> <enum value="6" name="VK_KHR_WAYLAND_SURFACE_SPEC_VERSION"/>
src/vulkan/wsi/wsi_common.h +10 -2
@@ -42,7 +42,8 @@ struct wsi_image_fns {uint32_t *size_p, uint32_t *offset_p, uint32_t *row_pitch_p, - int *fd_p); + int *fd_p, + uint32_t *handle_p); void (*free_wsi_image)(VkDevice device, const VkAllocationCallbacks *pAllocator, VkImage image_h,
@@ -104,7 +105,7 @@ struct wsi_interface { struct wsi_swapchain **swapchain); }; -#define VK_ICD_WSI_PLATFORM_MAX 5 +#define VK_ICD_WSI_PLATFORM_MAX 6struct wsi_device {struct wsi_interface * wsi[VK_ICD_WSI_PLATFORM_MAX ];
@@ -162,5 +163,12 @@ VkResult wsi_wl_init_wsi(struct wsi_device *wsi_device,void wsi_wl_finish_wsi (struct wsi_device *wsi_device,const VkAllocationCallbacks *alloc); +VkResult wsi_display_init_wsi (struct wsi_device *wsi_device, +const VkAllocationCallbacks *alloc, +VkPhysicalDevice physical_device, +int fd, +const struct wsi_callbacks *cbs); +void wsi_display_finish_wsi (struct wsi_device *wsi_device, +const VkAllocationCallbacks *alloc);#endif
src/vulkan/wsi/wsi_common_display.c new file +1063 -0
1,063 lines not on this page · raw message
src/vulkan/wsi/wsi_common_display.h new file +80 -0
80 lines not on this page · raw message
src/vulkan/wsi/wsi_common_wayland.c +1 -1
@@ -659,7 +659,7 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, &size, &offset, &row_pitch, - &fd); + &fd, NULL);if (result !=VK_SUCCESS )return result;
src/vulkan/wsi/wsi_common_x11.c +2 -2
@@ -944,7 +944,7 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, &size, &offset, &row_pitch, - &fd); + &fd, NULL);if (result !=VK_SUCCESS )return result;
@@ -959,7 +959,7 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, &size, &offset, &row_pitch, - &fd); + &fd, NULL);if (result !=VK_SUCCESS ) { chain->base.image_fns->free_wsi_image (device_h, pAllocator, image->image, image->memory);
Signature · 1 line
2.11.0
Signature · 2 lines
-- -keith
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel