diff options
author | Rob Clark <[email protected]> | 2017-11-04 11:14:09 -0400 |
---|---|---|
committer | Rob Clark <[email protected]> | 2017-11-12 12:28:59 -0500 |
commit | 13fe1feb627752a0220882b1999bd8597fdbad3b (patch) | |
tree | 4f1b675ed8681c86b08e42296c02cc4c67420447 | |
parent | 12c1c3ab2349cff1f9a9be62b7d32b8ed49552b5 (diff) |
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 <[email protected]>
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_context.h | 8 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_state.c | 48 |
2 files changed, 56 insertions, 0 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index f10f7ef4ea5..61f1fb4ba4f 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -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; diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c index 012e2b3e9bf..0b37bd31cc6 100644 --- a/src/gallium/drivers/freedreno/freedreno_state.c +++ b/src/gallium/drivers/freedreno/freedreno_state.c @@ -162,6 +162,53 @@ fd_set_shader_buffers(struct pipe_context *pctx, } 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; |