diff options
| author | Fernando Sahmkow <fsahmkow27@gmail.com> | 2022-12-05 17:14:34 +0100 | 
|---|---|---|
| committer | Fernando Sahmkow <fsahmkow27@gmail.com> | 2023-01-01 16:43:58 -0500 | 
| commit | f800e485c9bcd98e08128db974540e7ba0324128 (patch) | |
| tree | c931bf1f7e8aa04d6f0ea6c110dedc1c10642cab /src/video_core | |
| parent | c897c55e3cf007b771351267ff61114d36011ac6 (diff) | |
Vulkan Implement Dynamic State 2 LogicOp and PatchVertices
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/fixed_pipeline_state.h | 30 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 15 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_state_tracker.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_state_tracker.h | 5 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.h | 10 | 
12 files changed, 75 insertions, 27 deletions
| diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index d44a5cabf..7f406e171 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -124,6 +124,7 @@ void Maxwell3D::InitializeRegisterDefaults() {      regs.gl_front_face = Maxwell3D::Regs::FrontFace::ClockWise;      regs.polygon_mode_back = Maxwell3D::Regs::PolygonMode::Fill;      regs.polygon_mode_front = Maxwell3D::Regs::PolygonMode::Fill; +    regs.logic_op.op = Maxwell3D::Regs::LogicOp::Op::Clear;      shadow_state = regs;  } diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index f13ff09c6..b1623b882 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp @@ -55,6 +55,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe      raw1 = 0;      extended_dynamic_state.Assign(features.has_extended_dynamic_state ? 1 : 0);      extended_dynamic_state_2.Assign(features.has_extended_dynamic_state_2 ? 1 : 0); +    extended_dynamic_state_2_extra.Assign(features.has_extended_dynamic_state_2_extra ? 1 : 0);      extended_dynamic_state_3.Assign(features.has_extended_dynamic_state_3 ? 1 : 0);      dynamic_vertex_input.Assign(features.has_dynamic_vertex_input ? 1 : 0);      xfb_enabled.Assign(regs.transform_feedback_enabled != 0); @@ -66,13 +67,12 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe                                      Maxwell::ViewportClipControl::GeometryClip::FrustumZ);      ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0);      polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front)); -    patch_control_points_minus_one.Assign(regs.patch_vertices - 1);      tessellation_primitive.Assign(static_cast<u32>(regs.tessellation.params.domain_type.Value()));      tessellation_spacing.Assign(static_cast<u32>(regs.tessellation.params.spacing.Value()));      tessellation_clockwise.Assign(regs.tessellation.params.output_primitives.Value() ==                                    Maxwell::Tessellation::OutputPrimitives::Triangles_CW);      logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0); -    logic_op.Assign(PackLogicOp(regs.logic_op.op)); +    patch_control_points_minus_one.Assign(regs.patch_vertices - 1);      topology.Assign(topology_);      msaa_mode.Assign(regs.anti_alias_samples_mode); @@ -156,8 +156,8 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe      if (!extended_dynamic_state) {          dynamic_state.Refresh(regs);      } -    if (!extended_dynamic_state_2) { -        dynamic_state.Refresh2(regs, topology); +    if (!extended_dynamic_state_2_extra) { +        dynamic_state.Refresh2(regs, topology, extended_dynamic_state_2);      }      if (!extended_dynamic_state_3) {          dynamic_state.Refresh3(regs); @@ -241,7 +241,13 @@ void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) {      });  } -void FixedPipelineState::DynamicState::Refresh2(const Maxwell& regs, Maxwell::PrimitiveTopology topology_) { +void FixedPipelineState::DynamicState::Refresh2(const Maxwell& regs, Maxwell::PrimitiveTopology topology_, bool base_feautures_supported) { +    logic_op.Assign(PackLogicOp(regs.logic_op.op)); + +    if (base_feautures_supported) { +        return; +    } +      const std::array enabled_lut{          regs.polygon_offset_point_enable,          regs.polygon_offset_line_enable, diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index ac2ec3edc..88680e448 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h @@ -146,6 +146,7 @@ struct FixedPipelineState {              BitField<3, 1, u32> primitive_restart_enable;              BitField<4, 1, u32> depth_bias_enable;              BitField<5, 1, u32> rasterize_enable; +            BitField<6, 4, u32> logic_op;          };          union {              u32 raw2; @@ -162,7 +163,7 @@ struct FixedPipelineState {          std::array<u16, Maxwell::NumVertexArrays> vertex_strides;          void Refresh(const Maxwell& regs); -        void Refresh2(const Maxwell& regs, Maxwell::PrimitiveTopology topology); +        void Refresh2(const Maxwell& regs, Maxwell::PrimitiveTopology topology, bool base_feautures_supported);          void Refresh3(const Maxwell& regs);          Maxwell::ComparisonOp DepthTestFunc() const noexcept { @@ -182,18 +183,19 @@ struct FixedPipelineState {          u32 raw1;          BitField<0, 1, u32> extended_dynamic_state;          BitField<1, 1, u32> extended_dynamic_state_2; -        BitField<2, 1, u32> extended_dynamic_state_3; -        BitField<3, 1, u32> dynamic_vertex_input; -        BitField<4, 1, u32> xfb_enabled; -        BitField<5, 1, u32> depth_clamp_disabled; -        BitField<6, 1, u32> ndc_minus_one_to_one; -        BitField<7, 2, u32> polygon_mode; -        BitField<9, 5, u32> patch_control_points_minus_one; -        BitField<14, 2, u32> tessellation_primitive; -        BitField<16, 2, u32> tessellation_spacing; -        BitField<18, 1, u32> tessellation_clockwise; -        BitField<19, 1, u32> logic_op_enable; -        BitField<20, 4, u32> logic_op; +        BitField<2, 1, u32> extended_dynamic_state_2_extra; +        BitField<3, 1, u32> extended_dynamic_state_3; +        BitField<4, 1, u32> dynamic_vertex_input; +        BitField<5, 1, u32> xfb_enabled; +        BitField<6, 1, u32> depth_clamp_disabled; +        BitField<7, 1, u32> ndc_minus_one_to_one; +        BitField<8, 2, u32> polygon_mode; +        BitField<10, 2, u32> tessellation_primitive; +        BitField<12, 2, u32> tessellation_spacing; +        BitField<14, 1, u32> tessellation_clockwise; +        BitField<15, 1, u32> logic_op_enable; +        BitField<16, 5, u32> patch_control_points_minus_one; +          BitField<24, 4, Maxwell::PrimitiveTopology> topology;          BitField<28, 4, Tegra::Texture::MsaaMode> msaa_mode;      }; @@ -246,7 +248,7 @@ struct FixedPipelineState {              // Exclude dynamic state and attributes              return offsetof(FixedPipelineState, attributes);          } -        if (extended_dynamic_state_2) { +        if (extended_dynamic_state_2_extra) {              // Exclude dynamic state              return offsetof(FixedPipelineState, dynamic_state);          } diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index d21d5aaf4..ce82a9c65 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -628,7 +628,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {          .pNext = nullptr,          .flags = 0,          .topology = input_assembly_topology, -        .primitiveRestartEnable = key.state.dynamic_state.primitive_restart_enable != 0 && +        .primitiveRestartEnable = dynamic.primitive_restart_enable != 0 &&                                    ((input_assembly_topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST &&                                      device.IsTopologyListPrimitiveRestartSupported()) ||                                     SupportsPrimitiveRestart(input_assembly_topology) || @@ -786,12 +786,12 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {          .pNext = nullptr,          .flags = 0,          .logicOpEnable = key.state.logic_op_enable != 0, -        .logicOp = static_cast<VkLogicOp>(key.state.logic_op.Value()), +        .logicOp = static_cast<VkLogicOp>(dynamic.logic_op.Value()),          .attachmentCount = static_cast<u32>(cb_attachments.size()),          .pAttachments = cb_attachments.data(),          .blendConstants = {},      }; -    static_vector<VkDynamicState, 22> dynamic_states{ +    static_vector<VkDynamicState, 23> 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, @@ -822,6 +822,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {              };              dynamic_states.insert(dynamic_states.end(), extended2.begin(), extended2.end());          } +        if (key.state.extended_dynamic_state_2_extra) { +            dynamic_states.push_back(VK_DYNAMIC_STATE_LOGIC_OP_EXT); +        }      }      const VkPipelineDynamicStateCreateInfo dynamic_state_ci{          .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 1292b6bdf..ee1ad744f 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -454,6 +454,8 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading                  dynamic_features.has_extended_dynamic_state ||              (key.state.extended_dynamic_state_2 != 0) !=                  dynamic_features.has_extended_dynamic_state_2 || +            (key.state.extended_dynamic_state_2_extra != 0) != +                dynamic_features.has_extended_dynamic_state_2_extra ||              (key.state.extended_dynamic_state_3 != 0) !=                  dynamic_features.has_extended_dynamic_state_3 ||              (key.state.dynamic_vertex_input != 0) != dynamic_features.has_dynamic_vertex_input) { diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index f52cebc22..3cf6b796b 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -680,7 +680,6 @@ void RasterizerVulkan::UpdateDynamicStates() {      UpdateLineWidth(regs);      if (device.IsExtExtendedDynamicStateSupported()) {          UpdateCullMode(regs); -          UpdateDepthCompareOp(regs);          UpdateFrontFace(regs);          UpdateStencilOp(regs); @@ -700,6 +699,9 @@ void RasterizerVulkan::UpdateDynamicStates() {                  UpdateDepthBiasEnable(regs);              }          } +        if (device.IsExtExtendedDynamicState2ExtrasSupported()) { +            UpdateLogicOp(regs); +        }      }  } @@ -1028,6 +1030,17 @@ void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) {      }  } +void RasterizerVulkan::UpdateLogicOp(Tegra::Engines::Maxwell3D::Regs& regs) { +    if (!regs.logic_op.enable) { +        return; +    } +    if (!state_tracker.TouchLogicOp()) { +        return; +    } +    auto op = static_cast<VkLogicOp>(static_cast<u32>(regs.logic_op.op) - 0x1500); +    scheduler.Record([op](vk::CommandBuffer cmdbuf) { cmdbuf.SetLogicOpEXT(op); }); +} +  void RasterizerVulkan::UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs) {      if (!state_tracker.TouchStencilTestEnable()) {          return; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index c09415a6a..67d35eff7 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -145,6 +145,7 @@ private:      void UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs);      void UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs);      void UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs); +    void UpdateLogicOp(Tegra::Engines::Maxwell3D::Regs& regs);      void UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs); diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index 339679ff9..1f8528e3e 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp @@ -48,6 +48,7 @@ Flags MakeInvalidationFlags() {          PrimitiveRestartEnable,          RasterizerDiscardEnable,          DepthBiasEnable, +        LogicOp,      };      Flags flags{};      for (const int flag : INVALIDATION_FLAGS) { @@ -162,6 +163,10 @@ void SetupDirtyBlending(Tables& tables) {      FillBlock(tables[0], OFF(blend_per_target), NUM(blend_per_target), Blending);  } +void SetupDirtySpecialOps(Tables& tables) { +    tables[0][OFF(logic_op.op)] = LogicOp; +} +  void SetupDirtyViewportSwizzles(Tables& tables) {      static constexpr size_t swizzle_offset = 6;      for (size_t index = 0; index < Regs::NumViewports; ++index) { @@ -210,6 +215,7 @@ void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) {      SetupDirtyViewportSwizzles(tables);      SetupDirtyVertexAttributes(tables);      SetupDirtyVertexBindings(tables); +    SetupDirtySpecialOps(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 583bfe135..6050f5d26 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h @@ -49,6 +49,7 @@ enum : u8 {      RasterizerDiscardEnable,      DepthBiasEnable,      StateEnable, +    LogicOp,      Blending,      ViewportSwizzles, @@ -159,6 +160,10 @@ public:          return Exchange(Dirty::StencilTestEnable, false);      } +    bool TouchLogicOp() { +        return Exchange(Dirty::LogicOp, false); +    } +      bool ChangePrimitiveTopology(Maxwell::PrimitiveTopology new_topology) {          const bool has_changed = current_topology != new_topology;          current_topology = new_topology; diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 9a420a293..7294fcfe3 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -576,8 +576,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR              .pNext = nullptr,              .extendedDynamicState2 = VK_TRUE,              .extendedDynamicState2LogicOp = ext_extended_dynamic_state2_extra ? VK_TRUE : VK_FALSE, -            .extendedDynamicState2PatchControlPoints = -                ext_extended_dynamic_state2_extra ? VK_TRUE : VK_FALSE,          };          SetNext(next, dynamic_state2);      } else { @@ -1330,8 +1328,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {              extensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);              ext_extended_dynamic_state2 = true;              ext_extended_dynamic_state2_extra = -                extended_dynamic_state2.extendedDynamicState2LogicOp && -                extended_dynamic_state2.extendedDynamicState2PatchControlPoints; +                extended_dynamic_state2.extendedDynamicState2LogicOp;          }      }      if (has_ext_extended_dynamic_state3) { diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 4dde325ff..8745cf80f 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -126,6 +126,8 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {      X(vkCmdSetRasterizerDiscardEnableEXT);      X(vkCmdSetDepthBiasEnableEXT);      X(vkCmdSetFrontFaceEXT); +    X(vkCmdSetLogicOpEXT); +    X(vkCmdSetPatchControlPointsEXT);      X(vkCmdSetLineWidth);      X(vkCmdSetPrimitiveTopologyEXT);      X(vkCmdSetStencilOpEXT); diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 0d3f71460..c4b7051fc 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h @@ -239,6 +239,8 @@ struct DeviceDispatch : InstanceDispatch {      PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT{};      PFN_vkCmdSetEvent vkCmdSetEvent{};      PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT{}; +    PFN_vkCmdSetPatchControlPointsEXT vkCmdSetPatchControlPointsEXT{}; +    PFN_vkCmdSetLogicOpEXT vkCmdSetLogicOpEXT{};      PFN_vkCmdSetLineWidth vkCmdSetLineWidth{};      PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT{};      PFN_vkCmdSetScissor vkCmdSetScissor{}; @@ -1238,6 +1240,14 @@ public:          dld->vkCmdSetFrontFaceEXT(handle, front_face);      } +    void SetLogicOpEXT(VkLogicOp logic_op) const noexcept { +        dld->vkCmdSetLogicOpEXT(handle, logic_op); +    } + +    void SetPatchControlPointsEXT(uint32_t patch_control_points) const noexcept { +        dld->vkCmdSetPatchControlPointsEXT(handle, patch_control_points); +    } +      void SetLineWidth(float line_width) const noexcept {          dld->vkCmdSetLineWidth(handle, line_width);      } | 
