All of lore.kernel.org
 help / color / mirror / Atom feed
From: Emil Velikov <emil.l.velikov@gmail.com>
To: Thierry Reding <thierry.reding@gmail.com>,
	mesa-dev@lists.freedesktop.org
Cc: nouveau@lists.freedesktop.org, emil.l.velikov@gmail.com
Subject: Re: [RFC] tegra: Initial support
Date: Fri, 28 Nov 2014 16:26:36 +0000	[thread overview]
Message-ID: <5478A23C.8080100@gmail.com> (raw)
In-Reply-To: <1417106361-705-1-git-send-email-thierry.reding@gmail.com>

Hi Thierry,

Must admit that I really prefer this idea over modifying existing
applications/users [1] because:
 - Most of these setups are tightly coupled (imx+vivante, tegra+nouveau)
and pushing this down to the driver prevents duplication, and hardware
specific details in the users.
 - Removes the need (at least temporary) to have an arbiter and policies
about which devices can and how they should be coupled.

Hope your trip through the build/target helpers did not leave you
tearing your hairs out :)

[1] xserver's libglx and everyone else whole deals with gbm or dri
modules directly.

On 27/11/14 16:39, Thierry Reding wrote:
> Tegra K1 and later use a GPU that can be driven by the Nouveau driver.
> But the GPU is a pure render node and has no display engine, hence the
> scanout needs to happen on the Tegra display hardware. The GPU and the
> display engine each have a separate DRM device node exposed by the
> kernel.
> 
> To make the setup appear as a single device, this driver instantiates
> a Nouveau screen with each instance of a Tegra screen and forwards GPU
> requests to the Nouveau screen. For purposes of scanout it will import
> buffers created on the GPU into the display driver. Handles that
> userspace requests are those of the display driver so that they can be
> used to create framebuffers.
> 
> This has been tested with some GBM test programs, as well as kmscube and
> weston. All of those run without modifications, but I'm sure there is a
> lot that can be improved.
> 
> TODO:
> - use Nouveau headers to get at the prototype for creating a screen
I've addressed those inline for you :)

> - implement enough support to seamlessly integrate with X
> - refactor some of the code to be reusable by other drivers
I think this topic will be open for debate for a while. Especially since
tegra is only one driver (for now) that uses this type on
stacking/wrapping thus it's not so easy to predict if others won't need
anything extra.

> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  configure.ac                                       |  12 +-
>  src/gallium/Makefile.am                            |   5 +
>  .../auxiliary/target-helpers/inline_drm_helper.h   |  30 +
>  src/gallium/drivers/tegra/Automake.inc             |  11 +
>  src/gallium/drivers/tegra/Makefile.am              |  17 +
>  src/gallium/drivers/tegra/Makefile.sources         |   4 +
>  src/gallium/drivers/tegra/tegra_context.c          | 699 +++++++++++++++++++++
>  src/gallium/drivers/tegra/tegra_context.h          |  80 +++
>  src/gallium/drivers/tegra/tegra_resource.c         | 219 +++++++
>  src/gallium/drivers/tegra/tegra_resource.h         |  98 +++
>  src/gallium/drivers/tegra/tegra_screen.c           | 311 +++++++++
>  src/gallium/drivers/tegra/tegra_screen.h           |  45 ++
>  src/gallium/targets/dri/Makefile.am                |   2 +
>  src/gallium/winsys/tegra/drm/Makefile.am           |  11 +
>  src/gallium/winsys/tegra/drm/Makefile.sources      |   2 +
>  src/gallium/winsys/tegra/drm/tegra_drm_public.h    |  31 +
>  src/gallium/winsys/tegra/drm/tegra_drm_winsys.c    |  33 +
>  17 files changed, 1609 insertions(+), 1 deletion(-)
>  create mode 100644 src/gallium/drivers/tegra/Automake.inc
>  create mode 100644 src/gallium/drivers/tegra/Makefile.am
>  create mode 100644 src/gallium/drivers/tegra/Makefile.sources
>  create mode 100644 src/gallium/drivers/tegra/tegra_context.c
>  create mode 100644 src/gallium/drivers/tegra/tegra_context.h
>  create mode 100644 src/gallium/drivers/tegra/tegra_resource.c
>  create mode 100644 src/gallium/drivers/tegra/tegra_resource.h
>  create mode 100644 src/gallium/drivers/tegra/tegra_screen.c
>  create mode 100644 src/gallium/drivers/tegra/tegra_screen.h
>  create mode 100644 src/gallium/winsys/tegra/drm/Makefile.am
>  create mode 100644 src/gallium/winsys/tegra/drm/Makefile.sources
>  create mode 100644 src/gallium/winsys/tegra/drm/tegra_drm_public.h
>  create mode 100644 src/gallium/winsys/tegra/drm/tegra_drm_winsys.c
> 
> diff --git a/configure.ac b/configure.ac
> index 1d9d015481ec..ae50bec95339 100644
> --- a/configure.ac
> +++ b/configure.ac
[...]
> @@ -1937,6 +1938,12 @@ if test -n "$with_gallium_drivers"; then
>              gallium_require_drm "freedreno"
>              gallium_require_drm_loader
>              ;;
> +        xtegra)
> +            HAVE_GALLIUM_TEGRA=yes
> +            PKG_CHECK_MODULES([TEGRA], [libdrm_tegra >= $LIBDRM_TEGRA_REQUIRED])
> +            gallium_require_drm "tegra"
> +            gallium_require_drm_loader
> +            ;;
You might want to have something like the following further down.
Admittedly it's not perfect (it will create a nouveau_dri.so hardlink)
but it'll avoid the manual case for nouveau dependencies.


if test "x$HAVE_GALLIUM_NOUVEAU" != xyes -a
   test "x$HAVE_GALLIUM_TEGRA" = xyes; then
   AC_ERROR([Building with tegra requires that nouveau])
fi


[...]
> diff --git a/src/gallium/drivers/tegra/Makefile.am b/src/gallium/drivers/tegra/Makefile.am
> new file mode 100644
> index 000000000000..eb03df9bb2ed
> --- /dev/null
> +++ b/src/gallium/drivers/tegra/Makefile.am
> @@ -0,0 +1,17 @@
> +AUTOMAKE_OPTIONS = subdir-objects
> +
Don't think you need the AUTOMAKE_OPTIONS here.

> +include Makefile.sources
> +include $(top_srcdir)/src/gallium/Automake.inc
> +
> +AM_CFLAGS = \
> +	$(GALLIUM_DRIVER_CFLAGS) \
> +	$(LIBUDEV_CFLAGS) \
> +	$(TEGRA_CFLAGS)
> +
> +noinst_LTLIBRARIES = libtegra.la
> +
> +libtegra_la_SOURCES = \
> +	$(C_SOURCES)
> +
> +libtegra_la_LIBADD = \
> +	$(LIBUDEV_LIBS)
Here comes the big question:
Can we do something to avoid the link against libudev ? If we _do_ need
to go through libudev, can we please dlopen/dlsym it.

> diff --git a/src/gallium/drivers/tegra/Makefile.sources b/src/gallium/drivers/tegra/Makefile.sources
> new file mode 100644
> index 000000000000..978dd14667f5
> --- /dev/null
> +++ b/src/gallium/drivers/tegra/Makefile.sources
> @@ -0,0 +1,4 @@
> +C_SOURCES := \
> +	tegra_context.c \
> +	tegra_resource.c \
> +	tegra_screen.c
Please add the headers to the above list. It will help automake pick
them up in the distribution tarball.

[...]
> diff --git a/src/gallium/drivers/tegra/tegra_resource.c b/src/gallium/drivers/tegra/tegra_resource.c
> new file mode 100644
> index 000000000000..8c5b7d4e41fc
> --- /dev/null
> +++ b/src/gallium/drivers/tegra/tegra_resource.c
[...]
> +#include <drm/tegra_drm.h>
Please drop the "drm/" part.

> diff --git a/src/gallium/drivers/tegra/tegra_screen.c b/src/gallium/drivers/tegra/tegra_screen.c
> new file mode 100644
> index 000000000000..aa7bf65cb7ec
> --- /dev/null
> +++ b/src/gallium/drivers/tegra/tegra_screen.c
[...]
> +#ifdef HAVE_LIBUDEV
> +#include <libudev.h>
> +#endif
> +
You might as well drop the #ifdef here. Afaics you're using udev API
explicitly below.

> +#include "util/u_debug.h"
> +
> +#include "tegra/tegra_context.h"
> +#include "tegra/tegra_resource.h"
> +#include "tegra/tegra_screen.h"
> +
> +/* TODO: obtain from include file */
> +struct pipe_screen *nouveau_drm_screen_create(int fd);
> +
#include "nouveau/drm/nouveau_drm_public.h" ?

> +static const char *
> +tegra_get_name(struct pipe_screen *pscreen)
> +{
> +	return "tegra";
For nouveau/radeons we add the chipset name so I guess doing similar
thing here wouldn't be a bad idea. Additionally for combined/stacked
drivers we might want to return both the base + gpu's get_name(). It
will provide nice feedback about the actual rendering device + programs
which use device name hacks will continue working :)

> +}
> +
> +static const char *
> +tegra_get_vendor(struct pipe_screen *pscreen)
> +{
> +	return "tegra";
Provide both vendors similar to above ? "NVIDIA Corp + nouveau" :P

[...]
> +static int tegra_open_render_node(int fd)
> +{
[...]
> +	udev_list_entry_foreach(entry, list) {
> +		const char *path = udev_list_entry_get_name(entry);
> +		struct udev_device *device, *bus;
> +
> +		device = udev_device_new_from_syspath(udev, path);
> +		if (!device)
> +			continue;
> +
> +		path = udev_device_get_devnode(device);
> +
> +		parent = udev_device_get_parent(device);
> +		if (!parent) {
> +			udev_device_unref(device);
> +			continue;
> +		}
> +
> +		/* do not match if the render nodes shares the same parent */
> +		if (udev_device_match(parent, display)) {
> +			udev_device_unref(parent);
> +			udev_device_unref(device);
> +			continue;
> +		}
> +
> +		bus = udev_device_get_root(device);
> +		if (!bus) {
> +			udev_device_unref(parent);
> +			udev_device_unref(device);
> +			continue;
> +		}
> +
> +		/* both devices need to be on the same bus, though */
> +		if (udev_device_match(bus, root)) {
> +			fd = open(path, O_RDWR);
open(path) only to ignore it and return open("renderD128") below ? Seems
like something is missing here.

> +			if (fd < 0)
> +				fd = -errno;
> +
> +			break;
> +		}
> +	}
> +
> +	udev_enumerate_unref(enumerate);
> +	udev_unref(udev);
> +
> +	return open("/dev/dri/renderD128", O_RDWR);
> +}
> +

[...]
> diff --git a/src/gallium/winsys/tegra/drm/Makefile.am b/src/gallium/winsys/tegra/drm/Makefile.am
> new file mode 100644
> index 000000000000..8e3685ee20e8
> --- /dev/null
> +++ b/src/gallium/winsys/tegra/drm/Makefile.am
> @@ -0,0 +1,11 @@
> +include Makefile.sources
> +include $(top_srcdir)/src/gallium/Automake.inc
> +
> +AM_CFLAGS = \
> +	-I$(top_srcdir)/src/gallium/drivers \
> +	$(GALLIUM_WINSYS_CFLAGS) \
> +	$(FREEDRENO_CFLAGS)
> +
Do we even need FREEDRENO/TEGRA_CFLAGS here ?

> +noinst_LTLIBRARIES = libtegradrm.la
> +
> +libtegradrm_la_SOURCES = $(C_SOURCES)
> diff --git a/src/gallium/winsys/tegra/drm/Makefile.sources b/src/gallium/winsys/tegra/drm/Makefile.sources
> new file mode 100644
> index 000000000000..fe0d5c42e72d
> --- /dev/null
> +++ b/src/gallium/winsys/tegra/drm/Makefile.sources
> @@ -0,0 +1,2 @@
> +C_SOURCES := \
> +	tegra_drm_winsys.c
Please add tegra_drm_public.h to the list.

[...]
> diff --git a/src/gallium/winsys/tegra/drm/tegra_drm_winsys.c b/src/gallium/winsys/tegra/drm/tegra_drm_winsys.c
> new file mode 100644
> index 000000000000..99b0e1649026
> --- /dev/null
> +++ b/src/gallium/winsys/tegra/drm/tegra_drm_winsys.c
> @@ -0,0 +1,33 @@
> +/*
> + * 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 (including the next
> + * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
> + */
> +
> +#include "util/u_debug.h"
> +
> +#include "tegra/tegra_screen.h"
> +
> +struct pipe_screen *tegra_drm_screen_create(int fd);
> +
util/u_debug.h is not be needed so the following should suffice.

#include "tegra_drm_public.h"
#include "tegra/tegra_screen.h"


Thanks
Emil

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

      parent reply	other threads:[~2014-11-28 16:26 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-27 16:39 [RFC] tegra: Initial support Thierry Reding
     [not found] ` <1417106361-705-1-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-11-27 16:51   ` [Mesa-dev] " Rob Clark
     [not found]     ` <CAF6AEGuf9d_U7NpS2z-4_UTk=9cY3HX+FYpS-JYv_FagZBVG5A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-11-28  8:46       ` Thierry Reding
2014-11-28  5:14   ` Alexandre Courbot
     [not found]     ` <547804B0.4020603-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2014-11-28  8:48       ` Thierry Reding
2014-11-28  8:52         ` Alexandre Courbot
2014-11-28  9:19           ` [Nouveau] " Thierry Reding
2014-11-28  5:32 ` Ilia Mirkin
2014-11-28  9:17   ` Thierry Reding
2014-11-28 15:54     ` [Mesa-dev] " Daniel Stone
2014-11-28 16:26 ` Emil Velikov [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5478A23C.8080100@gmail.com \
    --to=emil.l.velikov@gmail.com \
    --cc=mesa-dev@lists.freedesktop.org \
    --cc=nouveau@lists.freedesktop.org \
    --cc=thierry.reding@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.