Mesa (master): nouveau: place static buffers in VRAM if preferred by the driver

Christoph Bumiller chrisbmr at kemper.freedesktop.org
Thu May 17 13:27:18 UTC 2012


Module: Mesa
Branch: master
Commit: 1befacc7647f51344f5cfbfa86b62e53625a436f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1befacc7647f51344f5cfbfa86b62e53625a436f

Author: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Date:   Thu May 17 14:43:47 2012 +0200

nouveau: place static buffers in VRAM if preferred by the driver

---

 src/gallium/drivers/nouveau/nouveau_buffer.c |   29 ++++++++++++++++++++++---
 src/gallium/drivers/nouveau/nouveau_screen.c |   10 +++++++++
 src/gallium/drivers/nouveau/nouveau_screen.h |    8 ++++++-
 src/gallium/drivers/nv30/nv30_screen.c       |   10 ++++++--
 src/gallium/drivers/nv50/nv50_screen.c       |   10 +++++++-
 src/gallium/drivers/nvc0/nvc0_screen.c       |    7 ++++-
 6 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index c396e3c..d04ac2f 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -363,10 +363,31 @@ nouveau_buffer_create(struct pipe_screen *pscreen,
    pipe_reference_init(&buffer->base.reference, 1);
    buffer->base.screen = pscreen;
 
-   if ((buffer->base.bind & screen->sysmem_bindings) == screen->sysmem_bindings)
-      ret = nouveau_buffer_allocate(screen, buffer, 0);
-   else
-      ret = nouveau_buffer_allocate(screen, buffer, NOUVEAU_BO_GART);
+   if (buffer->base.bind &
+       (screen->vidmem_bindings & screen->sysmem_bindings)) {
+      switch (buffer->base.usage) {
+      case PIPE_USAGE_DEFAULT:
+      case PIPE_USAGE_IMMUTABLE:
+      case PIPE_USAGE_STATIC:
+         buffer->domain = NOUVEAU_BO_VRAM;
+         break;
+      case PIPE_USAGE_DYNAMIC:
+      case PIPE_USAGE_STAGING:
+      case PIPE_USAGE_STREAM:
+         buffer->domain = NOUVEAU_BO_GART;
+         break;
+      default:
+         assert(0);
+         break;
+      }
+   } else {
+      if (buffer->base.bind & screen->vidmem_bindings)
+         buffer->domain = NOUVEAU_BO_VRAM;
+      else
+      if (buffer->base.bind & screen->sysmem_bindings)
+         buffer->domain = NOUVEAU_BO_GART;
+   }
+   ret = nouveau_buffer_allocate(screen, buffer, buffer->domain);
 
    if (ret == FALSE)
       goto fail;
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 7437779..9baa68c 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -148,6 +148,16 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
 
 	util_format_s3tc_init();
 
+	screen->lowmem_bindings = PIPE_BIND_GLOBAL; /* gallium limit */
+	screen->vidmem_bindings =
+		PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL |
+		PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR |
+		PIPE_BIND_SAMPLER_VIEW |
+		PIPE_BIND_SHADER_RESOURCE | PIPE_BIND_COMPUTE_RESOURCE |
+		PIPE_BIND_GLOBAL;
+	screen->sysmem_bindings =
+		PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT;
+
 	memset(&mm_config, 0, sizeof(mm_config));
 
 	screen->mm_GART = nouveau_mm_create(dev,
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index 4ca286b..5a3cfab 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -17,7 +17,13 @@ struct nouveau_screen {
 	struct nouveau_client *client;
 	struct nouveau_pushbuf *pushbuf;
 
-	unsigned sysmem_bindings;
+	unsigned vidmem_bindings; /* PIPE_BIND_* where VRAM placement is desired */
+	unsigned sysmem_bindings; /* PIPE_BIND_* where GART placement is desired */
+	unsigned lowmem_bindings; /* PIPE_BIND_* that require an address < 4 GiB */
+	/*
+	 * For bindings with (vidmem & sysmem) bits set set, PIPE_USAGE_* decides
+	 * placement.
+	 */
 
 	uint16_t class_3d;
 
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index f5120e7..67de8c0 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -371,14 +371,18 @@ nv30_screen_create(struct nouveau_device *dev)
 
    screen->base.fence.emit = nv30_screen_fence_emit;
    screen->base.fence.update = nv30_screen_fence_update;
-   screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER;
-   if (oclass != NV40_3D_CLASS)
-      screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER;
 
    ret = nouveau_screen_init(&screen->base, dev);
    if (ret)
       FAIL_SCREEN_INIT("nv30_screen_init failed: %d\n", ret);
 
+   screen->base.vidmem_bindings |= PIPE_BIND_VERTEX_BUFFER;
+   screen->base.sysmem_bindings |= PIPE_BIND_VERTEX_BUFFER;
+   if (oclass == NV40_3D_CLASS) {
+      screen->base.vidmem_bindings |= PIPE_BIND_INDEX_BUFFER;
+      screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER;
+   }
+
    fifo = screen->base.channel->data;
    push = screen->base.pushbuf;
    push->rsvd_kick = 16;
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index d7efa35..9567abb 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -532,12 +532,18 @@ nv50_screen_create(struct nouveau_device *dev)
       return NULL;
    pscreen = &screen->base.base;
 
-   screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER;
-
    ret = nouveau_screen_init(&screen->base, dev);
    if (ret)
       FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret);
 
+   /* TODO: Prevent FIFO prefetch before transfer of index buffers and
+    *  admit them to VRAM.
+    */
+   screen->base.vidmem_bindings |= PIPE_BIND_CONSTANT_BUFFER |
+      PIPE_BIND_VERTEX_BUFFER;
+   screen->base.sysmem_bindings |=
+      PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER;
+
    screen->base.pushbuf->user_priv = screen;
    screen->base.pushbuf->rsvd_kick = 5;
 
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index 0717ac8..49d6118 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -418,8 +418,6 @@ nvc0_screen_create(struct nouveau_device *dev)
       return NULL;
    pscreen = &screen->base.base;
 
-   screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER;
-
    ret = nouveau_screen_init(&screen->base, dev);
    if (ret) {
       nvc0_screen_destroy(pscreen);
@@ -429,6 +427,11 @@ nvc0_screen_create(struct nouveau_device *dev)
    push = screen->base.pushbuf;
    push->user_priv = screen;
 
+   screen->base.vidmem_bindings |= PIPE_BIND_CONSTANT_BUFFER |
+      PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER;
+   screen->base.sysmem_bindings |=
+      PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER;
+
    pscreen->destroy = nvc0_screen_destroy;
    pscreen->context_create = nvc0_create;
    pscreen->is_format_supported = nvc0_screen_is_format_supported;




More information about the mesa-commit mailing list