From 7b4c1b3a426ec781c81f48bf57e5e7de07bea2af Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 8 Jun 2023 16:24:27 -0400 Subject: [PATCH] zink: track and apply ds3 states only on change drivers don't do their own state tracking, so ensure the calls are only made when necessary Part-of: --- src/gallium/drivers/zink/zink_blit.c | 11 +++++++ src/gallium/drivers/zink/zink_context.c | 16 +++++++-- src/gallium/drivers/zink/zink_draw.cpp | 52 +++++++++++++++++++----------- src/gallium/drivers/zink/zink_state.c | 57 +++++++++++++++++++++++++++++++++ src/gallium/drivers/zink/zink_types.h | 25 +++++++++++++++ 5 files changed, 140 insertions(+), 21 deletions(-) diff --git a/src/gallium/drivers/zink/zink_blit.c b/src/gallium/drivers/zink/zink_blit.c index d371b85..fa4b891 100644 --- a/src/gallium/drivers/zink/zink_blit.c +++ b/src/gallium/drivers/zink/zink_blit.c @@ -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; diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index e45eb85..631b2fd 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -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); diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp index 6ee08a4..e34ac4c 100644 --- a/src/gallium/drivers/zink/zink_draw.cpp +++ b/src/gallium/drivers/zink/zink_draw.cpp @@ -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 */ diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c index cbe77ad..c69484c 100644 --- a/src/gallium/drivers/zink/zink_state.c +++ b/src/gallium/drivers/zink/zink_state.c @@ -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; diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index ddf67d2..94850d8 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -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; -- 2.7.4