nvc0: add a memory barrier when there are persistent UBOs
authorIlia Mirkin <imirkin@alum.mit.edu>
Tue, 1 Jul 2014 04:49:34 +0000 (00:49 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Fri, 4 Jul 2014 00:08:41 +0000 (20:08 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Cc: "10.2" <mesa-stable@lists.freedesktop.org>
src/gallium/drivers/nouveau/nvc0/nvc0_context.c
src/gallium/drivers/nouveau/nvc0/nvc0_context.h
src/gallium/drivers/nouveau/nvc0/nvc0_state.c
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
src/gallium/drivers/nouveau/nvc0/nvc0_winsys.h

index e5040c463322efd8a055295d2047b1afd7c88362..5928c994c5de35afff4fb97d05559a592aa57945 100644 (file)
@@ -60,7 +60,7 @@ static void
 nvc0_memory_barrier(struct pipe_context *pipe, unsigned flags)
 {
    struct nvc0_context *nvc0 = nvc0_context(pipe);
-   int i;
+   int i, s;
 
    if (flags & PIPE_BARRIER_MAPPED_BUFFER) {
       for (i = 0; i < nvc0->num_vtxbufs; ++i) {
@@ -73,6 +73,26 @@ nvc0_memory_barrier(struct pipe_context *pipe, unsigned flags)
       if (nvc0->idxbuf.buffer &&
           nvc0->idxbuf.buffer->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
          nvc0->base.vbo_dirty = TRUE;
+
+      for (s = 0; s < 5 && !nvc0->cb_dirty; ++s) {
+         uint32_t valid = nvc0->constbuf_valid[s];
+
+         while (valid && !nvc0->cb_dirty) {
+            const unsigned i = ffs(valid) - 1;
+            struct pipe_resource *res;
+
+            valid &= ~(1 << i);
+            if (nvc0->constbuf[s][i].user)
+               continue;
+
+            res = nvc0->constbuf[s][i].u.buf;
+            if (!res)
+               continue;
+
+            if (res->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
+               nvc0->cb_dirty = TRUE;
+         }
+      }
    }
 }
 
index 052f0bae5c6bf1a2112bf58367ec8ae41aed6f89..ebeb8c48fbaf4d52b6731e31b450ab08e6614dec 100644 (file)
@@ -154,6 +154,8 @@ struct nvc0_context {
 
    struct nvc0_constbuf constbuf[6][NVC0_MAX_PIPE_CONSTBUFS];
    uint16_t constbuf_dirty[6];
+   uint16_t constbuf_valid[6];
+   boolean cb_dirty;
 
    struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
    unsigned num_vtxbufs;
index ef9d479ca07975b6955b873c635f47f28d28076c..d1a7cf515595eae3cf6c6cbf32e730d463088ad3 100644 (file)
@@ -808,10 +808,15 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
    if (nvc0->constbuf[s][i].user) {
       nvc0->constbuf[s][i].u.data = cb->user_buffer;
       nvc0->constbuf[s][i].size = cb->buffer_size;
+      nvc0->constbuf_valid[s] |= 1 << i;
    } else
    if (cb) {
       nvc0->constbuf[s][i].offset = cb->buffer_offset;
       nvc0->constbuf[s][i].size = align(cb->buffer_size, 0x100);
+      nvc0->constbuf_valid[s] |= 1 << i;
+   }
+   else {
+      nvc0->constbuf_valid[s] &= ~(1 << i);
    }
 }
 
index 83d406d564652e73bdb67360751df2baf7696c16..c26b98fb5f03705a57b843d2da2154fc879b927e 100644 (file)
@@ -799,7 +799,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct nvc0_context *nvc0 = nvc0_context(pipe);
    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
-   int i;
+   int i, s;
 
    /* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
    nvc0->vb_elt_first = info->min_index + info->index_bias;
@@ -832,6 +832,31 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 
    push->kick_notify = nvc0_draw_vbo_kick_notify;
 
+   for (s = 0; s < 5 && !nvc0->cb_dirty; ++s) {
+      uint32_t valid = nvc0->constbuf_valid[s];
+
+      while (valid && !nvc0->cb_dirty) {
+         const unsigned i = ffs(valid) - 1;
+         struct pipe_resource *res;
+
+         valid &= ~(1 << i);
+         if (nvc0->constbuf[s][i].user)
+            continue;
+
+         res = nvc0->constbuf[s][i].u.buf;
+         if (!res)
+            continue;
+
+         if (res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)
+            nvc0->cb_dirty = TRUE;
+      }
+   }
+
+   if (nvc0->cb_dirty) {
+      IMMED_NVC0(push, NVC0_3D(MEM_BARRIER), 0x1011);
+      nvc0->cb_dirty = FALSE;
+   }
+
    if (nvc0->state.vbo_mode) {
       nvc0_push_vbo(nvc0, info);
       push->kick_notify = nvc0_default_kick_notify;
index 3514d9dc3d044ce79457b0610472661175159256..a83b31d0dc437043d16b47799ee2ae29af01cef6 100644 (file)
@@ -80,8 +80,9 @@ NVC0_FIFO_PKHDR_NI(int subc, int mthd, unsigned size)
 }
 
 static INLINE uint32_t
-NVC0_FIFO_PKHDR_IL(int subc, int mthd, uint8_t data)
+NVC0_FIFO_PKHDR_IL(int subc, int mthd, uint16_t data)
 {
+   assert(data < 0x2000);
    return 0x80000000 | (data << 16) | (subc << 13) | (mthd >> 2);
 }
 
@@ -133,7 +134,7 @@ BEGIN_1IC0(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
 }
 
 static INLINE void
-IMMED_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, uint8_t data)
+IMMED_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, uint16_t data)
 {
 #ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
    PUSH_SPACE(push, 1);