<div dir="ltr">Sorry for the multitude of replies. :-(<br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 7, 2018 at 11:24 PM, Keith Packard <span dir="ltr"><<a href="mailto:keithp@keithp.com" target="_blank">keithp@keithp.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This adds support for the KHR_display extension support to the vulkan<br>
WSI layer. Driver support will be added separately.<br>
<br>
v2:<br>
        * fix double ;; in wsi_common_display.c<br>
<br>
        * Move mode list from wsi_display to wsi_display_connector<br>
<br>
        * Fix scope for wsi_display_mode andwsi_display_connector<br>
          allocs<br>
<br>
        * Switch all allocations to vk_zalloc instead of vk_alloc.<br>
<br>
        * Fix DRM failure in<br>
          wsi_display_get_physical_<wbr>device_display_properties<br>
<br>
          When DRM fails, or when we don't have a master fd<br>
          (presumably due to application errors), just return 0<br>
          properties from this function, which is at least a valid<br>
          response.<br>
<br>
        * Use vk_outarray for all property queries<br>
<br>
          This is a bit less error-prone than open-coding the same<br>
          stuff.<br>
<br>
        * Remove VK_COMPOSITE_ALPHA_INHERIT_<wbr>BIT_KHR from surface caps<br>
<br>
          Until we have multi-plane support, we shouldn't pretend to<br>
          have any multi-plane semantics, even if undefined.<br>
<br>
        Suggested-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br>
<br>
        * Simplify addition of VK_USE_PLATFORM_DISPLAY_KHR to<br>
          vulkan_wsi_args<br>
<br>
        Suggested-by: Eric Engestrom <<a href="mailto:eric.engestrom@imgtec.com">eric.engestrom@imgtec.com</a>><br>
<br>
v3:<br>
        Add separate 'display_fd' and 'render_fd' arguments to<br>
        wsi_device_init API. This allows drivers to use different FDs<br>
        for the different aspects of the device.<br>
<br>
        Use largest mode as display size when no preferred mode.<br>
<br>
        If the display doesn't provide a preferred mode, we'll assume<br>
        that the largest supported mode is the "physical size" of the<br>
        device and report that.<br>
<br>
v4:<br>
        Make wsi_image_state enumeration values uppercase.<br>
        Follow more common mesa conventions.<br>
<br>
        Remove 'render_fd' from wsi_device_init API.  The<br>
        wsi_common_display code doesn't use this fd at all, so stop<br>
        passing it in. This avoids any potential confusion over which<br>
        fd to use when creating display-relative object handles.<br>
<br>
        Remove call to wsi_create_prime_image which would never have<br>
        been reached as the necessary condition (use_prime_blit) is<br>
        never set.<br>
<br>
        whitespace cleanups in wsi_common_display.c<br>
<br>
        Suggested-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br>
<br>
        Add depth/bpp info to available surface formats.  Instead of<br>
        hard-coding depth 24 bpp 32 in the drmModeAddFB call, use the<br>
        requested format to find suitable values.<br>
<br>
        Destroy kernel buffers and FBs when swapchain is destroyed. We<br>
        were leaking both of these kernel objects across swapchain<br>
        destruction.<br>
<br>
        Note that wsi_display_wait_for_event waits for anything to<br>
        happen.  wsi_display_wait_for_event is simply a yield so that<br>
        the caller can then check to see if the desired state change<br>
        has occurred.<br>
<br>
        Record swapchain failures in chain for later return. If some<br>
        asynchronous swapchain activity fails, we need to tell the<br>
        application eventually. Record the failure in the swapchain<br>
        and report it at the next acquire_next_image or queue_present<br>
        call.<br>
<br>
        Fix error returns from wsi_display_setup_connector.  If a<br>
        malloc failed, then the result should be<br>
        VK_ERROR_OUT_OF_HOST_MEMORY. Otherwise, the associated ioctl<br>
        failed and we're either VT switched away, or our lease has<br>
        been revoked, in which case we should return<br>
        VK_ERROR_OUT_OF_DATE_KHR.<br>
<br>
        Make sure both sides of if/else brace use matches<br>
<br>
        Note that we assume drmModeSetCrtc is synchronous. Add a<br>
        comment explaining why we can idle any previous displayed<br>
        image as soon as the mode set returns.<br>
<br>
        Note that EACCES from drmModePageFlip means VT inactive.  When<br>
        vt switched away drmModePageFlip returns EACCES. Poll once a<br>
        second waiting until we get some other return value back.<br>
<br>
        Clean up after alloc failure in<br>
        wsi_display_surface_create_<wbr>swapchain. Destroy any created<br>
        images, free the swapchain.<br>
<br>
        Remove physical_device from wsi_display_init_wsi. We never<br>
        need this value, so remove it from the API and from the<br>
        internal wsi_display structure.<br>
<br>
        Use drmModeAddFB2 in wsi_display_image_init.  This takes a drm<br>
        format instead of depth/bpp, which provides more control over<br>
        the format of the data.<br>
<br>
Signed-off-by: Keith Packard <<a href="mailto:keithp@keithp.com">keithp@keithp.com</a>><br>
---<br>
 <a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a>                        |    1 +<br>
 meson.build                         |    4 +-<br>
 src/amd/vulkan/radv_device.c        |    8 +<br>
 src/amd/vulkan/radv_private.h       |    1 +<br>
 src/amd/vulkan/radv_wsi.c           |    3 +-<br>
 src/intel/vulkan/anv_device.c       |    4 +<br>
 src/intel/vulkan/anv_private.h      |    1 +<br>
 src/intel/vulkan/anv_wsi.c          |    3 +-<br>
 src/vulkan/Makefile.am              |    7 +<br>
 src/vulkan/Makefile.sources         |    4 +<br>
 src/vulkan/wsi/meson.build          |    8 +<br>
 src/vulkan/wsi/wsi_common.c         |   19 +-<br>
 src/vulkan/wsi/wsi_common.h         |    5 +-<br>
 src/vulkan/wsi/wsi_common_<wbr>display.c | 1401 ++++++++++++++++++++++++++++++<wbr>+++++<br>
 src/vulkan/wsi/wsi_common_<wbr>display.h |   72 ++<br>
 src/vulkan/wsi/wsi_common_<wbr>private.h |    9 +<br>
 16 files changed, 1544 insertions(+), 6 deletions(-)<br>
 create mode 100644 src/vulkan/wsi/wsi_common_<wbr>display.c<br>
 create mode 100644 src/vulkan/wsi/wsi_common_<wbr>display.h<br>
<br>
diff --git a/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a> b/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
index 172da6b443c..7fcb3220eaa 100644<br>
--- a/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
+++ b/<a href="http://configure.ac" rel="noreferrer" target="_blank">configure.ac</a><br>
@@ -1856,6 +1856,7 @@ fi<br>
 AM_CONDITIONAL(HAVE_PLATFORM_<wbr>X11, echo "$platforms" | grep -q 'x11')<br>
 AM_CONDITIONAL(HAVE_PLATFORM_<wbr>WAYLAND, echo "$platforms" | grep -q 'wayland')<br>
 AM_CONDITIONAL(HAVE_PLATFORM_<wbr>DRM, echo "$platforms" | grep -q 'drm')<br>
+AM_CONDITIONAL(HAVE_PLATFORM_<wbr>DISPLAY, echo "$platforms" | grep -q 'drm')<br>
 AM_CONDITIONAL(HAVE_PLATFORM_<wbr>SURFACELESS, echo "$platforms" | grep -q 'surfaceless')<br>
 AM_CONDITIONAL(HAVE_PLATFORM_<wbr>ANDROID, echo "$platforms" | grep -q 'android')<br>
<br>
diff --git a/meson.build b/meson.build<br>
index 8a17d7f240a..788aed6e159 100644<br>
--- a/meson.build<br>
+++ b/meson.build<br>
@@ -239,11 +239,12 @@ with_platform_wayland = false<br>
 with_platform_x11 = false<br>
 with_platform_drm = false<br>
 with_platform_surfaceless = false<br>
+with_platform_display = false<br>
 egl_native_platform = ''<br>
 _platforms = get_option('platforms')<br>
 if _platforms == 'auto'<br>
   if system_has_kms_drm<br>
-    _platforms = 'x11,wayland,drm,surfaceless'<br>
+    _platforms = 'x11,wayland,drm,surfaceless,<wbr>display'<br>
   elif ['darwin', 'windows', 'cygwin'].contains(host_<wbr>machine.system())<br>
     _platforms = 'x11,surfaceless'<br>
   elif ['haiku'].contains(host_<wbr>machine.system())<br>
@@ -260,6 +261,7 @@ if _platforms != ''<br>
   with_platform_drm = _split.contains('drm')<br>
   with_platform_haiku = _split.contains('haiku')<br>
   with_platform_surfaceless = _split.contains('surfaceless')<br>
+  with_platform_display = _split.contains('display')<br>
   egl_native_platform = _split[0]<br>
 endif<br>
<br>
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c<br>
index 7a11e08f97c..35fd1ef6b29 100644<br>
--- a/src/amd/vulkan/radv_device.c<br>
+++ b/src/amd/vulkan/radv_device.c<br>
@@ -223,6 +223,7 @@ radv_physical_device_init(<wbr>struct radv_physical_device *device,<br>
        VkResult result;<br>
        drmVersionPtr version;<br>
        int fd;<br>
+       int master_fd = -1;<br>
<br>
        fd = open(path, O_RDWR | O_CLOEXEC);<br>
        if (fd < 0)<br>
@@ -237,6 +238,8 @@ radv_physical_device_init(<wbr>struct radv_physical_device *device,<br>
<br>
        if (strcmp(version->name, "amdgpu")) {<br>
                drmFreeVersion(version);<br>
+               if (master_fd != -1)<br>
+                       close(master_fd);<br>
                close(fd);<br>
                return VK_ERROR_INCOMPATIBLE_DRIVER;<br>
        }<br>
@@ -254,6 +257,7 @@ radv_physical_device_init(<wbr>struct radv_physical_device *device,<br>
                goto fail;<br>
        }<br>
<br>
+       device->master_fd = master_fd;<br>
        device->local_fd = fd;<br>
        device->ws->query_info(device-<wbr>>ws, &device->rad_info);<br>
<br>
@@ -317,6 +321,8 @@ radv_physical_device_init(<wbr>struct radv_physical_device *device,<br>
<br>
 fail:<br>
        close(fd);<br>
+       if (master_fd != -1)<br>
+               close(master_fd);<br>
        return result;<br>
 }<br>
<br>
@@ -327,6 +333,8 @@ radv_physical_device_finish(<wbr>struct radv_physical_device *device)<br>
        device->ws->destroy(device-><wbr>ws);<br>
        disk_cache_destroy(device-><wbr>disk_cache);<br>
        close(device->local_fd);<br>
+       if (device->master_fd != -1)<br>
+               close(device->master_fd);<br>
 }<br>
<br>
 static void *<br>
diff --git a/src/amd/vulkan/radv_private.<wbr>h b/src/amd/vulkan/radv_private.<wbr>h<br>
index 0f8ddb2e106..35a161c3671 100644<br>
--- a/src/amd/vulkan/radv_private.<wbr>h<br>
+++ b/src/amd/vulkan/radv_private.<wbr>h<br>
@@ -281,6 +281,7 @@ struct radv_physical_device {<br>
        uint8_t                                     cache_uuid[VK_UUID_SIZE];<br>
<br>
        int local_fd;<br>
+       int master_fd;<br>
        struct wsi_device                       wsi_device;<br>
<br>
        bool has_rbplus; /* if RB+ register exist */<br>
diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c<br>
index 927650480a6..2840b666727 100644<br>
--- a/src/amd/vulkan/radv_wsi.c<br>
+++ b/src/amd/vulkan/radv_wsi.c<br>
@@ -41,7 +41,8 @@ radv_init_wsi(struct radv_physical_device *physical_device)<br>
        return wsi_device_init(&physical_<wbr>device->wsi_device,<br>
                               radv_physical_device_to_<wbr>handle(physical_device),<br>
                               radv_wsi_proc_addr,<br>
-                              &physical_device->instance-><wbr>alloc);<br>
+                              &physical_device->instance-><wbr>alloc,<br>
+                              physical_device->master_fd);<br></blockquote><div><br></div><div>We can just pass -1 in here and move the rest of the anv/radv stuff into patches 1 and 2.  That would make 1 and 2 a bit easier to review but it doesn't really matter now that I've found this bit of code. :)<br><br></div><div>--Jason<br></div></div></div></div>