etnaviv: add etna_constbuf_state object
authorChristian Gmeiner <christian.gmeiner@gmail.com>
Fri, 14 Feb 2020 18:55:24 +0000 (19:55 +0100)
committerChristian Gmeiner <christian.gmeiner@gmail.com>
Fri, 6 Mar 2020 16:48:17 +0000 (17:48 +0100)
With this new state object we keep track of enabled pipe_constant_buffer
and only mark them as read when needed.

Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Reviewed-by: Jonathan Marek <jonathan@marek.ca>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4088>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4088>

src/gallium/drivers/etnaviv/etnaviv_context.c
src/gallium/drivers/etnaviv/etnaviv_context.h
src/gallium/drivers/etnaviv/etnaviv_emit.c
src/gallium/drivers/etnaviv/etnaviv_state.c

index df8c00c55563618f079a6ca9e4a31ec2d598b76f..388f9d1306a1b1386ff0c7bc3105ceaa98af92db 100644 (file)
@@ -288,10 +288,11 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
    }
 
    /* Mark constant buffers as being read */
-   for (unsigned i = 0; i < ETNA_MAX_CONST_BUF; i++) {
-      resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_VERTEX][i].buffer);
-      resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_FRAGMENT][i].buffer);
-   }
+   foreach_bit(i, ctx->constant_buffer[PIPE_SHADER_VERTEX].enabled_mask)
+      resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_VERTEX].cb[i].buffer);
+
+   foreach_bit(i, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].enabled_mask)
+      resource_read(ctx, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].cb[i].buffer);
 
    /* Mark VBOs as being read */
    foreach_bit(i, ctx->vertex_buffer.enabled_mask) {
index 6e3d7d1a347d728c473ed68cb20fd326e08b0b58..97f02cdb36947692da9f8ef101823cefad049ff5 100644 (file)
@@ -73,6 +73,11 @@ struct etna_transfer {
    void *mapped;
 };
 
+struct etna_constbuf_state {
+   struct pipe_constant_buffer cb[ETNA_MAX_CONST_BUF];
+   uint32_t enabled_mask;
+};
+
 struct etna_vertexbuf_state {
    struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
    struct compiled_set_vertex_buffer cvb[PIPE_MAX_ATTRIBS];
@@ -164,7 +169,7 @@ struct etna_context {
    uint32_t active_sampler_views;
    uint32_t dirty_sampler_views;
    struct pipe_sampler_view *sampler_view[PIPE_MAX_SAMPLERS];
-   struct pipe_constant_buffer constant_buffer[PIPE_SHADER_TYPES][ETNA_MAX_CONST_BUF];
+   struct etna_constbuf_state constant_buffer[PIPE_SHADER_TYPES];
    struct etna_vertexbuf_state vertex_buffer;
    struct etna_index_buffer index_buffer;
    struct etna_shader_state shader;
index 072f5854644ea5fc096952293193ae9a0664e727..46e1719ad71054d18a0d57d249b94a1ed6defd38 100644 (file)
@@ -669,12 +669,12 @@ etna_emit_state(struct etna_context *ctx)
       if (do_uniform_flush)
          etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH);
 
-      etna_uniforms_write(ctx, ctx->shader.vs, ctx->constant_buffer[PIPE_SHADER_VERTEX]);
+      etna_uniforms_write(ctx, ctx->shader.vs, ctx->constant_buffer[PIPE_SHADER_VERTEX].cb);
 
       if (do_uniform_flush)
          etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH | VIVS_VS_UNIFORM_CACHE_PS);
 
-      etna_uniforms_write(ctx, ctx->shader.fs, ctx->constant_buffer[PIPE_SHADER_FRAGMENT]);
+      etna_uniforms_write(ctx, ctx->shader.fs, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].cb);
 
       if (ctx->specs.halti >= 5) {
          /* HALTI5 needs to be prompted to pre-fetch shaders */
@@ -688,14 +688,14 @@ etna_emit_state(struct etna_context *ctx)
          etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH);
 
       if (dirty & (uniform_dirty_bits | ctx->shader.vs->uniforms_dirty_bits))
-         etna_uniforms_write(ctx, ctx->shader.vs, ctx->constant_buffer[PIPE_SHADER_VERTEX]);
+         etna_uniforms_write(ctx, ctx->shader.vs, ctx->constant_buffer[PIPE_SHADER_VERTEX].cb);
 
       /* ideally this cache would only be flushed if there are PS uniform changes */
       if (do_uniform_flush)
          etna_set_state(stream, VIVS_VS_UNIFORM_CACHE, VIVS_VS_UNIFORM_CACHE_FLUSH | VIVS_VS_UNIFORM_CACHE_PS);
 
       if (dirty & (uniform_dirty_bits | ctx->shader.fs->uniforms_dirty_bits))
-         etna_uniforms_write(ctx, ctx->shader.fs, ctx->constant_buffer[PIPE_SHADER_FRAGMENT]);
+         etna_uniforms_write(ctx, ctx->shader.fs, ctx->constant_buffer[PIPE_SHADER_FRAGMENT].cb);
    }
 /**** End of state update ****/
 #undef EMIT_STATE
index 5de34a887176a68941726982935fb5bd952ac009..3470774c89fb25c56be94110abfad582b1522835 100644 (file)
@@ -82,23 +82,27 @@ etna_set_constant_buffer(struct pipe_context *pctx,
       const struct pipe_constant_buffer *cb)
 {
    struct etna_context *ctx = etna_context(pctx);
+   struct etna_constbuf_state *so = &ctx->constant_buffer[shader];
 
    assert(index < ETNA_MAX_CONST_BUF);
 
-   util_copy_constant_buffer(&ctx->constant_buffer[shader][index], cb);
+   util_copy_constant_buffer(&so->cb[index], cb);
 
    /* Note that the state tracker can unbind constant buffers by
     * passing NULL here. */
-   if (unlikely(!cb || (!cb->buffer && !cb->user_buffer)))
+   if (unlikely(!cb || (!cb->buffer && !cb->user_buffer))) {
+      so->enabled_mask &= ~(1 << index);
       return;
+   }
 
    assert(index != 0 || cb->user_buffer != NULL);
 
    if (!cb->buffer) {
-      struct pipe_constant_buffer *cb = &ctx->constant_buffer[shader][index];
+      struct pipe_constant_buffer *cb = &so->cb[index];
       u_upload_data(pctx->const_uploader, 0, cb->buffer_size, 16, cb->user_buffer, &cb->buffer_offset, &cb->buffer);
    }
 
+   so->enabled_mask |= 1 << index;
    ctx->dirty |= ETNA_DIRTY_CONSTBUF;
 }