nv50: do an explicit flush on draw when there are persistent buffers
authorIlia Mirkin <imirkin@alum.mit.edu>
Tue, 1 Jul 2014 03:49:46 +0000 (23:49 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Fri, 4 Jul 2014 00:01:07 +0000 (20:01 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Cc: "10.2" <mesa-stable@lists.freedesktop.org>
src/gallium/drivers/nouveau/nv50/nv50_context.c
src/gallium/drivers/nouveau/nv50/nv50_context.h
src/gallium/drivers/nouveau/nv50/nv50_vbo.c

index 3f3a888eaf2ed5b2dc4ad76cdb8e1848198836e4..c2eb0c000ec95593bddd9755e130308e20d00e09 100644 (file)
@@ -61,7 +61,7 @@ static void
 nv50_memory_barrier(struct pipe_context *pipe, unsigned flags)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
-   int i;
+   int i, s;
 
    if (flags & PIPE_BARRIER_MAPPED_BUFFER) {
       for (i = 0; i < nv50->num_vtxbufs; ++i) {
@@ -74,6 +74,26 @@ nv50_memory_barrier(struct pipe_context *pipe, unsigned flags)
       if (nv50->idxbuf.buffer &&
           nv50->idxbuf.buffer->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
          nv50->base.vbo_dirty = TRUE;
+
+      for (s = 0; s < 3 && !nv50->cb_dirty; ++s) {
+         uint32_t valid = nv50->constbuf_valid[s];
+
+         while (valid && !nv50->cb_dirty) {
+            const unsigned i = ffs(valid) - 1;
+            struct pipe_resource *res;
+
+            valid &= ~(1 << i);
+            if (nv50->constbuf[s][i].user)
+               continue;
+
+            res = nv50->constbuf[s][i].u.buf;
+            if (!res)
+               continue;
+
+            if (res->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
+               nv50->cb_dirty = TRUE;
+         }
+      }
    }
 }
 
index 3b7cb1854d5275b67f97fa6c57b698844c8add10..9c2af40e53bf6d9ff06c3960f1c3cad1ed2bd599 100644 (file)
@@ -106,6 +106,7 @@ struct nv50_context {
    struct nouveau_bufctx *bufctx;
 
    uint32_t dirty;
+   boolean cb_dirty;
 
    struct {
       uint32_t instance_elts; /* bitmask of per-instance elements */
index 7c2b7ff1049007a4ee4b61e36c16c0d6d11320d1..5a4a4578d51e73a25f52d91101d4506a19f5a150 100644 (file)
@@ -747,7 +747,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
    struct nouveau_pushbuf *push = nv50->base.pushbuf;
-   int i;
+   int i, s;
 
    /* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
    nv50->vb_elt_first = info->min_index + info->index_bias;
@@ -776,6 +776,33 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 
    push->kick_notify = nv50_draw_vbo_kick_notify;
 
+   for (s = 0; s < 3 && !nv50->cb_dirty; ++s) {
+      uint32_t valid = nv50->constbuf_valid[s];
+
+      while (valid && !nv50->cb_dirty) {
+         const unsigned i = ffs(valid) - 1;
+         struct pipe_resource *res;
+
+         valid &= ~(1 << i);
+         if (nv50->constbuf[s][i].user)
+            continue;
+
+         res = nv50->constbuf[s][i].u.buf;
+         if (!res)
+            continue;
+
+         if (res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)
+            nv50->cb_dirty = TRUE;
+      }
+   }
+
+   /* If there are any coherent constbufs, flush the cache */
+   if (nv50->cb_dirty) {
+      BEGIN_NV04(push, NV50_3D(CODE_CB_FLUSH), 1);
+      PUSH_DATA (push, 0);
+      nv50->cb_dirty = FALSE;
+   }
+
    if (nv50->vbo_fifo) {
       nv50_push_vbo(nv50, info);
       push->kick_notify = nv50_default_kick_notify;