From 09b1062628f2cbddb3ebae20e7b3b8a0a93acebf Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 28 Sep 2010 20:45:27 +0000 Subject: nouveau: Let the user choose the push buffer size. Signed-off-by: Francisco Jerez Acked-by: Ben Skeggs --- diff --git a/nouveau/nouveau_channel.c b/nouveau/nouveau_channel.c index 40a0b34..ded5424 100644 --- a/nouveau/nouveau_channel.c +++ b/nouveau/nouveau_channel.c @@ -28,7 +28,8 @@ int nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, - uint32_t tt_ctxdma, struct nouveau_channel **chan) + uint32_t tt_ctxdma, int pushbuf_size, + struct nouveau_channel **chan) { struct nouveau_device_priv *nvdev = nouveau_device(dev); struct nouveau_channel_priv *nvchan; @@ -90,7 +91,7 @@ nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma, return ret; } - ret = nouveau_pushbuf_init(&nvchan->base); + ret = nouveau_pushbuf_init(&nvchan->base, pushbuf_size); if (ret) { nouveau_channel_free((void *)&nvchan); return ret; diff --git a/nouveau/nouveau_channel.h b/nouveau/nouveau_channel.h index ddcf8e4..d61a4c0 100644 --- a/nouveau/nouveau_channel.h +++ b/nouveau/nouveau_channel.h @@ -49,7 +49,7 @@ struct nouveau_channel { int nouveau_channel_alloc(struct nouveau_device *, uint32_t fb, uint32_t tt, - struct nouveau_channel **); + int pushbuf_size, struct nouveau_channel **); void nouveau_channel_free(struct nouveau_channel **); diff --git a/nouveau/nouveau_private.h b/nouveau/nouveau_private.h index 5a952f7..4c53534 100644 --- a/nouveau/nouveau_private.h +++ b/nouveau/nouveau_private.h @@ -37,8 +37,8 @@ #include "nouveau_pushbuf.h" #include "nouveau_reloc.h" -#define CALPB_BUFFERS 4 -#define CALPB_BUFSZ 16384 +#define CALPB_BUFFERS 3 + struct nouveau_pushbuf_priv { uint32_t cal_suffix0; uint32_t cal_suffix1; @@ -64,7 +64,7 @@ struct nouveau_pushbuf_priv { #define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) int -nouveau_pushbuf_init(struct nouveau_channel *); +nouveau_pushbuf_init(struct nouveau_channel *, int buf_size); void nouveau_pushbuf_fini(struct nouveau_channel *); diff --git a/nouveau/nouveau_pushbuf.c b/nouveau/nouveau_pushbuf.c index 28b8018..90836bc 100644 --- a/nouveau/nouveau_pushbuf.c +++ b/nouveau/nouveau_pushbuf.c @@ -78,7 +78,7 @@ nouveau_pushbuf_fini_call(struct nouveau_channel *chan) } static int -nouveau_pushbuf_init_call(struct nouveau_channel *chan) +nouveau_pushbuf_init_call(struct nouveau_channel *chan, int buf_size) { struct drm_nouveau_gem_pushbuf req; struct nouveau_channel_priv *nvchan = nouveau_channel(chan); @@ -101,7 +101,7 @@ nouveau_pushbuf_init_call(struct nouveau_channel *chan) for (i = 0; i < CALPB_BUFFERS; i++) { ret = nouveau_bo_new(dev, flags | NOUVEAU_BO_MAP, - 0, CALPB_BUFSZ, &nvpb->buffer[i]); + 0, buf_size, &nvpb->buffer[i]); if (ret) { nouveau_pushbuf_fini_call(chan); return ret; @@ -114,13 +114,13 @@ nouveau_pushbuf_init_call(struct nouveau_channel *chan) } int -nouveau_pushbuf_init(struct nouveau_channel *chan) +nouveau_pushbuf_init(struct nouveau_channel *chan, int buf_size) { struct nouveau_channel_priv *nvchan = nouveau_channel(chan); struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; int ret; - ret = nouveau_pushbuf_init_call(chan); + ret = nouveau_pushbuf_init_call(chan, buf_size); if (ret) return ret; -- cgit v0.8.3-6-g21f6 From 1b9187c43a0c17600611edb9e299141748e87974 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 28 Sep 2010 20:47:11 +0000 Subject: nouveau: Define buffer object usage flags. Signed-off-by: Francisco Jerez Acked-by: Ben Skeggs --- diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index fe917de..f115eab 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h @@ -80,6 +80,7 @@ struct drm_nouveau_gpuobj_free { #define NOUVEAU_GETPARAM_VM_VRAM_BASE 12 #define NOUVEAU_GETPARAM_GRAPH_UNITS 13 #define NOUVEAU_GETPARAM_PTIMER_TIME 14 +#define NOUVEAU_GETPARAM_HAS_BO_USAGE 15 struct drm_nouveau_getparam { uint64_t param; uint64_t value; @@ -95,6 +96,12 @@ struct drm_nouveau_setparam { #define NOUVEAU_GEM_DOMAIN_GART (1 << 2) #define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3) +#define NOUVEAU_GEM_TILE_LAYOUT_MASK 0x0000ff00 +#define NOUVEAU_GEM_TILE_16BPP 0x00000001 +#define NOUVEAU_GEM_TILE_32BPP 0x00000002 +#define NOUVEAU_GEM_TILE_ZETA 0x00000004 +#define NOUVEAU_GEM_TILE_NONCONTIG 0x00000008 + struct drm_nouveau_gem_info { uint32_t handle; uint32_t domain; diff --git a/nouveau/nouveau_bo.c b/nouveau/nouveau_bo.c index 32b23b6..c1432b0 100644 --- a/nouveau/nouveau_bo.c +++ b/nouveau/nouveau_bo.c @@ -52,7 +52,8 @@ nouveau_bo_info(struct nouveau_bo_priv *nvbo, struct drm_nouveau_gem_info *arg) nvbo->offset = arg->offset; nvbo->map_handle = arg->map_handle; nvbo->base.tile_mode = arg->tile_mode; - nvbo->base.tile_flags = arg->tile_flags; + /* XXX - flag inverted for backwards compatibility */ + nvbo->base.tile_flags = arg->tile_flags ^ NOUVEAU_GEM_TILE_NONCONTIG; return 0; } @@ -140,6 +141,10 @@ nouveau_bo_kalloc(struct nouveau_bo_priv *nvbo, struct nouveau_channel *chan) info->tile_mode = nvbo->base.tile_mode; info->tile_flags = nvbo->base.tile_flags; + /* XXX - flag inverted for backwards compatibility */ + info->tile_flags ^= NOUVEAU_GEM_TILE_NONCONTIG; + if (!nvdev->has_bo_usage) + info->tile_flags &= NOUVEAU_GEM_TILE_LAYOUT_MASK; ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_NEW, &req, sizeof(req)); diff --git a/nouveau/nouveau_bo.h b/nouveau/nouveau_bo.h index 1e77ab0..3a1f2d4 100644 --- a/nouveau/nouveau_bo.h +++ b/nouveau/nouveau_bo.h @@ -39,6 +39,12 @@ #define NOUVEAU_BO_IFLUSH (1 << 15) #define NOUVEAU_BO_DUMMY (1 << 31) +#define NOUVEAU_BO_TILE_LAYOUT_MASK 0x0000ff00 +#define NOUVEAU_BO_TILE_16BPP 0x00000001 +#define NOUVEAU_BO_TILE_32BPP 0x00000002 +#define NOUVEAU_BO_TILE_ZETA 0x00000004 +#define NOUVEAU_BO_TILE_SCANOUT 0x00000008 + struct nouveau_bo { struct nouveau_device *device; uint32_t handle; diff --git a/nouveau/nouveau_device.c b/nouveau/nouveau_device.c index 9a091fb..2ffcba6 100644 --- a/nouveau/nouveau_device.c +++ b/nouveau/nouveau_device.c @@ -95,6 +95,11 @@ nouveau_device_open_existing(struct nouveau_device **dev, int close, } nvdev->base.chipset = value; + ret = nouveau_device_get_param(&nvdev->base, + NOUVEAU_GETPARAM_HAS_BO_USAGE, &value); + if (!ret) + nvdev->has_bo_usage = value; + *dev = &nvdev->base; return 0; } diff --git a/nouveau/nouveau_drmif.h b/nouveau/nouveau_drmif.h index bc860d2..ec226a2 100644 --- a/nouveau/nouveau_drmif.h +++ b/nouveau/nouveau_drmif.h @@ -35,6 +35,7 @@ struct nouveau_device_priv { drm_context_t ctx; drmLock *lock; int needs_close; + int has_bo_usage; }; #define nouveau_device(n) ((struct nouveau_device_priv *)(n)) -- cgit v0.8.3-6-g21f6 From c5286f4a871e054b63dee8a60a6f06574c4ca1b8 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 21 Oct 2010 21:02:43 +0000 Subject: nouveau: Define the HAS_PAGEFLIP getparam. Signed-off-by: Francisco Jerez --- diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index f115eab..b18cad0 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h @@ -81,6 +81,7 @@ struct drm_nouveau_gpuobj_free { #define NOUVEAU_GETPARAM_GRAPH_UNITS 13 #define NOUVEAU_GETPARAM_PTIMER_TIME 14 #define NOUVEAU_GETPARAM_HAS_BO_USAGE 15 +#define NOUVEAU_GETPARAM_HAS_PAGEFLIP 16 struct drm_nouveau_getparam { uint64_t param; uint64_t value; -- cgit v0.8.3-6-g21f6 From d0a4f2e292e5b347f7e5ee2cdbe4f077986eb9da Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 31 Oct 2010 00:22:29 +0000 Subject: nouveau: Avoid unnecessary call to CPU_FINI. nouveau_bo_unmap called the CPU_FINI IOCTL even if it was a NOSYNC mapping. It caused no harmful effects (actually CPU_FINI is a no-op on recent enough kernels) besides the precious CPU cycles being wasted. Signed-off-by: Francisco Jerez --- diff --git a/nouveau/nouveau_bo.c b/nouveau/nouveau_bo.c index c1432b0..d6bb22d 100644 --- a/nouveau/nouveau_bo.c +++ b/nouveau/nouveau_bo.c @@ -434,6 +434,8 @@ nouveau_bo_map_range(struct nouveau_bo *bo, uint32_t delta, uint32_t size, (flags & NOUVEAU_BO_NOWAIT), 0); if (ret) return ret; + + nvbo->map_refcnt++; } bo->map = (char *)nvbo->map + delta; @@ -458,13 +460,14 @@ nouveau_bo_unmap(struct nouveau_bo *bo) { struct nouveau_bo_priv *nvbo = nouveau_bo(bo); - if (bo->map && !nvbo->sysmem) { + if (bo->map && !nvbo->sysmem && nvbo->map_refcnt) { 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)); + nvbo->map_refcnt--; } bo->map = NULL; diff --git a/nouveau/nouveau_private.h b/nouveau/nouveau_private.h index 4c53534..124fe87 100644 --- a/nouveau/nouveau_private.h +++ b/nouveau/nouveau_private.h @@ -115,6 +115,7 @@ struct nouveau_bo_priv { uint32_t global_handle; drm_handle_t handle; uint64_t map_handle; + int map_refcnt; void *map; /* Last known information from kernel on buffer status */ -- cgit v0.8.3-6-g21f6 From d17681d538ce86a3f8d6d1c7407df3ceb2bcc499 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 20 Nov 2010 13:32:45 +0000 Subject: nouveau: Add implicit pushbuf flush before gpuobj destruction. It makes sure that GPU object destruction is executed in order with respect to the previous FIFO commands. Signed-off-by: Francisco Jerez Acked-by: Ben Skeggs --- diff --git a/nouveau/nouveau_grobj.c b/nouveau/nouveau_grobj.c index 2b6e53a..df2ffb9 100644 --- a/nouveau/nouveau_grobj.c +++ b/nouveau/nouveau_grobj.c @@ -99,6 +99,8 @@ nouveau_grobj_free(struct nouveau_grobj **grobj) if (nvgrobj->base.grclass) { struct drm_nouveau_gpuobj_free f; + FIRE_RING(&chan->base); + f.channel = chan->drm.channel; f.handle = nvgrobj->base.handle; drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, diff --git a/nouveau/nouveau_notifier.c b/nouveau/nouveau_notifier.c index f8cfd8b..513fa63 100644 --- a/nouveau/nouveau_notifier.c +++ b/nouveau/nouveau_notifier.c @@ -80,6 +80,8 @@ nouveau_notifier_free(struct nouveau_notifier **notifier) nvchan = nouveau_channel(nvnotify->base.channel); nvdev = nouveau_device(nvchan->base.device); + FIRE_RING(&nvchan->base); + f.channel = nvchan->drm.channel; f.handle = nvnotify->base.handle; drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, &f, sizeof(f)); -- cgit v0.8.3-6-g21f6