tegra: Initial support
RFC 1/1 tegra: Initial support
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
- implement enough support to seamlessly integrate with X
- refactor some of the code to be reusable by other drivers
--- 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
configure.ac +11 -1
@@ -33,6 +33,7 @@ LIBDRM_INTEL_REQUIRED=2.4.52 LIBDRM_NVVIEUX_REQUIRED=2.4.33 LIBDRM_NOUVEAU_REQUIRED="2.4.33 libdrm >= 2.4.41" LIBDRM_FREEDRENO_REQUIRED=2.4.57 +LIBDRM_TEGRA_REQUIRED=2.4.58 DRI2PROTO_REQUIRED=2.6 DRI3PROTO_REQUIRED=1.0 PRESENTPROTO_REQUIRED=1.0
@@ -733,7 +734,7 @@ GALLIUM_DRIVERS_DEFAULT="r300,r600,svga,swrast" AC_ARG_WITH([gallium-drivers], [AS_HELP_STRING([--with-gallium-drivers@<:@=DIRS...@:>@], [comma delimited Gallium drivers list, e.g. - "i915,ilo,nouveau,r300,r600,radeonsi,freedreno,svga,swrast,vc4" + "i915,ilo,nouveau,r300,r600,radeonsi,freedreno,tegra,svga,swrast,vc4" @<:@default=r300,r600,svga,swrast@:>@])], [with_gallium_drivers="$withval"], [with_gallium_drivers="$GALLIUM_DRIVERS_DEFAULT"])
@@ -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 + ;; xswrast) HAVE_GALLIUM_SOFTPIPE=yes if test "x$MESA_LLVM" = x1; then
@@ -2018,6 +2025,7 @@ AM_CONDITIONAL(HAVE_GALLIUM_RADEON_COMMON, test "x$HAVE_GALLIUM_R600" = xyes -o "x$HAVE_GALLIUM_RADEONSI" = xyes) AM_CONDITIONAL(HAVE_GALLIUM_NOUVEAU, test "x$HAVE_GALLIUM_NOUVEAU" = xyes) AM_CONDITIONAL(HAVE_GALLIUM_FREEDRENO, test "x$HAVE_GALLIUM_FREEDRENO" = xyes) +AM_CONDITIONAL(HAVE_GALLIUM_TEGRA, test "x$HAVE_GALLIUM_TEGRA" = xyes) AM_CONDITIONAL(HAVE_GALLIUM_SOFTPIPE, test "x$HAVE_GALLIUM_SOFTPIPE" = xyes) AM_CONDITIONAL(HAVE_GALLIUM_LLVMPIPE, test "x$HAVE_GALLIUM_LLVMPIPE" = xyes) AM_CONDITIONAL(HAVE_GALLIUM_VC4, test "x$HAVE_GALLIUM_VC4" = xyes)
@@ -2159,6 +2167,7 @@ AC_CONFIG_FILES([Makefile src/gallium/drivers/rbug/Makefile src/gallium/drivers/softpipe/Makefile src/gallium/drivers/svga/Makefile + src/gallium/drivers/tegra/Makefile src/gallium/drivers/trace/Makefile src/gallium/drivers/vc4/Makefile src/gallium/drivers/vc4/kernel/Makefile
@@ -2204,6 +2213,7 @@ AC_CONFIG_FILES([Makefile src/gallium/winsys/sw/wayland/Makefile src/gallium/winsys/sw/wrapper/Makefile src/gallium/winsys/sw/xlib/Makefile + src/gallium/winsys/tegra/drm/Makefile src/gallium/winsys/vc4/drm/Makefile src/gbm/Makefile src/gbm/main/gbm.pc
src/gallium/Makefile.am +5 -0
@@ -77,6 +77,11 @@ SUBDIRS += drivers/llvmpipe endif endif +## tegra +if HAVE_GALLIUM_TEGRA +SUBDIRS += drivers/tegra winsys/tegra/drm +endif + ## vc4/rpi if HAVE_GALLIUM_VC4 SUBDIRS += drivers/vc4 winsys/vc4/drm
src/gallium/auxiliary/target-helpers/inline_drm_helper.h +30 -0
@@ -58,6 +58,10 @@#include "vc4/drm/vc4_drm_public.h" #endif +#if GALLIUM_TEGRA +#include "tegra/drm/tegra_drm_public.h" +#endif +static char * driver_name =NULL ;/* XXX: We need to teardown the winsys if *screen_create() fails. */
@@ -332,6 +336,27 @@ pipe_vc4_create_screen(int fd) }#endif +#if defined(GALLIUM_TEGRA ) +#if defined(DRI_TARGET ) +const __DRIextension **__driDriverGetExtensions_tegra (void ); + +PUBLIC const __DRIextension **__driDriverGetExtensions_tegra(void) +{ + globalDriverAPI = &galliumdrm_driver_api; +return galliumdrm_driver_extensions; +} +#endif + +static struct pipe_screen *pipe_tegra_create_screen (int fd) +{ +struct pipe_screen *screen; + + screen =tegra_drm_screen_create (fd); + +return screen ?debug_screen_wrap (screen) :NULL ; +} +#endif +inline struct pipe_screen *dd_create_screen (int fd) {
@@ -389,6 +414,11 @@ dd_create_screen(int fd) else#endif #endif +#if defined(GALLIUM_TEGRA ) +if (strcmp (driver_name,"tegra" ) ==0 ) +return pipe_tegra_create_screen (fd); + else +#endif return NULL ; }
src/gallium/drivers/tegra/Automake.inc new file +11 -0
@@ -0,0 +1,11 @@ +if HAVE_GALLIUM_TEGRA + +TARGET_DRIVERS += tegra +TARGET_CPPFLAGS += -DGALLIUM_TEGRA +TARGET_LIB_DEPS += \ + $(top_builddir)/src/gallium/winsys/tegra/drm/libtegradrm.la \ + $(top_builddir)/src/gallium/drivers/tegra/libtegra.la \ + $(LIBDRM_LIBS) \ + $(TEGRA_LIBS) + +endif
src/gallium/drivers/tegra/Makefile.am new file +17 -0
@@ -0,0 +1,17 @@ +AUTOMAKE_OPTIONS = subdir-objects + +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)
src/gallium/drivers/tegra/Makefile.sources new file +4 -0
@@ -0,0 +1,4 @@ +C_SOURCES := \ + tegra_context.c \ + tegra_resource.c \ + tegra_screen.c
src/gallium/drivers/tegra/tegra_context.c new file +699 -0
699 lines not on this page · raw message
src/gallium/drivers/tegra/tegra_context.h new file +80 -0
80 lines not on this page · raw message
src/gallium/drivers/tegra/tegra_resource.c new file +219 -0
219 lines not on this page · raw message
src/gallium/drivers/tegra/tegra_resource.h new file +98 -0
98 lines not on this page · raw message
src/gallium/drivers/tegra/tegra_screen.c new file +311 -0
311 lines not on this page · raw message
src/gallium/drivers/tegra/tegra_screen.h new file +45 -0
45 lines not on this page · raw message
src/gallium/targets/dri/Makefile.am +2 -0
@@ -83,6 +83,8 @@ include $(top_srcdir)/src/gallium/drivers/svga/Automake.inc include $(top_srcdir)/src/gallium/drivers/freedreno/Automake.inc +include $(top_srcdir)/src/gallium/drivers/tegra/Automake.inc + include $(top_srcdir)/src/gallium/drivers/vc4/Automake.inc include $(top_srcdir)/src/gallium/drivers/softpipe/Automake.inc
src/gallium/winsys/tegra/drm/Makefile.am new file +11 -0
@@ -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) + +noinst_LTLIBRARIES = libtegradrm.la + +libtegradrm_la_SOURCES = $(C_SOURCES)
src/gallium/winsys/tegra/drm/Makefile.sources new file +2 -0
@@ -0,0 +1,2 @@ +C_SOURCES := \ + tegra_drm_winsys.c
src/gallium/winsys/tegra/drm/tegra_drm_public.h new file +31 -0
@@ -0,0 +1,31 @@ +/* +* 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. +*/ + +#ifndef __TEGRA_DRM_PUBLIC_H__ +#define __TEGRA_DRM_PUBLIC_H__ + +struct pipe_screen ; + +struct pipe_screen *tegra_drm_screen_create (int fd); + +#endif /* __TEGRA_DRM_PUBLIC_H__ */
src/gallium/winsys/tegra/drm/tegra_drm_winsys.c new file +33 -0
@@ -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); + +struct pipe_screen *tegra_drm_screen_create (int fd) +{ +return tegra_screen_create (fd); +}
Signature · 6 lines
2.1.3 _______________________________________________ Nouveau mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/nouveau
A message that is not in the archive (sent off-list or not yet received): 1417106361-705-1-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Quoted 13 lines · Thierry Reding
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.
Quoted 8 lines
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
- implement enough support to seamlessly integrate with X
- refactor some of the code to be reusable by other drivers
I haven't looked too carefully at the implementation yet, but couldn't you just put in src/gallium/drivers/shim ? I guess you'd just want a small if/else ladder where you create the *actual* screen, to create a nouveau screen for tegra, an etnaviv screen for imx, armada, etc..?
BR,
-R
Quoted 1,819 lines
Signed-off-by Thierry Reding <[email protected]>--- 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.cconfigure.ac +11
-1@@ -33,6 +33,7 @@ LIBDRM_INTEL_REQUIRED=2.4.52 LIBDRM_NVVIEUX_REQUIRED=2.4.33 LIBDRM_NOUVEAU_REQUIRED="2.4.33 libdrm >= 2.4.41" LIBDRM_FREEDRENO_REQUIRED=2.4.57 +LIBDRM_TEGRA_REQUIRED=2.4.58 DRI2PROTO_REQUIRED=2.6 DRI3PROTO_REQUIRED=1.0 PRESENTPROTO_REQUIRED=1.0@@ -733,7 +734,7 @@ GALLIUM_DRIVERS_DEFAULT="r300,r600,svga,swrast" AC_ARG_WITH([gallium-drivers], [AS_HELP_STRING([--with-gallium-drivers@<:@=DIRS...@:>@], [comma delimited Gallium drivers list, e.g. - "i915,ilo,nouveau,r300,r600,radeonsi,freedreno,svga,swrast,vc4" + "i915,ilo,nouveau,r300,r600,radeonsi,freedreno,tegra,svga,swrast,vc4" @<:@default=r300,r600,svga,swrast@:>@])], [with_gallium_drivers="$withval"], [with_gallium_drivers="$GALLIUM_DRIVERS_DEFAULT"])@@ -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 + ;; xswrast) HAVE_GALLIUM_SOFTPIPE=yes if test "x$MESA_LLVM" = x1; then@@ -2018,6 +2025,7 @@ AM_CONDITIONAL(HAVE_GALLIUM_RADEON_COMMON, test "x$HAVE_GALLIUM_R600" = xyes -o "x$HAVE_GALLIUM_RADEONSI" = xyes) AM_CONDITIONAL(HAVE_GALLIUM_NOUVEAU, test "x$HAVE_GALLIUM_NOUVEAU" = xyes) AM_CONDITIONAL(HAVE_GALLIUM_FREEDRENO, test "x$HAVE_GALLIUM_FREEDRENO" = xyes) +AM_CONDITIONAL(HAVE_GALLIUM_TEGRA, test "x$HAVE_GALLIUM_TEGRA" = xyes) AM_CONDITIONAL(HAVE_GALLIUM_SOFTPIPE, test "x$HAVE_GALLIUM_SOFTPIPE" = xyes) AM_CONDITIONAL(HAVE_GALLIUM_LLVMPIPE, test "x$HAVE_GALLIUM_LLVMPIPE" = xyes) AM_CONDITIONAL(HAVE_GALLIUM_VC4, test "x$HAVE_GALLIUM_VC4" = xyes)@@ -2159,6 +2167,7 @@ AC_CONFIG_FILES([Makefile src/gallium/drivers/rbug/Makefile src/gallium/drivers/softpipe/Makefile src/gallium/drivers/svga/Makefile + src/gallium/drivers/tegra/Makefile src/gallium/drivers/trace/Makefile src/gallium/drivers/vc4/Makefile src/gallium/drivers/vc4/kernel/Makefile@@ -2204,6 +2213,7 @@ AC_CONFIG_FILES([Makefile src/gallium/winsys/sw/wayland/Makefile src/gallium/winsys/sw/wrapper/Makefile src/gallium/winsys/sw/xlib/Makefile + src/gallium/winsys/tegra/drm/Makefile src/gallium/winsys/vc4/drm/Makefile src/gbm/Makefile src/gbm/main/gbm.pcsrc/gallium/Makefile.am +5
-0@@ -77,6 +77,11 @@ SUBDIRS += drivers/llvmpipe endif endif +## tegra +if HAVE_GALLIUM_TEGRA +SUBDIRS += drivers/tegra winsys/tegra/drm +endif + ## vc4/rpi if HAVE_GALLIUM_VC4 SUBDIRS += drivers/vc4 winsys/vc4/drmsrc/gallium/auxiliary/target-helpers/inline_drm_helper.h +30
-0@@ -58,6 +58,10 @@#include "vc4/drm/vc4_drm_public.h" #endif +#if GALLIUM_TEGRA +#include "tegra/drm/tegra_drm_public.h" +#endif +static char * driver_name =NULL ;/* XXX: We need to teardown the winsys if *screen_create() fails. */ @@ -332,6 +336,27 @@ pipe_vc4_create_screen(int fd) }#endif +#if defined(GALLIUM_TEGRA ) +#if defined(DRI_TARGET ) +const __DRIextension **__driDriverGetExtensions_tegra (void ); + +PUBLIC const __DRIextension **__driDriverGetExtensions_tegra(void) +{ + globalDriverAPI = &galliumdrm_driver_api; +return galliumdrm_driver_extensions; +} +#endif + +static struct pipe_screen *pipe_tegra_create_screen (int fd) +{ +struct pipe_screen *screen; + + screen =tegra_drm_screen_create (fd); + +return screen ?debug_screen_wrap (screen) :NULL ; +} +#endif +inline struct pipe_screen *dd_create_screen (int fd) {@@ -389,6 +414,11 @@ dd_create_screen(int fd) else#endif #endif +#if defined(GALLIUM_TEGRA ) +if (strcmp (driver_name,"tegra" ) ==0 ) +return pipe_tegra_create_screen (fd); + else +#endif return NULL ; }src/gallium/drivers/tegra/Automake.inc new file +11
-0@@ -0,0 +1,11 @@ +if HAVE_GALLIUM_TEGRA + +TARGET_DRIVERS += tegra +TARGET_CPPFLAGS += -DGALLIUM_TEGRA +TARGET_LIB_DEPS += \ + $(top_builddir)/src/gallium/winsys/tegra/drm/libtegradrm.la \ + $(top_builddir)/src/gallium/drivers/tegra/libtegra.la \ + $(LIBDRM_LIBS) \ + $(TEGRA_LIBS) + +endifsrc/gallium/drivers/tegra/Makefile.am new file +17
-0@@ -0,0 +1,17 @@ +AUTOMAKE_OPTIONS = subdir-objects + +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)src/gallium/drivers/tegra/Makefile.sources new file +4
-0@@ -0,0 +1,4 @@ +C_SOURCES := \ + tegra_context.c \ + tegra_resource.c \ + tegra_screen.csrc/gallium/drivers/tegra/tegra_context.c new file +699
-0@@ -0,0 +1,699 @@ +/* +* 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 <stdlib.h> + +#include "util/u_debug.h" +#include "util/u_inlines.h" + +#include "tegra/tegra_context.h" +#include "tegra/tegra_resource.h" +#include "tegra/tegra_screen.h" + +static void +tegra_destroy (struct pipe_context *pcontext) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->destroy (context->gpu); +free (context); +} + +static void +tegra_draw_vbo (struct pipe_context *pcontext, +const struct pipe_draw_info *pinfo) +{ +struct tegra_context *context =to_tegra_context (pcontext); +struct pipe_draw_info info; + +if (pinfo && pinfo->indirect) { +memcpy (&info, pinfo,sizeof (info)); + info.indirect =tegra_resource_unwrap (info.indirect); + pinfo = &info; + } + + context->gpu->draw_vbo (context->gpu, pinfo); +} + +static void * +tegra_create_blend_state (struct pipe_context *pcontext, +const struct pipe_blend_state *cso) +{ +struct tegra_context *context =to_tegra_context (pcontext); + +return context->gpu->create_blend_state (context->gpu, cso); +} + +static void +tegra_bind_blend_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->bind_blend_state (context->gpu, so); +} + +static void +tegra_delete_blend_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->delete_blend_state (context->gpu, so); +} + +static void * +tegra_create_sampler_state (struct pipe_context *pcontext, +const struct pipe_sampler_state *cso) +{ +struct tegra_context *context =to_tegra_context (pcontext); + +return context->gpu->create_sampler_state (context->gpu, cso); +} + +static void +tegra_bind_sampler_states (struct pipe_context *pcontext, +unsigned shader, +unsigned start_slot, +unsigned num_samplers, +void **samplers) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->bind_sampler_states (context->gpu, shader, start_slot, + num_samplers, samplers); +} + +static void +tegra_delete_sampler_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->delete_sampler_state (context->gpu, so); +} + +static void * +tegra_create_rasterizer_state (struct pipe_context *pcontext, +const struct pipe_rasterizer_state *cso) +{ +struct tegra_context *context =to_tegra_context (pcontext); + +return context->gpu->create_rasterizer_state (context->gpu, cso); +} + +static void +tegra_bind_rasterizer_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->bind_rasterizer_state (context->gpu, so); +} + +static void +tegra_delete_rasterizer_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->delete_rasterizer_state (context->gpu, so); +} + +static void * +tegra_create_depth_stencil_alpha_state (struct pipe_context *pcontext, +const struct pipe_depth_stencil_alpha_state *cso) +{ +struct tegra_context *context =to_tegra_context (pcontext); + +return context->gpu->create_depth_stencil_alpha_state (context->gpu, + cso); +} + +static void +tegra_bind_depth_stencil_alpha_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->bind_depth_stencil_alpha_state (context->gpu, so); +} + +static void +tegra_delete_depth_stencil_alpha_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->delete_depth_stencil_alpha_state (context->gpu, so); +} + +static void * +tegra_create_fs_state (struct pipe_context *pcontext, +const struct pipe_shader_state *cso) +{ +struct tegra_context *context =to_tegra_context (pcontext); + +return context->gpu->create_fs_state (context->gpu, cso); +} + +static void +tegra_bind_fs_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->bind_fs_state (context->gpu, so); +} + +static void +tegra_delete_fs_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->delete_fs_state (context->gpu, so); +} + +static void * +tegra_create_vs_state (struct pipe_context *pcontext, +const struct pipe_shader_state *cso) +{ +struct tegra_context *context =to_tegra_context (pcontext); + +return context->gpu->create_vs_state (context->gpu, cso); +} + +static void +tegra_bind_vs_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->bind_vs_state (context->gpu, so); +} + +static void +tegra_delete_vs_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->delete_vs_state (context->gpu, so); +} + +static void * +tegra_create_gs_state (struct pipe_context *pcontext, +const struct pipe_shader_state *cso) +{ +struct tegra_context *context =to_tegra_context (pcontext); + +return context->gpu->create_gs_state (context->gpu, cso); +} + +static void +tegra_bind_gs_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->bind_gs_state (context->gpu, so); +} + +static void +tegra_delete_gs_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->delete_gs_state (context->gpu, so); +} + +static void * +tegra_create_vertex_elements_state (struct pipe_context *pcontext, +unsigned num_elements, +const struct pipe_vertex_element *elements) +{ +struct tegra_context *context =to_tegra_context (pcontext); + +return context->gpu->create_vertex_elements_state (context->gpu, + num_elements, + elements); +} + +static void +tegra_bind_vertex_elements_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->bind_vertex_elements_state (context->gpu, so); +} + +static void +tegra_delete_vertex_elements_state (struct pipe_context *pcontext, +void *so) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->delete_vertex_elements_state (context->gpu, so); +} + +static void +tegra_set_constant_buffer (struct pipe_context *pcontext, +uint shader, +uint index, +struct pipe_constant_buffer *buf) +{ +struct tegra_context *context =to_tegra_context (pcontext); +struct pipe_constant_buffer buffer; + +if (buf && buf->buffer) { +memcpy (&buffer, buf,sizeof (buffer)); + buffer.buffer =tegra_resource_unwrap (buffer.buffer); + buf = &buffer; + } + + context->gpu->set_constant_buffer (context->gpu, shader, index, buf); +} + +static void +tegra_set_framebuffer_state (struct pipe_context *pcontext, +const struct pipe_framebuffer_state *fb) +{ +struct tegra_context *context =to_tegra_context (pcontext); +struct pipe_framebuffer_state state; +unsigned i; + +if (fb) { +memcpy (&state, fb,sizeof (state)); + +for (i =0 ; i < fb->nr_cbufs; i++) + state.cbufs[i] =tegra_surface_unwrap (fb->cbufs[i]); + +while (i <PIPE_MAX_COLOR_BUFS ) + state.cbufs[i++] =NULL ; + + state.zsbuf =tegra_surface_unwrap (fb->zsbuf); + + fb = &state; + } + + context->gpu->set_framebuffer_state (context->gpu, fb); +} + +static void +tegra_set_polygon_stipple (struct pipe_context *pcontext, +const struct pipe_poly_stipple *stipple) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->set_polygon_stipple (context->gpu, stipple); +} + +static void +tegra_set_scissor_states (struct pipe_context *pcontext, +unsigned start_slot, +unsigned num_scissors, +const struct pipe_scissor_state *scissors) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->set_scissor_states (context->gpu, start_slot, + num_scissors, scissors); +} + +static void +tegra_set_viewport_states (struct pipe_context *pcontext, +unsigned start_slot, +unsigned num_viewports, +const struct pipe_viewport_state *viewports) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->set_viewport_states (context->gpu, start_slot, + num_viewports, viewports); +} + +static void +tegra_set_sampler_views (struct pipe_context *pcontext, +unsigned shader, +unsigned start_slot, +unsigned num_views, +struct pipe_sampler_view **pviews) +{ +struct pipe_sampler_view *views[PIPE_MAX_SHADER_SAMPLER_VIEWS ]; +struct tegra_context *context =to_tegra_context (pcontext); +unsigned i; + +for (i =0 ; i < num_views; i++) + views[i] =tegra_sampler_view_unwrap (pviews[i]); + + context->gpu->set_sampler_views (context->gpu, shader, start_slot, + num_views, views); +} + +static void +tegra_set_shader_resources (struct pipe_context *pcontext, +unsigned start, +unsigned count, +struct pipe_surface **resources) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->set_shader_resources (context->gpu, start, count, + resources); +} + +static void +tegra_set_vertex_buffers (struct pipe_context *pcontext, +unsigned start_slot, +unsigned num_buffers, +const struct pipe_vertex_buffer *buffers) +{ +struct tegra_context *context =to_tegra_context (pcontext); +struct pipe_vertex_buffer buf[PIPE_MAX_SHADER_INPUTS ]; +unsigned i; + +if (num_buffers && buffers) { +memcpy (buf, buffers, num_buffers *sizeof (struct pipe_vertex_buffer )); + +for (i =0 ; i < num_buffers; i++) + buf[i].buffer =tegra_resource_unwrap (buf[i].buffer); + + buffers = buf; + } + + context->gpu->set_vertex_buffers (context->gpu, start_slot, + num_buffers, buffers); +} + +static void +tegra_set_index_buffer (struct pipe_context *pcontext, +const struct pipe_index_buffer *buffer) +{ +struct tegra_context *context =to_tegra_context (pcontext); +struct pipe_index_buffer buf; + +if (buffer) { +memcpy (&buf, buffer,sizeof (buf)); + buf.buffer =tegra_resource_unwrap (buf.buffer); + buffer = &buf; + } + + context->gpu->set_index_buffer (context->gpu, buffer); +} + +static struct pipe_stream_output_target * +tegra_create_stream_output_target (struct pipe_context *pcontext, +struct pipe_resource *presource, +unsigned buffer_offset, +unsigned buffer_size) +{ +struct tegra_resource *resource =to_tegra_resource (presource); +struct tegra_context *context =to_tegra_context (pcontext); + +return context->gpu->create_stream_output_target (context->gpu, + resource->gpu, + buffer_offset, + buffer_size); +} + +static void +tegra_stream_output_target_destroy (struct pipe_context *pcontext, +struct pipe_stream_output_target *target) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->stream_output_target_destroy (context->gpu, target); +} + +static void +tegra_set_stream_output_targets (struct pipe_context *pcontext, +unsigned num_targets, +struct pipe_stream_output_target **targets, +const unsigned *offsets) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->set_stream_output_targets (context->gpu, num_targets, + targets, offsets); +} + +static void +tegra_blit (struct pipe_context *pcontext, +const struct pipe_blit_info *pinfo) +{ +struct tegra_context *context =to_tegra_context (pcontext); +struct pipe_blit_info info; + +if (pinfo) { +memcpy (&info, pinfo,sizeof (info)); + info.dst.resource =tegra_resource_unwrap (info.dst.resource); + info.src.resource =tegra_resource_unwrap (info.src.resource); + pinfo = &info; + } + + context->gpu->blit (context->gpu, pinfo); +} + +static void +tegra_clear (struct pipe_context *pcontext, +unsigned buffers, +const union pipe_color_union *color, +double depth, +unsigned stencil) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->clear (context->gpu, buffers, color, depth, stencil); +} + +static void +tegra_flush (struct pipe_context *pcontext, +struct pipe_fence_handle **fence, +unsigned flags) +{ +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->flush (context->gpu, fence, flags); +} + +static struct pipe_sampler_view * +tegra_create_sampler_view (struct pipe_context *pcontext, +struct pipe_resource *ptexture, +const struct pipe_sampler_view *template) +{ +struct tegra_resource *texture =to_tegra_resource (ptexture); +struct tegra_context *context =to_tegra_context (pcontext); +struct tegra_sampler_view *view; + + view =calloc (1 ,sizeof (*view)); +if (!view) +return NULL ; + + view->gpu = context->gpu->create_sampler_view (context->gpu, + texture->gpu, + template); +memcpy (&view->base, view->gpu,sizeof (*view->gpu)); +/* overwrite to prevent reference from being released */ + view->base.texture =NULL ; + +pipe_reference_init (&view->base.reference,1 ); +pipe_resource_reference (&view->base.texture, ptexture); + view->base.context = pcontext; + +return &view->base; +} + +static void +tegra_sampler_view_destroy (struct pipe_context *pcontext, +struct pipe_sampler_view *pview) +{ +struct tegra_sampler_view *view =to_tegra_sampler_view (pview); + +pipe_resource_reference (&view->base.texture,NULL ); +pipe_sampler_view_reference (&view->gpu,NULL ); +free (view); +} + +static void +tegra_flush_resource (struct pipe_context *pcontext, +struct pipe_resource *presource) +{ +struct tegra_resource *resource =to_tegra_resource (presource); +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->flush_resource (context->gpu, resource->gpu); +} + +static void * +tegra_transfer_map (struct pipe_context *pcontext, +struct pipe_resource *presource, +unsigned level, +unsigned usage, +const struct pipe_box *box, +struct pipe_transfer **ptransfer) +{ +struct tegra_resource *resource =to_tegra_resource (presource); +struct tegra_context *context =to_tegra_context (pcontext); +struct tegra_transfer *transfer; + + transfer =calloc (1 ,sizeof (*transfer)); +if (!transfer) +return NULL ; + + transfer->map = context->gpu->transfer_map (context->gpu, + resource->gpu, + level, + usage, + box, + &transfer->gpu); +memcpy (&transfer->base, transfer->gpu,sizeof (*transfer->gpu)); + transfer->base.resource =NULL ; +pipe_resource_reference (&transfer->base.resource, presource); + + *ptransfer = &transfer->base; + +return transfer->map; +} + +static void +tegra_transfer_unmap (struct pipe_context *pcontext, +struct pipe_transfer *ptransfer) +{ +struct tegra_transfer *transfer =to_tegra_transfer (ptransfer); +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->transfer_unmap (context->gpu, transfer->gpu); +pipe_resource_reference (&transfer->base.resource,NULL ); +free (transfer); +} + +static void +tegra_transfer_inline_write (struct pipe_context *pcontext, +struct pipe_resource *presource, +unsigned level, +unsigned usage, +const struct pipe_box *box, +const void *data, +unsigned stride, +unsigned layer_stride) +{ +struct tegra_resource *resource =to_tegra_resource (presource); +struct tegra_context *context =to_tegra_context (pcontext); + + context->gpu->transfer_inline_write (context->gpu, resource->gpu, + level, usage, box, data, stride, + layer_stride); +} + +struct pipe_context * +tegra_context_create (struct pipe_screen *pscreen,void *priv) +{ +struct tegra_screen *screen =to_tegra_screen (pscreen); +struct tegra_context *context; + + context =calloc (1 ,sizeof (*context)); +if (!context) +return NULL ; + + context->gpu = screen->gpu->context_create (screen->gpu, priv); +if (!context->gpu) { +debug_error ("failed to create GPU context\n" ); +free (context); +return NULL ; + } + + context->base.screen = &screen->base; + context->base.priv = priv; + + context->base.destroy = tegra_destroy; + + context->base.draw_vbo = tegra_draw_vbo; + + context->base.create_blend_state = tegra_create_blend_state; + context->base.bind_blend_state = tegra_bind_blend_state; + context->base.delete_blend_state = tegra_delete_blend_state; + + context->base.create_sampler_state = tegra_create_sampler_state; + context->base.bind_sampler_states = tegra_bind_sampler_states; + context->base.delete_sampler_state = tegra_delete_sampler_state; + + context->base.create_rasterizer_state = tegra_create_rasterizer_state; + context->base.bind_rasterizer_state = tegra_bind_rasterizer_state; + context->base.delete_rasterizer_state = tegra_delete_rasterizer_state; + + context->base.create_depth_stencil_alpha_state = tegra_create_depth_stencil_alpha_state; + context->base.bind_depth_stencil_alpha_state = tegra_bind_depth_stencil_alpha_state; + context->base.delete_depth_stencil_alpha_state = tegra_delete_depth_stencil_alpha_state; + + context->base.create_fs_state = tegra_create_fs_state; + context->base.bind_fs_state = tegra_bind_fs_state; + context->base.delete_fs_state = tegra_delete_fs_state; + + context->base.create_vs_state = tegra_create_vs_state; + context->base.bind_vs_state = tegra_bind_vs_state; + context->base.delete_vs_state = tegra_delete_vs_state; + + context->base.create_gs_state = tegra_create_gs_state; + context->base.bind_gs_state = tegra_bind_gs_state; + context->base.delete_gs_state = tegra_delete_gs_state; + + context->base.create_vertex_elements_state = tegra_create_vertex_elements_state; + context->base.bind_vertex_elements_state = tegra_bind_vertex_elements_state; + context->base.delete_vertex_elements_state = tegra_delete_vertex_elements_state; + + context->base.set_constant_buffer = tegra_set_constant_buffer; + context->base.set_framebuffer_state = tegra_set_framebuffer_state; + context->base.set_polygon_stipple = tegra_set_polygon_stipple; + context->base.set_scissor_states = tegra_set_scissor_states; + context->base.set_viewport_states = tegra_set_viewport_states; + context->base.set_sampler_views = tegra_set_sampler_views; + + context->base.set_shader_resources = tegra_set_shader_resources; + context->base.set_vertex_buffers = tegra_set_vertex_buffers; + context->base.set_index_buffer = tegra_set_index_buffer; + + context->base.create_stream_output_target = tegra_create_stream_output_target; + context->base.stream_output_target_destroy = tegra_stream_output_target_destroy; + context->base.set_stream_output_targets = tegra_set_stream_output_targets; + + context->base.blit = tegra_blit; + context->base.clear = tegra_clear; + context->base.flush = tegra_flush; + + context->base.create_sampler_view = tegra_create_sampler_view; + context->base.sampler_view_destroy = tegra_sampler_view_destroy; + + context->base.flush_resource = tegra_flush_resource; + + context->base.create_surface = tegra_create_surface; + context->base.surface_destroy = tegra_surface_destroy; + + context->base.transfer_map = tegra_transfer_map; + context->base.transfer_unmap = tegra_transfer_unmap; + context->base.transfer_inline_write = tegra_transfer_inline_write; + +return &context->base; +}src/gallium/drivers/tegra/tegra_context.h new file +80
-0@@ -0,0 +1,80 @@ +/* +* 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. +*/ + +#ifndef TEGRA_CONTEXT_H +#define TEGRA_CONTEXT_H + +#include "pipe/p_context.h" +#include "pipe/p_state.h" + +struct tegra_screen ; + +struct tegra_context { +struct pipe_context base; +struct pipe_context *gpu; +}; + +static inline struct tegra_context * +to_tegra_context (struct pipe_context *context) +{ +return (struct tegra_context *)context; +} + +struct pipe_context *tegra_context_create (struct pipe_screen *pscreen, +void *priv); + +struct tegra_sampler_view { +struct pipe_sampler_view base; +struct pipe_sampler_view *gpu; +}; + +static INLINE struct tegra_sampler_view * +to_tegra_sampler_view (struct pipe_sampler_view *view) +{ +return (struct tegra_sampler_view *)view; +} + +static INLINE struct pipe_sampler_view * +tegra_sampler_view_unwrap (struct pipe_sampler_view *view) +{ +if (!view) +return NULL ; + +return to_tegra_sampler_view (view)->gpu; +} + +struct tegra_transfer { +struct pipe_transfer base; +struct pipe_transfer *gpu; + +unsigned int count; +void *map; +}; + +static INLINE struct tegra_transfer * +to_tegra_transfer (struct pipe_transfer *transfer) +{ +return (struct tegra_transfer *)transfer; +} + +#endif /* TEGRA_SCREEN_H */ src/gallium/drivers/tegra/tegra_resource.c new file +219
-0@@ -0,0 +1,219 @@ +/* +* 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 <errno.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdio.h> + +#include <drm/tegra_drm.h> +#include <xf86drm.h> + +#include "pipe/p_state.h" +#include "util/u_debug.h" +#include "util/u_format.h" +#include "util/u_inlines.h" + +#include "state_tracker/drm_driver.h" + +#include "tegra/tegra_context.h" +#include "tegra/tegra_resource.h" +#include "tegra/tegra_screen.h" + +struct pipe_resource * +tegra_resource_create (struct pipe_screen *pscreen, +const struct pipe_resource *template) +{ +struct tegra_screen *screen =to_tegra_screen (pscreen); +struct tegra_resource *resource; + + resource =calloc (1 ,sizeof (*resource)); +if (!resource) +return NULL ; + +/* import scanout buffers for display */ +if (template->bind &PIPE_BIND_SCANOUT ) { +struct drm_tegra_gem_set_tiling args; +struct winsys_handle handle; +boolean status; +int fd, err; + + resource->gpu = screen->gpu->resource_create (screen->gpu, + template); +if (!resource->gpu) + goto free; + +memset (&handle,0 ,sizeof (handle)); + handle.type =DRM_API_HANDLE_TYPE_FD ; + + status = screen->gpu->resource_get_handle (screen->gpu, + resource->gpu, + &handle); +if (!status) + goto destroy; + + resource->stride = handle.stride; + fd = handle.handle; + + err =drmPrimeFDToHandle (screen->fd, fd, &resource->handle); +if (err <0 ) { +fprintf (stderr,"drmPrimeFDToHandle() failed: %s\n" , +strerror (errno)); +close (fd); + goto destroy; + } + +close (fd); + +memset (&args,0 ,sizeof (args)); + args.handle = resource->handle; + args.mode =DRM_TEGRA_GEM_TILING_MODE_BLOCK ; + args.value =4 ; + + err =drmIoctl (screen->fd,DRM_IOCTL_TEGRA_GEM_SET_TILING , + &args); +if (err <0 ) { +fprintf (stderr,"failed to set tiling parameters: %s\n" , +strerror (errno)); + goto destroy; + } + }else { + resource->gpu = screen->gpu->resource_create (screen->gpu, + template); +if (!resource->gpu) + goto free; + } + +memcpy (&resource->base, resource->gpu,sizeof (*resource->gpu)); +pipe_reference_init (&resource->base.reference,1 ); + resource->base.screen = &screen->base; + +return &resource->base; + +destroy: + screen->gpu->resource_destroy (screen->gpu, resource->gpu); +free: +free (resource); +return NULL ; +} + +struct pipe_resource * +tegra_resource_from_handle (struct pipe_screen *pscreen, +const struct pipe_resource *template, +struct winsys_handle *handle) +{ +struct tegra_screen *screen =to_tegra_screen (pscreen); +struct tegra_resource *resource; + + resource =calloc (1 ,sizeof (*resource)); +if (!resource) +return NULL ; + + resource->gpu = screen->gpu->resource_from_handle (screen->gpu, + template, + handle); +if (!resource->gpu) { +free (resource); +return NULL ; + } + +memcpy (&resource->base, resource->gpu,sizeof (*resource->gpu)); +pipe_reference_init (&resource->base.reference,1 ); + resource->base.screen = &screen->base; + +return &resource->base; +} + +boolean +tegra_resource_get_handle (struct pipe_screen *pscreen, +struct pipe_resource *presource, +struct winsys_handle *handle) +{ +struct tegra_resource *resource =to_tegra_resource (presource); +struct tegra_screen *screen =to_tegra_screen (pscreen); +boolean ret = TRUE; + +if (presource->bind &PIPE_BIND_SCANOUT ) { + handle->handle = resource->handle; + handle->stride = resource->stride; + }else { + ret = screen->gpu->resource_get_handle (screen->gpu, + resource->gpu, + handle); + } + +return ret; +} + +void +tegra_resource_destroy (struct pipe_screen *pscreen, +struct pipe_resource *presource) +{ +struct tegra_resource *resource =to_tegra_resource (presource); + +pipe_resource_reference (&resource->gpu,NULL ); +free (resource); +} + +struct pipe_surface * +tegra_create_surface (struct pipe_context *pcontext, +struct pipe_resource *presource, +const struct pipe_surface *template) +{ +struct tegra_resource *resource =to_tegra_resource (presource); +struct tegra_context *context =to_tegra_context (pcontext); +struct tegra_surface *surface; + + surface =calloc (1 ,sizeof (*surface)); +if (!surface) +return NULL ; + + surface->gpu = context->gpu->create_surface (context->gpu, + resource->gpu, + template); +if (!surface->gpu) { +free (surface); +return NULL ; + } + +memcpy (&surface->base, surface->gpu,sizeof (*surface->gpu)); +/* overwrite to prevent reference from being released */ + surface->base.texture =NULL ; + +pipe_reference_init (&surface->base.reference,1 ); +pipe_resource_reference (&surface->base.texture, presource); + surface->base.context = &context->base; + +return &surface->base; +} + +void +tegra_surface_destroy (struct pipe_context *pcontext, +struct pipe_surface *psurface) +{ +struct tegra_surface *surface =to_tegra_surface (psurface); + +pipe_resource_reference (&surface->base.texture,NULL ); +pipe_surface_reference (&surface->gpu,NULL ); +free (surface); +}src/gallium/drivers/tegra/tegra_resource.h new file +98
-0@@ -0,0 +1,98 @@ +/* +* 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. +*/ + +#ifndef TEGRA_RESOURCE_H +#define TEGRA_RESOURCE_H + +#include "pipe/p_state.h" + +struct winsys_handle ; + +struct tegra_resource { +struct pipe_resource base; +struct pipe_resource *gpu; + +uint32_t stride; +uint32_t handle; +size_t size; +}; + +static INLINE struct tegra_resource * +to_tegra_resource (struct pipe_resource *resource) +{ +return (struct tegra_resource *)resource; +} + +static INLINE struct pipe_resource * +tegra_resource_unwrap (struct pipe_resource *resource) +{ +if (!resource) +return NULL ; + +return to_tegra_resource (resource)->gpu; +} + +struct pipe_resource * +tegra_resource_create (struct pipe_screen *pscreen, +const struct pipe_resource *template); +struct pipe_resource * +tegra_resource_from_handle (struct pipe_screen *pscreen, +const struct pipe_resource *template, +struct winsys_handle *handle); +boolean +tegra_resource_get_handle (struct pipe_screen *pscreen, +struct pipe_resource *resource, +struct winsys_handle *handle); +void +tegra_resource_destroy (struct pipe_screen *pscreen, +struct pipe_resource *resource); + +struct tegra_surface { +struct pipe_surface base; +struct pipe_surface *gpu; +}; + +static INLINE struct tegra_surface * +to_tegra_surface (struct pipe_surface *surface) +{ +return (struct tegra_surface *)surface; +} + +static INLINE struct pipe_surface * +tegra_surface_unwrap (struct pipe_surface *surface) +{ +if (!surface) +return NULL ; + +return to_tegra_surface (surface)->gpu; +} + +struct pipe_surface * +tegra_create_surface (struct pipe_context *pcontext, +struct pipe_resource *presource, +const struct pipe_surface *template); +void +tegra_surface_destroy (struct pipe_context *pcontext, +struct pipe_surface *psurface); + +#endif /* TEGRA_RESOURCE_H */ src/gallium/drivers/tegra/tegra_screen.c new file +311
-0@@ -0,0 +1,311 @@ +/* +* 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 <errno.h> +#include <fcntl.h> +#include <stdio.h> + +#ifdef HAVE_LIBUDEV +#include <libudev.h> +#endif + +#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); + +static const char * +tegra_get_name (struct pipe_screen *pscreen) +{ +return "tegra" ; +} + +static const char * +tegra_get_vendor (struct pipe_screen *pscreen) +{ +return "tegra" ; +} + +static void tegra_screen_destroy (struct pipe_screen *pscreen) +{ +struct tegra_screen *screen =to_tegra_screen (pscreen); + + screen->gpu->destroy (screen->gpu); +free (pscreen); +} + +static int +tegra_screen_get_param (struct pipe_screen *pscreen,enum pipe_cap param) +{ +struct tegra_screen *screen =to_tegra_screen (pscreen); + +return screen->gpu->get_param (screen->gpu, param); +} + +static float +tegra_screen_get_paramf (struct pipe_screen *pscreen,enum pipe_capf param) +{ +struct tegra_screen *screen =to_tegra_screen (pscreen); + +return screen->gpu->get_paramf (screen->gpu, param); +} + +static int +tegra_screen_get_shader_param (struct pipe_screen *pscreen, +unsigned shader, +enum pipe_shader_cap param) +{ +struct tegra_screen *screen =to_tegra_screen (pscreen); + +return screen->gpu->get_shader_param (screen->gpu, shader, param); +} + +static boolean +tegra_screen_is_format_supported (struct pipe_screen *pscreen, +enum pipe_format format, +enum pipe_texture_target target, +unsigned sample_count, +unsigned usage) +{ +struct tegra_screen *screen =to_tegra_screen (pscreen); + +return screen->gpu->is_format_supported (screen->gpu, format, target, + sample_count, usage); +} + +static void +tegra_fence_reference (struct pipe_screen *pscreen, +struct pipe_fence_handle **ptr, +struct pipe_fence_handle *fence) +{ +struct tegra_screen *screen =to_tegra_screen (pscreen); + + screen->gpu->fence_reference (screen->gpu, ptr, fence); +} + +static boolean +tegra_fence_signalled (struct pipe_screen *pscreen, +struct pipe_fence_handle *fence) +{ +struct tegra_screen *screen =to_tegra_screen (pscreen); + +return screen->gpu->fence_signalled (screen->gpu, fence); +} + +static boolean +tegra_fence_finish (struct pipe_screen *pscreen, +struct pipe_fence_handle *fence, +uint64_t timeout) +{ +struct tegra_screen *screen =to_tegra_screen (pscreen); + +return screen->gpu->fence_finish (screen->gpu, fence, timeout); +} + +static struct udev_device *udev_device_new_from_fd (struct udev *udev,int fd) +{ +struct udev_device *device; +struct stat stat; +int err; + + err =fstat (fd, &stat); +if (err <0 ) { +fprintf (stderr,"fstat() failed: %s\n" ,strerror (errno)); +return NULL ; + } + + device =udev_device_new_from_devnum (udev,'c' , stat.st_rdev); +if (!device) { +fprintf (stderr,"udev_device_new_from_devnum() failed\n" ); +return NULL ; + } + +return device; +} + +static struct udev_device *udev_device_get_root (struct udev_device *device) +{ +struct udev_device *parent; + +while (true) { + parent =udev_device_get_parent (device); +if (!parent) +break ; + + device = parent; + } + +return device; +} + +static bool udev_device_match (struct udev_device *x,struct udev_device *y) +{ +const char *p1 =udev_device_get_syspath (x); +const char *p2 =udev_device_get_syspath (y); + +return strcmp (p1, p2) ==0 ; +} + +static int tegra_open_render_node (int fd) +{ +struct udev_device *display, *parent, *root; +struct udev_list_entry *list, *entry; +struct udev_enumerate *enumerate; +struct udev *udev; + + udev =udev_new (); +if (!udev) +return -ENOMEM ; + + display =udev_device_new_from_fd (udev, fd); +if (!display) { +udev_unref (udev); +return -ENODEV ; + } + + parent =udev_device_get_parent (display); +if (!parent) { +udev_device_unref (display); +udev_unref (udev); +return -ENODEV ; + } + + display = parent; + + root =udev_device_get_root (display); +if (!root) { +udev_device_unref (display); +udev_unref (udev); +return -ENODEV ; + } + + enumerate =udev_enumerate_new (udev); +if (!enumerate) { +udev_device_unref (display); +udev_unref (udev); +return -ENOMEM ; + } + +udev_enumerate_add_match_subsystem (enumerate,"drm" ); +udev_enumerate_add_match_sysname (enumerate,"render*" ); +udev_enumerate_scan_devices (enumerate); + + list =udev_enumerate_get_list_entry (enumerate); + + 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 ); +if (fd <0 ) + fd = -errno; + +break ; + } + } + +udev_enumerate_unref (enumerate); +udev_unref (udev); + +return open ("/dev/dri/renderD128" ,O_RDWR ); +} + +struct pipe_screen * +tegra_screen_create (int fd) +{ +struct tegra_screen *screen; + + screen =calloc (1 ,sizeof (*screen)); +if (!screen) +return NULL ; + + screen->fd = fd; + + screen->gpu_fd =tegra_open_render_node (screen->fd); +if (screen->gpu_fd <0 ) { +fprintf (stderr,"failed to open GPU device: %s\n" , +strerror (errno)); +free (screen); +return NULL ; + } + + screen->gpu =nouveau_drm_screen_create (screen->gpu_fd); +if (!screen->gpu) { +fprintf (stderr,"failed to create GPU screen\n" ); +close (screen->gpu_fd); +free (screen); +return NULL ; + } + + screen->base.get_name = tegra_get_name; + screen->base.get_vendor = tegra_get_vendor; + screen->base.destroy = tegra_screen_destroy; + screen->base.get_param = tegra_screen_get_param; + screen->base.get_paramf = tegra_screen_get_paramf; + screen->base.get_shader_param = tegra_screen_get_shader_param; + screen->base.context_create = tegra_context_create; + screen->base.is_format_supported = tegra_screen_is_format_supported; + + screen->base.resource_create = tegra_resource_create; + screen->base.resource_from_handle = tegra_resource_from_handle; + screen->base.resource_get_handle = tegra_resource_get_handle; + screen->base.resource_destroy = tegra_resource_destroy; + + screen->base.fence_reference = tegra_fence_reference; + screen->base.fence_signalled = tegra_fence_signalled; + screen->base.fence_finish = tegra_fence_finish; + +return &screen->base; +}src/gallium/drivers/tegra/tegra_screen.h new file +45
-0@@ -0,0 +1,45 @@ +/* +* 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. +*/ + +#ifndef TEGRA_SCREEN_H +#define TEGRA_SCREEN_H + +#include "pipe/p_screen.h" + +struct tegra_screen { +struct pipe_screen base; +int fd; + +struct pipe_screen *gpu; +int gpu_fd; +}; + +static inline struct tegra_screen * +to_tegra_screen (struct pipe_screen *pscreen) +{ +return (struct tegra_screen *)pscreen; +} + +struct pipe_screen *tegra_screen_create (int fd); + +#endif /* TEGRA_SCREEN_H */ src/gallium/targets/dri/Makefile.am +2
-0@@ -83,6 +83,8 @@ include $(top_srcdir)/src/gallium/drivers/svga/Automake.inc include $(top_srcdir)/src/gallium/drivers/freedreno/Automake.inc +include $(top_srcdir)/src/gallium/drivers/tegra/Automake.inc + include $(top_srcdir)/src/gallium/drivers/vc4/Automake.inc include $(top_srcdir)/src/gallium/drivers/softpipe/Automake.incsrc/gallium/winsys/tegra/drm/Makefile.am new file +11
-0@@ -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) + +noinst_LTLIBRARIES = libtegradrm.la + +libtegradrm_la_SOURCES = $(C_SOURCES)src/gallium/winsys/tegra/drm/Makefile.sources new file +2
-0@@ -0,0 +1,2 @@ +C_SOURCES := \ + tegra_drm_winsys.csrc/gallium/winsys/tegra/drm/tegra_drm_public.h new file +31
-0@@ -0,0 +1,31 @@ +/* +* 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. +*/ + +#ifndef __TEGRA_DRM_PUBLIC_H__ +#define __TEGRA_DRM_PUBLIC_H__ + +struct pipe_screen ; + +struct pipe_screen *tegra_drm_screen_create (int fd); + +#endif /* __TEGRA_DRM_PUBLIC_H__ */ src/gallium/winsys/tegra/drm/tegra_drm_winsys.c new file +33
-1@@ -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); + +struct pipe_screen *tegra_drm_screen_create (int fd) +{ +return tegra_screen_create (fd); +} --2.1.3
Quoted 4 lines
_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau
A message that is not in the archive (sent off-list or not yet received): CAF6AEGuf9d_U7NpS2z-4_UTk=9cY3HX+FYpS-JYv_FagZBVG5A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Quoted 24 lines · Rob Clark
Quoted 13 lines · Thierry Reding
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.
Quoted 8 lines
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
- implement enough support to seamlessly integrate with X
- refactor some of the code to be reusable by other drivers
Quoted 4 lines
I haven't looked too carefully at the implementation yet, but couldn't you just put in src/gallium/drivers/shim ? I guess you'd just want a small if/else ladder where you create the *actual* screen, to create a nouveau screen for tegra, an etnaviv screen for imx, armada, etc..?
That's not how Mesa's loader works. Typically only a file descriptor is passed in and helpers determine a name for the driver to load, then the DRI code will load <name>_dri.so. I don't see how this could be made to work with a single Gallium driver.
There's also the fact that these drivers need to become very HW-specific at some point, so sharing a single driver will likely just cause an explosion of conditionals to special-case for each and everyone of the drivers.
Lastly, Tegra is also somewhat special in this regard because earlier generations did have a GPU that's controlled via the same DRM device as the display part. If ever a Mesa driver shows up for that older GPU we are going to have a conflict between the shim and the Tegra driver that isn't going to be easy to untangle. With a separate driver we can use SoC-specific knowledge to determine whether the driver is running on an old SoC generation or Tegra K1 and later.
Thierry
_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau
Quoted 13 lines · Thierry Reding
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.
Quoted 3 lines
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.
Tested with kmscube and Weston and I can confirm this works. However, EGL clients inside Weston have their window filled with garbage (they seem to run fine otherwise). Do you also experience this?
_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 14 lines · Alexandre Courbot
Quoted 13 lines · Thierry Reding
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.
Quoted 7 lines
Quoted 3 lines
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.
Tested with kmscube and Weston and I can confirm this works. However, EGL clients inside Weston have their window filled with garbage (they seem to run fine otherwise). Do you also experience this?
To be honest, that wasn't part of my set of test cases. I had assumed that since Weston could composite buffers into a final scan out buffer everything else would just work as well. Do you have any particular demos that aren't working?
Thierry
_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau
Quoted 19 lines · Thierry Reding
Quoted 18 lines · Alexandre Courbot
Quoted 16 lines · Thierry Reding
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.
Quoted 8 lines
Quoted 3 lines
Tested with kmscube and Weston and I can confirm this works. However, EGL clients inside Weston have their window filled with garbage (they seem to run fine otherwise). Do you also experience this?
To be honest, that wasn't part of my set of test cases. I had assumed that since Weston could composite buffers into a final scan out buffer everything else would just work as well. Do you have any particular demos that aren't working?
Anything using EGL under Wayland - the simplest case would be weston-simple-egl. glmark2 also displays a broken window, but then crashes shortly after. With weston-simpe-egl I get the framerate feedback and can see the GPU performance counters moving as expected, indicating that the app is rendering correctly but that Weston gets the wrong buffer to display.
_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau
Quoted 30 lines · Alexandre Courbot
Quoted 19 lines · Thierry Reding
Quoted 18 lines · Alexandre Courbot
Quoted 16 lines · Thierry Reding
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.
Quoted 8 lines
Quoted 3 lines
Tested with kmscube and Weston and I can confirm this works. However, EGL clients inside Weston have their window filled with garbage (they seem to run fine otherwise). Do you also experience this?
To be honest, that wasn't part of my set of test cases. I had assumed that since Weston could composite buffers into a final scan out buffer everything else would just work as well. Do you have any particular demos that aren't working?
Quoted 6 lines
Anything using EGL under Wayland - the simplest case would be weston-simple-egl. glmark2 also displays a broken window, but then crashes shortly after. With weston-simpe-egl I get the framerate feedback and can see the GPU performance counters moving as expected, indicating that the app is rendering correctly but that Weston gets the wrong buffer to display.
Okay, I'll need to look into this more closely. Thanks for reporting.
Thierry
_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Quoted 17 lines · Thierry Reding
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.
Quoted 6 lines
TODO:
- use Nouveau headers to get at the prototype for creating a screen
- implement enough support to seamlessly integrate with X
- refactor some of the code to be reusable by other driversSigned-off-by Thierry Reding <[email protected]>
With the exception of resource creation, I don't see anything tegra-specific in here. Is there perhaps something that could be done to abstract that a little more, e.g. a wrapper driver, or... something? This is a situation that several mobile GPU's are in, AFAIK, and it may be nice to make it work for them as well.
Also, can you explain why it's advantageous for the setup to appear as though it is a single device? i.e. what's wrong with just using nouveau as a render node or whatever? [The answer may be simple, but I'm very unfamiliar with a lot of that stuff, and perhaps others are in a similar predicament.]
src/gallium/winsys/tegra/drm/Makefile.am line 7
Quoted 13 lines
src/gallium/winsys/tegra/drm/Makefile.am new file +7
-0@@ -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)
oops?
src/gallium/winsys/tegra/drm/Makefile.am line 11
Quoted 4 lines
src/gallium/winsys/tegra/drm/Makefile.am new file +4
-0+ +noinst_LTLIBRARIES = libtegradrm.la + +libtegradrm_la_SOURCES = $(C_SOURCES)
_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Quoted 24 lines · Ilia Mirkin
Quoted 22 lines · Thierry Reding
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
- implement enough support to seamlessly integrate with X
- refactor some of the code to be reusable by other drivers
Quoted 7 lines
Quoted 1 line
Signed-off-by Thierry Reding <[email protected]>With the exception of resource creation, I don't see anything tegra-specific in here. Is there perhaps something that could be done to abstract that a little more, e.g. a wrapper driver, or... something? This is a situation that several mobile GPU's are in, AFAIK, and it may be nice to make it work for them as well.
I think it might be possible to factor out some things to reduce some amount of boilerplate, but I don't expect it to be very much. There is likely going to be hardware-specific details in each of these drivers that will be hard to abstract out.
Given that this is the first driver of this sort I have no idea what other drivers will require, so it doesn't seem wise for me to make this any more generic. It's very likely to turn out completely wrong. Hence why I opted for just a straight implementation that would work on Tegra.
That said, if it turns out that drivers for other SoCs need to duplicate a lot of the code in this driver I'm sure we can find ways to alleviate some of that. But like I already said in my reply to Rob, I don't think a common wrapper driver is going to cut it. Perhaps something like the u_transfer abstraction could work, but there is potential for that to turn into a midlayer of sorts and actually make things more difficult.
The bottom-line is that the vast majority of the code is really just a skeleton driver, so it's not unlike any of the existing drivers. Requiring this particular driver to be common for all "mobile" SoCs is a little like saying that Radeon and Nouveau should share code because they both use PCI as the transport.
Quoted 5 lines
Also, can you explain why it's advantageous for the setup to appear as though it is a single device? i.e. what's wrong with just using nouveau as a render node or whatever? [The answer may be simple, but I'm very unfamiliar with a lot of that stuff, and perhaps others are in a similar predicament.]
There are two reasons. For one, pretty much every software out there that runs on the "bare metal" (i.e. GBM) uses the same initialization sequence and it doesn't involve opening two DRM devices. So in order to support Tegra and other SoCs with a similar architecture, each of these applications would need to be patched. Now typically a lot of the applications would run under X or Wayland, so the number of applications that need patching is somewhat reduced. However, it would still mean that every Wayland compositor would need to be patched in order to support this, and each of them would use a mostly identical copy of that code.
The second reason derives from the first. One of the issues I ran into when I prototyped the dual-fd code for kmscube was that the code to share these buffers between GPU and display is in fact highly hardware- specific. At least on Tegra it is, because we can take advantage of the tight coupling between GPU and display by directly scanning out block- linear buffers. For that to work we need to make assumptions and that just doesn't work generically.
So we need to solve two problems: reduce code duplication and hide the hardware specific details. The natural solution for these two problems is to move the code into a library. But we already have that library:
Mesa/GBM.
Quoted 7 lines
Quoted 7 lines
src/gallium/winsys/tegra/drm/Makefile.am new file +1
-0@@ -0,0 +1,11 @@ +include Makefile.sources
Quoted 8 lines
src/gallium/winsys/tegra/drm/Makefile.am line 7
Quoted 6 lines
src/gallium/winsys/tegra/drm/Makefile.am new file +6
-0+include $(top_srcdir)/src/gallium/Automake.inc + +AM_CFLAGS = \ + -I$(top_srcdir)/src/gallium/drivers \ + $(GALLIUM_WINSYS_CFLAGS) \ + $(FREEDRENO_CFLAGS)oops?
Yes, I wanted to make it obvious from where I copied. =) Good catch, thanks.
Thierry
_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Hi,
Quoted 7 lines · Thierry Reding
On Fri, Nov 28, 2014 at 12:32:43AM -0500, Ilia Mirkin wrote:> Also, can you explain why it's advantageous for the setup to appear as
Quoted 4 lines
though it is a single device? i.e. what's wrong with just using nouveau as a render node or whatever? [The answer may be simple, but I'm very unfamiliar with a lot of that stuff, and perhaps others are in a similar predicament.]
Quoted 11 lines
There are two reasons. For one, pretty much every software out there that runs on the "bare metal" (i.e. GBM) uses the same initialization sequence and it doesn't involve opening two DRM devices. So in order to support Tegra and other SoCs with a similar architecture, each of these applications would need to be patched. Now typically a lot of the applications would run under X or Wayland, so the number of applications that need patching is somewhat reduced. However, it would still mean that every Wayland compositor would need to be patched in order to support this, and each of them would use a mostly identical copy of that code.
More specifically, the gbm/EGL API works thusly:
drm_fd = drmOpen("display_controller");
gbm_dev = gbm_create_device(drm_fd);
egl_dpy = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_EXT, gbm_dev, NULL);
So in the last stage, you have to magically infer a relationship between your display controller's device and your GPU's. On most mobile devices you can just work this out (there's only one GPU), but it also breaks in the multi-GPU case.
The best idea I've come up with to fix this in the long term, is to use EGL_EXT_device_base to enumerate the GPUs and then feed the device ID you get from that as a new attrib to eglGetPlatformDisplayEXT. It's either that, or a new gbm_device_create_multi(display_controller_fd, gpu_fd) entrypoint.
Of course, the first complication in all of this is that Weston doesn't support platform_base at all anyway ...
Cheers,
Daniel
_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau
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.
Quoted 13 lines · Thierry Reding
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.
Quoted 6 lines
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 :)
Quoted 2 lines
- 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.
Quoted 39 lines
Signed-off-by Thierry Reding <[email protected]>--- 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.cconfigure.ac +0
-0
[...]
configure.ac if test -n "$with_gallium_drivers"; then · line 1946
Quoted 10 lines
configure.ac +6
-0@@ -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
[...]
src/gallium/drivers/tegra/Makefile.am line 2
Quoted 8 lines
src/gallium/drivers/tegra/Makefile.am new file +2
-0@@ -0,0 +1,17 @@ +AUTOMAKE_OPTIONS = subdir-objects +
Don't think you need the AUTOMAKE_OPTIONS here.
Quoted 5 lines
src/gallium/drivers/tegra/Makefile.am new file +5
-0+include Makefile.sources +include $(top_srcdir)/src/gallium/Automake.inc + +AM_CFLAGS = \ + $(GALLIUM_DRIVER_CFLAGS) \
src/gallium/drivers/tegra/Makefile.am line 17
Quoted 10 lines
src/gallium/drivers/tegra/Makefile.am new file +10
-0+ $(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.
src/gallium/drivers/tegra/Makefile.sources line 4
Quoted 10 lines
src/gallium/drivers/tegra/Makefile.sources new file +4
-0@@ -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.
[...]
Quoted 5 lines
src/gallium/drivers/tegra/tegra_resource.c new file +0
-0
[...]
Quoted 1 line
+#include <
drm/tegra_drm.h>
Please drop the "drm/" part.
Quoted 5 lines
src/gallium/drivers/tegra/tegra_screen.c new file +0
-0
[...]
src/gallium/drivers/tegra/tegra_screen.c line 31
Quoted 4 lines
src/gallium/drivers/tegra/tegra_screen.c new file +4
-0+#ifdef HAVE_LIBUDEV +#include <libudev.h> +#endif +
You might as well drop the #ifdef here. Afaics you're using udev API explicitly below.
src/gallium/drivers/tegra/tegra_screen.c line 40
Quoted 9 lines
src/gallium/drivers/tegra/tegra_screen.c new file +9
-0+#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" ?
src/gallium/drivers/tegra/tegra_screen.c line 44
Quoted 4 lines
src/gallium/drivers/tegra/tegra_screen.c new file +4
-0+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 :)
src/gallium/drivers/tegra/tegra_screen.c line 50
Quoted 6 lines
src/gallium/drivers/tegra/tegra_screen.c new file +6
-0+} + +static const char * +tegra_get_vendor (struct pipe_screen *pscreen) +{ +return "tegra" ;
Provide both vendors similar to above ? "NVIDIA Corp + nouveau" :P
[...]
Quoted 2 lines
src/gallium/drivers/tegra/tegra_screen.c new file +2
-0+static int tegra_open_render_node (int fd) +{
[...]
Quoted 23 lines
src/gallium/drivers/tegra/tegra_screen.c new file +23
-0+ 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 ; + } +
src/gallium/drivers/tegra/tegra_screen.c line 251
Quoted 10 lines
src/gallium/drivers/tegra/tegra_screen.c new file +10
-0+ 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.
Quoted 13 lines
src/gallium/drivers/tegra/tegra_screen.c new file +13
-0+if (fd <0 ) + fd = -errno; + +break ; + } + } + +udev_enumerate_unref (enumerate); +udev_unref (udev); + +return open ("/dev/dri/renderD128" ,O_RDWR ); +} +
[...]
Quoted 6 lines
src/gallium/winsys/tegra/drm/Makefile.am new file +0
-0
src/gallium/winsys/tegra/drm/Makefile.am line 8
Quoted 8 lines
src/gallium/winsys/tegra/drm/Makefile.am new file +8
-0@@ -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 ?
src/gallium/winsys/tegra/drm/Makefile.sources line 2
Quoted 11 lines
src/gallium/winsys/tegra/drm/Makefile.am new file +3
-0+noinst_LTLIBRARIES = libtegradrm.la + +libtegradrm_la_SOURCES = $(C_SOURCES)src/gallium/winsys/tegra/drm/Makefile.sources new file +2
-0@@ -0,0 +1,2 @@ +C_SOURCES := \ + tegra_drm_winsys.c
Please add tegra_drm_public.h to the list.
[...]
Quoted 25 lines
src/gallium/winsys/tegra/drm/tegra_drm_winsys.c new file +19
-0@@ -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
src/gallium/winsys/tegra/drm/tegra_drm_winsys.c line 29
Quoted 10 lines
src/gallium/winsys/tegra/drm/tegra_drm_winsys.c new file +10
-0+* 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
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev