Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

nouveau: pull in major libdrm rewrite

Redesigned primarily to allow us to better take advantage of BO's having
fixed GPU virtual addresses on GeForce 8 and up, and to reduce the overhead
of handling relocations on earlier chipsets.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information...
commit b7b78a85e237effe6e5b0113e7f58996c40e7e19 1 parent a38df61
Ben Skeggs authored

Showing 29 changed files with 1,991 additions and 2,744 deletions. Show diff stats Hide diff stats

  1. +18 7 configure.ac
  2. +9 27 nouveau/Makefile.am
  3. +197 0 nouveau/abi16.c
  4. +170 0 nouveau/bufctx.c
  5. +1 1  nouveau/libdrm_nouveau.pc.in
  6. +489 0 nouveau/nouveau.c
  7. +211 0 nouveau/nouveau.h
  8. +0 549 nouveau/nouveau_bo.c
  9. +0 104 nouveau/nouveau_bo.h
  10. +0 142 nouveau/nouveau_channel.c
  11. +0 57 nouveau/nouveau_channel.h
  12. +0 198 nouveau/nouveau_device.c
  13. +0 33 nouveau/nouveau_device.h
  14. +0 58 nouveau/nouveau_drmif.h
  15. +0 148 nouveau/nouveau_grobj.c
  16. +0 48 nouveau/nouveau_grobj.h
  17. +0 148 nouveau/nouveau_notifier.c
  18. +0 63 nouveau/nouveau_notifier.h
  19. +0 136 nouveau/nouveau_private.h
  20. +0 344 nouveau/nouveau_pushbuf.c
  21. +0 162 nouveau/nouveau_pushbuf.h
  22. +0 154 nouveau/nouveau_reloc.c
  23. +0 32 nouveau/nouveau_reloc.h
  24. +0 124 nouveau/nouveau_resource.c
  25. +0 51 nouveau/nouveau_resource.h
  26. +0 66 nouveau/nv04_pushbuf.h
  27. +0 92 nouveau/nvc0_pushbuf.h
  28. +122 0 nouveau/private.h
  29. +774 0 nouveau/pushbuf.c
25 configure.ac
@@ -73,16 +73,16 @@ AC_ARG_ENABLE(radeon,
73 73 [Enable support for radeon's KMS API (default: auto)]),
74 74 [RADEON=$enableval], [RADEON=auto])
75 75
  76 +AC_ARG_ENABLE(nouveau,
  77 + AS_HELP_STRING([--disable-nouveau],
  78 + [Enable support for nouveau's KMS API (default: auto)]),
  79 + [NOUVEAU=$enableval], [NOUVEAU=auto])
  80 +
76 81 AC_ARG_ENABLE(vmwgfx-experimental-api,
77 82 AS_HELP_STRING([--enable-vmwgfx-experimental-api],
78 83 [Install vmwgfx's experimental kernel API header (default: disabled)]),
79 84 [VMWGFX=$enableval], [VMWGFX=no])
80 85
81   -AC_ARG_ENABLE(nouveau-experimental-api,
82   - AS_HELP_STRING([--enable-nouveau-experimental-api],
83   - [Enable support for nouveau's experimental API (default: disabled)]),
84   - [NOUVEAU=$enableval], [NOUVEAU=no])
85   -
86 86 AC_ARG_ENABLE(omap-experimental-api,
87 87 AS_HELP_STRING([--enable-omap-experimental-api],
88 88 [Enable support for OMAP's experimental API (default: disabled)]),
@@ -204,7 +204,7 @@ if test "x$HAVE_LIBUDEV" = xyes; then
204 204 fi
205 205 AM_CONDITIONAL(HAVE_LIBUDEV, [test "x$HAVE_LIBUDEV" = xyes])
206 206
207   -if test "x$INTEL" != "xno" -o "x$RADEON" != "xno"; then
  207 +if test "x$INTEL" != "xno" -o "x$RADEON" != "xno" -o "x$NOUVEAU" != "xno"; then
208 208 # Check for atomic intrinsics
209 209 AC_CACHE_CHECK([for native atomic primitives], drm_cv_atomic_primitives,
210 210 [
@@ -252,7 +252,14 @@ if test "x$INTEL" != "xno" -o "x$RADEON" != "xno"; then
252 252 AC_MSG_WARN([Disabling libdrm_radeon. It depends on atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package.])
253 253 RADEON=no
254 254 fi
255   -
  255 + if test "x$NOUVEAU" != "xauto"; then
  256 + if test "x$NOUVEAU" != "xno"; then
  257 + AC_MSG_ERROR([libdrm_nouveau depends upon atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package, or, failing both of those, disable support for NVIDIA GPUs by passing --disable-nouveau to ./configure])
  258 + fi
  259 + else
  260 + AC_MSG_WARN([Disabling libdrm_nouveau. It depends on atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package.])
  261 + NOUVEAU=no
  262 + fi
256 263 else
257 264 if test "x$INTEL" != "xno"; then
258 265 case $host_cpu in
@@ -263,6 +270,9 @@ if test "x$INTEL" != "xno" -o "x$RADEON" != "xno"; then
263 270 if test "x$RADEON" != "xno"; then
264 271 RADEON=yes
265 272 fi
  273 + if test "x$NOUVEAU" != "xno"; then
  274 + NOUVEAU=yes
  275 + fi
266 276 fi
267 277 fi
268 278
@@ -279,6 +289,7 @@ fi
279 289
280 290 AM_CONDITIONAL(HAVE_INTEL, [test "x$INTEL" != "xno"])
281 291 AM_CONDITIONAL(HAVE_RADEON, [test "x$RADEON" != "xno"])
  292 +AM_CONDITIONAL(HAVE_NOUVEAU, [test "x$NOUVEAU" != "xno"])
282 293 if test "x$RADEON" = xyes; then
283 294 AC_DEFINE(HAVE_RADEON, 1, [Have radeon support])
284 295 fi
36 nouveau/Makefile.am
@@ -3,41 +3,23 @@ AM_CFLAGS = \
3 3 -I$(top_srcdir) \
4 4 -I$(top_srcdir)/nouveau \
5 5 $(PTHREADSTUBS_CFLAGS) \
6   - -I$(top_srcdir)/include/drm
  6 + -I$(top_srcdir)/include/drm \
  7 + -DDEBUG
7 8
8 9 libdrm_nouveau_la_LTLIBRARIES = libdrm_nouveau.la
9 10 libdrm_nouveau_ladir = $(libdir)
10   -libdrm_nouveau_la_LDFLAGS = -version-number 1:0:0 -no-undefined
  11 +libdrm_nouveau_la_LDFLAGS = -version-number 2:0:0 -no-undefined
11 12 libdrm_nouveau_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
12 13
13   -libdrm_nouveau_la_SOURCES = \
14   - nouveau_device.c \
15   - nouveau_channel.c \
16   - nouveau_pushbuf.c \
17   - nouveau_grobj.c \
18   - nouveau_notifier.c \
19   - nouveau_bo.c \
20   - nouveau_resource.c \
21   - nouveau_private.h \
22   - nouveau_reloc.c
23   -
24   -libdrm_nouveaucommonincludedir = ${includedir}/nouveau
25   -libdrm_nouveaucommoninclude_HEADERS = \
26   - nouveau_device.h \
27   - nouveau_channel.h \
28   - nouveau_grobj.h \
29   - nouveau_notifier.h \
30   - nouveau_pushbuf.h \
31   - nv04_pushbuf.h \
32   - nvc0_pushbuf.h \
33   - nouveau_bo.h \
34   - nouveau_resource.h \
35   - nouveau_reloc.h
  14 +libdrm_nouveau_la_SOURCES = nouveau.c \
  15 + pushbuf.c \
  16 + bufctx.c \
  17 + abi16.c \
  18 + private.h
36 19
37 20
38 21 libdrm_nouveauincludedir = ${includedir}/libdrm
39   -libdrm_nouveauinclude_HEADERS = \
40   - nouveau_drmif.h
  22 +libdrm_nouveauinclude_HEADERS = nouveau.h
41 23
42 24 pkgconfigdir = @pkgconfigdir@
43 25 pkgconfig_DATA = libdrm_nouveau.pc
197 nouveau/abi16.c
... ... @@ -0,0 +1,197 @@
  1 +/*
  2 + * Copyright 2012 Red Hat Inc.
  3 + *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a
  5 + * copy of this software and associated documentation files (the "Software"),
  6 + * to deal in the Software without restriction, including without limitation
  7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 + * and/or sell copies of the Software, and to permit persons to whom the
  9 + * Software is furnished to do so, subject to the following conditions:
  10 + *
  11 + * The above copyright notice and this permission notice shall be included in
  12 + * all copies or substantial portions of the Software.
  13 + *
  14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 + * OTHER DEALINGS IN THE SOFTWARE.
  21 + *
  22 + * Authors: Ben Skeggs
  23 + */
  24 +
  25 +#include <stdlib.h>
  26 +#include <stdint.h>
  27 +
  28 +#include "private.h"
  29 +
  30 +int
  31 +abi16_chan_nv04(struct nouveau_object *obj)
  32 +{
  33 + struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
  34 + struct drm_nouveau_channel_alloc req;
  35 + struct nv04_fifo *nv04 = obj->data;
  36 + int ret;
  37 +
  38 + req.fb_ctxdma_handle = nv04->vram;
  39 + req.tt_ctxdma_handle = nv04->gart;
  40 +
  41 + ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
  42 + &req, sizeof(req));
  43 + if (ret)
  44 + return ret;
  45 +
  46 + nv04->base.channel = req.channel;
  47 + nv04->base.pushbuf = req.pushbuf_domains;
  48 + nv04->notify = req.notifier_handle;
  49 + nv04->base.object->handle = req.channel;
  50 + nv04->base.object->length = sizeof(*nv04);
  51 + return 0;
  52 +}
  53 +
  54 +int
  55 +abi16_chan_nvc0(struct nouveau_object *obj)
  56 +{
  57 + struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
  58 + struct drm_nouveau_channel_alloc req;
  59 + struct nvc0_fifo *nvc0 = obj->data;
  60 + int ret;
  61 +
  62 + ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
  63 + &req, sizeof(req));
  64 + if (ret)
  65 + return ret;
  66 +
  67 + nvc0->base.channel = req.channel;
  68 + nvc0->base.pushbuf = req.pushbuf_domains;
  69 + nvc0->base.object->handle = req.channel;
  70 + nvc0->base.object->length = sizeof(*nvc0);
  71 + return 0;
  72 +}
  73 +
  74 +int
  75 +abi16_engobj(struct nouveau_object *obj)
  76 +{
  77 + struct drm_nouveau_grobj_alloc req = {
  78 + obj->parent->handle, obj->handle, obj->oclass
  79 + };
  80 + struct nouveau_device *dev;
  81 + int ret;
  82 +
  83 + dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
  84 + ret = drmCommandWrite(dev->fd, DRM_NOUVEAU_GROBJ_ALLOC,
  85 + &req, sizeof(req));
  86 + if (ret)
  87 + return ret;
  88 +
  89 + obj->length = sizeof(struct nouveau_object *);
  90 + return 0;
  91 +}
  92 +
  93 +int
  94 +abi16_ntfy(struct nouveau_object *obj)
  95 +{
  96 + struct nv04_notify *ntfy = obj->data;
  97 + struct drm_nouveau_notifierobj_alloc req = {
  98 + obj->parent->handle, ntfy->object->handle, ntfy->length
  99 + };
  100 + struct nouveau_device *dev;
  101 + int ret;
  102 +
  103 + dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
  104 + ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
  105 + &req, sizeof(req));
  106 + if (ret)
  107 + return ret;
  108 +
  109 + ntfy->offset = req.offset;
  110 + ntfy->object->length = sizeof(*ntfy);
  111 + return 0;
  112 +}
  113 +
  114 +void
  115 +abi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info)
  116 +{
  117 + struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
  118 +
  119 + nvbo->map_handle = info->map_handle;
  120 + bo->handle = info->handle;
  121 + bo->size = info->size;
  122 + bo->offset = info->offset;
  123 +
  124 + bo->flags = 0;
  125 + if (info->domain & NOUVEAU_GEM_DOMAIN_VRAM)
  126 + bo->flags |= NOUVEAU_BO_VRAM;
  127 + if (info->domain & NOUVEAU_GEM_DOMAIN_GART)
  128 + bo->flags |= NOUVEAU_BO_GART;
  129 + if (!(info->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG))
  130 + bo->flags |= NOUVEAU_BO_CONTIG;
  131 + if (nvbo->map_handle)
  132 + bo->flags |= NOUVEAU_BO_MAP;
  133 +
  134 + if (bo->device->chipset >= 0xc0) {
  135 + bo->config.nvc0.memtype = (info->tile_flags & 0xff00) >> 8;
  136 + bo->config.nvc0.tile_mode = info->tile_mode;
  137 + } else
  138 + if (bo->device->chipset >= 0x80 || bo->device->chipset == 0x50) {
  139 + bo->config.nv50.memtype = (info->tile_flags & 0x07f00) >> 8 |
  140 + (info->tile_flags & 0x30000) >> 9;
  141 + bo->config.nv50.tile_mode = info->tile_mode << 4;
  142 + } else {
  143 + bo->config.nv04.surf_flags = info->tile_flags & 7;
  144 + bo->config.nv04.surf_pitch = info->tile_mode;
  145 + }
  146 +}
  147 +
  148 +int
  149 +abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment,
  150 + union nouveau_bo_config *config)
  151 +{
  152 + struct nouveau_device *dev = bo->device;
  153 + struct drm_nouveau_gem_new req = {};
  154 + struct drm_nouveau_gem_info *info = &req.info;
  155 + int ret;
  156 +
  157 + if (bo->flags & NOUVEAU_BO_VRAM)
  158 + info->domain |= NOUVEAU_GEM_DOMAIN_VRAM;
  159 + if (bo->flags & NOUVEAU_BO_GART)
  160 + info->domain |= NOUVEAU_GEM_DOMAIN_GART;
  161 + if (!info->domain)
  162 + info->domain |= NOUVEAU_GEM_DOMAIN_VRAM |
  163 + NOUVEAU_GEM_DOMAIN_GART;
  164 +
  165 + if (bo->flags & NOUVEAU_BO_MAP)
  166 + info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE;
  167 +
  168 + if (!(bo->flags & NOUVEAU_BO_CONTIG))
  169 + info->tile_flags = NOUVEAU_GEM_TILE_NONCONTIG;
  170 +
  171 + info->size = bo->size;
  172 + req.align = alignment;
  173 +
  174 + if (config) {
  175 + if (dev->chipset >= 0xc0) {
  176 + info->tile_flags = (config->nvc0.memtype & 0xff) << 8;
  177 + info->tile_mode = config->nvc0.tile_mode;
  178 + } else
  179 + if (dev->chipset >= 0x80 || dev->chipset == 0x50) {
  180 + info->tile_flags = (config->nv50.memtype & 0x07f) << 8 |
  181 + (config->nv50.memtype & 0x180) << 9;
  182 + info->tile_mode = config->nv50.tile_mode >> 4;
  183 + } else {
  184 + info->tile_flags = config->nv04.surf_flags & 7;
  185 + info->tile_mode = config->nv04.surf_pitch;
  186 + }
  187 + }
  188 +
  189 + if (!nouveau_device(dev)->have_bo_usage)
  190 + info->tile_flags &= 0x0000ff00;
  191 +
  192 + ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_NEW,
  193 + &req, sizeof(req));
  194 + if (ret == 0)
  195 + abi16_bo_info(bo, &req.info);
  196 + return ret;
  197 +}
170 nouveau/bufctx.c
... ... @@ -0,0 +1,170 @@
  1 +/*
  2 + * Copyright 2012 Red Hat Inc.
  3 + *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a
  5 + * copy of this software and associated documentation files (the "Software"),
  6 + * to deal in the Software without restriction, including without limitation
  7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 + * and/or sell copies of the Software, and to permit persons to whom the
  9 + * Software is furnished to do so, subject to the following conditions:
  10 + *
  11 + * The above copyright notice and this permission notice shall be included in
  12 + * all copies or substantial portions of the Software.
  13 + *
  14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 + * OTHER DEALINGS IN THE SOFTWARE.
  21 + *
  22 + * Authors: Ben Skeggs
  23 + */
  24 +
  25 +#ifdef HAVE_CONFIG_H
  26 +#include <config.h>
  27 +#endif
  28 +
  29 +#include <stdio.h>
  30 +#include <stdlib.h>
  31 +#include <stdint.h>
  32 +#include <stdbool.h>
  33 +#include <assert.h>
  34 +#include <errno.h>
  35 +
  36 +#include "libdrm_lists.h"
  37 +
  38 +#include "nouveau.h"
  39 +#include "private.h"
  40 +
  41 +struct nouveau_bufref_priv {
  42 + struct nouveau_bufref base;
  43 + struct nouveau_bufref_priv *next;
  44 + struct nouveau_bufctx *bufctx;
  45 +};
  46 +
  47 +static inline struct nouveau_bufref_priv *
  48 +nouveau_bufref(struct nouveau_bufref *bctx)
  49 +{
  50 + return (struct nouveau_bufref_priv *)bctx;
  51 +}
  52 +
  53 +struct nouveau_bufbin_priv {
  54 + struct nouveau_bufref_priv *list;
  55 + int relocs;
  56 +};
  57 +
  58 +struct nouveau_bufctx_priv {
  59 + struct nouveau_bufctx base;
  60 + struct nouveau_bufref_priv *free;
  61 + int nr_bins;
  62 + struct nouveau_bufbin_priv bins[];
  63 +};
  64 +
  65 +static inline struct nouveau_bufctx_priv *
  66 +nouveau_bufctx(struct nouveau_bufctx *bctx)
  67 +{
  68 + return (struct nouveau_bufctx_priv *)bctx;
  69 +}
  70 +
  71 +int
  72 +nouveau_bufctx_new(struct nouveau_client *client, int bins,
  73 + struct nouveau_bufctx **pbctx)
  74 +{
  75 + struct nouveau_bufctx_priv *priv;
  76 +
  77 + priv = calloc(1, sizeof(*priv) + sizeof(priv->bins[0]) * bins);
  78 + if (priv) {
  79 + DRMINITLISTHEAD(&priv->base.head);
  80 + DRMINITLISTHEAD(&priv->base.pending);
  81 + DRMINITLISTHEAD(&priv->base.current);
  82 + priv->base.client = client;
  83 + priv->nr_bins = bins;
  84 + *pbctx = &priv->base;
  85 + return 0;
  86 + }
  87 +
  88 + return -ENOMEM;
  89 +}
  90 +
  91 +void
  92 +nouveau_bufctx_del(struct nouveau_bufctx **pbctx)
  93 +{
  94 + struct nouveau_bufctx_priv *pctx = nouveau_bufctx(*pbctx);
  95 + struct nouveau_bufref_priv *pref;
  96 + if (pctx) {
  97 + while (pctx->nr_bins--)
  98 + nouveau_bufctx_reset(&pctx->base, pctx->nr_bins);
  99 + while ((pref = pctx->free)) {
  100 + pctx->free = pref->next;
  101 + free(pref);
  102 + }
  103 + free(pctx);
  104 + *pbctx = NULL;
  105 + }
  106 +}
  107 +
  108 +void
  109 +nouveau_bufctx_reset(struct nouveau_bufctx *bctx, int bin)
  110 +{
  111 + struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx);
  112 + struct nouveau_bufbin_priv *pbin = &pctx->bins[bin];
  113 + struct nouveau_bufref_priv *pref;
  114 +
  115 + while ((pref = pbin->list)) {
  116 + DRMLISTDELINIT(&pref->base.thead);
  117 + pbin->list = pref->next;
  118 + pref->next = pctx->free;
  119 + pctx->free = pref;
  120 + }
  121 +
  122 + bctx->relocs -= pbin->relocs;
  123 + pbin->relocs = 0;
  124 +}
  125 +
  126 +struct nouveau_bufref *
  127 +nouveau_bufctx_refn(struct nouveau_bufctx *bctx, int bin,
  128 + struct nouveau_bo *bo, uint32_t flags)
  129 +{
  130 + struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx);
  131 + struct nouveau_bufbin_priv *pbin = &pctx->bins[bin];
  132 + struct nouveau_bufref_priv *pref = pctx->free;
  133 +
  134 + if (!pref)
  135 + pref = malloc(sizeof(*pref));
  136 + else
  137 + pctx->free = pref->next;
  138 +
  139 + if (pref) {
  140 + pref->base.bo = bo;
  141 + pref->base.flags = flags;
  142 + pref->base.packet = 0;
  143 +
  144 + DRMLISTADDTAIL(&pref->base.thead, &bctx->pending);
  145 + pref->bufctx = bctx;
  146 + pref->next = pbin->list;
  147 + pbin->list = pref;
  148 + }
  149 +
  150 + return &pref->base;
  151 +}
  152 +
  153 +struct nouveau_bufref *
  154 +nouveau_bufctx_mthd(struct nouveau_bufctx *bctx, int bin, uint32_t packet,
  155 + struct nouveau_bo *bo, uint64_t data, uint32_t flags,
  156 + uint32_t vor, uint32_t tor)
  157 +{
  158 + struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx);
  159 + struct nouveau_bufbin_priv *pbin = &pctx->bins[bin];
  160 + struct nouveau_bufref *bref = nouveau_bufctx_refn(bctx, bin, bo, flags);
  161 + if (bref) {
  162 + bref->packet = packet;
  163 + bref->data = data;
  164 + bref->vor = vor;
  165 + bref->tor = tor;
  166 + pbin->relocs++;
  167 + bctx->relocs++;
  168 + }
  169 + return bref;
  170 +}
2  nouveau/libdrm_nouveau.pc.in
@@ -5,7 +5,7 @@ includedir=@includedir@
5 5
6 6 Name: libdrm_nouveau
7 7 Description: Userspace interface to nouveau kernel DRM services
8   -Version: 0.6
  8 +Version: 2.4.33
9 9 Libs: -L${libdir} -ldrm_nouveau
10 10 Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/nouveau
11 11 Requires.private: libdrm
489 nouveau/nouveau.c
... ... @@ -0,0 +1,489 @@
  1 +/*
  2 + * Copyright 2012 Red Hat Inc.
  3 + *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a
  5 + * copy of this software and associated documentation files (the "Software"),
  6 + * to deal in the Software without restriction, including without limitation
  7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 + * and/or sell copies of the Software, and to permit persons to whom the
  9 + * Software is furnished to do so, subject to the following conditions:
  10 + *
  11 + * The above copyright notice and this permission notice shall be included in
  12 + * all copies or substantial portions of the Software.
  13 + *
  14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 + * OTHER DEALINGS IN THE SOFTWARE.
  21 + *
  22 + * Authors: Ben Skeggs
  23 + */
  24 +
  25 +#ifdef HAVE_CONFIG_H
  26 +#include <config.h>
  27 +#endif
  28 +
  29 +#include <stdio.h>
  30 +#include <stdlib.h>
  31 +#include <stdint.h>
  32 +#include <string.h>
  33 +#include <stdbool.h>
  34 +#include <assert.h>
  35 +#include <errno.h>
  36 +#include <sys/mman.h>
  37 +
  38 +#include <xf86drm.h>
  39 +#include <xf86atomic.h>
  40 +#include "libdrm_lists.h"
  41 +#include "nouveau_drm.h"
  42 +
  43 +#include "nouveau.h"
  44 +#include "private.h"
  45 +
  46 +#ifdef DEBUG
  47 +uint32_t nouveau_debug = 0;
  48 +
  49 +static void
  50 +debug_init(char *args)
  51 +{
  52 + if (args) {
  53 + int n = strtol(args, NULL, 0);
  54 + if (n >= 0)
  55 + nouveau_debug = n;
  56 + }
  57 +}
  58 +#endif
  59 +
  60 +/* this is the old libdrm's version of nouveau_device_wrap(), the symbol
  61 + * is kept here to prevent AIGLX from crashing if the DDX is linked against
  62 + * the new libdrm, but the DRI driver against the old
  63 + */
  64 +int
  65 +nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd,
  66 + drm_context_t ctx)
  67 +{
  68 + return -EACCES;
  69 +}
  70 +
  71 +int
  72 +nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
  73 +{
  74 + struct nouveau_device_priv *nvdev = calloc(1, sizeof(*nvdev));
  75 + struct nouveau_device *dev = &nvdev->base;
  76 + uint64_t chipset, vram, gart, bousage;
  77 + drmVersionPtr ver;
  78 + int ret;
  79 +
  80 +#ifdef DEBUG
  81 + debug_init(getenv("NOUVEAU_LIBDRM_DEBUG"));
  82 +#endif
  83 +
  84 + if (!nvdev)
  85 + return -ENOMEM;
  86 + nvdev->base.fd = fd;
  87 +
  88 + ver = drmGetVersion(fd);
  89 + if (ver) dev->drm_version = (ver->version_major << 24) |
  90 + (ver->version_minor << 8) |
  91 + ver->version_patchlevel;
  92 + drmFreeVersion(ver);
  93 +
  94 + if ( dev->drm_version != 0x00000010 &&
  95 + (dev->drm_version < 0x01000000 ||
  96 + dev->drm_version >= 0x02000000)) {
  97 + nouveau_device_del(&dev);
  98 + return -EINVAL;
  99 + }
  100 +
  101 + ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &chipset);
  102 + if (ret == 0)
  103 + ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &vram);
  104 + if (ret == 0)
  105 + ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &gart);
  106 + if (ret) {
  107 + nouveau_device_del(&dev);
  108 + return ret;
  109 + }
  110 +
  111 + ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &bousage);
  112 + if (ret == 0)
  113 + nvdev->have_bo_usage = (bousage != 0);
  114 +
  115 + nvdev->close = close;
  116 + DRMINITLISTHEAD(&nvdev->bo_list);
  117 + nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
  118 + nvdev->base.lib_version = 0x01000000;
  119 + nvdev->base.chipset = chipset;
  120 + nvdev->base.vram_size = vram;
  121 + nvdev->base.gart_size = gart;
  122 + nvdev->base.vram_limit = (nvdev->base.vram_size * 80) / 100;
  123 + nvdev->base.gart_limit = (nvdev->base.gart_size * 80) / 100;
  124 +
  125 + *pdev = &nvdev->base;
  126 + return 0;
  127 +}
  128 +
  129 +int
  130 +nouveau_device_open(const char *busid, struct nouveau_device **pdev)
  131 +{
  132 + int ret = -ENODEV, fd = drmOpen("nouveau", busid);
  133 + if (fd >= 0) {
  134 + ret = nouveau_device_wrap(fd, 1, pdev);
  135 + if (ret)
  136 + drmClose(fd);
  137 + }
  138 + return ret;
  139 +}
  140 +
  141 +void
  142 +nouveau_device_del(struct nouveau_device **pdev)
  143 +{
  144 + struct nouveau_device_priv *nvdev = nouveau_device(*pdev);
  145 + if (nvdev) {
  146 + if (nvdev->close)
  147 + drmClose(nvdev->base.fd);
  148 + free(nvdev->client);
  149 + free(nvdev);
  150 + *pdev = NULL;
  151 + }
  152 +}
  153 +
  154 +int
  155 +nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value)
  156 +{
  157 + struct drm_nouveau_getparam r = { param, 0 };
  158 + int fd = dev->fd, ret =
  159 + drmCommandWriteRead(fd, DRM_NOUVEAU_GETPARAM, &r, sizeof(r));
  160 + *value = r.value;
  161 + return ret;
  162 +}
  163 +
  164 +int
  165 +nouveau_setparam(struct nouveau_device *dev, uint64_t param, uint64_t value)
  166 +{
  167 + struct drm_nouveau_setparam r = { param, value };
  168 + return drmCommandWrite(dev->fd, DRM_NOUVEAU_SETPARAM, &r, sizeof(r));
  169 +}
  170 +
  171 +int
  172 +nouveau_client_new(struct nouveau_device *dev, struct nouveau_client **pclient)
  173 +{
  174 + struct nouveau_device_priv *nvdev = nouveau_device(dev);
  175 + struct nouveau_client_priv *pcli;
  176 + int id = 0, i, ret = -ENOMEM;
  177 + uint32_t *clients;
  178 +
  179 + for (i = 0; i < nvdev->nr_client; i++) {
  180 + id = ffs(nvdev->client[i]) - 1;
  181 + if (id >= 0)
  182 + goto out;
  183 + }
  184 +
  185 + clients = realloc(nvdev->client, sizeof(uint32_t) * (i + 1));
  186 + if (!clients)
  187 + return ret;
  188 + nvdev->client = clients;
  189 + nvdev->client[i] = 0;
  190 + nvdev->nr_client++;
  191 +
  192 +out:
  193 + pcli = calloc(1, sizeof(*pcli));
  194 + if (pcli) {
  195 + nvdev->client[i] |= (1 << id);
  196 + pcli->base.device = dev;
  197 + pcli->base.id = (i * 32) + id;
  198 + ret = 0;
  199 + }
  200 +
  201 + *pclient = &pcli->base;
  202 + return ret;
  203 +}
  204 +
  205 +void
  206 +nouveau_client_del(struct nouveau_client **pclient)
  207 +{
  208 + struct nouveau_client_priv *pcli = nouveau_client(*pclient);
  209 + struct nouveau_device_priv *nvdev;
  210 + if (pcli) {
  211 + int id = pcli->base.id;
  212 + nvdev = nouveau_device(pcli->base.device);
  213 + nvdev->client[id / 32] &= ~(1 << (id % 32));
  214 + free(pcli->kref);
  215 + free(pcli);
  216 + }
  217 +}
  218 +
  219 +int
  220 +nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
  221 + uint32_t oclass, void *data, uint32_t length,
  222 + struct nouveau_object **pobj)
  223 +{
  224 + struct nouveau_device *dev;
  225 + struct nouveau_object *obj;
  226 + int ret = -EINVAL;
  227 +
  228 + if (length == 0)
  229 + length = sizeof(struct nouveau_object *);
  230 + obj = malloc(sizeof(*obj) + length);
  231 + obj->parent = parent;
  232 + obj->handle = handle;
  233 + obj->oclass = oclass;
  234 + obj->length = length;
  235 + obj->data = obj + 1;
  236 + if (data)
  237 + memcpy(obj->data, data, length);
  238 + *(struct nouveau_object **)obj->data = obj;
  239 +
  240 + dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
  241 + switch (parent->oclass) {
  242 + case NOUVEAU_DEVICE_CLASS:
  243 + switch (obj->oclass) {
  244 + case NOUVEAU_FIFO_CHANNEL_CLASS:
  245 + {
  246 + if (dev->chipset < 0xc0)
  247 + ret = abi16_chan_nv04(obj);
  248 + else
  249 + ret = abi16_chan_nvc0(obj);
  250 + }
  251 + break;
  252 + default:
  253 + break;
  254 + }
  255 + break;
  256 + case NOUVEAU_FIFO_CHANNEL_CLASS:
  257 + switch (obj->oclass) {
  258 + case NOUVEAU_NOTIFIER_CLASS:
  259 + ret = abi16_ntfy(obj);
  260 + break;
  261 + default:
  262 + ret = abi16_engobj(obj);
  263 + break;
  264 + }
  265 + default:
  266 + break;
  267 + }
  268 +
  269 + if (ret) {
  270 + free(obj);
  271 + return ret;
  272 + }
  273 +
  274 + *pobj = obj;
  275 + return 0;
  276 +}
  277 +
  278 +void
  279 +nouveau_object_del(struct nouveau_object **pobj)
  280 +{
  281 + struct drm_nouveau_gpuobj_free req;
  282 + struct nouveau_object *obj = *pobj;
  283 + struct nouveau_device *dev;
  284 + if (obj) {
  285 + dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
  286 + req.channel = obj->parent->handle;
  287 + req.handle = obj->handle;
  288 + drmCommandWrite(dev->fd, DRM_NOUVEAU_GPUOBJ_FREE,
  289 + &req, sizeof(req));
  290 + }
  291 + free(obj);
  292 + *pobj = NULL;
  293 +}
  294 +
  295 +void *
  296 +nouveau_object_find(struct nouveau_object *obj, uint32_t pclass)
  297 +{
  298 + while (obj && obj->oclass != pclass) {
  299 + obj = obj->parent;
  300 + if (pclass == NOUVEAU_PARENT_CLASS)
  301 + break;
  302 + }
  303 + return obj;
  304 +}
  305 +
  306 +static void
  307 +nouveau_bo_del(struct nouveau_bo *bo)
  308 +{
  309 + struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
  310 + struct drm_gem_close req = { bo->handle };
  311 + DRMLISTDEL(&nvbo->head);
  312 + if (bo->map)
  313 + munmap(bo->map, bo->size);
  314 + drmIoctl(bo->device->fd, DRM_IOCTL_GEM_CLOSE, &req);
  315 + free(nvbo);
  316 +}
  317 +
  318 +int
  319 +nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, uint32_t align,
  320 + uint64_t size, union nouveau_bo_config *config,
  321 + struct nouveau_bo **pbo)
  322 +{
  323 + struct nouveau_device_priv *nvdev = nouveau_device(dev);
  324 + struct nouveau_bo_priv *nvbo = calloc(1, sizeof(*nvbo));
  325 + struct nouveau_bo *bo = &nvbo->base;
  326 + int ret;
  327 +
  328 + if (!nvbo)
  329 + return -ENOMEM;
  330 + atomic_set(&nvbo->refcnt, 1);
  331 + bo->device = dev;
  332 + bo->flags = flags;
  333 + bo->size = size;
  334 +
  335 + ret = abi16_bo_init(bo, align, config);
  336 + if (ret) {
  337 + free(nvbo);
  338 + return ret;
  339 + }
  340 +
  341 + DRMLISTADD(&nvbo->head, &nvdev->bo_list);
  342 +
  343 + *pbo = bo;
  344 + return 0;
  345 +}
  346 +
  347 +int
  348 +nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle,
  349 + struct nouveau_bo **pbo)
  350 +{
  351 + struct nouveau_device_priv *nvdev = nouveau_device(dev);
  352 + struct drm_nouveau_gem_info req = { .handle = handle };
  353 + struct nouveau_bo_priv *nvbo;
  354 + int ret;
  355 +
  356 + DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) {
  357 + if (nvbo->base.handle == handle) {
  358 + *pbo = NULL;
  359 + nouveau_bo_ref(&nvbo->base, pbo);
  360 + return 0;
  361 + }
  362 + }
  363 +
  364 + ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_INFO,
  365 + &req, sizeof(req));
  366 + if (ret)
  367 + return ret;
  368 +
  369 + nvbo = calloc(1, sizeof(*nvbo));
  370 + if (nvbo) {
  371 + atomic_set(&nvbo->refcnt, 1);
  372 + nvbo->base.device = dev;
  373 + abi16_bo_info(&nvbo->base, &req);
  374 + DRMLISTADD(&nvbo->head, &nvdev->bo_list);
  375 + *pbo = &nvbo->base;
  376 + return 0;
  377 + }
  378 +
  379 + return -ENOMEM;
  380 +}
  381 +
  382 +int
  383 +nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
  384 + struct nouveau_bo **pbo)
  385 +{
  386 + struct nouveau_device_priv *nvdev = nouveau_device(dev);
  387 + struct nouveau_bo_priv *nvbo;
  388 + struct drm_gem_open req = { .name = name };
  389 + int ret;
  390 +
  391 + DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) {
  392 + if (nvbo->name == name) {
  393 + *pbo = NULL;
  394 + nouveau_bo_ref(&nvbo->base, pbo);
  395 + return 0;
  396 + }
  397 + }
  398 +
  399 + ret = drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req);
  400 + if (ret == 0) {
  401 + ret = nouveau_bo_wrap(dev, req.handle, pbo);
  402 + nouveau_bo((*pbo))->name = name;
  403 + }
  404 +
  405 + return ret;
  406 +}
  407 +
  408 +int
  409 +nouveau_bo_name_get(struct nouveau_bo *bo, uint32_t *name)
  410 +{
  411 + struct drm_gem_flink req = { .handle = bo->handle };
  412 + struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
  413 + if (!nvbo->name) {
  414 + int ret = drmIoctl(bo->device->fd, DRM_IOCTL_GEM_FLINK, &req);
  415 + if (ret)
  416 + return ret;
  417 + nvbo->name = req.name;
  418 + }
  419 + *name = nvbo->name;
  420 + return 0;
  421 +}
  422 +
  423 +void
  424 +nouveau_bo_ref(struct nouveau_bo *bo, struct nouveau_bo **pref)
  425 +{
  426 + struct nouveau_bo *ref = *pref;
  427 + if (bo) {
  428 + atomic_inc(&nouveau_bo(bo)->refcnt);
  429 + }
  430 + if (ref) {
  431 + if (atomic_dec_and_test(&nouveau_bo(ref)->refcnt))
  432 + nouveau_bo_del(ref);
  433 + }
  434 + *pref = bo;
  435 +}
  436 +
  437 +int
  438 +nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access,
  439 + struct nouveau_client *client)
  440 +{
  441 + struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
  442 + struct drm_nouveau_gem_cpu_prep req;
  443 + struct nouveau_pushbuf *push;
  444 + int ret = 0;
  445 +
  446 + if (!(access & NOUVEAU_BO_RDWR))
  447 + return 0;
  448 +
  449 + push = cli_push_get(client, bo);
  450 + if (push && push->channel)
  451 + nouveau_pushbuf_kick(push, push->channel);
  452 +
  453 + if (!nvbo->name && !(nvbo->access & NOUVEAU_BO_WR) &&
  454 + !( access & NOUVEAU_BO_WR))
  455 + return 0;
  456 +
  457 + req.handle = bo->handle;
  458 + req.flags = 0;
  459 + if (access & NOUVEAU_BO_WR)
  460 + req.flags |= NOUVEAU_GEM_CPU_PREP_WRITE;
  461 + if (access & NOUVEAU_BO_NOBLOCK)
  462 + req.flags |= NOUVEAU_GEM_CPU_PREP_NOWAIT;
  463 +
  464 + do {
  465 + ret = drmCommandWrite(bo->device->fd,
  466 + DRM_NOUVEAU_GEM_CPU_PREP,
  467 + &req, sizeof(req));
  468 + } while (ret == -EAGAIN);
  469 +
  470 + if (ret == 0)
  471 + nvbo->access = 0;
  472 + return ret;
  473 +}
  474 +
  475 +int
  476 +nouveau_bo_map(struct nouveau_bo *bo, uint32_t access,
  477 + struct nouveau_client *client)
  478 +{
  479 + struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
  480 + if (bo->map == NULL) {
  481 + bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE,
  482 + MAP_SHARED, bo->device->fd, nvbo->map_handle);
  483 + if (bo->map == MAP_FAILED) {
  484 + bo->map = NULL;
  485 + return -errno;
  486 + }
  487 + }
  488 + return nouveau_bo_wait(bo, access, client);
  489 +}
211 nouveau/nouveau.h
... ... @@ -0,0 +1,211 @@
  1 +#ifndef __NOUVEAU_H__
  2 +#define __NOUVEAU_H__
  3 +
  4 +#include <stdint.h>
  5 +#include <stdbool.h>
  6 +
  7 +#define NOUVEAU_DEVICE_CLASS 0x80000000
  8 +#define NOUVEAU_FIFO_CHANNEL_CLASS 0x80000001
  9 +#define NOUVEAU_NOTIFIER_CLASS 0x80000002
  10 +#define NOUVEAU_PARENT_CLASS 0xffffffff
  11 +
  12 +struct nouveau_list {
  13 + struct nouveau_list *prev;
  14 + struct nouveau_list *next;
  15 +};
  16 +
  17 +struct nouveau_object {
  18 + struct nouveau_object *parent;
  19 + uint64_t handle;
  20 + uint32_t oclass;
  21 + uint32_t length;
  22 + void *data;
  23 +};
  24 +
  25 +struct nouveau_fifo {
  26 + struct nouveau_object *object;
  27 + uint32_t channel;
  28 + uint32_t pushbuf;
  29 + uint64_t unused1[3];
  30 +};
  31 +
  32 +struct nv04_fifo {
  33 + struct nouveau_fifo base;
  34 + uint32_t vram;
  35 + uint32_t gart;
  36 + uint32_t notify;
  37 +};
  38 +
  39 +struct nvc0_fifo {
  40 + struct nouveau_fifo base;
  41 +};
  42 +
  43 +struct nv04_notify {
  44 + struct nouveau_object *object;
  45 + uint32_t offset;
  46 + uint32_t length;
  47 +};
  48 +
  49 +int nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
  50 + uint32_t oclass, void *data, uint32_t length,
  51 + struct nouveau_object **);
  52 +void nouveau_object_del(struct nouveau_object **);
  53 +void *nouveau_object_find(struct nouveau_object *, uint32_t parent_class);
  54 +
  55 +struct nouveau_device {
  56 + struct nouveau_object object;
  57 + int fd;
  58 + uint32_t lib_version;
  59 + uint32_t drm_version;
  60 + uint32_t chipset;
  61 + uint64_t vram_size;
  62 + uint64_t gart_size;
  63 + uint64_t vram_limit;
  64 + uint64_t gart_limit;
  65 +};
  66 +
  67 +int nouveau_device_wrap(int fd, int close, struct nouveau_device **);
  68 +int nouveau_device_open(const char *busid, struct nouveau_device **);
  69 +void nouveau_device_del(struct nouveau_device **);
  70 +int nouveau_getparam(struct nouveau_device *, uint64_t param, uint64_t *value);
  71 +int nouveau_setparam(struct nouveau_device *, uint64_t param, uint64_t value);
  72 +
  73 +struct nouveau_client {
  74 + struct nouveau_device *device;
  75 + int id;
  76 +};
  77 +
  78 +int nouveau_client_new(struct nouveau_device *, struct nouveau_client **);
  79 +void nouveau_client_del(struct nouveau_client **);
  80 +
  81 +union nouveau_bo_config {
  82 + struct {
  83 +#define NV04_BO_16BPP 0x00000001
  84 +#define NV04_BO_32BPP 0x00000002
  85 +#define NV04_BO_ZETA 0x00000004
  86 + uint32_t surf_flags;
  87 + uint32_t surf_pitch;
  88 + } nv04;
  89 + struct {
  90 + uint32_t memtype;
  91 + uint32_t tile_mode;
  92 + } nv50;
  93 + struct {
  94 + uint32_t memtype;
  95 + uint32_t tile_mode;
  96 + } nvc0;
  97 + uint32_t data[8];
  98 +};
  99 +
  100 +#define NOUVEAU_BO_VRAM 0x00000001
  101 +#define NOUVEAU_BO_GART 0x00000002
  102 +#define NOUVEAU_BO_APER (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART)
  103 +#define NOUVEAU_BO_RD 0x00000100
  104 +#define NOUVEAU_BO_WR 0x00000200
  105 +#define NOUVEAU_BO_RDWR (NOUVEAU_BO_RD | NOUVEAU_BO_WR)
  106 +#define NOUVEAU_BO_NOBLOCK 0x00000400
  107 +#define NOUVEAU_BO_LOW 0x00001000
  108 +#define NOUVEAU_BO_HIGH 0x00002000
  109 +#define NOUVEAU_BO_OR 0x00004000
  110 +#define NOUVEAU_BO_MAP 0x80000000
  111 +#define NOUVEAU_BO_CONTIG 0x40000000
  112 +#define NOUVEAU_BO_NOSNOOP 0x20000000
  113 +
  114 +struct nouveau_bo {
  115 + struct nouveau_device *device;
  116 + uint32_t handle;
  117 + uint64_t size;
  118 + uint32_t flags;
  119 + uint64_t offset;
  120 + void *map;
  121 + union nouveau_bo_config config;
  122 +};
  123 +
  124 +int nouveau_bo_new(struct nouveau_device *, uint32_t flags, uint32_t align,
  125 + uint64_t size, union nouveau_bo_config *,
  126 + struct nouveau_bo **);
  127 +int nouveau_bo_wrap(struct nouveau_device *, uint32_t handle,
  128 + struct nouveau_bo **);
  129 +int nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
  130 + struct nouveau_bo **);
  131 +int nouveau_bo_name_get(struct nouveau_bo *, uint32_t *name);
  132 +void nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **);
  133 +int nouveau_bo_map(struct nouveau_bo *, uint32_t access,
  134 + struct nouveau_client *);
  135 +int nouveau_bo_wait(struct nouveau_bo *, uint32_t access,
  136 + struct nouveau_client *);
  137 +
  138 +struct nouveau_bufref {
  139 + struct nouveau_list thead;
  140 + struct nouveau_bo *bo;
  141 + uint32_t packet;
  142 + uint32_t flags;
  143 + uint32_t data;
  144 + uint32_t vor;
  145 + uint32_t tor;
  146 + uint32_t priv_data;
  147 + void *priv;
  148 +};
  149 +
  150 +struct nouveau_bufctx {
  151 + struct nouveau_client *client;
  152 + struct nouveau_list head;
  153 + struct nouveau_list pending;
  154 + struct nouveau_list current;
  155 + int relocs;
  156 +};
  157 +
  158 +int nouveau_bufctx_new(struct nouveau_client *, int bins,
  159 + struct nouveau_bufctx **);
  160 +void nouveau_bufctx_del(struct nouveau_bufctx **);
  161 +struct nouveau_bufref *
  162 +nouveau_bufctx_refn(struct nouveau_bufctx *, int bin,
  163 + struct nouveau_bo *, uint32_t flags);
  164 +struct nouveau_bufref *
  165 +nouveau_bufctx_mthd(struct nouveau_bufctx *, int bin, uint32_t packet,
  166 + struct nouveau_bo *, uint64_t data, uint32_t flags,
  167 + uint32_t vor, uint32_t tor);
  168 +void nouveau_bufctx_reset(struct nouveau_bufctx *, int bin);
  169 +
  170 +struct nouveau_pushbuf_krec;
  171 +struct nouveau_pushbuf {
  172 + struct nouveau_client *client;
  173 + struct nouveau_object *channel;
  174 + struct nouveau_bufctx *bufctx;
  175 + void (*kick_notify)(struct nouveau_pushbuf *);
  176 + void *user_priv;
  177 + uint32_t rsvd_kick;
  178 + uint32_t flags;
  179 + uint32_t *cur;
  180 + uint32_t *end;
  181 +};
  182 +
  183 +struct nouveau_pushbuf_refn {
  184 + struct nouveau_bo *bo;
  185 + uint32_t flags;
  186 +};
  187 +
  188 +int nouveau_pushbuf_new(struct nouveau_client *, struct nouveau_object *channel,
  189 + int nr, uint32_t size, bool immediate,
  190 + struct nouveau_pushbuf **);
  191 +void nouveau_pushbuf_del(struct nouveau_pushbuf **);
  192 +int nouveau_pushbuf_space(struct nouveau_pushbuf *, uint32_t dwords,
  193 + uint32_t relocs, uint32_t pushes);
  194 +void nouveau_pushbuf_data(struct nouveau_pushbuf *, struct nouveau_bo *,
  195 + uint64_t offset, uint64_t length);
  196 +int nouveau_pushbuf_refn(struct nouveau_pushbuf *,
  197 + struct nouveau_pushbuf_refn *, int nr);
  198 +/* Emits a reloc into the push buffer at the current position, you *must*
  199 + * have previously added the referenced buffer to a buffer context, and
  200 + * validated it against the current push buffer.
  201 + */
  202 +void nouveau_pushbuf_reloc(struct nouveau_pushbuf *, struct nouveau_bo *,
  203 + uint32_t data, uint32_t flags,
  204 + uint32_t vor, uint32_t tor);
  205 +int nouveau_pushbuf_validate(struct nouveau_pushbuf *);
  206 +uint32_t nouveau_pushbuf_refd(struct nouveau_pushbuf *, struct nouveau_bo *);
  207 +int nouveau_pushbuf_kick(struct nouveau_pushbuf *, struct nouveau_object *channel);
  208 +struct nouveau_bufctx *
  209 +nouveau_pushbuf_bufctx(struct nouveau_pushbuf *, struct nouveau_bufctx *);
  210 +
  211 +#endif
549 nouveau/nouveau_bo.c
... ... @@ -1,549 +0,0 @@
1   -/*
2   - * Copyright 2007 Nouveau Project
3   - *
4   - * Permission is hereby granted, free of charge, to any person obtaining a
5   - * copy of this software and associated documentation files (the "Software"),
6   - * to deal in the Software without restriction, including without limitation
7   - * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8   - * and/or sell copies of the Software, and to permit persons to whom the
9   - * Software is furnished to do so, subject to the following conditions:
10   - *
11   - * The above copyright notice and this permission notice shall be included in
12   - * all copies or substantial portions of the Software.
13   - *
14   - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17   - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18   - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19   - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   - * SOFTWARE.
21   - */
22   -
23   -#ifdef HAVE_CONFIG_H
24   -#include <config.h>
25   -#endif
26