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; bool in_rp = ctx->batch.in_rp;
uint64_t tc_data = ctx->dynamic_fb.tc_info.data; uint64_t tc_data = ctx->dynamic_fb.tc_info.data;
bool queries_disabled = ctx->queries_disabled; bool queries_disabled = ctx->queries_disabled;
unsigned ds3_states = ctx->ds3_states;
if (ctx->unordered_blitting) { if (ctx->unordered_blitting) {
/* for unordered blit, swap the unordered cmdbuf for the main one for the whole op to avoid conditional hell */ /* 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; ctx->batch.state->cmdbuf = ctx->batch.state->barrier_cmdbuf;
@ -415,6 +416,15 @@ zink_blit(struct pipe_context *pctx,
ctx->queries_disabled = true; ctx->queries_disabled = true;
ctx->batch.state->has_barriers = true; ctx->batch.state->has_barriers = true;
ctx->pipeline_changed[0] = 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_select_draw_vbo(ctx);
} }
zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | ZINK_BLIT_SAVE_TEXTURES); 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->batch.state->cmdbuf = cmdbuf;
ctx->gfx_pipeline_state.pipeline = pipeline; ctx->gfx_pipeline_state.pipeline = pipeline;
ctx->pipeline_changed[0] = true; ctx->pipeline_changed[0] = true;
ctx->ds3_states = ds3_states;
zink_select_draw_vbo(ctx); zink_select_draw_vbo(ctx);
} }
ctx->unordered_blitting = false; 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) { if (ctx->batch.state->is_device_lost) {
check_device_lost(ctx); check_device_lost(ctx);
} else { } else {
struct zink_screen *screen = zink_screen(ctx->base.screen);
zink_start_batch(ctx, batch); 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->dirty_so_targets = true;
ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true; ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true;
zink_select_draw_vbo(ctx); zink_select_draw_vbo(ctx);
@ -3219,6 +3220,14 @@ flush_batch(struct zink_context *ctx, bool sync)
if (ctx->oom_stall) if (ctx->oom_stall)
stall(ctx); 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_flush = false;
ctx->oom_stall = false; ctx->oom_stall = false;
ctx->dd.bindless_bound = 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 */ /* 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.nr_cbufs != state->nr_cbufs;
ctx->rp_changed |= !!ctx->fb_state.zsbuf != !!state->zsbuf; 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; 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); util_copy_framebuffer_state(&ctx->fb_state, state);
zink_update_fbfetch(ctx); 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(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); 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) { if (DYNAMIC_STATE >= ZINK_DYNAMIC_STATE3) {
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); 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); 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); 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); VKCTX(CmdSetDepthClipNegativeOneToOneEXT)(batch->state->cmdbuf, !rast_state->hw_state.clip_halfz);
VKCTX(CmdSetProvokingVertexModeEXT)(batch->state->cmdbuf, rast_state->hw_state.pv_last ? 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_LAST_VERTEX_EXT :
VK_PROVOKING_VERTEX_MODE_FIRST_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); 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_ON))
VKCTX(CmdSetLineStippleEnableEXT)(batch->state->cmdbuf, rast_state->hw_state.line_stipple_enable); 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); VKCTX(CmdSetSampleMaskEXT)(batch->state->cmdbuf, (VkSampleCountFlagBits)(ctx->gfx_pipeline_state.rast_samples + 1), &ctx->gfx_pipeline_state.sample_mask);
ctx->sample_mask_changed = false; 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) { if (ctx->gfx_pipeline_state.blend_state) {
if (ctx->ds3_states & BITFIELD_BIT(ZINK_DS3_BLEND_A2C))
VKCTX(CmdSetAlphaToCoverageEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_coverage); 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_A21))
VKCTX(CmdSetAlphaToOneEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_one); VKCTX(CmdSetAlphaToOneEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_one);
if (ctx->fb_state.nr_cbufs) { if (ctx->fb_state.nr_cbufs) {
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); 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); 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(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_LOGIC_ON))
VKCTX(CmdSetLogicOpEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_enable); 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); VKCTX(CmdSetLogicOpEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_func);
} }
} }
ctx->ds3_states = 0;
if (BATCH_CHANGED || if (BATCH_CHANGED ||
/* only re-emit on non-batch change when actually drawing lines */ /* 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_coverage = blend_state->alpha_to_coverage;
cso->alpha_to_one = blend_state->alpha_to_one; 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) { for (int i = 0; i < blend_state->max_rt + 1; ++i) {
const struct pipe_rt_blend_state *rt = blend_state->rt; 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) if (rt->colormask & PIPE_MASK_A)
att.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT; 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->attachments[i] = att;
cso->ds3.enables[i] = att.blendEnable; 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; struct zink_gfx_pipeline_state* state = &zink_context(pctx)->gfx_pipeline_state;
zink_flush_dgc_if_enabled(ctx); zink_flush_dgc_if_enabled(ctx);
struct zink_blend_state *blend = cso; struct zink_blend_state *blend = cso;
struct zink_blend_state *old_blend = state->blend_state;
if (state->blend_state != cso) { if (state->blend_state != cso) {
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) 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; zink_set_fs_base_key(ctx)->force_dual_color_blend = force_dual_color_blend;
ctx->blend_state_changed = true; 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_context *ctx = zink_context(pctx);
struct zink_screen *screen = zink_screen(pctx->screen); 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 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 scissor = ctx->rast_state ? ctx->rast_state->base.scissor : false;
bool pv_last = ctx->rast_state ? ctx->rast_state->hw_state.pv_last : 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; 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) if (fabs(ctx->rast_state->base.line_width - line_width) > FLT_EPSILON)
ctx->line_width_changed = true; ctx->line_width_changed = true;

View file

@ -352,6 +352,7 @@ struct zink_rasterizer_state {
struct zink_blend_state { struct zink_blend_state {
uint32_t hash; uint32_t hash;
unsigned num_rts;
VkPipelineColorBlendAttachmentState attachments[PIPE_MAX_COLOR_BUFS]; VkPipelineColorBlendAttachmentState attachments[PIPE_MAX_COLOR_BUFS];
struct { struct {
@ -366,6 +367,9 @@ struct zink_blend_state {
VkBool32 alpha_to_coverage; VkBool32 alpha_to_coverage;
VkBool32 alpha_to_one; VkBool32 alpha_to_one;
uint32_t wrmask;
uint8_t enables;
bool dual_src_blend; bool dual_src_blend;
}; };
@ -1722,6 +1726,25 @@ typedef void (*pipe_draw_vertex_state_func)(struct pipe_context *ctx,
unsigned num_draws); unsigned num_draws);
typedef void (*pipe_launch_grid_func)(struct pipe_context *pipe, const struct pipe_grid_info *info); 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 zink_context {
struct pipe_context base; struct pipe_context base;
struct threaded_context *tc; struct threaded_context *tc;
@ -1953,6 +1976,8 @@ struct zink_context {
uint8_t barrier_set_idx[2]; uint8_t barrier_set_idx[2];
unsigned memory_barrier; unsigned memory_barrier;
uint32_t ds3_states;
uint32_t num_so_targets; uint32_t num_so_targets;
struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_OUTPUTS]; struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_OUTPUTS];
bool dirty_so_targets; bool dirty_so_targets;