diff --git a/docs/features.txt b/docs/features.txt index d5590a6fea8..8725f672ed4 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -522,7 +522,7 @@ Vulkan 1.4 -- all DONE: anv, hk, lvp, nvk, panvk/v10+, radv/gfx8+, tu/a7xx+, vn VK_KHR_dynamic_rendering_local_read DONE (anv, lvp, nvk, panvk, radv, tu, vn) VK_KHR_global_priority DONE (anv, kk, lvp, nvk, panvk, radv, tu, vn) VK_KHR_index_type_uint8 DONE (anv, kk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn) - VK_KHR_line_rasterization DONE (anv, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn) + VK_KHR_line_rasterization DONE (anv, kk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn) VK_KHR_load_store_op_none DONE (anv, kk, lvp, nvk, panvk, radv, tu, v3dv, vn) VK_KHR_maintenance5 DONE (anv, hasvk, lvp, nvk, panvk/v10+, radv, tu, v3dv, vn) VK_KHR_maintenance6 DONE (anv, hasvk, lvp, nvk, panvk/v10+, radv, tu, vn) @@ -656,7 +656,7 @@ Khronos extensions that are not part of any Vulkan version: VK_EXT_index_type_uint8 DONE (anv, hasvk, hk, kk, nvk, lvp, panvk, pvr, radv/gfx8+, tu, v3dv, vn) VK_EXT_legacy_dithering DONE (anv, panvk, tu, vn) VK_EXT_legacy_vertex_attributes DONE (anv, lvp, nvk, radv, tu, vn) - VK_EXT_line_rasterization DONE (anv, hasvk, hk, nvk, panvk, pvr, lvp, radv, tu, v3dv, vn) + VK_EXT_line_rasterization DONE (anv, hasvk, hk, kk, nvk, panvk, pvr, lvp, radv, tu, v3dv, vn) VK_EXT_load_store_op_none DONE (anv, hk, kk, lvp, nvk, panvk, radv, tu, v3dv, vn) VK_EXT_map_memory_placed DONE (anv, hk, nvk, panvk, pvr, radv, tu, vn) VK_EXT_memory_budget DONE (anv, hasvk, lvp, nvk, panvk, radv, tu, v3dv, vn) diff --git a/src/kosmickrisp/bridge/mtl_render_state.h b/src/kosmickrisp/bridge/mtl_render_state.h index cf13b4678f8..f5416e0f620 100644 --- a/src/kosmickrisp/bridge/mtl_render_state.h +++ b/src/kosmickrisp/bridge/mtl_render_state.h @@ -73,6 +73,11 @@ void mtl_render_pass_descriptor_set_render_target_height( void mtl_render_pass_descriptor_set_default_raster_sample_count( mtl_render_pass_descriptor *descriptor, uint32_t sample_count); +void mtl_render_pass_descriptor_set_sample_positions( + mtl_render_pass_descriptor *descriptor, + const struct mtl_sample_position *positions, + uint32_t count); + void mtl_render_pass_descriptor_set_visibility_buffer( mtl_render_pass_descriptor *descriptor, mtl_buffer *visibility_buffer); diff --git a/src/kosmickrisp/bridge/mtl_render_state.m b/src/kosmickrisp/bridge/mtl_render_state.m index 0a5051c286a..afb9377e7e8 100644 --- a/src/kosmickrisp/bridge/mtl_render_state.m +++ b/src/kosmickrisp/bridge/mtl_render_state.m @@ -181,6 +181,26 @@ mtl_render_pass_descriptor_set_default_raster_sample_count(mtl_render_pass_descr } } +void +mtl_render_pass_descriptor_set_sample_positions( + mtl_render_pass_descriptor *descriptor, + const struct mtl_sample_position *positions, + uint32_t count) +{ + @autoreleasepool { + MTLRenderPassDescriptor *desc = (MTLRenderPassDescriptor *)descriptor; + if (count > 0) { + MTLSamplePosition pos[count]; + for (uint32_t i = 0; i < count; i++) { + pos[i] = MTLSamplePositionMake(positions[i].x, positions[i].y); + } + [desc setSamplePositions:pos count:count]; + } else { + [desc setSamplePositions:NULL count:count]; + } + } +} + void mtl_render_pass_descriptor_set_visibility_buffer(mtl_render_pass_descriptor *descriptor, mtl_buffer *visibility_buffer) diff --git a/src/kosmickrisp/bridge/mtl_types.h b/src/kosmickrisp/bridge/mtl_types.h index 04495865c1c..600cb0db992 100644 --- a/src/kosmickrisp/bridge/mtl_types.h +++ b/src/kosmickrisp/bridge/mtl_types.h @@ -234,6 +234,10 @@ struct mtl_size { size_t x, y, z; }; +struct mtl_sample_position { + float x, y; +}; + struct mtl_viewport { double originX, originY, width, height, znear, zfar; }; diff --git a/src/kosmickrisp/bridge/stubs/mtl_render_state.c b/src/kosmickrisp/bridge/stubs/mtl_render_state.c index e971c5e460f..baf5d836499 100644 --- a/src/kosmickrisp/bridge/stubs/mtl_render_state.c +++ b/src/kosmickrisp/bridge/stubs/mtl_render_state.c @@ -114,6 +114,14 @@ mtl_render_pass_descriptor_set_default_raster_sample_count( { } +void +mtl_render_pass_descriptor_set_sample_positions( + mtl_render_pass_descriptor *descriptor, + const struct mtl_sample_position *positions, + uint32_t count) +{ +} + void mtl_render_pass_descriptor_set_visibility_buffer( mtl_render_pass_descriptor *descriptor, mtl_buffer *visibility_buffer) diff --git a/src/kosmickrisp/vulkan/kk_cmd_buffer.h b/src/kosmickrisp/vulkan/kk_cmd_buffer.h index 82b93cc1bcd..c66cc07de31 100644 --- a/src/kosmickrisp/vulkan/kk_cmd_buffer.h +++ b/src/kosmickrisp/vulkan/kk_cmd_buffer.h @@ -119,10 +119,11 @@ struct kk_graphics_state { mtl_render_pass_descriptor *render_pass_descriptor; bool is_depth_stencil_dynamic; bool is_cull_front_and_back; + bool is_ms_bresenham_lines; bool need_to_start_render_pass; enum kk_dirty dirty; - uint32_t sample_count; + uint32_t pipeline_sample_count; struct { enum mtl_visibility_result_mode mode; diff --git a/src/kosmickrisp/vulkan/kk_encoder.c b/src/kosmickrisp/vulkan/kk_encoder.c index edcd4a09e81..a9335dda061 100644 --- a/src/kosmickrisp/vulkan/kk_encoder.c +++ b/src/kosmickrisp/vulkan/kk_encoder.c @@ -274,19 +274,78 @@ kk_encoder_submit(struct kk_encoder *encoder) mtl_command_buffer_commit(encoder->main.cmd_buffer); } +static bool +kk_try_configure_line_ms(struct kk_cmd_buffer *cmd) +{ + struct kk_graphics_state *gfx = &cmd->state.gfx; + struct vk_dynamic_graphics_state *dyn = &cmd->vk.dynamic_graphics_state; + + bool was_ms_bresenham_lines = cmd->state.gfx.is_ms_bresenham_lines; + gfx->is_ms_bresenham_lines = + u_reduced_prim(dyn->ia.primitive_topology) == MESA_PRIM_LINES && + dyn->rs.line.mode == VK_LINE_RASTERIZATION_MODE_BRESENHAM && + gfx->render.samples > 1; + + if (was_ms_bresenham_lines != gfx->is_ms_bresenham_lines) { + if (gfx->is_ms_bresenham_lines) { + /* Set all sample positions to center for bresenham lines */ + static const struct mtl_sample_position center = + {0.5f, 0.5f}; + static const struct mtl_sample_position center_all[8] = { + center, center, center, center, center, center, center, center + }; + mtl_render_pass_descriptor_set_sample_positions( + gfx->render_pass_descriptor, center_all, gfx->render.samples); + } else { + /* Disable sample positions */ + mtl_render_pass_descriptor_set_sample_positions( + gfx->render_pass_descriptor, NULL, 0); + } + + return true; + } + + return false; +} + +static bool +kk_flush_render_pass(struct kk_cmd_buffer *cmd) +{ + struct kk_encoder *encoder = cmd->encoder; + + bool needs_restart = kk_try_configure_line_ms(cmd); + if (needs_restart && encoder->main.last_used == KK_ENC_RENDER && + encoder->main.encoder) { + kk_encoder_signal_fence_and_end(cmd); + kk_cmd_buffer_dirty_all_gfx(cmd); + } + + return needs_restart; +} + 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; + + bool start_render_pass = false; if (gfx->need_to_start_render_pass) { + gfx->render.samples = gfx->pipeline_sample_count; mtl_render_pass_descriptor_set_default_raster_sample_count( - cmd->state.gfx.render_pass_descriptor, gfx->sample_count); + cmd->state.gfx.render_pass_descriptor, gfx->render.samples); gfx->need_to_start_render_pass = false; + start_render_pass = true; + } + + start_render_pass |= kk_flush_render_pass(cmd); + + if (start_render_pass) { 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_physical_device.c b/src/kosmickrisp/vulkan/kk_physical_device.c index adc0c9d449b..07af93abcc3 100644 --- a/src/kosmickrisp/vulkan/kk_physical_device.c +++ b/src/kosmickrisp/vulkan/kk_physical_device.c @@ -116,6 +116,7 @@ kk_get_device_extensions(const struct kk_instance *instance, /* Vulkan 1.4 */ .KHR_global_priority = true, + .KHR_line_rasterization = true, .KHR_index_type_uint8 = true, .KHR_load_store_op_none = true, .KHR_map_memory2 = true, @@ -126,6 +127,7 @@ kk_get_device_extensions(const struct kk_instance *instance, .EXT_global_priority = true, .EXT_global_priority_query = true, .EXT_index_type_uint8 = true, + .EXT_line_rasterization = true, .EXT_pipeline_robustness = true, .EXT_vertex_attribute_divisor = true, @@ -289,6 +291,7 @@ kk_get_device_features( .vulkanMemoryModelDeviceScope = true, /* Vulkan 1.4 */ + .bresenhamLines = true, .globalPriorityQuery = true, .indexTypeUint8 = true, .pipelineRobustness = true, @@ -331,6 +334,7 @@ kk_get_device_features( /* VK_EXT_extended_dynamic_state3 */ .extendedDynamicState3DepthClampEnable = true, .extendedDynamicState3DepthClipNegativeOneToOne = true, + .extendedDynamicState3LineRasterizationMode = true, /* EXT_image_2d_view_of_3d */ .image2DViewOf3D = true, diff --git a/src/kosmickrisp/vulkan/kk_shader.c b/src/kosmickrisp/vulkan/kk_shader.c index 98b824a5ccf..91bada8acd9 100644 --- a/src/kosmickrisp/vulkan/kk_shader.c +++ b/src/kosmickrisp/vulkan/kk_shader.c @@ -1377,7 +1377,7 @@ 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_VB; - cmd->state.gfx.sample_count = shader->info.vs.sample_count; + cmd->state.gfx.pipeline_sample_count = shader->info.vs.sample_count; } static void