freedreno: add image view state tracking
authorRob Clark <robdclark@gmail.com>
Sat, 4 Nov 2017 15:14:09 +0000 (11:14 -0400)
committerRob Clark <robdclark@gmail.com>
Sun, 12 Nov 2017 17:28:59 +0000 (12:28 -0500)
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>
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_state.c

index f10f7ef4ea50b5ec2673a8aaf71e0911f5b8aa87..61f1fb4ba4fafe13d4e439328b38c20aeba80195 100644 (file)
@@ -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;
 
index 012e2b3e9bfbc1620a9b5485c034e0ca86b7ac16..0b37bd31cc654c15195cd3c4f424edde50537738 100644 (file)
@@ -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;