nv50,nvc0: prevent pushbuf flush during ctx reloc emission
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 23 Jun 2011 11:13:22 +0000 (13:13 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 23 Jun 2011 22:15:58 +0000 (00:15 +0200)
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
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_screen.h
src/gallium/drivers/nv50/nv50_vbo.c
src/gallium/drivers/nvc0/nvc0_context.c
src/gallium/drivers/nvc0/nvc0_context.h
src/gallium/drivers/nvc0/nvc0_screen.h
src/gallium/drivers/nvc0/nvc0_vbo.c

index 632ca4daf742adaa557bcfabbb61ef574a791c67..ceb83f6e684a51a184fad8607964d80e1f78a99e 100644 (file)
@@ -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);
 
index 3f031994f0a29f130ad08c20deb1d7d17b833f3e..b4af24f6bce6ed2187123a8c3e2f87338617793f 100644 (file)
@@ -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);
 }
 
index aea434b86795d38f2c08c14d12115d2c646aa8f7..64ad209a728a3053c8a60d67f33d523ef75df40a 100644 (file)
@@ -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;
index abdb9ce2f936a01d43b07067c5283a4ac74c5980..bb08941c24301617d5671fe0d40f80e5d1bdfb0d 100644 (file)
@@ -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);
 }
index 2f2a3da7c44f7f011238fe0b43364cdf86090569..2679b7f86aaa389fd30a9ea3c04988c4b17fa99d 100644 (file)
@@ -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);
 
index f97141dd46e0ad1c14cd52e86e4d5bcb3fae1a26..b05cc337d5de0b9c0e023053a3bc77c6a8a7af89 100644 (file)
@@ -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);
 }
 
index 94bf0cf348151df0237d1b2b90f3c7c63fe45d62..015807e2f5d97fabb90adef8b65547dd2e18124b 100644 (file)
@@ -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;
index 6bbcf2447eca1271b45a28407fb565e2b726a751..41079104b3992b1e4f05c714092ba4f1da3df0f6 100644 (file)
@@ -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);
 }