[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