[TEST] Line/ conservative rasterization adjustment

This commit is contained in:
CamilleLaVey
2026-07-29 04:28:38 -04:00
parent 7e1fc154c7
commit 6cb9e3a9da
7 changed files with 63 additions and 27 deletions
@@ -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);
@@ -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;
@@ -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,
@@ -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 =
@@ -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);
@@ -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);
@@ -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;
}