uint32_t dirty_mask;
};
+struct fd_shaderbuf_stateobj {
+ struct pipe_shader_buffer sb[PIPE_MAX_SHADER_BUFFERS];
+ uint32_t enabled_mask;
+ uint32_t dirty_mask;
+};
+
struct fd_vertexbuf_stateobj {
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
unsigned count;
FD_DIRTY_SHADER_PROG = BIT(0),
FD_DIRTY_SHADER_CONST = BIT(1),
FD_DIRTY_SHADER_TEX = BIT(2),
+ FD_DIRTY_SHADER_SSBO = BIT(3),
};
struct fd_context {
struct pipe_poly_stipple stipple;
struct pipe_viewport_state viewport;
struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES];
+ struct fd_shaderbuf_stateobj shaderbuf[PIPE_SHADER_TYPES];
struct pipe_index_buffer indexbuf;
struct fd_streamout_stateobj streamout;
struct pipe_clip_state ucp;
batch->gmem_reason |= FD_GMEM_BLEND_ENABLED;
}
+ /* Mark SSBOs as being written.. we don't actually know which ones are
+ * read vs written, so just assume the worst
+ */
+ foreach_bit(i, ctx->shaderbuf[PIPE_SHADER_FRAGMENT].enabled_mask)
+ resource_read(batch, ctx->shaderbuf[PIPE_SHADER_FRAGMENT].sb[i].buffer);
+
foreach_bit(i, ctx->constbuf[PIPE_SHADER_VERTEX].enabled_mask)
resource_read(batch, ctx->constbuf[PIPE_SHADER_VERTEX].cb[i].buffer);
foreach_bit(i, ctx->constbuf[PIPE_SHADER_FRAGMENT].enabled_mask)
if (ctx->tex[stage].textures[i] && (ctx->tex[stage].textures[i]->texture == prsc))
ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_TEX;
}
+
+ /* SSBOs */
+ const unsigned num_ssbos = util_last_bit(ctx->shaderbuf[stage].enabled_mask);
+ for (unsigned i = 0; i < num_ssbos; i++) {
+ if (ctx->dirty_shader[stage] & FD_DIRTY_SHADER_SSBO)
+ break;
+ if (ctx->shaderbuf[stage].sb[i].buffer == prsc)
+ ctx->dirty_shader[stage] |= FD_DIRTY_SHADER_SSBO;
+ }
}
}
ctx->dirty |= 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)
+{
+ struct fd_context *ctx = fd_context(pctx);
+ struct fd_shaderbuf_stateobj *so = &ctx->shaderbuf[shader];
+ unsigned mask = 0;
+
+ if (buffers) {
+ for (unsigned i = 0; i < count; i++) {
+ unsigned n = i + start;
+ struct pipe_shader_buffer *buf = &so->sb[n];
+
+ if ((buf->buffer == buffers[i].buffer) &&
+ (buf->buffer_offset == buffers[i].buffer_offset) &&
+ (buf->buffer_size == buffers[i].buffer_size))
+ continue;
+
+ mask |= BIT(n);
+
+ buf->buffer_offset = buffers[i].buffer_offset;
+ buf->buffer_size = buffers[i].buffer_size;
+ pipe_resource_reference(&buf->buffer, buffers[i].buffer);
+
+ if (buf->buffer)
+ 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_shader_buffer *buf = &so->sb[n];
+
+ pipe_resource_reference(&buf->buffer, NULL);
+ }
+
+ so->enabled_mask &= ~mask;
+ }
+
+ so->dirty_mask |= mask;
+ ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_SSBO;
+}
+
static void
fd_set_framebuffer_state(struct pipe_context *pctx,
const struct pipe_framebuffer_state *framebuffer)
pctx->set_clip_state = fd_set_clip_state;
pctx->set_sample_mask = fd_set_sample_mask;
pctx->set_constant_buffer = fd_set_constant_buffer;
+ pctx->set_shader_buffers = fd_set_shader_buffers;
pctx->set_framebuffer_state = fd_set_framebuffer_state;
pctx->set_polygon_stipple = fd_set_polygon_stipple;
pctx->set_scissor_states = fd_set_scissor_states;