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 <imirkin@alum.mit.edu>
Cc: "12.0" <mesa-stable@lists.freedesktop.org>
This commit is contained in:
Ilia Mirkin 2016-06-04 13:50:21 -04:00
parent e8ee161b16
commit 0f673db6f0

View file

@ -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;