From 317a2492054c762606ec9d2ff699fb69b0d2e75c Mon Sep 17 00:00:00 2001 From: Aitor Camacho Date: Tue, 16 Dec 2025 02:31:12 +0900 Subject: [PATCH] kk: Attachmentless render passes start postponed to pipeline bind Sample count is only known at pipeline bind not when the render pass is started since there is no attachments to infer sample count. Acked-by: Arcady Goldmints-Orlov Signed-off-by: Aitor Camacho Part-of: --- src/kosmickrisp/vulkan/kk_cmd_buffer.h | 2 ++ src/kosmickrisp/vulkan/kk_cmd_draw.c | 17 ++++++++++++----- src/kosmickrisp/vulkan/kk_encoder.c | 9 +++++++++ src/kosmickrisp/vulkan/kk_shader.c | 5 +++++ src/kosmickrisp/vulkan/kk_shader.h | 1 + 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/kosmickrisp/vulkan/kk_cmd_buffer.h b/src/kosmickrisp/vulkan/kk_cmd_buffer.h index 6ee834dee79..ed81ac4013a 100644 --- a/src/kosmickrisp/vulkan/kk_cmd_buffer.h +++ b/src/kosmickrisp/vulkan/kk_cmd_buffer.h @@ -115,10 +115,12 @@ struct kk_graphics_state { bool is_depth_stencil_dynamic; bool is_cull_front_and_back; bool restart_disabled; + bool need_to_start_render_pass; enum mtl_primitive_type primitive_type; enum mesa_prim prim; enum kk_dirty dirty; + uint32_t sample_count; struct { enum mtl_visibility_result_mode mode; diff --git a/src/kosmickrisp/vulkan/kk_cmd_draw.c b/src/kosmickrisp/vulkan/kk_cmd_draw.c index 3acfc90c444..fdb37887539 100644 --- a/src/kosmickrisp/vulkan/kk_cmd_draw.c +++ b/src/kosmickrisp/vulkan/kk_cmd_draw.c @@ -229,8 +229,13 @@ kk_CmdBeginRendering(VkCommandBuffer commandBuffer, mtl_new_render_pass_descriptor(); /* Framebufferless rendering, need to set pass_descriptors - * renderTargetWidth/Height to non-0 values and defaultRasterSampleCount */ - if (framebuffer_extent.width == 0u && framebuffer_extent.height == 0u) { + * renderTargetWidth/Height to non-0 values and defaultRasterSampleCount. + * However, since the sample count will only be known at first pipeline bind, + * we need to delay the start of the pass until then since Metal will ignore + * bound pipeline's sample count. */ + bool no_framebuffer = + framebuffer_extent.width == 0u && framebuffer_extent.height == 0u; + if (no_framebuffer) { framebuffer_extent.width = render->area.extent.width; framebuffer_extent.height = render->area.extent.height; mtl_render_pass_descriptor_set_render_target_width( @@ -345,9 +350,10 @@ kk_CmdBeginRendering(VkCommandBuffer commandBuffer, // TODO_KOSMICKRISP Fragment shading rate support goes here if Metal supports // it - /* Start new encoder and encode sync commands from previous barriers (aka - * fences) */ - kk_encoder_start_render(cmd, pass_descriptor, render->view_mask); + /* Rendering with no attachments requires pushing the start of the render + * pass to first pipeline binding to know sample count. */ + if (!no_framebuffer) + kk_encoder_start_render(cmd, pass_descriptor, render->view_mask); /* Store descriptor in case we need to restart the pass at pipeline barrier, * but force loads */ @@ -373,6 +379,7 @@ kk_CmdBeginRendering(VkCommandBuffer commandBuffer, attachment_descriptor, MTL_LOAD_ACTION_LOAD); } cmd->state.gfx.render_pass_descriptor = pass_descriptor; + cmd->state.gfx.need_to_start_render_pass = no_framebuffer; kk_cmd_buffer_dirty_all_gfx(cmd); diff --git a/src/kosmickrisp/vulkan/kk_encoder.c b/src/kosmickrisp/vulkan/kk_encoder.c index eeb91c561c5..2790e33ec80 100644 --- a/src/kosmickrisp/vulkan/kk_encoder.c +++ b/src/kosmickrisp/vulkan/kk_encoder.c @@ -270,6 +270,15 @@ mtl_render_encoder * kk_render_encoder(struct kk_cmd_buffer *cmd) { struct kk_encoder *encoder = cmd->encoder; + + struct kk_graphics_state *gfx = &cmd->state.gfx; + if (gfx->need_to_start_render_pass) { + mtl_render_pass_descriptor_set_default_raster_sample_count( + cmd->state.gfx.render_pass_descriptor, gfx->sample_count); + gfx->need_to_start_render_pass = false; + kk_encoder_start_render(cmd, gfx->render_pass_descriptor, + gfx->render.view_mask); + } /* Render encoders are created at vkBeginRendering only */ assert(encoder->main.last_used == KK_ENC_RENDER && encoder->main.encoder); return (mtl_render_encoder *)encoder->main.encoder; diff --git a/src/kosmickrisp/vulkan/kk_shader.c b/src/kosmickrisp/vulkan/kk_shader.c index 1dabf5cc605..2e2d845cf50 100644 --- a/src/kosmickrisp/vulkan/kk_shader.c +++ b/src/kosmickrisp/vulkan/kk_shader.c @@ -953,6 +953,7 @@ kk_compile_graphics_pipeline(struct kk_device *device, pipeline_descriptor, max_amplification); } + vertex_shader->pipeline.gfx.sample_count = 1u; if (state->ms) { mtl_render_pipeline_descriptor_set_raster_sample_count( pipeline_descriptor, state->ms->rasterization_samples); @@ -960,6 +961,8 @@ kk_compile_graphics_pipeline(struct kk_device *device, pipeline_descriptor, state->ms->alpha_to_coverage_enable); mtl_render_pipeline_descriptor_set_alpha_to_one( pipeline_descriptor, state->ms->alpha_to_one_enable); + vertex_shader->pipeline.gfx.sample_count = + state->ms->rasterization_samples; } vertex_shader->pipeline.gfx.handle = @@ -1216,6 +1219,8 @@ kk_cmd_bind_graphics_shader(struct kk_cmd_buffer *cmd, 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->pipeline.gfx.sample_count; } static void diff --git a/src/kosmickrisp/vulkan/kk_shader.h b/src/kosmickrisp/vulkan/kk_shader.h index 6015d81815b..207bab524a7 100644 --- a/src/kosmickrisp/vulkan/kk_shader.h +++ b/src/kosmickrisp/vulkan/kk_shader.h @@ -42,6 +42,7 @@ struct kk_shader { mtl_render_pipeline_state *handle; mtl_depth_stencil_state *mtl_depth_stencil_state_handle; enum mtl_primitive_type primitive_type; + uint32_t sample_count; } gfx; mtl_compute_pipeline_state *cs; };