Signed-off-by: Eric Engestrom <[email protected]>
---
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
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev