diff --git a/src/kosmickrisp/vulkan/kk_cmd_buffer.h b/src/kosmickrisp/vulkan/kk_cmd_buffer.h index ed50ec70e09..904dd750ecd 100644 --- a/src/kosmickrisp/vulkan/kk_cmd_buffer.h +++ b/src/kosmickrisp/vulkan/kk_cmd_buffer.h @@ -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; } diff --git a/src/kosmickrisp/vulkan/kk_cmd_draw.c b/src/kosmickrisp/vulkan/kk_cmd_draw.c index a1683de63a6..24a5e8619e6 100644 --- a/src/kosmickrisp/vulkan/kk_cmd_draw.c +++ b/src/kosmickrisp/vulkan/kk_cmd_draw.c @@ -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 diff --git a/src/kosmickrisp/vulkan/kk_cmd_meta.c b/src/kosmickrisp/vulkan/kk_cmd_meta.c index 3d571be7e57..fd6bd19b4a1 100644 --- a/src/kosmickrisp/vulkan/kk_cmd_meta.c +++ b/src/kosmickrisp/vulkan/kk_cmd_meta.c @@ -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; diff --git a/src/kosmickrisp/vulkan/kk_shader.c b/src/kosmickrisp/vulkan/kk_shader.c index 8400a3f9e0d..d85dfcdad2e 100644 --- a/src/kosmickrisp/vulkan/kk_shader.c +++ b/src/kosmickrisp/vulkan/kk_shader.c @@ -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;