aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2019-02-27 12:43:04 +0100
committerGerd Hoffmann <kraxel@redhat.com>2019-02-27 12:43:04 +0100
commit437f8e7a66a36054862b2cca8cbe475796704303 (patch)
treee68e14f8a45a81762dd9dba12e904dc5c78b4f3b
parent559ed303bd98f35bf46eb90958088bce90384c25 (diff)
downloaddrminfo-437f8e7a66a36054862b2cca8cbe475796704303.tar.gz
property and plane type bits
-rw-r--r--drminfo.c143
-rw-r--r--drmtest.c4
-rw-r--r--drmtools.c104
-rw-r--r--drmtools.h9
4 files changed, 204 insertions, 56 deletions
diff --git a/drminfo.c b/drminfo.c
index baaa135..66addda 100644
--- a/drminfo.c
+++ b/drminfo.c
@@ -7,6 +7,7 @@
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
+#include <termios.h>
#include <sys/ioctl.h>
#include <libdrm/drm_fourcc.h>
@@ -23,7 +24,39 @@ static int ttycols = 80;
/* ------------------------------------------------------------------ */
-static void drm_info_conn(int fd, drmModeConnector *conn)
+static void drm_list_properties(int fd, uint32_t id, uint32_t objtype)
+{
+ drmModeObjectProperties *props =
+ drmModeObjectGetProperties(fd, id, objtype);
+ drmModePropertyPtr prop;
+ uint32_t i;
+
+ for (i = 0; i < props->count_props; i++) {
+ prop = drmModeGetProperty(fd, props->props[i]);
+ if (prop->count_values) {
+ fprintf(stderr, " property: %s, value %" PRId64 "\n",
+ prop->name, props->prop_values[i]);
+ } else {
+ fprintf(stderr, " property: %s\n", prop->name);
+ }
+ drmModeFreeProperty(prop);
+ }
+ drmModeFreeObjectProperties(props);
+}
+
+static drmModePropertyBlobRes *
+drm_get_property_blob(int fd, uint32_t id, uint32_t objtype, const char *name)
+{
+ uint64_t blob_id =
+ drm_get_property_value(fd, id, objtype, name);
+
+ if (!blob_id)
+ return NULL;
+ return drmModeGetPropertyBlob(fd, blob_id);
+}
+
+static void drm_info_conn(int fd, drmModeConnector *conn,
+ bool print_properties)
{
drmModeEncoder *enc;
drmModeCrtc *crtc;
@@ -62,6 +95,10 @@ static void drm_info_conn(int fd, drmModeConnector *conn)
drmModeFreeEncoder(enc);
}
+ if (print_properties)
+ drm_list_properties(fd, conn->connector_id,
+ DRM_MODE_OBJECT_CONNECTOR);
+
c = 1;
for (m = 0; m < conn->count_modes; m++) {
if (m+1 < conn->count_modes &&
@@ -81,7 +118,7 @@ static void drm_info_conn(int fd, drmModeConnector *conn)
}
}
-static void drm_info_conns(int fd)
+static void drm_info_conns(int fd, bool print_properties)
{
drmModeConnector *conn;
drmModeRes *res;
@@ -98,7 +135,7 @@ static void drm_info_conns(int fd)
if (!conn)
continue;
- drm_info_conn(fd, conn);
+ drm_info_conn(fd, conn, print_properties);
drmModeFreeConnector(conn);
fprintf(stdout, "\n");
}
@@ -127,40 +164,13 @@ static size_t drm_modifiers_for_format(int fd, uint32_t plane_id,
uint32_t drm_format,
uint64_t **drm_modifiers)
{
- /* Get the properties of the plane */
- drmModeObjectProperties *props =
- drmModeObjectGetProperties(fd, plane_id, DRM_MODE_OBJECT_PLANE);
- if (!props)
- return 0;
-
- /* Find the blob the contains the formats and their modifiers */
- uint32_t blob_id = 0;
- for (size_t i = 0; i< props->count_props; i++) {
- const drmModePropertyPtr prop =
- drmModeGetProperty(fd, props->props[i]);
-
- if (!strcmp(prop->name, "IN_FORMATS")) {
- blob_id = props->prop_values[i];
- drmModeFreeProperty(prop);
- break;
- }
-
- drmModeFreeProperty(prop);
- }
-
- /* Property not found, which means old kernel, so definitely no
- * modifiers support */
- if (blob_id == 0) {
- drmModeFreeObjectProperties(props);
- return 0;
- }
-
/* Grab the IN_FORMATS blob */
- drmModePropertyBlobRes *blob = drmModeGetPropertyBlob(fd, blob_id);
- if (!blob) {
- drmModeFreeObjectProperties(props);
+ drmModePropertyBlobRes *blob =
+ drm_get_property_blob(fd, plane_id, DRM_MODE_OBJECT_PLANE,
+ "IN_FORMATS");
+
+ if (!blob)
return 0;
- }
/* Get the formats and modifiers out of the blob */
struct drm_format_modifier_blob *fmt_mod_blob = blob->data;
@@ -197,19 +207,37 @@ static size_t drm_modifiers_for_format(int fd, uint32_t plane_id,
}
drmModeFreePropertyBlob(blob);
- drmModeFreeObjectProperties(props);
*drm_modifiers = modifiers;
return modifiers_count;
}
+static const char *drm_info_plane_type_string(uint64_t type)
+{
+ switch (type) {
+ case 0:
+ return "overlay";
+ case 1:
+ return "primary";
+ case 2:
+ return "cursor";
+ default:
+ return "unknown";
+ }
+}
+
static void drm_info_plane(int fd, drmModePlane *plane,
- bool print_modifiers)
+ bool print_modifiers, bool print_properties)
{
+ uint64_t type = drm_get_property_value(fd, plane->plane_id,
+ DRM_MODE_OBJECT_PLANE, "type");
int i;
- fprintf(stdout, "plane: %d, crtc: %d, fb: %d\n",
- plane->plane_id, plane->crtc_id, plane->fb_id);
+ fprintf(stdout, "plane: %d, crtc: %d, fb: %d, type: %s\n",
+ plane->plane_id, plane->crtc_id, plane->fb_id,
+ drm_info_plane_type_string(type));
+ if (print_properties)
+ drm_list_properties(fd, plane->plane_id, DRM_MODE_OBJECT_PLANE);
if (!print_modifiers) {
fprintf(stdout, " formats:");
@@ -255,7 +283,7 @@ static void drm_info_plane(int fd, drmModePlane *plane,
}
}
-static void drm_info_planes(int fd, bool print_modifiers)
+static void drm_info_planes(int fd, bool print_modifiers, bool print_properties)
{
drmModePlaneRes *pres;
drmModePlane *plane;
@@ -273,7 +301,7 @@ static void drm_info_planes(int fd, bool print_modifiers)
if (!plane)
continue;
- drm_info_plane(fd, plane, print_modifiers);
+ drm_info_plane(fd, plane, print_modifiers, print_properties);
drmModeFreePlane(plane);
fprintf(stdout, "\n");
}
@@ -283,10 +311,11 @@ static void drm_info_fmts(int fd)
{
int i;
+ drm_plane_init(fd);
fprintf(stdout, "framebuffer formats\n");
drm_print_format_hdr(stdout, 4, true);
for (i = 0; i < fmtcnt; i++) {
- if (!drm_probe_format(fd, &fmts[i]))
+ if (!drm_probe_format_fb(fd, &fmts[i]))
continue;
drm_print_format(stdout, &fmts[i], 4, true);
}
@@ -351,11 +380,13 @@ static void usage(FILE *fp)
" -h print this\n"
" -c <nr> pick card\n"
" -a print all card info\n"
+ " -A print all card info, with plane modifiers\n"
" -m print misc card info (busid)\n"
" -o print supported outputs (crtcs)\n"
" -p print supported planes\n"
" -P print supported planes, with modifiers\n"
" -f print supported formats\n"
+ " -r list properties\n"
" -l list all known formats\n"
"\n");
}
@@ -368,11 +399,12 @@ int main(int argc, char **argv)
bool conn = false;
bool plane = false;
bool modifiers = false;
+ bool properties = false;
bool format = false;
char *columns;
for (;;) {
- c = getopt(argc, argv, "hlamopPfc:");
+ c = getopt(argc, argv, "hlaAmopPfrc:");
if (c == -1)
break;
switch (c) {
@@ -382,12 +414,14 @@ int main(int argc, char **argv)
case 'l':
list_formats(stdout);
exit(0);
+ case 'A':
+ modifiers = true;
+ /* fall through */
case 'a':
misc = true;
conn = true;
plane = true;
format = true;
- modifiers = true;
break;
case 'm':
misc = true;
@@ -395,12 +429,14 @@ int main(int argc, char **argv)
case 'o':
conn = true;
break;
+ case 'P':
+ modifiers = true;
+ /* fall through */
case 'p':
plane = true;
break;
- case 'P':
- plane = true;
- modifiers = true;
+ case 'r':
+ properties = true;
break;
case 'f':
format = true;
@@ -415,16 +451,23 @@ int main(int argc, char **argv)
}
columns = getenv("COLUMNS");
- if (columns)
+ if (columns) {
ttycols = atoi(columns);
+ } else {
+ struct winsize win = { 0 };
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 &&
+ win.ws_col != 0) {
+ ttycols = win.ws_col;
+ }
+ }
fd = drm_open(card);
if (misc)
drm_info_misc(fd);
if (conn)
- drm_info_conns(fd);
+ drm_info_conns(fd, properties);
if (plane)
- drm_info_planes(fd, modifiers);
+ drm_info_planes(fd, modifiers, properties);
if (format)
drm_info_fmts(fd);
return 0;
diff --git a/drmtest.c b/drmtest.c
index c2c119f..4d72fb7 100644
--- a/drmtest.c
+++ b/drmtest.c
@@ -274,7 +274,9 @@ int main(int argc, char **argv)
if (fmts[i].cairo == CAIRO_FORMAT_INVALID)
continue;
}
- if (!drm_probe_format(fd, &fmts[i]))
+ if (!drm_probe_format_fb(fd, &fmts[i]))
+ continue;
+ if (!drm_probe_format_primary(&fmts[i]))
continue;
fmt = &fmts[i];
break;
diff --git a/drmtools.c b/drmtools.c
index 93c1260..fb4c420 100644
--- a/drmtools.c
+++ b/drmtools.c
@@ -524,7 +524,98 @@ void drm_conn_name(drmModeConnector *conn, char *dest, int dlen)
/* ------------------------------------------------------------------ */
-bool drm_probe_format(int fd, const struct fbformat *fmt)
+static drmModePlane *primary;
+static drmModePlane *cursor;
+static drmModePlane *overlay;
+
+uint64_t drm_get_property_value(int fd, uint32_t id, uint32_t objtype,
+ const char *name)
+{
+ drmModeObjectProperties *props =
+ drmModeObjectGetProperties(fd, id, objtype);
+ drmModePropertyPtr prop;
+ uint64_t value = 0;
+ uint32_t i;
+
+ for (i = 0; i < props->count_props; i++) {
+ prop = drmModeGetProperty(fd, props->props[i]);
+ if (!strcmp(prop->name, name))
+ value = props->prop_values[i];
+ drmModeFreeProperty(prop);
+ }
+ drmModeFreeObjectProperties(props);
+
+ return value;
+}
+
+static bool drm_probe_format_plane(const drmModePlane *plane,
+ const struct fbformat *fmt)
+{
+ int i;
+
+ if (!plane)
+ return false;
+ for (i = 0; i < plane->count_formats; i++)
+ if (plane->formats[i] == fmt->fourcc)
+ return true;
+ return false;
+}
+
+bool drm_probe_format_primary(const struct fbformat *fmt)
+{
+ return drm_probe_format_plane(primary, fmt);
+}
+
+bool drm_probe_format_cursor(const struct fbformat *fmt)
+{
+ return drm_probe_format_plane(cursor, fmt);
+}
+
+bool drm_probe_format_overlay(const struct fbformat *fmt)
+{
+ return drm_probe_format_plane(overlay, fmt);
+}
+
+void drm_plane_init(int fd)
+{
+ drmModePlaneRes *pres;
+ drmModePlane *plane;
+ uint64_t type;
+ int i;
+
+ drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+ pres = drmModeGetPlaneResources(fd);
+ if (pres == NULL) {
+ fprintf(stderr, "drmModeGetPlaneResources() failed\n");
+ exit(1);
+ }
+
+ /* find plane */
+ for (i = 0; i < pres->count_planes; i++) {
+ plane = drmModeGetPlane(fd, pres->planes[i]);
+ if (!plane)
+ continue;
+ type = drm_get_property_value(fd, plane->plane_id,
+ DRM_MODE_OBJECT_PLANE, "type");
+ if (type == 0 /* overlay */) {
+ if (!overlay)
+ overlay = drmModeGetPlane(fd, pres->planes[i]);
+ }
+ if (type == 1 /* primary */) {
+ if (!primary)
+ primary = drmModeGetPlane(fd, pres->planes[i]);
+ }
+ if (type == 2 /* cursor */) {
+ if (!cursor)
+ cursor = drmModeGetPlane(fd, pres->planes[i]);
+ }
+ drmModeFreePlane(plane);
+ }
+}
+
+/* ------------------------------------------------------------------ */
+
+bool drm_probe_format_fb(int fd, const struct fbformat *fmt)
{
struct drm_mode_create_dumb cd;
struct drm_mode_destroy_dumb dd;
@@ -569,9 +660,12 @@ done:
void drm_print_format(FILE *fp, const struct fbformat *fmt,
int indent, bool libs)
{
- fprintf(fp, "%*s%-8s: [%2d:0] %-14s %-11s %-16s",
+ fprintf(fp, "%*s%-8s: [%2d:0] %-14s %-11s %c %c %c %-16s",
indent, "",
fmt->name, fmt->bpp - 1, fmt->fields, fmt->bits,
+ drm_probe_format_primary(fmt) ? 'P' : '.',
+ drm_probe_format_overlay(fmt) ? 'O' : '.',
+ drm_probe_format_cursor(fmt) ? 'C' : '.',
fmt->fourcc
? "fourcc le"
: "legacy cpu " LE_BE("(le)", "(be)"));
@@ -585,9 +679,9 @@ void drm_print_format(FILE *fp, const struct fbformat *fmt,
void drm_print_format_hdr(FILE *fp, int indent, bool libs)
{
- fprintf(fp, "%*s%-8s: %-6s %-14s %-11s %-16s",
+ fprintf(fp, "%*s%-8s: %-6s %-14s %-11s %-6s %-16s",
indent, "",
- "name", "bpp", "fields", "bits",
+ "name", "bpp", "fields", "bits", "plane",
"type endian");
if (libs) {
fprintf(fp, " lib support");
@@ -698,6 +792,8 @@ void drm_init_dev(int devnr, const char *output,
exit(1);
}
+ drm_plane_init(fd);
+
/* save crtc */
scrtc = drmModeGetCrtc(fd, enc->crtc_id);
}
diff --git a/drmtools.h b/drmtools.h
index 3934375..f95b4fa 100644
--- a/drmtools.h
+++ b/drmtools.h
@@ -19,7 +19,14 @@ const char *drm_connector_type_name(int nr);
const char *drm_connector_mode_name(int nr);
const char *drm_encoder_type_name(int nr);
void drm_conn_name(drmModeConnector *conn, char *dest, int dlen);
-bool drm_probe_format(int fd, const struct fbformat *fmt);
+
+uint64_t drm_get_property_value(int fd, uint32_t id, uint32_t objtype,
+ const char *name);
+bool drm_probe_format_primary(const struct fbformat *fmt);
+bool drm_probe_format_cursor(const struct fbformat *fmt);
+void drm_plane_init(int fd);
+
+bool drm_probe_format_fb(int fd, const struct fbformat *fmt);
void drm_print_format(FILE *fp, const struct fbformat *fmt,
int indent, bool libs);
void drm_print_format_hdr(FILE *fp, int indent, bool libs);