[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