WIP: [vk] Enable line stipple and depth bound reg transfer

It should improve line stipple accuracy and the depth stencilling.

Co-authored-by: crueter <crueter@eden-emu.dev>
Signed-off-by: Aleksandr Popovich <popovich@eden-emu.dev>
This commit is contained in:
Aleksandr Popovich 2025-07-13 21:29:58 -04:00 committed by crueter
parent 2e092010e6
commit ffea122af1
8 changed files with 44 additions and 12 deletions

View file

@ -86,6 +86,12 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
alpha_to_one_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_one != 0 ? 1 : 0); alpha_to_one_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_one != 0 ? 1 : 0);
app_stage.Assign(maxwell3d.engine_state); app_stage.Assign(maxwell3d.engine_state);
depth_bounds_min = static_cast<u32>(regs.depth_bounds[0]);
depth_bounds_max = static_cast<u32>(regs.depth_bounds[1]);
line_stipple_factor = regs.line_stipple_params.factor;
line_stipple_pattern = regs.line_stipple_params.pattern;
for (size_t i = 0; i < regs.rt.size(); ++i) { for (size_t i = 0; i < regs.rt.size(); ++i) {
color_formats[i] = static_cast<u8>(regs.rt[i].format); color_formats[i] = static_cast<u8>(regs.rt[i].format);
} }
@ -258,6 +264,8 @@ void FixedPipelineState::DynamicState::Refresh3(const Maxwell& regs) {
Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ || Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ ||
regs.viewport_clip_control.geometry_clip == regs.viewport_clip_control.geometry_clip ==
Maxwell::ViewportClipControl::GeometryClip::FrustumZ); Maxwell::ViewportClipControl::GeometryClip::FrustumZ);
line_stipple_enable.Assign(regs.line_stipple_enable);
} }
size_t FixedPipelineState::Hash() const noexcept { size_t FixedPipelineState::Hash() const noexcept {

View file

@ -150,6 +150,7 @@ struct FixedPipelineState {
BitField<6, 4, u32> logic_op; BitField<6, 4, u32> logic_op;
BitField<10, 1, u32> logic_op_enable; BitField<10, 1, u32> logic_op_enable;
BitField<11, 1, u32> depth_clamp_disabled; BitField<11, 1, u32> depth_clamp_disabled;
BitField<12, 1, u32> line_stipple_enable;
}; };
union { union {
u32 raw2; u32 raw2;
@ -218,6 +219,7 @@ struct FixedPipelineState {
u32 alpha_test_ref; u32 alpha_test_ref;
u32 point_size; u32 point_size;
std::array<u16, Maxwell::NumViewports> viewport_swizzles; std::array<u16, Maxwell::NumViewports> viewport_swizzles;
union { union {
u64 attribute_types; // Used with VK_EXT_vertex_input_dynamic_state u64 attribute_types; // Used with VK_EXT_vertex_input_dynamic_state
@ -233,6 +235,12 @@ struct FixedPipelineState {
VideoCommon::TransformFeedbackState xfb_state; VideoCommon::TransformFeedbackState xfb_state;
u32 depth_bounds_min;
u32 depth_bounds_max;
u32 line_stipple_factor;
u32 line_stipple_pattern;
void Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFeatures& features); void Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFeatures& features);
size_t Hash() const noexcept; size_t Hash() const noexcept;

View file

@ -701,6 +701,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.depthBiasClamp = 0.0f, .depthBiasClamp = 0.0f,
.depthBiasSlopeFactor = 0.0f, .depthBiasSlopeFactor = 0.0f,
.lineWidth = 1.0f, .lineWidth = 1.0f,
// TODO(alekpop): Transfer from regs
}; };
VkPipelineRasterizationLineStateCreateInfoEXT line_state{ VkPipelineRasterizationLineStateCreateInfoEXT line_state{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT, .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT,
@ -708,9 +709,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.lineRasterizationMode = key.state.smooth_lines != 0 .lineRasterizationMode = key.state.smooth_lines != 0
? VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT ? VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT
: VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, : VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT,
.stippledLineEnable = VK_FALSE, // TODO .stippledLineEnable = dynamic.line_stipple_enable ? VK_TRUE : VK_FALSE,
.lineStippleFactor = 0, .lineStippleFactor = key.state.line_stipple_factor,
.lineStipplePattern = 0, .lineStipplePattern = static_cast<uint16_t>(key.state.line_stipple_pattern),
}; };
VkPipelineRasterizationConservativeStateCreateInfoEXT conservative_raster{ VkPipelineRasterizationConservativeStateCreateInfoEXT conservative_raster{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT,
@ -763,8 +764,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.stencilTestEnable = dynamic.stencil_enable, .stencilTestEnable = dynamic.stencil_enable,
.front = GetStencilFaceState(dynamic.front), .front = GetStencilFaceState(dynamic.front),
.back = GetStencilFaceState(dynamic.back), .back = GetStencilFaceState(dynamic.back),
.minDepthBounds = 0.0f, .minDepthBounds = static_cast<f32>(key.state.depth_bounds_min),
.maxDepthBounds = 0.0f, .maxDepthBounds = static_cast<f32>(key.state.depth_bounds_max),
}; };
if (dynamic.depth_bounds_enable && !device.IsDepthBoundsSupported()) { if (dynamic.depth_bounds_enable && !device.IsDepthBoundsSupported()) {
LOG_WARNING(Render_Vulkan, "Depth bounds is enabled but not supported"); LOG_WARNING(Render_Vulkan, "Depth bounds is enabled but not supported");
@ -855,9 +856,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT, VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
// additional state3 extensions // additional state3 extensions
// FIXME(crueter): conservative rasterization is totally broken
// VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT, VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT,
VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT, VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT,
@ -865,7 +863,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT, VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT,
VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT, VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT, VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT,
VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT, VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT,
VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT, VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT,
}; };

View file

@ -935,6 +935,7 @@ void RasterizerVulkan::UpdateDynamicStates() {
UpdateDepthBounds(regs); UpdateDepthBounds(regs);
UpdateStencilFaces(regs); UpdateStencilFaces(regs);
UpdateLineWidth(regs); UpdateLineWidth(regs);
// UpdateLineStipple(regs); // TODO
const u8 dynamic_state = Settings::values.dyna_state.GetValue(); const u8 dynamic_state = Settings::values.dyna_state.GetValue();
@ -1368,6 +1369,17 @@ void RasterizerVulkan::UpdateLineStippleEnable(Tegra::Engines::Maxwell3D::Regs&
}); });
} }
void RasterizerVulkan::UpdateLineStipple(Tegra::Engines::Maxwell3D::Regs& regs)
{
if (!state_tracker.TouchLineStippleEnable()) {
return;
}
scheduler.Record([params = regs.line_stipple_params](vk::CommandBuffer cmdbuf) {
cmdbuf.SetLineStippleEXT(params.factor, u16(params.pattern));
});
}
void RasterizerVulkan::UpdateLineRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs) void RasterizerVulkan::UpdateLineRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs)
{ {
// if (!state_tracker.TouchLi()) { // if (!state_tracker.TouchLi()) {

View file

@ -180,6 +180,7 @@ private:
void UpdateRasterizerDiscardEnable(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateRasterizerDiscardEnable(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateConservativeRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateConservativeRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateLineStippleEnable(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 UpdateLineRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateLogicOpEnable(Tegra::Engines::Maxwell3D::Regs& regs); void UpdateLogicOpEnable(Tegra::Engines::Maxwell3D::Regs& regs);

View file

@ -52,9 +52,7 @@ Flags MakeInvalidationFlags() {
VertexInput, VertexInput,
StateEnable, StateEnable,
PrimitiveRestartEnable, PrimitiveRestartEnable,
RasterizerDiscardEnable, LineStippleParams,
ConservativeRasterizationMode,
LineStippleEnable,
DepthBiasEnable, DepthBiasEnable,
LogicOpEnable, LogicOpEnable,
DepthClampEnable, DepthClampEnable,
@ -144,6 +142,7 @@ void SetupDirtyStateEnable(Tables& tables) {
setup(OFF(rasterize_enable), RasterizerDiscardEnable); setup(OFF(rasterize_enable), RasterizerDiscardEnable);
setup(OFF(conservative_raster_enable), ConservativeRasterizationMode); setup(OFF(conservative_raster_enable), ConservativeRasterizationMode);
setup(OFF(line_stipple_enable), LineStippleEnable); setup(OFF(line_stipple_enable), LineStippleEnable);
setup(OFF(line_stipple_params), LineStippleParams);
setup(OFF(polygon_offset_point_enable), DepthBiasEnable); setup(OFF(polygon_offset_point_enable), DepthBiasEnable);
setup(OFF(polygon_offset_line_enable), DepthBiasEnable); setup(OFF(polygon_offset_line_enable), DepthBiasEnable);
setup(OFF(polygon_offset_fill_enable), DepthBiasEnable); setup(OFF(polygon_offset_fill_enable), DepthBiasEnable);

View file

@ -55,6 +55,7 @@ enum : u8 {
RasterizerDiscardEnable, RasterizerDiscardEnable,
ConservativeRasterizationMode, ConservativeRasterizationMode,
LineStippleEnable, LineStippleEnable,
LineStippleParams,
DepthBiasEnable, DepthBiasEnable,
StateEnable, StateEnable,
LogicOp, LogicOp,

View file

@ -240,6 +240,7 @@ struct DeviceDispatch : InstanceDispatch {
PFN_vkCmdSetConservativeRasterizationModeEXT vkCmdSetConservativeRasterizationModeEXT{}; PFN_vkCmdSetConservativeRasterizationModeEXT vkCmdSetConservativeRasterizationModeEXT{};
PFN_vkCmdSetLineRasterizationModeEXT vkCmdSetLineRasterizationModeEXT{}; PFN_vkCmdSetLineRasterizationModeEXT vkCmdSetLineRasterizationModeEXT{};
PFN_vkCmdSetLineStippleEnableEXT vkCmdSetLineStippleEnableEXT{}; PFN_vkCmdSetLineStippleEnableEXT vkCmdSetLineStippleEnableEXT{};
PFN_vkCmdSetLineStippleEXT vkCmdSetLineStippleEXT{};
PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT{}; PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT{};
PFN_vkCmdSetLogicOpEnableEXT vkCmdSetLogicOpEnableEXT{}; PFN_vkCmdSetLogicOpEnableEXT vkCmdSetLogicOpEnableEXT{};
PFN_vkCmdSetDepthClampEnableEXT vkCmdSetDepthClampEnableEXT{}; PFN_vkCmdSetDepthClampEnableEXT vkCmdSetDepthClampEnableEXT{};
@ -1452,6 +1453,11 @@ public:
dld->vkCmdSetLineStippleEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); dld->vkCmdSetLineStippleEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
} }
void SetLineStippleEXT(u32 factor, u16 pattern) const noexcept
{
dld->vkCmdSetLineStippleEXT(handle, factor, pattern);
}
void SetDepthBiasEnableEXT(bool enable) const noexcept { void SetDepthBiasEnableEXT(bool enable) const noexcept {
dld->vkCmdSetDepthBiasEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); dld->vkCmdSetDepthBiasEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
} }