kk: Rework command buffers' graphics shader state tracking

Signed-off-by: Aitor Camacho <aitor@lunarg.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40763>
This commit is contained in:
Aitor Camacho 2026-04-01 19:28:19 +09:00 committed by Marge Bot
parent 2952ae2861
commit fa240cec0b
4 changed files with 28 additions and 16 deletions

View file

@ -97,19 +97,14 @@ struct kk_rendering_state {
* shaders_dirty.
*/
enum kk_dirty {
KK_DIRTY_INDEX = BITFIELD_BIT(0),
KK_DIRTY_VB = BITFIELD_BIT(1),
KK_DIRTY_OCCLUSION = BITFIELD_BIT(2),
KK_DIRTY_PROVOKING = BITFIELD_BIT(3),
KK_DIRTY_VARYINGS = BITFIELD_BIT(4),
KK_DIRTY_PIPELINE = BITFIELD_BIT(5),
KK_DIRTY_VB = BITFIELD_BIT(0),
KK_DIRTY_OCCLUSION = BITFIELD_BIT(1),
};
struct kk_graphics_state {
struct kk_rendering_state render;
struct kk_descriptor_state descriptors;
mtl_render_pipeline_state *pipeline_state;
mtl_depth_stencil_state *depth_stencil_state;
mtl_render_pass_descriptor *render_pass_descriptor;
bool is_depth_stencil_dynamic;
@ -168,6 +163,7 @@ struct kk_cmd_buffer {
struct kk_graphics_state gfx;
struct kk_compute_state cs;
struct kk_shader *shaders[MESA_SHADER_STAGES];
/* Only tracks graphics shaders since compute is always bound for now. */
uint32_t dirty_shaders;
} state;
@ -213,6 +209,7 @@ kk_cmd_buffer_dirty_all_gfx(struct kk_cmd_buffer *cmd)
{
/* Ensure we flush all graphics state */
vk_dynamic_graphics_state_dirty_all(&cmd->vk.dynamic_graphics_state);
cmd->state.dirty_shaders = ~0u;
cmd->state.gfx.dirty = ~0u;
cmd->state.gfx.descriptors.root_dirty = true;
}

View file

@ -645,8 +645,11 @@ set_empty_scissor(mtl_render_encoder *enc)
}
static void
kk_flush_draw_state(struct kk_cmd_buffer *cmd)
kk_flush_gfx_state(struct kk_cmd_buffer *cmd)
{
#define IS_SHADER_DIRTY(bit) \
(cmd->state.dirty_shaders & BITFIELD_BIT(MESA_SHADER_##bit))
struct kk_device *device = kk_cmd_buffer_device(cmd);
struct kk_graphics_state *gfx = &cmd->state.gfx;
struct vk_dynamic_graphics_state *dyn = &cmd->vk.dynamic_graphics_state;
@ -778,8 +781,9 @@ kk_flush_draw_state(struct kk_cmd_buffer *cmd)
desc->root_dirty = true;
}
if (gfx->dirty & KK_DIRTY_PIPELINE) {
mtl_render_set_pipeline_state(enc, gfx->pipeline_state);
if (IS_SHADER_DIRTY(VERTEX)) {
mtl_render_set_pipeline_state(
enc, cmd->state.shaders[MESA_SHADER_VERTEX]->pipeline.gfx.handle);
if (gfx->depth_stencil_state)
mtl_set_depth_stencil_state(enc, gfx->depth_stencil_state);
}
@ -800,8 +804,11 @@ kk_flush_draw_state(struct kk_cmd_buffer *cmd)
gfx->occlusion.index * sizeof(uint64_t));
}
cmd->state.dirty_shaders = 0u;
gfx->dirty = 0u;
vk_dynamic_graphics_state_clear_dirty(dyn);
#undef IS_SHADER_DIRTY
}
struct kk_draw_data {
@ -988,7 +995,7 @@ kk_draw(struct kk_cmd_buffer *cmd, struct kk_draw_data data)
if (!data.indirect && (data.count[0] == 0u || data.count[1] == 0u))
return;
kk_flush_draw_state(cmd);
kk_flush_gfx_state(cmd);
/* If the restart bool is set, it means that primitive restart is disabled
* but index type is not uint32_t which requires promoting the type to

View file

@ -100,7 +100,11 @@ kk_meta_begin(struct kk_cmd_buffer *cmd, struct kk_meta_save *save,
save->dynamic = cmd->vk.dynamic_graphics_state;
save->_dynamic_vi = cmd->state.gfx._dynamic_vi;
save->_dynamic_sl = cmd->state.gfx._dynamic_sl;
save->pipeline.gfx.ps = cmd->state.gfx.pipeline_state;
for (uint32_t stage = 0u; stage < MESA_SHADER_COMPUTE; ++stage) {
save->shaders[stage] = cmd->state.shaders[stage];
}
save->pipeline.gfx.ds = cmd->state.gfx.depth_stencil_state;
save->pipeline.gfx.attribs_read = cmd->state.gfx.vb.attribs_read;
save->pipeline.gfx.occlusion = cmd->state.gfx.occlusion.mode;
@ -158,14 +162,17 @@ kk_meta_end(struct kk_cmd_buffer *cmd, struct kk_meta_save *save,
cmd->vk.dynamic_graphics_state.set,
sizeof(cmd->vk.dynamic_graphics_state.set));
for (uint32_t stage = 0u; stage < MESA_SHADER_COMPUTE; ++stage) {
cmd->state.shaders[stage] = save->shaders[stage];
}
cmd->state.dirty_shaders |= BITFIELD_MASK(MESA_SHADER_COMPUTE);
if (cmd->state.gfx.is_depth_stencil_dynamic)
mtl_release(cmd->state.gfx.depth_stencil_state);
cmd->state.gfx.pipeline_state = save->pipeline.gfx.ps;
cmd->state.gfx.depth_stencil_state = save->pipeline.gfx.ds;
cmd->state.gfx.vb.attribs_read = save->pipeline.gfx.attribs_read;
cmd->state.gfx.is_depth_stencil_dynamic =
save->pipeline.gfx.is_ds_dynamic;
cmd->state.gfx.dirty |= KK_DIRTY_PIPELINE;
cmd->state.gfx.vb.addr_range[0] = save->vb0;
cmd->state.gfx.vb.handles[0] = save->vb0_handle;

View file

@ -1335,11 +1335,13 @@ kk_cmd_bind_graphics_shader(struct kk_cmd_buffer *cmd,
const mesa_shader_stage stage,
struct kk_shader *shader)
{
cmd->state.shaders[stage] = shader;
cmd->state.dirty_shaders |= BITFIELD_BIT(stage);
/* Relevant pipeline data is only stored in vertex shaders */
if (stage != MESA_SHADER_VERTEX)
return;
cmd->state.gfx.pipeline_state = shader->pipeline.gfx.handle;
cmd->state.gfx.vb.attribs_read = shader->info.vs.attribs_read;
bool requires_dynamic_depth_stencil =
@ -1358,7 +1360,6 @@ kk_cmd_bind_graphics_shader(struct kk_cmd_buffer *cmd,
cmd->state.gfx.depth_stencil_state =
shader->pipeline.gfx.mtl_depth_stencil_state_handle;
cmd->state.gfx.is_depth_stencil_dynamic = requires_dynamic_depth_stencil;
cmd->state.gfx.dirty |= KK_DIRTY_PIPELINE;
cmd->state.gfx.dirty |= KK_DIRTY_VB;
cmd->state.gfx.sample_count = shader->info.vs.sample_count;