diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 587e03e12b3..6c915daac07 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -27,6 +27,21 @@ #include "vk_common_entrypoints.h" #include "vk_util.h" +float +v3dv_get_aa_line_width(struct v3dv_pipeline *pipeline, + struct v3dv_cmd_buffer *buffer) +{ + float width = buffer->state.dynamic.line_width; + + /* If line smoothing is enabled then we want to add some extra pixels to + * the width in order to have some semi-transparent edges. + */ + if (pipeline->line_smooth) + width = floorf(M_SQRT2 * width) + 3; + + return width; +} + void v3dv_job_add_bo(struct v3dv_job *job, struct v3dv_bo *bo) { diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index f622e4aa0a0..1ab1e9ffaa8 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -394,7 +394,7 @@ get_features(const struct v3dv_physical_device *physical_device, /* VK_EXT_line_rasterization */ .rectangularLines = true, .bresenhamLines = true, - .smoothLines = false, + .smoothLines = true, .stippledRectangularLines = false, .stippledBresenhamLines = false, .stippledSmoothLines = false, diff --git a/src/broadcom/vulkan/v3dv_pipeline.c b/src/broadcom/vulkan/v3dv_pipeline.c index 7bf4326125a..3c57ee2d7c4 100644 --- a/src/broadcom/vulkan/v3dv_pipeline.c +++ b/src/broadcom/vulkan/v3dv_pipeline.c @@ -1095,6 +1095,32 @@ static const enum pipe_logicop vk_to_pipe_logicop[] = { [VK_LOGIC_OP_SET] = PIPE_LOGICOP_SET, }; +static bool +enable_line_smooth(uint8_t topology, + const VkPipelineRasterizationStateCreateInfo *rs_info) +{ + if (!rs_info || rs_info->rasterizerDiscardEnable) + return false; + + const VkPipelineRasterizationLineStateCreateInfoKHR *ls_info = + vk_find_struct_const(rs_info->pNext, + PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_KHR); + + if (!ls_info) + return false; + + switch(topology) { + case MESA_PRIM_LINES: + case MESA_PRIM_LINE_LOOP: + case MESA_PRIM_LINE_STRIP: + case MESA_PRIM_LINES_ADJACENCY: + case MESA_PRIM_LINE_STRIP_ADJACENCY: + return ls_info->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_KHR; + default: + return false; + } +} + static void pipeline_populate_v3d_fs_key(struct v3d_fs_key *key, const VkGraphicsPipelineCreateInfo *pCreateInfo, @@ -1159,6 +1185,8 @@ pipeline_populate_v3d_fs_key(struct v3d_fs_key *key, key->sample_alpha_to_one = ms_info->alphaToOneEnable; } + key->line_smoothing = enable_line_smooth(topology, pCreateInfo->pRasterizationState); + /* This is intended for V3D versions before 4.1, otherwise we just use the * tile buffer load/store swap R/B bit. */ @@ -1950,6 +1978,8 @@ pipeline_populate_graphics_key(struct v3dv_pipeline *pipeline, memset(key, 0, sizeof(*key)); + key->line_smooth = pipeline->line_smooth; + const bool raster_enabled = pCreateInfo->pRasterizationState && !pCreateInfo->pRasterizationState->rasterizerDiscardEnable; @@ -2950,6 +2980,7 @@ pipeline_init(struct v3dv_pipeline *pipeline, pipeline_set_sample_mask(pipeline, ms_info); pipeline_set_sample_rate_shading(pipeline, ms_info); + pipeline->line_smooth = enable_line_smooth(pipeline->topology, rs_info); pipeline->primitive_restart = pCreateInfo->pInputAssemblyState->primitiveRestartEnable; diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index a1c14abc449..d37aacf5bda 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -339,6 +339,7 @@ struct v3dv_pipeline_key { uint8_t f32_color_rb; uint32_t va_swap_rb_mask; bool has_multiview; + bool line_smooth; }; struct v3dv_pipeline_cache_stats { @@ -2297,6 +2298,8 @@ struct v3dv_pipeline { enum mesa_prim topology; + bool line_smooth; + struct v3dv_pipeline_shared_data *shared_data; /* It is the combined stages sha1, layout sha1, plus the pipeline key sha1. */ @@ -2680,6 +2683,10 @@ v3dv_update_image_layout(struct v3dv_device *device, bool disjoint, const VkImageDrmFormatModifierExplicitCreateInfoEXT *explicit_mod_info); +float +v3dv_get_aa_line_width(struct v3dv_pipeline *pipeline, + struct v3dv_cmd_buffer *buffer); + #if DETECT_OS_ANDROID VkResult v3dv_gralloc_to_drm_explicit_layout(struct u_gralloc *gralloc, diff --git a/src/broadcom/vulkan/v3dv_uniforms.c b/src/broadcom/vulkan/v3dv_uniforms.c index 9bf36eadf5e..018c471fe30 100644 --- a/src/broadcom/vulkan/v3dv_uniforms.c +++ b/src/broadcom/vulkan/v3dv_uniforms.c @@ -661,6 +661,15 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer, cl_aligned_u32(&uniforms, job->cmd_buffer->state.draw_id); break; + case QUNIFORM_LINE_WIDTH: + cl_aligned_u32(&uniforms, job->cmd_buffer->state.dynamic.line_width); + break; + + case QUNIFORM_AA_LINE_WIDTH: + cl_aligned_u32(&uniforms, + v3dv_get_aa_line_width(pipeline, job->cmd_buffer)); + break; + default: unreachable("unsupported quniform_contents uniform type\n"); } diff --git a/src/broadcom/vulkan/v3dvx_cmd_buffer.c b/src/broadcom/vulkan/v3dvx_cmd_buffer.c index 6862a6e4766..7ce6a41a3d1 100644 --- a/src/broadcom/vulkan/v3dvx_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dvx_cmd_buffer.c @@ -1551,7 +1551,8 @@ v3dX(cmd_buffer_emit_line_width)(struct v3dv_cmd_buffer *cmd_buffer) v3dv_return_if_oom(cmd_buffer, NULL); cl_emit(&job->bcl, LINE_WIDTH, line) { - line.line_width = cmd_buffer->state.dynamic.line_width; + line.line_width = v3dv_get_aa_line_width(cmd_buffer->state.gfx.pipeline, + cmd_buffer); } cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_LINE_WIDTH;