All of lore.kernel.org
 help / color / mirror / Atom feed
* some patches and remarks for ng
@ 2009-01-03 16:53 Maarten Maathuis
       [not found] ` <6d4bc9fc0901030853q7f341c16l231ebf42c4643ede-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: Maarten Maathuis @ 2009-01-03 16:53 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

[-- Attachment #1: Type: text/plain, Size: 1052 bytes --]

1 patch for libnouveau_drm, 4 for drm and one work in progress patch
for the ddx.

Getting nv50 to run proved to be more difficult than i thought (at
some point i stopped because it would require significant changes), i
just have a few remarks.

- Buffer object access is not guarded by fences at all, which is a
major issue. You worked around that by using M2MF I suppose, but this
needs a structural fix.
- Comments are scarce, please be more verbose. I know it's all very
obvious to the people that write the code, but for others it's less
obvious.
- I think buffer object untiling should happen in userspace, which
will also allow some nice optimizations that EXA does (using damage to
selectively copy and such).
- The WIP patch contains sysmem pixmaps, i fixed this for git xserver
(and nominated it for 1.6), but expect older versions to blow up due
to NULL'ing of devPrivate.ptr.
(http://cgit.freedesktop.org/xorg/xserver/commit/?id=3534a5e5d9c5af85149c799f324257f89507fa23)

Consider the patches hints, and don't blindly apply them.

Maarten.

[-- Attachment #2: 0001-A-few-minor-fixes.patch --]
[-- Type: application/octet-stream, Size: 1891 bytes --]

From abed0dd3583ac173e19570a4a0010eb56b45bc0b Mon Sep 17 00:00:00 2001
From: Maarten Maathuis <madman2003@gmail.com>
Date: Tue, 23 Dec 2008 21:16:10 +0100
Subject: [PATCH] A few minor fixes.

---
 src/nouveau_bo.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/nouveau_bo.c b/src/nouveau_bo.c
index 851eaf9..de6f167 100644
--- a/src/nouveau_bo.c
+++ b/src/nouveau_bo.c
@@ -328,7 +328,9 @@ nouveau_bo_wait(struct nouveau_bo *bo, int cpu_write)
 		nouveau_pushbuf_flush(nvbo->pending_channel, 0);
 	}
 
-	nouveau_bo_kmap(nvbo);
+	ret = nouveau_bo_kmap(nvbo);
+	if (ret)
+		return ret;
 
 	req.handle = nvbo->handle;
 	ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GEM_CPU_PREP,
@@ -350,8 +352,11 @@ nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags)
 		return -EINVAL;
 
 	if (!nouveau_bo_allocated(nvbo)) {
-		if (nvbo->flags & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART))
-			nouveau_bo_kalloc(nvbo, NULL);
+		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);
@@ -468,7 +473,9 @@ nouveau_bo_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo)
 		return nvbo->pending;
 
 	if (!nvbo->handle) {
-		nouveau_bo_kalloc(nvbo, chan);
+		ret = nouveau_bo_kalloc(nvbo, chan);
+		if (ret)
+			return NULL;
 		if (nvbo->sysmem) {
 			void *sysmem_tmp = nvbo->sysmem;
 
@@ -494,7 +501,7 @@ nouveau_bo_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo)
 	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 =
+	pbbo->read_domains = 0;
 	pbbo->write_domains = 0;
 	pbbo->presumed_domain = nvbo->domain;
 	pbbo->presumed_offset = nvbo->offset;
-- 
1.6.0.6


[-- Attachment #3: 0001-nv50-properly-handle-gart.patch --]
[-- Type: application/octet-stream, Size: 1392 bytes --]

From 8caaf0c4a3dc4579e09963173438d876d335fbb5 Mon Sep 17 00:00:00 2001
From: Maarten Maathuis <madman2003@gmail.com>
Date: Tue, 23 Dec 2008 21:12:14 +0100
Subject: [PATCH] nv50: properly handle gart.

---
 shared-core/nouveau_object.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c
index 4c8d364..f7d93a8 100644
--- a/shared-core/nouveau_object.c
+++ b/shared-core/nouveau_object.c
@@ -961,6 +961,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
 
 	/* VRAM ctxdma */
 	if (dev_priv->card_type >= NV_50) {
+		/* VRAM is mapped into 512-1024 MB in the page directory. */
+		/* The reason available size is used, is to avoid dma'ing into RAMIN. */
 		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
 					     (512*1024*1024),
 					     dev_priv->fb_available_size,
@@ -986,7 +988,12 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
 
 	/* TT memory ctxdma */
 	if (dev_priv->card_type >= NV_50) {
-		tt = vram;
+		/* GART is mapped into 0-512MB of the page directory. */
+		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+					     0,
+					     512*1024*1024,
+					     NV_DMA_ACCESS_RW,
+					     NV_DMA_TARGET_AGP, &tt);
 	} else
 	if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) {
 		ret = nouveau_gpuobj_gart_dma_new(chan, 0,
-- 
1.6.0.6


[-- Attachment #4: 0002-nouveau-At-least-do-something-if-drm_fence_emit-f.patch --]
[-- Type: application/octet-stream, Size: 862 bytes --]

From 4fa3a8c10d9960343e98d37caa730c26438af1f3 Mon Sep 17 00:00:00 2001
From: Maarten Maathuis <madman2003@gmail.com>
Date: Fri, 26 Dec 2008 14:40:19 +0100
Subject: [PATCH] nouveau: At least do something if drm_fence_emit() fails.

---
 linux-core/nouveau_gem.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/linux-core/nouveau_gem.c b/linux-core/nouveau_gem.c
index 7d90adf..0feaad6 100644
--- a/linux-core/nouveau_gem.c
+++ b/linux-core/nouveau_gem.c
@@ -443,7 +443,9 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
 		ret = drm_fence_object_emit(fence, 0, chan->id,
 					    DRM_FENCE_TYPE_EXE);
 		if (ret) {
-			/*XXX*/
+			/*XXX: something better that can be done? */
+			DRM_ERROR("drm_fence_object_emit failed, expect problems.\n");
+			goto out;
 		}
 
 		if (nouveau_gem_pushbuf_sync(chan)) {
-- 
1.6.0.6


[-- Attachment #5: 0003-nouveau-Fix-some-major-brain-damage-in-the-size-of.patch --]
[-- Type: application/octet-stream, Size: 1388 bytes --]

From 6c11a595323be09b15f61c5daa31a13b65565243 Mon Sep 17 00:00:00 2001
From: Maarten Maathuis <madman2003@gmail.com>
Date: Sat, 27 Dec 2008 20:25:37 +0100
Subject: [PATCH] nouveau: Fix some major brain damage in the size of useable vram.

- On NV50 ramin would get overwritten with serious concequences.
---
 shared-core/nouveau_mem.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c
index 7df4723..01e9c6a 100644
--- a/shared-core/nouveau_mem.c
+++ b/shared-core/nouveau_mem.c
@@ -384,6 +384,9 @@ nouveau_mem_init(struct drm_device *dev)
 	/* non-mappable vram */
 	dev_priv->fb_available_size = nouveau_mem_fb_amount(dev);
 	dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
+	/* It's possible that this size is including the reserved area. */
+	if (dev_priv->card_type == NV_50)
+		dev_priv->fb_available_size -= dev_priv->ramin->size;
 	vram_size = dev_priv->fb_available_size >> PAGE_SHIFT;
 	bar1_size = drm_get_resource_len(dev, 1) >> PAGE_SHIFT;
 	if (bar1_size < vram_size) {
@@ -396,7 +399,7 @@ nouveau_mem_init(struct drm_device *dev)
 	}
 
 	/* mappable vram */
-	if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, vram_size*3, 1))) {
+	if ((ret = drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, vram_size, 1))) {
 		DRM_ERROR("Failed VRAM mm init: %d\n", ret);
 		return ret;
 	}
-- 
1.6.0.6


[-- Attachment #6: 0004-nv50-Also-reset-old-pages-in-nouveau_bo_move.patch --]
[-- Type: application/octet-stream, Size: 1726 bytes --]

From 39153befd2ce0c1342e86970972365255d6cec63 Mon Sep 17 00:00:00 2001
From: Maarten Maathuis <madman2003@gmail.com>
Date: Sun, 28 Dec 2008 00:56:43 +0100
Subject: [PATCH] nv50: Also reset old pages in nouveau_bo_move().

---
 linux-core/nouveau_bo.c |   22 +++++++++++++++++++++-
 1 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/linux-core/nouveau_bo.c b/linux-core/nouveau_bo.c
index 7382b87..ea860b6 100644
--- a/linux-core/nouveau_bo.c
+++ b/linux-core/nouveau_bo.c
@@ -293,6 +293,7 @@ nouveau_bo_move(struct drm_buffer_object *bo, int evict, int no_wait,
 	if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE)
 		return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
 
+	/* DRM_BO_MEM_PRIV0 is used for vram beyond the first 256 MB. */
 	if (dev_priv->card_type == NV_50 &&
 	    (new_mem->mem_type == DRM_BO_MEM_VRAM ||
 	     new_mem->mem_type == DRM_BO_MEM_PRIV0) &&
@@ -317,7 +318,26 @@ nouveau_bo_move(struct drm_buffer_object *bo, int evict, int no_wait,
 			offset += 65536;
 		}
 	}
-		
+
+	/* Also clean up old pages. */
+	if (dev_priv->card_type == NV_50 &&
+	    (old_mem->mem_type == DRM_BO_MEM_VRAM ||
+	     old_mem->mem_type == DRM_BO_MEM_PRIV0) &&
+	    !(old_mem->flags & DRM_NOUVEAU_BO_FLAG_NOVM)) {
+		struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt;
+		unsigned offset = old_mem->mm_node->start << PAGE_SHIFT;
+		unsigned count = old_mem->size / 65536;
+		unsigned tile = 0;
+
+		while (count--) {
+			unsigned pte = offset / 65536;
+
+			INSTANCE_WR(pt, (pte * 2) + 0, 0);
+			INSTANCE_WR(pt, (pte * 2) + 1, 0);
+			offset += 65536;
+		}
+	}
+
 	if (old_mem->flags & DRM_BO_FLAG_CLEAN) {
 		return drm_bo_move_accel_cleanup(bo, 1, no_wait,
 						 bo->new_fence_class,
-- 
1.6.0.6


[-- Attachment #7: WIP.patch --]
[-- Type: application/octet-stream, Size: 10755 bytes --]

diff --git a/src/nv50_exa.c b/src/nv50_exa.c
index fc6af10..023f2d2 100644
--- a/src/nv50_exa.c
+++ b/src/nv50_exa.c
@@ -114,6 +114,8 @@ NV50EXAAcquireSurface2D(PixmapPtr ppix, int is_src)
 	if (!NV50EXA2DSurfaceFormat(ppix, &fmt))
 		return FALSE;
 
+	ErrorF("is_src %d ppix 0x%08X tiled %d width %d height %d\n", is_src, ppix, surf->bo->tiled, ppix->drawable.width, ppix->drawable.height);
+
 	bo_flags  = NOUVEAU_BO_VRAM;
 	bo_flags |= is_src ? NOUVEAU_BO_RD : NOUVEAU_BO_WR;
 
@@ -274,6 +276,8 @@ NV50EXACopy(PixmapPtr pdpix, int srcX , int srcY,
 {
 	NV50EXA_LOCALS(pdpix);
 
+	ErrorF("srcX %d srcY %d dstX %d dstY %d width %d height %d\n", srcX, srcY, dstX, dstY, width, height);
+
 	BEGIN_RING(chan, eng2d, 0x0110, 1);
 	OUT_RING  (chan, 0);
 	BEGIN_RING(chan, eng2d, 0x088c, 1);
diff --git a/src/nv_exa.c b/src/nv_exa.c
index ee5a08e..38c5663 100644
--- a/src/nv_exa.c
+++ b/src/nv_exa.c
@@ -254,6 +254,123 @@ static inline Bool NVAccelMemcpyRect(char *dst, const char *src, int height,
 	return TRUE;
 }
 
+/*
+ * Generic M2MF function to copy a buffer object.
+ * Partial copies are possible too.
+ * Buffer objects must have equal size.
+ */
+static inline bool
+nv_accel_m2mf_copy_bo(ScrnInfoPtr pScrn, struct nouveau_bo_copy *info)
+{
+	NVPtr pNv = NVPTR(pScrn);
+	struct nouveau_channel *chan = pNv->chan;
+	struct nouveau_grobj *m2mf = pNv->NvMemFormat;
+	uint32_t src_flags = 0, dst_flags = 0;
+	int line_len = info->src_line_len, cpp = info->cpp;
+	int h = info->h, x = info->x, y = info->y;
+	int src_pitch = 0, dst_pitch = 0, src_offset = 0, dst_offset = 0;
+	struct nouveau_bo *src = info->src, *dst = info->dst;
+
+	if (src->size != dst->size) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Trying to copy two buffer objects of different size.\n");
+		return FALSE;
+	}
+
+	ErrorF("src_pitch %d dst_pitch %d src_height %d dst_height %d x %d y %d w %d h %d cpp %d\n", info->src_pitch, info->dst_pitch, info->src_height, info->dst_height, x, y, info->w, h, cpp);
+
+	/* Getting the actual flags requires pinning the bo. */
+	src_flags = NOUVEAU_BO_GART | NOUVEAU_BO_VRAM;
+	dst_flags = NOUVEAU_BO_GART | NOUVEAU_BO_VRAM;
+
+	/* Some methods always need the pitch, some only when !tiled. */
+	if (!src->tiled) {
+		src_pitch  = info->src_pitch;
+		src_offset = (y * src_pitch) + (x * cpp);
+	}
+
+	if (!dst->tiled) {
+		dst_pitch  = info->dst_pitch;
+		dst_offset = (y * dst_pitch) + (x * cpp);
+	}
+
+	BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
+	OUT_RELOCo(chan, src, src_flags | NOUVEAU_BO_RD);
+	OUT_RELOCo(chan, dst, dst_flags | NOUVEAU_BO_WR);
+
+	/* This code assumes the default tile size of 8x8. */
+	if (pNv->Architecture >= NV_ARCH_50) {
+		if (src->tiled) {
+			BEGIN_RING(chan, m2mf, 0x0200, 6);
+			OUT_RING  (chan, 0);
+			OUT_RING  (chan, 0); /* Something to do with tilesize iirc. */
+			OUT_RING  (chan, info->src_pitch  /*info->src_line_len*/);
+			OUT_RING  (chan, info->src_height);
+			OUT_RING  (chan, 1);
+			OUT_RING  (chan, 0);
+		} else {
+			BEGIN_RING(chan, m2mf, 0x0200, 1);
+			OUT_RING  (chan, 1);
+		}
+
+		if (dst->tiled) {
+			BEGIN_RING(chan, m2mf, 0x021c, 6);
+			OUT_RING  (chan, 0);
+			OUT_RING  (chan, 0); /* Something to do with tilesize iirc. */
+			OUT_RING  (chan, info->dst_pitch /*info->dst_line_len*/);
+			OUT_RING  (chan, info->dst_height);
+			OUT_RING  (chan, 1);
+			OUT_RING  (chan, 0);
+		} else {
+			BEGIN_RING(chan, m2mf, 0x021c, 1);
+			OUT_RING  (chan, 1);
+		}
+	}
+
+	while (h) {
+		int line_count = h;
+
+		/* HW limitations */
+		if (line_count > 2047)
+			line_count = 2047;
+
+		if (pNv->Architecture >= NV_ARCH_50) {
+			if (src->tiled) {
+				BEGIN_RING(chan, m2mf, 0x0218, 1);
+				OUT_RING  (chan, (y << 16) | (x * cpp));
+			}
+
+			if (dst->tiled) {
+				BEGIN_RING(chan, m2mf, 0x0234, 1);
+				OUT_RING  (chan, (y << 16) | (x * cpp));
+			}
+
+			BEGIN_RING(chan, m2mf, NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH, 2);
+			OUT_RELOCh(chan, src, src_offset, src_flags | NOUVEAU_BO_RD);
+			OUT_RELOCh(chan, dst, dst_offset, dst_flags | NOUVEAU_BO_WR);
+		}
+
+		BEGIN_RING(chan, m2mf,
+			   NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+		OUT_RELOCl(chan, src, src_offset, src_flags | NOUVEAU_BO_RD);
+		OUT_RELOCl(chan, dst, dst_offset, dst_flags | NOUVEAU_BO_WR);
+		OUT_RING(chan, info->src_pitch);
+		OUT_RING(chan, info->dst_pitch);
+		OUT_RING(chan, line_len);
+		OUT_RING(chan, line_count);
+		OUT_RING(chan, (1<<8)|1);
+		OUT_RING(chan, 0);
+
+		if (!src->tiled)
+			src_offset += line_count * src_pitch;
+		if (!dst->tiled)
+			dst_offset += line_count * dst_pitch;
+		h -= line_count;
+		y += line_count;
+	}
+
+	return TRUE;
+}
+
 static inline Bool
 NVAccelDownloadM2MF(PixmapPtr pspix, int x, int y, int w, int h,
 		    char *dst, unsigned dst_pitch)
@@ -683,18 +800,78 @@ NVExaPrepareAccess(PixmapPtr pPix, int index)
 	ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
 	NVPtr pNv = NVPTR(pScrn);
 	struct nouveau_pixmap *nvpix;
+	bool already_prepared = false;
 	(void)pNv;
-
+	
 	nvpix = exaGetPixmapDriverPrivate(pPix);
 	if (!nvpix || !nvpix->bo)
 		return FALSE;
 
-	if (!nvpix->bo->map) {
-		if (nouveau_bo_map(nvpix->bo, NOUVEAU_BO_RDWR))
+	ErrorF("PrepareAccess %d on pixmap 0x%16X\n", index, pPix);
+
+	if (pPix->drawable.bitsPerPixel < 8) {
+		ErrorF("bpp 8 is the minimum\n");
+		return FALSE;
+	}
+
+	if (nvpix->flags)
+		already_prepared = true;
+
+	nvpix->flags |= (1 << index);
+
+	if (already_prepared)
+		return TRUE;
+
+	if (pPix->devPrivate.ptr)
+		ErrorF("devPrivate.ptr is non-NULL\n");
+
+	if (nvpix->bo->tiled) {
+		if (!nvpix->lbo || !nvpix->lbo->map) {
+			ErrorF("Tiled PrepareAccess\n");
+			struct nouveau_bo_copy info;
+			uint32_t flags = NOUVEAU_BO_VRAM;
+			int ret = nouveau_bo_new(pNv->dev, flags, 0, nvpix->bo->size, &nvpix->lbo);
+			if (ret) {
+				xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate linear bo for copying.\n");
+				return FALSE;
+			}
+
+			info.src = nvpix->bo;
+			info.dst = nvpix->lbo;
+			info.x = info.y = 0;
+			info.w = pPix->drawable.width;
+			info.h = pPix->drawable.height;
+			info.cpp = pPix->drawable.bitsPerPixel >> 3;
+			info.src_pitch = info.dst_pitch = exaGetPixmapPitch(pPix);
+			info.src_line_len = info.dst_line_len = info.w * info.cpp;
+			info.src_height = info.dst_height = info.h;
+
+			ret = nv_accel_m2mf_copy_bo(pScrn, &info);
+			if (!ret) {
+				xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to copy tiled data to linear bo.\n");
+				nouveau_bo_ref(NULL, &nvpix->lbo);
+				return FALSE;
+			}
+
+			if (nouveau_bo_map(nvpix->lbo, NOUVEAU_BO_RDWR)) {
+				xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Mapping of linear bo failed\n");
+				nouveau_bo_ref(NULL, &nvpix->lbo);
+				return FALSE;
+			}
+
+			pPix->devPrivate.ptr = nvpix->lbo->map;
+		}
+
+		pPix->devPrivate.ptr = nvpix->lbo->map;
+	} else {
+		if (nouveau_bo_map(nvpix->bo, NOUVEAU_BO_RDWR)) {
+			xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Mapping of bo failed\n");
 			return FALSE;
+		}
+
+		pPix->devPrivate.ptr = nvpix->bo->map;
 	}
 
-	pPix->devPrivate.ptr = nvpix->bo->map;
 	return TRUE;
 }
 
@@ -710,7 +887,38 @@ NVExaFinishAccess(PixmapPtr pPix, int index)
 	if (!nvpix || !nvpix->bo)
 		return;
 
-	nouveau_bo_unmap(nvpix->bo);
+	ErrorF("FinishAccess %d on pixmap 0x%16X\n", index, pPix);
+
+	nvpix->flags &= ~(1 << index);
+
+	/* Someone else still needs it. */
+	if (nvpix->flags)
+		return;
+
+	if (nvpix->bo->tiled) {
+		ErrorF("Tiled FinishAccess\n");
+		struct nouveau_bo_copy info;
+		int ret;
+
+		info.src = nvpix->lbo;
+		info.dst = nvpix->bo;
+		info.x = info.y = 0;
+		info.w = pPix->drawable.width;
+		info.h = pPix->drawable.height;
+		info.cpp = pPix->drawable.bitsPerPixel >> 3;
+		info.src_pitch = info.dst_pitch = exaGetPixmapPitch(pPix);
+		info.src_line_len = info.dst_line_len = info.w * info.cpp;
+		info.src_height = info.dst_height = info.h;
+
+		ret = nv_accel_m2mf_copy_bo(pScrn, &info);
+		if (!ret)
+			xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to copy linear data to tiled bo.\n");
+
+		nouveau_bo_unmap(nvpix->lbo);
+		nouveau_bo_ref(NULL, &nvpix->lbo);
+	} else
+		nouveau_bo_unmap(nvpix->bo);
+
 	pPix->devPrivate.ptr = NULL;
 }
 
@@ -726,6 +934,9 @@ NVExaPixmapIsOffscreen(PixmapPtr pPix)
 	if (!nvpix || !nvpix->bo)
 		return FALSE;
 
+	if (pPix->drawable.bitsPerPixel < 8)
+		return FALSE;
+
 	return TRUE;
 }
 
@@ -791,8 +1002,9 @@ NVExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
 			 */
 			uint32_t bpp = pPixmap->drawable.bitsPerPixel;
 
-			/* At some point we should just keep bpp 1 pixmaps in sysram. */
-			flags = NOUVEAU_BO_VRAM;
+			/* Keep bpp 1 pixmaps in sysram. */
+			if (pPixmap->drawable.bitsPerPixel >= 8)
+				flags |= NOUVEAU_BO_VRAM;
 
 			/* Assuming that exa doesn't mess with devKind. */
 			/* The migration code isn't touched so that is a fairly safe assumption. */
@@ -809,12 +1021,23 @@ NVExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
 			if (nouveau_bo_new(pNv->dev, flags, 0, nvpix->size,
 					   &nvpix->bo)) {
 				xfree(nvpix);
+				ErrorF("nouveau_bo_new failed\n");
 				return FALSE;
 			}
 
 			/* We don't want devPrivate.ptr set at all. */
 			miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, NULL);
 
+			/* Permanently map sysram pixmaps. This is what exa expects for !offscreen. */
+			if (pPixmap->drawable.bitsPerPixel < 8) {
+				if (nouveau_bo_map(nvpix->bo, NOUVEAU_BO_RDWR)) {
+					ErrorF("Mapping of sysram pixmap failed.\n");
+					return FALSE;
+				}
+				pPixmap->devPrivate.ptr = nvpix->bo->map;
+				ErrorF("ptr 0x%08X\n", pPixmap->devPrivate.ptr);
+			}
+
 			/* Returning TRUE means the ModifyPixmapHeader chain needs to be stopped. */
 			/* Otherwise you end up with devKind being overriden again. */
 			return TRUE;
diff --git a/src/nv_type.h b/src/nv_type.h
index 0e6e890..40f8dae 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -357,9 +357,25 @@ enum LVDS_script {
 
 struct nouveau_pixmap {
 	struct nouveau_bo *bo;
+	struct nouveau_bo *lbo; /* Linear copy for nv50. */
+	uint32_t flags; /* tiled access flags */
 	int size;
 };
 
+struct nouveau_bo_copy {
+	/* Buffer objects. */
+	struct nouveau_bo *src;
+	struct nouveau_bo *dst;
+
+	/* Dimensions to copy. */
+	int x, y, w, h;
+
+	/* Pixmap information. */
+	int cpp;
+	int src_pitch, src_line_len, src_height;
+	int dst_pitch, dst_line_len, dst_height;
+};
+
 static inline struct nouveau_pixmap *
 nouveau_pixmap(PixmapPtr pPixmap)
 {
@@ -604,7 +620,7 @@ typedef struct _NVPortPrivRec {
 
 #define TIMER_MASK      (OFF_TIMER | FREE_TIMER)
 
-#if 0
+#if 1
 #define NOUVEAU_FALLBACK(fmt,args...) do {        \
 	fprintf(stderr, "FALLBACK: "fmt, ##args); \
 	return FALSE;                             \

[-- Attachment #8: Type: text/plain, Size: 181 bytes --]

_______________________________________________
Nouveau mailing list
Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-01-05 20:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-03 16:53 some patches and remarks for ng Maarten Maathuis
     [not found] ` <6d4bc9fc0901030853q7f341c16l231ebf42c4643ede-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-01-05  0:24   ` Ben Skeggs
     [not found]     ` <1231115075.14351.23.camel-oFTkVezJ1HzzwxVw7NwMvg@public.gmane.org>
2009-01-05 15:07       ` Maarten Maathuis
     [not found]         ` <49622226.6070705-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-01-05 15:27           ` Maarten Maathuis
     [not found]             ` <496226DD.5020403-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-01-05 20:57               ` Ben Skeggs

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.