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;
else
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_BUF);
+ return true;
}
static void
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;