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