summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-06-04 13:50:21 -0400
committerIlia Mirkin <[email protected]>2016-06-04 23:50:56 -0400
commit0f673db6f08995312a2f5ed04aba191d59910099 (patch)
treed6ac814ecb3a7b56c7169ad7b5b3d6cdec7a0012
parente8ee161b160f6ff18134ff279b046f2e056bccd0 (diff)
nvc0: reduce overhead from always marking buffers dirty
We would revalidate buffers when anything was touched at all. Which is unfortunate, since the state tracker does not use CSO's to reduce the workload. So instead implement a protocol to ensure that something has changed before revalidating all the SSBOs. Signed-off-by: Ilia Mirkin <[email protected]> Cc: "12.0" <[email protected]>
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_state.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index e437a6479a0..6cdc007a086 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -1287,29 +1287,41 @@ nvc0_set_shader_images(struct pipe_context *pipe, unsigned shader,
nvc0_context(pipe)->dirty_3d |= NVC0_NEW_3D_SURFACES;
}
-static void
+static bool
nvc0_bind_buffers_range(struct nvc0_context *nvc0, const unsigned t,
unsigned start, unsigned nr,
struct pipe_shader_buffer *pbuffers)
{
const unsigned end = start + nr;
- const unsigned mask = ((1 << nr) - 1) << start;
+ unsigned mask = 0;
unsigned i;
assert(t < 6);
if (pbuffers) {
for (i = start; i < end; ++i) {
+ struct pipe_shader_buffer *buf = &nvc0->buffers[t][i];
const unsigned p = i - start;
+ if (buf->buffer == pbuffers[p].buffer &&
+ buf->buffer_offset == pbuffers[p].buffer_offset &&
+ buf->buffer_size == pbuffers[p].buffer_size)
+ continue;
+
+ mask |= (1 << i);
if (pbuffers[p].buffer)
nvc0->buffers_valid[t] |= (1 << i);
else
nvc0->buffers_valid[t] &= ~(1 << i);
- nvc0->buffers[t][i].buffer_offset = pbuffers[p].buffer_offset;
- nvc0->buffers[t][i].buffer_size = pbuffers[p].buffer_size;
- pipe_resource_reference(&nvc0->buffers[t][i].buffer, pbuffers[p].buffer);
+ buf->buffer_offset = pbuffers[p].buffer_offset;
+ buf->buffer_size = pbuffers[p].buffer_size;
+ pipe_resource_reference(&buf->buffer, pbuffers[p].buffer);
}
+ if (!mask)
+ return false;
} else {
+ mask = ((1 << nr) - 1) << start;
+ if (!(nvc0->buffers_valid[t] & mask))
+ return false;
for (i = start; i < end; ++i)
pipe_resource_reference(&nvc0->buffers[t][i].buffer, NULL);
nvc0->buffers_valid[t] &= ~mask;
@@ -1321,6 +1333,7 @@ nvc0_bind_buffers_range(struct nvc0_context *nvc0, const unsigned t,
else
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_BUF);
+ return true;
}
static void
@@ -1330,7 +1343,8 @@ nvc0_set_shader_buffers(struct pipe_context *pipe,
struct pipe_shader_buffer *buffers)
{
const unsigned s = nvc0_shader_stage(shader);
- nvc0_bind_buffers_range(nvc0_context(pipe), s, start, nr, buffers);
+ if (!nvc0_bind_buffers_range(nvc0_context(pipe), s, start, nr, buffers))
+ return;
if (s == 5)
nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_BUFFERS;