summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nouveau
diff options
context:
space:
mode:
authorIlia Mirkin <imirkin@alum.mit.edu>2014-06-30 23:49:46 -0400
committerCarl Worth <cworth@cworth.org>2014-07-03 20:04:12 -0700
commite11b3f8fbc65d8d8022f65c1df69ae9c82840d54 (patch)
treea9a4f10d400a21f26166c013c7185c05db0d7b21 /src/gallium/drivers/nouveau
parentda80e6a1c45a6dc6952f7a009caedf26efd0320b (diff)
nv50: do an explicit flush on draw when there are persistent buffers
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Cc: "10.2" <mesa-stable@lists.freedesktop.org> (cherry picked from commit 5d4f5218bb71cb387f1a57ea08125245e5039e94)
Diffstat (limited to 'src/gallium/drivers/nouveau')
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_context.c22
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_context.h1
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_vbo.c29
3 files changed, 50 insertions, 2 deletions
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c
index 3f3a888eaf2..c2eb0c000ec 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c
@@ -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;
+ }
+ }
}
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h
index 3b7cb1854d5..9c2af40e53b 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h
@@ -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 */
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index 7c2b7ff1049..5a4a4578d51 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
@@ -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;