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.

Some fixes contributed by Hector Martin <marcan@marcan.st>.

Changes in v2:
- duplicate file descriptor in winsys to avoid potential issues
- require nouveau when building the tegra driver
- check for nouveau driver name on render node
- remove unneeded dependency on libdrm_tegra
- remove zombie references to libudev
- add missing headers to C_SOURCES variable
- drop unneeded tegra/ prefix for includes
- open device files with O_CLOEXEC
- update copyrights

Changes in v3:
- properly unwrap resources in ->resource_copy_region()
- support vertex buffers passed by user pointer
- allocate custom stream and const uploader
- silence error message on pre-Tegra124
- support X without explicit PRIME

Changes in v4:
- ship Meson build files in distribution tarball
- drop duplicate driver_tegra dependency

Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Acked-by: Emil Velikov <emil.velikov@collabora.com>
Tested-by: Andre Heider <a.heider@gmail.com>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
Thierry Reding 2014-05-28 00:36:48 +02:00 committed by Thierry Reding
parent 2052dbdae3
commit 1755f608f5
26 changed files with 2770 additions and 4 deletions

View File

@ -1357,7 +1357,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,nouveau,r300,r600,radeonsi,freedreno,pl111,svga,swrast,swr,vc4,vc5,virgl,etnaviv,imx"
"i915,nouveau,r300,r600,radeonsi,freedreno,pl111,svga,swrast,swr,tegra,vc4,vc5,virgl,etnaviv,imx"
@<:@default=r300,r600,svga,swrast@:>@])],
[with_gallium_drivers="$withval"],
[with_gallium_drivers="$GALLIUM_DRIVERS_DEFAULT"])
@ -2631,6 +2631,10 @@ if test -n "$with_gallium_drivers"; then
ximx)
HAVE_GALLIUM_IMX=yes
;;
xtegra)
HAVE_GALLIUM_TEGRA=yes
require_libdrm "tegra"
;;
xswrast)
HAVE_GALLIUM_SOFTPIPE=yes
if test "x$enable_llvm" = xyes; then
@ -2755,6 +2759,9 @@ if test "x$HAVE_GALLIUM_VC4" != xyes -a "x$HAVE_GALLIUM_PL111" = xyes ; then
AC_MSG_ERROR([Building with pl111 requires vc4])
fi
if test "x$HAVE_GALLIUM_NOUVEAU" != xyes -a "x$HAVE_GALLIUM_TEGRA" = xyes; then
AC_MSG_ERROR([Building with tegra requires nouveau])
fi
detect_old_buggy_llvm() {
dnl llvm-config may not give the right answer when llvm is a built as a
@ -2854,6 +2861,7 @@ 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_ETNAVIV, test "x$HAVE_GALLIUM_ETNAVIV" = xyes)
AM_CONDITIONAL(HAVE_GALLIUM_IMX, test "x$HAVE_GALLIUM_IMX" = 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_SWR, test "x$HAVE_GALLIUM_SWR" = xyes)
@ -3006,6 +3014,7 @@ AC_CONFIG_FILES([Makefile
src/gallium/drivers/softpipe/Makefile
src/gallium/drivers/svga/Makefile
src/gallium/drivers/swr/Makefile
src/gallium/drivers/tegra/Makefile
src/gallium/drivers/trace/Makefile
src/gallium/drivers/etnaviv/Makefile
src/gallium/drivers/imx/Makefile
@ -3056,6 +3065,7 @@ AC_CONFIG_FILES([Makefile
src/gallium/winsys/sw/null/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/gallium/winsys/vc5/drm/Makefile
src/gallium/winsys/virgl/drm/Makefile

View File

@ -0,0 +1,225 @@
/*
* Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _TEGRA_DRM_H_
#define _TEGRA_DRM_H_
#include "drm.h"
#if defined(__cplusplus)
extern "C" {
#endif
#define DRM_TEGRA_GEM_CREATE_TILED (1 << 0)
#define DRM_TEGRA_GEM_CREATE_BOTTOM_UP (1 << 1)
struct drm_tegra_gem_create {
__u64 size;
__u32 flags;
__u32 handle;
};
struct drm_tegra_gem_mmap {
__u32 handle;
__u32 pad;
__u64 offset;
};
struct drm_tegra_syncpt_read {
__u32 id;
__u32 value;
};
struct drm_tegra_syncpt_incr {
__u32 id;
__u32 pad;
};
struct drm_tegra_syncpt_wait {
__u32 id;
__u32 thresh;
__u32 timeout;
__u32 value;
};
#define DRM_TEGRA_NO_TIMEOUT (0xffffffff)
struct drm_tegra_open_channel {
__u32 client;
__u32 pad;
__u64 context;
};
struct drm_tegra_close_channel {
__u64 context;
};
struct drm_tegra_get_syncpt {
__u64 context;
__u32 index;
__u32 id;
};
struct drm_tegra_get_syncpt_base {
__u64 context;
__u32 syncpt;
__u32 id;
};
struct drm_tegra_syncpt {
__u32 id;
__u32 incrs;
};
struct drm_tegra_cmdbuf {
__u32 handle;
__u32 offset;
__u32 words;
__u32 pad;
};
struct drm_tegra_reloc {
struct {
__u32 handle;
__u32 offset;
} cmdbuf;
struct {
__u32 handle;
__u32 offset;
} target;
__u32 shift;
__u32 pad;
};
struct drm_tegra_waitchk {
__u32 handle;
__u32 offset;
__u32 syncpt;
__u32 thresh;
};
#define DRM_TEGRA_FENCE_WAIT (1 << 0)
#define DRM_TEGRA_FENCE_EMIT (1 << 1)
#define DRM_TEGRA_FENCE_FD (1 << 2)
#define DRM_TEGRA_FENCE_FLAGS (DRM_TEGRA_FENCE_WAIT | \
DRM_TEGRA_FENCE_EMIT | \
DRM_TEGRA_FENCE_FD)
struct drm_tegra_fence {
__u32 handle;
__u32 flags;
};
#define DRM_TEGRA_SUBMIT_FLAGS 0
struct drm_tegra_submit {
__u64 context;
__u32 num_syncpts;
__u32 num_cmdbufs;
__u32 num_relocs;
__u32 num_waitchks;
__u32 waitchk_mask;
__u32 timeout;
__u64 syncpts;
__u64 cmdbufs;
__u64 relocs;
__u64 waitchks;
__u32 flags;
__u32 num_fences;
__u64 fences;
__u32 reserved[2]; /* future expansion */
};
#define DRM_TEGRA_GEM_TILING_MODE_PITCH 0
#define DRM_TEGRA_GEM_TILING_MODE_TILED 1
#define DRM_TEGRA_GEM_TILING_MODE_BLOCK 2
struct drm_tegra_gem_set_tiling {
/* input */
__u32 handle;
__u32 mode;
__u32 value;
__u32 pad;
};
struct drm_tegra_gem_get_tiling {
/* input */
__u32 handle;
/* output */
__u32 mode;
__u32 value;
__u32 pad;
};
#define DRM_TEGRA_GEM_BOTTOM_UP (1 << 0)
#define DRM_TEGRA_GEM_FLAGS (DRM_TEGRA_GEM_BOTTOM_UP)
struct drm_tegra_gem_set_flags {
/* input */
__u32 handle;
/* output */
__u32 flags;
};
struct drm_tegra_gem_get_flags {
/* input */
__u32 handle;
/* output */
__u32 flags;
};
#define DRM_TEGRA_GEM_CREATE 0x00
#define DRM_TEGRA_GEM_MMAP 0x01
#define DRM_TEGRA_SYNCPT_READ 0x02
#define DRM_TEGRA_SYNCPT_INCR 0x03
#define DRM_TEGRA_SYNCPT_WAIT 0x04
#define DRM_TEGRA_OPEN_CHANNEL 0x05
#define DRM_TEGRA_CLOSE_CHANNEL 0x06
#define DRM_TEGRA_GET_SYNCPT 0x07
#define DRM_TEGRA_SUBMIT 0x08
#define DRM_TEGRA_GET_SYNCPT_BASE 0x09
#define DRM_TEGRA_GEM_SET_TILING 0x0a
#define DRM_TEGRA_GEM_GET_TILING 0x0b
#define DRM_TEGRA_GEM_SET_FLAGS 0x0c
#define DRM_TEGRA_GEM_GET_FLAGS 0x0d
#define DRM_IOCTL_TEGRA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_CREATE, struct drm_tegra_gem_create)
#define DRM_IOCTL_TEGRA_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_MMAP, struct drm_tegra_gem_mmap)
#define DRM_IOCTL_TEGRA_SYNCPT_READ DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_READ, struct drm_tegra_syncpt_read)
#define DRM_IOCTL_TEGRA_SYNCPT_INCR DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_INCR, struct drm_tegra_syncpt_incr)
#define DRM_IOCTL_TEGRA_SYNCPT_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_WAIT, struct drm_tegra_syncpt_wait)
#define DRM_IOCTL_TEGRA_OPEN_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_OPEN_CHANNEL, struct drm_tegra_open_channel)
#define DRM_IOCTL_TEGRA_CLOSE_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_CLOSE_CHANNEL, struct drm_tegra_open_channel)
#define DRM_IOCTL_TEGRA_GET_SYNCPT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_SYNCPT, struct drm_tegra_get_syncpt)
#define DRM_IOCTL_TEGRA_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SUBMIT, struct drm_tegra_submit)
#define DRM_IOCTL_TEGRA_GET_SYNCPT_BASE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_SYNCPT_BASE, struct drm_tegra_get_syncpt_base)
#define DRM_IOCTL_TEGRA_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_SET_TILING, struct drm_tegra_gem_set_tiling)
#define DRM_IOCTL_TEGRA_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_TILING, struct drm_tegra_gem_get_tiling)
#define DRM_IOCTL_TEGRA_GEM_SET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_SET_FLAGS, struct drm_tegra_gem_set_flags)
#define DRM_IOCTL_TEGRA_GEM_GET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_FLAGS, struct drm_tegra_gem_get_flags)
#if defined(__cplusplus)
}
#endif
#endif /* _TEGRA_DRM_H_ */

View File

@ -135,6 +135,7 @@ with_gallium_vc4 = false
with_gallium_vc5 = false
with_gallium_etnaviv = false
with_gallium_imx = false
with_gallium_tegra = false
with_gallium_i915 = false
with_gallium_svga = false
with_gallium_virgl = false
@ -146,7 +147,7 @@ if _drivers == 'auto'
if ['x86', 'x86_64'].contains(host_machine.cpu_family())
_drivers = 'r300,r600,radeonsi,nouveau,virgl,svga,swrast'
elif ['arm', 'aarch64'].contains(host_machine.cpu_family())
_drivers = 'pl111,vc4,vc5,freedreno,etnaviv,imx,virgl,svga,swrast'
_drivers = 'pl111,vc4,vc5,freedreno,etnaviv,imx,nouveau,tegra,virgl,svga,swrast'
else
error('Unknown architecture. Please pass -Dgallium-drivers to set driver options. Patches gladly accepted to fix this.')
endif
@ -169,6 +170,7 @@ if _drivers != ''
with_gallium_vc5 = _split.contains('vc5')
with_gallium_etnaviv = _split.contains('etnaviv')
with_gallium_imx = _split.contains('imx')
with_gallium_tegra = _split.contains('tegra')
with_gallium_i915 = _split.contains('i915')
with_gallium_svga = _split.contains('svga')
with_gallium_virgl = _split.contains('virgl')
@ -220,6 +222,9 @@ endif
if with_gallium_pl111 and not with_gallium_vc4
error('pl111 driver requires vc4 driver')
endif
if with_gallium_tegra and not with_gallium_nouveau
error('tegra driver requires nouveau driver')
endif
dep_libdrm_intel = []
if with_dri_i915 or with_gallium_i915

View File

@ -89,6 +89,11 @@ if HAVE_GALLIUM_SWR
SUBDIRS += drivers/swr
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

View File

@ -134,7 +134,12 @@ static const struct drm_driver_descriptor driver_descriptors[] = {
.driver_name = "imx-drm",
.create_screen = pipe_imx_drm_create_screen,
.configuration = pipe_default_configuration_query,
}
},
{
.driver_name = "tegra",
.create_screen = pipe_tegra_create_screen,
.configuration = pipe_default_configuration_query,
},
};
#endif

View File

@ -379,5 +379,28 @@ pipe_imx_drm_create_screen(int fd, const struct pipe_screen_config *config)
#endif
#ifdef GALLIUM_TEGRA
#include "tegra/drm/tegra_drm_public.h"
struct pipe_screen *
pipe_tegra_create_screen(int fd, const struct pipe_screen_config *config)
{
struct pipe_screen *screen;
screen = tegra_drm_screen_create(fd);
return screen ? debug_screen_wrap(screen) : NULL;
}
#else
struct pipe_screen *
pipe_tegra_create_screen(int fd, const struct pipe_screen_config *config)
{
fprintf(stderr, "tegra: driver missing\n");
return NULL;
}
#endif
#endif /* DRM_HELPER_H */

View File

@ -51,6 +51,9 @@ pipe_etna_create_screen(int fd, const struct pipe_screen_config *config);
struct pipe_screen *
pipe_imx_drm_create_screen(int fd, const struct pipe_screen_config *config);
struct pipe_screen *
pipe_tegra_create_screen(int fd, const struct pipe_screen_config *config);
const struct drm_conf_ret *
pipe_default_configuration_query(enum drm_conf conf);

View File

@ -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

View File

@ -0,0 +1,14 @@
include Makefile.sources
include $(top_srcdir)/src/gallium/Automake.inc
AM_CFLAGS = \
-I$(top_srcdir)/include/drm-uapi \
$(GALLIUM_DRIVER_CFLAGS)
noinst_LTLIBRARIES = libtegra.la
libtegra_la_SOURCES = \
$(C_SOURCES)
EXTRA_DIST = \
meson.build

View File

@ -0,0 +1,6 @@
C_SOURCES := \
tegra_context.c \
tegra_context.h \
tegra_resource.h \
tegra_screen.c \
tegra_screen.h

View File

@ -0,0 +1,41 @@
# Copyright © 2018 NVIDIA CORPORATION
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# 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.
files_tegra = files(
'tegra_context.c',
'tegra_context.h',
'tegra_resource.h',
'tegra_screen.c',
)
libtegra = static_library(
'tegra',
files_tegra,
c_args : [c_vis_args],
include_directories : [
inc_include, inc_src, inc_gallium, inc_gallium_aux, inc_gallium_drivers,
inc_gallium_winsys, inc_drm_uapi
],
)
driver_tegra = declare_dependency(
compile_args : '-DGALLIUM_TEGRA',
link_with : [libtegra, libtegradrm],
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,81 @@
/*
* Copyright © 2014-2018 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_screen_context_create(struct pipe_screen *pscreen, void *priv,
unsigned int flags);
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 */

View File

@ -0,0 +1,76 @@
/*
* Copyright © 2014-2018 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;
uint64_t modifier;
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 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;
}
#endif /* TEGRA_RESOURCE_H */

View File

@ -0,0 +1,688 @@
/*
* Copyright © 2014-2018 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 <inttypes.h>
#include <stdio.h>
#include <sys/stat.h>
#include <drm_fourcc.h>
#include <tegra_drm.h>
#include <xf86drm.h>
#include "pipe/p_state.h"
#include "util/u_debug.h"
#include "util/u_inlines.h"
#include "state_tracker/drm_driver.h"
#include "nouveau/drm/nouveau_drm_public.h"
#include "tegra_context.h"
#include "tegra_resource.h"
#include "tegra_screen.h"
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 const char *
tegra_screen_get_name(struct pipe_screen *pscreen)
{
return "tegra";
}
static const char *
tegra_screen_get_vendor(struct pipe_screen *pscreen)
{
return "NVIDIA";
}
static const char *
tegra_screen_get_device_vendor(struct pipe_screen *pscreen)
{
return "NVIDIA";
}
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 int
tegra_screen_get_video_param(struct pipe_screen *pscreen,
enum pipe_video_profile profile,
enum pipe_video_entrypoint entrypoint,
enum pipe_video_cap param)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->get_video_param(screen->gpu, profile, entrypoint,
param);
}
static int
tegra_screen_get_compute_param(struct pipe_screen *pscreen,
enum pipe_shader_ir ir_type,
enum pipe_compute_cap param,
void *retp)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->get_compute_param(screen->gpu, ir_type, param,
retp);
}
static uint64_t
tegra_screen_get_timestamp(struct pipe_screen *pscreen)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->get_timestamp(screen->gpu);
}
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 boolean
tegra_screen_is_video_format_supported(struct pipe_screen *pscreen,
enum pipe_format format,
enum pipe_video_profile profile,
enum pipe_video_entrypoint entrypoint)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->is_video_format_supported(screen->gpu, format, profile,
entrypoint);
}
static boolean
tegra_screen_can_create_resource(struct pipe_screen *pscreen,
const struct pipe_resource *template)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->can_create_resource(screen->gpu, template);
}
static int tegra_open_render_node(void)
{
drmDevicePtr *devices, device;
int err, render = -ENOENT, fd;
unsigned int num, i;
err = drmGetDevices2(0, NULL, 0);
if (err < 0)
return err;
num = err;
devices = calloc(num, sizeof(*devices));
if (!devices)
return -ENOMEM;
err = drmGetDevices2(0, devices, num);
if (err < 0) {
render = err;
goto free;
}
for (i = 0; i < num; i++) {
device = devices[i];
if ((device->available_nodes & (1 << DRM_NODE_RENDER)) &&
(device->bustype == DRM_BUS_PLATFORM)) {
drmVersionPtr version;
fd = open(device->nodes[DRM_NODE_RENDER], O_RDWR | O_CLOEXEC);
if (fd < 0)
continue;
version = drmGetVersion(fd);
if (!version) {
close(fd);
continue;
}
if (strcmp(version->name, "nouveau") != 0) {
close(fd);
continue;
}
drmFreeVersion(version);
render = fd;
break;
}
}
drmFreeDevices(devices, num);
free:
free(devices);
return render;
}
static int tegra_screen_import_resource(struct tegra_screen *screen,
struct tegra_resource *resource,
bool has_modifiers)
{
unsigned usage = PIPE_HANDLE_USAGE_READ;
struct drm_tegra_gem_set_tiling args;
struct winsys_handle handle;
boolean status;
int fd, err;
memset(&handle, 0, sizeof(handle));
handle.modifier = DRM_FORMAT_MOD_INVALID;
handle.type = DRM_API_HANDLE_TYPE_FD;
status = screen->gpu->resource_get_handle(screen->gpu, NULL, resource->gpu,
&handle, usage);
if (!status)
return -EINVAL;
assert(handle.modifier != DRM_FORMAT_MOD_INVALID);
if (handle.modifier == DRM_FORMAT_MOD_INVALID) {
close(handle.handle);
return -EINVAL;
}
resource->modifier = handle.modifier;
resource->stride = handle.stride;
fd = handle.handle;
err = drmPrimeFDToHandle(screen->fd, fd, &resource->handle);
if (err < 0)
err = -errno;
close(fd);
if (!has_modifiers) {
memset(&args, 0, sizeof(args));
args.handle = resource->handle;
switch (handle.modifier) {
case DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED:
args.mode = DRM_TEGRA_GEM_TILING_MODE_TILED;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB:
args.mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK;
args.value = 0;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB:
args.mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK;
args.value = 1;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB:
args.mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK;
args.value = 2;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB:
args.mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK;
args.value = 3;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB:
args.mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK;
args.value = 4;
break;
case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB:
args.mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK;
args.value = 5;
break;
default:
debug_printf("unsupported modifier %" PRIx64 ", assuming linear\n",
handle.modifier);
/* fall-through */
case DRM_FORMAT_MOD_LINEAR:
args.mode = DRM_TEGRA_GEM_TILING_MODE_PITCH;
break;
}
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));
err = -errno;
goto out;
}
}
return 0;
out:
return err;
}
static struct pipe_resource *
tegra_screen_resource_create(struct pipe_screen *pscreen,
const struct pipe_resource *template)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
struct tegra_resource *resource;
int err;
resource = calloc(1, sizeof(*resource));
if (!resource)
return NULL;
resource->gpu = screen->gpu->resource_create(screen->gpu, template);
if (!resource->gpu)
goto free;
/* import scanout buffers for display */
if (template->bind & PIPE_BIND_SCANOUT) {
err = tegra_screen_import_resource(screen, resource, false);
if (err < 0)
goto destroy;
}
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;
}
/* XXX */
static struct pipe_resource *
tegra_screen_resource_create_front(struct pipe_screen *pscreen,
const struct pipe_resource *template,
const void *map_front_private)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
struct pipe_resource *resource;
resource = screen->gpu->resource_create_front(screen->gpu, template,
map_front_private);
if (resource)
resource->screen = pscreen;
return resource;
}
static struct pipe_resource *
tegra_screen_resource_from_handle(struct pipe_screen *pscreen,
const struct pipe_resource *template,
struct winsys_handle *handle,
unsigned usage)
{
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, usage);
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;
}
/* XXX */
static struct pipe_resource *
tegra_screen_resource_from_user_memory(struct pipe_screen *pscreen,
const struct pipe_resource *template,
void *buffer)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
struct pipe_resource *resource;
resource = screen->gpu->resource_from_user_memory(screen->gpu, template,
buffer);
if (resource)
resource->screen = pscreen;
return resource;
}
static boolean
tegra_screen_resource_get_handle(struct pipe_screen *pscreen,
struct pipe_context *pcontext,
struct pipe_resource *presource,
struct winsys_handle *handle,
unsigned usage)
{
struct tegra_resource *resource = to_tegra_resource(presource);
struct tegra_context *context = to_tegra_context(pcontext);
struct tegra_screen *screen = to_tegra_screen(pscreen);
boolean ret = TRUE;
/*
* Assume that KMS handles for scanout resources will only ever be used
* to pass buffers into Tegra DRM for display. In all other cases, return
* the Nouveau handle, assuming they will be used for sharing in DRI2/3.
*/
if (handle->type == DRM_API_HANDLE_TYPE_KMS &&
presource->bind & PIPE_BIND_SCANOUT) {
handle->modifier = resource->modifier;
handle->handle = resource->handle;
handle->stride = resource->stride;
} else {
ret = screen->gpu->resource_get_handle(screen->gpu,
context ? context->gpu : NULL,
resource->gpu, handle, usage);
}
return ret;
}
static void
tegra_screen_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);
}
static void
tegra_screen_flush_frontbuffer(struct pipe_screen *pscreen,
struct pipe_resource *resource,
unsigned int level,
unsigned int layer,
void *winsys_drawable_handle,
struct pipe_box *box)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
screen->gpu->flush_frontbuffer(screen->gpu, resource, level, layer,
winsys_drawable_handle, box);
}
static void
tegra_screen_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_screen_fence_finish(struct pipe_screen *pscreen,
struct pipe_context *pcontext,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
struct tegra_context *context = to_tegra_context(pcontext);
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->fence_finish(screen->gpu,
context ? context->gpu : NULL,
fence, timeout);
}
static int
tegra_screen_fence_get_fd(struct pipe_screen *pscreen,
struct pipe_fence_handle *fence)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->fence_get_fd(screen->gpu, fence);
}
static int
tegra_screen_get_driver_query_info(struct pipe_screen *pscreen,
unsigned int index,
struct pipe_driver_query_info *info)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->get_driver_query_info(screen->gpu, index, info);
}
static int
tegra_screen_get_driver_query_group_info(struct pipe_screen *pscreen,
unsigned int index,
struct pipe_driver_query_group_info *info)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->get_driver_query_group_info(screen->gpu, index, info);
}
static void
tegra_screen_query_memory_info(struct pipe_screen *pscreen,
struct pipe_memory_info *info)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
screen->gpu->query_memory_info(screen->gpu, info);
}
static const void *
tegra_screen_get_compiler_options(struct pipe_screen *pscreen,
enum pipe_shader_ir ir,
unsigned int shader)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
const void *options = NULL;
if (screen->gpu->get_compiler_options)
options = screen->gpu->get_compiler_options(screen->gpu, ir, shader);
return options;
}
static struct disk_cache *
tegra_screen_get_disk_shader_cache(struct pipe_screen *pscreen)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->get_disk_shader_cache(screen->gpu);
}
static struct pipe_resource *
tegra_screen_resource_create_with_modifiers(struct pipe_screen *pscreen,
const struct pipe_resource *template,
const uint64_t *modifiers,
int count)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
struct tegra_resource *resource;
int err;
resource = calloc(1, sizeof(*resource));
if (!resource)
return NULL;
resource->gpu = screen->gpu->resource_create_with_modifiers(screen->gpu,
template,
modifiers,
count);
if (!resource->gpu)
goto free;
err = tegra_screen_import_resource(screen, resource, true);
if (err < 0)
goto destroy;
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;
}
static void tegra_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
enum pipe_format format,
int max, uint64_t *modifiers,
unsigned int *external_only,
int *count)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
screen->gpu->query_dmabuf_modifiers(screen->gpu, format, max, modifiers,
external_only, count);
}
static struct pipe_memory_object *
tegra_screen_memobj_create_from_handle(struct pipe_screen *pscreen,
struct winsys_handle *handle,
bool dedicated)
{
struct tegra_screen *screen = to_tegra_screen(pscreen);
return screen->gpu->memobj_create_from_handle(screen->gpu, handle,
dedicated);
}
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();
if (screen->gpu_fd < 0) {
if (errno != ENOENT)
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.destroy = tegra_screen_destroy;
screen->base.get_name = tegra_screen_get_name;
screen->base.get_vendor = tegra_screen_get_vendor;
screen->base.get_device_vendor = tegra_screen_get_device_vendor;
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.get_video_param = tegra_screen_get_video_param;
screen->base.get_compute_param = tegra_screen_get_compute_param;
screen->base.get_timestamp = tegra_screen_get_timestamp;
screen->base.context_create = tegra_screen_context_create;
screen->base.is_format_supported = tegra_screen_is_format_supported;
screen->base.is_video_format_supported = tegra_screen_is_video_format_supported;
/* allow fallback implementation if GPU driver doesn't implement it */
if (screen->gpu->can_create_resource)
screen->base.can_create_resource = tegra_screen_can_create_resource;
screen->base.resource_create = tegra_screen_resource_create;
screen->base.resource_create_front = tegra_screen_resource_create_front;
screen->base.resource_from_handle = tegra_screen_resource_from_handle;
screen->base.resource_from_user_memory = tegra_screen_resource_from_user_memory;
screen->base.resource_get_handle = tegra_screen_resource_get_handle;
screen->base.resource_destroy = tegra_screen_resource_destroy;
screen->base.flush_frontbuffer = tegra_screen_flush_frontbuffer;
screen->base.fence_reference = tegra_screen_fence_reference;
screen->base.fence_finish = tegra_screen_fence_finish;
screen->base.fence_get_fd = tegra_screen_fence_get_fd;
screen->base.get_driver_query_info = tegra_screen_get_driver_query_info;
screen->base.get_driver_query_group_info = tegra_screen_get_driver_query_group_info;
screen->base.query_memory_info = tegra_screen_query_memory_info;
screen->base.get_compiler_options = tegra_screen_get_compiler_options;
screen->base.get_disk_shader_cache = tegra_screen_get_disk_shader_cache;
screen->base.resource_create_with_modifiers = tegra_screen_resource_create_with_modifiers;
screen->base.query_dmabuf_modifiers = tegra_screen_query_dmabuf_modifiers;
screen->base.memobj_create_from_handle = tegra_screen_memobj_create_from_handle;
return &screen->base;
}

View File

@ -0,0 +1,45 @@
/*
* Copyright © 2014-2018 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 */

View File

@ -119,6 +119,12 @@ if with_gallium_imx
else
driver_imx = declare_dependency()
endif
if with_gallium_tegra
subdir('winsys/tegra/drm')
subdir('drivers/tegra')
else
driver_tegra = declare_dependency()
endif
if with_gallium_i915
subdir('winsys/i915/drm')
subdir('drivers/i915')

View File

@ -82,6 +82,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/vc5/Automake.inc
include $(top_srcdir)/src/gallium/drivers/pl111/Automake.inc

View File

@ -62,7 +62,8 @@ libgallium_dri = shared_library(
dep_selinux, dep_expat, dep_libdrm, dep_llvm, dep_thread,
driver_swrast, driver_r300, driver_r600, driver_radeonsi, driver_nouveau,
driver_pl111, driver_vc4, driver_vc5, driver_freedreno, driver_etnaviv,
driver_imx, driver_i915, driver_svga, driver_virgl, driver_swr,
driver_imx, driver_tegra, driver_i915, driver_svga, driver_virgl,
driver_swr,
],
)
@ -76,6 +77,7 @@ foreach d : [[with_gallium_pl111, 'pl111_dri.so'],
[with_gallium_vc5, 'vc5_dri.so'],
[with_gallium_etnaviv, 'etnaviv_dri.so'],
[with_gallium_imx, 'imx-drm_dri.so'],
[with_gallium_tegra, 'tegra_dri.so'],
[with_gallium_i915, 'i915_dri.so'],
[with_gallium_r300, 'r300_dri.so'],
[with_gallium_r600, 'r600_dri.so'],

View File

@ -86,3 +86,7 @@ DEFINE_LOADER_DRM_ENTRYPOINT(vc5)
DEFINE_LOADER_DRM_ENTRYPOINT(imx_drm)
DEFINE_LOADER_DRM_ENTRYPOINT(etnaviv)
#endif
#if defined(GALLIUM_TEGRA)
DEFINE_LOADER_DRM_ENTRYPOINT(tegra);
#endif

View File

@ -57,6 +57,8 @@ include $(top_srcdir)/src/gallium/drivers/r300/Automake.inc
include $(top_srcdir)/src/gallium/drivers/r600/Automake.inc
include $(top_srcdir)/src/gallium/drivers/radeonsi/Automake.inc
include $(top_srcdir)/src/gallium/drivers/tegra/Automake.inc
if HAVE_GALLIUM_STATIC_TARGETS
libvdpau_gallium_la_SOURCES += target.c

View File

@ -0,0 +1,13 @@
include Makefile.sources
include $(top_srcdir)/src/gallium/Automake.inc
AM_CFLAGS = \
-I$(top_srcdir)/src/gallium/drivers \
$(GALLIUM_WINSYS_CFLAGS)
noinst_LTLIBRARIES = libtegradrm.la
libtegradrm_la_SOURCES = $(C_SOURCES)
EXTRA_DIST = \
meson.build

View File

@ -0,0 +1,2 @@
C_SOURCES := \
tegra_drm_winsys.c

View File

@ -0,0 +1,33 @@
# Copyright © 2018 NVIDIA CORPORATION
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# 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.
libtegradrm = static_library(
'tegradrm',
'tegra_drm_winsys.c',
include_directories : [
inc_include, inc_src, inc_gallium, inc_gallium_aux, inc_gallium_drivers,
inc_gallium_winsys
],
)
driver_tegra = declare_dependency(
compile_args : '-DGALLIUM_TEGRA',
link_with : libtegradrm,
)

View File

@ -0,0 +1,31 @@
/*
* Copyright © 2014-2018 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__ */

View File

@ -0,0 +1,49 @@
/*
* Copyright © 2014-2018 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 <fcntl.h>
#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)
{
struct pipe_screen *screen;
/*
* NOTE: There are reportedly issues with reusing the file descriptor
* as-is related to Xinerama. Duplicate it to side-step any issues.
*/
fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
if (fd < 0)
return NULL;
screen = tegra_screen_create(fd);
if (!screen)
close(fd);
return screen;
}