summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-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;