summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/maxwell_3d.cpp1
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp16
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h30
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp9
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp15
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h1
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.h5
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp5
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.cpp2
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.h10
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() {
124 regs.gl_front_face = Maxwell3D::Regs::FrontFace::ClockWise; 124 regs.gl_front_face = Maxwell3D::Regs::FrontFace::ClockWise;
125 regs.polygon_mode_back = Maxwell3D::Regs::PolygonMode::Fill; 125 regs.polygon_mode_back = Maxwell3D::Regs::PolygonMode::Fill;
126 regs.polygon_mode_front = Maxwell3D::Regs::PolygonMode::Fill; 126 regs.polygon_mode_front = Maxwell3D::Regs::PolygonMode::Fill;
127 regs.logic_op.op = Maxwell3D::Regs::LogicOp::Op::Clear;
127 128
128 shadow_state = regs; 129 shadow_state = regs;
129} 130}
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
55 raw1 = 0; 55 raw1 = 0;
56 extended_dynamic_state.Assign(features.has_extended_dynamic_state ? 1 : 0); 56 extended_dynamic_state.Assign(features.has_extended_dynamic_state ? 1 : 0);
57 extended_dynamic_state_2.Assign(features.has_extended_dynamic_state_2 ? 1 : 0); 57 extended_dynamic_state_2.Assign(features.has_extended_dynamic_state_2 ? 1 : 0);
58 extended_dynamic_state_2_extra.Assign(features.has_extended_dynamic_state_2_extra ? 1 : 0);
58 extended_dynamic_state_3.Assign(features.has_extended_dynamic_state_3 ? 1 : 0); 59 extended_dynamic_state_3.Assign(features.has_extended_dynamic_state_3 ? 1 : 0);
59 dynamic_vertex_input.Assign(features.has_dynamic_vertex_input ? 1 : 0); 60 dynamic_vertex_input.Assign(features.has_dynamic_vertex_input ? 1 : 0);
60 xfb_enabled.Assign(regs.transform_feedback_enabled != 0); 61 xfb_enabled.Assign(regs.transform_feedback_enabled != 0);
@@ -66,13 +67,12 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
66 Maxwell::ViewportClipControl::GeometryClip::FrustumZ); 67 Maxwell::ViewportClipControl::GeometryClip::FrustumZ);
67 ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0); 68 ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0);
68 polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front)); 69 polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front));
69 patch_control_points_minus_one.Assign(regs.patch_vertices - 1);
70 tessellation_primitive.Assign(static_cast<u32>(regs.tessellation.params.domain_type.Value())); 70 tessellation_primitive.Assign(static_cast<u32>(regs.tessellation.params.domain_type.Value()));
71 tessellation_spacing.Assign(static_cast<u32>(regs.tessellation.params.spacing.Value())); 71 tessellation_spacing.Assign(static_cast<u32>(regs.tessellation.params.spacing.Value()));
72 tessellation_clockwise.Assign(regs.tessellation.params.output_primitives.Value() == 72 tessellation_clockwise.Assign(regs.tessellation.params.output_primitives.Value() ==
73 Maxwell::Tessellation::OutputPrimitives::Triangles_CW); 73 Maxwell::Tessellation::OutputPrimitives::Triangles_CW);
74 logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0); 74 logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0);
75 logic_op.Assign(PackLogicOp(regs.logic_op.op)); 75 patch_control_points_minus_one.Assign(regs.patch_vertices - 1);
76 topology.Assign(topology_); 76 topology.Assign(topology_);
77 msaa_mode.Assign(regs.anti_alias_samples_mode); 77 msaa_mode.Assign(regs.anti_alias_samples_mode);
78 78
@@ -156,8 +156,8 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
156 if (!extended_dynamic_state) { 156 if (!extended_dynamic_state) {
157 dynamic_state.Refresh(regs); 157 dynamic_state.Refresh(regs);
158 } 158 }
159 if (!extended_dynamic_state_2) { 159 if (!extended_dynamic_state_2_extra) {
160 dynamic_state.Refresh2(regs, topology); 160 dynamic_state.Refresh2(regs, topology, extended_dynamic_state_2);
161 } 161 }
162 if (!extended_dynamic_state_3) { 162 if (!extended_dynamic_state_3) {
163 dynamic_state.Refresh3(regs); 163 dynamic_state.Refresh3(regs);
@@ -241,7 +241,13 @@ void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) {
241 }); 241 });
242} 242}
243 243
244void FixedPipelineState::DynamicState::Refresh2(const Maxwell& regs, Maxwell::PrimitiveTopology topology_) { 244void FixedPipelineState::DynamicState::Refresh2(const Maxwell& regs, Maxwell::PrimitiveTopology topology_, bool base_feautures_supported) {
245 logic_op.Assign(PackLogicOp(regs.logic_op.op));
246
247 if (base_feautures_supported) {
248 return;
249 }
250
245 const std::array enabled_lut{ 251 const std::array enabled_lut{
246 regs.polygon_offset_point_enable, 252 regs.polygon_offset_point_enable,
247 regs.polygon_offset_line_enable, 253 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 {
146 BitField<3, 1, u32> primitive_restart_enable; 146 BitField<3, 1, u32> primitive_restart_enable;
147 BitField<4, 1, u32> depth_bias_enable; 147 BitField<4, 1, u32> depth_bias_enable;
148 BitField<5, 1, u32> rasterize_enable; 148 BitField<5, 1, u32> rasterize_enable;
149 BitField<6, 4, u32> logic_op;
149 }; 150 };
150 union { 151 union {
151 u32 raw2; 152 u32 raw2;
@@ -162,7 +163,7 @@ struct FixedPipelineState {
162 std::array<u16, Maxwell::NumVertexArrays> vertex_strides; 163 std::array<u16, Maxwell::NumVertexArrays> vertex_strides;
163 164
164 void Refresh(const Maxwell& regs); 165 void Refresh(const Maxwell& regs);
165 void Refresh2(const Maxwell& regs, Maxwell::PrimitiveTopology topology); 166 void Refresh2(const Maxwell& regs, Maxwell::PrimitiveTopology topology, bool base_feautures_supported);
166 void Refresh3(const Maxwell& regs); 167 void Refresh3(const Maxwell& regs);
167 168
168 Maxwell::ComparisonOp DepthTestFunc() const noexcept { 169 Maxwell::ComparisonOp DepthTestFunc() const noexcept {
@@ -182,18 +183,19 @@ struct FixedPipelineState {
182 u32 raw1; 183 u32 raw1;
183 BitField<0, 1, u32> extended_dynamic_state; 184 BitField<0, 1, u32> extended_dynamic_state;
184 BitField<1, 1, u32> extended_dynamic_state_2; 185 BitField<1, 1, u32> extended_dynamic_state_2;
185 BitField<2, 1, u32> extended_dynamic_state_3; 186 BitField<2, 1, u32> extended_dynamic_state_2_extra;
186 BitField<3, 1, u32> dynamic_vertex_input; 187 BitField<3, 1, u32> extended_dynamic_state_3;
187 BitField<4, 1, u32> xfb_enabled; 188 BitField<4, 1, u32> dynamic_vertex_input;
188 BitField<5, 1, u32> depth_clamp_disabled; 189 BitField<5, 1, u32> xfb_enabled;
189 BitField<6, 1, u32> ndc_minus_one_to_one; 190 BitField<6, 1, u32> depth_clamp_disabled;
190 BitField<7, 2, u32> polygon_mode; 191 BitField<7, 1, u32> ndc_minus_one_to_one;
191 BitField<9, 5, u32> patch_control_points_minus_one; 192 BitField<8, 2, u32> polygon_mode;
192 BitField<14, 2, u32> tessellation_primitive; 193 BitField<10, 2, u32> tessellation_primitive;
193 BitField<16, 2, u32> tessellation_spacing; 194 BitField<12, 2, u32> tessellation_spacing;
194 BitField<18, 1, u32> tessellation_clockwise; 195 BitField<14, 1, u32> tessellation_clockwise;
195 BitField<19, 1, u32> logic_op_enable; 196 BitField<15, 1, u32> logic_op_enable;
196 BitField<20, 4, u32> logic_op; 197 BitField<16, 5, u32> patch_control_points_minus_one;
198
197 BitField<24, 4, Maxwell::PrimitiveTopology> topology; 199 BitField<24, 4, Maxwell::PrimitiveTopology> topology;
198 BitField<28, 4, Tegra::Texture::MsaaMode> msaa_mode; 200 BitField<28, 4, Tegra::Texture::MsaaMode> msaa_mode;
199 }; 201 };
@@ -246,7 +248,7 @@ struct FixedPipelineState {
246 // Exclude dynamic state and attributes 248 // Exclude dynamic state and attributes
247 return offsetof(FixedPipelineState, attributes); 249 return offsetof(FixedPipelineState, attributes);
248 } 250 }
249 if (extended_dynamic_state_2) { 251 if (extended_dynamic_state_2_extra) {
250 // Exclude dynamic state 252 // Exclude dynamic state
251 return offsetof(FixedPipelineState, dynamic_state); 253 return offsetof(FixedPipelineState, dynamic_state);
252 } 254 }
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) {
628 .pNext = nullptr, 628 .pNext = nullptr,
629 .flags = 0, 629 .flags = 0,
630 .topology = input_assembly_topology, 630 .topology = input_assembly_topology,
631 .primitiveRestartEnable = key.state.dynamic_state.primitive_restart_enable != 0 && 631 .primitiveRestartEnable = dynamic.primitive_restart_enable != 0 &&
632 ((input_assembly_topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && 632 ((input_assembly_topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST &&
633 device.IsTopologyListPrimitiveRestartSupported()) || 633 device.IsTopologyListPrimitiveRestartSupported()) ||
634 SupportsPrimitiveRestart(input_assembly_topology) || 634 SupportsPrimitiveRestart(input_assembly_topology) ||
@@ -786,12 +786,12 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
786 .pNext = nullptr, 786 .pNext = nullptr,
787 .flags = 0, 787 .flags = 0,
788 .logicOpEnable = key.state.logic_op_enable != 0, 788 .logicOpEnable = key.state.logic_op_enable != 0,
789 .logicOp = static_cast<VkLogicOp>(key.state.logic_op.Value()), 789 .logicOp = static_cast<VkLogicOp>(dynamic.logic_op.Value()),
790 .attachmentCount = static_cast<u32>(cb_attachments.size()), 790 .attachmentCount = static_cast<u32>(cb_attachments.size()),
791 .pAttachments = cb_attachments.data(), 791 .pAttachments = cb_attachments.data(),
792 .blendConstants = {}, 792 .blendConstants = {},
793 }; 793 };
794 static_vector<VkDynamicState, 22> dynamic_states{ 794 static_vector<VkDynamicState, 23> dynamic_states{
795 VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, 795 VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR,
796 VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS, 796 VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS,
797 VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, 797 VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
@@ -822,6 +822,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
822 }; 822 };
823 dynamic_states.insert(dynamic_states.end(), extended2.begin(), extended2.end()); 823 dynamic_states.insert(dynamic_states.end(), extended2.begin(), extended2.end());
824 } 824 }
825 if (key.state.extended_dynamic_state_2_extra) {
826 dynamic_states.push_back(VK_DYNAMIC_STATE_LOGIC_OP_EXT);
827 }
825 } 828 }
826 const VkPipelineDynamicStateCreateInfo dynamic_state_ci{ 829 const VkPipelineDynamicStateCreateInfo dynamic_state_ci{
827 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 830 .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
454 dynamic_features.has_extended_dynamic_state || 454 dynamic_features.has_extended_dynamic_state ||
455 (key.state.extended_dynamic_state_2 != 0) != 455 (key.state.extended_dynamic_state_2 != 0) !=
456 dynamic_features.has_extended_dynamic_state_2 || 456 dynamic_features.has_extended_dynamic_state_2 ||
457 (key.state.extended_dynamic_state_2_extra != 0) !=
458 dynamic_features.has_extended_dynamic_state_2_extra ||
457 (key.state.extended_dynamic_state_3 != 0) != 459 (key.state.extended_dynamic_state_3 != 0) !=
458 dynamic_features.has_extended_dynamic_state_3 || 460 dynamic_features.has_extended_dynamic_state_3 ||
459 (key.state.dynamic_vertex_input != 0) != dynamic_features.has_dynamic_vertex_input) { 461 (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() {
680 UpdateLineWidth(regs); 680 UpdateLineWidth(regs);
681 if (device.IsExtExtendedDynamicStateSupported()) { 681 if (device.IsExtExtendedDynamicStateSupported()) {
682 UpdateCullMode(regs); 682 UpdateCullMode(regs);
683
684 UpdateDepthCompareOp(regs); 683 UpdateDepthCompareOp(regs);
685 UpdateFrontFace(regs); 684 UpdateFrontFace(regs);
686 UpdateStencilOp(regs); 685 UpdateStencilOp(regs);
@@ -700,6 +699,9 @@ void RasterizerVulkan::UpdateDynamicStates() {
700 UpdateDepthBiasEnable(regs); 699 UpdateDepthBiasEnable(regs);
701 } 700 }
702 } 701 }
702 if (device.IsExtExtendedDynamicState2ExtrasSupported()) {
703 UpdateLogicOp(regs);
704 }
703 } 705 }
704} 706}
705 707
@@ -1028,6 +1030,17 @@ void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) {
1028 } 1030 }
1029} 1031}
1030 1032
1033void RasterizerVulkan::UpdateLogicOp(Tegra::Engines::Maxwell3D::Regs& regs) {
1034 if (!regs.logic_op.enable) {
1035 return;
1036 }
1037 if (!state_tracker.TouchLogicOp()) {
1038 return;
1039 }
1040 auto op = static_cast<VkLogicOp>(static_cast<u32>(regs.logic_op.op) - 0x1500);
1041 scheduler.Record([op](vk::CommandBuffer cmdbuf) { cmdbuf.SetLogicOpEXT(op); });
1042}
1043
1031void RasterizerVulkan::UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs) { 1044void RasterizerVulkan::UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs) {
1032 if (!state_tracker.TouchStencilTestEnable()) { 1045 if (!state_tracker.TouchStencilTestEnable()) {
1033 return; 1046 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:
145 void UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs); 145 void UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs);
146 void UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs); 146 void UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs);
147 void UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs); 147 void UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs);
148 void UpdateLogicOp(Tegra::Engines::Maxwell3D::Regs& regs);
148 149
149 void UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs); 150 void UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs);
150 151
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() {
48 PrimitiveRestartEnable, 48 PrimitiveRestartEnable,
49 RasterizerDiscardEnable, 49 RasterizerDiscardEnable,
50 DepthBiasEnable, 50 DepthBiasEnable,
51 LogicOp,
51 }; 52 };
52 Flags flags{}; 53 Flags flags{};
53 for (const int flag : INVALIDATION_FLAGS) { 54 for (const int flag : INVALIDATION_FLAGS) {
@@ -162,6 +163,10 @@ void SetupDirtyBlending(Tables& tables) {
162 FillBlock(tables[0], OFF(blend_per_target), NUM(blend_per_target), Blending); 163 FillBlock(tables[0], OFF(blend_per_target), NUM(blend_per_target), Blending);
163} 164}
164 165
166void SetupDirtySpecialOps(Tables& tables) {
167 tables[0][OFF(logic_op.op)] = LogicOp;
168}
169
165void SetupDirtyViewportSwizzles(Tables& tables) { 170void SetupDirtyViewportSwizzles(Tables& tables) {
166 static constexpr size_t swizzle_offset = 6; 171 static constexpr size_t swizzle_offset = 6;
167 for (size_t index = 0; index < Regs::NumViewports; ++index) { 172 for (size_t index = 0; index < Regs::NumViewports; ++index) {
@@ -210,6 +215,7 @@ void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) {
210 SetupDirtyViewportSwizzles(tables); 215 SetupDirtyViewportSwizzles(tables);
211 SetupDirtyVertexAttributes(tables); 216 SetupDirtyVertexAttributes(tables);
212 SetupDirtyVertexBindings(tables); 217 SetupDirtyVertexBindings(tables);
218 SetupDirtySpecialOps(tables);
213} 219}
214 220
215void StateTracker::ChangeChannel(Tegra::Control::ChannelState& channel_state) { 221void 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 {
49 RasterizerDiscardEnable, 49 RasterizerDiscardEnable,
50 DepthBiasEnable, 50 DepthBiasEnable,
51 StateEnable, 51 StateEnable,
52 LogicOp,
52 53
53 Blending, 54 Blending,
54 ViewportSwizzles, 55 ViewportSwizzles,
@@ -159,6 +160,10 @@ public:
159 return Exchange(Dirty::StencilTestEnable, false); 160 return Exchange(Dirty::StencilTestEnable, false);
160 } 161 }
161 162
163 bool TouchLogicOp() {
164 return Exchange(Dirty::LogicOp, false);
165 }
166
162 bool ChangePrimitiveTopology(Maxwell::PrimitiveTopology new_topology) { 167 bool ChangePrimitiveTopology(Maxwell::PrimitiveTopology new_topology) {
163 const bool has_changed = current_topology != new_topology; 168 const bool has_changed = current_topology != new_topology;
164 current_topology = new_topology; 169 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
576 .pNext = nullptr, 576 .pNext = nullptr,
577 .extendedDynamicState2 = VK_TRUE, 577 .extendedDynamicState2 = VK_TRUE,
578 .extendedDynamicState2LogicOp = ext_extended_dynamic_state2_extra ? VK_TRUE : VK_FALSE, 578 .extendedDynamicState2LogicOp = ext_extended_dynamic_state2_extra ? VK_TRUE : VK_FALSE,
579 .extendedDynamicState2PatchControlPoints =
580 ext_extended_dynamic_state2_extra ? VK_TRUE : VK_FALSE,
581 }; 579 };
582 SetNext(next, dynamic_state2); 580 SetNext(next, dynamic_state2);
583 } else { 581 } else {
@@ -1330,8 +1328,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
1330 extensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); 1328 extensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
1331 ext_extended_dynamic_state2 = true; 1329 ext_extended_dynamic_state2 = true;
1332 ext_extended_dynamic_state2_extra = 1330 ext_extended_dynamic_state2_extra =
1333 extended_dynamic_state2.extendedDynamicState2LogicOp && 1331 extended_dynamic_state2.extendedDynamicState2LogicOp;
1334 extended_dynamic_state2.extendedDynamicState2PatchControlPoints;
1335 } 1332 }
1336 } 1333 }
1337 if (has_ext_extended_dynamic_state3) { 1334 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 {
126 X(vkCmdSetRasterizerDiscardEnableEXT); 126 X(vkCmdSetRasterizerDiscardEnableEXT);
127 X(vkCmdSetDepthBiasEnableEXT); 127 X(vkCmdSetDepthBiasEnableEXT);
128 X(vkCmdSetFrontFaceEXT); 128 X(vkCmdSetFrontFaceEXT);
129 X(vkCmdSetLogicOpEXT);
130 X(vkCmdSetPatchControlPointsEXT);
129 X(vkCmdSetLineWidth); 131 X(vkCmdSetLineWidth);
130 X(vkCmdSetPrimitiveTopologyEXT); 132 X(vkCmdSetPrimitiveTopologyEXT);
131 X(vkCmdSetStencilOpEXT); 133 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 {
239 PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT{}; 239 PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT{};
240 PFN_vkCmdSetEvent vkCmdSetEvent{}; 240 PFN_vkCmdSetEvent vkCmdSetEvent{};
241 PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT{}; 241 PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT{};
242 PFN_vkCmdSetPatchControlPointsEXT vkCmdSetPatchControlPointsEXT{};
243 PFN_vkCmdSetLogicOpEXT vkCmdSetLogicOpEXT{};
242 PFN_vkCmdSetLineWidth vkCmdSetLineWidth{}; 244 PFN_vkCmdSetLineWidth vkCmdSetLineWidth{};
243 PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT{}; 245 PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT{};
244 PFN_vkCmdSetScissor vkCmdSetScissor{}; 246 PFN_vkCmdSetScissor vkCmdSetScissor{};
@@ -1238,6 +1240,14 @@ public:
1238 dld->vkCmdSetFrontFaceEXT(handle, front_face); 1240 dld->vkCmdSetFrontFaceEXT(handle, front_face);
1239 } 1241 }
1240 1242
1243 void SetLogicOpEXT(VkLogicOp logic_op) const noexcept {
1244 dld->vkCmdSetLogicOpEXT(handle, logic_op);
1245 }
1246
1247 void SetPatchControlPointsEXT(uint32_t patch_control_points) const noexcept {
1248 dld->vkCmdSetPatchControlPointsEXT(handle, patch_control_points);
1249 }
1250
1241 void SetLineWidth(float line_width) const noexcept { 1251 void SetLineWidth(float line_width) const noexcept {
1242 dld->vkCmdSetLineWidth(handle, line_width); 1252 dld->vkCmdSetLineWidth(handle, line_width);
1243 } 1253 }