diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index 133ab01701..39f4fc6993 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp @@ -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); app_stage.Assign(maxwell3d.engine_state); + depth_bounds_min = static_cast(regs.depth_bounds[0]); + depth_bounds_max = static_cast(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) { color_formats[i] = static_cast(regs.rt[i].format); } @@ -258,6 +264,8 @@ void FixedPipelineState::DynamicState::Refresh3(const Maxwell& regs) { Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ || regs.viewport_clip_control.geometry_clip == Maxwell::ViewportClipControl::GeometryClip::FrustumZ); + + line_stipple_enable.Assign(regs.line_stipple_enable); } size_t FixedPipelineState::Hash() const noexcept { diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index dfe6d80323..f0b021ca08 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h @@ -150,6 +150,7 @@ struct FixedPipelineState { BitField<6, 4, u32> logic_op; BitField<10, 1, u32> logic_op_enable; BitField<11, 1, u32> depth_clamp_disabled; + BitField<12, 1, u32> line_stipple_enable; }; union { u32 raw2; @@ -218,6 +219,7 @@ struct FixedPipelineState { u32 alpha_test_ref; u32 point_size; + std::array viewport_swizzles; union { u64 attribute_types; // Used with VK_EXT_vertex_input_dynamic_state @@ -233,6 +235,12 @@ struct FixedPipelineState { 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); size_t Hash() const noexcept; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 5898e759c8..77ad4aebf9 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -697,6 +697,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .depthBiasClamp = 0.0f, .depthBiasSlopeFactor = 0.0f, .lineWidth = 1.0f, + // TODO(alekpop): Transfer from regs }; VkPipelineRasterizationLineStateCreateInfoEXT line_state{ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT, @@ -704,9 +705,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .lineRasterizationMode = key.state.smooth_lines != 0 ? VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT : VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, - .stippledLineEnable = VK_FALSE, // TODO - .lineStippleFactor = 0, - .lineStipplePattern = 0, + .stippledLineEnable = dynamic.line_stipple_enable ? VK_TRUE : VK_FALSE, + .lineStippleFactor = key.state.line_stipple_factor, + .lineStipplePattern = static_cast(key.state.line_stipple_pattern), }; VkPipelineRasterizationConservativeStateCreateInfoEXT conservative_raster{ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, @@ -759,8 +760,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .stencilTestEnable = dynamic.stencil_enable, .front = GetStencilFaceState(dynamic.front), .back = GetStencilFaceState(dynamic.back), - .minDepthBounds = 0.0f, - .maxDepthBounds = 0.0f, + .minDepthBounds = static_cast(key.state.depth_bounds_min), + .maxDepthBounds = static_cast(key.state.depth_bounds_max), }; if (dynamic.depth_bounds_enable && !device.IsDepthBoundsSupported()) { LOG_WARNING(Render_Vulkan, "Depth bounds is enabled but not supported"); @@ -800,12 +801,12 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .attachmentCount = static_cast(cb_attachments.size()), .pAttachments = cb_attachments.data(), .blendConstants = {}}; - static_vector dynamic_states{ + static_vector dynamic_states{ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, VK_DYNAMIC_STATE_STENCIL_REFERENCE, - VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_LINE_STIPPLE, + VK_DYNAMIC_STATE_LINE_WIDTH, }; if (key.state.extended_dynamic_state) { static constexpr std::array extended{ @@ -850,9 +851,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT, // 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_CONSERVATIVE_RASTERIZATION_MODE_EXT, @@ -860,7 +858,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT, VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_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_PROVOKING_VERTEX_MODE_EXT, }; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 587db143b0..aa2e4aebbd 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -57,7 +57,7 @@ using VideoCommon::FileEnvironment; using VideoCommon::GenericEnvironment; using VideoCommon::GraphicsEnvironment; -constexpr u32 CACHE_VERSION = 11; +constexpr u32 CACHE_VERSION = 12; constexpr std::array VULKAN_CACHE_MAGIC_NUMBER{'y', 'u', 'z', 'u', 'v', 'k', 'c', 'h'}; template diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 19bfc60185..8f8d80de30 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -936,6 +936,8 @@ void RasterizerVulkan::UpdateDynamicStates() { UpdateDepthBounds(regs); UpdateStencilFaces(regs); UpdateLineWidth(regs); + // TODO: updating line stipple causes the cmdbuf to die + // UpdateLineStipple(regs); const u8 dynamic_state = Settings::values.dyna_state.GetValue(); @@ -1363,6 +1365,16 @@ void RasterizerVulkan::UpdateLineStippleEnable(Tegra::Engines::Maxwell3D::Regs& }); } +void RasterizerVulkan::UpdateLineStipple(Tegra::Engines::Maxwell3D::Regs& regs) { + if (!state_tracker.TouchLineStipple()) { + return; + } + + scheduler.Record([params = regs.line_stipple_params](vk::CommandBuffer cmdbuf) { + cmdbuf.SetLineStippleEXT(params.factor, static_cast(params.pattern)); + }); +} + void RasterizerVulkan::UpdateLineRasterizationMode(Tegra::Engines::Maxwell3D::Regs& regs) { // if (!state_tracker.TouchLi()) { // return; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index f562ad1941..ea032635c2 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -180,6 +180,7 @@ 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/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h index 51e7ab1e1d..54ab8ba52b 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_scheduler.h @@ -153,6 +153,7 @@ private: TypedCommand& operator=(TypedCommand&&) = delete; void Execute(vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) const override { + command(cmdbuf, upload_cmdbuf); } diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index ff274ede6e..242d03cf24 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp @@ -52,9 +52,6 @@ Flags MakeInvalidationFlags() { VertexInput, StateEnable, PrimitiveRestartEnable, - RasterizerDiscardEnable, - ConservativeRasterizationMode, - LineStippleEnable, DepthBiasEnable, LogicOpEnable, DepthClampEnable, @@ -63,6 +60,9 @@ Flags MakeInvalidationFlags() { ColorMask, BlendEquations, BlendEnable, + ConservativeRasterizationMode, + LineStippleEnable, + LineStippleParams, }; Flags flags{}; for (const int flag : INVALIDATION_FLAGS) { @@ -142,13 +142,12 @@ void SetupDirtyStateEnable(Tables& tables) { setup(OFF(stencil_enable), StencilTestEnable); setup(OFF(primitive_restart.enabled), PrimitiveRestartEnable); setup(OFF(rasterize_enable), RasterizerDiscardEnable); - setup(OFF(conservative_raster_enable), ConservativeRasterizationMode); - setup(OFF(line_stipple_enable), LineStippleEnable); setup(OFF(polygon_offset_point_enable), DepthBiasEnable); setup(OFF(polygon_offset_line_enable), DepthBiasEnable); setup(OFF(polygon_offset_fill_enable), DepthBiasEnable); setup(OFF(logic_op.enable), LogicOpEnable); setup(OFF(viewport_clip_control.geometry_clip), DepthClampEnable); + setup(OFF(line_stipple_enable), LineStippleEnable); } void SetupDirtyDepthCompareOp(Tables& tables) { @@ -221,6 +220,13 @@ void SetupDirtyVertexBindings(Tables& tables) { tables[1][OFF(vertex_streams) + i * NUM(vertex_streams[0]) + divisor_offset] = flag; } } + +void SetupRasterModes(Tables &tables) { + auto& table = tables[0]; + + table[OFF(line_stipple_params)] = LineStippleParams; + table[OFF(conservative_raster_enable)] = ConservativeRasterizationMode; +} } // Anonymous namespace void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) { @@ -243,6 +249,7 @@ void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) { SetupDirtyVertexAttributes(tables); SetupDirtyVertexBindings(tables); SetupDirtySpecialOps(tables); + SetupRasterModes(tables); } void StateTracker::ChangeChannel(Tegra::Control::ChannelState& channel_state) { diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h index 386dc017af..7edd464e7a 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h @@ -55,6 +55,7 @@ enum : u8 { RasterizerDiscardEnable, ConservativeRasterizationMode, LineStippleEnable, + LineStippleParams, DepthBiasEnable, StateEnable, LogicOp, @@ -210,7 +211,11 @@ public: } bool TouchLineStippleEnable() { - return Exchange(Dirty::ConservativeRasterizationMode, false); + return Exchange(Dirty::LineStippleEnable, false); + } + + bool TouchLineStipple() { + return Exchange(Dirty::LineStippleParams, false); } bool TouchDepthBiasEnable() { diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 45e2c71a05..0bdf4407a6 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h @@ -240,6 +240,7 @@ struct DeviceDispatch : InstanceDispatch { PFN_vkCmdSetConservativeRasterizationModeEXT vkCmdSetConservativeRasterizationModeEXT{}; PFN_vkCmdSetLineRasterizationModeEXT vkCmdSetLineRasterizationModeEXT{}; PFN_vkCmdSetLineStippleEnableEXT vkCmdSetLineStippleEnableEXT{}; + PFN_vkCmdSetLineStippleEXT vkCmdSetLineStippleEXT{}; PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT{}; PFN_vkCmdSetLogicOpEnableEXT vkCmdSetLogicOpEnableEXT{}; PFN_vkCmdSetDepthClampEnableEXT vkCmdSetDepthClampEnableEXT{}; @@ -1450,6 +1451,11 @@ public: 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 { dld->vkCmdSetDepthBiasEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); }