iris: Extend iris_context dirty state flags to 128 bits.
authorFrancisco Jerez <currojerez@riseup.net>
Fri, 29 May 2020 23:57:01 +0000 (16:57 -0700)
committerMarge Bot <eric+marge@anholt.net>
Wed, 3 Jun 2020 22:22:19 +0000 (22:22 +0000)
We're nearly out of dirty bits, and some patches pending review on
GitLab no longer apply due to that.  Make room for them by splitting
off shader stage-specific bits into a separate stage_dirty mask.

An alternative would be to split compute-related bits into a separate
mask, but that would prevent the '<< stage' indexing done in various
parts of the driver from working.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5279>

src/gallium/drivers/iris/iris_binder.c
src/gallium/drivers/iris/iris_blorp.c
src/gallium/drivers/iris/iris_clear.c
src/gallium/drivers/iris/iris_context.c
src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_draw.c
src/gallium/drivers/iris/iris_program.c
src/gallium/drivers/iris/iris_query.c
src/gallium/drivers/iris/iris_resolve.c
src/gallium/drivers/iris/iris_resource.c
src/gallium/drivers/iris/iris_state.c

index ab15ec987d6c6b4f9e05b2412a93b4bc40e3a556..19ee29fe9d7b24c02e271fd9672fd8de0655c3a9 100644 (file)
@@ -98,7 +98,8 @@ binder_realloc(struct iris_context *ice)
     * We do this here so that iris_binder_reserve_3d correctly gets a new
     * larger total_size when making the updated reservation.
     */
-   ice->state.dirty |= IRIS_ALL_DIRTY_BINDINGS;
+   ice->state.dirty |= IRIS_DIRTY_RENDER_BUFFER;
+   ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_BINDINGS;
 }
 
 static uint32_t
@@ -142,7 +143,8 @@ iris_binder_reserve_3d(struct iris_context *ice)
    unsigned total_size;
 
    /* If nothing is dirty, skip all this. */
-   if (!(ice->state.dirty & IRIS_ALL_DIRTY_BINDINGS))
+   if (!(ice->state.dirty & IRIS_DIRTY_RENDER_BUFFER) &&
+       !(ice->state.stage_dirty & IRIS_ALL_STAGE_DIRTY_BINDINGS))
       return;
 
    /* Get the binding table sizes for each stage */
@@ -158,7 +160,7 @@ iris_binder_reserve_3d(struct iris_context *ice)
    while (true) {
       total_size = 0;
       for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
-         if (ice->state.dirty & (IRIS_DIRTY_BINDINGS_VS << stage))
+         if (ice->state.stage_dirty & (IRIS_STAGE_DIRTY_BINDINGS_VS << stage))
             total_size += sizes[stage];
       }
 
@@ -181,7 +183,7 @@ iris_binder_reserve_3d(struct iris_context *ice)
    uint32_t offset = binder_insert(binder, total_size);
 
    for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
-      if (ice->state.dirty & (IRIS_DIRTY_BINDINGS_VS << stage)) {
+      if (ice->state.stage_dirty & (IRIS_STAGE_DIRTY_BINDINGS_VS << stage)) {
          binder->bt_offset[stage] = sizes[stage] > 0 ? offset : 0;
          iris_record_state_size(ice->state.sizes,
                                 binder->bo->gtt_offset + offset, sizes[stage]);
@@ -193,7 +195,7 @@ iris_binder_reserve_3d(struct iris_context *ice)
 void
 iris_binder_reserve_compute(struct iris_context *ice)
 {
-   if (!(ice->state.dirty & IRIS_DIRTY_BINDINGS_CS))
+   if (!(ice->state.stage_dirty & IRIS_STAGE_DIRTY_BINDINGS_CS))
       return;
 
    struct iris_binder *binder = &ice->state.binder;
index a295c6cacd3d9afe1f9e9072ae6ebe172f0d9726..1da234d9467fea63f7c0059cf1388e28bd2e35f5 100644 (file)
@@ -324,33 +324,34 @@ iris_blorp_exec(struct blorp_batch *blorp_batch,
                          IRIS_DIRTY_LINE_STIPPLE |
                          IRIS_ALL_DIRTY_FOR_COMPUTE |
                          IRIS_DIRTY_SCISSOR_RECT |
-                         IRIS_DIRTY_UNCOMPILED_VS |
-                         IRIS_DIRTY_UNCOMPILED_TCS |
-                         IRIS_DIRTY_UNCOMPILED_TES |
-                         IRIS_DIRTY_UNCOMPILED_GS |
-                         IRIS_DIRTY_UNCOMPILED_FS |
                          IRIS_DIRTY_VF |
-                         IRIS_DIRTY_SF_CL_VIEWPORT |
-                         IRIS_DIRTY_SAMPLER_STATES_VS |
-                         IRIS_DIRTY_SAMPLER_STATES_TCS |
-                         IRIS_DIRTY_SAMPLER_STATES_TES |
-                         IRIS_DIRTY_SAMPLER_STATES_GS);
+                         IRIS_DIRTY_SF_CL_VIEWPORT);
+   uint64_t skip_stage_bits = (IRIS_ALL_STAGE_DIRTY_FOR_COMPUTE |
+                               IRIS_STAGE_DIRTY_UNCOMPILED_VS |
+                               IRIS_STAGE_DIRTY_UNCOMPILED_TCS |
+                               IRIS_STAGE_DIRTY_UNCOMPILED_TES |
+                               IRIS_STAGE_DIRTY_UNCOMPILED_GS |
+                               IRIS_STAGE_DIRTY_UNCOMPILED_FS |
+                               IRIS_STAGE_DIRTY_SAMPLER_STATES_VS |
+                               IRIS_STAGE_DIRTY_SAMPLER_STATES_TCS |
+                               IRIS_STAGE_DIRTY_SAMPLER_STATES_TES |
+                               IRIS_STAGE_DIRTY_SAMPLER_STATES_GS);
 
    if (!ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL]) {
       /* BLORP disabled tessellation, that's fine for the next draw */
-      skip_bits |= IRIS_DIRTY_TCS |
-                   IRIS_DIRTY_TES |
-                   IRIS_DIRTY_CONSTANTS_TCS |
-                   IRIS_DIRTY_CONSTANTS_TES |
-                   IRIS_DIRTY_BINDINGS_TCS |
-                   IRIS_DIRTY_BINDINGS_TES;
+      skip_stage_bits |= IRIS_STAGE_DIRTY_TCS |
+                         IRIS_STAGE_DIRTY_TES |
+                         IRIS_STAGE_DIRTY_CONSTANTS_TCS |
+                         IRIS_STAGE_DIRTY_CONSTANTS_TES |
+                         IRIS_STAGE_DIRTY_BINDINGS_TCS |
+                         IRIS_STAGE_DIRTY_BINDINGS_TES;
    }
 
    if (!ice->shaders.uncompiled[MESA_SHADER_GEOMETRY]) {
       /* BLORP disabled geometry shaders, that's fine for the next draw */
-      skip_bits |= IRIS_DIRTY_GS |
-                   IRIS_DIRTY_CONSTANTS_GS |
-                   IRIS_DIRTY_BINDINGS_GS;
+      skip_stage_bits |= IRIS_STAGE_DIRTY_GS |
+                         IRIS_STAGE_DIRTY_CONSTANTS_GS |
+                         IRIS_STAGE_DIRTY_BINDINGS_GS;
    }
 
    /* we can skip flagging IRIS_DIRTY_DEPTH_BUFFER, if
@@ -363,6 +364,7 @@ iris_blorp_exec(struct blorp_batch *blorp_batch,
       skip_bits |= IRIS_DIRTY_BLEND_STATE | IRIS_DIRTY_PS_BLEND;
 
    ice->state.dirty |= ~skip_bits;
+   ice->state.stage_dirty |= ~skip_stage_bits;
 
    if (params->dst.enabled) {
       iris_render_cache_add_bo(batch, params->dst.addr.buffer,
index d8e94a22cd94c27de4a8903f8192c1b8714332aa..3800dfcc145e906768e55222c2f05f71e4fa24b1 100644 (file)
@@ -326,7 +326,8 @@ fast_clear_color(struct iris_context *ice,
 
    iris_resource_set_aux_state(ice, res, level, box->z,
                                box->depth, ISL_AUX_STATE_CLEAR);
-   ice->state.dirty |= IRIS_ALL_DIRTY_BINDINGS;
+   ice->state.dirty |= IRIS_DIRTY_RENDER_BUFFER;
+   ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_BINDINGS;
    return;
 }
 
index dbe3ec09562eed4ac56445cac35f813cab6ad117..5c0022f0331fe249cd3738bbf086eff7040456fa 100644 (file)
@@ -95,6 +95,7 @@ iris_lost_context_state(struct iris_batch *batch)
    }
 
    ice->state.dirty = ~0ull;
+   ice->state.stage_dirty = ~0ull;
    ice->state.current_hash_scale = 0;
    memset(ice->state.last_block, 0, sizeof(ice->state.last_block));
    memset(ice->state.last_grid, 0, sizeof(ice->state.last_grid));
index 9d681a5826e75c7af4f84564cbff503854eb9973..68dcdb5a59a4732a5c2b022a7821573f5cf9f1c5 100644 (file)
@@ -77,86 +77,97 @@ enum {
  *
  * See iris_upload_render_state().
  */
-#define IRIS_DIRTY_COLOR_CALC_STATE         (1ull <<  0)
-#define IRIS_DIRTY_POLYGON_STIPPLE          (1ull <<  1)
-#define IRIS_DIRTY_SCISSOR_RECT             (1ull <<  2)
-#define IRIS_DIRTY_WM_DEPTH_STENCIL         (1ull <<  3)
-#define IRIS_DIRTY_CC_VIEWPORT              (1ull <<  4)
-#define IRIS_DIRTY_SF_CL_VIEWPORT           (1ull <<  5)
-#define IRIS_DIRTY_PS_BLEND                 (1ull <<  6)
-#define IRIS_DIRTY_BLEND_STATE              (1ull <<  7)
-#define IRIS_DIRTY_RASTER                   (1ull <<  8)
-#define IRIS_DIRTY_CLIP                     (1ull <<  9)
-#define IRIS_DIRTY_SBE                      (1ull << 10)
-#define IRIS_DIRTY_LINE_STIPPLE             (1ull << 11)
-#define IRIS_DIRTY_VERTEX_ELEMENTS          (1ull << 12)
-#define IRIS_DIRTY_MULTISAMPLE              (1ull << 13)
-#define IRIS_DIRTY_VERTEX_BUFFERS           (1ull << 14)
-#define IRIS_DIRTY_SAMPLE_MASK              (1ull << 15)
-#define IRIS_DIRTY_SAMPLER_STATES_VS        (1ull << 16)
-#define IRIS_DIRTY_SAMPLER_STATES_TCS       (1ull << 17)
-#define IRIS_DIRTY_SAMPLER_STATES_TES       (1ull << 18)
-#define IRIS_DIRTY_SAMPLER_STATES_GS        (1ull << 19)
-#define IRIS_DIRTY_SAMPLER_STATES_PS        (1ull << 20)
-#define IRIS_DIRTY_SAMPLER_STATES_CS        (1ull << 21)
-#define IRIS_DIRTY_UNCOMPILED_VS            (1ull << 22)
-#define IRIS_DIRTY_UNCOMPILED_TCS           (1ull << 23)
-#define IRIS_DIRTY_UNCOMPILED_TES           (1ull << 24)
-#define IRIS_DIRTY_UNCOMPILED_GS            (1ull << 25)
-#define IRIS_DIRTY_UNCOMPILED_FS            (1ull << 26)
-#define IRIS_DIRTY_UNCOMPILED_CS            (1ull << 27)
-#define IRIS_DIRTY_VS                       (1ull << 28)
-#define IRIS_DIRTY_TCS                      (1ull << 29)
-#define IRIS_DIRTY_TES                      (1ull << 30)
-#define IRIS_DIRTY_GS                       (1ull << 31)
-#define IRIS_DIRTY_FS                       (1ull << 32)
-#define IRIS_DIRTY_CS                       (1ull << 33)
-#define IRIS_DIRTY_URB                      (1ull << 34)
-#define IRIS_SHIFT_FOR_DIRTY_CONSTANTS      35
-#define IRIS_DIRTY_CONSTANTS_VS             (1ull << 35)
-#define IRIS_DIRTY_CONSTANTS_TCS            (1ull << 36)
-#define IRIS_DIRTY_CONSTANTS_TES            (1ull << 37)
-#define IRIS_DIRTY_CONSTANTS_GS             (1ull << 38)
-#define IRIS_DIRTY_CONSTANTS_FS             (1ull << 39)
-#define IRIS_DIRTY_CONSTANTS_CS             (1ull << 40)
-#define IRIS_DIRTY_DEPTH_BUFFER             (1ull << 41)
-#define IRIS_DIRTY_WM                       (1ull << 42)
-#define IRIS_DIRTY_BINDINGS_VS              (1ull << 43)
-#define IRIS_DIRTY_BINDINGS_TCS             (1ull << 44)
-#define IRIS_DIRTY_BINDINGS_TES             (1ull << 45)
-#define IRIS_DIRTY_BINDINGS_GS              (1ull << 46)
-#define IRIS_DIRTY_BINDINGS_FS              (1ull << 47)
-#define IRIS_DIRTY_BINDINGS_CS              (1ull << 48)
-#define IRIS_DIRTY_SO_BUFFERS               (1ull << 49)
-#define IRIS_DIRTY_SO_DECL_LIST             (1ull << 50)
-#define IRIS_DIRTY_STREAMOUT                (1ull << 51)
-#define IRIS_DIRTY_VF_SGVS                  (1ull << 52)
-#define IRIS_DIRTY_VF                       (1ull << 53)
-#define IRIS_DIRTY_VF_TOPOLOGY              (1ull << 54)
-#define IRIS_DIRTY_RENDER_RESOLVES_AND_FLUSHES  (1ull << 55)
-#define IRIS_DIRTY_COMPUTE_RESOLVES_AND_FLUSHES (1ull << 56)
-#define IRIS_DIRTY_VF_STATISTICS            (1ull << 57)
-#define IRIS_DIRTY_PMA_FIX                  (1ull << 58)
-#define IRIS_DIRTY_DEPTH_BOUNDS             (1ull << 59)
-#define IRIS_DIRTY_RENDER_BUFFER            (1ull << 60)
-#define IRIS_DIRTY_STENCIL_REF              (1ull << 61)
-
-#define IRIS_ALL_DIRTY_FOR_COMPUTE (IRIS_DIRTY_CS | \
-                                    IRIS_DIRTY_SAMPLER_STATES_CS | \
-                                    IRIS_DIRTY_UNCOMPILED_CS | \
-                                    IRIS_DIRTY_CONSTANTS_CS | \
-                                    IRIS_DIRTY_BINDINGS_CS | \
-                                    IRIS_DIRTY_COMPUTE_RESOLVES_AND_FLUSHES)
-
-#define IRIS_ALL_DIRTY_FOR_RENDER ~IRIS_ALL_DIRTY_FOR_COMPUTE
-
-#define IRIS_ALL_DIRTY_BINDINGS (IRIS_DIRTY_BINDINGS_VS  | \
-                                 IRIS_DIRTY_BINDINGS_TCS | \
-                                 IRIS_DIRTY_BINDINGS_TES | \
-                                 IRIS_DIRTY_BINDINGS_GS  | \
-                                 IRIS_DIRTY_BINDINGS_FS  | \
-                                 IRIS_DIRTY_BINDINGS_CS  | \
-                                 IRIS_DIRTY_RENDER_BUFFER)
+#define IRIS_DIRTY_COLOR_CALC_STATE               (1ull <<  0)
+#define IRIS_DIRTY_POLYGON_STIPPLE                (1ull <<  1)
+#define IRIS_DIRTY_SCISSOR_RECT                   (1ull <<  2)
+#define IRIS_DIRTY_WM_DEPTH_STENCIL               (1ull <<  3)
+#define IRIS_DIRTY_CC_VIEWPORT                    (1ull <<  4)
+#define IRIS_DIRTY_SF_CL_VIEWPORT                 (1ull <<  5)
+#define IRIS_DIRTY_PS_BLEND                       (1ull <<  6)
+#define IRIS_DIRTY_BLEND_STATE                    (1ull <<  7)
+#define IRIS_DIRTY_RASTER                         (1ull <<  8)
+#define IRIS_DIRTY_CLIP                           (1ull <<  9)
+#define IRIS_DIRTY_SBE                            (1ull << 10)
+#define IRIS_DIRTY_LINE_STIPPLE                   (1ull << 11)
+#define IRIS_DIRTY_VERTEX_ELEMENTS                (1ull << 12)
+#define IRIS_DIRTY_MULTISAMPLE                    (1ull << 13)
+#define IRIS_DIRTY_VERTEX_BUFFERS                 (1ull << 14)
+#define IRIS_DIRTY_SAMPLE_MASK                    (1ull << 15)
+#define IRIS_DIRTY_URB                            (1ull << 16)
+#define IRIS_DIRTY_DEPTH_BUFFER                   (1ull << 17)
+#define IRIS_DIRTY_WM                             (1ull << 18)
+#define IRIS_DIRTY_SO_BUFFERS                     (1ull << 19)
+#define IRIS_DIRTY_SO_DECL_LIST                   (1ull << 20)
+#define IRIS_DIRTY_STREAMOUT                      (1ull << 21)
+#define IRIS_DIRTY_VF_SGVS                        (1ull << 22)
+#define IRIS_DIRTY_VF                             (1ull << 23)
+#define IRIS_DIRTY_VF_TOPOLOGY                    (1ull << 24)
+#define IRIS_DIRTY_RENDER_RESOLVES_AND_FLUSHES    (1ull << 25)
+#define IRIS_DIRTY_COMPUTE_RESOLVES_AND_FLUSHES   (1ull << 26)
+#define IRIS_DIRTY_VF_STATISTICS                  (1ull << 27)
+#define IRIS_DIRTY_PMA_FIX                        (1ull << 28)
+#define IRIS_DIRTY_DEPTH_BOUNDS                   (1ull << 29)
+#define IRIS_DIRTY_RENDER_BUFFER                  (1ull << 30)
+#define IRIS_DIRTY_STENCIL_REF                    (1ull << 31)
+
+#define IRIS_ALL_DIRTY_FOR_COMPUTE (IRIS_DIRTY_COMPUTE_RESOLVES_AND_FLUSHES)
+
+#define IRIS_ALL_DIRTY_FOR_RENDER (~IRIS_ALL_DIRTY_FOR_COMPUTE)
+
+/**
+ * Per-stage dirty flags.  When state changes, we flag some combination of
+ * these to indicate that particular GPU commands need to be re-emitted.
+ * Unlike the IRIS_DIRTY_* flags these are shader stage-specific and can be
+ * indexed by shifting the mask by the shader stage index.
+ *
+ * See iris_upload_render_state().
+ */
+#define IRIS_STAGE_DIRTY_SAMPLER_STATES_VS        (1ull << 0)
+#define IRIS_STAGE_DIRTY_SAMPLER_STATES_TCS       (1ull << 1)
+#define IRIS_STAGE_DIRTY_SAMPLER_STATES_TES       (1ull << 2)
+#define IRIS_STAGE_DIRTY_SAMPLER_STATES_GS        (1ull << 3)
+#define IRIS_STAGE_DIRTY_SAMPLER_STATES_PS        (1ull << 4)
+#define IRIS_STAGE_DIRTY_SAMPLER_STATES_CS        (1ull << 5)
+#define IRIS_STAGE_DIRTY_UNCOMPILED_VS            (1ull << 6)
+#define IRIS_STAGE_DIRTY_UNCOMPILED_TCS           (1ull << 7)
+#define IRIS_STAGE_DIRTY_UNCOMPILED_TES           (1ull << 8)
+#define IRIS_STAGE_DIRTY_UNCOMPILED_GS            (1ull << 9)
+#define IRIS_STAGE_DIRTY_UNCOMPILED_FS            (1ull << 10)
+#define IRIS_STAGE_DIRTY_UNCOMPILED_CS            (1ull << 11)
+#define IRIS_STAGE_DIRTY_VS                       (1ull << 12)
+#define IRIS_STAGE_DIRTY_TCS                      (1ull << 13)
+#define IRIS_STAGE_DIRTY_TES                      (1ull << 14)
+#define IRIS_STAGE_DIRTY_GS                       (1ull << 15)
+#define IRIS_STAGE_DIRTY_FS                       (1ull << 16)
+#define IRIS_STAGE_DIRTY_CS                       (1ull << 17)
+#define IRIS_SHIFT_FOR_STAGE_DIRTY_CONSTANTS      18
+#define IRIS_STAGE_DIRTY_CONSTANTS_VS             (1ull << 18)
+#define IRIS_STAGE_DIRTY_CONSTANTS_TCS            (1ull << 19)
+#define IRIS_STAGE_DIRTY_CONSTANTS_TES            (1ull << 20)
+#define IRIS_STAGE_DIRTY_CONSTANTS_GS             (1ull << 21)
+#define IRIS_STAGE_DIRTY_CONSTANTS_FS             (1ull << 22)
+#define IRIS_STAGE_DIRTY_CONSTANTS_CS             (1ull << 23)
+#define IRIS_STAGE_DIRTY_BINDINGS_VS              (1ull << 24)
+#define IRIS_STAGE_DIRTY_BINDINGS_TCS             (1ull << 25)
+#define IRIS_STAGE_DIRTY_BINDINGS_TES             (1ull << 26)
+#define IRIS_STAGE_DIRTY_BINDINGS_GS              (1ull << 27)
+#define IRIS_STAGE_DIRTY_BINDINGS_FS              (1ull << 28)
+#define IRIS_STAGE_DIRTY_BINDINGS_CS              (1ull << 29)
+
+#define IRIS_ALL_STAGE_DIRTY_FOR_COMPUTE (IRIS_STAGE_DIRTY_CS | \
+                                          IRIS_STAGE_DIRTY_SAMPLER_STATES_CS | \
+                                          IRIS_STAGE_DIRTY_UNCOMPILED_CS |    \
+                                          IRIS_STAGE_DIRTY_CONSTANTS_CS |     \
+                                          IRIS_STAGE_DIRTY_BINDINGS_CS)
+
+#define IRIS_ALL_STAGE_DIRTY_FOR_RENDER (~IRIS_ALL_STAGE_DIRTY_FOR_COMPUTE)
+
+#define IRIS_ALL_STAGE_DIRTY_BINDINGS (IRIS_STAGE_DIRTY_BINDINGS_VS  | \
+                                       IRIS_STAGE_DIRTY_BINDINGS_TCS | \
+                                       IRIS_STAGE_DIRTY_BINDINGS_TES | \
+                                       IRIS_STAGE_DIRTY_BINDINGS_GS  | \
+                                       IRIS_STAGE_DIRTY_BINDINGS_FS  | \
+                                       IRIS_STAGE_DIRTY_BINDINGS_CS)
 
 /**
  * Non-orthogonal state (NOS) dependency flags.
@@ -610,7 +621,8 @@ struct iris_context {
 
    struct {
       uint64_t dirty;
-      uint64_t dirty_for_nos[IRIS_NOS_COUNT];
+      uint64_t stage_dirty;
+      uint64_t stage_dirty_for_nos[IRIS_NOS_COUNT];
 
       unsigned num_viewports;
       unsigned sample_mask;
index d59f6e59e5091f304e29a779539a730d61addd03..c0d749e89270e249d273a7c919dffd1786e7f6d2 100644 (file)
@@ -86,14 +86,14 @@ iris_update_draw_info(struct iris_context *ice,
 
       /* 8_PATCH TCS needs this for key->input_vertices */
       if (compiler->use_tcs_8_patch)
-         ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_TCS;
+         ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_TCS;
 
       /* Flag constants dirty for gl_PatchVerticesIn if needed. */
       const struct shader_info *tcs_info =
          iris_get_shader_info(ice, MESA_SHADER_TESS_CTRL);
       if (tcs_info &&
           tcs_info->system_values_read & (1ull << SYSTEM_VALUE_VERTICES_IN)) {
-         ice->state.dirty |= IRIS_DIRTY_CONSTANTS_TCS;
+         ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_TCS;
          ice->state.shaders[MESA_SHADER_TESS_CTRL].sysvals_need_upload = true;
       }
    }
@@ -182,7 +182,8 @@ iris_indirect_draw_vbo(struct iris_context *ice,
       batch->screen->vtbl.load_register_reg64(batch, CS_GPR(15), MI_PREDICATE_RESULT);
    }
 
-   uint64_t orig_dirty = ice->state.dirty;
+   const uint64_t orig_dirty = ice->state.dirty;
+   const uint64_t orig_stage_dirty = ice->state.stage_dirty;
 
    for (int i = 0; i < info.indirect->draw_count; i++) {
       info.drawid = i;
@@ -194,6 +195,7 @@ iris_indirect_draw_vbo(struct iris_context *ice,
       batch->screen->vtbl.upload_render_state(ice, batch, &info);
 
       ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER;
+      ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
 
       info.indirect->offset += info.indirect->stride;
    }
@@ -206,6 +208,7 @@ iris_indirect_draw_vbo(struct iris_context *ice,
 
    /* Put this back for post-draw resolves, we'll clear it again after. */
    ice->state.dirty = orig_dirty;
+   ice->state.stage_dirty = orig_stage_dirty;
 }
 
 static void
@@ -238,8 +241,10 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
    /* We can't safely re-emit 3DSTATE_SO_BUFFERS because it may zero the
     * write offsets, changing the behavior.
     */
-   if (unlikely(INTEL_DEBUG & DEBUG_REEMIT))
+   if (unlikely(INTEL_DEBUG & DEBUG_REEMIT)) {
       ice->state.dirty |= IRIS_ALL_DIRTY_FOR_RENDER & ~IRIS_DIRTY_SO_BUFFERS;
+      ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
+   }
 
    iris_update_draw_info(ice, info);
 
@@ -274,6 +279,7 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
    iris_postdraw_update_resolve_tracking(ice, batch);
 
    ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER;
+   ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
 }
 
 static void
@@ -328,7 +334,7 @@ iris_update_grid_size_resource(struct iris_context *ice,
                          .stride_B = 1,
                          .mocs = iris_mocs(grid_bo, isl_dev));
 
-   ice->state.dirty |= IRIS_DIRTY_BINDINGS_CS;
+   ice->state.stage_dirty |= IRIS_STAGE_DIRTY_BINDINGS_CS;
 }
 
 void
@@ -340,8 +346,10 @@ iris_launch_grid(struct pipe_context *ctx, const struct pipe_grid_info *grid)
    if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
       return;
 
-   if (unlikely(INTEL_DEBUG & DEBUG_REEMIT))
+   if (unlikely(INTEL_DEBUG & DEBUG_REEMIT)) {
       ice->state.dirty |= IRIS_ALL_DIRTY_FOR_COMPUTE;
+      ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_FOR_COMPUTE;
+   }
 
    /* We can't do resolves on the compute engine, so awkwardly, we have to
     * do them on the render batch...
@@ -357,7 +365,7 @@ iris_launch_grid(struct pipe_context *ctx, const struct pipe_grid_info *grid)
 
    if (memcmp(ice->state.last_block, grid->block, sizeof(grid->block)) != 0) {
       memcpy(ice->state.last_block, grid->block, sizeof(grid->block));
-      ice->state.dirty |= IRIS_DIRTY_CONSTANTS_CS;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_CS;
       ice->state.shaders[MESA_SHADER_COMPUTE].sysvals_need_upload = true;
    }
 
@@ -379,6 +387,7 @@ iris_launch_grid(struct pipe_context *ctx, const struct pipe_grid_info *grid)
    iris_handle_always_flush_cache(batch);
 
    ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_COMPUTE;
+   ice->state.stage_dirty &= ~IRIS_ALL_STAGE_DIRTY_FOR_COMPUTE;
 
    /* Note: since compute shaders can't access the framebuffer, there's
     * no need to call iris_postdraw_update_resolve_tracking.
index 1b37245199c5396db576ed5ebee21a12b0df5079..98c1c3e93e7a2c9ae60772b66ec342b6af66c044 100644 (file)
@@ -1176,10 +1176,10 @@ iris_update_compiled_vs(struct iris_context *ice)
 
    if (old != shader) {
       ice->shaders.prog[IRIS_CACHE_VS] = shader;
-      ice->state.dirty |= IRIS_DIRTY_VS |
-                          IRIS_DIRTY_BINDINGS_VS |
-                          IRIS_DIRTY_CONSTANTS_VS |
-                          IRIS_DIRTY_VF_SGVS;
+      ice->state.dirty |= IRIS_DIRTY_VF_SGVS;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_VS |
+                                IRIS_STAGE_DIRTY_BINDINGS_VS |
+                                IRIS_STAGE_DIRTY_CONSTANTS_VS;
       shs->sysvals_need_upload = true;
 
       const struct brw_vs_prog_data *vs_prog_data =
@@ -1397,9 +1397,9 @@ iris_update_compiled_tcs(struct iris_context *ice)
 
    if (old != shader) {
       ice->shaders.prog[IRIS_CACHE_TCS] = shader;
-      ice->state.dirty |= IRIS_DIRTY_TCS |
-                          IRIS_DIRTY_BINDINGS_TCS |
-                          IRIS_DIRTY_CONSTANTS_TCS;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_TCS |
+                                IRIS_STAGE_DIRTY_BINDINGS_TCS |
+                                IRIS_STAGE_DIRTY_CONSTANTS_TCS;
       shs->sysvals_need_upload = true;
    }
 }
@@ -1512,16 +1512,16 @@ iris_update_compiled_tes(struct iris_context *ice)
 
    if (old != shader) {
       ice->shaders.prog[IRIS_CACHE_TES] = shader;
-      ice->state.dirty |= IRIS_DIRTY_TES |
-                          IRIS_DIRTY_BINDINGS_TES |
-                          IRIS_DIRTY_CONSTANTS_TES;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_TES |
+                                IRIS_STAGE_DIRTY_BINDINGS_TES |
+                                IRIS_STAGE_DIRTY_CONSTANTS_TES;
       shs->sysvals_need_upload = true;
    }
 
    /* TODO: Could compare and avoid flagging this. */
    const struct shader_info *tes_info = &ish->nir->info;
    if (tes_info->system_values_read & (1ull << SYSTEM_VALUE_VERTICES_IN)) {
-      ice->state.dirty |= IRIS_DIRTY_CONSTANTS_TES;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_TES;
       ice->state.shaders[MESA_SHADER_TESS_EVAL].sysvals_need_upload = true;
    }
 }
@@ -1635,9 +1635,9 @@ iris_update_compiled_gs(struct iris_context *ice)
 
    if (old != shader) {
       ice->shaders.prog[IRIS_CACHE_GS] = shader;
-      ice->state.dirty |= IRIS_DIRTY_GS |
-                          IRIS_DIRTY_BINDINGS_GS |
-                          IRIS_DIRTY_CONSTANTS_GS;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_GS |
+                                IRIS_STAGE_DIRTY_BINDINGS_GS |
+                                IRIS_STAGE_DIRTY_CONSTANTS_GS;
       shs->sysvals_need_upload = true;
    }
 }
@@ -1751,12 +1751,12 @@ iris_update_compiled_fs(struct iris_context *ice)
       // XXX: only need to flag CLIP if barycentric has NONPERSPECTIVE
       // toggles.  might be able to avoid flagging SBE too.
       ice->shaders.prog[IRIS_CACHE_FS] = shader;
-      ice->state.dirty |= IRIS_DIRTY_FS |
-                          IRIS_DIRTY_BINDINGS_FS |
-                          IRIS_DIRTY_CONSTANTS_FS |
-                          IRIS_DIRTY_WM |
+      ice->state.dirty |= IRIS_DIRTY_WM |
                           IRIS_DIRTY_CLIP |
                           IRIS_DIRTY_SBE;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_FS |
+                                IRIS_STAGE_DIRTY_BINDINGS_FS |
+                                IRIS_STAGE_DIRTY_CONSTANTS_FS;
       shs->sysvals_need_upload = true;
    }
 }
@@ -1783,9 +1783,9 @@ update_last_vue_map(struct iris_context *ice,
       ice->state.dirty |= IRIS_DIRTY_CLIP |
                           IRIS_DIRTY_SF_CL_VIEWPORT |
                           IRIS_DIRTY_CC_VIEWPORT |
-                          IRIS_DIRTY_SCISSOR_RECT |
-                          IRIS_DIRTY_UNCOMPILED_FS |
-                          ice->state.dirty_for_nos[IRIS_NOS_LAST_VUE_MAP];
+                          IRIS_DIRTY_SCISSOR_RECT;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_FS |
+         ice->state.stage_dirty_for_nos[IRIS_NOS_LAST_VUE_MAP];
    }
 
    if (changed_slots || (old_map && old_map->separate != vue_map->separate)) {
@@ -1821,7 +1821,7 @@ iris_update_pull_constant_descriptors(struct iris_context *ice,
    }
 
    if (any_new_descriptors)
-      ice->state.dirty |= IRIS_DIRTY_BINDINGS_VS << stage;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_BINDINGS_VS << stage;
 }
 
 /**
@@ -1850,6 +1850,7 @@ void
 iris_update_compiled_shaders(struct iris_context *ice)
 {
    const uint64_t dirty = ice->state.dirty;
+   const uint64_t stage_dirty = ice->state.stage_dirty;
 
    struct brw_vue_prog_data *old_prog_datas[4];
    if (!(dirty & IRIS_DIRTY_URB)) {
@@ -1857,7 +1858,8 @@ iris_update_compiled_shaders(struct iris_context *ice)
          old_prog_datas[i] = get_vue_prog_data(ice, i);
    }
 
-   if (dirty & (IRIS_DIRTY_UNCOMPILED_TCS | IRIS_DIRTY_UNCOMPILED_TES)) {
+   if (stage_dirty & (IRIS_STAGE_DIRTY_UNCOMPILED_TCS |
+                      IRIS_STAGE_DIRTY_UNCOMPILED_TES)) {
        struct iris_uncompiled_shader *tes =
           ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL];
        if (tes) {
@@ -1866,19 +1868,20 @@ iris_update_compiled_shaders(struct iris_context *ice)
        } else {
           ice->shaders.prog[IRIS_CACHE_TCS] = NULL;
           ice->shaders.prog[IRIS_CACHE_TES] = NULL;
-          ice->state.dirty |=
-             IRIS_DIRTY_TCS | IRIS_DIRTY_TES |
-             IRIS_DIRTY_BINDINGS_TCS | IRIS_DIRTY_BINDINGS_TES |
-             IRIS_DIRTY_CONSTANTS_TCS | IRIS_DIRTY_CONSTANTS_TES;
+          ice->state.stage_dirty |=
+             IRIS_STAGE_DIRTY_TCS | IRIS_STAGE_DIRTY_TES |
+             IRIS_STAGE_DIRTY_BINDINGS_TCS | IRIS_STAGE_DIRTY_BINDINGS_TES |
+             IRIS_STAGE_DIRTY_CONSTANTS_TCS | IRIS_STAGE_DIRTY_CONSTANTS_TES;
        }
    }
 
-   if (dirty & IRIS_DIRTY_UNCOMPILED_VS)
+   if (stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_VS)
       iris_update_compiled_vs(ice);
-   if (dirty & IRIS_DIRTY_UNCOMPILED_GS)
+   if (stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_GS)
       iris_update_compiled_gs(ice);
 
-   if (dirty & (IRIS_DIRTY_UNCOMPILED_GS | IRIS_DIRTY_UNCOMPILED_TES)) {
+   if (stage_dirty & (IRIS_STAGE_DIRTY_UNCOMPILED_GS |
+                      IRIS_STAGE_DIRTY_UNCOMPILED_TES)) {
       const struct iris_compiled_shader *gs =
          ice->shaders.prog[MESA_SHADER_GEOMETRY];
       const struct iris_compiled_shader *tes =
@@ -1923,7 +1926,7 @@ iris_update_compiled_shaders(struct iris_context *ice)
       }
    }
 
-   if (dirty & IRIS_DIRTY_UNCOMPILED_FS)
+   if (stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_FS)
       iris_update_compiled_fs(ice);
 
    /* Changing shader interfaces may require a URB configuration. */
@@ -1940,7 +1943,7 @@ iris_update_compiled_shaders(struct iris_context *ice)
    }
 
    for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_FRAGMENT; i++) {
-      if (ice->state.dirty & (IRIS_DIRTY_CONSTANTS_VS << i))
+      if (ice->state.stage_dirty & (IRIS_STAGE_DIRTY_CONSTANTS_VS << i))
          iris_update_pull_constant_descriptors(ice, i);
    }
 }
@@ -2024,9 +2027,9 @@ iris_update_compiled_cs(struct iris_context *ice)
 
    if (old != shader) {
       ice->shaders.prog[IRIS_CACHE_CS] = shader;
-      ice->state.dirty |= IRIS_DIRTY_CS |
-                          IRIS_DIRTY_BINDINGS_CS |
-                          IRIS_DIRTY_CONSTANTS_CS;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CS |
+                                IRIS_STAGE_DIRTY_BINDINGS_CS |
+                                IRIS_STAGE_DIRTY_CONSTANTS_CS;
       shs->sysvals_need_upload = true;
    }
 }
@@ -2034,10 +2037,10 @@ iris_update_compiled_cs(struct iris_context *ice)
 void
 iris_update_compiled_compute_shader(struct iris_context *ice)
 {
-   if (ice->state.dirty & IRIS_DIRTY_UNCOMPILED_CS)
+   if (ice->state.stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_CS)
       iris_update_compiled_cs(ice);
 
-   if (ice->state.dirty & IRIS_DIRTY_CONSTANTS_CS)
+   if (ice->state.stage_dirty & IRIS_STAGE_DIRTY_CONSTANTS_CS)
       iris_update_pull_constant_descriptors(ice, MESA_SHADER_COMPUTE);
 }
 
@@ -2409,7 +2412,7 @@ iris_delete_shader_state(struct pipe_context *ctx, void *state, gl_shader_stage
 
    if (ice->shaders.uncompiled[stage] == ish) {
       ice->shaders.uncompiled[stage] = NULL;
-      ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_VS << stage;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_VS << stage;
    }
 
    if (ish->const_data) {
@@ -2468,7 +2471,7 @@ bind_shader_state(struct iris_context *ice,
                   struct iris_uncompiled_shader *ish,
                   gl_shader_stage stage)
 {
-   uint64_t dirty_bit = IRIS_DIRTY_UNCOMPILED_VS << stage;
+   uint64_t stage_dirty_bit = IRIS_STAGE_DIRTY_UNCOMPILED_VS << stage;
    const uint64_t nos = ish ? ish->nos : 0;
 
    const struct shader_info *old_info = iris_get_shader_info(ice, stage);
@@ -2476,20 +2479,20 @@ bind_shader_state(struct iris_context *ice,
 
    if ((old_info ? util_last_bit(old_info->textures_used) : 0) !=
        (new_info ? util_last_bit(new_info->textures_used) : 0)) {
-      ice->state.dirty |= IRIS_DIRTY_SAMPLER_STATES_VS << stage;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_SAMPLER_STATES_VS << stage;
    }
 
    ice->shaders.uncompiled[stage] = ish;
-   ice->state.dirty |= dirty_bit;
+   ice->state.stage_dirty |= stage_dirty_bit;
 
    /* Record that CSOs need to mark IRIS_DIRTY_UNCOMPILED_XS when they change
     * (or that they no longer need to do so).
     */
    for (int i = 0; i < IRIS_NOS_COUNT; i++) {
       if (nos & (1 << i))
-         ice->state.dirty_for_nos[i] |= dirty_bit;
+         ice->state.stage_dirty_for_nos[i] |= stage_dirty_bit;
       else
-         ice->state.dirty_for_nos[i] &= ~dirty_bit;
+         ice->state.stage_dirty_for_nos[i] &= ~stage_dirty_bit;
    }
 }
 
index 26d15a833b8c8ff9d374679612f52a290d5003d9..8888a8fd2842ddbb82f17013d8629a1881c2db01 100644 (file)
@@ -737,13 +737,13 @@ iris_set_active_query_state(struct pipe_context *ctx, bool enable)
    // have to be done dynamically at draw time, which is a pain
    ice->state.statistics_counters_enabled = enable;
    ice->state.dirty |= IRIS_DIRTY_CLIP |
-                       IRIS_DIRTY_GS |
                        IRIS_DIRTY_RASTER |
                        IRIS_DIRTY_STREAMOUT |
-                       IRIS_DIRTY_TCS |
-                       IRIS_DIRTY_TES |
-                       IRIS_DIRTY_VS |
                        IRIS_DIRTY_WM;
+   ice->state.stage_dirty |= IRIS_STAGE_DIRTY_GS |
+                             IRIS_STAGE_DIRTY_TCS |
+                             IRIS_STAGE_DIRTY_TES |
+                             IRIS_STAGE_DIRTY_VS;
 }
 
 static void
index 01a2cce1a72c1c293aa62d611b643b82c8dfd9e4..f763f45f01e55fafc922d1305d3929b20f0d5a97 100644 (file)
@@ -167,10 +167,10 @@ iris_predraw_resolve_inputs(struct iris_context *ice,
    struct iris_shader_state *shs = &ice->state.shaders[stage];
    const struct shader_info *info = iris_get_shader_info(ice, stage);
 
-   uint64_t dirty = (IRIS_DIRTY_BINDINGS_VS << stage) |
-                    (consider_framebuffer ? IRIS_DIRTY_BINDINGS_FS : 0);
+   uint64_t stage_dirty = (IRIS_STAGE_DIRTY_BINDINGS_VS << stage) |
+      (consider_framebuffer ? IRIS_STAGE_DIRTY_BINDINGS_FS : 0);
 
-   if (ice->state.dirty & dirty) {
+   if (ice->state.stage_dirty & stage_dirty) {
       resolve_sampler_views(ice, batch, shs, info, draw_aux_buffer_disabled,
                             consider_framebuffer);
       resolve_image_views(ice, batch, shs, info, draw_aux_buffer_disabled,
@@ -227,7 +227,8 @@ iris_predraw_resolve_framebuffer(struct iris_context *ice,
       }
    }
 
-   if (ice->state.dirty & (IRIS_DIRTY_BINDINGS_FS | IRIS_DIRTY_BLEND_STATE)) {
+   if ((ice->state.dirty & IRIS_DIRTY_BLEND_STATE) ||
+       (ice->state.stage_dirty & IRIS_STAGE_DIRTY_BINDINGS_FS)) {
       for (unsigned i = 0; i < cso_fb->nr_cbufs; i++) {
          struct iris_surface *surf = (void *) cso_fb->cbufs[i];
          if (!surf)
@@ -243,7 +244,8 @@ iris_predraw_resolve_framebuffer(struct iris_context *ice,
          if (ice->state.draw_aux_usage[i] != aux_usage) {
             ice->state.draw_aux_usage[i] = aux_usage;
             /* XXX: Need to track which bindings to make dirty */
-            ice->state.dirty |= IRIS_ALL_DIRTY_BINDINGS;
+            ice->state.dirty |= IRIS_DIRTY_RENDER_BUFFER;
+            ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_BINDINGS;
          }
 
          iris_resource_prepare_render(ice, batch, res, surf->view.base_level,
@@ -312,7 +314,8 @@ iris_postdraw_update_resolve_tracking(struct iris_context *ice,
    }
 
    bool may_have_resolved_color =
-      ice->state.dirty & (IRIS_DIRTY_BINDINGS_FS | IRIS_DIRTY_BLEND_STATE);
+      (ice->state.dirty & IRIS_DIRTY_BLEND_STATE) ||
+      (ice->state.stage_dirty & IRIS_STAGE_DIRTY_BINDINGS_FS);
 
    for (unsigned i = 0; i < cso_fb->nr_cbufs; i++) {
       struct iris_surface *surf = (void *) cso_fb->cbufs[i];
@@ -899,7 +902,8 @@ iris_resource_set_aux_state(struct iris_context *ice,
       if (res->aux.state[level][start_layer + a] != aux_state) {
          res->aux.state[level][start_layer + a] = aux_state;
          /* XXX: Need to track which bindings to make dirty */
-         ice->state.dirty |= IRIS_ALL_DIRTY_BINDINGS;
+         ice->state.dirty |= IRIS_DIRTY_RENDER_BUFFER;
+         ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_BINDINGS;
       }
    }
 }
index 3d2805f3548843323f0a74e70befc7ae7a2821fd..7211abec65a6b1f3d05be27ff73ae8bbbec38b1f 100644 (file)
@@ -2016,13 +2016,14 @@ void
 iris_dirty_for_history(struct iris_context *ice,
                        struct iris_resource *res)
 {
-   uint64_t dirty = 0ull;
+   uint64_t stage_dirty = 0ull;
 
    if (res->bind_history & PIPE_BIND_CONSTANT_BUFFER) {
-      dirty |= ((uint64_t)res->bind_stages) << IRIS_SHIFT_FOR_DIRTY_CONSTANTS;
+      stage_dirty |= ((uint64_t)res->bind_stages)
+                        << IRIS_SHIFT_FOR_STAGE_DIRTY_CONSTANTS;
    }
 
-   ice->state.dirty |= dirty;
+   ice->state.stage_dirty |= stage_dirty;
 }
 
 /**
index 2546efd308d1bfb035df380b2530530209351f7d..bc3949385369207e2bad1f81a8f92be3b6055a5a 100644 (file)
@@ -1265,7 +1265,7 @@ iris_bind_blend_state(struct pipe_context *ctx, void *state)
    ice->state.dirty |= IRIS_DIRTY_PS_BLEND;
    ice->state.dirty |= IRIS_DIRTY_BLEND_STATE;
    ice->state.dirty |= IRIS_DIRTY_RENDER_RESOLVES_AND_FLUSHES;
-   ice->state.dirty |= ice->state.dirty_for_nos[IRIS_NOS_BLEND];
+   ice->state.stage_dirty |= ice->state.stage_dirty_for_nos[IRIS_NOS_BLEND];
 
    if (GEN_GEN == 8)
       ice->state.dirty |= IRIS_DIRTY_PMA_FIX;
@@ -1416,7 +1416,8 @@ iris_bind_zsa_state(struct pipe_context *ctx, void *state)
    ice->state.cso_zsa = new_cso;
    ice->state.dirty |= IRIS_DIRTY_CC_VIEWPORT;
    ice->state.dirty |= IRIS_DIRTY_WM_DEPTH_STENCIL;
-   ice->state.dirty |= ice->state.dirty_for_nos[IRIS_NOS_DEPTH_STENCIL_ALPHA];
+   ice->state.stage_dirty |=
+      ice->state.stage_dirty_for_nos[IRIS_NOS_DEPTH_STENCIL_ALPHA];
 
    if (GEN_GEN == 8)
       ice->state.dirty |= IRIS_DIRTY_PMA_FIX;
@@ -1827,13 +1828,14 @@ iris_bind_rasterizer_state(struct pipe_context *ctx, void *state)
          ice->state.dirty |= IRIS_DIRTY_SBE;
 
       if (cso_changed(conservative_rasterization))
-         ice->state.dirty |= IRIS_DIRTY_FS;
+         ice->state.stage_dirty |= IRIS_STAGE_DIRTY_FS;
    }
 
    ice->state.cso_rast = new_cso;
    ice->state.dirty |= IRIS_DIRTY_RASTER;
    ice->state.dirty |= IRIS_DIRTY_CLIP;
-   ice->state.dirty |= ice->state.dirty_for_nos[IRIS_NOS_RASTERIZER];
+   ice->state.stage_dirty |=
+      ice->state.stage_dirty_for_nos[IRIS_NOS_RASTERIZER];
 }
 
 /**
@@ -1975,7 +1977,7 @@ iris_bind_sampler_states(struct pipe_context *ctx,
    }
 
    if (dirty)
-      ice->state.dirty |= IRIS_DIRTY_SAMPLER_STATES_VS << stage;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_SAMPLER_STATES_VS << stage;
 }
 
 /**
@@ -2768,14 +2770,14 @@ iris_set_shader_images(struct pipe_context *ctx,
       }
    }
 
-   ice->state.dirty |= IRIS_DIRTY_BINDINGS_VS << stage;
+   ice->state.stage_dirty |= IRIS_STAGE_DIRTY_BINDINGS_VS << stage;
    ice->state.dirty |=
       stage == MESA_SHADER_COMPUTE ? IRIS_DIRTY_COMPUTE_RESOLVES_AND_FLUSHES
                                    : IRIS_DIRTY_RENDER_RESOLVES_AND_FLUSHES;
 
    /* Broadwell also needs brw_image_params re-uploaded */
    if (GEN_GEN < 9) {
-      ice->state.dirty |= IRIS_DIRTY_CONSTANTS_VS << stage;
+      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_VS << stage;
       shs->sysvals_need_upload = true;
    }
 }
@@ -2812,7 +2814,7 @@ iris_set_sampler_views(struct pipe_context *ctx,
       }
    }
 
-   ice->state.dirty |= (IRIS_DIRTY_BINDINGS_VS << stage);
+   ice->state.stage_dirty |= (IRIS_STAGE_DIRTY_BINDINGS_VS << stage);
    ice->state.dirty |=
       stage == MESA_SHADER_COMPUTE ? IRIS_DIRTY_COMPUTE_RESOLVES_AND_FLUSHES
                                    : IRIS_DIRTY_RENDER_RESOLVES_AND_FLUSHES;
@@ -2832,7 +2834,7 @@ iris_set_tess_state(struct pipe_context *ctx,
    memcpy(&ice->state.default_outer_level[0], &default_outer_level[0], 4 * sizeof(float));
    memcpy(&ice->state.default_inner_level[0], &default_inner_level[0], 2 * sizeof(float));
 
-   ice->state.dirty |= IRIS_DIRTY_CONSTANTS_TCS;
+   ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_TCS;
    shs->sysvals_need_upload = true;
 }
 
@@ -2858,8 +2860,9 @@ iris_set_clip_state(struct pipe_context *ctx,
 
    memcpy(&ice->state.clip_planes, state, sizeof(*state));
 
-   ice->state.dirty |= IRIS_DIRTY_CONSTANTS_VS | IRIS_DIRTY_CONSTANTS_GS |
-                       IRIS_DIRTY_CONSTANTS_TES;
+   ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_VS |
+                             IRIS_STAGE_DIRTY_CONSTANTS_GS |
+                             IRIS_STAGE_DIRTY_CONSTANTS_TES;
    shs->sysvals_need_upload = true;
    gshs->sysvals_need_upload = true;
    tshs->sysvals_need_upload = true;
@@ -3002,7 +3005,7 @@ iris_set_framebuffer_state(struct pipe_context *ctx,
 
       /* We need to toggle 3DSTATE_PS::32 Pixel Dispatch Enable */
       if (GEN_GEN >= 9 && (cso->samples == 16 || samples == 16))
-         ice->state.dirty |= IRIS_DIRTY_FS;
+         ice->state.stage_dirty |= IRIS_STAGE_DIRTY_FS;
    }
 
    if (cso->nr_cbufs != state->nr_cbufs) {
@@ -3088,13 +3091,14 @@ iris_set_framebuffer_state(struct pipe_context *ctx,
       iris_bo_offset_from_base_address(iris_resource_bo(ice->state.null_fb.res));
 
    /* Render target change */
-   ice->state.dirty |= IRIS_DIRTY_BINDINGS_FS;
+   ice->state.stage_dirty |= IRIS_STAGE_DIRTY_BINDINGS_FS;
 
    ice->state.dirty |= IRIS_DIRTY_RENDER_BUFFER;
 
    ice->state.dirty |= IRIS_DIRTY_RENDER_RESOLVES_AND_FLUSHES;
 
-   ice->state.dirty |= ice->state.dirty_for_nos[IRIS_NOS_FRAMEBUFFER];
+   ice->state.stage_dirty |=
+      ice->state.stage_dirty_for_nos[IRIS_NOS_FRAMEBUFFER];
 
    if (GEN_GEN == 8)
       ice->state.dirty |= IRIS_DIRTY_PMA_FIX;
@@ -3154,7 +3158,7 @@ iris_set_constant_buffer(struct pipe_context *ctx,
       pipe_resource_reference(&cbuf->buffer, NULL);
    }
 
-   ice->state.dirty |= IRIS_DIRTY_CONSTANTS_VS << stage;
+   ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_VS << stage;
 }
 
 static void
@@ -3287,7 +3291,7 @@ iris_set_shader_buffers(struct pipe_context *ctx,
       }
    }
 
-   ice->state.dirty |= IRIS_DIRTY_BINDINGS_VS << stage;
+   ice->state.stage_dirty |= IRIS_STAGE_DIRTY_BINDINGS_VS << stage;
 }
 
 static void
@@ -4896,6 +4900,7 @@ iris_restore_render_saved_bos(struct iris_context *ice,
    struct iris_genx_state *genx = ice->state.genx;
 
    const uint64_t clean = ~ice->state.dirty;
+   const uint64_t stage_clean = ~ice->state.stage_dirty;
 
    if (clean & IRIS_DIRTY_CC_VIEWPORT) {
       iris_use_optional_res(batch, ice->state.last_res.cc_vp, false);
@@ -4931,7 +4936,7 @@ iris_restore_render_saved_bos(struct iris_context *ice,
    }
 
    for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
-      if (!(clean & (IRIS_DIRTY_CONSTANTS_VS << stage)))
+      if (!(stage_clean & (IRIS_STAGE_DIRTY_CONSTANTS_VS << stage)))
          continue;
 
       struct iris_shader_state *shs = &ice->state.shaders[stage];
@@ -4964,7 +4969,7 @@ iris_restore_render_saved_bos(struct iris_context *ice,
    }
 
    for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
-      if (clean & (IRIS_DIRTY_BINDINGS_VS << stage)) {
+      if (stage_clean & (IRIS_STAGE_DIRTY_BINDINGS_VS << stage)) {
          /* Re-pin any buffers referred to by the binding table. */
          iris_populate_binding_table(ice, batch, stage, true);
       }
@@ -4978,7 +4983,7 @@ iris_restore_render_saved_bos(struct iris_context *ice,
    }
 
    for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
-      if (clean & (IRIS_DIRTY_VS << stage)) {
+      if (stage_clean & (IRIS_STAGE_DIRTY_VS << stage)) {
          struct iris_compiled_shader *shader = ice->shaders.prog[stage];
 
          if (shader) {
@@ -5019,12 +5024,12 @@ iris_restore_compute_saved_bos(struct iris_context *ice,
                                struct iris_batch *batch,
                                const struct pipe_grid_info *grid)
 {
-   const uint64_t clean = ~ice->state.dirty;
+   const uint64_t stage_clean = ~ice->state.stage_dirty;
 
    const int stage = MESA_SHADER_COMPUTE;
    struct iris_shader_state *shs = &ice->state.shaders[stage];
 
-   if (clean & IRIS_DIRTY_BINDINGS_CS) {
+   if (stage_clean & IRIS_STAGE_DIRTY_BINDINGS_CS) {
       /* Re-pin any buffers referred to by the binding table. */
       iris_populate_binding_table(ice, batch, stage, true);
    }
@@ -5033,14 +5038,14 @@ iris_restore_compute_saved_bos(struct iris_context *ice,
    if (sampler_res)
       iris_use_pinned_bo(batch, iris_resource_bo(sampler_res), false);
 
-   if ((clean & IRIS_DIRTY_SAMPLER_STATES_CS) &&
-       (clean & IRIS_DIRTY_BINDINGS_CS) &&
-       (clean & IRIS_DIRTY_CONSTANTS_CS) &&
-       (clean & IRIS_DIRTY_CS)) {
+   if ((stage_clean & IRIS_STAGE_DIRTY_SAMPLER_STATES_CS) &&
+       (stage_clean & IRIS_STAGE_DIRTY_BINDINGS_CS) &&
+       (stage_clean & IRIS_STAGE_DIRTY_CONSTANTS_CS) &&
+       (stage_clean & IRIS_STAGE_DIRTY_CS)) {
       iris_use_optional_res(batch, ice->state.last_res.cs_desc, false);
    }
 
-   if (clean & IRIS_DIRTY_CS) {
+   if (stage_clean & IRIS_STAGE_DIRTY_CS) {
       struct iris_compiled_shader *shader = ice->shaders.prog[stage];
 
       if (shader) {
@@ -5324,8 +5329,10 @@ iris_upload_dirty_render_state(struct iris_context *ice,
                                const struct pipe_draw_info *draw)
 {
    const uint64_t dirty = ice->state.dirty;
+   const uint64_t stage_dirty = ice->state.stage_dirty;
 
-   if (!(dirty & IRIS_ALL_DIRTY_FOR_RENDER))
+   if (!(dirty & IRIS_ALL_DIRTY_FOR_RENDER) &&
+       !(stage_dirty & IRIS_ALL_STAGE_DIRTY_FOR_RENDER))
       return;
 
    struct iris_genx_state *genx = ice->state.genx;
@@ -5517,14 +5524,15 @@ iris_upload_dirty_render_state(struct iris_context *ice,
     * any stage has a dirty binding table.
     */
    const bool emit_const_wa = GEN_GEN >= 11 &&
-      (dirty & IRIS_ALL_DIRTY_BINDINGS) != 0;
+      ((dirty & IRIS_DIRTY_RENDER_BUFFER) ||
+       (stage_dirty & IRIS_ALL_STAGE_DIRTY_BINDINGS));
 
 #if GEN_GEN >= 12
    uint32_t nobuffer_stages = 0;
 #endif
 
    for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
-      if (!(dirty & (IRIS_DIRTY_CONSTANTS_VS << stage)) &&
+      if (!(stage_dirty & (IRIS_STAGE_DIRTY_CONSTANTS_VS << stage)) &&
           !emit_const_wa)
          continue;
 
@@ -5571,8 +5579,9 @@ iris_upload_dirty_render_state(struct iris_context *ice,
        * in order to commit constants.  TODO: Investigate "Disable Gather
        * at Set Shader" to go back to legacy mode...
        */
-      if (dirty & ((IRIS_DIRTY_BINDINGS_VS |
-                    (GEN_GEN == 9 ? IRIS_DIRTY_CONSTANTS_VS : 0)) << stage)) {
+      if (stage_dirty & ((IRIS_STAGE_DIRTY_BINDINGS_VS |
+                          (GEN_GEN == 9 ? IRIS_STAGE_DIRTY_CONSTANTS_VS : 0))
+                            << stage)) {
          iris_emit_cmd(batch, GENX(3DSTATE_BINDING_TABLE_POINTERS_VS), ptr) {
             ptr._3DCommandSubOpcode = 38 + stage;
             ptr.PointertoVSBindingTable = binder->bt_offset[stage];
@@ -5599,13 +5608,13 @@ iris_upload_dirty_render_state(struct iris_context *ice,
    }
 
    for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
-      if (dirty & (IRIS_DIRTY_BINDINGS_VS << stage)) {
+      if (stage_dirty & (IRIS_STAGE_DIRTY_BINDINGS_VS << stage)) {
          iris_populate_binding_table(ice, batch, stage, false);
       }
    }
 
    for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
-      if (!(dirty & (IRIS_DIRTY_SAMPLER_STATES_VS << stage)) ||
+      if (!(stage_dirty & (IRIS_STAGE_DIRTY_SAMPLER_STATES_VS << stage)) ||
           !ice->shaders.prog[stage])
          continue;
 
@@ -5641,7 +5650,7 @@ iris_upload_dirty_render_state(struct iris_context *ice,
    }
 
    for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
-      if (!(dirty & (IRIS_DIRTY_VS << stage)))
+      if (!(stage_dirty & (IRIS_STAGE_DIRTY_VS << stage)))
          continue;
 
       struct iris_compiled_shader *shader = ice->shaders.prog[stage];
@@ -6494,7 +6503,7 @@ iris_upload_compute_state(struct iris_context *ice,
                           struct iris_batch *batch,
                           const struct pipe_grid_info *grid)
 {
-   const uint64_t dirty = ice->state.dirty;
+   const uint64_t stage_dirty = ice->state.stage_dirty;
    struct iris_screen *screen = batch->screen;
    const struct gen_device_info *devinfo = &screen->devinfo;
    struct iris_binder *binder = &ice->state.binder;
@@ -6516,13 +6525,14 @@ iris_upload_compute_state(struct iris_context *ice,
     */
    iris_use_pinned_bo(batch, ice->state.binder.bo, false);
 
-   if ((dirty & IRIS_DIRTY_CONSTANTS_CS) && shs->sysvals_need_upload)
+   if ((stage_dirty & IRIS_STAGE_DIRTY_CONSTANTS_CS) &&
+       shs->sysvals_need_upload)
       upload_sysvals(ice, MESA_SHADER_COMPUTE);
 
-   if (dirty & IRIS_DIRTY_BINDINGS_CS)
+   if (stage_dirty & IRIS_STAGE_DIRTY_BINDINGS_CS)
       iris_populate_binding_table(ice, batch, MESA_SHADER_COMPUTE, false);
 
-   if (dirty & IRIS_DIRTY_SAMPLER_STATES_CS)
+   if (stage_dirty & IRIS_STAGE_DIRTY_SAMPLER_STATES_CS)
       iris_upload_sampler_states(ice, MESA_SHADER_COMPUTE);
 
    iris_use_optional_res(batch, shs->sampler_table.res, false);
@@ -6535,7 +6545,7 @@ iris_upload_compute_state(struct iris_context *ice,
    genX(invalidate_aux_map_state)(batch);
 #endif
 
-   if (dirty & IRIS_DIRTY_CS) {
+   if (stage_dirty & IRIS_STAGE_DIRTY_CS) {
       /* The MEDIA_VFE_STATE documentation for Gen8+ says:
        *
        *   "A stalling PIPE_CONTROL is required before MEDIA_VFE_STATE unless
@@ -6576,7 +6586,7 @@ iris_upload_compute_state(struct iris_context *ice,
    }
 
    /* TODO: Combine subgroup-id with cbuf0 so we can push regular uniforms */
-   if (dirty & IRIS_DIRTY_CS) {
+   if (stage_dirty & IRIS_STAGE_DIRTY_CS) {
       uint32_t curbe_data_offset = 0;
       assert(cs_prog_data->push.cross_thread.dwords == 0 &&
              cs_prog_data->push.per_thread.dwords == 1 &&
@@ -6598,10 +6608,10 @@ iris_upload_compute_state(struct iris_context *ice,
       }
    }
 
-   if (dirty & (IRIS_DIRTY_SAMPLER_STATES_CS |
-                IRIS_DIRTY_BINDINGS_CS |
-                IRIS_DIRTY_CONSTANTS_CS |
-                IRIS_DIRTY_CS)) {
+   if (stage_dirty & (IRIS_STAGE_DIRTY_SAMPLER_STATES_CS |
+                      IRIS_STAGE_DIRTY_BINDINGS_CS |
+                      IRIS_STAGE_DIRTY_CONSTANTS_CS |
+                      IRIS_STAGE_DIRTY_CS)) {
       uint32_t desc[GENX(INTERFACE_DESCRIPTOR_DATA_length)];
 
       iris_pack_state(GENX(INTERFACE_DESCRIPTOR_DATA), desc, idd) {
@@ -6804,7 +6814,7 @@ iris_rebind_buffer(struct iris_context *ice,
 
             if (res->bo == iris_resource_bo(cbuf->buffer)) {
                pipe_resource_reference(&surf_state->res, NULL);
-               ice->state.dirty |= IRIS_DIRTY_CONSTANTS_VS << s;
+               ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_VS << s;
             }
          }
       }
@@ -6836,7 +6846,7 @@ iris_rebind_buffer(struct iris_context *ice,
 
             if (update_surface_state_addrs(ice->state.surface_uploader,
                                            &isv->surface_state, bo)) {
-               ice->state.dirty |= IRIS_DIRTY_BINDINGS_VS << s;
+               ice->state.stage_dirty |= IRIS_STAGE_DIRTY_BINDINGS_VS << s;
             }
          }
       }
@@ -6850,7 +6860,7 @@ iris_rebind_buffer(struct iris_context *ice,
 
             if (update_surface_state_addrs(ice->state.surface_uploader,
                                            &iv->surface_state, bo)) {
-               ice->state.dirty |= IRIS_DIRTY_BINDINGS_VS << s;
+               ice->state.stage_dirty |= IRIS_STAGE_DIRTY_BINDINGS_VS << s;
             }
          }
       }
@@ -7512,11 +7522,15 @@ iris_set_frontend_noop(struct pipe_context *ctx, bool enable)
 {
    struct iris_context *ice = (struct iris_context *) ctx;
 
-   if (iris_batch_prepare_noop(&ice->batches[IRIS_BATCH_RENDER], enable))
+   if (iris_batch_prepare_noop(&ice->batches[IRIS_BATCH_RENDER], enable)) {
       ice->state.dirty |= IRIS_ALL_DIRTY_FOR_RENDER;
+      ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_FOR_RENDER;
+   }
 
-   if (iris_batch_prepare_noop(&ice->batches[IRIS_BATCH_COMPUTE], enable))
+   if (iris_batch_prepare_noop(&ice->batches[IRIS_BATCH_COMPUTE], enable)) {
       ice->state.dirty |= IRIS_ALL_DIRTY_FOR_COMPUTE;
+      ice->state.stage_dirty |= IRIS_ALL_STAGE_DIRTY_FOR_COMPUTE;
+   }
 }
 
 void
@@ -7597,6 +7611,7 @@ genX(init_state)(struct iris_context *ice)
    screen->vtbl.lost_genx_state = iris_lost_genx_state;
 
    ice->state.dirty = ~0ull;
+   ice->state.stage_dirty = ~0ull;
 
    ice->state.statistics_counters_enabled = true;