[Mesa-dev] [PATCH kmscube] HACK: automatic modifier selection

Lucas Stach l.stach at pengutronix.de
Wed May 3 15:52:28 UTC 2017


This lacks proper abstractions and error checks, but sending out
anyways, as it might be helpful for other people testing the whole
modifier chain.

This works on top of Ben's plane property blob patches.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 common.c     | 29 ++++++++++--------------
 common.h     |  3 ++-
 drm-atomic.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 drm-common.h |  2 ++
 kmscube.c    |  3 +--
 5 files changed, 87 insertions(+), 22 deletions(-)

diff --git a/common.c b/common.c
index b76c9943fb35..ab8d1b971a21 100644
--- a/common.c
+++ b/common.c
@@ -30,30 +30,21 @@
 #include <string.h>
 
 #include "common.h"
+#include "drm-common.h"
 
 static struct gbm gbm;
 
-#ifdef HAVE_GBM_MODIFIERS
-static int
-get_modifiers(uint64_t **mods)
+const struct gbm * init_gbm(const struct drm *drm, uint64_t modifier)
 {
-	/* Assumed LINEAR is supported everywhere */
-	static uint64_t modifiers[] = {DRM_FORMAT_MOD_LINEAR};
-	*mods = modifiers;
-	return 1;
-}
-#endif
-
-const struct gbm * init_gbm(int drm_fd, int w, int h, uint64_t modifier)
-{
-	gbm.dev = gbm_create_device(drm_fd);
+	gbm.dev = gbm_create_device(drm->fd);
 
 #ifndef HAVE_GBM_MODIFIERS
 	if (modifier != DRM_FORMAT_MOD_INVALID) {
 		fprintf(stderr, "Modifiers requested but support isn't available\n");
 		return NULL;
 	}
-	gbm.surface = gbm_surface_create(gbm.dev, w, h,
+	gbm.surface = gbm_surface_create(gbm.dev,
+			drm->mode->hdisplay, drm->mode->vdisplay,
 			GBM_FORMAT_XRGB8888,
 			GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
 #else
@@ -63,9 +54,11 @@ const struct gbm * init_gbm(int drm_fd, int w, int h, uint64_t modifier)
 		count = 1;
 		mods = &modifier;
 	} else {
-		count = get_modifiers(&mods);
+		count = drm->count_modifiers;
+		mods = drm->modifiers;
 	}
-	gbm.surface = gbm_surface_create_with_modifiers(gbm.dev, w, h,
+	gbm.surface = gbm_surface_create_with_modifiers(gbm.dev,
+			drm->mode->hdisplay, drm->mode->vdisplay,
 			GBM_FORMAT_XRGB8888, mods, count);
 #endif
 
@@ -74,8 +67,8 @@ const struct gbm * init_gbm(int drm_fd, int w, int h, uint64_t modifier)
 		return NULL;
 	}
 
-	gbm.width = w;
-	gbm.height = h;
+	gbm.width = drm->mode->hdisplay;
+	gbm.height = drm->mode->vdisplay;
 
 	return &gbm;
 }
diff --git a/common.h b/common.h
index 0acf4c0dea99..7ace96a01694 100644
--- a/common.h
+++ b/common.h
@@ -63,7 +63,8 @@ struct gbm {
 	int width, height;
 };
 
-const struct gbm * init_gbm(int drm_fd, int w, int h, uint64_t modifier);
+struct drm;
+const struct gbm * init_gbm(const struct drm *drm, uint64_t modifier);
 
 
 struct egl {
diff --git a/drm-atomic.c b/drm-atomic.c
index 254897957fe8..b7569a242cf1 100644
--- a/drm-atomic.c
+++ b/drm-atomic.c
@@ -335,10 +335,53 @@ static int get_plane_id(void)
 	return ret;
 }
 
+struct drm_format_modifier {
+	uint64_t formats;
+	uint32_t offset;
+	uint32_t pad;
+
+	/* This modifier can be used with the format for this plane. */
+	uint64_t modifier;
+};
+
+struct drm_format_modifier_blob {
+	uint32_t version;
+
+	/* Flags */
+	uint32_t flags;
+
+	/* Number of fourcc formats supported */
+	uint32_t count_formats;
+
+	/* Where in this blob the formats exist (in bytes) */
+	uint32_t formats_offset;
+
+	/* Number of drm_format_modifiers */
+	uint32_t count_modifiers;
+
+	/* Where in this blob the modifiers exist (in bytes) */
+	uint32_t modifiers_offset;
+
+	/* u32 formats[] */
+	/* struct drm_format_modifier modifiers[] */
+};
+
+static inline uint32_t *
+formats_ptr(struct drm_format_modifier_blob *blob)
+{
+	return (uint32_t *)(((char *)blob) + blob->formats_offset);
+}
+
+static inline struct drm_format_modifier *
+modifiers_ptr(struct drm_format_modifier_blob *blob)
+{
+	return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset);
+}
+
 const struct drm * init_drm_atomic(const char *device)
 {
 	uint32_t plane_id;
-	int ret;
+	int ret, format_index = 0;
 
 	ret = init_drm(&drm, device);
 	if (ret)
@@ -400,6 +443,33 @@ const struct drm * init_drm_atomic(const char *device)
 	get_properties(crtc, CRTC, drm.crtc_id);
 	get_properties(connector, CONNECTOR, drm.connector_id);
 
+	for (int i = 0; i < (int)drm.plane->plane->count_formats; i++) {
+		if (drm.plane->plane->formats[i] == DRM_FORMAT_XRGB8888)
+			format_index = i;
+	}
+
+	for (int i = 0; i < (int)drm.plane->props->count_props; i++) {
+		if (!strcmp(drm.plane->props_info[i]->name, "IN_FORMATS")) {
+			drmModePropertyBlobPtr blob =
+					drmModeGetPropertyBlob(drm.fd, drm.plane->props->prop_values[i]);
+
+			struct drm_format_modifier_blob *m = blob->data;
+			struct drm_format_modifier *mod = modifiers_ptr(m);
+
+			for (int j = 0; j < (int)m->count_modifiers; j++, mod++) {
+				if (mod->formats & (1ULL << format_index))
+					drm.count_modifiers++;
+			}
+			drm.modifiers = calloc(drm.count_modifiers,
+					       sizeof(uint64_t));
+			mod = modifiers_ptr(m);
+			for (int j = 0; j < (int)m->count_modifiers; j++, mod++) {
+				if (mod->formats & (1ULL << format_index))
+					drm.modifiers[j] = mod->modifier;
+			}
+		}
+	}
+
 	drm.run = atomic_run;
 
 	return &drm;
diff --git a/drm-common.h b/drm-common.h
index 53af2cfee4a9..09733d1c8a0c 100644
--- a/drm-common.h
+++ b/drm-common.h
@@ -58,6 +58,8 @@ struct drm {
 	int crtc_index;
 	int kms_in_fence_fd;
 	int kms_out_fence_fd;
+	int count_modifiers;
+	uint64_t *modifiers;
 
 	drmModeModeInfo *mode;
 	uint32_t crtc_id;
diff --git a/kmscube.c b/kmscube.c
index 3a2c4dd1aa70..ac3bbb2deaa7 100644
--- a/kmscube.c
+++ b/kmscube.c
@@ -130,8 +130,7 @@ int main(int argc, char *argv[])
 		return -1;
 	}
 
-	gbm = init_gbm(drm->fd, drm->mode->hdisplay, drm->mode->vdisplay,
-			modifier);
+	gbm = init_gbm(drm, modifier);
 	if (!gbm) {
 		printf("failed to initialize GBM\n");
 		return -1;
-- 
2.11.0



More information about the mesa-dev mailing list