[Nouveau] [libdrm PATCH] nouveau: optimize OUT_RELOC2

Marcin Slusarz marcin.slusarz at gmail.com
Wed Jan 12 12:43:50 PST 2011


use one relocation with newly introduced flag

unfortunately we can't enable it unconditionally, because we don't
know if the kernel supports it...
---
 include/drm/nouveau_drm.h |    1 +
 nouveau/nouveau_bo.h      |    1 +
 nouveau/nouveau_pushbuf.h |    9 +++++++++
 nouveau/nouveau_reloc.c   |   28 ++++++++++++++++++++++------
 4 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h
index b18cad0..4c35399 100644
--- a/include/drm/nouveau_drm.h
+++ b/include/drm/nouveau_drm.h
@@ -138,6 +138,7 @@ struct drm_nouveau_gem_pushbuf_bo {
 #define NOUVEAU_GEM_RELOC_LOW  (1 << 0)
 #define NOUVEAU_GEM_RELOC_HIGH (1 << 1)
 #define NOUVEAU_GEM_RELOC_OR   (1 << 2)
+#define NOUVEAU_GEM_RELOC_HILO (1 << 3)
 #define NOUVEAU_GEM_MAX_RELOCS 1024
 struct drm_nouveau_gem_pushbuf_reloc {
 	uint32_t reloc_bo_index;
diff --git a/nouveau/nouveau_bo.h b/nouveau/nouveau_bo.h
index 3a1f2d4..bbf88ec 100644
--- a/nouveau/nouveau_bo.h
+++ b/nouveau/nouveau_bo.h
@@ -37,6 +37,7 @@
 #define NOUVEAU_BO_NOSYNC (1 << 13)
 #define NOUVEAU_BO_NOWAIT (1 << 14)
 #define NOUVEAU_BO_IFLUSH (1 << 15)
+#define NOUVEAU_BO_HILO   (1 << 16)
 #define NOUVEAU_BO_DUMMY  (1 << 31)
 
 #define NOUVEAU_BO_TILE_LAYOUT_MASK 0x0000ff00
diff --git a/nouveau/nouveau_pushbuf.h b/nouveau/nouveau_pushbuf.h
index f256c70..92bffde 100644
--- a/nouveau/nouveau_pushbuf.h
+++ b/nouveau/nouveau_pushbuf.h
@@ -142,15 +142,24 @@ OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo,
 	return OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0);
 }
 
+//disabled for now
+//#define NOUVEAU_DRM_NEW_RELOC
 /* High 32-bits, then low 32-bits of offset */
 static __inline__ int
 OUT_RELOC2(struct nouveau_channel *chan, struct nouveau_bo *bo,
 	   unsigned delta, unsigned flags)
 {
+#ifdef NOUVEAU_DRM_NEW_RELOC
+	int r = nouveau_pushbuf_emit_reloc(chan, chan->cur, bo,
+					  delta, flags | NOUVEAU_BO_HILO, 0, 0);
+	chan->cur += 2;
+	return r;
+#else
 	int r = OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0);
 	if (r)
 		return r;
 	return OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0);
+#endif
 }
 
 #endif
diff --git a/nouveau/nouveau_reloc.c b/nouveau/nouveau_reloc.c
index c636333..864ab61 100644
--- a/nouveau/nouveau_reloc.c
+++ b/nouveau/nouveau_reloc.c
@@ -29,19 +29,21 @@
 
 static uint32_t
 nouveau_reloc_calc(struct drm_nouveau_gem_pushbuf_bo *pbbo,
-		   struct drm_nouveau_gem_pushbuf_reloc *r)
+		   struct drm_nouveau_gem_pushbuf_reloc *r,
+		   uint32_t flags)
 {
 	uint32_t push = 0;
+	flags |= r->flags;
 
-	if (r->flags & NOUVEAU_GEM_RELOC_LOW)
+	if (flags & NOUVEAU_GEM_RELOC_LOW)
 		push = (pbbo->presumed.offset + r->data);
 	else
-	if (r->flags & NOUVEAU_GEM_RELOC_HIGH)
+	if (flags & NOUVEAU_GEM_RELOC_HIGH)
 		push = (pbbo->presumed.offset + r->data) >> 32;
 	else
 		push = r->data;
 
-	if (r->flags & NOUVEAU_GEM_RELOC_OR) {
+	if (flags & NOUVEAU_GEM_RELOC_OR) {
 		if (pbbo->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM)
 			push |= r->vor;
 		else
@@ -138,15 +140,29 @@ nouveau_reloc_emit(struct nouveau_channel *chan, struct nouveau_bo *reloc_bo,
 		r->flags |= NOUVEAU_GEM_RELOC_HIGH;
 	if (flags & NOUVEAU_BO_OR)
 		r->flags |= NOUVEAU_GEM_RELOC_OR;
+	if (flags & NOUVEAU_BO_HILO)
+		r->flags |= NOUVEAU_GEM_RELOC_HILO;
 	r->data = data;
 	r->vor = vor;
 	r->tor = tor;
 
 	if (reloc_ptr) {
 		if (flags & NOUVEAU_BO_DUMMY)
-			*reloc_ptr = 0;
+			if (flags & NOUVEAU_BO_HILO) {
+				reloc_ptr[0] = 0;
+				reloc_ptr[1] = 0;
+			} else 
+				*reloc_ptr = 0;
 		else
-			*reloc_ptr = nouveau_reloc_calc(pbbo, r);
+		{
+			if (flags & NOUVEAU_BO_HILO) {
+				reloc_ptr[0] = nouveau_reloc_calc(pbbo, r,
+							NOUVEAU_GEM_RELOC_HIGH);
+				reloc_ptr[1] = nouveau_reloc_calc(pbbo, r,
+							NOUVEAU_GEM_RELOC_LOW);
+			} else
+				*reloc_ptr = nouveau_reloc_calc(pbbo, r, 0);
+		}
 	}
 
 	return 0;
-- 
1.7.3.3



More information about the Nouveau mailing list