zink: track and apply ds3 states only on change
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Thu, 8 Jun 2023 20:24:27 +0000 (16:24 -0400)
committerMarge Bot <emma+marge@anholt.net>
Wed, 21 Jun 2023 22:43:48 +0000 (22:43 +0000)
drivers don't do their own state tracking, so ensure the calls are only
made when necessary

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23758>

src/gallium/drivers/zink/zink_blit.c
src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_draw.cpp
src/gallium/drivers/zink/zink_state.c
src/gallium/drivers/zink/zink_types.h

index d371b85..fa4b891 100644 (file)
@@ -407,6 +407,7 @@ zink_blit(struct pipe_context *pctx,
    bool in_rp = ctx->batch.in_rp;
    uint64_t tc_data = ctx->dynamic_fb.tc_info.data;
    bool queries_disabled = ctx->queries_disabled;
+   unsigned ds3_states = ctx->ds3_states;
    if (ctx->unordered_blitting) {
       /* for unordered blit, swap the unordered cmdbuf for the main one for the whole op to avoid conditional hell */
       ctx->batch.state->cmdbuf = ctx->batch.state->barrier_cmdbuf;
@@ -415,6 +416,15 @@ zink_blit(struct pipe_context *pctx,
       ctx->queries_disabled = true;
       ctx->batch.state->has_barriers = true;
       ctx->pipeline_changed[0] = true;
+      struct zink_screen *screen = zink_screen(pctx->screen);
+      if (screen->info.have_EXT_extended_dynamic_state3) {
+         if (screen->have_full_ds3)
+            ctx->ds3_states = UINT32_MAX;
+         else
+            ctx->ds3_states = BITFIELD_MASK(ZINK_DS3_BLEND_A2C);
+         if (!screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToOneEnable)
+            ctx->ds3_states &= ~BITFIELD_BIT(ZINK_DS3_BLEND_A21);
+      }
       zink_select_draw_vbo(ctx);
    }
    zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | ZINK_BLIT_SAVE_TEXTURES);
@@ -460,6 +470,7 @@ zink_blit(struct pipe_context *pctx,
       ctx->batch.state->cmdbuf = cmdbuf;
       ctx->gfx_pipeline_state.pipeline = pipeline;
       ctx->pipeline_changed[0] = true;
+      ctx->ds3_states = ds3_states;
       zink_select_draw_vbo(ctx);
    }
    ctx->unordered_blitting = false;
index e45eb85..631b2fd 100644 (file)
@@ -3210,8 +3210,9 @@ flush_batch(struct zink_context *ctx, bool sync)
    if (ctx->batch.state->is_device_lost) {
       check_device_lost(ctx);
    } else {
+      struct zink_screen *screen = zink_screen(ctx->base.screen);
       zink_start_batch(ctx, batch);
-      if (zink_screen(ctx->base.screen)->info.have_EXT_transform_feedback && ctx->num_so_targets)
+      if (screen->info.have_EXT_transform_feedback && ctx->num_so_targets)
          ctx->dirty_so_targets = true;
       ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true;
       zink_select_draw_vbo(ctx);
@@ -3219,6 +3220,14 @@ flush_batch(struct zink_context *ctx, bool sync)
 
       if (ctx->oom_stall)
          stall(ctx);
+      if (screen->info.have_EXT_extended_dynamic_state3) {
+         if (screen->have_full_ds3)
+            ctx->ds3_states = UINT32_MAX;
+         else
+            ctx->ds3_states = BITFIELD_MASK(ZINK_DS3_BLEND_A2C);
+         if (!screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToOneEnable)
+            ctx->ds3_states &= ~BITFIELD_BIT(ZINK_DS3_BLEND_A21);
+      }
       ctx->oom_flush = false;
       ctx->oom_stall = false;
       ctx->dd.bindless_bound = false;
@@ -3412,8 +3421,11 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
    /* renderpass changes if the number or types of attachments change */
    ctx->rp_changed |= ctx->fb_state.nr_cbufs != state->nr_cbufs;
    ctx->rp_changed |= !!ctx->fb_state.zsbuf != !!state->zsbuf;
-   if (ctx->fb_state.nr_cbufs != state->nr_cbufs)
+   if (ctx->fb_state.nr_cbufs != state->nr_cbufs) {
       ctx->blend_state_changed |= screen->have_full_ds3;
+      if (state->nr_cbufs && screen->have_full_ds3)
+         ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_ON) | BITFIELD_BIT(ZINK_DS3_BLEND_WRITE) | BITFIELD_BIT(ZINK_DS3_BLEND_EQ);
+   }
 
    util_copy_framebuffer_state(&ctx->fb_state, state);
    zink_update_fbfetch(ctx);
index 6ee08a4..e34ac4c 100644 (file)
@@ -795,19 +795,26 @@ zink_draw(struct pipe_context *pctx,
          VKCTX(CmdSetFrontFaceEXT)(batch->state->cmdbuf, (VkFrontFace)ctx->gfx_pipeline_state.dyn_state1.front_face);
          VKCTX(CmdSetCullModeEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.dyn_state1.cull_mode);
       }
-      if (!screen->driver_workarounds.no_linestipple && (DYNAMIC_STATE >= ZINK_DYNAMIC_STATE3 || rast_state->base.line_stipple_enable))
-         VKCTX(CmdSetLineStippleEXT)(batch->state->cmdbuf, rast_state->base.line_stipple_factor, rast_state->base.line_stipple_pattern);
 
       if (DYNAMIC_STATE >= ZINK_DYNAMIC_STATE3) {
-         VKCTX(CmdSetDepthClipEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.depth_clip);
-         VKCTX(CmdSetDepthClampEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.depth_clamp);
-         VKCTX(CmdSetPolygonModeEXT)(batch->state->cmdbuf, (VkPolygonMode)rast_state->hw_state.polygon_mode);
-         VKCTX(CmdSetDepthClipNegativeOneToOneEXT)(batch->state->cmdbuf, !rast_state->hw_state.clip_halfz);
-         VKCTX(CmdSetProvokingVertexModeEXT)(batch->state->cmdbuf, rast_state->hw_state.pv_last ?
-                                                                  VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT :
-                                                                  VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT);
-         VKCTX(CmdSetLineRasterizationModeEXT)(batch->state->cmdbuf, rast_state->dynamic_line_mode);
-         if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_STIPPLE))
+            VKCTX(CmdSetLineStippleEXT)(batch->state->cmdbuf, rast_state->base.line_stipple_factor, rast_state->base.line_stipple_pattern);
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_CLIP))
+            VKCTX(CmdSetDepthClipEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.depth_clip);
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_CLAMP))
+            VKCTX(CmdSetDepthClampEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.depth_clamp);
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_POLYGON))
+            VKCTX(CmdSetPolygonModeEXT)(batch->state->cmdbuf, (VkPolygonMode)rast_state->hw_state.polygon_mode);
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_HALFZ))
+            VKCTX(CmdSetDepthClipNegativeOneToOneEXT)(batch->state->cmdbuf, !rast_state->hw_state.clip_halfz);
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_PV))
+            VKCTX(CmdSetProvokingVertexModeEXT)(batch->state->cmdbuf,
+                                                rast_state->hw_state.pv_last ?
+                                                VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT :
+                                                VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT);
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_CLIP))
+            VKCTX(CmdSetLineRasterizationModeEXT)(batch->state->cmdbuf, rast_state->dynamic_line_mode);
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_RAST_STIPPLE_ON))
             VKCTX(CmdSetLineStippleEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.line_stipple_enable);
       }
    }
@@ -816,20 +823,27 @@ zink_draw(struct pipe_context *pctx,
       VKCTX(CmdSetSampleMaskEXT)(batch->state->cmdbuf, (VkSampleCountFlagBits)(ctx->gfx_pipeline_state.rast_samples + 1), &ctx->gfx_pipeline_state.sample_mask);
       ctx->sample_mask_changed = false;
    }
-   if ((BATCH_CHANGED || ctx->blend_state_changed) && screen->have_full_ds3) {
+   if ((BATCH_CHANGED || ctx->blend_state_changed)) {
       if (ctx->gfx_pipeline_state.blend_state) {
-         VKCTX(CmdSetAlphaToCoverageEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_coverage);
-         if (screen->info.feats.features.alphaToOne)
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_A2C))
+            VKCTX(CmdSetAlphaToCoverageEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_coverage);
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_A21))
             VKCTX(CmdSetAlphaToOneEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_one);
          if (ctx->fb_state.nr_cbufs) {
-            VKCTX(CmdSetColorBlendEnableEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.enables);
-            VKCTX(CmdSetColorWriteMaskEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.wrmask);
-            VKCTX(CmdSetColorBlendEquationEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.eq);
+            if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_ON))
+               VKCTX(CmdSetColorBlendEnableEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.enables);
+            if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_WRITE))
+               VKCTX(CmdSetColorWriteMaskEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.wrmask);
+            if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_EQ))
+               VKCTX(CmdSetColorBlendEquationEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.eq);
          }
-         VKCTX(CmdSetLogicOpEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_enable);
-         VKCTX(CmdSetLogicOpEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_func);
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_LOGIC_ON))
+            VKCTX(CmdSetLogicOpEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_enable);
+         if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_LOGIC))
+            VKCTX(CmdSetLogicOpEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_func);
       }
    }
+   ctx->ds3_states = 0;
 
    if (BATCH_CHANGED ||
        /* only re-emit on non-batch change when actually drawing lines */
index cbe77ad..c69484c 100644 (file)
@@ -356,6 +356,7 @@ zink_create_blend_state(struct pipe_context *pctx,
     */
    cso->alpha_to_coverage = blend_state->alpha_to_coverage;
    cso->alpha_to_one = blend_state->alpha_to_one;
+   cso->num_rts = blend_state->max_rt + 1;
 
    for (int i = 0; i < blend_state->max_rt + 1; ++i) {
       const struct pipe_rt_blend_state *rt = blend_state->rt;
@@ -383,6 +384,10 @@ zink_create_blend_state(struct pipe_context *pctx,
       if (rt->colormask & PIPE_MASK_A)
          att.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
 
+      cso->wrmask |= (rt->colormask << i);
+      if (rt->blend_enable)
+         cso->enables |= BITFIELD_BIT(i);
+
       cso->attachments[i] = att;
 
       cso->ds3.enables[i] = att.blendEnable;
@@ -407,6 +412,7 @@ zink_bind_blend_state(struct pipe_context *pctx, void *cso)
    struct zink_gfx_pipeline_state* state = &zink_context(pctx)->gfx_pipeline_state;
    zink_flush_dgc_if_enabled(ctx);
    struct zink_blend_state *blend = cso;
+   struct zink_blend_state *old_blend = state->blend_state;
 
    if (state->blend_state != cso) {
       state->blend_state = cso;
@@ -419,6 +425,30 @@ zink_bind_blend_state(struct pipe_context *pctx, void *cso)
       if (force_dual_color_blend != zink_get_fs_base_key(ctx)->force_dual_color_blend)
          zink_set_fs_base_key(ctx)->force_dual_color_blend = force_dual_color_blend;
       ctx->blend_state_changed = true;
+
+      if (cso && screen->have_full_ds3) {
+#define STATE_CHECK(NAME, FLAG) \
+   if ((!old_blend || old_blend->NAME != blend->NAME)) \
+      ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_##FLAG)
+
+         STATE_CHECK(alpha_to_coverage, A2C);
+         if (screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToOneEnable) {
+            STATE_CHECK(alpha_to_one, A21);
+         }
+         STATE_CHECK(enables, ON);
+         STATE_CHECK(wrmask, WRITE);
+         if (old_blend && blend->num_rts == old_blend->num_rts) {
+            if (memcmp(blend->ds3.eq, old_blend->ds3.eq, blend->num_rts * sizeof(blend->ds3.eq[0])))
+               ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_EQ);
+         } else {
+            ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_EQ);
+         }
+         STATE_CHECK(logicop_enable, LOGIC_ON);
+         STATE_CHECK(logicop_func, LOGIC);
+
+#undef STATE_CHECK
+      }
+
    }
 }
 
@@ -652,6 +682,7 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
 {
    struct zink_context *ctx = zink_context(pctx);
    struct zink_screen *screen = zink_screen(pctx->screen);
+   struct zink_rasterizer_state *prev_state = ctx->rast_state;
    bool point_quad_rasterization = ctx->rast_state ? ctx->rast_state->base.point_quad_rasterization : false;
    bool scissor = ctx->rast_state ? ctx->rast_state->base.scissor : false;
    bool pv_last = ctx->rast_state ? ctx->rast_state->hw_state.pv_last : false;
@@ -682,6 +713,32 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
          ctx->vp_state_changed = true;
       }
 
+      if (screen->info.have_EXT_extended_dynamic_state3) {
+#define STATE_CHECK(NAME, FLAG) \
+   if (cso && (!prev_state || prev_state->NAME != ctx->rast_state->NAME)) \
+      ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_RAST_##FLAG)
+
+         if (!screen->driver_workarounds.no_linestipple) {
+            if (ctx->rast_state->base.line_stipple_enable) {
+               STATE_CHECK(base.line_stipple_factor, STIPPLE);
+               STATE_CHECK(base.line_stipple_pattern, STIPPLE);
+            } else {
+               ctx->ds3_states &= ~BITFIELD_BIT(ZINK_DS3_RAST_STIPPLE);
+            }
+            if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable) {
+               STATE_CHECK(hw_state.line_stipple_enable, STIPPLE_ON);
+            }
+         }
+         STATE_CHECK(hw_state.depth_clip, CLIP);
+         STATE_CHECK(hw_state.depth_clamp, CLAMP);
+         STATE_CHECK(hw_state.polygon_mode, POLYGON);
+         STATE_CHECK(hw_state.clip_halfz, HALFZ);
+         STATE_CHECK(hw_state.pv_last, PV);
+         STATE_CHECK(dynamic_line_mode, LINE);
+
+#undef STATE_CHECK
+      }
+
       if (fabs(ctx->rast_state->base.line_width - line_width) > FLT_EPSILON)
          ctx->line_width_changed = true;
 
index ddf67d2..94850d8 100644 (file)
@@ -352,6 +352,7 @@ struct zink_rasterizer_state {
 
 struct zink_blend_state {
    uint32_t hash;
+   unsigned num_rts;
    VkPipelineColorBlendAttachmentState attachments[PIPE_MAX_COLOR_BUFS];
 
    struct {
@@ -366,6 +367,9 @@ struct zink_blend_state {
    VkBool32 alpha_to_coverage;
    VkBool32 alpha_to_one;
 
+   uint32_t wrmask;
+   uint8_t enables;
+
    bool dual_src_blend;
 };
 
@@ -1722,6 +1726,25 @@ typedef void (*pipe_draw_vertex_state_func)(struct pipe_context *ctx,
                                             unsigned num_draws);
 typedef void (*pipe_launch_grid_func)(struct pipe_context *pipe, const struct pipe_grid_info *info);
 
+
+enum zink_ds3_state {
+   ZINK_DS3_RAST_STIPPLE,
+   ZINK_DS3_RAST_CLIP,
+   ZINK_DS3_RAST_CLAMP,
+   ZINK_DS3_RAST_POLYGON,
+   ZINK_DS3_RAST_HALFZ,
+   ZINK_DS3_RAST_PV,
+   ZINK_DS3_RAST_LINE,
+   ZINK_DS3_RAST_STIPPLE_ON,
+   ZINK_DS3_BLEND_A2C,
+   ZINK_DS3_BLEND_A21,
+   ZINK_DS3_BLEND_ON,
+   ZINK_DS3_BLEND_WRITE,
+   ZINK_DS3_BLEND_EQ,
+   ZINK_DS3_BLEND_LOGIC_ON,
+   ZINK_DS3_BLEND_LOGIC,
+};
+
 struct zink_context {
    struct pipe_context base;
    struct threaded_context *tc;
@@ -1953,6 +1976,8 @@ struct zink_context {
    uint8_t barrier_set_idx[2];
    unsigned memory_barrier;
 
+   uint32_t ds3_states;
+
    uint32_t num_so_targets;
    struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_OUTPUTS];
    bool dirty_so_targets;