From: <th...@ke...> - 2009-02-20 09:20:35
|
configure.ac | 19 libdrm/Makefile.am | 2 libdrm/intel/Makefile.am | 1 libdrm/intel/intel_bufmgr_fake.c | 1 libdrm/intel/intel_bufmgr_gem.c | 92 libdrm/intel/intel_chipset.h | 71 libdrm/nouveau/Makefile.am | 40 libdrm/nouveau/libdrm_nouveau.pc.in | 10 libdrm/nouveau/nouveau_bo.c | 845 +++ libdrm/nouveau/nouveau_bo.h | 97 libdrm/nouveau/nouveau_channel.c | 178 libdrm/nouveau/nouveau_channel.h | 56 libdrm/nouveau/nouveau_class.h | 8006 ++++++++++++++++++++++++++++++++++++ libdrm/nouveau/nouveau_device.c | 186 libdrm/nouveau/nouveau_device.h | 31 libdrm/nouveau/nouveau_dma.c | 216 libdrm/nouveau/nouveau_dma.h | 154 libdrm/nouveau/nouveau_drmif.h | 59 libdrm/nouveau/nouveau_fence.c | 249 + libdrm/nouveau/nouveau_grobj.c | 138 libdrm/nouveau/nouveau_grobj.h | 48 libdrm/nouveau/nouveau_notifier.c | 146 libdrm/nouveau/nouveau_notifier.h | 63 libdrm/nouveau/nouveau_private.h | 203 libdrm/nouveau/nouveau_pushbuf.c | 276 + libdrm/nouveau/nouveau_pushbuf.h | 160 libdrm/nouveau/nouveau_resource.c | 115 libdrm/nouveau/nouveau_resource.h | 48 libdrm/xf86drmMode.c | 8 libdrm/xf86drmMode.h | 127 shared-core/i915_drm.h | 10 31 files changed, 11628 insertions(+), 27 deletions(-) New commits: commit f785d1a15e1bb7fd5370f538102efea624c2db5c Author: Thomas Hellstrom <thellstrom-at-vmware-dot-com> Date: Fri Feb 20 10:06:53 2009 +0100 Update to latest libdrm. diff --git a/configure.ac b/configure.ac index a842b8d..78039e2 100644 --- a/configure.ac +++ b/configure.ac @@ -42,6 +42,10 @@ AC_ARG_ENABLE(udev, AS_HELP_STRING([--enable-udev], [Enable support for using udev instead of mknod (default: disabled)]), [UDEV=$enableval], [UDEV=no]) +AC_ARG_ENABLE(nouveau-experimental-api, + AS_HELP_STRING([--enable-nouveau-experimental-api], + [Enable support for nouveau's experimental API (default: disabled)]), + [NOUVEAU=$enableval], [NOUVEAU=no]) dnl =========================================================================== dnl check compiler flags @@ -119,13 +123,28 @@ if test "x$UDEV" = xyes; then AC_DEFINE(UDEV, 1, [Have UDEV support]) fi +if test "x$NOUVEAU" = xyes; then +NOUVEAU_SUBDIR="nouveau" +AC_SUBST(NOUVEAU_SUBDIR) +fi + +PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no]) +if test "x$HAVE_CAIRO" = xyes; then + AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support]) +fi +AM_CONDITIONAL(HAVE_CAIRO, [test "x$HAVE_CAIRO" = xyes]) + + AC_SUBST(WARN_CFLAGS) AC_OUTPUT([ Makefile libdrm/Makefile libdrm/intel/Makefile + libdrm/nouveau/Makefile + libdrm/nouveau/libdrm_nouveau.pc shared-core/Makefile tests/Makefile tests/modeprint/Makefile tests/modetest/Makefile + linux-core/ttm/Makefile libdrm.pc]) diff --git a/libdrm/Makefile.am b/libdrm/Makefile.am index a568aac..76145bc 100644 --- a/libdrm/Makefile.am +++ b/libdrm/Makefile.am @@ -18,7 +18,7 @@ # 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. -SUBDIRS = . intel +SUBDIRS = . intel @NOUVEAU_SUBDIR@ libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) diff --git a/libdrm/intel/Makefile.am b/libdrm/intel/Makefile.am index 5e3dee0..c7526f6 100644 --- a/libdrm/intel/Makefile.am +++ b/libdrm/intel/Makefile.am @@ -39,6 +39,7 @@ libdrm_intel_la_SOURCES = \ intel_bufmgr_priv.h \ intel_bufmgr_fake.c \ intel_bufmgr_gem.c \ + intel_chipset.h \ mm.c \ mm.h diff --git a/libdrm/intel/intel_bufmgr_fake.c b/libdrm/intel/intel_bufmgr_fake.c index 0e46530..6c21625 100644 --- a/libdrm/intel/intel_bufmgr_fake.c +++ b/libdrm/intel/intel_bufmgr_fake.c @@ -1070,6 +1070,7 @@ drm_intel_fake_kick_all_locked(drm_intel_bufmgr_fake *bufmgr_fake) if (!(bo_fake->flags & BM_NO_BACKING_STORE)) bo_fake->dirty = 1; } + } static int diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c index b3702a1..51641b7 100644 --- a/libdrm/intel/intel_bufmgr_gem.c +++ b/libdrm/intel/intel_bufmgr_gem.c @@ -54,6 +54,7 @@ #include "errno.h" #include "intel_bufmgr.h" #include "intel_bufmgr_priv.h" +#include "intel_chipset.h" #include "string.h" #include "i915_drm.h" @@ -99,6 +100,8 @@ typedef struct _drm_intel_bufmgr_gem { struct drm_intel_gem_bo_bucket cache_bucket[DRM_INTEL_GEM_BO_BUCKETS]; uint64_t gtt_size; + int available_fences; + int pci_device; } drm_intel_bufmgr_gem; struct _drm_intel_bo_gem { @@ -165,6 +168,11 @@ struct _drm_intel_bo_gem { * the common case. */ int reloc_tree_size; + /** + * Number of potential fence registers required by this buffer and its + * relocations. + */ + int reloc_tree_fences; }; static void drm_intel_gem_bo_reference_locked(drm_intel_bo *bo); @@ -347,6 +355,7 @@ drm_intel_gem_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name, struct drm_i915_gem_busy busy; bo_gem = bucket->head; + memset(&busy, 0, sizeof(busy)); busy.handle = bo_gem->gem_handle; ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy); @@ -386,6 +395,7 @@ drm_intel_gem_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name, bo_gem->refcount = 1; bo_gem->validate_index = -1; bo_gem->reloc_tree_size = bo_gem->bo.size; + bo_gem->reloc_tree_fences = 0; bo_gem->used_as_reloc_target = 0; bo_gem->tiling_mode = I915_TILING_NONE; bo_gem->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; @@ -435,6 +445,7 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr, const char *name, bo_gem->gem_handle = open_arg.handle; bo_gem->global_name = handle; + memset(&get_tiling, 0, sizeof(get_tiling)); get_tiling.handle = bo_gem->gem_handle; ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &get_tiling); if (ret != 0) { @@ -443,6 +454,10 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr, const char *name, } bo_gem->tiling_mode = get_tiling.tiling_mode; bo_gem->swizzle_mode = get_tiling.swizzle_mode; + if (bo_gem->tiling_mode == I915_TILING_NONE) + bo_gem->reloc_tree_fences = 0; + else + bo_gem->reloc_tree_fences = 1; DBG("bo_create_from_handle: %d (%s)\n", handle, bo_gem->name); @@ -461,14 +476,6 @@ drm_intel_gem_bo_reference(drm_intel_bo *bo) } static void -dri_gem_bo_reference_locked(dri_bo *bo) -{ - drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo; - - bo_gem->refcount++; -} - -static void drm_intel_gem_bo_reference_locked(drm_intel_bo *bo) { drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo; @@ -488,6 +495,7 @@ drm_intel_gem_bo_free(drm_intel_bo *bo) munmap (bo_gem->virtual, bo_gem->bo.size); /* Close this object */ + memset(&close, 0, sizeof(close)); close.handle = bo_gem->gem_handle; ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close); if (ret != 0) { @@ -868,6 +876,7 @@ drm_intel_gem_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset, */ assert(!bo_gem->used_as_reloc_target); bo_gem->reloc_tree_size += target_bo_gem->reloc_tree_size; + bo_gem->reloc_tree_fences += target_bo_gem->reloc_tree_fences; /* Flag the target to disallow further relocations in it. */ target_bo_gem->used_as_reloc_target = 1; @@ -1004,6 +1013,7 @@ drm_intel_gem_bo_pin(drm_intel_bo *bo, uint32_t alignment) struct drm_i915_gem_pin pin; int ret; + memset(&pin, 0, sizeof(pin)); pin.handle = bo_gem->gem_handle; pin.alignment = alignment; @@ -1026,6 +1036,7 @@ drm_intel_gem_bo_unpin(drm_intel_bo *bo) struct drm_i915_gem_unpin unpin; int ret; + memset(&unpin, 0, sizeof(unpin)); unpin.handle = bo_gem->gem_handle; ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_UNPIN, &unpin); @@ -1047,6 +1058,11 @@ drm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t *tiling_mode, if (bo_gem->global_name == 0 && *tiling_mode == bo_gem->tiling_mode) return 0; + /* If we're going from non-tiling to tiling, bump fence count */ + if (bo_gem->tiling_mode == I915_TILING_NONE) + bo_gem->reloc_tree_fences++; + + memset(&set_tiling, 0, sizeof(set_tiling)); set_tiling.handle = bo_gem->gem_handle; set_tiling.tiling_mode = *tiling_mode; set_tiling.stride = stride; @@ -1059,6 +1075,10 @@ drm_intel_gem_bo_set_tiling(drm_intel_bo *bo, uint32_t *tiling_mode, bo_gem->tiling_mode = set_tiling.tiling_mode; bo_gem->swizzle_mode = set_tiling.swizzle_mode; + /* If we're going from tiling to non-tiling, drop fence count */ + if (bo_gem->tiling_mode == I915_TILING_NONE) + bo_gem->reloc_tree_fences--; + *tiling_mode = bo_gem->tiling_mode; return 0; } @@ -1083,6 +1103,7 @@ drm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t *name) int ret; if (!bo_gem->global_name) { + memset(&flink, 0, sizeof(flink)); flink.handle = bo_gem->gem_handle; ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_FLINK, &flink); @@ -1137,6 +1158,31 @@ drm_intel_gem_bo_get_aperture_space(drm_intel_bo *bo) } /** + * Count the number of buffers in this list that need a fence reg + * + * If the count is greater than the number of available regs, we'll have + * to ask the caller to resubmit a batch with fewer tiled buffers. + * + * This function over-counts if the same buffer is used multiple times. + */ +static unsigned int +drm_intel_gem_total_fences(drm_intel_bo **bo_array, int count) +{ + int i; + unsigned int total = 0; + + for (i = 0; i < count; i++) { + drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo_array[i]; + + if (bo_gem == NULL) + continue; + + total += bo_gem->reloc_tree_fences; + } + return total; +} + +/** * Clear the flag set by drm_intel_gem_bo_get_aperture_space() so we're ready * for the next drm_intel_bufmgr_check_aperture_space() call. */ @@ -1214,9 +1260,17 @@ drm_intel_gem_check_aperture_space(drm_intel_bo **bo_array, int count) drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo_array[0]->bufmgr; unsigned int total = 0; unsigned int threshold = bufmgr_gem->gtt_size * 3 / 4; + int total_fences; + + /* Check for fence reg constraints if necessary */ + if (bufmgr_gem->available_fences) { + total_fences = drm_intel_gem_total_fences(bo_array, count); + if (total_fences > bufmgr_gem->available_fences) + return -1; + } total = drm_intel_gem_estimate_batch_space(bo_array, count); - + if (total > threshold) total = drm_intel_gem_compute_batch_space(bo_array, count); @@ -1242,6 +1296,7 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size) { drm_intel_bufmgr_gem *bufmgr_gem; struct drm_i915_gem_get_aperture aperture; + drm_i915_getparam_t gp; int ret, i; bufmgr_gem = calloc(1, sizeof(*bufmgr_gem)); @@ -1265,6 +1320,25 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size) (int)bufmgr_gem->gtt_size / 1024); } + gp.param = I915_PARAM_CHIPSET_ID; + gp.value = &bufmgr_gem->pci_device; + ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp); + if (ret) { + fprintf(stderr, "get chip id failed: %d\n", ret); + fprintf(stderr, "param: %d, val: %d\n", gp.param, *gp.value); + } + + if (!IS_I965G(bufmgr_gem)) { + gp.param = I915_PARAM_NUM_FENCES_AVAIL; + gp.value = &bufmgr_gem->available_fences; + ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp); + if (ret) { + fprintf(stderr, "get fences failed: %d\n", ret); + fprintf(stderr, "param: %d, val: %d\n", gp.param, *gp.value); + bufmgr_gem->available_fences = 0; + } + } + /* Let's go with one relocation per every 2 dwords (but round down a bit * since a power of two will mean an extra page allocation for the reloc * buffer). diff --git a/libdrm/intel/intel_chipset.h b/libdrm/intel/intel_chipset.h new file mode 100644 index 0000000..0b3af02 --- /dev/null +++ b/libdrm/intel/intel_chipset.h @@ -0,0 +1,71 @@ +/* + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 _INTEL_CHIPSET_H +#define _INTEL_CHIPSET_H + +#define IS_I830(dev) ((dev)->pci_device == 0x3577) +#define IS_845G(dev) ((dev)->pci_device == 0x2562) +#define IS_I85X(dev) ((dev)->pci_device == 0x3582) +#define IS_I855(dev) ((dev)->pci_device == 0x3582) +#define IS_I865G(dev) ((dev)->pci_device == 0x2572) + +#define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a) +#define IS_I915GM(dev) ((dev)->pci_device == 0x2592) +#define IS_I945G(dev) ((dev)->pci_device == 0x2772) +#define IS_I945GM(dev) ((dev)->pci_device == 0x27A2 ||\ + (dev)->pci_device == 0x27AE) +#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \ + (dev)->pci_device == 0x2982 || \ + (dev)->pci_device == 0x2992 || \ + (dev)->pci_device == 0x29A2 || \ + (dev)->pci_device == 0x2A02 || \ + (dev)->pci_device == 0x2A12 || \ + (dev)->pci_device == 0x2A42 || \ + (dev)->pci_device == 0x2E02 || \ + (dev)->pci_device == 0x2E12 || \ + (dev)->pci_device == 0x2E22) + +#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) + +#define IS_GM45(dev) ((dev)->pci_device == 0x2A42) + +#define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \ + (dev)->pci_device == 0x2E12 || \ + (dev)->pci_device == 0x2E22) + +#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ + (dev)->pci_device == 0x29B2 || \ + (dev)->pci_device == 0x29D2) + +#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ + IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev)) + +#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ + IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev)) + +#endif /* _INTEL_CHIPSET_H */ diff --git a/libdrm/nouveau/Makefile.am b/libdrm/nouveau/Makefile.am new file mode 100644 index 0000000..80fb780 --- /dev/null +++ b/libdrm/nouveau/Makefile.am @@ -0,0 +1,40 @@ +AM_CFLAGS = \ + $(WARN_CFLAGS) \ + -I$(top_srcdir)/libdrm \ + -I$(top_srcdir)/libdrm/nouveau \ + $(PTHREADSTUBS_CFLAGS) \ + -I$(top_srcdir)/shared-core + +libdrm_nouveau_la_LTLIBRARIES = libdrm_nouveau.la +libdrm_nouveau_ladir = $(libdir) +libdrm_nouveau_la_LDFLAGS = -version-number 1:0:0 -no-undefined +libdrm_nouveau_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ + +libdrm_nouveau_la_SOURCES = \ + nouveau_device.c \ + nouveau_channel.c \ + nouveau_pushbuf.c \ + nouveau_grobj.c \ + nouveau_notifier.c \ + nouveau_bo.c \ + nouveau_resource.c \ + nouveau_dma.c \ + nouveau_fence.c + +libdrm_nouveaucommonincludedir = ${includedir}/nouveau +libdrm_nouveaucommoninclude_HEADERS = \ + nouveau_device.h \ + nouveau_channel.h \ + nouveau_grobj.h \ + nouveau_notifier.h \ + nouveau_pushbuf.h \ + nouveau_bo.h \ + nouveau_resource.h \ + nouveau_class.h + +libdrm_nouveauincludedir = ${includedir}/drm +libdrm_nouveauinclude_HEADERS = \ + nouveau_drmif.h + +pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = libdrm_nouveau.pc diff --git a/libdrm/nouveau/libdrm_nouveau.pc.in b/libdrm/nouveau/libdrm_nouveau.pc.in new file mode 100644 index 0000000..9e67a23 --- /dev/null +++ b/libdrm/nouveau/libdrm_nouveau.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libdrm_nouveau +Description: Userspace interface to nouveau kernel DRM services +Version: 0.5 +Libs: -L${libdir} -ldrm_nouveau +Cflags: -I${includedir} -I${includedir}/drm -I${includedir}/nouveau diff --git a/libdrm/nouveau/nouveau_bo.c b/libdrm/nouveau/nouveau_bo.c new file mode 100644 index 0000000..6b9877f --- /dev/null +++ b/libdrm/nouveau/nouveau_bo.c @@ -0,0 +1,845 @@ +/* + * Copyright 2007 Nouveau Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 <stdint.h> +#include <stdlib.h> +#include <errno.h> +#include <assert.h> + +#include <sys/mman.h> +#include <sys/ioctl.h> + +#include "nouveau_private.h" + +int +nouveau_bo_init(struct nouveau_device *dev) +{ + return 0; +} + +void +nouveau_bo_takedown(struct nouveau_device *dev) +{ +} + +static int +nouveau_bo_allocated(struct nouveau_bo_priv *nvbo) +{ + if (nvbo->sysmem || nvbo->handle || (nvbo->flags & NOUVEAU_BO_PIN)) + return 1; + return 0; +} + +static int +nouveau_bo_ualloc(struct nouveau_bo_priv *nvbo) +{ + if (nvbo->user || nvbo->sysmem) { + assert(nvbo->sysmem); + return 0; + } + + nvbo->sysmem = malloc(nvbo->size); + if (!nvbo->sysmem) + return -ENOMEM; + + return 0; +} + +static void +nouveau_bo_ufree(struct nouveau_bo_priv *nvbo) +{ + if (nvbo->sysmem) { + if (!nvbo->user) + free(nvbo->sysmem); + nvbo->sysmem = NULL; + } +} + +static void +nouveau_bo_kfree_nomm(struct nouveau_bo_priv *nvbo) +{ + struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device); + struct drm_nouveau_mem_free req; + + if (nvbo->map) { + drmUnmap(nvbo->map, nvbo->size); + nvbo->map = NULL; + } + + req.offset = nvbo->offset; + if (nvbo->domain & NOUVEAU_BO_GART) + req.flags = NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI; + else + if (nvbo->domain & NOUVEAU_BO_VRAM) + req.flags = NOUVEAU_MEM_FB; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_MEM_FREE, &req, sizeof(req)); + + nvbo->handle = 0; +} + +static void +nouveau_bo_kfree(struct nouveau_bo_priv *nvbo) +{ + struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device); + struct drm_gem_close req; + + if (!nvbo->handle) + return; + + if (!nvdev->mm_enabled) { + nouveau_bo_kfree_nomm(nvbo); + return; + } + + if (nvbo->map) { + munmap(nvbo->map, nvbo->size); + nvbo->map = NULL; + } + + req.handle = nvbo->handle; + nvbo->handle = 0; + ioctl(nvdev->fd, DRM_IOCTL_GEM_CLOSE, &req); +} + +static int +nouveau_bo_kalloc_nomm(struct nouveau_bo_priv *nvbo) +{ + struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device); + struct drm_nouveau_mem_alloc req; + int ret; + + if (nvbo->handle) + return 0; + + if (!(nvbo->flags & (NOUVEAU_BO_VRAM|NOUVEAU_BO_GART))) + nvbo->flags |= (NOUVEAU_BO_GART | NOUVEAU_BO_VRAM); + + req.size = nvbo->size; + req.alignment = nvbo->align; + req.flags = 0; + if (nvbo->flags & NOUVEAU_BO_VRAM) + req.flags |= NOUVEAU_MEM_FB; + if (nvbo->flags & NOUVEAU_BO_GART) + req.flags |= (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI); + if (nvbo->flags & NOUVEAU_BO_TILED) { + req.flags |= NOUVEAU_MEM_TILE; + if (nvbo->flags & NOUVEAU_BO_ZTILE) + req.flags |= NOUVEAU_MEM_TILE_ZETA; + } + req.flags |= NOUVEAU_MEM_MAPPED; + + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_MEM_ALLOC, + &req, sizeof(req)); + if (ret) + return ret; + + nvbo->handle = req.map_handle; + nvbo->size = req.size; + nvbo->offset = req.offset; + if (req.flags & (NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI)) + nvbo->domain = NOUVEAU_BO_GART; + else + if (req.flags & NOUVEAU_MEM_FB) + nvbo->domain = NOUVEAU_BO_VRAM; + + return 0; +} + +static int +nouveau_bo_kalloc(struct nouveau_bo_priv *nvbo, struct nouveau_channel *chan) +{ + struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device); + struct drm_nouveau_gem_new req; + int ret; + + if (nvbo->handle || (nvbo->flags & NOUVEAU_BO_PIN)) + return 0; + + if (!nvdev->mm_enabled) + return nouveau_bo_kalloc_nomm(nvbo); + + req.channel_hint = chan ? chan->id : 0; + + req.size = nvbo->size; + req.align = nvbo->align; + + req.domain = 0; + + if (nvbo->flags & NOUVEAU_BO_VRAM) + req.domain |= NOUVEAU_GEM_DOMAIN_VRAM; + + if (nvbo->flags & NOUVEAU_BO_GART) + req.domain |= NOUVEAU_GEM_DOMAIN_GART; + + if (nvbo->flags & NOUVEAU_BO_TILED) { + req.domain |= NOUVEAU_GEM_DOMAIN_TILE; + if (nvbo->flags & NOUVEAU_BO_ZTILE) + req.domain |= NOUVEAU_GEM_DOMAIN_TILE_ZETA; + } + + if (!req.domain) { + req.domain |= (NOUVEAU_GEM_DOMAIN_VRAM | + NOUVEAU_GEM_DOMAIN_GART); + } + + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_NEW, + &req, sizeof(req)); + if (ret) + return ret; + nvbo->handle = nvbo->base.handle = req.handle; + nvbo->size = req.size; + nvbo->domain = req.domain; + nvbo->offset = req.offset; + + return 0; +} + +static int +nouveau_bo_kmap_nomm(struct nouveau_bo_priv *nvbo) +{ + struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device); + int ret; + + ret = drmMap(nvdev->fd, nvbo->handle, nvbo->size, &nvbo->map); + if (ret) { + nvbo->map = NULL; + return ret; + } + + return 0; +} + +static int +nouveau_bo_kmap(struct nouveau_bo_priv *nvbo) +{ + struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device); + struct drm_nouveau_gem_mmap req; + int ret; + + if (nvbo->map) + return 0; + + if (!nvbo->handle) + return -EINVAL; + + if (!nvdev->mm_enabled) + return nouveau_bo_kmap_nomm(nvbo); + + req.handle = nvbo->handle; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_MMAP, + &req, sizeof(req)); + if (ret) + return ret; + + nvbo->map = (void *)(unsigned long)req.vaddr; + return 0; +} + +int +nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, + int size, struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + int ret; + + if (!dev || !bo || *bo) + return -EINVAL; + + nvbo = calloc(1, sizeof(struct nouveau_bo_priv)); + if (!nvbo) + return -ENOMEM; + nvbo->base.device = dev; + nvbo->base.size = size; + + nvbo->refcount = 1; + /* Don't set NOUVEAU_BO_PIN here, or nouveau_bo_allocated() will + * decided the buffer's already allocated when it's not. The + * call to nouveau_bo_pin() later will set this flag. + */ + nvbo->flags = (flags & ~NOUVEAU_BO_PIN); + nvbo->size = size; + nvbo->align = align; + + /*XXX: murder me violently */ + if (flags & NOUVEAU_BO_TILED) { + nvbo->base.tiled = 1; + if (flags & NOUVEAU_BO_ZTILE) + nvbo->base.tiled |= 2; + } + + if (flags & NOUVEAU_BO_PIN) { + ret = nouveau_bo_pin((void *)nvbo, nvbo->flags); + if (ret) { + nouveau_bo_ref(NULL, (void *)nvbo); + return ret; + } + } + + *bo = &nvbo->base; + return 0; +} + +int +nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size, + struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + int ret; + + ret = nouveau_bo_new(dev, 0, 0, size, bo); + if (ret) + return ret; + nvbo = nouveau_bo(*bo); + + nvbo->sysmem = ptr; + nvbo->user = 1; + return 0; +} + +int +nouveau_bo_fake(struct nouveau_device *dev, uint64_t offset, uint32_t flags, + uint32_t size, void *map, struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + int ret; + + ret = nouveau_bo_new(dev, flags & ~NOUVEAU_BO_PIN, 0, size, bo); + if (ret) + return ret; + nvbo = nouveau_bo(*bo); + + nvbo->flags = flags | NOUVEAU_BO_PIN; + nvbo->domain = (flags & (NOUVEAU_BO_VRAM|NOUVEAU_BO_GART)); + nvbo->offset = offset; + nvbo->size = nvbo->base.size = size; + nvbo->map = map; + nvbo->base.flags = nvbo->flags; + nvbo->base.offset = nvbo->offset; + return 0; +} + +int +nouveau_bo_handle_get(struct nouveau_bo *bo, uint32_t *handle) +{ + struct nouveau_device_priv *nvdev = nouveau_device(bo->device); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + int ret; + + if (!bo || !handle) + return -EINVAL; + + if (!nvdev->mm_enabled) + return -ENODEV; + + if (!nvbo->global_handle) { + struct drm_gem_flink req; + + ret = nouveau_bo_kalloc(nvbo, NULL); + if (ret) + return ret; + + req.handle = nvbo->handle; + ret = ioctl(nvdev->fd, DRM_IOCTL_GEM_FLINK, &req); + if (ret) { + nouveau_bo_kfree(nvbo); + return ret; + } + + nvbo->global_handle = req.name; + } + + *handle = nvbo->global_handle; + return 0; +} + +int +nouveau_bo_handle_ref(struct nouveau_device *dev, uint32_t handle, + struct nouveau_bo **bo) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct nouveau_bo_priv *nvbo; + struct drm_gem_open req; + int ret; + + ret = nouveau_bo_new(dev, 0, 0, 0, bo); + if (ret) + return ret; + nvbo = nouveau_bo(*bo); + + if (!nvdev->mm_enabled) { + nvbo->handle = 0; + nvbo->offset = handle; + nvbo->domain = NOUVEAU_BO_VRAM; + nvbo->flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN; + nvbo->base.offset = nvbo->offset; + nvbo->base.flags = nvbo->flags; + } else { + req.name = handle; + ret = ioctl(nvdev->fd, DRM_IOCTL_GEM_OPEN, &req); + if (ret) { + nouveau_bo_ref(NULL, bo); + return ret; + } + + nvbo->size = req.size; + nvbo->handle = req.handle; + } + + return 0; +} + +static void +nouveau_bo_del_cb(void *priv) +{ + struct nouveau_bo_priv *nvbo = priv; + + nouveau_bo_kfree(nvbo); + free(nvbo); +} + +static void +nouveau_bo_del(struct nouveau_bo **bo) +{ + struct nouveau_bo_priv *nvbo; + + if (!bo || !*bo) + return; + nvbo = nouveau_bo(*bo); + *bo = NULL; + + if (--nvbo->refcount) + return; + + if (nvbo->pending) { + nvbo->pending = NULL; + nouveau_pushbuf_flush(nvbo->pending_channel, 0); + } + + nouveau_bo_ufree(nvbo); + + if (!nouveau_device(nvbo->base.device)->mm_enabled && nvbo->fence) { + nouveau_fence_flush(nvbo->fence->channel); + if (nouveau_fence(nvbo->fence)->signalled) { + nouveau_bo_del_cb(nvbo); + } else { + nouveau_fence_signal_cb(nvbo->fence, + nouveau_bo_del_cb, nvbo); + } + } else { + nouveau_bo_del_cb(nvbo); + } +} + +int +nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pbo) +{ + if (!pbo) + return -EINVAL; + + if (ref) + nouveau_bo(ref)->refcount++; + + if (*pbo) + nouveau_bo_del(pbo); + + *pbo = ref; + return 0; +} + +static int +nouveau_bo_wait_nomm(struct nouveau_bo *bo, int cpu_write) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + int ret = 0; + + if (cpu_write) + ret = nouveau_fence_wait(&nvbo->fence); + else + ret = nouveau_fence_wait(&nvbo->wr_fence); + if (ret) + return ret; + + nvbo->write_marker = 0; + return 0; +} + +static int +nouveau_bo_wait(struct nouveau_bo *bo, int cpu_write) +{ + struct nouveau_device_priv *nvdev = nouveau_device(bo->device); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct drm_nouveau_gem_cpu_prep req; + int ret; + + if (!nvbo->global_handle && !nvbo->write_marker && !cpu_write) + return 0; + + if (nvbo->pending && + (nvbo->pending->write_domains || cpu_write)) { + nvbo->pending = NULL; + nouveau_pushbuf_flush(nvbo->pending_channel, 0); + } + + if (!nvdev->mm_enabled) + return nouveau_bo_wait_nomm(bo, cpu_write); + + req.handle = nvbo->handle; + ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GEM_CPU_PREP, + &req, sizeof(req)); + if (ret) + return ret; + + nvbo->write_marker = 0; + return 0; +} + +int +nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + int ret; + + if (!nvbo || bo->map) + return -EINVAL; + + if (!nouveau_bo_allocated(nvbo)) { + if (nvbo->flags & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART)) { + ret = nouveau_bo_kalloc(nvbo, NULL); + if (ret) + return ret; + } + + if (!nouveau_bo_allocated(nvbo)) { + ret = nouveau_bo_ualloc(nvbo); + if (ret) + return ret; + } + } + + if (nvbo->sysmem) { + bo->map = nvbo->sysmem; + } else { + ret = nouveau_bo_kmap(nvbo); + if (ret) + return ret; + + ret = nouveau_bo_wait(bo, (flags & NOUVEAU_BO_WR)); + if (ret) + return ret; + + bo->map = nvbo->map; + } + + return 0; +} + +void +nouveau_bo_unmap(struct nouveau_bo *bo) +{ + struct nouveau_device_priv *nvdev = nouveau_device(bo->device); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + + if (nvdev->mm_enabled && bo->map && !nvbo->sysmem) { + struct nouveau_device_priv *nvdev = nouveau_device(bo->device); + struct drm_nouveau_gem_cpu_fini req; + + req.handle = nvbo->handle; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GEM_CPU_FINI, + &req, sizeof(req)); + } + + bo->map = NULL; +} + +int +nouveau_bo_validate_nomm(struct nouveau_bo_priv *nvbo, uint32_t flags) +{ + struct nouveau_bo *new = NULL; + uint32_t t_handle, t_domain, t_offset, t_size; + void *t_map; + int ret; + + if ((flags & NOUVEAU_BO_VRAM) && nvbo->domain == NOUVEAU_BO_VRAM) + return 0; + if ((flags & NOUVEAU_BO_GART) && nvbo->domain == NOUVEAU_BO_GART) + return 0; + assert(flags & (NOUVEAU_BO_VRAM|NOUVEAU_BO_GART)); + + /* Keep tiling info */ + flags |= (nvbo->flags & (NOUVEAU_BO_TILED|NOUVEAU_BO_ZTILE)); + + ret = nouveau_bo_new(nvbo->base.device, flags, 0, nvbo->size, &new); + if (ret) + return ret; + + ret = nouveau_bo_kalloc(nouveau_bo(new), NULL); + if (ret) { + nouveau_bo_ref(NULL, &new); + return ret; + } + + if (nvbo->handle || nvbo->sysmem) { + nouveau_bo_kmap(nouveau_bo(new)); + + if (!nvbo->base.map) { + nouveau_bo_map(&nvbo->base, NOUVEAU_BO_RD); + memcpy(nouveau_bo(new)->map, nvbo->base.map, nvbo->base.size); + nouveau_bo_unmap(&nvbo->base); + } else { + memcpy(nouveau_bo(new)->map, nvbo->base.map, nvbo->base.size); + } + } + + t_handle = nvbo->handle; + t_domain = nvbo->domain; + t_offset = nvbo->offset; + t_size = nvbo->size; + t_map = nvbo->map; + + nvbo->handle = nouveau_bo(new)->handle; + nvbo->domain = nouveau_bo(new)->domain; + nvbo->offset = nouveau_bo(new)->offset; + nvbo->size = nouveau_bo(new)->size; + nvbo->map = nouveau_bo(new)->map; + + nouveau_bo(new)->handle = t_handle; + nouveau_bo(new)->domain = t_domain; + nouveau_bo(new)->offset = t_offset; + nouveau_bo(new)->size = t_size; + nouveau_bo(new)->map = t_map; + + nouveau_bo_ref(NULL, &new); + + return 0; +} + +static int +nouveau_bo_pin_nomm(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + int ret; + + if (!nvbo->handle) { + if (!(flags & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART))) + return -EINVAL; + + ret = nouveau_bo_validate_nomm(nvbo, flags & ~NOUVEAU_BO_PIN); + if (ret) + return ret; + } + + nvbo->pinned = 1; + + /* Fill in public nouveau_bo members */ + bo->flags = nvbo->domain; + bo->offset = nvbo->offset; + + return 0; +} + +int +nouveau_bo_pin(struct nouveau_bo *bo, uint32_t flags) +{ + struct nouveau_device_priv *nvdev = nouveau_device(bo->device); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct drm_nouveau_gem_pin req; + int ret; + + if (nvbo->pinned) + return 0; + + if (!nvdev->mm_enabled) + return nouveau_bo_pin_nomm(bo, flags); + + /* Ensure we have a kernel object... */ + if (!nvbo->handle) { + if (!(flags & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART))) + return -EINVAL; + nvbo->flags = flags; + + ret = nouveau_bo_kalloc(nvbo, NULL); + if (ret) + return ret; + } + + /* Now force it to stay put :) */ + req.handle = nvbo->handle; + req.domain = 0; + if (nvbo->flags & NOUVEAU_BO_VRAM) + req.domain |= NOUVEAU_GEM_DOMAIN_VRAM; + if (nvbo->flags & NOUVEAU_BO_GART) + req.domain |= NOUVEAU_GEM_DOMAIN_GART; + + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_PIN, &req, + sizeof(struct drm_nouveau_gem_pin)); + if (ret) + return ret; + nvbo->offset = req.offset; + nvbo->domain = req.domain; + nvbo->pinned = 1; + nvbo->flags |= NOUVEAU_BO_PIN; + + /* Fill in public nouveau_bo members */ + if (nvbo->domain & NOUVEAU_GEM_DOMAIN_VRAM) + bo->flags = NOUVEAU_BO_VRAM; + if (nvbo->domain & NOUVEAU_GEM_DOMAIN_GART) + bo->flags = NOUVEAU_BO_GART; + bo->offset = nvbo->offset; + + return 0; +} + +void +nouveau_bo_unpin(struct nouveau_bo *bo) +{ + struct nouveau_device_priv *nvdev = nouveau_device(bo->device); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct drm_nouveau_gem_unpin req; + + if (!nvbo->pinned) + return; + + if (nvdev->mm_enabled) { + req.handle = nvbo->handle; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GEM_UNPIN, + &req, sizeof(req)); + } + + nvbo->pinned = bo->offset = bo->flags = 0; +} + +int +nouveau_bo_tile(struct nouveau_bo *bo, uint32_t flags, uint32_t delta, + uint32_t size) +{ + struct nouveau_device_priv *nvdev = nouveau_device(bo->device); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + uint32_t kern_flags = 0; + int ret = 0; + + if (flags & NOUVEAU_BO_TILED) { + kern_flags |= NOUVEAU_MEM_TILE; + if (flags & NOUVEAU_BO_ZTILE) + kern_flags |= NOUVEAU_MEM_TILE_ZETA; + } + + if (nvdev->mm_enabled) { + struct drm_nouveau_gem_tile req; + + req.handle = nvbo->handle; + req.delta = delta; + req.size = size; + req.flags = kern_flags; + ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GEM_TILE, + &req, sizeof(req)); + } else { + struct drm_nouveau_mem_tile req; + + req.offset = nvbo->offset; + req.delta = delta; + req.size = size; + req.flags = kern_flags; + + if (flags & NOUVEAU_BO_VRAM) + req.flags |= NOUVEAU_MEM_FB; + if (flags & NOUVEAU_BO_GART) + req.flags |= NOUVEAU_MEM_AGP; + + ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_MEM_TILE, + &req, sizeof(req)); + } + + return 0; +} + +int +nouveau_bo_busy(struct nouveau_bo *bo, uint32_t access) +{ + struct nouveau_device_priv *nvdev = nouveau_device(bo->device); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + + if (!nvdev->mm_enabled) { + struct nouveau_fence *fence; + + if (nvbo->pending && (nvbo->pending->write_domains || + (access & NOUVEAU_BO_WR))) + return 1; + + if (access & NOUVEAU_BO_WR) + fence = nvbo->fence; + else + fence = nvbo->wr_fence; + return !nouveau_fence(fence)->signalled; + } + + return 1; +} + +struct drm_nouveau_gem_pushbuf_bo * +nouveau_bo_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) +{ + struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct drm_nouveau_gem_pushbuf_bo *pbbo; + struct nouveau_bo *ref = NULL; + int ret; + + if (nvbo->pending) + return nvbo->pending; + + if (!nvbo->handle) { + ret = nouveau_bo_kalloc(nvbo, chan); + if (ret) + return NULL; + + if (nvbo->sysmem) { + void *sysmem_tmp = nvbo->sysmem; + + nvbo->sysmem = NULL; + ret = nouveau_bo_map(bo, NOUVEAU_BO_WR); + if (ret) + return NULL; + nvbo->sysmem = sysmem_tmp; + + memcpy(bo->map, nvbo->sysmem, nvbo->base.size); + nouveau_bo_unmap(bo); + nouveau_bo_ufree(nvbo); + } + } + + if (nvpb->nr_buffers >= NOUVEAU_PUSHBUF_MAX_BUFFERS) + return NULL; + pbbo = nvpb->buffers + nvpb->nr_buffers++; + nvbo->pending = pbbo; + nvbo->pending_channel = chan; + + nouveau_bo_ref(bo, &ref); + pbbo->user_priv = (uint64_t)(unsigned long)ref; + pbbo->handle = nvbo->handle; + pbbo->valid_domains = NOUVEAU_GEM_DOMAIN_VRAM | NOUVEAU_GEM_DOMAIN_GART; + pbbo->read_domains = 0; + pbbo->write_domains = 0; + pbbo->presumed_domain = nvbo->domain; + pbbo->presumed_offset = nvbo->offset; + pbbo->presumed_ok = 1; + return pbbo; +} diff --git a/libdrm/nouveau/nouveau_bo.h b/libdrm/nouveau/nouveau_bo.h new file mode 100644 index 0000000..84a4348 --- /dev/null +++ b/libdrm/nouveau/nouveau_bo.h @@ -0,0 +1,97 @@ +/* + * Copyright 2007 Nouveau Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 __NOUVEAU_BO_H__ +#define __NOUVEAU_BO_H__ + +/* Relocation/Buffer type flags */ +#define NOUVEAU_BO_VRAM (1 << 0) +#define NOUVEAU_BO_GART (1 << 1) +#define NOUVEAU_BO_RD (1 << 2) +#define NOUVEAU_BO_WR (1 << 3) +#define NOUVEAU_BO_RDWR (NOUVEAU_BO_RD | NOUVEAU_BO_WR) +#define NOUVEAU_BO_MAP (1 << 4) +#define NOUVEAU_BO_PIN (1 << 5) +#define NOUVEAU_BO_LOW (1 << 6) +#define NOUVEAU_BO_HIGH (1 << 7) +#define NOUVEAU_BO_OR (1 << 8) +#define NOUVEAU_BO_LOCAL (1 << 9) +#define NOUVEAU_BO_TILED (1 << 10) +#define NOUVEAU_BO_ZTILE (1 << 11) +#define NOUVEAU_BO_DUMMY (1 << 31) + +struct nouveau_bo { + struct nouveau_device *device; + uint32_t handle; + + uint64_t size; + void *map; + + int tiled; + + /* Available when buffer is pinned *only* */ + uint32_t flags; + uint64_t offset; +}; + +int +nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size, + struct nouveau_bo **); + +int +nouveau_bo_user(struct nouveau_device *, void *ptr, int size, + struct nouveau_bo **); + +int +nouveau_bo_fake(struct nouveau_device *dev, uint64_t offset, uint32_t flags, + uint32_t size, void *map, struct nouveau_bo **); + +int +nouveau_bo_handle_get(struct nouveau_bo *, uint32_t *); + +int +nouveau_bo_handle_ref(struct nouveau_device *, uint32_t handle, + struct nouveau_bo **); + +int +nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **); + +int +nouveau_bo_map(struct nouveau_bo *, uint32_t flags); + +void +nouveau_bo_unmap(struct nouveau_bo *); + +int +nouveau_bo_pin(struct nouveau_bo *, uint32_t flags); + +void +nouveau_bo_unpin(struct nouveau_bo *); + +int +nouveau_bo_tile(struct nouveau_bo *, uint32_t flags, uint32_t delta, + uint32_t size); + +int +nouveau_bo_busy(struct nouveau_bo *, uint32_t access); + +#endif diff --git a/libdrm/nouveau/nouveau_channel.c b/libdrm/nouveau/nouveau_channel.c new file mode 100644 index 0000000..5de27dc --- /dev/null +++ b/libdrm/nouveau/nouveau_channel.c @@ -0,0 +1,178 @@ +/* + * Copyright 2007 Nouveau Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 <string.h> +#include <errno.h> + +#include "nouveau_private.h" + +int +nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, + uint32_t tt_ctxdma, struct nouveau_channel **chan) +{ + struct nouveau_device_priv *nvdev = nouveau_device(dev); + struct nouveau_channel_priv *nvchan; + unsigned i; + int ret; + + if (!nvdev || !chan || *chan) + return -EINVAL; + + nvchan = calloc(1, sizeof(struct nouveau_channel_priv)); + if (!nvchan) + return -ENOMEM; + nvchan->base.device = dev; + + nvchan->drm.fb_ctxdma_handle = fb_ctxdma; + nvchan->drm.tt_ctxdma_handle = tt_ctxdma; + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC, + &nvchan->drm, sizeof(nvchan->drm)); + if (ret) { + free(nvchan); + return ret; + } + + nvchan->base.id = nvchan->drm.channel; + if (nouveau_grobj_ref(&nvchan->base, nvchan->drm.fb_ctxdma_handle, + &nvchan->base.vram) || + nouveau_grobj_ref(&nvchan->base, nvchan->drm.tt_ctxdma_handle, + &nvchan->base.gart)) { + nouveau_channel_free((void *)&nvchan); + return -EINVAL; + } + + /* Mark all DRM-assigned subchannels as in-use */ + for (i = 0; i < nvchan->drm.nr_subchan; i++) { + struct nouveau_grobj_priv *gr = calloc(1, sizeof(*gr)); + + gr->base.bound = NOUVEAU_GROBJ_BOUND_EXPLICIT; + gr->base.subc = i; + gr->base.handle = nvchan->drm.subchan[i].handle; + gr->base.grclass = nvchan->drm.subchan[i].grclass; + gr->base.channel = &nvchan->base; + + nvchan->base.subc[i].gr = &gr->base; + } + + ret = drmMap(nvdev->fd, nvchan->drm.notifier, nvchan->drm.notifier_size, + (drmAddressPtr)&nvchan->notifier_block); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + ret = nouveau_grobj_alloc(&nvchan->base, 0x00000000, 0x0030, + &nvchan->base.nullobj); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + if (!nvdev->mm_enabled) { + ret = drmMap(nvdev->fd, nvchan->drm.ctrl, nvchan->drm.ctrl_size, + (void*)&nvchan->user); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + nvchan->put = &nvchan->user[0x40/4]; + nvchan->get = &nvchan->user[0x44/4]; + nvchan->ref_cnt = &nvchan->user[0x48/4]; + + ret = drmMap(nvdev->fd, nvchan->drm.cmdbuf, + nvchan->drm.cmdbuf_size, (void*)&nvchan->pushbuf); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + nouveau_dma_channel_init(&nvchan->base); + } + + nouveau_pushbuf_init(&nvchan->base); + + if (!nvdev->mm_enabled && dev->chipset < 0x10) { + ret = nouveau_grobj_alloc(&nvchan->base, 0xbeef3904, 0x5039, + &nvchan->fence_grobj); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + ret = nouveau_notifier_alloc(&nvchan->base, 0xbeef3905, 1, + &nvchan->fence_ntfy); + if (ret) { + nouveau_channel_free((void *)&nvchan); + return ret; + } + + BEGIN_RING(&nvchan->base, nvchan->fence_grobj, 0x0180, 1); + OUT_RING (&nvchan->base, nvchan->fence_ntfy->handle); + nvchan->fence_grobj->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT; + } + + *chan = &nvchan->base; + return 0; +} + +void +nouveau_channel_free(struct nouveau_channel **chan) +{ + struct nouveau_channel_priv *nvchan; + struct nouveau_device_priv *nvdev; + struct drm_nouveau_channel_free cf; + + if (!chan || !*chan) + return; + nvchan = nouveau_channel(*chan); + *chan = NULL; + nvdev = nouveau_device(nvchan->base.device); + + FIRE_RING(&nvchan->base); + + if (!nvdev->mm_enabled) { + struct nouveau_fence *fence = NULL; + + /* Make sure all buffer objects on delayed delete queue + * actually get freed. + */ + nouveau_fence_new(&nvchan->base, &fence); + nouveau_fence_emit(fence); + nouveau_fence_wait(&fence); + } + + if (nvchan->notifier_block) + drmUnmap(nvchan->notifier_block, nvchan->drm.notifier_size); + + nouveau_grobj_free(&nvchan->base.vram); + nouveau_grobj_free(&nvchan->base.gart); + nouveau_grobj_free(&nvchan->base.nullobj); + nouveau_grobj_free(&nvchan->fence_grobj); + nouveau_notifier_free(&nvchan->fence_ntfy); + + cf.channel = nvchan->drm.channel; + drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf)); + free(nvchan); +} + + diff --git a/libdrm/nouveau/nouveau_channel.h b/libdrm/nouveau/nouveau_channel.h new file mode 100644 index 0000000..294f749 --- /dev/null +++ b/libdrm/nouveau/nouveau_channel.h @@ -0,0 +1,56 @@ +/* + * Copyright 2007 Nouveau Project + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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 __NOUVEAU_CHANNEL_H__ +#define __NOUVEAU_CHANNEL_H__ + +struct nouveau_subchannel { + struct nouveau_grobj *gr; + unsigned sequence; +}; + +struct nouveau_channel { + struct nouveau_device *device; + int id; + + struct nouveau_pushbuf *pushbuf; + + struct nouveau_grobj *nullobj; + struct nouveau_grobj *vram; + struct nouveau_grobj *gart; + + void *user_private; + void (*hang_notify)(struct nouveau_channel *); + void (*flush_notify)(struct nouveau_channel *); + + struct nouveau_subchannel subc[8]; + unsigned subc_sequence; +}; + +int +nouveau_channel_alloc(struct nouveau_device *, uint32_t fb, uint32_t tt, + struct nouveau_channel **); + +void +nouveau_channel_free(struct nouveau_channel **); + +#endif diff --git a/libdrm/nouveau/nouveau_class.h b/libdrm/nouveau/nouveau_class.h new file mode 100644 index 0000000..3df3d7b --- /dev/null +++ b/libdrm/nouveau/nouveau_class.h @@ -0,0 +1,8006 @@ +/************************************************************************* + + Autogenerated file, do not edit ! + +************************************************************************** + + Copyright (C) 2006-2008 : + Dmitry Baryshkov, + Laurent Carlier, + Matthieu Castet, + Dawid Gajownik, + Jeremy Kolb, + Stephane Loeuillet, + Patrice Mandin, + Stephane Marchesin, + Serge Martin, + Sylvain Munaut, + Simon Raffeiner, + Ben Skeggs, + Erik Waling, + koala_br, + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 NOUVEAU_REG_H +#define NOUVEAU_REG_H 1 + + +#define NV01_ROOT 0x00000001 + + + +#define NV01_CONTEXT_DMA 0x00000002 + + + +#define NV01_DEVICE 0x00000003 + + + +#define NV01_TIMER 0x00000004 + +#define NV01_TIMER_SYNCHRONIZE 0x00000100 +#define NV01_TIMER_STOP_ALARM 0x00000104 +#define NV01_TIMER_DMA_NOTIFY 0x00000180 +#define NV01_TIMER_TIME(x) (0x00000300+((x)*4)) +#define NV01_TIMER_TIME__SIZE 0x00000002 +#define NV01_TIMER_ALARM_NOTIFY 0x00000308 + + +#define NV_IMAGE_STENCIL 0x00000010 + +#define NV_IMAGE_STENCIL_NOTIFY 0x00000104 +#define NV_IMAGE_STENCIL_DMA_NOTIFY 0x00000180 +#define NV_IMAGE_STENCIL_IMAGE_OUTPUT 0x00000200 +#define NV_IMAGE_STENCIL_IMAGE_INPUT(x) (0x00000204+((x)*4)) +#define NV_IMAGE_STENCIL_IMAGE_INPUT__SIZE 0x00000002 + + +#define NV_IMAGE_BLEND_AND 0x00000011 + +#define NV_IMAGE_BLEND_AND_NOP 0x00000100 +#define NV_IMAGE_BLEND_AND_NOTIFY 0x00000104 +#define NV_IMAGE_BLEND_AND_DMA_NOTIFY 0x00000180 +#define NV_IMAGE_BLEND_AND_IMAGE_OUTPUT 0x00000200 +#define NV_IMAGE_BLEND_AND_BETA_INPUT 0x00000204 +#define NV_IMAGE_BLEND_AND_IMAGE_INPUT 0x00000208 + + +#define NV01_CONTEXT_BETA1 0x00000012 + +#define NV01_CONTEXT_BETA1_NOP 0x00000100 +#define NV01_CONTEXT_BETA1_NOTIFY 0x00000104 +#define NV01_CONTEXT_BETA1_DMA_NOTIFY 0x00000180 +#define NV01_CONTEXT_BETA1_BETA_1D31 0x00000300 + + +#define NV_IMAGE_ROP_AND 0x00000013 + +#define NV_IMAGE_ROP_AND_NOTIFY 0x00000104 +#define NV_IMAGE_ROP_AND_DMA_NOTIFY 0x00000180 +#define NV_IMAGE_ROP_AND_IMAGE_OUTPUT 0x00000200 +#define NV_IMAGE_ROP_AND_ROP_INPUT 0x00000204 +#define NV_IMAGE_ROP_AND_IMAGE_INPUT(x) (0x00000208+((x)*4)) +#define NV_IMAGE_ROP_AND_IMAGE_INPUT__SIZE 0x00000002 + + +#define NV_IMAGE_COLOR_KEY 0x00000015 + + + +#define NV01_CONTEXT_COLOR_KEY 0x00000017 + +#define NV01_CONTEXT_COLOR_KEY_NOP 0x00000100 +#define NV01_CONTEXT_COLOR_KEY_NOTIFY 0x00000104 +#define NV01_CONTEXT_COLOR_KEY_DMA_NOTIFY 0x00000180 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT 0x00000300 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X16A8Y8 0x00000001 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X24Y8 0x00000002 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X16A1R5G5B5 0x00000003 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X17R5G5B5 0x00000004 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_A8R8G8B8 0x00000005 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X8R8G8B8 0x00000006 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_A16Y16 0x00000007 +#define NV01_CONTEXT_COLOR_KEY_COLOR_FORMAT_X16Y16 0x00000008 +#define NV01_CONTEXT_COLOR_KEY_COLOR 0x00000304 + + +#define NV01_CONTEXT_PATTERN 0x00000018 + +#define NV01_CONTEXT_PATTERN_NOP 0x00000100 +#define NV01_CONTEXT_PATTERN_NOTIFY 0x00000104 +#define NV01_CONTEXT_PATTERN_DMA_NOTIFY 0x00000180 +#define NV01_CONTEXT_PATTERN_COLOR_FORMAT 0x00000300 +#define NV01_CONTEXT_PATTERN_MONOCHROME_FORMAT 0x00000304 +#define NV01_CONTEXT_PATTERN_SHAPE 0x00000308 +#define NV01_CONTEXT_PATTERN_COLOR(x) (0x00000310+((x)*4)) +#define NV01_CONTEXT_PATTERN_COLOR__SIZE 0x00000002 +#define NV01_CONTEXT_PATTERN_PATTERN(x) (0x00000318+((x)*4)) +#define NV01_CONTEXT_PATTERN_PATTERN__SIZE 0x00000002 + + +#define NV01_CONTEXT_CLIP_RECTANGLE 0x00000019 + +#define NV01_CONTEXT_CLIP_RECTANGLE_NOP 0x00000100 +#define NV01_CONTEXT_CLIP_RECTANGLE_NOTIFY 0x00000104 +#define NV01_CONTEXT_CLIP_RECTANGLE_DMA_NOTIFY 0x00000180 +#define NV01_CONTEXT_CLIP_RECTANGLE_POINT 0x00000300 +#define NV01_CONTEXT_CLIP_RECTANGLE_POINT_X_SHIFT 0 +#define NV01_CONTEXT_CLIP_RECTANGLE_POINT_X_MASK 0x0000ffff +#define NV01_CONTEXT_CLIP_RECTANGLE_POINT_Y_SHIFT 16 +#define NV01_CONTEXT_CLIP_RECTANGLE_POINT_Y_MASK 0xffff0000 +#define NV01_CONTEXT_CLIP_RECTANGLE_SIZE 0x00000304 +#define NV01_CONTEXT_CLIP_RECTANGLE_SIZE_W_SHIFT 0 +#define NV01_CONTEXT_CLIP_RECTANGLE_SIZE_W_MASK 0x0000ffff +#define NV01_CONTEXT_CLIP_RECTANGLE_SIZE_H_SHIFT 16 +#define NV01_CONTEXT_CLIP_RECTANGLE_SIZE_H_MASK 0xffff0000 + + +#define NV01_RENDER_SOLID_LINE 0x0000001c + +#define NV01_RENDER_SOLID_LINE_NOP 0x00000100 +#define NV01_RENDER_SOLID_LINE_NOTIFY 0x00000104 +#define NV01_RENDER_SOLID_LINE_PATCH 0x0000010c +#define NV01_RENDER_SOLID_LINE_DMA_NOTIFY 0x00000180 +#define NV01_RENDER_SOLID_LINE_CLIP_RECTANGLE 0x00000184 +#define NV01_RENDER_SOLID_LINE_PATTERN 0x00000188 +#define NV01_RENDER_SOLID_LINE_ROP 0x0000018c +#define NV01_RENDER_SOLID_LINE_BETA1 0x00000190 +#define NV01_RENDER_SOLID_LINE_SURFACE 0x00000194 +#define NV01_RENDER_SOLID_LINE_OPERATION 0x000002fc +#define NV01_RENDER_SOLID_LINE_OPERATION_SRCCOPY_AND 0x00000000 +#define NV01_RENDER_SOLID_LINE_OPERATION_ROP_AND 0x00000001 +#define NV01_RENDER_SOLID_LINE_OPERATION_BLEND_AND 0x00000002 +#define NV01_RENDER_SOLID_LINE_OPERATION_SRCCOPY 0x00000003 +#define NV01_RENDER_SOLID_LINE_OPERATION_SRCCOPY_PREMULT 0x00000004 +#define NV01_RENDER_SOLID_LINE_OPERATION_BLEND_PREMULT 0x00000005 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT 0x00000300 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X16A8Y8 0x00000001 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X24Y8 0x00000002 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X16A1R5G5B5 0x00000003 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X17R5G5B5 0x00000004 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_A8R8G8B8 0x00000005 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X8R8G8B8 0x00000006 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_A16Y16 0x00000007 +#define NV01_RENDER_SOLID_LINE_COLOR_FORMAT_X16Y16 0x00000008 +#define NV01_RENDER_SOLID_LINE_COLOR 0x00000304 +#define NV01_RENDER_SOLID_LINE_LINE_POINT0(x) (0x00000400+((x)*8)) +#define NV01_RENDER_SOLID_LINE_LINE_POINT0__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_LINE_POINT0_X_SHIFT 0 +#define NV01_RENDER_SOLID_LINE_LINE_POINT0_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_LINE_LINE_POINT0_Y_SHIFT 16 +#define NV01_RENDER_SOLID_LINE_LINE_POINT0_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_LINE_LINE_POINT1(x) (0x00000404+((x)*8)) +#define NV01_RENDER_SOLID_LINE_LINE_POINT1__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_LINE_POINT1_X_SHIFT 0 +#define NV01_RENDER_SOLID_LINE_LINE_POINT1_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_LINE_LINE_POINT1_Y_SHIFT 16 +#define NV01_RENDER_SOLID_LINE_LINE_POINT1_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_LINE_LINE32_POINT0_X(x) (0x00000480+((x)*16)) +#define NV01_RENDER_SOLID_LINE_LINE32_POINT0_X__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_LINE32_POINT0_Y(x) (0x00000484+((x)*16)) +#define NV01_RENDER_SOLID_LINE_LINE32_POINT0_Y__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_LINE32_POINT1_X(x) (0x00000488+((x)*16)) +#define NV01_RENDER_SOLID_LINE_LINE32_POINT1_X__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_LINE32_POINT1_Y(x) (0x0000048c+((x)*16)) +#define NV01_RENDER_SOLID_LINE_LINE32_POINT1_Y__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_POLYLINE(x) (0x00000500+((x)*4)) +#define NV01_RENDER_SOLID_LINE_POLYLINE__SIZE 0x00000020 +#define NV01_RENDER_SOLID_LINE_POLYLINE_X_SHIFT 0 +#define NV01_RENDER_SOLID_LINE_POLYLINE_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_LINE_POLYLINE_Y_SHIFT 16 +#define NV01_RENDER_SOLID_LINE_POLYLINE_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_LINE_POLYLINE32_POINT_X(x) (0x00000580+((x)*8)) +#define NV01_RENDER_SOLID_LINE_POLYLINE32_POINT_X__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_POLYLINE32_POINT_Y(x) (0x00000584+((x)*8)) +#define NV01_RENDER_SOLID_LINE_POLYLINE32_POINT_Y__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_COLOR(x) (0x00000600+((x)*8)) +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_COLOR__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT(x) (0x00000604+((x)*8)) +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT__SIZE 0x00000010 +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT_X_SHIFT 0 +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT_Y_SHIFT 16 +#define NV01_RENDER_SOLID_LINE_CPOLYLINE_POINT_Y_MASK 0xffff0000 + + +#define NV01_RENDER_SOLID_TRIANGLE 0x0000001d + +#define NV01_RENDER_SOLID_TRIANGLE_NOP 0x00000100 +#define NV01_RENDER_SOLID_TRIANGLE_NOTIFY 0x00000104 +#define NV01_RENDER_SOLID_TRIANGLE_PATCH 0x0000010c +#define NV01_RENDER_SOLID_TRIANGLE_DMA_NOTIFY 0x00000180 +#define NV01_RENDER_SOLID_TRIANGLE_CLIP_RECTANGLE 0x00000184 +#define NV01_RENDER_SOLID_TRIANGLE_PATTERN 0x00000188 +#define NV01_RENDER_SOLID_TRIANGLE_ROP 0x0000018c +#define NV01_RENDER_SOLID_TRIANGLE_BETA1 0x00000190 +#define NV01_RENDER_SOLID_TRIANGLE_SURFACE 0x00000194 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION 0x000002fc +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_SRCCOPY_AND 0x00000000 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_ROP_AND 0x00000001 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_BLEND_AND 0x00000002 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_SRCCOPY 0x00000003 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_SRCCOPY_PREMULT 0x00000004 +#define NV01_RENDER_SOLID_TRIANGLE_OPERATION_BLEND_PREMULT 0x00000005 +#define NV01_RENDER_SOLID_TRIANGLE_COLOR_FORMAT 0x00000300 +#define NV01_RENDER_SOLID_TRIANGLE_COLOR 0x00000304 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT0 0x00000310 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT0_X_SHIFT 0 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT0_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT0_Y_SHIFT 16 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT0_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT1 0x00000314 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT1_X_SHIFT 0 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT1_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT1_Y_SHIFT 16 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT1_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT2 0x00000318 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT2_X_SHIFT 0 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT2_X_MASK 0x0000ffff +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT2_Y_SHIFT 16 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE_POINT2_Y_MASK 0xffff0000 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE32_POINT0_X 0x00000320 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE32_POINT0_Y 0x00000324 +#define NV01_RENDER_SOLID_TRIANGLE_TRIANGLE32_POINT1_X 0x00000328 +#define NV01_RENDER_SOLID... [truncated message content] |