+
+ fd_resource_set_usage(cb->buffer, FD_DIRTY_CONST);
+}
+
+static void
+fd_set_shader_buffers(struct pipe_context *pctx,
+ enum pipe_shader_type shader,
+ unsigned start, unsigned count,
+ const struct pipe_shader_buffer *buffers,
+ unsigned writable_bitmask)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ struct fd_shaderbuf_stateobj *so = &ctx->shaderbuf[shader];
+ const unsigned modified_bits = u_bit_consecutive(start, count);
+
+ so->enabled_mask &= ~modified_bits;
+ so->writable_mask &= ~modified_bits;
+ so->writable_mask |= writable_bitmask << start;
+
+ for (unsigned i = 0; i < count; i++) {
+ unsigned n = i + start;
+ struct pipe_shader_buffer *buf = &so->sb[n];
+
+ if (buffers && buffers[i].buffer) {
+ if ((buf->buffer == buffers[i].buffer) &&
+ (buf->buffer_offset == buffers[i].buffer_offset) &&
+ (buf->buffer_size == buffers[i].buffer_size))
+ continue;
+
+ buf->buffer_offset = buffers[i].buffer_offset;
+ buf->buffer_size = buffers[i].buffer_size;
+ pipe_resource_reference(&buf->buffer, buffers[i].buffer);
+
+ fd_resource_set_usage(buffers[i].buffer, FD_DIRTY_SSBO);
+
+ so->enabled_mask |= BIT(n);
+ } else {
+ pipe_resource_reference(&buf->buffer, NULL);
+ }
+ }
+
+ ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_SSBO;
+ ctx->dirty |= FD_DIRTY_SSBO;
+}
+
+void
+fd_set_shader_images(struct pipe_context *pctx,
+ enum pipe_shader_type shader,
+ unsigned start, unsigned count,
+ const struct pipe_image_view *images)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ struct fd_shaderimg_stateobj *so = &ctx->shaderimg[shader];
+
+ unsigned mask = 0;
+
+ if (images) {
+ for (unsigned i = 0; i < count; i++) {
+ unsigned n = i + start;
+ struct pipe_image_view *buf = &so->si[n];
+
+ if ((buf->resource == images[i].resource) &&
+ (buf->format == images[i].format) &&
+ (buf->access == images[i].access) &&
+ !memcmp(&buf->u, &images[i].u, sizeof(buf->u)))
+ continue;
+
+ mask |= BIT(n);
+ util_copy_image_view(buf, &images[i]);
+
+ if (buf->resource) {
+ fd_resource_set_usage(buf->resource, FD_DIRTY_IMAGE);
+ so->enabled_mask |= BIT(n);
+ } else {
+ so->enabled_mask &= ~BIT(n);
+ }
+ }
+ } else {
+ mask = (BIT(count) - 1) << start;
+
+ for (unsigned i = 0; i < count; i++) {
+ unsigned n = i + start;
+ struct pipe_image_view *img = &so->si[n];
+
+ pipe_resource_reference(&img->resource, NULL);
+ }
+
+ so->enabled_mask &= ~mask;
+ }
+
+ ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_IMAGE;
+ ctx->dirty |= FD_DIRTY_IMAGE;