Mesa (master): nv50, nvc0: prevent pushbuf flush during ctx reloc emission

Christoph Bumiller chrisbmr at kemper.freedesktop.org
Thu Jun 23 22:17:00 UTC 2011


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

Author: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Date:   Thu Jun 23 13:13:22 2011 +0200

nv50,nvc0: prevent pushbuf flush during ctx reloc emission

Should unify this too, but will delay that until the planned
libdrm_nouveau/winsys changes which are likely to cause major
changes to this bo validation code too.

---

 src/gallium/drivers/nv50/nv50_context.c |    8 +++++++-
 src/gallium/drivers/nv50/nv50_context.h |    2 ++
 src/gallium/drivers/nv50/nv50_screen.h  |    2 ++
 src/gallium/drivers/nv50/nv50_vbo.c     |   15 +++++----------
 src/gallium/drivers/nvc0/nvc0_context.c |    8 +++++++-
 src/gallium/drivers/nvc0/nvc0_context.h |    2 ++
 src/gallium/drivers/nvc0/nvc0_screen.h  |    2 ++
 src/gallium/drivers/nvc0/nvc0_vbo.c     |   15 +++++----------
 8 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 632ca4d..ceb83f6 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -168,6 +168,7 @@ nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx,
 
    if (!resource->bo)
       return;
+   nv50->residents_size += sizeof(struct resident);
 
    /* We don't need to reference the resource here, it will be referenced
     * in the context/state, and bufctx will be reset when state changes.
@@ -189,6 +190,7 @@ nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx,
          top = util_dynarray_pop_ptr(&nv50->residents[ctx], struct resident);
          if (rsd != top)
             *rsd = *top;
+         nv50->residents_size -= sizeof(struct resident);
          break;
       }
    }
@@ -201,11 +203,15 @@ nv50_bufctx_emit_relocs(struct nv50_context *nv50)
    struct util_dynarray *array;
    unsigned ctx, i, n;
 
+   n  = nv50->residents_size / sizeof(struct resident);
+   n += NV50_SCREEN_RESIDENT_BO_COUNT;
+
+   MARK_RING(nv50->screen->base.channel, n, n);
+
    for (ctx = 0; ctx < NV50_BUFCTX_COUNT; ++ctx) {
       array = &nv50->residents[ctx];
 
       n = array->size / sizeof(struct resident);
-      MARK_RING(nv50->screen->base.channel, n, n);
       for (i = 0; i < n; ++i) {
          rsd = util_dynarray_element(array, struct resident, i);
 
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 3f03199..b4af24f 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -64,6 +64,7 @@ struct nv50_context {
    struct nv50_screen *screen;
 
    struct util_dynarray residents[NV50_BUFCTX_COUNT];
+   unsigned residents_size;
 
    uint32_t dirty;
 
@@ -156,6 +157,7 @@ void nv50_bufctx_del_resident(struct nv50_context *, int ctx,
 static INLINE void
 nv50_bufctx_reset(struct nv50_context *nv50, int ctx)
 {
+   nv50->residents_size -= nv50->residents[ctx].size;
    util_dynarray_resize(&nv50->residents[ctx], 0);
 }
 
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index aea434b..64ad209 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -19,6 +19,8 @@ struct nv50_context;
 #define NV50_SCRATCH_SIZE (2 << 20)
 #define NV50_SCRATCH_NR_BUFFERS 2
 
+#define NV50_SCREEN_RESIDENT_BO_COUNT 5
+
 struct nv50_screen {
    struct nouveau_screen base;
    struct nouveau_winsys *nvws;
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index abdb9ce..bb08941 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -404,9 +404,6 @@ nv50_draw_arrays(struct nv50_context *nv50,
    struct nouveau_channel *chan = nv50->screen->base.channel;
    unsigned prim;
 
-   chan->flush_notify = nv50_draw_vbo_flush_notify;
-   chan->user_private = nv50;
-
    prim = nv50_prim_gl(mode);
 
    while (instance_count--) {
@@ -420,8 +417,6 @@ nv50_draw_arrays(struct nv50_context *nv50,
 
       prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
    }
-
-   chan->flush_notify = nv50_default_flush_notify;
 }
 
 static void
@@ -523,9 +518,6 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten,
    unsigned prim;
    const unsigned index_size = nv50->idxbuf.index_size;
 
-   chan->flush_notify = nv50_draw_vbo_flush_notify;
-   chan->user_private = nv50;
-
    prim = nv50_prim_gl(mode);
 
    if (index_bias != nv50->state.index_bias) {
@@ -631,8 +623,6 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten,
          prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
       }
    }
-
-   chan->flush_notify = nv50_default_flush_notify;
 }
 
 void
@@ -659,8 +649,12 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 
    nv50_state_validate(nv50);
 
+   chan->flush_notify = nv50_draw_vbo_flush_notify;
+   chan->user_private = nv50;
+
    if (nv50->vbo_fifo) {
       nv50_push_vbo(nv50, info);
+      chan->flush_notify = nv50_default_flush_notify;
       return;
    }
 
@@ -712,6 +706,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
                          info->mode, info->start, info->count,
                          info->instance_count, info->index_bias);
    }
+   chan->flush_notify = nv50_default_flush_notify;
 
    nv50_release_user_vbufs(nv50);
 }
diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c
index 2f2a3da..2679b7f 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nvc0/nvc0_context.c
@@ -169,6 +169,7 @@ nvc0_bufctx_add_resident(struct nvc0_context *nvc0, int ctx,
 
    if (!resource->bo)
       return;
+   nvc0->residents_size += sizeof(struct resident);
 
    /* We don't need to reference the resource here, it will be referenced
     * in the context/state, and bufctx will be reset when state changes.
@@ -190,6 +191,7 @@ nvc0_bufctx_del_resident(struct nvc0_context *nvc0, int ctx,
          top = util_dynarray_pop_ptr(&nvc0->residents[ctx], struct resident);
          if (rsd != top)
             *rsd = *top;
+         nvc0->residents_size -= sizeof(struct resident);
          break;
       }
    }
@@ -202,11 +204,15 @@ nvc0_bufctx_emit_relocs(struct nvc0_context *nvc0)
    struct util_dynarray *array;
    unsigned ctx, i, n;
 
+   n  = nvc0->residents_size / sizeof(struct resident);
+   n += NVC0_SCREEN_RESIDENT_BO_COUNT;
+
+   MARK_RING(nvc0->screen->base.channel, n, n);
+
    for (ctx = 0; ctx < NVC0_BUFCTX_COUNT; ++ctx) {
       array = &nvc0->residents[ctx];
 
       n = array->size / sizeof(struct resident);
-      MARK_RING(nvc0->screen->base.channel, n, n);
       for (i = 0; i < n; ++i) {
          rsd = util_dynarray_element(array, struct resident, i);
 
diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h
index f97141d..b05cc33 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nvc0/nvc0_context.h
@@ -62,6 +62,7 @@ struct nvc0_context {
    struct nvc0_screen *screen;
 
    struct util_dynarray residents[NVC0_BUFCTX_COUNT];
+   unsigned residents_size;
 
    uint32_t dirty;
 
@@ -163,6 +164,7 @@ void nvc0_bufctx_del_resident(struct nvc0_context *, int ctx,
 static INLINE void
 nvc0_bufctx_reset(struct nvc0_context *nvc0, int ctx)
 {
+   nvc0->residents_size -= nvc0->residents[ctx].size;
    util_dynarray_resize(&nvc0->residents[ctx], 0);
 }
 
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h
index 94bf0cf..015807e 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nvc0/nvc0_screen.h
@@ -16,6 +16,8 @@ struct nvc0_context;
 #define NVC0_SCRATCH_SIZE (2 << 20)
 #define NVC0_SCRATCH_NR_BUFFERS 2
 
+#define NVC0_SCREEN_RESIDENT_BO_COUNT 5
+
 struct nvc0_screen {
    struct nouveau_screen base;
    struct nouveau_winsys *nvws;
diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c
index 6bbcf24..4107910 100644
--- a/src/gallium/drivers/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nvc0/nvc0_vbo.c
@@ -382,9 +382,6 @@ nvc0_draw_arrays(struct nvc0_context *nvc0,
    struct nouveau_channel *chan = nvc0->screen->base.channel;
    unsigned prim;
 
-   chan->flush_notify = nvc0_draw_vbo_flush_notify;
-   chan->user_private = nvc0;
-
    prim = nvc0_prim_gl(mode);
 
    while (instance_count--) {
@@ -397,8 +394,6 @@ nvc0_draw_arrays(struct nvc0_context *nvc0,
 
       prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
    }
-
-   chan->flush_notify = nvc0_default_flush_notify;
 }
 
 static void
@@ -500,9 +495,6 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
    unsigned prim;
    const unsigned index_size = nvc0->idxbuf.index_size;
 
-   chan->flush_notify = nvc0_draw_vbo_flush_notify;
-   chan->user_private = nvc0;
-
    prim = nvc0_prim_gl(mode);
 
    if (index_bias != nvc0->state.index_bias) {
@@ -568,8 +560,6 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
          prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
       }
    }
-
-   chan->flush_notify = nvc0_default_flush_notify;
 }
 
 void
@@ -596,8 +586,12 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 
    nvc0_state_validate(nvc0);
 
+   chan->flush_notify = nvc0_draw_vbo_flush_notify;
+   chan->user_private = nvc0;
+
    if (nvc0->vbo_fifo) {
       nvc0_push_vbo(nvc0, info);
+      chan->flush_notify = nvc0_default_flush_notify;
       return;
    }
 
@@ -648,6 +642,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
                          info->mode, info->start, info->count,
                          info->instance_count, info->index_bias);
    }
+   chan->flush_notify = nvc0_default_flush_notify;
 
    nvc0_release_user_vbufs(nvc0);
 }




More information about the mesa-commit mailing list