zink: add templates for pipeline stage comparison
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Fri, 5 Aug 2022 17:20:24 +0000 (13:20 -0400)
committerMarge Bot <emma+marge@anholt.net>
Sat, 20 Aug 2022 01:27:13 +0000 (01:27 +0000)
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18135>

src/gallium/drivers/zink/zink_program.c
src/gallium/drivers/zink/zink_program.h
src/gallium/drivers/zink/zink_program_state.hpp

index 4e24cd9..a8b6928 100644 (file)
@@ -629,7 +629,7 @@ zink_create_gfx_program(struct zink_context *ctx,
       prog->last_vertex_stage = stages[MESA_SHADER_VERTEX];
 
    for (int i = 0; i < ARRAY_SIZE(prog->pipelines); ++i) {
-      _mesa_hash_table_init(&prog->pipelines[i], prog, NULL, zink_get_gfx_pipeline_eq_func(screen));
+      _mesa_hash_table_init(&prog->pipelines[i], prog, NULL, zink_get_gfx_pipeline_eq_func(screen, prog));
       /* only need first 3/4 for point/line/tri/patch */
       if (screen->info.have_EXT_extended_dynamic_state &&
           i == (prog->last_vertex_stage->nir->info.stage == MESA_SHADER_TESS_EVAL ? 4 : 3))
index 3752df8..d69f70a 100644 (file)
@@ -298,7 +298,7 @@ bool
 zink_set_rasterizer_discard(struct zink_context *ctx, bool disable);
 
 equals_gfx_pipeline_state_func
-zink_get_gfx_pipeline_eq_func(struct zink_screen *screen);
+zink_get_gfx_pipeline_eq_func(struct zink_screen *screen, struct zink_gfx_program *prog);
 #ifdef __cplusplus
 }
 #endif
index c6c3017..b66f382 100644 (file)
@@ -261,7 +261,7 @@ zink_get_gfx_pipeline(struct zink_context *ctx,
    return state->pipeline;
 }
 
-template <zink_pipeline_dynamic_state DYNAMIC_STATE>
+template <zink_pipeline_dynamic_state DYNAMIC_STATE, unsigned STAGE_MASK>
 static bool
 equals_gfx_pipeline_state(const void *a, const void *b)
 {
@@ -304,28 +304,64 @@ equals_gfx_pipeline_state(const void *a, const void *b)
       if (sa->dyn_state2.vertices_per_patch != sb->dyn_state2.vertices_per_patch)
          return false;
    }
-   return !memcmp(sa->modules, sb->modules, sizeof(sa->modules)) &&
-          !memcmp(a, b, offsetof(struct zink_gfx_pipeline_state, hash));
+   if (STAGE_MASK & BITFIELD_BIT(MESA_SHADER_TESS_CTRL)) {
+      if (sa->modules[MESA_SHADER_TESS_CTRL] != sb->modules[MESA_SHADER_TESS_CTRL])
+         return false;
+   }
+   if (STAGE_MASK & BITFIELD_BIT(MESA_SHADER_TESS_EVAL)) {
+      if (sa->modules[MESA_SHADER_TESS_EVAL] != sb->modules[MESA_SHADER_TESS_EVAL])
+         return false;
+   }
+   if (STAGE_MASK & BITFIELD_BIT(MESA_SHADER_GEOMETRY)) {
+      if (sa->modules[MESA_SHADER_GEOMETRY] != sb->modules[MESA_SHADER_GEOMETRY])
+         return false;
+   }
+   if (sa->modules[MESA_SHADER_VERTEX] != sb->modules[MESA_SHADER_VERTEX])
+      return false;
+   if (sa->modules[MESA_SHADER_FRAGMENT] != sb->modules[MESA_SHADER_FRAGMENT])
+      return false;
+   return !memcmp(a, b, offsetof(struct zink_gfx_pipeline_state, hash));
+}
+
+template <zink_pipeline_dynamic_state DYNAMIC_STATE>
+static equals_gfx_pipeline_state_func
+get_gfx_pipeline_stage_eq_func(struct zink_gfx_program *prog)
+{
+   unsigned vertex_stages = prog->stages_present & BITFIELD_MASK(MESA_SHADER_FRAGMENT);
+   if (vertex_stages == BITFIELD_MASK(MESA_SHADER_FRAGMENT))
+      /* all stages */
+      return equals_gfx_pipeline_state<DYNAMIC_STATE,
+                                       BITFIELD_MASK(MESA_SHADER_COMPUTE)>;
+   if (vertex_stages == BITFIELD_MASK(MESA_SHADER_GEOMETRY))
+      /* tess only: includes generated tcs too */
+      return equals_gfx_pipeline_state<DYNAMIC_STATE,
+                                       BITFIELD_MASK(MESA_SHADER_COMPUTE) & ~BITFIELD_BIT(MESA_SHADER_GEOMETRY)>;
+   if (vertex_stages == (BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_GEOMETRY)))
+      /* geom only */
+      return equals_gfx_pipeline_state<DYNAMIC_STATE,
+                                       BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_FRAGMENT) | BITFIELD_BIT(MESA_SHADER_GEOMETRY)>;
+   return equals_gfx_pipeline_state<DYNAMIC_STATE,
+                                    BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_FRAGMENT)>;
 }
 
 equals_gfx_pipeline_state_func
-zink_get_gfx_pipeline_eq_func(struct zink_screen *screen)
+zink_get_gfx_pipeline_eq_func(struct zink_screen *screen, struct zink_gfx_program *prog)
 {
    if (screen->info.have_EXT_extended_dynamic_state) {
       if (screen->info.have_EXT_extended_dynamic_state2) {
          if (screen->info.have_EXT_vertex_input_dynamic_state) {
             if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
-               return equals_gfx_pipeline_state<ZINK_PIPELINE_DYNAMIC_VERTEX_INPUT_PCP>;
+               return get_gfx_pipeline_stage_eq_func<ZINK_PIPELINE_DYNAMIC_VERTEX_INPUT_PCP>(prog);
             else
-               return equals_gfx_pipeline_state<ZINK_PIPELINE_DYNAMIC_VERTEX_INPUT>;
+               return get_gfx_pipeline_stage_eq_func<ZINK_PIPELINE_DYNAMIC_VERTEX_INPUT>(prog);
          } else {
             if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
-               return equals_gfx_pipeline_state<ZINK_PIPELINE_DYNAMIC_STATE2_PCP>;
+               return get_gfx_pipeline_stage_eq_func<ZINK_PIPELINE_DYNAMIC_STATE2_PCP>(prog);
             else
-               return equals_gfx_pipeline_state<ZINK_PIPELINE_DYNAMIC_STATE2>;
+               return get_gfx_pipeline_stage_eq_func<ZINK_PIPELINE_DYNAMIC_STATE2>(prog);
          }
       }
-      return equals_gfx_pipeline_state<ZINK_PIPELINE_DYNAMIC_STATE>;
+      return get_gfx_pipeline_stage_eq_func<ZINK_PIPELINE_DYNAMIC_STATE>(prog);
    }
-   return equals_gfx_pipeline_state<ZINK_PIPELINE_NO_DYNAMIC_STATE>;
+   return get_gfx_pipeline_stage_eq_func<ZINK_PIPELINE_NO_DYNAMIC_STATE>(prog);
 }