dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type
@ 2015-09-23  2:45 Hyungwon Hwang
  2015-09-23  2:45 ` [PATCH v3 2/3] modetest: add atomic modeset support Hyungwon Hwang
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Hyungwon Hwang @ 2015-09-23  2:45 UTC (permalink / raw)
  To: dri-devel, ppaalanen, emil.l.velikov

Modetest gets the property name from user to set it. So the name must be
converted to its id. Until now, this is done in the set_property(). But to
support atomic modeset in modetest, this logic should be separated from the
fuction, because atomic modeset and legacy modeset use different IOCTLs.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
---
 tests/modetest/modetest.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 3b01918..08ecf58 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -894,12 +894,11 @@ struct property_arg {
 	uint64_t value;
 };

-static void set_property(struct device *dev, struct property_arg *p)
+static int get_prop_info(struct resources *resources, struct property_arg *p,
+							const char *obj_type)
 {
 	drmModeObjectProperties *props = NULL;
 	drmModePropertyRes **props_info = NULL;
-	const char *obj_type;
-	int ret;
 	int i;

 	p->obj_type = 0;
@@ -918,21 +917,21 @@ static void set_property(struct device *dev, struct property_arg *p)
 		}								\
 	} while(0)								\

-	find_object(dev->resources, res, crtc, CRTC);
+	find_object(resources, res, crtc, CRTC);
 	if (p->obj_type == 0)
-		find_object(dev->resources, res, connector, CONNECTOR);
+		find_object(resources, res, connector, CONNECTOR);
 	if (p->obj_type == 0)
-		find_object(dev->resources, plane_res, plane, PLANE);
+		find_object(resources, plane_res, plane, PLANE);
 	if (p->obj_type == 0) {
 		fprintf(stderr, "Object %i not found, can't set property\n",
 			p->obj_id);
-			return;
+			return -1;
 	}

 	if (!props) {
 		fprintf(stderr, "%s %i has no properties\n",
 			obj_type, p->obj_id);
-		return;
+		return -1;
 	}

 	for (i = 0; i < (int)props->count_props; ++i) {
@@ -945,11 +944,23 @@ static void set_property(struct device *dev, struct property_arg *p)
 	if (i == (int)props->count_props) {
 		fprintf(stderr, "%s %i has no %s property\n",
 			obj_type, p->obj_id, p->name);
-		return;
+		return -1;
 	}

 	p->prop_id = props->props[i];

+	return 0;
+}
+
+static void set_property(struct device *dev, struct property_arg *p)
+{
+	int ret;
+	const char *obj_type = NULL;
+
+	ret = get_prop_info(dev->resources, p, obj_type);
+	if (ret < 0)
+		return;
+
 	ret = drmModeObjectSetProperty(dev->fd, p->obj_id, p->obj_type,
 				       p->prop_id, p->value);
 	if (ret < 0)
--
2.4.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 2/3] modetest: add atomic modeset support
  2015-09-23  2:45 [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type Hyungwon Hwang
@ 2015-09-23  2:45 ` Hyungwon Hwang
  2015-11-26 23:42   ` Emil Velikov
  2015-09-23  2:45 ` [PATCH v3 3/3] modetest: add atomic page flip support Hyungwon Hwang
  2015-11-26 16:42 ` [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type Emil Velikov
  2 siblings, 1 reply; 8+ messages in thread
From: Hyungwon Hwang @ 2015-09-23  2:45 UTC (permalink / raw)
  To: dri-devel, ppaalanen, emil.l.velikov

This patch adds support for atomic modeset. Using -a option, user can
make modeset to use DRM_IOCTL_MODE_ATOMIC instead of legacy IOCTLs.
Also, by using -w option, user can set the property as before.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
---
 tests/modetest/modetest.c | 273 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 265 insertions(+), 8 deletions(-)

diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 08ecf58..bc5a227 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -1477,25 +1477,32 @@ static int parse_property(struct property_arg *p, const char *arg)

 static void usage(char *name)
 {
-	fprintf(stderr, "usage: %s [-cDdefMPpsCvw]\n", name);
+	fprintf(stderr, "usage: %s [-acDdefMPpsCvw]\n", name);
+	fprintf(stderr, "\tA: supported in atomic modeset\n");
+	fprintf(stderr, "\tL: supported in legacy modeset\n");

-	fprintf(stderr, "\n Query options:\n\n");
+	fprintf(stderr, "\n Query options: [AL]\n\n");
 	fprintf(stderr, "\t-c\tlist connectors\n");
 	fprintf(stderr, "\t-e\tlist encoders\n");
 	fprintf(stderr, "\t-f\tlist framebuffers\n");
 	fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n");

-	fprintf(stderr, "\n Test options:\n\n");
+	fprintf(stderr, "\n Common Test options: [AL]\n\n");
+	fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");
+
+	fprintf(stderr, "\n Atomic Test options: [A]\n\n");
+	fprintf(stderr, "\t-a\tuse atomic modeset\n");
+
+	fprintf(stderr, "\n Legacy test options: [L]\n\n");
 	fprintf(stderr, "\t-P <crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane\n");
 	fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[-<vrefresh>][@<format>]\tset a mode\n");
 	fprintf(stderr, "\t-C\ttest hw cursor\n");
 	fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
-	fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");

 	fprintf(stderr, "\n Generic options:\n\n");
-	fprintf(stderr, "\t-d\tdrop master after mode set\n");
-	fprintf(stderr, "\t-M module\tuse the given driver\n");
-	fprintf(stderr, "\t-D device\tuse the given device\n");
+	fprintf(stderr, "\t-d\tdrop master after mode set [L]\n");
+	fprintf(stderr, "\t-M module\tuse the given driver [AL]\n");
+	fprintf(stderr, "\t-D device\tuse the given device [AL]\n");

 	fprintf(stderr, "\n\tDefault is to dump all info.\n");
 	exit(0);
@@ -1554,7 +1561,224 @@ static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe)
 	return 0;
 }

-static char optstr[] = "cdD:efM:P:ps:Cvw:";
+static bool is_obj_id_in_prop_args(struct property_arg *prop_args,
+				unsigned int prop_count, uint32_t obj_id)
+{
+	unsigned int i;
+
+	for (i = 0; i < prop_count; i++)
+		if (obj_id == prop_args[i].obj_id)
+			return true;
+
+	return false;
+}
+
+static int get_value_in_prop_args(struct property_arg *prop_args,
+			unsigned int prop_count, uint32_t obj_id,
+			const char *name, uint64_t *out)
+{
+	unsigned int i;
+
+	for (i = 0; i < prop_count; i++) {
+		if (prop_args[i].obj_id == obj_id &&
+		    !strcmp(prop_args[i].name, name)) {
+			*out = prop_args[i].value;
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+static uint32_t get_plane_prop_id(struct resources *res, uint32_t obj_id,
+							const char *name)
+{
+	drmModePropertyRes *props_info;
+	struct plane *plane;
+	unsigned int i, j;
+
+	for (i = 0; i < res->plane_res->count_planes; i++) {
+		plane = &res->planes[i];
+		if (plane->plane->plane_id != obj_id)
+			continue;
+
+		for (j = 0; j < plane->props->count_props; j++) {
+			props_info = plane->props_info[j];
+			if (!strcmp(props_info->name, name))
+				return props_info->prop_id;
+		}
+	}
+
+	return 0;
+}
+
+static int allocate_fb(int fd, drmModeAtomicReqPtr req, struct resources *res,
+			uint32_t width,	uint32_t height, uint32_t pixel_format,
+			int pattern, struct bo **bo, uint32_t *fb_id)
+{
+	uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
+	int ret;
+
+	*bo = bo_create(fd, pixel_format, width, height,
+			handles, pitches, offsets, pattern);
+	if (*bo == NULL) {
+		fprintf(stderr, "failed to create bo (%ux%u): %s\n",
+				width, height, strerror(errno));
+		return -1;
+	}
+
+	ret = drmModeAddFB2(fd, width, height, pixel_format,
+			handles, pitches, offsets, fb_id, 0);
+	if (ret) {
+		fprintf(stderr, "failed to add fb (%ux%u): %s\n",
+				width, height, strerror(errno));
+		bo_destroy(*bo);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int allocate_fbs(struct device *dev, drmModeAtomicReqPtr req,
+			struct resources *res, struct property_arg *prop_args,
+			unsigned int prop_count, struct bo **bo, uint32_t *fb_id)
+{
+	uint32_t plane_id, fb_obj_id, pixel_format;
+	uint64_t width, height;
+	int ret = 0, i;
+
+	for (i = 0; i < (int)res->plane_res->count_planes; i++) {
+		plane_id = res->planes[i].plane->plane_id;
+		if (!is_obj_id_in_prop_args(prop_args, prop_count, plane_id))
+			continue;
+
+		fb_obj_id = get_plane_prop_id(res, plane_id, "FB_ID");
+		if (!fb_obj_id) {
+			fprintf(stderr, "plane(%u) does not exist\n", plane_id);
+			goto err;
+		}
+
+		ret = get_value_in_prop_args(prop_args, prop_count, plane_id,
+								"SRC_W", &width);
+		if (ret < 0) {
+			fprintf(stderr, "SRC_W for plane (%u) must be set\n", plane_id);
+			goto err;
+		}
+
+		ret = get_value_in_prop_args(prop_args, prop_count, plane_id,
+								"SRC_H", &height);
+		if (ret < 0) {
+			fprintf(stderr, "SRC_H for plane (%u) must be set\n", plane_id);
+			goto err;
+		}
+
+		pixel_format = DRM_FORMAT_XRGB8888;
+
+		ret = allocate_fb(dev->fd, req, res, width, height, pixel_format,
+						PATTERN_SMPTE, &bo[i], &fb_id[i]);
+		if (ret < 0)
+			goto err;
+
+		ret = drmModeAtomicAddProperty(req, plane_id, fb_obj_id, fb_id[i]);
+		if (ret < 0) {
+			fprintf(stderr, "failed to add atomic property for atomic modeset\n");
+			goto err;
+		}
+	}
+
+	return 0;
+
+err:
+	while (i > -1) {
+		if (!fb_id[i])
+			continue;
+
+		drmModeRmFB(dev->fd, fb_id[i]);
+		bo_destroy(bo[i]);
+		i--;
+	}
+
+	return ret;
+}
+
+static void deallocate_fbs(int fd, int num_planes, uint32_t *fb_id, struct bo **bo)
+{
+	int i;
+
+	for (i = 0; i < num_planes; i++) {
+		if (!fb_id[i])
+			continue;
+
+		drmModeRmFB(fd, fb_id[i]);
+		bo_destroy(bo[i]);
+	}
+}
+
+static int atomic_modeset(struct device *dev, drmModeAtomicReqPtr req,
+			struct property_arg *prop_args, unsigned int prop_count)
+{
+	unsigned int num_planes;
+	const char *obj_type = NULL;
+	uint32_t flags = 0;
+	uint32_t *fb_id;
+	struct bo **bo;
+	int ret, i;
+
+	for (i = 0; (unsigned int)i < prop_count; ++i) {
+		ret = get_prop_info(dev->resources, &prop_args[i], obj_type);
+		if (ret < 0)
+			return ret;
+
+		ret = drmModeAtomicAddProperty(req, prop_args[i].obj_id,
+				prop_args[i].prop_id, prop_args[i].value);
+		if (ret < 0) {
+			fprintf(stderr, "failed to add property for atomic modeset (%d)\n",
+					ret);
+			return ret;
+		}
+	}
+
+	num_planes = dev->resources->plane_res->count_planes;
+
+	bo = calloc(num_planes, sizeof(*bo));
+	if (!bo) {
+		fprintf(stderr, "failed to allocate memory fo bo array\n");
+		return -1;
+	}
+
+	fb_id = calloc(num_planes, sizeof(*fb_id));
+	if (!fb_id) {
+		fprintf(stderr, "failed to allocate memory fo fb_id array\n");
+		free(bo);
+		return -1;
+	}
+
+	ret = allocate_fbs(dev, req, dev->resources, prop_args, prop_count, bo, fb_id);
+	if (ret < 0) {
+		free(fb_id);
+		free(bo);
+		return ret;
+	}
+
+	ret = drmModeAtomicCommit(dev->fd, req, flags, NULL);
+	if (ret < 0) {
+		fprintf(stderr, "failed to commit for atomic modeset\n");
+		deallocate_fbs(dev->fd, num_planes, fb_id, bo);
+		free(fb_id);
+		free(bo);
+		return ret;
+	}
+
+	getchar();
+
+	deallocate_fbs(dev->fd, num_planes, fb_id, bo);
+	free(fb_id);
+	free(bo);
+
+	return 0;
+}
+
+static char optstr[] = "acdD:efM:P:ps:Cvw:";

 int main(int argc, char **argv)
 {
@@ -1574,6 +1798,8 @@ int main(int argc, char **argv)
 	struct pipe_arg *pipe_args = NULL;
 	struct plane_arg *plane_args = NULL;
 	struct property_arg *prop_args = NULL;
+	drmModeAtomicReqPtr req = NULL;
+	bool is_atomic = false;
 	unsigned int args = 0;
 	int ret;

@@ -1584,6 +1810,10 @@ int main(int argc, char **argv)
 		args++;

 		switch (c) {
+		case 'a':
+			is_atomic = true;
+			args--;
+			break;
 		case 'c':
 			connectors = 1;
 			break;
@@ -1705,6 +1935,22 @@ int main(int argc, char **argv)
 		return -1;
 	}

+	if (is_atomic) {
+		req = drmModeAtomicAlloc();
+		if (req == NULL) {
+			fprintf(stderr, "failed to allocate drmModeAtomicReqPtr\n");
+			return 1;
+		}
+
+		ret = drmSetClientCap(dev.fd, DRM_CLIENT_CAP_ATOMIC, 1);
+		if (ret) {
+			fprintf(stderr, "Kernel DRM driver is not capable of atomic modeset\n");
+			drmModeAtomicFree(req);
+
+			return 1;
+		}
+	}
+
 	dev.resources = get_resources(&dev);
 	if (!dev.resources) {
 		drmClose(dev.fd);
@@ -1727,6 +1973,17 @@ int main(int argc, char **argv)
 	dump_resource(&dev, planes);
 	dump_resource(&dev, framebuffers);

+	if (is_atomic) {
+		ret = atomic_modeset(&dev, req, prop_args, prop_count);
+		if (ret < 0)
+			fprintf(stderr, "failed to atomic modeset (%s)\n",
+					strerror(errno));
+
+		free_resources(dev.resources);
+		drmModeAtomicFree(req);
+		return ret;
+	}
+
 	for (i = 0; i < prop_count; ++i)
 		set_property(&dev, &prop_args[i]);

--
2.4.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 3/3] modetest: add atomic page flip support
  2015-09-23  2:45 [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type Hyungwon Hwang
  2015-09-23  2:45 ` [PATCH v3 2/3] modetest: add atomic modeset support Hyungwon Hwang
@ 2015-09-23  2:45 ` Hyungwon Hwang
  2015-11-26 23:57   ` Emil Velikov
  2015-11-26 16:42 ` [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type Emil Velikov
  2 siblings, 1 reply; 8+ messages in thread
From: Hyungwon Hwang @ 2015-09-23  2:45 UTC (permalink / raw)
  To: dri-devel, ppaalanen, emil.l.velikov

This patch adds support for atomic page flip. User can specify -V option
with the plane id for testing atomic page flipping.

Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
---
 tests/modetest/modetest.c | 195 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 187 insertions(+), 8 deletions(-)

diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index bc5a227..418acaa 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -747,6 +747,10 @@ struct pipe_arg {
 	struct timeval start;
 
 	int swap_count;
+
+	/* for atomic modeset */
+	uint32_t plane_id;
+	uint32_t fb_obj_id;
 };
 
 struct plane_arg {
@@ -1477,7 +1481,7 @@ static int parse_property(struct property_arg *p, const char *arg)
 
 static void usage(char *name)
 {
-	fprintf(stderr, "usage: %s [-acDdefMPpsCvw]\n", name);
+	fprintf(stderr, "usage: %s [-acDdefMPpsCvVw]\n", name);
 	fprintf(stderr, "\tA: supported in atomic modeset\n");
 	fprintf(stderr, "\tL: supported in legacy modeset\n");
 
@@ -1492,6 +1496,7 @@ static void usage(char *name)
 
 	fprintf(stderr, "\n Atomic Test options: [A]\n\n");
 	fprintf(stderr, "\t-a\tuse atomic modeset\n");
+	fprintf(stderr, "\t-V <flipping_plane_id>\ttest vsynced page flipping\n");
 
 	fprintf(stderr, "\n Legacy test options: [L]\n\n");
 	fprintf(stderr, "\t-P <crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane\n");
@@ -1641,7 +1646,8 @@ static int allocate_fb(int fd, drmModeAtomicReqPtr req, struct resources *res,
 
 static int allocate_fbs(struct device *dev, drmModeAtomicReqPtr req,
 			struct resources *res, struct property_arg *prop_args,
-			unsigned int prop_count, struct bo **bo, uint32_t *fb_id)
+			unsigned int prop_count, struct bo **bo, uint32_t *fb_id,
+			uint32_t flip_plane_id)
 {
 	uint32_t plane_id, fb_obj_id, pixel_format;
 	uint64_t width, height;
@@ -1652,6 +1658,9 @@ static int allocate_fbs(struct device *dev, drmModeAtomicReqPtr req,
 		if (!is_obj_id_in_prop_args(prop_args, prop_count, plane_id))
 			continue;
 
+		if (flip_plane_id == plane_id)
+			dev->mode.fb_id = fb_id[i];
+
 		fb_obj_id = get_plane_prop_id(res, plane_id, "FB_ID");
 		if (!fb_obj_id) {
 			fprintf(stderr, "plane(%u) does not exist\n", plane_id);
@@ -1714,8 +1723,162 @@ static void deallocate_fbs(int fd, int num_planes, uint32_t *fb_id, struct bo **
 	}
 }
 
+static void atomic_page_flip_handler(int fd, unsigned int frame, unsigned int sec,
+					unsigned int usec, void *data)
+{
+	static drmModeAtomicReqPtr req = NULL;
+	unsigned int new_fb_id;
+	struct timeval end;
+	struct pipe_arg *pipe;
+	double t;
+	uint32_t flags = 0;
+	int ret;
+
+	pipe = (struct pipe_arg *)(unsigned long)data;
+
+	req = drmModeAtomicAlloc();
+	if (!req) {
+		fprintf(stderr, "failed to allocate drmModeAtomicReqPtr\n");
+		return;
+	}
+
+	if (pipe->current_fb_id == pipe->fb_id[0])
+		new_fb_id = pipe->fb_id[1];
+	else
+		new_fb_id = pipe->fb_id[0];
+
+	pipe->current_fb_id = new_fb_id;
+	pipe->swap_count++;
+
+	ret = drmModeAtomicAddProperty(req, pipe->plane_id, pipe->fb_obj_id, new_fb_id);
+	if (ret < 0) {
+		fprintf(stderr, "failed to add atomic property in pageflip handler\n");
+		drmModeAtomicFree(req);
+		return;
+	}
+
+	flags = DRM_MODE_PAGE_FLIP_EVENT;
+	ret = drmModeAtomicCommit(fd, req, flags, pipe);
+	if (ret < 0) {
+		fprintf(stderr, "failed to commit in pageflip handler\n");
+		drmModeAtomicFree(req);
+		return;
+	}
+
+	if (pipe->swap_count == 60) {
+		gettimeofday(&end, NULL);
+		t = end.tv_sec + end.tv_usec * 1e-6 -
+			(pipe->start.tv_sec + pipe->start.tv_usec * 1e-6);
+		fprintf(stderr, "freq: %.02fHz\n", pipe->swap_count / t);
+		pipe->swap_count = 0;
+		pipe->start = end;
+	}
+
+	drmModeAtomicFree(req);
+}
+
+static void atomic_test_page_flip(struct device *dev, drmModeAtomicReqPtr req,
+			struct resources *res, struct property_arg *prop_args,
+			unsigned int prop_count, unsigned int flip_plane_id)
+{
+	struct bo *other_bo;
+	unsigned int other_fb_id;
+	struct pipe_arg pipe;
+	drmEventContext evctx;
+	uint32_t flags = 0, fb_obj_id = 0, pixel_format;
+	uint64_t width, height;
+	int ret;
+
+	fb_obj_id = get_plane_prop_id(res, flip_plane_id, "FB_ID");
+	if (!fb_obj_id) {
+		fprintf(stderr, "plane(%u) does not exist\n", flip_plane_id);
+		return;
+	}
+
+	if (!is_obj_id_in_prop_args(prop_args, prop_count, flip_plane_id)) {
+		fprintf(stderr, "plane (%u) must be set for pageflip\n", flip_plane_id);
+		return;
+	}
+
+	ret = get_value_in_prop_args(prop_args, prop_count, flip_plane_id,
+					"SRC_W", &width);
+	if (ret < 0) {
+		fprintf(stderr, "SRC_W for plane (%u) must be set\n", flip_plane_id);
+		return;
+	}
+
+	ret = get_value_in_prop_args(prop_args, prop_count, flip_plane_id,
+					"SRC_H", &height);
+	if (ret < 0) {
+		fprintf(stderr, "SRC_H for plane (%u) must be set\n", flip_plane_id);
+		return;
+	}
+
+	pixel_format = DRM_FORMAT_XRGB8888;
+
+	ret = allocate_fb(dev->fd, req, res, width, height, pixel_format,
+			PATTERN_TILES, &other_bo, &other_fb_id);
+	if (ret < 0)
+		return;
+
+	ret = drmModeAtomicAddProperty(req, flip_plane_id, fb_obj_id,
+			other_fb_id);
+	if (ret < 0) {
+		fprintf(stderr, "failed to add atomic property for pageflip");
+		goto err;
+	}
+
+	gettimeofday(&pipe.start, NULL);
+	pipe.swap_count = 0;
+	pipe.plane_id = flip_plane_id;
+	pipe.fb_obj_id = fb_obj_id;
+	pipe.fb_id[0] = dev->mode.fb_id;
+	pipe.fb_id[1] = other_fb_id;
+	pipe.current_fb_id = other_fb_id;
+
+	flags = DRM_MODE_PAGE_FLIP_EVENT;
+
+	ret = drmModeAtomicCommit(dev->fd, req, flags, &pipe);
+	if (ret < 0) {
+		fprintf(stderr, "failed to commit for pageflip\n");
+		goto err;
+	}
+
+	memset(&evctx, 0, sizeof evctx);
+	evctx.version = 2;
+	evctx.vblank_handler = NULL;
+	evctx.page_flip_handler = atomic_page_flip_handler;
+
+	while (1) {
+		struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
+		fd_set fds;
+
+		FD_ZERO(&fds);
+		FD_SET(0, &fds);
+		FD_SET(dev->fd, &fds);
+		ret = select(dev->fd + 1, &fds, NULL, NULL, &timeout);
+
+		if (ret <= 0) {
+			fprintf(stderr, "select timed out or error (ret %d)\n",
+					ret);
+			continue;
+		} else if (FD_ISSET(0, &fds)) {
+			break;
+		}
+
+		drmHandleEvent(dev->fd, &evctx);
+	}
+
+err:
+	drmModeRmFB(dev->fd, other_fb_id);
+	bo_destroy(other_bo);
+
+	return;
+}
+
 static int atomic_modeset(struct device *dev, drmModeAtomicReqPtr req,
-			struct property_arg *prop_args, unsigned int prop_count)
+			struct property_arg *prop_args, unsigned int prop_count,
+			int test_vsync, int flip_plane_id)
 {
 	unsigned int num_planes;
 	const char *obj_type = NULL;
@@ -1753,7 +1916,8 @@ static int atomic_modeset(struct device *dev, drmModeAtomicReqPtr req,
 		return -1;
 	}
 
-	ret = allocate_fbs(dev, req, dev->resources, prop_args, prop_count, bo, fb_id);
+	ret = allocate_fbs(dev, req, dev->resources, prop_args, prop_count, bo,
+				fb_id, flip_plane_id);
 	if (ret < 0) {
 		free(fb_id);
 		free(bo);
@@ -1769,6 +1933,10 @@ static int atomic_modeset(struct device *dev, drmModeAtomicReqPtr req,
 		return ret;
 	}
 
+	if (test_vsync)
+		atomic_test_page_flip(dev, req, dev->resources,
+				prop_args, prop_count, flip_plane_id);
+
 	getchar();
 
 	deallocate_fbs(dev->fd, num_planes, fb_id, bo);
@@ -1778,7 +1946,7 @@ static int atomic_modeset(struct device *dev, drmModeAtomicReqPtr req,
 	return 0;
 }
 
-static char optstr[] = "acdD:efM:P:ps:Cvw:";
+static char optstr[] = "acdD:efM:P:ps:CvV:w:";
 
 int main(int argc, char **argv)
 {
@@ -1792,7 +1960,7 @@ int main(int argc, char **argv)
 	const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "tilcdc", "msm", "sti", "tegra", "imx-drm", "rockchip", "atmel-hlcdc" };
 	char *device = NULL;
 	char *module = NULL;
-	unsigned int i;
+	unsigned int i, flip_plane_id = 0;
 	unsigned int count = 0, plane_count = 0;
 	unsigned int prop_count = 0;
 	struct pipe_arg *pipe_args = NULL;
@@ -1873,6 +2041,11 @@ int main(int argc, char **argv)
 		case 'v':
 			test_vsync = 1;
 			break;
+		case 'V':
+			if (sscanf(optarg, "%u", &flip_plane_id) != 1)
+				usage(argv[0]);
+			test_vsync = 1;
+			break;
 		case 'w':
 			prop_args = realloc(prop_args,
 					   (prop_count + 1) * sizeof *prop_args);
@@ -1925,11 +2098,16 @@ int main(int argc, char **argv)
 		return -1;
 	}
 
-	if (test_vsync && !count) {
+	if (test_vsync && (!count && !is_atomic)) {
 		fprintf(stderr, "page flipping requires at least one -s option.\n");
 		return -1;
 	}
 
+	if (test_vsync && is_atomic && flip_plane_id == 0) {
+		fprintf(stderr, "fliping plane id must be set for atomic pageflip\n");
+		return -1;
+	}
+
 	if (test_cursor && !cursor_supported()) {
 		fprintf(stderr, "hw cursor not supported by drm.\n");
 		return -1;
@@ -1974,7 +2152,8 @@ int main(int argc, char **argv)
 	dump_resource(&dev, framebuffers);
 
 	if (is_atomic) {
-		ret = atomic_modeset(&dev, req, prop_args, prop_count);
+		ret = atomic_modeset(&dev, req, prop_args, prop_count,
+					test_vsync, flip_plane_id);
 		if (ret < 0)
 			fprintf(stderr, "failed to atomic modeset (%s)\n",
 					strerror(errno));
-- 
2.4.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type
  2015-09-23  2:45 [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type Hyungwon Hwang
  2015-09-23  2:45 ` [PATCH v3 2/3] modetest: add atomic modeset support Hyungwon Hwang
  2015-09-23  2:45 ` [PATCH v3 3/3] modetest: add atomic page flip support Hyungwon Hwang
@ 2015-11-26 16:42 ` Emil Velikov
  2015-11-27  2:37   ` Hyungwon Hwang
  2 siblings, 1 reply; 8+ messages in thread
From: Emil Velikov @ 2015-11-26 16:42 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: ML dri-devel

Hi Hyungwon

I completely missed out that you've sent an updated version of the
series. I will take a look at them later on tonight. Meanwhile have
you looked at the atomic tests/helpers work from Thierry [1] ? It
creates nice simple helpers (as opposed to a single massive C file
like modetest) and I'm leaning that there is quite a lot of code that
can be reused from there.

Speaking of which Thierry,
What is happening with these patches ? Last time you've respun them
I've pinged you to send them over for inclusion. There was a trivial
fix needed here or there but they were in pretty good shape.

Thanks
Emil

[1] http://cgit.freedesktop.org/~tagr/drm/
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 2/3] modetest: add atomic modeset support
  2015-09-23  2:45 ` [PATCH v3 2/3] modetest: add atomic modeset support Hyungwon Hwang
@ 2015-11-26 23:42   ` Emil Velikov
  0 siblings, 0 replies; 8+ messages in thread
From: Emil Velikov @ 2015-11-26 23:42 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: ML dri-devel

On 23 September 2015 at 03:45, Hyungwon Hwang <human.hwang@samsung.com> wrote:
> This patch adds support for atomic modeset. Using -a option, user can
> make modeset to use DRM_IOCTL_MODE_ATOMIC instead of legacy IOCTLs.
> Also, by using -w option, user can set the property as before.
>
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> ---
>  tests/modetest/modetest.c | 273 ++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 265 insertions(+), 8 deletions(-)
>
> diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
> index 08ecf58..bc5a227 100644
> --- a/tests/modetest/modetest.c
> +++ b/tests/modetest/modetest.c
> @@ -1477,25 +1477,32 @@ static int parse_property(struct property_arg *p, const char *arg)
>
>  static void usage(char *name)
>  {
> -       fprintf(stderr, "usage: %s [-cDdefMPpsCvw]\n", name);
> +       fprintf(stderr, "usage: %s [-acDdefMPpsCvw]\n", name);
> +       fprintf(stderr, "\tA: supported in atomic modeset\n");
> +       fprintf(stderr, "\tL: supported in legacy modeset\n");
>
> -       fprintf(stderr, "\n Query options:\n\n");
> +       fprintf(stderr, "\n Query options: [AL]\n\n");
>         fprintf(stderr, "\t-c\tlist connectors\n");
>         fprintf(stderr, "\t-e\tlist encoders\n");
>         fprintf(stderr, "\t-f\tlist framebuffers\n");
>         fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n");
>
> -       fprintf(stderr, "\n Test options:\n\n");
> +       fprintf(stderr, "\n Common Test options: [AL]\n\n");
> +       fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");
> +
> +       fprintf(stderr, "\n Atomic Test options: [A]\n\n");
> +       fprintf(stderr, "\t-a\tuse atomic modeset\n");
> +
> +       fprintf(stderr, "\n Legacy test options: [L]\n\n");
>         fprintf(stderr, "\t-P <crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane\n");
>         fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[-<vrefresh>][@<format>]\tset a mode\n");
>         fprintf(stderr, "\t-C\ttest hw cursor\n");
>         fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
> -       fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");
>
>         fprintf(stderr, "\n Generic options:\n\n");
> -       fprintf(stderr, "\t-d\tdrop master after mode set\n");
> -       fprintf(stderr, "\t-M module\tuse the given driver\n");
> -       fprintf(stderr, "\t-D device\tuse the given device\n");
> +       fprintf(stderr, "\t-d\tdrop master after mode set [L]\n");
> +       fprintf(stderr, "\t-M module\tuse the given driver [AL]\n");
> +       fprintf(stderr, "\t-D device\tuse the given device [AL]\n");
>
>         fprintf(stderr, "\n\tDefault is to dump all info.\n");
>         exit(0);
> @@ -1554,7 +1561,224 @@ static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe)
>         return 0;
>  }
>
> -static char optstr[] = "cdD:efM:P:ps:Cvw:";
> +static bool is_obj_id_in_prop_args(struct property_arg *prop_args,
const struct

> +                               unsigned int prop_count, uint32_t obj_id)
> +{
> +       unsigned int i;
> +
> +       for (i = 0; i < prop_count; i++)
> +               if (obj_id == prop_args[i].obj_id)
> +                       return true;
> +
> +       return false;
> +}
> +
> +static int get_value_in_prop_args(struct property_arg *prop_args,
Ditto

> +                       unsigned int prop_count, uint32_t obj_id,
> +                       const char *name, uint64_t *out)
> +{
> +       unsigned int i;
> +
> +       for (i = 0; i < prop_count; i++) {
> +               if (prop_args[i].obj_id == obj_id &&
> +                   !strcmp(prop_args[i].name, name)) {
> +                       *out = prop_args[i].value;
> +                       return 0;
> +               }
> +       }
> +
> +       return -1;
> +}
> +
> +static uint32_t get_plane_prop_id(struct resources *res, uint32_t obj_id,
Ditto

> +                                                       const char *name)
> +{
> +       drmModePropertyRes *props_info;
> +       struct plane *plane;
> +       unsigned int i, j;
> +
> +       for (i = 0; i < res->plane_res->count_planes; i++) {
> +               plane = &res->planes[i];
> +               if (plane->plane->plane_id != obj_id)
> +                       continue;
> +
> +               for (j = 0; j < plane->props->count_props; j++) {
> +                       props_info = plane->props_info[j];
> +                       if (!strcmp(props_info->name, name))
> +                               return props_info->prop_id;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static int allocate_fb(int fd, drmModeAtomicReqPtr req, struct resources *res,
req and res are unused.

> +                       uint32_t width, uint32_t height, uint32_t pixel_format,
> +                       int pattern, struct bo **bo, uint32_t *fb_id)
> +{
> +       uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
> +       int ret;
> +
> +       *bo = bo_create(fd, pixel_format, width, height,
> +                       handles, pitches, offsets, pattern);
> +       if (*bo == NULL) {
> +               fprintf(stderr, "failed to create bo (%ux%u): %s\n",
> +                               width, height, strerror(errno));
> +               return -1;
> +       }
> +
> +       ret = drmModeAddFB2(fd, width, height, pixel_format,
> +                       handles, pitches, offsets, fb_id, 0);
> +       if (ret) {
> +               fprintf(stderr, "failed to add fb (%ux%u): %s\n",
> +                               width, height, strerror(errno));
> +               bo_destroy(*bo);
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static int allocate_fbs(struct device *dev, drmModeAtomicReqPtr req,
> +                       struct resources *res, struct property_arg *prop_args,
Constify res and prop_args ?

> +                       unsigned int prop_count, struct bo **bo, uint32_t *fb_id)
> +{
> +       uint32_t plane_id, fb_obj_id, pixel_format;
> +       uint64_t width, height;
> +       int ret = 0, i;
> +
> +       for (i = 0; i < (int)res->plane_res->count_planes; i++) {
Define i as unsigned, drop the cast and ...

> +               plane_id = res->planes[i].plane->plane_id;
> +               if (!is_obj_id_in_prop_args(prop_args, prop_count, plane_id))
> +                       continue;
> +
> +               fb_obj_id = get_plane_prop_id(res, plane_id, "FB_ID");
> +               if (!fb_obj_id) {
> +                       fprintf(stderr, "plane(%u) does not exist\n", plane_id);
> +                       goto err;
> +               }
> +
> +               ret = get_value_in_prop_args(prop_args, prop_count, plane_id,
> +                                                               "SRC_W", &width);
> +               if (ret < 0) {
> +                       fprintf(stderr, "SRC_W for plane (%u) must be set\n", plane_id);
> +                       goto err;
> +               }
> +
> +               ret = get_value_in_prop_args(prop_args, prop_count, plane_id,
> +                                                               "SRC_H", &height);
> +               if (ret < 0) {
> +                       fprintf(stderr, "SRC_H for plane (%u) must be set\n", plane_id);
> +                       goto err;
> +               }
> +
> +               pixel_format = DRM_FORMAT_XRGB8888;
> +
> +               ret = allocate_fb(dev->fd, req, res, width, height, pixel_format,
> +                                               PATTERN_SMPTE, &bo[i], &fb_id[i]);
> +               if (ret < 0)
> +                       goto err;
> +
> +               ret = drmModeAtomicAddProperty(req, plane_id, fb_obj_id, fb_id[i]);
> +               if (ret < 0) {
> +                       fprintf(stderr, "failed to add atomic property for atomic modeset\n");
> +                       goto err;
> +               }
> +       }
> +
> +       return 0;
> +
> +err:
> +       while (i > -1) {
... then use
       while (i--) {

> +               if (!fb_id[i])
> +                       continue;
> +
> +               drmModeRmFB(dev->fd, fb_id[i]);
> +               bo_destroy(bo[i]);
> +               i--;
and drop this line.

> +       }
> +
> +       return ret;
> +}
> +
> +static void deallocate_fbs(int fd, int num_planes, uint32_t *fb_id, struct bo **bo)
> +{
> +       int i;
> +
Make both i and num_planes unsigned ?

> +       for (i = 0; i < num_planes; i++) {
> +               if (!fb_id[i])
> +                       continue;
> +
> +               drmModeRmFB(fd, fb_id[i]);
> +               bo_destroy(bo[i]);
Shove the contents of the loop into deallocate_fb() to complement
allocate_fb() and use it here + allocate_fbs() error path ?

> +       }
> +}
> +
> +static int atomic_modeset(struct device *dev, drmModeAtomicReqPtr req,
> +                       struct property_arg *prop_args, unsigned int prop_count)
> +{
> +       unsigned int num_planes;
> +       const char *obj_type = NULL;
You don't need this.

> +       uint32_t flags = 0;
And you can use 0 directly where needed.

> +       uint32_t *fb_id;
> +       struct bo **bo;
> +       int ret, i;
> +
> +       for (i = 0; (unsigned int)i < prop_count; ++i) {
Why is i signed int ?

> +               ret = get_prop_info(dev->resources, &prop_args[i], obj_type);
> +               if (ret < 0)
> +                       return ret;
> +
> +               ret = drmModeAtomicAddProperty(req, prop_args[i].obj_id,
> +                               prop_args[i].prop_id, prop_args[i].value);
> +               if (ret < 0) {
Perhaps we should unwind all the state that we've accumulated (same
goes for the remaining error paths in this func), although I might be
pushing my luck with your patience.

> +                       fprintf(stderr, "failed to add property for atomic modeset (%d)\n",
> +                                       ret);
> +                       return ret;
> +               }
> +       }
> +
> +       num_planes = dev->resources->plane_res->count_planes;
> +
> +       bo = calloc(num_planes, sizeof(*bo));
> +       if (!bo) {
> +               fprintf(stderr, "failed to allocate memory fo bo array\n");
> +               return -1;
> +       }
> +
> +       fb_id = calloc(num_planes, sizeof(*fb_id));
> +       if (!fb_id) {
> +               fprintf(stderr, "failed to allocate memory fo fb_id array\n");
> +               free(bo);
> +               return -1;
> +       }
> +
> +       ret = allocate_fbs(dev, req, dev->resources, prop_args, prop_count, bo, fb_id);
> +       if (ret < 0) {
> +               free(fb_id);
> +               free(bo);
> +               return ret;
> +       }
> +
> +       ret = drmModeAtomicCommit(dev->fd, req, flags, NULL);
> +       if (ret < 0) {
> +               fprintf(stderr, "failed to commit for atomic modeset\n");
Use labels rather than the ever increasing teardown ?

> +               deallocate_fbs(dev->fd, num_planes, fb_id, bo);
> +               free(fb_id);
> +               free(bo);
> +               return ret;
> +       }
> +
> +       getchar();
> +
> +       deallocate_fbs(dev->fd, num_planes, fb_id, bo);
> +       free(fb_id);
> +       free(bo);
> +
> +       return 0;
> +}
> +
> +static char optstr[] = "acdD:efM:P:ps:Cvw:";
>
>  int main(int argc, char **argv)
>  {
> @@ -1574,6 +1798,8 @@ int main(int argc, char **argv)
>         struct pipe_arg *pipe_args = NULL;
>         struct plane_arg *plane_args = NULL;
>         struct property_arg *prop_args = NULL;
> +       drmModeAtomicReqPtr req = NULL;
Initialisation isn't needed.

-Emil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 3/3] modetest: add atomic page flip support
  2015-09-23  2:45 ` [PATCH v3 3/3] modetest: add atomic page flip support Hyungwon Hwang
@ 2015-11-26 23:57   ` Emil Velikov
  0 siblings, 0 replies; 8+ messages in thread
From: Emil Velikov @ 2015-11-26 23:57 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: ML dri-devel

On 23 September 2015 at 03:45, Hyungwon Hwang <human.hwang@samsung.com> wrote:
> This patch adds support for atomic page flip. User can specify -V option
> with the plane id for testing atomic page flipping.
>
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> ---
>  tests/modetest/modetest.c | 195 ++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 187 insertions(+), 8 deletions(-)
>
> diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
> index bc5a227..418acaa 100644
> --- a/tests/modetest/modetest.c
> +++ b/tests/modetest/modetest.c
> @@ -747,6 +747,10 @@ struct pipe_arg {
>         struct timeval start;
>
>         int swap_count;
> +
> +       /* for atomic modeset */
> +       uint32_t plane_id;
> +       uint32_t fb_obj_id;
>  };
>
>  struct plane_arg {
> @@ -1477,7 +1481,7 @@ static int parse_property(struct property_arg *p, const char *arg)
>
>  static void usage(char *name)
>  {
> -       fprintf(stderr, "usage: %s [-acDdefMPpsCvw]\n", name);
> +       fprintf(stderr, "usage: %s [-acDdefMPpsCvVw]\n", name);
>         fprintf(stderr, "\tA: supported in atomic modeset\n");
>         fprintf(stderr, "\tL: supported in legacy modeset\n");
>
> @@ -1492,6 +1496,7 @@ static void usage(char *name)
>
>         fprintf(stderr, "\n Atomic Test options: [A]\n\n");
>         fprintf(stderr, "\t-a\tuse atomic modeset\n");
> +       fprintf(stderr, "\t-V <flipping_plane_id>\ttest vsynced page flipping\n");
>
>         fprintf(stderr, "\n Legacy test options: [L]\n\n");
>         fprintf(stderr, "\t-P <crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane\n");
> @@ -1641,7 +1646,8 @@ static int allocate_fb(int fd, drmModeAtomicReqPtr req, struct resources *res,
>
>  static int allocate_fbs(struct device *dev, drmModeAtomicReqPtr req,
>                         struct resources *res, struct property_arg *prop_args,
> -                       unsigned int prop_count, struct bo **bo, uint32_t *fb_id)
> +                       unsigned int prop_count, struct bo **bo, uint32_t *fb_id,
> +                       uint32_t flip_plane_id)
>  {
>         uint32_t plane_id, fb_obj_id, pixel_format;
>         uint64_t width, height;
> @@ -1652,6 +1658,9 @@ static int allocate_fbs(struct device *dev, drmModeAtomicReqPtr req,
>                 if (!is_obj_id_in_prop_args(prop_args, prop_count, plane_id))
>                         continue;
>
> +               if (flip_plane_id == plane_id)
> +                       dev->mode.fb_id = fb_id[i];
> +
>                 fb_obj_id = get_plane_prop_id(res, plane_id, "FB_ID");
>                 if (!fb_obj_id) {
>                         fprintf(stderr, "plane(%u) does not exist\n", plane_id);
> @@ -1714,8 +1723,162 @@ static void deallocate_fbs(int fd, int num_planes, uint32_t *fb_id, struct bo **
>         }
>  }
>
> +static void atomic_page_flip_handler(int fd, unsigned int frame, unsigned int sec,
> +                                       unsigned int usec, void *data)
> +{
> +       static drmModeAtomicReqPtr req = NULL;
Initialisation not needed

> +       unsigned int new_fb_id;
> +       struct timeval end;
> +       struct pipe_arg *pipe;
> +       double t;
> +       uint32_t flags = 0;
Feed 0 directly into the function ?

> +       int ret;
> +
> +       pipe = (struct pipe_arg *)(unsigned long)data;
> +
> +       req = drmModeAtomicAlloc();
> +       if (!req) {
> +               fprintf(stderr, "failed to allocate drmModeAtomicReqPtr\n");
> +               return;
> +       }
> +
> +       if (pipe->current_fb_id == pipe->fb_id[0])
> +               new_fb_id = pipe->fb_id[1];
> +       else
> +               new_fb_id = pipe->fb_id[0];
> +
> +       pipe->current_fb_id = new_fb_id;
> +       pipe->swap_count++;
> +
> +       ret = drmModeAtomicAddProperty(req, pipe->plane_id, pipe->fb_obj_id, new_fb_id);
> +       if (ret < 0) {
> +               fprintf(stderr, "failed to add atomic property in pageflip handler\n");
Use a goto label ?
> +               drmModeAtomicFree(req);
> +               return;
> +       }
> +
> +       flags = DRM_MODE_PAGE_FLIP_EVENT;
> +       ret = drmModeAtomicCommit(fd, req, flags, pipe);
> +       if (ret < 0) {
> +               fprintf(stderr, "failed to commit in pageflip handler\n");
> +               drmModeAtomicFree(req);
> +               return;
> +       }
> +
> +       if (pipe->swap_count == 60) {
Use vrefresh here ?

> +               gettimeofday(&end, NULL);
> +               t = end.tv_sec + end.tv_usec * 1e-6 -
> +                       (pipe->start.tv_sec + pipe->start.tv_usec * 1e-6);
> +               fprintf(stderr, "freq: %.02fHz\n", pipe->swap_count / t);
> +               pipe->swap_count = 0;
> +               pipe->start = end;
> +       }
> +
> +       drmModeAtomicFree(req);
> +}
> +
> +static void atomic_test_page_flip(struct device *dev, drmModeAtomicReqPtr req,
> +                       struct resources *res, struct property_arg *prop_args,
constify the structs ?

> +                       unsigned int prop_count, unsigned int flip_plane_id)
> +{
> +       struct bo *other_bo;
> +       unsigned int other_fb_id;
> +       struct pipe_arg pipe;
> +       drmEventContext evctx;
> +       uint32_t flags = 0, fb_obj_id = 0, pixel_format;
Variable and initialisation isn't needed.

> +       uint64_t width, height;
> +       int ret;
> +
> +       fb_obj_id = get_plane_prop_id(res, flip_plane_id, "FB_ID");
> +       if (!fb_obj_id) {
> +               fprintf(stderr, "plane(%u) does not exist\n", flip_plane_id);
> +               return;
> +       }
> +
> +       if (!is_obj_id_in_prop_args(prop_args, prop_count, flip_plane_id)) {
> +               fprintf(stderr, "plane (%u) must be set for pageflip\n", flip_plane_id);
> +               return;
> +       }
> +
> +       ret = get_value_in_prop_args(prop_args, prop_count, flip_plane_id,
> +                                       "SRC_W", &width);
> +       if (ret < 0) {
> +               fprintf(stderr, "SRC_W for plane (%u) must be set\n", flip_plane_id);
> +               return;
> +       }
> +
> +       ret = get_value_in_prop_args(prop_args, prop_count, flip_plane_id,
> +                                       "SRC_H", &height);
> +       if (ret < 0) {
> +               fprintf(stderr, "SRC_H for plane (%u) must be set\n", flip_plane_id);
> +               return;
> +       }
> +
> +       pixel_format = DRM_FORMAT_XRGB8888;
> +
> +       ret = allocate_fb(dev->fd, req, res, width, height, pixel_format,
> +                       PATTERN_TILES, &other_bo, &other_fb_id);
> +       if (ret < 0)
> +               return;
> +
> +       ret = drmModeAtomicAddProperty(req, flip_plane_id, fb_obj_id,
> +                       other_fb_id);
> +       if (ret < 0) {
> +               fprintf(stderr, "failed to add atomic property for pageflip");
> +               goto err;
> +       }
> +
> +       gettimeofday(&pipe.start, NULL);
> +       pipe.swap_count = 0;
> +       pipe.plane_id = flip_plane_id;
> +       pipe.fb_obj_id = fb_obj_id;
> +       pipe.fb_id[0] = dev->mode.fb_id;
> +       pipe.fb_id[1] = other_fb_id;
> +       pipe.current_fb_id = other_fb_id;
> +
> +       flags = DRM_MODE_PAGE_FLIP_EVENT;
> +
> +       ret = drmModeAtomicCommit(dev->fd, req, flags, &pipe);
> +       if (ret < 0) {
> +               fprintf(stderr, "failed to commit for pageflip\n");
> +               goto err;
> +       }
> +
> +       memset(&evctx, 0, sizeof evctx);
> +       evctx.version = 2;
> +       evctx.vblank_handler = NULL;
> +       evctx.page_flip_handler = atomic_page_flip_handler;
> +
> +       while (1) {
> +               struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
> +               fd_set fds;
> +
> +               FD_ZERO(&fds);
> +               FD_SET(0, &fds);
> +               FD_SET(dev->fd, &fds);
> +               ret = select(dev->fd + 1, &fds, NULL, NULL, &timeout);
> +
> +               if (ret <= 0) {
> +                       fprintf(stderr, "select timed out or error (ret %d)\n",
> +                                       ret);
> +                       continue;
> +               } else if (FD_ISSET(0, &fds)) {
> +                       break;
> +               }
> +
> +               drmHandleEvent(dev->fd, &evctx);
> +       }
> +
> +err:
> +       drmModeRmFB(dev->fd, other_fb_id);
> +       bo_destroy(other_bo);
> +
> +       return;
> +}
> +
>  static int atomic_modeset(struct device *dev, drmModeAtomicReqPtr req,
> -                       struct property_arg *prop_args, unsigned int prop_count)
> +                       struct property_arg *prop_args, unsigned int prop_count,
> +                       int test_vsync, int flip_plane_id)
>  {
>         unsigned int num_planes;
>         const char *obj_type = NULL;
> @@ -1753,7 +1916,8 @@ static int atomic_modeset(struct device *dev, drmModeAtomicReqPtr req,
>                 return -1;
>         }
>
> -       ret = allocate_fbs(dev, req, dev->resources, prop_args, prop_count, bo, fb_id);
> +       ret = allocate_fbs(dev, req, dev->resources, prop_args, prop_count, bo,
> +                               fb_id, flip_plane_id);
>         if (ret < 0) {
>                 free(fb_id);
>                 free(bo);
> @@ -1769,6 +1933,10 @@ static int atomic_modeset(struct device *dev, drmModeAtomicReqPtr req,
>                 return ret;
>         }
>
> +       if (test_vsync)
> +               atomic_test_page_flip(dev, req, dev->resources,
> +                               prop_args, prop_count, flip_plane_id);
> +
>         getchar();
>
>         deallocate_fbs(dev->fd, num_planes, fb_id, bo);
> @@ -1778,7 +1946,7 @@ static int atomic_modeset(struct device *dev, drmModeAtomicReqPtr req,
>         return 0;
>  }
>
> -static char optstr[] = "acdD:efM:P:ps:Cvw:";
> +static char optstr[] = "acdD:efM:P:ps:CvV:w:";
>
>  int main(int argc, char **argv)
>  {
> @@ -1792,7 +1960,7 @@ int main(int argc, char **argv)
>         const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "tilcdc", "msm", "sti", "tegra", "imx-drm", "rockchip", "atmel-hlcdc" };
>         char *device = NULL;
>         char *module = NULL;
> -       unsigned int i;
> +       unsigned int i, flip_plane_id = 0;
>         unsigned int count = 0, plane_count = 0;
>         unsigned int prop_count = 0;
>         struct pipe_arg *pipe_args = NULL;
> @@ -1873,6 +2041,11 @@ int main(int argc, char **argv)
>                 case 'v':
>                         test_vsync = 1;
>                         break;
> +               case 'V':
> +                       if (sscanf(optarg, "%u", &flip_plane_id) != 1)
> +                               usage(argv[0]);
> +                       test_vsync = 1;
> +                       break;
>                 case 'w':
>                         prop_args = realloc(prop_args,
>                                            (prop_count + 1) * sizeof *prop_args);
> @@ -1925,11 +2098,16 @@ int main(int argc, char **argv)
>                 return -1;
>         }
>
> -       if (test_vsync && !count) {
> +       if (test_vsync && (!count && !is_atomic)) {
>                 fprintf(stderr, "page flipping requires at least one -s option.\n");
>                 return -1;
>         }
>
> +       if (test_vsync && is_atomic && flip_plane_id == 0) {
> +               fprintf(stderr, "fliping plane id must be set for atomic pageflip\n");
And how does average Joe find out the ID ? Something feels quite funny
with this approach.

Hyungwon, despite my nitpicking your work looks quite good. The above
question is rather important and I take care of everything else
-either before pushing or as a follow up patch-es, depending on your
preference. Let me know how you feel about it.

Thanks
Emil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type
  2015-11-26 16:42 ` [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type Emil Velikov
@ 2015-11-27  2:37   ` Hyungwon Hwang
  2015-12-07 16:37     ` Thierry Reding
  0 siblings, 1 reply; 8+ messages in thread
From: Hyungwon Hwang @ 2015-11-27  2:37 UTC (permalink / raw)
  To: Emil Velikov, treding; +Cc: ML dri-devel

Hello all,

+To Thierry Reding

On Thu, 26 Nov 2015 16:42:01 +0000
Emil Velikov <emil.l.velikov@gmail.com> wrote:

> Hi Hyungwon
> 
> I completely missed out that you've sent an updated version of the
> series. I will take a look at them later on tonight. Meanwhile have
> you looked at the atomic tests/helpers work from Thierry [1] ? It
> creates nice simple helpers (as opposed to a single massive C file
> like modetest) and I'm leaning that there is quite a lot of code that
> can be reused from there.
> 
> Speaking of which Thierry,
> What is happening with these patches ? Last time you've respun them
> I've pinged you to send them over for inclusion. There was a trivial
> fix needed here or there but they were in pretty good shape.

Yes. I checked it now. It would be more clear concise, if they comes.
Would it be better to wait Thierry for sending them again? Can you
afford to do that, Thierry?

BRs,
Hyungwon Hwang


> 
> Thanks
> Emil
> 
> [1] http://cgit.freedesktop.org/~tagr/drm/
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type
  2015-11-27  2:37   ` Hyungwon Hwang
@ 2015-12-07 16:37     ` Thierry Reding
  0 siblings, 0 replies; 8+ messages in thread
From: Thierry Reding @ 2015-12-07 16:37 UTC (permalink / raw)
  To: Hyungwon Hwang; +Cc: Emil Velikov, ML dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 1183 bytes --]

On Fri, Nov 27, 2015 at 11:37:33AM +0900, Hyungwon Hwang wrote:
> Hello all,
> 
> +To Thierry Reding
> 
> On Thu, 26 Nov 2015 16:42:01 +0000
> Emil Velikov <emil.l.velikov@gmail.com> wrote:
> 
> > Hi Hyungwon
> > 
> > I completely missed out that you've sent an updated version of the
> > series. I will take a look at them later on tonight. Meanwhile have
> > you looked at the atomic tests/helpers work from Thierry [1] ? It
> > creates nice simple helpers (as opposed to a single massive C file
> > like modetest) and I'm leaning that there is quite a lot of code that
> > can be reused from there.
> > 
> > Speaking of which Thierry,
> > What is happening with these patches ? Last time you've respun them
> > I've pinged you to send them over for inclusion. There was a trivial
> > fix needed here or there but they were in pretty good shape.
> 
> Yes. I checked it now. It would be more clear concise, if they comes.
> Would it be better to wait Thierry for sending them again? Can you
> afford to do that, Thierry?

Yeah, I think I can do that. It'll probably take until tomorrow for me
to find a free slot to rebase and send out again.

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-12-07 16:37 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-23  2:45 [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type Hyungwon Hwang
2015-09-23  2:45 ` [PATCH v3 2/3] modetest: add atomic modeset support Hyungwon Hwang
2015-11-26 23:42   ` Emil Velikov
2015-09-23  2:45 ` [PATCH v3 3/3] modetest: add atomic page flip support Hyungwon Hwang
2015-11-26 23:57   ` Emil Velikov
2015-11-26 16:42 ` [PATCH v3 1/3] modetest: introduce get_prop_info() for getting property id and type Emil Velikov
2015-11-27  2:37   ` Hyungwon Hwang
2015-12-07 16:37     ` Thierry Reding

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox