From 6cb9e3a9da9af2b636d33b77dcf026550c1341bc Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Wed, 29 Jul 2026 04:28:38 -0400 Subject: [PATCH] [TEST] Line/ conservative rasterization adjustment --- .../renderer_vulkan/fixed_pipeline_state.cpp | 4 +- .../renderer_vulkan/fixed_pipeline_state.h | 1 + .../renderer_vulkan/vk_graphics_pipeline.cpp | 11 ++---- .../renderer_vulkan/vk_pipeline_cache.cpp | 3 ++ .../renderer_vulkan/vk_rasterizer.cpp | 38 ++++++++++--------- .../renderer_vulkan/vk_rasterizer.h | 1 - src/video_core/vulkan_common/vulkan_device.h | 32 ++++++++++++++++ 7 files changed, 63 insertions(+), 27 deletions(-) diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index cc99fc562b..02ee3e1e6e 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp @@ -164,7 +164,9 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe } provoking_vertex_last.Assign(use_last_provoking_vertex ? 1 : 0); - conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0); + if (!features.has_dynamic_state3_conservative_raster_mode) { + conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0); + } smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0); alpha_to_coverage_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_coverage != 0 ? 1 : 0); alpha_to_one_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_one != 0 ? 1 : 0); diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index b3b5c6bc7e..45920042f9 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h @@ -30,6 +30,7 @@ struct DynamicFeatures { bool has_extended_dynamic_state_3_blend; bool has_extended_dynamic_state_3_enables; bool has_dynamic_state3_depth_clamp_enable; + bool has_dynamic_state3_conservative_raster_mode; bool has_depth_clip_enable; bool has_dynamic_state3_logic_op_enable; bool has_dynamic_state3_line_stipple_enable; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 4477cfc2a1..943565f43e 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -757,16 +757,13 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .lineWidth = 1.0f, // TODO(alekpop): Transfer from regs }; - const bool smooth_lines_supported = - device.IsExtLineRasterizationSupported() && device.SupportsSmoothLines(); - const bool stippled_lines_supported = - device.IsExtLineRasterizationSupported() && device.SupportsStippledRectangularLines(); + const VkLineRasterizationModeEXT line_raster_mode = + device.GetLineRasterizationMode(key.state.smooth_lines != 0); + const bool stippled_lines_supported = device.SupportsStippleForMode(line_raster_mode); VkPipelineRasterizationLineStateCreateInfoEXT line_state{ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT, .pNext = nullptr, - .lineRasterizationMode = key.state.smooth_lines != 0 && smooth_lines_supported - ? VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT - : VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, + .lineRasterizationMode = line_raster_mode, .stippledLineEnable = (dynamic.line_stipple_enable && stippled_lines_supported) ? VK_TRUE : VK_FALSE, .lineStippleFactor = key.state.line_stipple_factor, diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index d339a676f0..e765acce34 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -515,6 +515,9 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, dynamic_features.has_dynamic_state3_depth_clamp_enable = dynamic_features.has_extended_dynamic_state_3_enables && device.SupportsDynamicState3DepthClampEnable(); + dynamic_features.has_dynamic_state3_conservative_raster_mode = + dynamic_features.has_extended_dynamic_state_3_enables && + device.SupportsDynamicState3ConservativeRasterizationMode(); dynamic_features.has_depth_clip_enable = device.IsExtDepthClipEnableSupported(); dynamic_features.has_dynamic_state3_logic_op_enable = diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index d78bf6e58e..a988099538 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1470,7 +1470,10 @@ void RasterizerVulkan::UpdateLineWidth(Tegra::Engines::Maxwell3D::Regs& regs) { } const float width = regs.line_anti_alias_enable ? regs.line_width_smooth : regs.line_width_aliased; - scheduler.Record([width](vk::CommandBuffer cmdbuf) { cmdbuf.SetLineWidth(width); }); + const float clamped_width = device.ClampLineWidth(width); + scheduler.Record([clamped_width](vk::CommandBuffer cmdbuf) { + cmdbuf.SetLineWidth(clamped_width); + }); } void RasterizerVulkan::UpdateCullMode(Tegra::Engines::Maxwell3D::Regs& regs) { @@ -1567,7 +1570,10 @@ void RasterizerVulkan::UpdateLineStippleEnable(Tegra::Engines::Maxwell3D::Regs& return; } - scheduler.Record([enable = regs.line_stipple_enable](vk::CommandBuffer cmdbuf) { + const VkLineRasterizationModeEXT mode = + device.GetLineRasterizationMode(regs.line_anti_alias_enable != 0); + const bool enable = regs.line_stipple_enable != 0 && device.SupportsStippleForMode(mode); + scheduler.Record([enable](vk::CommandBuffer cmdbuf) { cmdbuf.SetLineStippleEnableEXT(enable); }); } @@ -1581,28 +1587,24 @@ void RasterizerVulkan::UpdateLineRasterizationMode(Tegra::Engines::Maxwell3D::Re } if (!device.SupportsDynamicState3LineRasterizationMode()) { - static std::once_flag warn_missing_rect; - std::call_once(warn_missing_rect, [] { + static std::once_flag warn_missing_dynamic_state; + std::call_once(warn_missing_dynamic_state, [] { LOG_WARNING(Render_Vulkan, - "Driver lacks rectangular line rasterization support; skipping dynamic " - "line state updates"); + "Driver lacks dynamic line rasterization mode; the pipeline static value " + "is used instead"); }); return; } const bool wants_smooth = regs.line_anti_alias_enable != 0; - VkLineRasterizationModeEXT mode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT; - if (wants_smooth) { - if (device.SupportsSmoothLines()) { - mode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT; - } else { - static std::once_flag warn_missing_smooth; - std::call_once(warn_missing_smooth, [] { - LOG_WARNING(Render_Vulkan, - "Line anti-aliasing requested but smoothLines feature unavailable; " - "using rectangular rasterization"); - }); - } + const VkLineRasterizationModeEXT mode = device.GetLineRasterizationMode(wants_smooth); + if (wants_smooth && mode != VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT) { + static std::once_flag warn_missing_smooth; + std::call_once(warn_missing_smooth, [] { + LOG_WARNING(Render_Vulkan, + "Line anti-aliasing requested but smoothLines feature unavailable; " + "falling back to the closest supported mode"); + }); } scheduler.Record([mode](vk::CommandBuffer cmdbuf) { cmdbuf.SetLineRasterizationModeEXT(mode); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 206bf1043a..9003df44c5 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -179,7 +179,6 @@ private: void UpdateRasterizerDiscardEnable(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateConservativeRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateLineStippleEnable(Tegra::Engines::Maxwell3D::Regs& regs); - void UpdateLineStipple(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateLineRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateLogicOpEnable(Tegra::Engines::Maxwell3D::Regs& regs); diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 54539fb7a1..b73905ad25 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -756,6 +756,38 @@ FN_MAX_LIMIT_LIST return features.line_rasterization.stippledRectangularLines != VK_FALSE; } + VkLineRasterizationModeEXT GetLineRasterizationMode(bool wants_smooth) const { + if (wants_smooth && SupportsSmoothLines()) { + return VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT; + } + if (SupportsRectangularLines()) { + return VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT; + } + return VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT; + } + + bool SupportsStippleForMode(VkLineRasterizationModeEXT mode) const { + switch (mode) { + case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT: + return features.line_rasterization.stippledSmoothLines != VK_FALSE; + case VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT: + return features.line_rasterization.stippledBresenhamLines != VK_FALSE; + default: + return features.line_rasterization.stippledRectangularLines != VK_FALSE; + } + } + + float ClampLineWidth(float width) const { + if (!features.features.wideLines) { + return 1.0f; + } + const auto& range = properties.properties.limits.lineWidthRange; + if (!(width >= range[0])) { + return range[0]; + } + return width > range[1] ? range[1] : width; + } + bool SupportsAlphaToOne() const { return features.features.alphaToOne != VK_FALSE; }