freedreno: add image view state tracking
It is unfortunate that image state isn't a real CSO, since (at least for a4xx/a5xx) it is a combination of sampler and "SSBO" image state, and it would be useful to pre-compute the state block "register" values rather than doing it at emit time. Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
@@ -78,6 +78,12 @@ struct fd_shaderbuf_stateobj {
|
||||
uint32_t dirty_mask;
|
||||
};
|
||||
|
||||
struct fd_shaderimg_stateobj {
|
||||
struct pipe_image_view si[PIPE_MAX_SHADER_IMAGES];
|
||||
uint32_t enabled_mask;
|
||||
uint32_t dirty_mask;
|
||||
};
|
||||
|
||||
struct fd_vertexbuf_stateobj {
|
||||
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
|
||||
unsigned count;
|
||||
@@ -149,6 +155,7 @@ enum fd_dirty_shader_state {
|
||||
FD_DIRTY_SHADER_CONST = BIT(1),
|
||||
FD_DIRTY_SHADER_TEX = BIT(2),
|
||||
FD_DIRTY_SHADER_SSBO = BIT(3),
|
||||
FD_DIRTY_SHADER_IMAGE = BIT(4),
|
||||
};
|
||||
|
||||
struct fd_context {
|
||||
@@ -274,6 +281,7 @@ struct fd_context {
|
||||
struct pipe_viewport_state viewport;
|
||||
struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES];
|
||||
struct fd_shaderbuf_stateobj shaderbuf[PIPE_SHADER_TYPES];
|
||||
struct fd_shaderimg_stateobj shaderimg[PIPE_SHADER_TYPES];
|
||||
struct fd_streamout_stateobj streamout;
|
||||
struct pipe_clip_state ucp;
|
||||
|
||||
|
||||
@@ -161,6 +161,53 @@ fd_set_shader_buffers(struct pipe_context *pctx,
|
||||
ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_SSBO;
|
||||
}
|
||||
|
||||
static 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)
|
||||
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;
|
||||
}
|
||||
|
||||
so->dirty_mask |= mask;
|
||||
ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_IMAGE;
|
||||
}
|
||||
|
||||
static void
|
||||
fd_set_framebuffer_state(struct pipe_context *pctx,
|
||||
const struct pipe_framebuffer_state *framebuffer)
|
||||
@@ -468,6 +515,7 @@ fd_state_init(struct pipe_context *pctx)
|
||||
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_shader_images = fd_set_shader_images;
|
||||
pctx->set_framebuffer_state = fd_set_framebuffer_state;
|
||||
pctx->set_polygon_stipple = fd_set_polygon_stipple;
|
||||
pctx->set_scissor_states = fd_set_scissor_states;
|
||||
|
||||
Reference in New Issue
Block a user