diff options
author | Thierry Reding <treding@nvidia.com> | 2016-07-04 11:36:19 +0200 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2016-07-04 11:36:19 +0200 |
commit | 6155941e45bc244a523a9ca62b234e71365aff2d (patch) | |
tree | a94e585ba464e3488d2e00ec887f18c71e6ca875 | |
parent | f5002d2e7394af77ce459ce8c38de3fa4f06d135 (diff) | |
parent | 9a934c22c4e6d643823acaa80d8ef631ee34c637 (diff) |
Merge branch 'staging/tegra' into staging/masterstaging/master
21 files changed, 2060 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index 8321e8eb21da..5cd1d9bd8cd5 100644 --- a/configure.ac +++ b/configure.ac @@ -75,6 +75,7 @@ LIBDRM_INTEL_REQUIRED=2.4.61 LIBDRM_NVVIEUX_REQUIRED=2.4.66 LIBDRM_NOUVEAU_REQUIRED=2.4.66 LIBDRM_FREEDRENO_REQUIRED=2.4.67 +LIBDRM_TEGRA_REQUIRED=2.4.58 DRI2PROTO_REQUIRED=2.6 DRI3PROTO_REQUIRED=1.0 PRESENTPROTO_REQUIRED=1.0 @@ -971,7 +972,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,virgl" + "i915,ilo,nouveau,r300,r600,radeonsi,freedreno,svga,swrast,tegra,vc4,virgl" @<:@default=r300,r600,svga,swrast@:>@])], [with_gallium_drivers="$withval"], [with_gallium_drivers="$GALLIUM_DRIVERS_DEFAULT"]) @@ -2429,6 +2430,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 @@ -2542,6 +2549,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_SWR, test "x$HAVE_GALLIUM_SWR" = xyes) @@ -2682,6 +2690,9 @@ AC_CONFIG_FILES([Makefile src/gallium/drivers/softpipe/Makefile src/gallium/drivers/svga/Makefile src/gallium/drivers/swr/Makefile + src/gallium/drivers/swr/avx/Makefile + src/gallium/drivers/swr/avx2/Makefile + src/gallium/drivers/tegra/Makefile src/gallium/drivers/trace/Makefile src/gallium/drivers/vc4/Makefile src/gallium/drivers/virgl/Makefile @@ -2724,6 +2735,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/virgl/drm/Makefile src/gallium/winsys/virgl/vtest/Makefile diff --git a/src/gallium/Makefile.am b/src/gallium/Makefile.am index 34671ca88d50..c2fc47abf560 100644 --- a/src/gallium/Makefile.am +++ b/src/gallium/Makefile.am @@ -82,6 +82,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 diff --git a/src/gallium/auxiliary/target-helpers/drm_helper.h b/src/gallium/auxiliary/target-helpers/drm_helper.h index 90820d3fe910..0d625f7b018f 100644 --- a/src/gallium/auxiliary/target-helpers/drm_helper.h +++ b/src/gallium/auxiliary/target-helpers/drm_helper.h @@ -266,5 +266,28 @@ pipe_vc4_create_screen(int fd) #endif +#ifdef GALLIUM_TEGRA +#include "tegra/drm/tegra_drm_public.h" + +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; +} + +#else + +struct pipe_screen * +pipe_tegra_create_screen(int fd) +{ + fprintf(stderr, "tegra: driver missing\n"); + return NULL; +} + +#endif #endif /* DRM_HELPER_H */ diff --git a/src/gallium/auxiliary/target-helpers/drm_helper_public.h b/src/gallium/auxiliary/target-helpers/drm_helper_public.h index d1f9382a6f97..5eb5f488f7f0 100644 --- a/src/gallium/auxiliary/target-helpers/drm_helper_public.h +++ b/src/gallium/auxiliary/target-helpers/drm_helper_public.h @@ -34,4 +34,7 @@ pipe_virgl_create_screen(int fd); struct pipe_screen * pipe_vc4_create_screen(int fd); +struct pipe_screen * +pipe_tegra_create_screen(int fd); + #endif /* _DRM_HELPER_PUBLIC_H */ diff --git a/src/gallium/drivers/tegra/Automake.inc b/src/gallium/drivers/tegra/Automake.inc new file mode 100644 index 000000000000..f65281916245 --- /dev/null +++ b/src/gallium/drivers/tegra/Automake.inc @@ -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 diff --git a/src/gallium/drivers/tegra/Makefile.am b/src/gallium/drivers/tegra/Makefile.am new file mode 100644 index 000000000000..eb03df9bb2ed --- /dev/null +++ b/src/gallium/drivers/tegra/Makefile.am @@ -0,0 +1,17 @@ +AUTOMAKE_OPTIONS = subdir-objects + +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) diff --git a/src/gallium/drivers/tegra/Makefile.sources b/src/gallium/drivers/tegra/Makefile.sources new file mode 100644 index 000000000000..978dd14667f5 --- /dev/null +++ b/src/gallium/drivers/tegra/Makefile.sources @@ -0,0 +1,4 @@ +C_SOURCES := \ + tegra_context.c \ + tegra_resource.c \ + tegra_screen.c diff --git a/src/gallium/drivers/tegra/tegra_context.c b/src/gallium/drivers/tegra/tegra_context.c new file mode 100644 index 000000000000..389bc8bc6a59 --- /dev/null +++ b/src/gallium/drivers/tegra/tegra_context.c @@ -0,0 +1,962 @@ +/* + * 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); + + debug_printf("> %s(pcontext=%p)\n", __func__, pcontext); + + context->gpu->destroy(context->gpu); + free(context); + + debug_printf("< %s()\n", __func__); +} + +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; + + debug_printf("> %s(pcontext=%p, pinfo=%p)\n", __func__, pcontext, + pinfo); + debug_printf(" pinfo:\n"); + debug_printf(" indexed: %d\n", pinfo->indexed); + debug_printf(" mode: %x\n", pinfo->mode); + debug_printf(" start: %u\n", pinfo->start); + debug_printf(" count: %u\n", pinfo->count); + + if (pinfo && pinfo->indirect) { + debug_printf(" unwrapping pipe_draw_info\n"); + memcpy(&info, pinfo, sizeof(info)); + info.indirect = tegra_resource_unwrap(info.indirect); + pinfo = &info; + } + + context->gpu->draw_vbo(context->gpu, pinfo); + + debug_printf("< %s()\n", __func__); +} + +static void * +tegra_create_blend_state(struct pipe_context *pcontext, + const struct pipe_blend_state *cso) +{ + struct tegra_context *context = to_tegra_context(pcontext); + void *so; + + debug_printf("> %s(pcontext=%p, cso=%p)\n", __func__, pcontext, cso); + + so = context->gpu->create_blend_state(context->gpu, cso); + + debug_printf("< %s() = %p\n", __func__, so); + return so; +} + +static void +tegra_bind_blend_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->bind_blend_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void +tegra_delete_blend_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->delete_blend_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void * +tegra_create_sampler_state(struct pipe_context *pcontext, + const struct pipe_sampler_state *cso) +{ + struct tegra_context *context = to_tegra_context(pcontext); + void *so; + + debug_printf("> %s(pcontext=%p, cso=%p)\n", __func__, pcontext, cso); + + so = context->gpu->create_sampler_state(context->gpu, cso); + + debug_printf("< %s() = %p\n", __func__, so); + return so; +} + +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); + + debug_printf("> %s(pcontext=%p, shader=%u, start_slot=%u, num_samplers=%u, samplers=%p)\n", + __func__, pcontext, shader, start_slot, num_samplers, + samplers); + + context->gpu->bind_sampler_states(context->gpu, shader, start_slot, + num_samplers, samplers); + + debug_printf("< %s()\n", __func__); +} + +static void +tegra_delete_sampler_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->delete_sampler_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void * +tegra_create_rasterizer_state(struct pipe_context *pcontext, + const struct pipe_rasterizer_state *cso) +{ + struct tegra_context *context = to_tegra_context(pcontext); + void *so; + + debug_printf("> %s(pcontext=%p, cso=%p)\n", __func__, pcontext, cso); + + so = context->gpu->create_rasterizer_state(context->gpu, cso); + + debug_printf("< %s() = %p\n", __func__, so); + return so; +} + +static void +tegra_bind_rasterizer_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->bind_rasterizer_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void +tegra_delete_rasterizer_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->delete_rasterizer_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +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); + void *so; + + debug_printf("> %s(pcontext=%p, cso=%p)\n", __func__, pcontext, cso); + + so = context->gpu->create_depth_stencil_alpha_state(context->gpu, + cso); + + debug_printf("< %s() = %p\n", __func__, so); + return so; +} + +static void +tegra_bind_depth_stencil_alpha_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->bind_depth_stencil_alpha_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void +tegra_delete_depth_stencil_alpha_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->delete_depth_stencil_alpha_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void * +tegra_create_fs_state(struct pipe_context *pcontext, + const struct pipe_shader_state *cso) +{ + struct tegra_context *context = to_tegra_context(pcontext); + void *so; + + debug_printf("> %s(pcontext=%p, cso=%p)\n", __func__, pcontext, cso); + + so = context->gpu->create_fs_state(context->gpu, cso); + + debug_printf("< %s() = %p\n", __func__, so); + return so; +} + +static void +tegra_bind_fs_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->bind_fs_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void +tegra_delete_fs_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->delete_fs_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void * +tegra_create_vs_state(struct pipe_context *pcontext, + const struct pipe_shader_state *cso) +{ + struct tegra_context *context = to_tegra_context(pcontext); + void *so; + + debug_printf("> %s(pcontext=%p, cso=%p)\n", __func__, pcontext, cso); + + so = context->gpu->create_vs_state(context->gpu, cso); + + debug_printf("< %s() = %p\n", __func__, so); + return so; +} + +static void +tegra_bind_vs_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->bind_vs_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void +tegra_delete_vs_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->delete_vs_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void * +tegra_create_gs_state(struct pipe_context *pcontext, + const struct pipe_shader_state *cso) +{ + struct tegra_context *context = to_tegra_context(pcontext); + void *so; + + debug_printf("> %s(pcontext=%p, cso=%p)\n", __func__, pcontext, cso); + + so = context->gpu->create_gs_state(context->gpu, cso); + + debug_printf("< %s() = %p\n", __func__, so); + return so; +} + +static void +tegra_bind_gs_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->bind_gs_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void +tegra_delete_gs_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->delete_gs_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +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); + void *so; + + debug_printf("> %s(pcontext=%p, num_elements=%u, elements=%p)\n", + __func__, pcontext, num_elements, elements); + + so = context->gpu->create_vertex_elements_state(context->gpu, + num_elements, + elements); + + debug_printf("< %s() = %p\n", __func__, so); + return so; +} + +static void +tegra_bind_vertex_elements_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->bind_vertex_elements_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +static void +tegra_delete_vertex_elements_state(struct pipe_context *pcontext, + void *so) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, so=%p)\n", __func__, pcontext, so); + + context->gpu->delete_vertex_elements_state(context->gpu, so); + + debug_printf("< %s()\n", __func__); +} + +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; + + debug_printf("> %s(pcontext=%p, shader=%u, index=%u, buf=%p)\n", + __func__, pcontext, shader, index, buf); + + if (buf && buf->buffer) { + memcpy(&buffer, buf, sizeof(buffer)); + debug_printf(" buffer: %p -> %p\n", buffer.buffer, + tegra_resource_unwrap(buffer.buffer)); + buffer.buffer = tegra_resource_unwrap(buffer.buffer); + buf = &buffer; + } + + context->gpu->set_constant_buffer(context->gpu, shader, index, buf); + + debug_printf("< %s()\n", __func__); +} + +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; + + debug_printf("> %s(pcontext=%p, fb=%p)\n", __func__, pcontext, fb); + + if (fb) { + memcpy(&state, fb, sizeof(state)); + + for (i = 0; i < fb->nr_cbufs; i++) { + state.cbufs[i] = tegra_surface_unwrap(fb->cbufs[i]); + debug_printf(" %u: %p -> %p\n", i, fb->cbufs[i], + state.cbufs[i]); + } + + while (i < PIPE_MAX_COLOR_BUFS) + state.cbufs[i++] = NULL; + + state.zsbuf = tegra_surface_unwrap(fb->zsbuf); + debug_printf(" zsbuf: %p -> %p\n", fb->zsbuf, state.zsbuf); + + fb = &state; + } + + context->gpu->set_framebuffer_state(context->gpu, fb); + + debug_printf("< %s()\n", __func__); +} + +static void +tegra_set_polygon_stipple(struct pipe_context *pcontext, + const struct pipe_poly_stipple *stipple) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, stipple=%p)\n", __func__, pcontext, + stipple); + + context->gpu->set_polygon_stipple(context->gpu, stipple); + + debug_printf("< %s()\n", __func__); +} + +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); + + debug_printf("> %s(pcontext=%p, start_slot=%u, num_scissors=%u, scissors=%p)\n", + __func__, pcontext, start_slot, num_scissors, scissors); + + context->gpu->set_scissor_states(context->gpu, start_slot, + num_scissors, scissors); + + debug_printf("< %s()\n", __func__); +} + +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); + + debug_printf("> %s(pcontext=%p, start_slot=%u, num_viewports=%u, viewports=%p)\n", + __func__, pcontext, start_slot, num_viewports, + viewports); + + context->gpu->set_viewport_states(context->gpu, start_slot, + num_viewports, viewports); + + debug_printf("< %s()\n", __func__); +} + +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; + + debug_printf("> %s(pcontext=%p, shader=%u, start_slot=%u, num_views=%u, pviews=%p)\n", + __func__, pcontext, shader, start_slot, num_views, + pviews); + + 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); + + debug_printf("< %s()\n", __func__); +} + +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); + + debug_printf("> %s(pcontext=%p, startt=%u, count=%u, resources=%p)\n", + __func__, pcontext, start, count, resources); + + context->gpu->set_shader_resources(context->gpu, start, count, + resources); + + debug_printf("< %s()\n", __func__); +} + +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; + + debug_printf("> %s(pcontext=%p, start_slot=%u, num_buffers=%u, buffers=%p)\n", + __func__, pcontext, start_slot, num_buffers, buffers); + + if (num_buffers && buffers) { + for (i = 0; i < num_buffers; i++) { + debug_printf(" %u:\n", i); + debug_printf(" stride: %u\n", buffers[i].stride); + debug_printf(" offset: %u\n", buffers[i].buffer_offset); + debug_printf(" buffer: %p\n", buffers[i].buffer); + debug_printf(" user: %p\n", buffers[i].user_buffer); + } + + memcpy(buf, buffers, num_buffers * sizeof(struct pipe_vertex_buffer)); + + for (i = 0; i < num_buffers; i++) { + debug_printf(" %u: %p -> %p\n", i, buf[i].buffer, + tegra_resource_unwrap(buf[i].buffer)); + buf[i].buffer = tegra_resource_unwrap(buf[i].buffer); + } + + buffers = buf; + } + + context->gpu->set_vertex_buffers(context->gpu, start_slot, + num_buffers, buffers); + + debug_printf("< %s()\n", __func__); +} + +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; + + debug_printf("> %s(pcontext=%p, buffer=%p)\n", __func__, pcontext, + buffer); + + if (buffer) { + memcpy(&buf, buffer, sizeof(buf)); + debug_printf(" buffer: %p -> %p\n", buf.buffer, + tegra_resource_unwrap(buf.buffer)); + buf.buffer = tegra_resource_unwrap(buf.buffer); + buffer = &buf; + } + + context->gpu->set_index_buffer(context->gpu, buffer); + + debug_printf("< %s()\n", __func__); +} + +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); + struct pipe_stream_output_target *target; + + debug_printf("> %s(pcontext=%p, presource=%p, buffer_offset=%u, buffer_size=%u)\n", + __func__, pcontext, presource, buffer_offset, + buffer_size); + + target = context->gpu->create_stream_output_target(context->gpu, + resource->gpu, + buffer_offset, + buffer_size); + + debug_printf("< %s() = %p\n", __func__, target); + return target; +} + +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); + + debug_printf("> %s(pcontext=%p, target=%p)\n", __func__, pcontext, + target); + + context->gpu->stream_output_target_destroy(context->gpu, target); + + debug_printf("< %s()\n", __func__); +} + +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); + + debug_printf("> %s(pcontext=%p, num_targets=%u, targets=%p, offsets=%p)\n", + __func__, pcontext, num_targets, targets, offsets); + + context->gpu->set_stream_output_targets(context->gpu, num_targets, + targets, offsets); + + debug_printf("< %s()\n", __func__); +} + +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; + + debug_printf("> %s(pcontext=%p, pinfo=%p)\n", __func__, pcontext, + pinfo); + + 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); + + debug_printf("< %s()\n", __func__); +} + +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); + + debug_printf("> %s(pcontext=%p, buffers=%x, color=%p, depth=%f, stencil=%u)\n", + __func__, pcontext, buffers, color, depth, stencil); + + context->gpu->clear(context->gpu, buffers, color, depth, stencil); + + debug_printf("< %s()\n", __func__); +} + +static void +tegra_flush(struct pipe_context *pcontext, + struct pipe_fence_handle **fence, + unsigned flags) +{ + struct tegra_context *context = to_tegra_context(pcontext); + + debug_printf("> %s(pcontext=%p, fence=%p, flags=%x)\n", __func__, + pcontext, fence, flags); + + context->gpu->flush(context->gpu, fence, flags); + + debug_printf("< %s()\n", __func__); +} + +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; + + debug_printf("> %s(pcontext=%p, ptexture=%p, template=%p)\n", + __func__, pcontext, ptexture, template); + + 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; + + debug_printf("< %s() = %p\n", __func__, &view->base); + 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); + + debug_printf("> %s(pcontext=%p, view=%p)\n", __func__, pcontext, + view); + + pipe_resource_reference(&view->base.texture, NULL); + pipe_sampler_view_reference(&view->gpu, NULL); + free(view); + + debug_printf("< %s()\n", __func__); +} + +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); + + debug_printf("> %s(pcontext=%p, presource=%p)\n", __func__, pcontext, + presource); + + context->gpu->flush_resource(context->gpu, resource->gpu); + + debug_printf("< %s()\n", __func__); +} + +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; + + debug_printf("> %s(pcontext=%p, presource=%p, level=%u, usage=%x, box=%p, ptransfer=%p)\n", + __func__, pcontext, presource, level, usage, box, + ptransfer); + + 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)); + if (transfer->base.resource != NULL) + debug_printf(" resource: %p\n", transfer->base.resource); + transfer->base.resource = NULL; + pipe_resource_reference(&transfer->base.resource, presource); + + *ptransfer = &transfer->base; + + debug_printf("< %s() = %p\n", __func__, transfer->map); + 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); + + debug_printf("> %s(pcontext=%p, ptransfer=%p)\n", __func__, pcontext, + ptransfer); + + context->gpu->transfer_unmap(context->gpu, transfer->gpu); + pipe_resource_reference(&transfer->base.resource, NULL); + free(transfer); + + debug_printf("< %s()\n", __func__); +} + +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); + + debug_printf("> %s(pcontext=%p, presource=%p, level=%u, usage=%x, box=%p, data=%p, stride=%u, layer_stride=%u)\n", + __func__, pcontext, presource, level, usage, box, data, + stride, layer_stride); + + context->gpu->transfer_inline_write(context->gpu, resource->gpu, + level, usage, box, data, stride, + layer_stride); + + debug_printf("< %s()\n", __func__); +} + +struct pipe_context * +tegra_context_create(struct pipe_screen *pscreen, void *priv) +{ + struct tegra_screen *screen = to_tegra_screen(pscreen); + struct tegra_context *context; + + debug_printf("> %s(pscreen=%p, priv=%p)\n", __func__, pscreen, priv); + + 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; + + debug_printf("< %s() = %p\n", __func__, &context->base); + return &context->base; +} diff --git a/src/gallium/drivers/tegra/tegra_context.h b/src/gallium/drivers/tegra/tegra_context.h new file mode 100644 index 000000000000..2a26ec6d9c63 --- /dev/null +++ b/src/gallium/drivers/tegra/tegra_context.h @@ -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 */ diff --git a/src/gallium/drivers/tegra/tegra_resource.c b/src/gallium/drivers/tegra/tegra_resource.c new file mode 100644 index 000000000000..3b8accad9f3d --- /dev/null +++ b/src/gallium/drivers/tegra/tegra_resource.c @@ -0,0 +1,262 @@ +/* + * 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; + + debug_printf("> %s(pscreen=%p, template=%p)\n", __func__, pscreen, + template); + /* + debug_printf(" template: %p\n", template); + debug_printf(" target: %u\n", template->target); + debug_printf(" format: %u\n", template->format); + debug_printf(" width: %u\n", template->width0); + debug_printf(" height: %u\n", template->height0); + debug_printf(" depth: %u\n", template->depth0); + debug_printf(" array_size: %u\n", template->array_size); + debug_printf(" last_level: %u\n", template->last_level); + debug_printf(" nr_samples: %u\n", template->nr_samples); + debug_printf(" usage: %u\n", template->usage); + debug_printf(" bind: %x\n", template->bind); + debug_printf(" flags: %x\n", template->flags); + */ + + 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; + } + + debug_printf(" gpu: %p\n", resource->gpu); + + memcpy(&resource->base, resource->gpu, sizeof(*resource->gpu)); + pipe_reference_init(&resource->base.reference, 1); + resource->base.screen = &screen->base; + + debug_printf("< %s() = %p\n", __func__, &resource->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; + + _debug_printf("> %s(pscreen=%p, template=%p, handle=%p)\n", __func__, + pscreen, template); + + 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; + + _debug_printf("< %s() = %p\n", __func__, &resource->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; + + debug_printf("> %s(pscreen=%p, presource=%p, handle=%p)\n", __func__, + pscreen, presource, handle); + + 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); + } + + debug_printf("< %s() = %d\n", __func__, ret); + return ret; +} + +void +tegra_resource_destroy(struct pipe_screen *pscreen, + struct pipe_resource *presource) +{ + struct tegra_resource *resource = to_tegra_resource(presource); + + debug_printf("> %s(pscreen=%p, presource=%p)\n", __func__, pscreen, + presource); + + pipe_resource_reference(&resource->gpu, NULL); + free(resource); + + debug_printf("< %s()\n", __func__); +} + +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; + + debug_printf("> %s(pcontext=%p, presource=%p, template=%p)\n", + __func__, pcontext, presource, template); + + 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; + + debug_printf(" gpu: %p\n", surface->gpu); + debug_printf("< %s() = %p\n", __func__, &surface->base); + return &surface->base; +} + +void +tegra_surface_destroy(struct pipe_context *pcontext, + struct pipe_surface *psurface) +{ + struct tegra_surface *surface = to_tegra_surface(psurface); + + debug_printf("> %s(pcontext=%p, psurface=%p)\n", __func__, pcontext, + psurface); + + pipe_resource_reference(&surface->base.texture, NULL); + pipe_surface_reference(&surface->gpu, NULL); + free(surface); + + debug_printf("< %s()\n", __func__); +} diff --git a/src/gallium/drivers/tegra/tegra_resource.h b/src/gallium/drivers/tegra/tegra_resource.h new file mode 100644 index 000000000000..783fb37ec466 --- /dev/null +++ b/src/gallium/drivers/tegra/tegra_resource.h @@ -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 */ diff --git a/src/gallium/drivers/tegra/tegra_screen.c b/src/gallium/drivers/tegra/tegra_screen.c new file mode 100644 index 000000000000..b6394faa0c61 --- /dev/null +++ b/src/gallium/drivers/tegra/tegra_screen.c @@ -0,0 +1,384 @@ +/* + * 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); + + debug_printf("> %s(pscreen=%p)\n", __func__, pscreen); + + screen->gpu->destroy(screen->gpu); + free(pscreen); + + debug_printf("< %s()\n", __func__); +} + +static int +tegra_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) +{ + struct tegra_screen *screen = to_tegra_screen(pscreen); + int ret; + + debug_printf("> %s(pscreen=%p, param=%d)\n", __func__, pscreen, + param); + + ret = screen->gpu->get_param(screen->gpu, param); + + debug_printf("< %s() = %d\n", __func__, ret); + return ret; +} + +static float +tegra_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) +{ + struct tegra_screen *screen = to_tegra_screen(pscreen); + float ret; + + debug_printf("> %s(pscreen=%p, param=%d)\n", __func__, pscreen, + param); + + ret = screen->gpu->get_paramf(screen->gpu, param); + + debug_printf("< %s() = %f\n", __func__, ret); + return ret; +} + +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); + int ret; + + debug_printf("> %s(pscreen=%p, param=%d)\n", __func__, pscreen, + param); + + ret = screen->gpu->get_shader_param(screen->gpu, shader, param); + + debug_printf("< %s() = %d\n", __func__, ret); + return ret; +} + +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); + boolean ret; + + debug_printf("> %s(pscreen=%p, format=%d, target=%d, sample_count=%u, usage=%x)\n", + __func__, pscreen, format, target, sample_count, usage); + + ret = screen->gpu->is_format_supported(screen->gpu, format, target, + sample_count, usage); + + debug_printf("< %s() = %d\n", __func__, ret); + return ret; +} + +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); + + debug_printf("> %s(pscreen=%p, ptr=%p, fence=%p)\n", __func__, + pscreen, ptr, fence); + + screen->gpu->fence_reference(screen->gpu, ptr, fence); + + debug_printf("< %s()\n", __func__); +} + +static boolean +tegra_fence_signalled(struct pipe_screen *pscreen, + struct pipe_fence_handle *fence) +{ + struct tegra_screen *screen = to_tegra_screen(pscreen); + boolean ret; + + debug_printf("> %s(pscreen=%p, fence=%p)\n", __func__, pscreen, + fence); + + ret = screen->gpu->fence_signalled(screen->gpu, fence); + + debug_printf("< %s() = %d\n", __func__, ret); + return ret; +} + +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); + boolean ret; + + debug_printf("> %s(pscreen=%p, fence=%p, timeout=%llu)\n", __func__, + pscreen, fence, timeout); + + ret = screen->gpu->fence_finish(screen->gpu, fence, timeout); + + debug_printf("< %s() = %d\n", __func__, ret); + return ret; +} + +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; + + debug_printf("> %s(device=%p)\n", __func__, device); + debug_printf(" syspath: %s\n", udev_device_get_syspath(device)); + + while (true) { + parent = udev_device_get_parent(device); + if (!parent) + break; + + debug_printf(" parent: %p\n", parent); + debug_printf(" syspath: %s\n", udev_device_get_syspath(parent)); + device = parent; + } + + debug_printf("< %s() = %p\n", __func__, device); + 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; + } + + debug_printf("path: %s\n", udev_device_get_devpath(display)); + + parent = udev_device_get_parent(display); + if (!parent) { + udev_device_unref(display); + udev_unref(udev); + return -ENODEV; + } + + debug_printf("parent: %s\n", udev_device_get_syspath(parent)); + + display = parent; + + root = udev_device_get_root(display); + if (!root) { + udev_device_unref(display); + udev_unref(udev); + return -ENODEV; + } + + debug_printf("root: %s\n", udev_device_get_syspath(root)); + + 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); + + debug_printf("devices:\n"); + + 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)) { + debug_printf("match found: %s\n", path); + + 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; + + debug_printf("> %s()\n", __func__); + + 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; + } + + debug_printf("GPU: %p\n", screen->gpu); + debug_printf(" fd: %d\n", screen->gpu_fd); + + 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; + + debug_printf("< %s() = %p\n", __func__, &screen->base); + return &screen->base; +} diff --git a/src/gallium/drivers/tegra/tegra_screen.h b/src/gallium/drivers/tegra/tegra_screen.h new file mode 100644 index 000000000000..1fba510c241f --- /dev/null +++ b/src/gallium/drivers/tegra/tegra_screen.h @@ -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 */ diff --git a/src/gallium/targets/dri/Makefile.am b/src/gallium/targets/dri/Makefile.am index f42dd25a56be..235eafdf66ab 100644 --- a/src/gallium/targets/dri/Makefile.am +++ b/src/gallium/targets/dri/Makefile.am @@ -80,6 +80,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/virgl/Automake.inc diff --git a/src/gallium/targets/dri/target.c b/src/gallium/targets/dri/target.c index 01532e242b8d..2db3f0a4438f 100644 --- a/src/gallium/targets/dri/target.c +++ b/src/gallium/targets/dri/target.c @@ -161,4 +161,14 @@ PUBLIC const __DRIextension **__driDriverGetExtensions_i965(void) return galliumdrm_driver_extensions; } #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 diff --git a/src/gallium/targets/pipe-loader/Makefile.am b/src/gallium/targets/pipe-loader/Makefile.am index 18b403f73315..9635c7aaed1f 100644 --- a/src/gallium/targets/pipe-loader/Makefile.am +++ b/src/gallium/targets/pipe-loader/Makefile.am @@ -178,6 +178,22 @@ pipe_msm_la_LIBADD = \ endif +if HAVE_GALLIUM_TEGRA +pipe_LTLIBRARIES += pipe_tegra.la + +pipe_tegra_la_SOURCES = pipe_tegra.c +nodist_EXTRA_pipe_tegra_la_SOURCES = dummy.cpp +pipe_tegra_la_LIBADD = \ + $(PIPE_LIBS) \ + $(top_builddir)/src/gallium/winsys/tegra/drm/libtegradrm.la \ + $(top_builddir)/src/gallium/winsys/nouveau/drm/libnouveaudrm.la \ + $(top_builddir)/src/gallium/drivers/tegra/libtegra.la \ + $(top_builddir)/src/gallium/drivers/nouveau/libnouveau.la \ + $(TEGRA_LIBS) \ + $(NOUVEAU_LIBS) \ + $(LIBDRM_LIBS) +endif + if HAVE_GALLIUM_SVGA pipe_LTLIBRARIES += pipe_vmwgfx.la diff --git a/src/gallium/targets/pipe-loader/pipe_tegra.c b/src/gallium/targets/pipe-loader/pipe_tegra.c new file mode 100644 index 000000000000..ff952080ac08 --- /dev/null +++ b/src/gallium/targets/pipe-loader/pipe_tegra.c @@ -0,0 +1,41 @@ +/* + * 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 "state_tracker/drm_driver.h" +#include "target-helpers/inline_debug_helper.h" +#include "tegra/drm/tegra_drm_public.h" + +static struct pipe_screen * +tegra_create_screen(int fd) +{ + struct pipe_screen *screen; + + screen = tegra_drm_screen_create(fd); + if (!screen) + return NULL; + + return debug_screen_wrap(screen); +} + +PUBLIC +DRM_DRIVER_DESCRIPTOR("tegra", "tegra", tegra_create_screen, NULL); diff --git a/src/gallium/winsys/tegra/drm/Makefile.am b/src/gallium/winsys/tegra/drm/Makefile.am new file mode 100644 index 000000000000..8af32530479a --- /dev/null +++ b/src/gallium/winsys/tegra/drm/Makefile.am @@ -0,0 +1,11 @@ +include Makefile.sources +include $(top_srcdir)/src/gallium/Automake.inc + +AM_CFLAGS = \ + -I$(top_srcdir)/src/gallium/drivers \ + $(GALLIUM_WINSYS_CFLAGS) \ + $(TEGRA_CFLAGS) + +noinst_LTLIBRARIES = libtegradrm.la + +libtegradrm_la_SOURCES = $(C_SOURCES) diff --git a/src/gallium/winsys/tegra/drm/Makefile.sources b/src/gallium/winsys/tegra/drm/Makefile.sources new file mode 100644 index 000000000000..fe0d5c42e72d --- /dev/null +++ b/src/gallium/winsys/tegra/drm/Makefile.sources @@ -0,0 +1,2 @@ +C_SOURCES := \ + tegra_drm_winsys.c diff --git a/src/gallium/winsys/tegra/drm/tegra_drm_public.h b/src/gallium/winsys/tegra/drm/tegra_drm_public.h new file mode 100644 index 000000000000..45e3e006f9be --- /dev/null +++ b/src/gallium/winsys/tegra/drm/tegra_drm_public.h @@ -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__ */ diff --git a/src/gallium/winsys/tegra/drm/tegra_drm_winsys.c b/src/gallium/winsys/tegra/drm/tegra_drm_winsys.c new file mode 100644 index 000000000000..037a043360ab --- /dev/null +++ b/src/gallium/winsys/tegra/drm/tegra_drm_winsys.c @@ -0,0 +1,40 @@ +/* + * 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) +{ + struct pipe_screen *screen; + + debug_printf("> %s(fd=%d)\n", __func__, fd); + + screen = tegra_screen_create(fd); + + debug_printf("< %s() = %p\n", __func__, screen); + return screen; +} |