[Mesa-dev] [PATCH mesa 2/6] vulkan/wsi/display: also select a plane when selecting a crtc

Eric Engestrom eric.engestrom at intel.com
Wed Sep 26 15:38:06 UTC 2018


Signed-off-by: Eric Engestrom <eric.engestrom at intel.com>
---
 src/vulkan/wsi/wsi_common_display.c | 80 +++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
index 2d378afe3d36fe7cc177..6c9160a445c8f25a8ad5 100644
--- a/src/vulkan/wsi/wsi_common_display.c
+++ b/src/vulkan/wsi/wsi_common_display.c
@@ -74,6 +74,7 @@ typedef struct wsi_display_connector {
    struct wsi_display           *wsi;
    uint32_t                     id;
    uint32_t                     crtc_id;
+   uint32_t                     plane_id;
    char                         *name;
    bool                         connected;
    bool                         active;
@@ -1348,6 +1349,81 @@ wsi_display_select_crtc(const struct wsi_display_connector *connector,
    return crtc_id;
 }
 
+/*
+ * Pick a suitable plane for the current CRTC. Prefer a plane currently
+ * active on the CRTC. Settle for a plane which is currently idle but
+ * is compatible with the CRTC. Fall back to the first idle plane found.
+ */
+static uint32_t
+wsi_display_select_plane(const struct wsi_display_connector * const connector)
+{
+   struct wsi_display *wsi = connector->wsi;
+   uint32_t plane_id = connector->plane_id;
+
+   if (plane_id)
+      return plane_id;
+
+   /* We understand universal planes */
+   drmSetClientCap(wsi->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+
+   drmModePlaneRes *plane_res = drmModeGetPlaneResources(wsi->fd);
+   if (!plane_res)
+      return 0;
+
+   /* if there's a plane is active on the connector's crtc, pick it */
+   for (size_t i = 0; i < plane_res->count_planes; i++) {
+      drmModePlane *plane = drmModeGetPlane(wsi->fd, plane_res->planes[i]);
+      if (!plane)
+         continue;
+
+      if (plane->crtc_id != connector->crtc_id) {
+         drmModeFreePlane(plane);
+         continue;
+      }
+
+      plane_id = plane->plane_id;
+      drmModeFreePlane(plane);
+      goto success;
+   }
+
+   /* if a plane is not active on any crtc but the connector's crtc is
+    * in the plane's possible_crtcs, pick it */
+   for (size_t i = 0; i < plane_res->count_planes; i++) {
+      drmModePlane *plane = drmModeGetPlane(wsi->fd, plane_res->planes[i]);
+      if (!plane)
+         continue;
+
+      if (!(plane->possible_crtcs & (1u << connector->crtc_id))) {
+         drmModeFreePlane(plane);
+         continue;
+      }
+
+      plane_id = plane->plane_id;
+      drmModeFreePlane(plane);
+      goto success;
+   }
+
+   /* if all else fails, pick a plane not active on any crtc */
+   for (size_t i = 0; i < plane_res->count_planes; i++) {
+      drmModePlane *plane = drmModeGetPlane(wsi->fd, plane_res->planes[i]);
+      if (!plane)
+         continue;
+
+      if (plane->crtc_id) {
+         drmModeFreePlane(plane);
+         continue;
+      }
+
+      plane_id = plane->plane_id;
+      drmModeFreePlane(plane);
+      goto success;
+   }
+
+success:
+   drmModeFreePlaneResources(plane_res);
+   return plane_id;
+}
+
 static VkResult
 wsi_display_setup_connector(wsi_display_connector *connector,
                             wsi_display_mode *display_mode)
@@ -1387,6 +1463,10 @@ wsi_display_setup_connector(wsi_display_connector *connector,
          result = VK_ERROR_SURFACE_LOST_KHR;
          goto bail_connector;
       }
+
+      /* Select the primary plane of that CRTC, and populate the
+       * format/modifier lists for that plane */
+      connector->plane_id = wsi_display_select_plane(connector);
    }
 
    if (connector->current_mode != display_mode) {
-- 
Cheers,
  Eric



More information about the mesa-dev mailing list