Mesa (master): zink: pre-hash gfx-pipeline-state

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Aug 7 14:51:26 UTC 2020


Module: Mesa
Branch: master
Commit: 1185b3f32d97a260dfd388bd0ca032bc6a380bbf
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1185b3f32d97a260dfd388bd0ca032bc6a380bbf

Author: Antonio Caggiano <antonio.caggiano at collabora.com>
Date:   Fri Jul 24 16:50:15 2020 +0200

zink: pre-hash gfx-pipeline-state

Store a hash in `zink_gfx_pipeline_state` to keep track of state
changes and avoid to recompute it when the state has not changed.

Signed-off-by: Antonio Caggiano <antonio.caggiano at collabora.com>
Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6061>

---

 src/gallium/drivers/zink/zink_context.c  |  3 +++
 src/gallium/drivers/zink/zink_pipeline.h |  4 ++++
 src/gallium/drivers/zink/zink_program.c  | 20 ++++++++++++++------
 src/gallium/drivers/zink/zink_state.c    | 26 ++++++++++++++++++++++----
 4 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index c5ec154cf3c..786de9c095c 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -612,6 +612,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
 
    ctx->gfx_pipeline_state.rast_samples = MAX2(state->samples, 1);
    ctx->gfx_pipeline_state.num_attachments = state->nr_cbufs;
+   ctx->gfx_pipeline_state.hash = 0;
 
    struct zink_batch *batch = zink_batch_no_rp(ctx);
 
@@ -1050,6 +1051,8 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    if (!ctx)
       goto fail;
 
+   ctx->gfx_pipeline_state.hash = 0;
+
    ctx->base.screen = pscreen;
    ctx->base.priv = priv;
 
diff --git a/src/gallium/drivers/zink/zink_pipeline.h b/src/gallium/drivers/zink/zink_pipeline.h
index 757bae6266f..116ce656405 100644
--- a/src/gallium/drivers/zink/zink_pipeline.h
+++ b/src/gallium/drivers/zink/zink_pipeline.h
@@ -53,6 +53,10 @@ struct zink_gfx_pipeline_state {
    uint8_t rast_samples;
 
    bool primitive_restart;
+
+   /* Pre-hashed value for table lookup, invalid when zero.
+    * Members after this point are not included in pipeline state hash key */
+   uint32_t hash;
 };
 
 VkPipeline
diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c
index f8462e04107..ef6fa7a2457 100644
--- a/src/gallium/drivers/zink/zink_program.c
+++ b/src/gallium/drivers/zink/zink_program.c
@@ -163,13 +163,13 @@ update_shader_modules(struct zink_context *ctx, struct zink_shader *stages[ZINK_
 static uint32_t
 hash_gfx_pipeline_state(const void *key)
 {
-   return _mesa_hash_data(key, sizeof(struct zink_gfx_pipeline_state));
+   return _mesa_hash_data(key, offsetof(struct zink_gfx_pipeline_state, hash));
 }
 
 static bool
 equals_gfx_pipeline_state(const void *a, const void *b)
 {
-   return memcmp(a, b, sizeof(struct zink_gfx_pipeline_state)) == 0;
+   return memcmp(a, b, offsetof(struct zink_gfx_pipeline_state, hash)) == 0;
 }
 
 struct zink_gfx_program *
@@ -319,9 +319,16 @@ zink_get_gfx_pipeline(struct zink_screen *screen,
 {
    assert(mode <= ARRAY_SIZE(prog->pipelines));
 
-   /* TODO: use pre-hashed versions to save some time (can re-hash only when
-      state changes) */
-   struct hash_entry *entry = _mesa_hash_table_search(prog->pipelines[mode], state);
+   struct hash_entry *entry = NULL;
+   
+   if (!state->hash) {
+      state->hash = hash_gfx_pipeline_state(state);
+      /* make sure the hash is not zero, as we take it as invalid.
+       * TODO: rework this using a separate dirty-bit */
+      assert(state->hash != 0);
+   }
+   entry = _mesa_hash_table_search_pre_hashed(prog->pipelines[mode], state->hash, state);
+
    if (!entry) {
       VkPrimitiveTopology vkmode = primitive_topology(mode);
       VkPipeline pipeline = zink_create_gfx_pipeline(screen, prog,
@@ -336,7 +343,8 @@ zink_get_gfx_pipeline(struct zink_screen *screen,
       memcpy(&pc_entry->state, state, sizeof(*state));
       pc_entry->pipeline = pipeline;
 
-      entry = _mesa_hash_table_insert(prog->pipelines[mode], &pc_entry->state, pc_entry);
+      assert(state->hash);
+      entry = _mesa_hash_table_insert_pre_hashed(prog->pipelines[mode], state->hash, state, pc_entry);
       assert(entry);
 
       reference_render_pass(screen, prog, state->render_pass);
diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c
index bec8d05d585..95f23c273ba 100644
--- a/src/gallium/drivers/zink/zink_state.c
+++ b/src/gallium/drivers/zink/zink_state.c
@@ -81,6 +81,7 @@ zink_bind_vertex_elements_state(struct pipe_context *pctx,
    struct zink_context *ctx = zink_context(pctx);
    struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state;
    ctx->element_state = cso;
+   state->hash = 0;
    if (cso) {
       state->element_state = &ctx->element_state->hw_state;
       struct zink_vertex_elements_state *ves = cso;
@@ -256,7 +257,12 @@ zink_create_blend_state(struct pipe_context *pctx,
 static void
 zink_bind_blend_state(struct pipe_context *pctx, void *cso)
 {
-   zink_context(pctx)->gfx_pipeline_state.blend_state = cso;
+   struct zink_gfx_pipeline_state* state = &zink_context(pctx)->gfx_pipeline_state;
+
+   if (state->blend_state != cso) {
+      state->blend_state = cso;
+      state->hash = 0;
+   }
 }
 
 static void
@@ -348,7 +354,12 @@ zink_create_depth_stencil_alpha_state(struct pipe_context *pctx,
 static void
 zink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso)
 {
-   zink_context(pctx)->gfx_pipeline_state.depth_stencil_alpha_state = cso;
+   struct zink_gfx_pipeline_state* state = &zink_context(pctx)->gfx_pipeline_state;
+
+   if (state->depth_stencil_alpha_state != cso) {
+      state->depth_stencil_alpha_state = cso;
+      state->hash = 0;
+   }
 }
 
 static void
@@ -423,8 +434,15 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
    ctx->rast_state = cso;
 
    if (ctx->rast_state) {
-      ctx->gfx_pipeline_state.rast_state = &ctx->rast_state->hw_state;
-      ctx->line_width = ctx->rast_state->line_width;
+      if (ctx->gfx_pipeline_state.rast_state != &ctx->rast_state->hw_state) {
+         ctx->gfx_pipeline_state.rast_state = &ctx->rast_state->hw_state;
+         ctx->gfx_pipeline_state.hash = 0;
+      }
+
+      if (ctx->line_width != ctx->rast_state->line_width) {
+         ctx->line_width = ctx->rast_state->line_width;
+         ctx->gfx_pipeline_state.hash = 0;
+      }
    }
 }
 



More information about the mesa-commit mailing list