diff mbox

[v2,libdrm,6/7] tegra: Add gr2d-fill test

Message ID 1397043630-13972-7-git-send-email-thierry.reding@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Thierry Reding April 9, 2014, 11:40 a.m. UTC
From: Thierry Reding <treding@nvidia.com>

This test uses the IOCTLs for job submission and fences to fill a sub-
region of the screen to a specific color using gr2d.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v2:
- free framebuffer when done

 tests/tegra/.gitignore  |   1 +
 tests/tegra/Makefile.am |   1 +
 tests/tegra/gr2d-fill.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 148 insertions(+)
 create mode 100644 tests/tegra/gr2d-fill.c

Comments

Erik Faye-Lund April 10, 2014, 5:28 p.m. UTC | #1
On Wed, Apr 9, 2014 at 1:40 PM, Thierry Reding <thierry.reding@gmail.com> wrote:
> diff --git a/tests/tegra/gr2d-fill.c b/tests/tegra/gr2d-fill.c
> new file mode 100644
> index 000000000000..b6ba35a9d668
> --- /dev/null
> +++ b/tests/tegra/gr2d-fill.c
> @@ -0,0 +1,146 @@
> +/*
> + * Copyright © 2014 NVIDIA Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#  include "config.h"
> +#endif
> +
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <stdbool.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +
> +#include <sys/ioctl.h>
> +
> +#include "xf86drm.h"
> +#include "xf86drmMode.h"
> +#include "drm_fourcc.h"
> +
> +#include "drm-test-tegra.h"
> +#include "tegra.h"
> +
> +int main(int argc, char *argv[])
> +{
> +       uint32_t format = DRM_FORMAT_XRGB8888;
> +       struct drm_tegra_gr2d *gr2d;
> +       struct drm_framebuffer *fb;
> +       struct drm_screen *screen;
> +       unsigned int pitch, size;
> +       struct drm_tegra_bo *bo;
> +       struct drm_tegra *drm;
> +       uint32_t handle;
> +       int fd, err;
> +       void *ptr;
> +
> +       fd = drm_open(argv[1]);
> +       if (fd < 0) {
> +               fprintf(stderr, "failed to open DRM device %s: %s\n", argv[1],
> +                       strerror(errno));
> +               return 1;
> +       }

I'm not quite sure I understand this part. Why would argv[1] be
anything else than NULL? Is this useful for manual debugging, perhaps?

> +       err = drm_tegra_gr2d_fill(gr2d, fb, fb->width / 4, fb->height / 4,
> +                                 fb->width / 2, fb->height / 2, 0x00000000);
> +       if (err < 0) {
> +               fprintf(stderr, "failed to fill rectangle: %s\n",
> +                       strerror(-err));
> +               return 1;
> +       }
> +
> +       sleep(1);
> +

Why do we need to sleep here?
Thierry Reding May 2, 2014, 2:25 p.m. UTC | #2
On Thu, Apr 10, 2014 at 07:28:16PM +0200, Erik Faye-Lund wrote:
> On Wed, Apr 9, 2014 at 1:40 PM, Thierry Reding <thierry.reding@gmail.com> wrote:
> > diff --git a/tests/tegra/gr2d-fill.c b/tests/tegra/gr2d-fill.c
> > new file mode 100644
> > index 000000000000..b6ba35a9d668
> > --- /dev/null
> > +++ b/tests/tegra/gr2d-fill.c
> > @@ -0,0 +1,146 @@
> > +/*
> > + * Copyright © 2014 NVIDIA Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice shall be included in
> > + * all copies or substantial portions of the Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> > + * OTHER DEALINGS IN THE SOFTWARE.
> > + */
> > +
> > +#ifdef HAVE_CONFIG_H
> > +#  include "config.h"
> > +#endif
> > +
> > +#include <errno.h>
> > +#include <fcntl.h>
> > +#include <stdbool.h>
> > +#include <stdint.h>
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <unistd.h>
> > +
> > +#include <sys/ioctl.h>
> > +
> > +#include "xf86drm.h"
> > +#include "xf86drmMode.h"
> > +#include "drm_fourcc.h"
> > +
> > +#include "drm-test-tegra.h"
> > +#include "tegra.h"
> > +
> > +int main(int argc, char *argv[])
> > +{
> > +       uint32_t format = DRM_FORMAT_XRGB8888;
> > +       struct drm_tegra_gr2d *gr2d;
> > +       struct drm_framebuffer *fb;
> > +       struct drm_screen *screen;
> > +       unsigned int pitch, size;
> > +       struct drm_tegra_bo *bo;
> > +       struct drm_tegra *drm;
> > +       uint32_t handle;
> > +       int fd, err;
> > +       void *ptr;
> > +
> > +       fd = drm_open(argv[1]);
> > +       if (fd < 0) {
> > +               fprintf(stderr, "failed to open DRM device %s: %s\n", argv[1],
> > +                       strerror(errno));
> > +               return 1;
> > +       }
> 
> I'm not quite sure I understand this part. Why would argv[1] be
> anything else than NULL? Is this useful for manual debugging, perhaps?

Yes. On newer Tegra generations the nouveau driver can create its own
device files in /dev/dri and depending on device probe order, the card0
device can be the wrong one. For such cases these test programs can be
passed the path to the correct device via the command-line.

Probably a better approach would be to search for a compatible device
via udev matching or iterating over /dev/dri/card* and querying the
driver name (which is what drm_tegra_new() already does). But that seems
overkill currently. Perhaps when this turns into a more fully-fledged
test suite that could be implemented more cleverly.

For now I've addressed this by making the tests fallback to a default
device (/dev/dri/card0) if no argument has been specified.

> > +       err = drm_tegra_gr2d_fill(gr2d, fb, fb->width / 4, fb->height / 4,
> > +                                 fb->width / 2, fb->height / 2, 0x00000000);
> > +       if (err < 0) {
> > +               fprintf(stderr, "failed to fill rectangle: %s\n",
> > +                       strerror(-err));
> > +               return 1;
> > +       }
> > +
> > +       sleep(1);
> > +
> 
> Why do we need to sleep here?

This is a visual test, so that one second gives me some time to see if
the result looks as expected.

I have tentative plans to implement a set of more automated tests, where
an image is rendered and the checksum computed over the content can be
compared with a known good reference checksum, but for now this is
better than nothing.

Thierry
Erik Faye-Lund May 2, 2014, 3:02 p.m. UTC | #3
On Fri, May 2, 2014 at 4:25 PM, Thierry Reding <thierry.reding@gmail.com> wrote:
> On Thu, Apr 10, 2014 at 07:28:16PM +0200, Erik Faye-Lund wrote:
>> On Wed, Apr 9, 2014 at 1:40 PM, Thierry Reding <thierry.reding@gmail.com> wrote:
>> > diff --git a/tests/tegra/gr2d-fill.c b/tests/tegra/gr2d-fill.c
>> > new file mode 100644
>> > index 000000000000..b6ba35a9d668
>> > --- /dev/null
>> > +++ b/tests/tegra/gr2d-fill.c
>> > @@ -0,0 +1,146 @@
>> > +/*
>> > + * Copyright © 2014 NVIDIA Corporation
>> > + *
>> > + * Permission is hereby granted, free of charge, to any person obtaining a
>> > + * copy of this software and associated documentation files (the "Software"),
>> > + * to deal in the Software without restriction, including without limitation
>> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
>> > + * and/or sell copies of the Software, and to permit persons to whom the
>> > + * Software is furnished to do so, subject to the following conditions:
>> > + *
>> > + * The above copyright notice and this permission notice shall be included in
>> > + * all copies or substantial portions of the Software.
>> > + *
>> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
>> > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
>> > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
>> > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>> > + * OTHER DEALINGS IN THE SOFTWARE.
>> > + */
>> > +
>> > +#ifdef HAVE_CONFIG_H
>> > +#  include "config.h"
>> > +#endif
>> > +
>> > +#include <errno.h>
>> > +#include <fcntl.h>
>> > +#include <stdbool.h>
>> > +#include <stdint.h>
>> > +#include <stdio.h>
>> > +#include <stdlib.h>
>> > +#include <string.h>
>> > +#include <unistd.h>
>> > +
>> > +#include <sys/ioctl.h>
>> > +
>> > +#include "xf86drm.h"
>> > +#include "xf86drmMode.h"
>> > +#include "drm_fourcc.h"
>> > +
>> > +#include "drm-test-tegra.h"
>> > +#include "tegra.h"
>> > +
>> > +int main(int argc, char *argv[])
>> > +{
>> > +       uint32_t format = DRM_FORMAT_XRGB8888;
>> > +       struct drm_tegra_gr2d *gr2d;
>> > +       struct drm_framebuffer *fb;
>> > +       struct drm_screen *screen;
>> > +       unsigned int pitch, size;
>> > +       struct drm_tegra_bo *bo;
>> > +       struct drm_tegra *drm;
>> > +       uint32_t handle;
>> > +       int fd, err;
>> > +       void *ptr;
>> > +
>> > +       fd = drm_open(argv[1]);
>> > +       if (fd < 0) {
>> > +               fprintf(stderr, "failed to open DRM device %s: %s\n", argv[1],
>> > +                       strerror(errno));
>> > +               return 1;
>> > +       }
>>
>> I'm not quite sure I understand this part. Why would argv[1] be
>> anything else than NULL? Is this useful for manual debugging, perhaps?
>
> Yes. On newer Tegra generations the nouveau driver can create its own
> device files in /dev/dri and depending on device probe order, the card0
> device can be the wrong one. For such cases these test programs can be
> passed the path to the correct device via the command-line.
>
> Probably a better approach would be to search for a compatible device
> via udev matching or iterating over /dev/dri/card* and querying the
> driver name (which is what drm_tegra_new() already does). But that seems
> overkill currently. Perhaps when this turns into a more fully-fledged
> test suite that could be implemented more cleverly.
>
> For now I've addressed this by making the tests fallback to a default
> device (/dev/dri/card0) if no argument has been specified.
>

Thanks for the explanation, makes sense!

>> > +       err = drm_tegra_gr2d_fill(gr2d, fb, fb->width / 4, fb->height / 4,
>> > +                                 fb->width / 2, fb->height / 2, 0x00000000);
>> > +       if (err < 0) {
>> > +               fprintf(stderr, "failed to fill rectangle: %s\n",
>> > +                       strerror(-err));
>> > +               return 1;
>> > +       }
>> > +
>> > +       sleep(1);
>> > +
>>
>> Why do we need to sleep here?
>
> This is a visual test, so that one second gives me some time to see if
> the result looks as expected.
>
> I have tentative plans to implement a set of more automated tests, where
> an image is rendered and the checksum computed over the content can be
> compared with a known good reference checksum, but for now this is
> better than nothing.

Aha, makes sense. Thanks, looks good!
diff mbox

Patch

diff --git a/tests/tegra/.gitignore b/tests/tegra/.gitignore
index 5c5216c5c5e6..5e0b5c601dd1 100644
--- a/tests/tegra/.gitignore
+++ b/tests/tegra/.gitignore
@@ -1 +1,2 @@ 
+gr2d-fill
 openclose
diff --git a/tests/tegra/Makefile.am b/tests/tegra/Makefile.am
index e468029d152e..286af4b4d706 100644
--- a/tests/tegra/Makefile.am
+++ b/tests/tegra/Makefile.am
@@ -19,6 +19,7 @@  LDADD = \
 
 TESTS = \
 	openclose \
+	gr2d-fill
 
 if HAVE_INSTALL_TESTS
 testdir = $(libexecdir)/libdrm/tests/tegra
diff --git a/tests/tegra/gr2d-fill.c b/tests/tegra/gr2d-fill.c
new file mode 100644
index 000000000000..b6ba35a9d668
--- /dev/null
+++ b/tests/tegra/gr2d-fill.c
@@ -0,0 +1,146 @@ 
+/*
+ * Copyright © 2014 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+
+#include "xf86drm.h"
+#include "xf86drmMode.h"
+#include "drm_fourcc.h"
+
+#include "drm-test-tegra.h"
+#include "tegra.h"
+
+int main(int argc, char *argv[])
+{
+	uint32_t format = DRM_FORMAT_XRGB8888;
+	struct drm_tegra_gr2d *gr2d;
+	struct drm_framebuffer *fb;
+	struct drm_screen *screen;
+	unsigned int pitch, size;
+	struct drm_tegra_bo *bo;
+	struct drm_tegra *drm;
+	uint32_t handle;
+	int fd, err;
+	void *ptr;
+
+	fd = drm_open(argv[1]);
+	if (fd < 0) {
+		fprintf(stderr, "failed to open DRM device %s: %s\n", argv[1],
+			strerror(errno));
+		return 1;
+	}
+
+	err = drm_screen_open(&screen, fd);
+	if (err < 0) {
+		fprintf(stderr, "failed to open screen: %s\n", strerror(-err));
+		return 1;
+	}
+
+	err = drm_tegra_new(&drm, fd);
+	if (err < 0) {
+		fprintf(stderr, "failed to create Tegra DRM context: %s\n",
+			strerror(-err));
+		return 1;
+	}
+
+	err = drm_tegra_gr2d_open(&gr2d, drm);
+	if (err < 0) {
+		fprintf(stderr, "failed to open gr2d channel: %s\n",
+			strerror(-err));
+		return 1;
+	}
+
+	pitch = screen->width * screen->bpp / 8;
+	size = pitch * screen->height;
+
+	err = drm_tegra_bo_new(&bo, drm, 0, size);
+	if (err < 0) {
+		fprintf(stderr, "failed to create buffer object: %s\n",
+			strerror(-err));
+		return 1;
+	}
+
+	err = drm_tegra_bo_get_handle(bo, &handle);
+	if (err < 0) {
+		fprintf(stderr, "failed to get handle to buffer object: %s\n",
+			strerror(-err));
+		return 1;
+	}
+
+	err = drm_tegra_bo_map(bo, &ptr);
+	if (err < 0) {
+		fprintf(stderr, "failed to map buffer object: %s\n",
+			strerror(-err));
+		return 1;
+	}
+
+	memset(ptr, 0xff, size);
+
+	err = drm_framebuffer_new(&fb, screen, handle, screen->width,
+				  screen->height, pitch, format, bo);
+	if (err < 0) {
+		fprintf(stderr, "failed to create framebuffer: %s\n",
+			strerror(-err));
+		return 1;
+	}
+
+	err = drm_screen_set_framebuffer(screen, fb);
+	if (err < 0) {
+		fprintf(stderr, "failed to display framebuffer: %s\n",
+			strerror(-err));
+		return 1;
+	}
+
+	sleep(1);
+
+	err = drm_tegra_gr2d_fill(gr2d, fb, fb->width / 4, fb->height / 4,
+				  fb->width / 2, fb->height / 2, 0x00000000);
+	if (err < 0) {
+		fprintf(stderr, "failed to fill rectangle: %s\n",
+			strerror(-err));
+		return 1;
+	}
+
+	sleep(1);
+
+	drm_framebuffer_free(fb);
+	drm_tegra_bo_put(bo);
+	drm_tegra_gr2d_close(gr2d);
+	drm_tegra_close(drm);
+	drm_screen_close(screen);
+	drm_close(fd);
+
+	return 0;
+}