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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23758>
This commit is contained in:
Mike Blumenkrantz 2023-06-08 16:24:27 -04:00 committed by Marge Bot
parent 5dc2d329cb
commit 7b4c1b3a42
5 changed files with 140 additions and 21 deletions

View 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;

View 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);

View 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 */

View 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;

View 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;